LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - ww8par.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 2103 3036 69.3 %
Date: 2014-11-03 Functions: 120 145 82.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : 
      22             : #include <sal/config.h>
      23             : 
      24             : #include <boost/noncopyable.hpp>
      25             : #include <boost/unordered_set.hpp>
      26             : #include <com/sun/star/embed/ElementModes.hpp>
      27             : 
      28             : #include <i18nlangtag/languagetag.hxx>
      29             : 
      30             : #include <unotools/ucbstreamhelper.hxx>
      31             : #include <rtl/random.h>
      32             : #include <rtl/ustring.hxx>
      33             : #include <rtl/ustrbuf.hxx>
      34             : 
      35             : #include <sfx2/docinf.hxx>
      36             : #include <sfx2/request.hxx>
      37             : #include <sfx2/frame.hxx>
      38             : #include <tools/urlobj.hxx>
      39             : #include <unotools/tempfile.hxx>
      40             : 
      41             : #include <comphelper/docpasswordrequest.hxx>
      42             : #include <comphelper/string.hxx>
      43             : 
      44             : #include <editeng/brushitem.hxx>
      45             : #include <editeng/tstpitem.hxx>
      46             : #include <editeng/ulspitem.hxx>
      47             : #include <editeng/langitem.hxx>
      48             : #include <editeng/opaqitem.hxx>
      49             : #include <editeng/charhiddenitem.hxx>
      50             : #include <editeng/fontitem.hxx>
      51             : #include <svx/unoapi.hxx>
      52             : #include <svx/svdoole2.hxx>
      53             : #include <svx/svdoashp.hxx>
      54             : #include <svx/svxerr.hxx>
      55             : #include <filter/msfilter/mscodec.hxx>
      56             : #include <svx/svdmodel.hxx>
      57             : #include <svx/xflclit.hxx>
      58             : 
      59             : #include <unotools/fltrcfg.hxx>
      60             : #include <fmtfld.hxx>
      61             : #include <fmturl.hxx>
      62             : #include <fmtinfmt.hxx>
      63             : #include <reffld.hxx>
      64             : #include <fmthdft.hxx>
      65             : #include <fmtcntnt.hxx>
      66             : #include <fmtcnct.hxx>
      67             : #include <fmtanchr.hxx>
      68             : #include <fmtpdsc.hxx>
      69             : #include <ftninfo.hxx>
      70             : #include <fmtftn.hxx>
      71             : #include <txtftn.hxx>
      72             : #include <ndtxt.hxx>
      73             : #include <pagedesc.hxx>
      74             : #include <paratr.hxx>
      75             : #include <fmtclbl.hxx>
      76             : #include <section.hxx>
      77             : #include <docsh.hxx>
      78             : #include <IDocumentFieldsAccess.hxx>
      79             : #include <IDocumentLayoutAccess.hxx>
      80             : #include <IDocumentStylePoolAccess.hxx>
      81             : #include <IDocumentExternalData.hxx>
      82             : #include <docufld.hxx>
      83             : #include <swfltopt.hxx>
      84             : #include <viewsh.hxx>
      85             : #include <shellres.hxx>
      86             : #include <mdiexp.hxx>
      87             : #include <statstr.hrc>
      88             : #include <swerror.h>
      89             : #include <swtable.hxx>
      90             : #include <fchrfmt.hxx>
      91             : #include <charfmt.hxx>
      92             : #include <unocrsr.hxx>
      93             : #include <IDocumentSettingAccess.hxx>
      94             : 
      95             : #include <fltini.hxx>
      96             : 
      97             : #include "writerwordglue.hxx"
      98             : 
      99             : #include "ndgrf.hxx"
     100             : #include <editeng/editids.hrc>
     101             : #include <txtflcnt.hxx>
     102             : #include <fmtflcnt.hxx>
     103             : #include <txatbase.hxx>
     104             : 
     105             : #include "ww8par2.hxx"
     106             : 
     107             : #include <com/sun/star/beans/PropertyAttribute.hpp>
     108             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
     109             : #include <com/sun/star/document/XViewDataSupplier.hpp>
     110             : #include <com/sun/star/document/IndexedPropertyValues.hpp>
     111             : #include <svl/itemiter.hxx>
     112             : 
     113             : #include <comphelper/processfactory.hxx>
     114             : #include <basic/basmgr.hxx>
     115             : 
     116             : #include "ww8toolbar.hxx"
     117             : #include <osl/file.hxx>
     118             : 
     119             : #include <breakit.hxx>
     120             : 
     121             : #if OSL_DEBUG_LEVEL > 1
     122             : #include <iostream>
     123             : #include <dbgoutsw.hxx>
     124             : #endif
     125             : #include <unotools/localfilehelper.hxx>
     126             : 
     127             : #include <svx/hlnkitem.hxx>
     128             : #include "WW8Sttbf.hxx"
     129             : #include "WW8FibData.hxx"
     130             : 
     131             : using namespace ::com::sun::star;
     132             : using namespace sw::util;
     133             : using namespace sw::types;
     134             : using namespace nsHdFtFlags;
     135             : 
     136             : #include <com/sun/star/i18n/ScriptType.hpp>
     137             : #include <unotools/pathoptions.hxx>
     138             : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
     139             : 
     140             : #include <com/sun/star/script/vba/XVBACompatibility.hpp>
     141             : #include <comphelper/sequenceashashmap.hxx>
     142             : #include <oox/ole/vbaproject.hxx>
     143             : #include <oox/ole/olestorage.hxx>
     144             : 
     145             : //#define VT_EMPTY            0
     146             : //#define VT_I4               3
     147             : //#define VT_LPSTR            30
     148             : //#define VT_LPWSTR           31
     149             : //#define VT_BLOB             65
     150             : //#define VT_TYPEMASK         0xFFF
     151             : /** Expands to a pointer behind the last element of a STATIC data array (like STL end()). */
     152             : //#define STATIC_TABLE_END( array )   ((array)+STATIC_TABLE_SIZE(array))
     153             : /** Expands to the size of a STATIC data array. */
     154             : //#define STATIC_TABLE_SIZE( array )  (sizeof(array)/sizeof(*(array)))
     155             : 
     156           2 : SwMacroInfo* GetMacroInfo( SdrObject* pObj, bool bCreate )             // static
     157             : {
     158           2 :     if ( pObj )
     159             :     {
     160           2 :         sal_uInt16 nCount = pObj->GetUserDataCount();
     161           2 :         for( sal_uInt16 i = 0; i < nCount; i++ )
     162             :         {
     163           0 :             SdrObjUserData* pData = pObj->GetUserData( i );
     164           0 :             if( pData && pData->GetInventor() == SW_DRAWLAYER
     165           0 :                 && pData->GetId() == SW_UD_IMAPDATA)
     166             :             {
     167           0 :                 return dynamic_cast<SwMacroInfo*>(pData);
     168             :             }
     169             :         }
     170           2 :         if ( bCreate )
     171             :         {
     172           2 :             SwMacroInfo* pData = new SwMacroInfo;
     173           2 :             pObj->AppendUserData(pData);
     174           2 :             return pData;
     175             :         }
     176             :     }
     177             : 
     178           0 :     return 0;
     179             : };
     180             : 
     181           2 : void lclGetAbsPath(OUString& rPath, sal_uInt16 nLevel, SwDocShell* pDocShell)
     182             : {
     183           2 :     OUString aTmpStr;
     184           4 :     while( nLevel )
     185             :     {
     186           0 :         aTmpStr += "../";
     187           0 :         --nLevel;
     188             :     }
     189           2 :     if (!aTmpStr.isEmpty())
     190           0 :         aTmpStr += rPath;
     191             :     else
     192           2 :         aTmpStr = rPath;
     193             : 
     194           2 :     if (!aTmpStr.isEmpty())
     195             :     {
     196           2 :         bool bWasAbs = false;
     197           2 :         rPath = pDocShell->GetMedium()->GetURLObject().smartRel2Abs( aTmpStr, bWasAbs ).GetMainURL( INetURLObject::NO_DECODE );
     198             :         // full path as stored in SvxURLField must be encoded
     199           2 :     }
     200           2 : }
     201             : 
     202           0 : void lclIgnoreString32( SvMemoryStream& rStrm, bool b16Bit )
     203             : {
     204           0 :     sal_uInt32 nChars(0);
     205           0 :     rStrm.ReadUInt32( nChars );
     206           0 :     if( b16Bit )
     207           0 :         nChars *= 2;
     208           0 :     rStrm.SeekRel( nChars );
     209           0 : }
     210             : 
     211           4 : OUString SwWW8ImplReader::ReadRawUniString(SvMemoryStream& rStrm, sal_uInt16 nChars, bool b16Bit)
     212             : {
     213             :     // Fixed-size characters
     214           4 :     const sal_uInt8 WW8_NUL_C                   = '\x00';       /// NUL chararcter.
     215           4 :     const sal_uInt16 WW8_NUL                    = WW8_NUL_C;    /// NUL chararcter (unicode).
     216           4 :     sal_Unicode         mcNulSubst = '\0';
     217             : 
     218           4 :     sal_uInt16 nCharsLeft = nChars;
     219           4 :     sal_Unicode* pcBuffer = new sal_Unicode[ nCharsLeft + 1 ];
     220             : 
     221           4 :     sal_Unicode* pcUniChar = pcBuffer;
     222           4 :     sal_Unicode* pcEndChar = pcBuffer + nCharsLeft;
     223             : 
     224           4 :     if( b16Bit )
     225             :     {
     226             :         sal_uInt16 nReadChar;
     227          16 :         for( ;  (pcUniChar < pcEndChar); ++pcUniChar )
     228             :         {
     229          14 :             rStrm.ReadUInt16( nReadChar );
     230          14 :             (*pcUniChar) = (nReadChar == WW8_NUL) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
     231             :         }
     232             :     }
     233             :     else
     234             :     {
     235             :         sal_uInt8 nReadChar;
     236          18 :         for( ; (pcUniChar < pcEndChar); ++pcUniChar )
     237             :         {
     238          16 :             rStrm.ReadUChar( nReadChar ) ;
     239          16 :             (*pcUniChar) = (nReadChar == WW8_NUL_C) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
     240             :         }
     241             :     }
     242             : 
     243           4 :     *pcEndChar = '\0';
     244           4 :     OUString aRet(pcBuffer);
     245           4 :     delete[] pcBuffer;
     246           4 :     return aRet;
     247             : }
     248             : 
     249           4 : void lclAppendString32(OUString& rString, SvMemoryStream& rStrm, sal_uInt32 nChars, bool b16Bit)
     250             : {
     251           4 :     sal_uInt16 nReadChars = ulimit_cast< sal_uInt16 >( nChars );
     252           4 :     OUString urlStr = SwWW8ImplReader::ReadRawUniString( rStrm, nReadChars, b16Bit );
     253           4 :     rString += urlStr;
     254           4 : }
     255             : 
     256           2 : void lclAppendString32(OUString& rString, SvMemoryStream& rStrm, bool b16Bit)
     257             : {
     258           2 :     sal_uInt32 nValue(0);
     259           2 :     rStrm.ReadUInt32( nValue );
     260           2 :     lclAppendString32(rString, rStrm, nValue, b16Bit);
     261           2 : }
     262             : 
     263           2 : void SwWW8ImplReader::ReadEmbeddedData( SvMemoryStream& rStrm, SwDocShell* pDocShell, struct HyperLinksTable& hlStr)
     264             : {
     265             :     // (0x01B8) HLINK
     266             :     // const sal_uInt16 WW8_ID_HLINK               = 0x01B8;
     267           2 :     const sal_uInt32 WW8_HLINK_BODY             = 0x00000001;   /// Contains file link or URL.
     268           2 :     const sal_uInt32 WW8_HLINK_ABS              = 0x00000002;   /// Absolute path.
     269           2 :     const sal_uInt32 WW8_HLINK_DESCR            = 0x00000014;   /// Description.
     270           2 :     const sal_uInt32 WW8_HLINK_MARK             = 0x00000008;   /// Text mark.
     271           2 :     const sal_uInt32 WW8_HLINK_FRAME            = 0x00000080;   /// Target frame.
     272           2 :     const sal_uInt32 WW8_HLINK_UNC              = 0x00000100;   /// UNC path.
     273             : 
     274             :     //sal_uInt8 maGuidStdLink[ 16 ] ={
     275             :     //    0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
     276             : 
     277             :     sal_uInt8 maGuidUrlMoniker[ 16 ] = {
     278           2 :         0xE0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
     279             : 
     280             :     sal_uInt8 maGuidFileMoniker[ 16 ] = {
     281           2 :         0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
     282             : 
     283             :     sal_uInt8 aGuid[16];
     284           2 :     sal_uInt32 nFlags(0);
     285             : 
     286           2 :     rStrm.Read(aGuid, 16);
     287           2 :     rStrm.SeekRel( 4 );
     288           2 :     rStrm.ReadUInt32( nFlags );
     289             : 
     290           2 :     sal_uInt16 nLevel = 0;                  // counter for level to climb down in path
     291           2 :     boost::scoped_ptr< OUString > xLongName;    // link / file name
     292           4 :     boost::scoped_ptr< OUString > xShortName;   // 8.3-representation of file name
     293           4 :     boost::scoped_ptr< OUString > xTextMark;    // text mark
     294             : 
     295             :     // description (ignore)
     296           2 :     if( ::get_flag( nFlags, WW8_HLINK_DESCR ) )
     297           0 :         lclIgnoreString32( rStrm, true );
     298             : 
     299             :     // target frame
     300           2 :     if( ::get_flag( nFlags, WW8_HLINK_FRAME ) )
     301             :     {
     302           0 :         OUString sFrmName;
     303           0 :         lclAppendString32(sFrmName, rStrm, true);
     304           0 :         hlStr.tarFrm = sFrmName;
     305             :     }
     306             : 
     307             :         // UNC path
     308           2 :     if( ::get_flag( nFlags, WW8_HLINK_UNC ) )
     309             :     {
     310           0 :         xLongName.reset( new OUString );
     311           0 :         lclAppendString32( *xLongName, rStrm, true );
     312           0 :         lclGetAbsPath( *xLongName, 0 , pDocShell);
     313             :     }
     314             :     // file link or URL
     315           2 :     else if( ::get_flag( nFlags, WW8_HLINK_BODY ) )
     316             :     {
     317           2 :         rStrm.Read( aGuid, 16);
     318             : 
     319           2 :         if( (memcmp(aGuid, maGuidFileMoniker, 16) == 0) )
     320             :         {
     321           2 :             rStrm.ReadUInt16( nLevel );
     322           2 :             xShortName.reset( new OUString );
     323           2 :             lclAppendString32( *xShortName,rStrm, false );
     324           2 :             rStrm.SeekRel( 24 );
     325             : 
     326           2 :             sal_uInt32 nStrLen(0);
     327           2 :             rStrm.ReadUInt32( nStrLen );
     328           2 :             if( nStrLen )
     329             :             {
     330           2 :                 nStrLen = 0;
     331           2 :                 rStrm.ReadUInt32( nStrLen );
     332           2 :                 nStrLen /= 2;
     333           2 :                 rStrm.SeekRel( 2 );
     334           2 :                 xLongName.reset( new OUString );
     335           2 :                 lclAppendString32( *xLongName, rStrm,nStrLen, true );
     336           2 :                 lclGetAbsPath( *xLongName, nLevel, pDocShell);
     337             :             }
     338             :             else
     339           0 :                 lclGetAbsPath( *xShortName, nLevel, pDocShell);
     340             :         }
     341           0 :         else if( (memcmp(aGuid, maGuidUrlMoniker, 16) == 0) )
     342             :         {
     343           0 :             sal_uInt32 nStrLen(0);
     344           0 :             rStrm.ReadUInt32( nStrLen );
     345           0 :             nStrLen /= 2;
     346           0 :             xLongName.reset( new OUString );
     347           0 :             lclAppendString32( *xLongName,rStrm, nStrLen, true );
     348           0 :             if( !::get_flag( nFlags, WW8_HLINK_ABS ) )
     349           0 :                 lclGetAbsPath( *xLongName, 0 ,pDocShell);
     350             :         }
     351             :         else
     352             :         {
     353             :             SAL_INFO("sw.ww8", "WW8Hyperlink::ReadEmbeddedData - unknown content GUID");
     354             :         }
     355             :     }
     356             : 
     357             :     // text mark
     358           2 :     if( ::get_flag( nFlags, WW8_HLINK_MARK ) )
     359             :     {
     360           0 :         xTextMark.reset( new OUString );
     361           0 :         lclAppendString32( *xTextMark, rStrm, true );
     362             :     }
     363             : 
     364           2 :     if( !xLongName.get() && xShortName.get() )
     365             :     {
     366           0 :         xLongName.reset( new OUString );
     367           0 :         *xLongName = xLongName->concat(*xShortName);
     368             :     }
     369           2 :     else if( !xLongName.get() && xTextMark.get() )
     370           0 :         xLongName.reset( new OUString );
     371             : 
     372           2 :     if( xLongName.get() )
     373             :     {
     374           2 :         if( xTextMark.get() )
     375             :         {
     376           0 :             if (xLongName->isEmpty())
     377           0 :                 *xTextMark = xTextMark->replace('!', '.');
     378           0 :             *xLongName = xLongName->concat("#");
     379           0 :             *xLongName = xLongName->concat(*xTextMark);
     380             :         }
     381           2 :         hlStr.hLinkAddr = *xLongName;
     382           2 :     }
     383           2 : }
     384             : 
     385         182 : class BasicProjImportHelper
     386             : {
     387             :     SwDocShell& mrDocShell;
     388             :     uno::Reference< uno::XComponentContext > mxCtx;
     389             : public:
     390         182 :     BasicProjImportHelper( SwDocShell& rShell ) : mrDocShell( rShell )
     391             :     {
     392         182 :         mxCtx = comphelper::getProcessComponentContext();
     393         182 :     }
     394             :     bool import( const uno::Reference< io::XInputStream >& rxIn );
     395             :     OUString getProjectName();
     396             : };
     397             : 
     398         182 : bool BasicProjImportHelper::import( const uno::Reference< io::XInputStream >& rxIn )
     399             : {
     400         182 :     bool bRet = false;
     401             :     try
     402             :     {
     403         182 :         oox::ole::OleStorage root( mxCtx, rxIn, false );
     404         364 :         oox::StorageRef vbaStg = root.openSubStorage( "Macros" , false );
     405         182 :         if ( vbaStg.get() )
     406             :         {
     407           2 :             oox::ole::VbaProject aVbaPrj( mxCtx, mrDocShell.GetModel(), OUString("Writer") );
     408           2 :             bRet = aVbaPrj.importVbaProject( *vbaStg );
     409         182 :         }
     410             :     }
     411           0 :     catch( const uno::Exception& )
     412             :     {
     413           0 :         bRet = false;
     414             :     }
     415         182 :     return bRet;
     416             : }
     417             : 
     418         182 : OUString BasicProjImportHelper::getProjectName()
     419             : {
     420         182 :     OUString sProjName( "Standard" );
     421         364 :     uno::Reference< beans::XPropertySet > xProps( mrDocShell.GetModel(), uno::UNO_QUERY );
     422         182 :     if ( xProps.is() )
     423             :     {
     424             :         try
     425             :         {
     426         238 :             uno::Reference< script::vba::XVBACompatibility > xVBA( xProps->getPropertyValue( "BasicLibraries" ), uno::UNO_QUERY_THROW  );
     427         126 :             sProjName = xVBA->getProjectName();
     428             : 
     429             :         }
     430          56 :         catch( const uno::Exception& )
     431             :         {
     432             :         }
     433             :     }
     434         364 :     return sProjName;
     435             : }
     436             : 
     437             : class Sttb : TBBase, private boost::noncopyable
     438             : {
     439       16008 : struct SBBItem
     440             : {
     441             :     sal_uInt16 cchData;
     442             :     OUString data;
     443        2484 :     SBBItem() : cchData(0){}
     444             : };
     445             :     sal_uInt16 fExtend;
     446             :     sal_uInt16 cData;
     447             :     sal_uInt16 cbExtra;
     448             : 
     449             :     std::vector< SBBItem > dataItems;
     450             : 
     451             : public:
     452             :     Sttb();
     453             :     virtual ~Sttb();
     454             :     bool Read(SvStream &rS) SAL_OVERRIDE;
     455             : #if OSL_DEBUG_LEVEL > 1
     456             :     virtual void Print( FILE* fp ) SAL_OVERRIDE;
     457             : #endif
     458             :     OUString getStringAtIndex( sal_uInt32 );
     459             : };
     460             : 
     461         144 : Sttb::Sttb()
     462             :     : fExtend(0)
     463             :     , cData(0)
     464         144 :     , cbExtra(0)
     465             : {
     466         144 : }
     467             : 
     468         144 : Sttb::~Sttb()
     469             : {
     470         144 : }
     471             : 
     472         144 : bool Sttb::Read( SvStream& rS )
     473             : {
     474             :     OSL_TRACE("Sttb::Read() stream pos 0x%x", rS.Tell() );
     475         144 :     nOffSet = rS.Tell();
     476         144 :     rS.ReadUInt16( fExtend ).ReadUInt16( cData ).ReadUInt16( cbExtra );
     477         144 :     if ( cData )
     478             :     {
     479             :         //if they are all going to be empty strings, how many could there be
     480         140 :         const size_t nMaxPossibleRecords = rS.remainingSize() / sizeof(sal_uInt16);
     481         140 :         if (cData > nMaxPossibleRecords)
     482           2 :             return false;
     483        2622 :         for ( sal_Int32 index = 0; index < cData; ++index )
     484             :         {
     485        2484 :             SBBItem aItem;
     486        2484 :             rS.ReadUInt16( aItem.cchData );
     487        2484 :             aItem.data = read_uInt16s_ToOUString(rS, aItem.cchData);
     488        2484 :             dataItems.push_back( aItem );
     489        2484 :         }
     490             :     }
     491         142 :     return true;
     492             : }
     493             : 
     494             : #if OSL_DEBUG_LEVEL > 1
     495             : void Sttb::Print( FILE* fp )
     496             : {
     497             :     fprintf( fp, "[ 0x%" SAL_PRIxUINT32 " ] Sttb - dump\n", nOffSet);
     498             :     fprintf( fp, " fExtend 0x%x [expected 0xFFFF ]\n", fExtend );
     499             :     fprintf( fp, " cData no. or string data items %d (0x%x)\n", cData, cData );
     500             : 
     501             :     if ( cData )
     502             :     {
     503             :         for (sal_uInt16 index = 0; index < cData; ++index)
     504             :         {
     505             :             if (index >= dataItems.size())
     506             :             {
     507             :                 fprintf(fp, "   Sttb truncated at entry %d(0x%x)\n", static_cast< int >( index ), static_cast< unsigned int >( index ));
     508             :                 break;
     509             :             }
     510             :             fprintf(fp,"   string dataItem[ %d(0x%x) ] has name %s\n", static_cast< int >( index ), static_cast< unsigned int >( index ), OUStringToOString( dataItems[ index ].data, RTL_TEXTENCODING_UTF8 ).getStr() );
     511             :         }
     512             :     }
     513             : }
     514             : #endif
     515             : 
     516             : OUString
     517         144 : Sttb::getStringAtIndex( sal_uInt32 index )
     518             : {
     519         144 :     OUString aRet;
     520         144 :     if ( index < dataItems.size() )
     521         138 :         aRet = dataItems[ index ].data;
     522         144 :     return aRet;
     523             : 
     524             : }
     525             : 
     526         106 : SwMSDffManager::SwMSDffManager( SwWW8ImplReader& rRdr )
     527         106 :     : SvxMSDffManager(*rRdr.pTableStream, rRdr.GetBaseURL(), rRdr.pWwFib->fcDggInfo,
     528             :         rRdr.pDataStream, 0, 0, COL_WHITE, 12, rRdr.pStrm),
     529         212 :     rReader(rRdr), pFallbackStream(0)
     530             : {
     531         106 :     SetSvxMSDffSettings( GetSvxMSDffSettings() );
     532         106 :     nSvxMSDffOLEConvFlags = SwMSDffManager::GetFilterFlags();
     533         106 : }
     534             : 
     535         116 : sal_uInt32 SwMSDffManager::GetFilterFlags()
     536             : {
     537         116 :     sal_uInt32 nFlags(0);
     538         116 :     const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
     539         116 :     if (rOpt.IsMathType2Math())
     540         116 :         nFlags |= OLE_MATHTYPE_2_STARMATH;
     541         116 :     if (rOpt.IsExcel2Calc())
     542         116 :         nFlags |= OLE_EXCEL_2_STARCALC;
     543         116 :     if (rOpt.IsPowerPoint2Impress())
     544         116 :         nFlags |= OLE_POWERPOINT_2_STARIMPRESS;
     545         116 :     if (rOpt.IsWinWord2Writer())
     546         116 :         nFlags |= OLE_WINWORD_2_STARWRITER;
     547         116 :     return nFlags;
     548             : }
     549             : 
     550             : /*
     551             :  * I would like to override the default OLE importing to add a test
     552             :  * and conversion of OCX controls from their native OLE type into our
     553             :  * native nonOLE Form Control Objects.
     554             :  *
     555             :  * cmc
     556             :  */
     557             : // #i32596# - consider new parameter <_nCalledByGroup>
     558          24 : SdrObject* SwMSDffManager::ImportOLE( long nOLEId,
     559             :                                       const Graphic& rGrf,
     560             :                                       const Rectangle& rBoundRect,
     561             :                                       const Rectangle& rVisArea,
     562             :                                       const int _nCalledByGroup,
     563             :                                       sal_Int64 nAspect ) const
     564             : {
     565             :     // #i32596# - no import of OLE object, if it's inside a group.
     566             :     // NOTE: This can be undone, if grouping of Writer fly frames is possible or
     567             :     // if drawing OLE objects are allowed in Writer.
     568          24 :     if ( _nCalledByGroup > 0 )
     569             :     {
     570           0 :         return 0L;
     571             :     }
     572             : 
     573          24 :     SdrObject* pRet = 0;
     574          24 :     OUString sStorageName;
     575          48 :     SotStorageRef xSrcStg;
     576          48 :     uno::Reference < embed::XStorage > xDstStg;
     577          24 :     if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
     578             :     {
     579             :         SvStorageRef xSrc = xSrcStg->OpenSotStorage( sStorageName,
     580          24 :             STREAM_READWRITE| STREAM_SHARE_DENYALL );
     581             :         OSL_ENSURE(rReader.pFormImpl, "No Form Implementation!");
     582          48 :         ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape;
     583          48 :         if ( (!(rReader.bIsHeader || rReader.bIsFooter)) &&
     584          24 :             rReader.pFormImpl->ReadOCXStream(xSrc,&xShape,true))
     585             :         {
     586           2 :             pRet = GetSdrObjectFromXShape(xShape);
     587             :         }
     588             :         else
     589             :         {
     590          22 :             ErrCode nError = ERRCODE_NONE;
     591             :             pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
     592          22 :                 rGrf, rBoundRect, rVisArea, pStData, nError, nSvxMSDffOLEConvFlags, nAspect );
     593          24 :         }
     594             :     }
     595          48 :     return pRet;
     596             : }
     597             : 
     598          50 : void SwMSDffManager::DisableFallbackStream()
     599             : {
     600             :     OSL_ENSURE(!pFallbackStream,
     601             :         "if you're recursive, you're broken");
     602          50 :     pFallbackStream = pStData2;
     603          50 :     aOldEscherBlipCache = aEscherBlipCache;
     604          50 :     aEscherBlipCache.clear();
     605          50 :     pStData2 = 0;
     606          50 : }
     607             : 
     608          50 : void SwMSDffManager::EnableFallbackStream()
     609             : {
     610          50 :     pStData2 = pFallbackStream;
     611          50 :     aEscherBlipCache = aOldEscherBlipCache;
     612          50 :     aOldEscherBlipCache.clear();
     613          50 :     pFallbackStream = 0;
     614          50 : }
     615             : 
     616        4438 : sal_uInt16 SwWW8ImplReader::GetToggleAttrFlags() const
     617             : {
     618        4438 :     return pCtrlStck ? pCtrlStck->GetToggleAttrFlags() : 0;
     619             : }
     620             : 
     621        4438 : sal_uInt16 SwWW8ImplReader::GetToggleBiDiAttrFlags() const
     622             : {
     623        4438 :     return pCtrlStck ? pCtrlStck->GetToggleBiDiAttrFlags() : 0;
     624             : }
     625             : 
     626        4438 : void SwWW8ImplReader::SetToggleAttrFlags(sal_uInt16 nFlags)
     627             : {
     628        4438 :     if (pCtrlStck)
     629        4438 :         pCtrlStck->SetToggleAttrFlags(nFlags);
     630        4438 : }
     631             : 
     632        4438 : void SwWW8ImplReader::SetToggleBiDiAttrFlags(sal_uInt16 nFlags)
     633             : {
     634        4438 :     if (pCtrlStck)
     635        4438 :         pCtrlStck->SetToggleBiDiAttrFlags(nFlags);
     636        4438 : }
     637             : 
     638         626 : SdrObject* SwMSDffManager::ProcessObj(SvStream& rSt,
     639             :                                        DffObjData& rObjData,
     640             :                                        void* pData,
     641             :                                        Rectangle& rTextRect,
     642             :                                        SdrObject* pObj
     643             :                                        )
     644             : {
     645         626 :     if( !rTextRect.IsEmpty() )
     646             :     {
     647         626 :         SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
     648         626 :         SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
     649             : 
     650             :         // fill Import Record with data
     651         626 :         pImpRec->nShapeId   = rObjData.nShapeId;
     652         626 :         pImpRec->eShapeType = rObjData.eShapeType;
     653             : 
     654             :         rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
     655             :                                             DFF_msofbtClientAnchor,
     656         626 :                                             SEEK_FROM_CURRENT_AND_RESTART );
     657         626 :         if( rObjData.bClientAnchor )
     658             :             ProcessClientAnchor( rSt,
     659         200 :                     maShapeRecords.Current()->nRecLen,
     660         400 :                     pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
     661             : 
     662             :         rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
     663             :                                             DFF_msofbtClientData,
     664         626 :                                             SEEK_FROM_CURRENT_AND_RESTART );
     665         626 :         if( rObjData.bClientData )
     666             :             ProcessClientData( rSt,
     667         540 :                     maShapeRecords.Current()->nRecLen,
     668        1080 :                     pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
     669             : 
     670             :         // process user (== Winword) defined parameters in 0xF122 record
     671             :         // #i84783# - set special value to determine, if property is provided or not.
     672         626 :         pImpRec->nLayoutInTableCell = 0xFFFFFFFF;
     673             : 
     674         626 :         if(    maShapeRecords.SeekToContent( rSt,
     675             :                                              DFF_msofbtUDefProp,
     676         626 :                                              SEEK_FROM_CURRENT_AND_RESTART )
     677         626 :             && maShapeRecords.Current()->nRecLen )
     678             :         {
     679         244 :             sal_uInt32  nBytesLeft = maShapeRecords.Current()->nRecLen;
     680             :             sal_uInt32  nUDData;
     681             :             sal_uInt16  nPID;
     682       20928 :             while( 5 < nBytesLeft )
     683             :             {
     684       20440 :                 rSt.ReadUInt16( nPID );
     685       20440 :                 if ( rSt.GetError() != 0 )
     686           0 :                     break;
     687       20440 :                 rSt.ReadUInt32( nUDData );
     688       20440 :                 switch( nPID )
     689             :                 {
     690          94 :                     case 0x038F: pImpRec->nXAlign = nUDData; break;
     691             :                     case 0x0390:
     692          72 :                         delete pImpRec->pXRelTo;
     693          72 :                         pImpRec->pXRelTo = new sal_uInt32;
     694          72 :                         *(pImpRec->pXRelTo) = nUDData;
     695          72 :                         break;
     696          94 :                     case 0x0391: pImpRec->nYAlign = nUDData; break;
     697             :                     case 0x0392:
     698          72 :                         delete pImpRec->pYRelTo;
     699          72 :                         pImpRec->pYRelTo = new sal_uInt32;
     700          72 :                         *(pImpRec->pYRelTo) = nUDData;
     701          72 :                         break;
     702          96 :                     case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
     703             :                     case 0x0393:
     704             :                     // This seems to correspond to o:hrpct from .docx (even including
     705             :                     // the difference that it's in 0.1% even though the .docx spec
     706             :                     // says it's in 1%).
     707           6 :                         pImpRec->relativeHorizontalWidth = nUDData;
     708           6 :                         break;
     709             :                     case 0x0394:
     710             :                     // And this is really just a guess, but a mere presence of this
     711             :                     // flag makes a horizontal rule be as wide as the page (unless
     712             :                     // overridden by something), so it probably matches o:hr from .docx.
     713           8 :                         pImpRec->isHorizontalRule = true;
     714           8 :                         break;
     715             :                 }
     716       20440 :                 if ( rSt.GetError() != 0 )
     717           0 :                     break;
     718       20440 :                 nBytesLeft  -= 6;
     719             :             }
     720             :         }
     721             : 
     722             :         // Text Frame also Title or Outline
     723         626 :         sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
     724         626 :         if( nTextId )
     725             :         {
     726         148 :             SfxItemSet aSet( pSdrModel->GetItemPool() );
     727             : 
     728             :             // Originally anything that as a mso_sptTextBox was created as a
     729             :             // textbox, this was changed to be created as a simple
     730             :             // rect to keep impress happy. For the rest of us we'd like to turn
     731             :             // it back into a textbox again.
     732         148 :             bool bIsSimpleDrawingTextBox = (pImpRec->eShapeType == mso_sptTextBox);
     733         148 :             if (!bIsSimpleDrawingTextBox)
     734             :             {
     735             :                 // Either
     736             :                 // a) it's a simple text object or
     737             :                 // b) it's a rectangle with text and square wrapping.
     738             :                 bIsSimpleDrawingTextBox =
     739             :                 (
     740         320 :                     (pImpRec->eShapeType == mso_sptTextSimple) ||
     741             :                     (
     742         112 :                         (pImpRec->eShapeType == mso_sptRectangle)
     743          96 :                         && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
     744             :                     )
     745         112 :                 );
     746             :             }
     747             : 
     748             :             // Distance of Textbox to it's surrounding Autoshape
     749         148 :             sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
     750         148 :             sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
     751         148 :             sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L  );
     752         148 :             sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
     753             : 
     754         148 :             ScaleEmu( nTextLeft );
     755         148 :             ScaleEmu( nTextRight );
     756         148 :             ScaleEmu( nTextTop );
     757         148 :             ScaleEmu( nTextBottom );
     758             : 
     759         148 :             sal_Int32 nTextRotationAngle=0;
     760         148 :             bool bVerticalText = false;
     761         148 :             if ( IsProperty( DFF_Prop_txflTextFlow ) )
     762             :             {
     763             :                 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
     764           6 :                     DFF_Prop_txflTextFlow) & 0xFFFF);
     765           6 :                 switch( eTextFlow )
     766             :                 {
     767             :                     case mso_txflBtoT:
     768           0 :                         nTextRotationAngle = 9000;
     769           0 :                     break;
     770             :                     case mso_txflVertN:
     771             :                     case mso_txflTtoBN:
     772           0 :                         nTextRotationAngle = 27000;
     773           0 :                         break;
     774             :                     case mso_txflTtoBA:
     775           0 :                         bVerticalText = true;
     776           0 :                     break;
     777             :                     case mso_txflHorzA:
     778           0 :                         bVerticalText = true;
     779           0 :                         nTextRotationAngle = 9000;
     780             :                     case mso_txflHorzN:
     781             :                     default :
     782           6 :                         break;
     783             :                 }
     784             :             }
     785             : 
     786         148 :             if (nTextRotationAngle)
     787             :             {
     788           0 :                 if (nTextRotationAngle == 9000)
     789             :                 {
     790           0 :                     long nWidth = rTextRect.GetWidth();
     791           0 :                     rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
     792           0 :                     rTextRect.Bottom() = rTextRect.Top() + nWidth;
     793             : 
     794           0 :                     sal_Int32 nOldTextLeft = nTextLeft;
     795           0 :                     sal_Int32 nOldTextRight = nTextRight;
     796           0 :                     sal_Int32 nOldTextTop = nTextTop;
     797           0 :                     sal_Int32 nOldTextBottom = nTextBottom;
     798             : 
     799           0 :                     nTextLeft = nOldTextBottom;
     800           0 :                     nTextRight = nOldTextTop;
     801           0 :                     nTextTop = nOldTextLeft;
     802           0 :                     nTextBottom = nOldTextRight;
     803             :                 }
     804           0 :                 else if (nTextRotationAngle == 27000)
     805             :                 {
     806           0 :                     long nWidth = rTextRect.GetWidth();
     807           0 :                     rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
     808           0 :                     rTextRect.Bottom() = rTextRect.Top() + nWidth;
     809             : 
     810           0 :                     sal_Int32 nOldTextLeft = nTextLeft;
     811           0 :                     sal_Int32 nOldTextRight = nTextRight;
     812           0 :                     sal_Int32 nOldTextTop = nTextTop;
     813           0 :                     sal_Int32 nOldTextBottom = nTextBottom;
     814             : 
     815           0 :                     nTextLeft = nOldTextTop;
     816           0 :                     nTextRight = nOldTextBottom;
     817           0 :                     nTextTop = nOldTextRight;
     818           0 :                     nTextBottom = nOldTextLeft;
     819             :                 }
     820             :             }
     821             : 
     822         148 :             if (bIsSimpleDrawingTextBox)
     823             :             {
     824         132 :                 SdrObject::Free( pObj );
     825         132 :                 pObj = new SdrRectObj(OBJ_TEXT, rTextRect);
     826             :             }
     827             : 
     828             :             // The vertical paragraph justification are contained within the
     829             :             // BoundRect so calculate it here
     830         148 :             Rectangle aNewRect(rTextRect);
     831         148 :             aNewRect.Bottom() -= nTextTop + nTextBottom;
     832         148 :             aNewRect.Right() -= nTextLeft + nTextRight;
     833             : 
     834             :             // Only if it's a simple Textbox, Writer can replace the Object
     835             :             // with a Frame, else
     836         148 :             if( bIsSimpleDrawingTextBox )
     837             :             {
     838             :                 ::boost::shared_ptr<SvxMSDffShapeInfo> const pTmpRec(
     839         132 :                         new SvxMSDffShapeInfo(0, pImpRec->nShapeId));
     840             : 
     841             :                 SvxMSDffShapeInfos_ById::const_iterator const it =
     842         132 :                     GetShapeInfos()->find(pTmpRec);
     843         132 :                 if (it != GetShapeInfos()->end())
     844             :                 {
     845         132 :                     SvxMSDffShapeInfo& rInfo = **it;
     846         132 :                     pImpRec->bReplaceByFly   = rInfo.bReplaceByFly;
     847         132 :                 }
     848             :             }
     849             : 
     850         148 :             if( bIsSimpleDrawingTextBox )
     851         132 :                 ApplyAttributes( rSt, aSet, rObjData );
     852             : 
     853         148 :             if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
     854             :             {
     855           0 :                 aSet.Put( makeSdrTextAutoGrowHeightItem( true ) );
     856             :                 aSet.Put( makeSdrTextMinFrameHeightItem(
     857           0 :                     aNewRect.Bottom() - aNewRect.Top() ) );
     858             :                 aSet.Put( makeSdrTextMinFrameWidthItem(
     859           0 :                     aNewRect.Right() - aNewRect.Left() ) );
     860             :             }
     861             :             else
     862             :             {
     863         148 :                 aSet.Put( makeSdrTextAutoGrowHeightItem( false ) );
     864         148 :                 aSet.Put( makeSdrTextAutoGrowWidthItem( false ) );
     865             :             }
     866             : 
     867         148 :             switch ( (MSO_WrapMode)
     868         148 :                 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
     869             :             {
     870             :                 case mso_wrapNone :
     871           0 :                     aSet.Put( makeSdrTextAutoGrowWidthItem( true ) );
     872           0 :                     pImpRec->bAutoWidth = true;
     873           0 :                 break;
     874             :                 case mso_wrapByPoints :
     875           0 :                     aSet.Put( makeSdrTextContourFrameItem( true ) );
     876           0 :                 break;
     877             :                 default:
     878             :                     ;
     879             :             }
     880             : 
     881             :             // Set distances on Textbox's margins
     882         148 :             aSet.Put( makeSdrTextLeftDistItem( nTextLeft ) );
     883         148 :             aSet.Put( makeSdrTextRightDistItem( nTextRight ) );
     884         148 :             aSet.Put( makeSdrTextUpperDistItem( nTextTop ) );
     885         148 :             aSet.Put( makeSdrTextLowerDistItem( nTextBottom ) );
     886         148 :             pImpRec->nDxTextLeft    = nTextLeft;
     887         148 :             pImpRec->nDyTextTop     = nTextTop;
     888         148 :             pImpRec->nDxTextRight   = nTextRight;
     889         148 :             pImpRec->nDyTextBottom  = nTextBottom;
     890             : 
     891             :             // Taking the correct default (which is mso_anchorTop)
     892             :             MSO_Anchor eTextAnchor =
     893         148 :                 (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
     894             : 
     895             :             SdrTextVertAdjust eTVA = bVerticalText
     896             :                                      ? SDRTEXTVERTADJUST_BLOCK
     897         148 :                                      : SDRTEXTVERTADJUST_CENTER;
     898             :             SdrTextHorzAdjust eTHA = bVerticalText
     899             :                                      ? SDRTEXTHORZADJUST_CENTER
     900         148 :                                      : SDRTEXTHORZADJUST_BLOCK;
     901             : 
     902         148 :             switch( eTextAnchor )
     903             :             {
     904             :                 case mso_anchorTop:
     905             :                 {
     906         132 :                     if ( bVerticalText )
     907           0 :                         eTHA = SDRTEXTHORZADJUST_RIGHT;
     908             :                     else
     909         132 :                         eTVA = SDRTEXTVERTADJUST_TOP;
     910             :                 }
     911         132 :                 break;
     912             :                 case mso_anchorTopCentered:
     913             :                 {
     914           0 :                     if ( bVerticalText )
     915           0 :                         eTHA = SDRTEXTHORZADJUST_RIGHT;
     916             :                     else
     917           0 :                         eTVA = SDRTEXTVERTADJUST_TOP;
     918             :                 }
     919           0 :                 break;
     920             :                 case mso_anchorMiddle:
     921          16 :                 break;
     922             :                 case mso_anchorMiddleCentered:
     923           0 :                 break;
     924             :                 case mso_anchorBottom:
     925             :                 {
     926           0 :                     if ( bVerticalText )
     927           0 :                         eTHA = SDRTEXTHORZADJUST_LEFT;
     928             :                     else
     929           0 :                         eTVA = SDRTEXTVERTADJUST_BOTTOM;
     930             :                 }
     931           0 :                 break;
     932             :                 case mso_anchorBottomCentered:
     933             :                 {
     934           0 :                     if ( bVerticalText )
     935           0 :                         eTHA = SDRTEXTHORZADJUST_LEFT;
     936             :                     else
     937           0 :                         eTVA = SDRTEXTVERTADJUST_BOTTOM;
     938             :                 }
     939           0 :                 break;
     940             :                 default:
     941             :                     ;
     942             :             }
     943             : 
     944         148 :             aSet.Put( SdrTextVertAdjustItem( eTVA ) );
     945         148 :             aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
     946             : 
     947         148 :             if (pObj != NULL)
     948             :             {
     949         148 :                 pObj->SetMergedItemSet(aSet);
     950         148 :                 pObj->SetModel(pSdrModel);
     951             : 
     952         148 :                 if (bVerticalText)
     953             :                 {
     954           0 :                     SdrTextObj *pTextObj = dynamic_cast< SdrTextObj* >(pObj);
     955           0 :                     if (pTextObj)
     956           0 :                         pTextObj->SetVerticalWriting(true);
     957             :                 }
     958             : 
     959         148 :                 if ( bIsSimpleDrawingTextBox )
     960             :                 {
     961         132 :                     if ( nTextRotationAngle )
     962             :                     {
     963           0 :                         long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
     964           0 :                             rTextRect.GetWidth() : rTextRect.GetHeight();
     965           0 :                         nMinWH /= 2;
     966           0 :                         Point aPivot(rTextRect.TopLeft());
     967           0 :                         aPivot.X() += nMinWH;
     968           0 :                         aPivot.Y() += nMinWH;
     969           0 :                         double a = nTextRotationAngle * nPi180;
     970           0 :                         pObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
     971             :                     }
     972             :                 }
     973             : 
     974         148 :                 if ( ( ( rObjData.nSpFlags & SP_FFLIPV ) || mnFix16Angle || nTextRotationAngle ) && dynamic_cast< SdrObjCustomShape* >( pObj ) )
     975             :                 {
     976           0 :                     SdrObjCustomShape* pCustomShape = dynamic_cast< SdrObjCustomShape* >( pObj );
     977           0 :                     if (pCustomShape)
     978             :                     {
     979           0 :                         double fExtraTextRotation = 0.0;
     980           0 :                         if ( mnFix16Angle && !( GetPropertyValue( DFF_Prop_FitTextToShape ) & 4 ) )
     981             :                         {   // text is already rotated, we have to take back the object rotation if DFF_Prop_RotateText is false
     982           0 :                             fExtraTextRotation = -mnFix16Angle;
     983             :                         }
     984           0 :                         if ( rObjData.nSpFlags & SP_FFLIPV )    // sj: in ppt the text is flipped, whereas in word the text
     985             :                         {                                       // remains unchanged, so we have to take back the flipping here
     986           0 :                             fExtraTextRotation += 18000.0;      // because our core will flip text if the shape is flipped.
     987             :                         }
     988           0 :                         fExtraTextRotation += nTextRotationAngle;
     989           0 :                         if ( !::basegfx::fTools::equalZero( fExtraTextRotation ) )
     990             :                         {
     991           0 :                             fExtraTextRotation /= 100.0;
     992           0 :                             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
     993           0 :                             const OUString sTextRotateAngle( "TextRotateAngle" );
     994           0 :                             com::sun::star::beans::PropertyValue aPropVal;
     995           0 :                             aPropVal.Name = sTextRotateAngle;
     996           0 :                             aPropVal.Value <<= fExtraTextRotation;
     997           0 :                             aGeometryItem.SetPropertyValue( aPropVal );
     998           0 :                             pCustomShape->SetMergedItem( aGeometryItem );
     999             :                         }
    1000             :                     }
    1001             :                 }
    1002         148 :                 else if ( mnFix16Angle )
    1003             :                 {
    1004             :                     // rotate text with shape ?
    1005           0 :                     double a = mnFix16Angle * nPi180;
    1006           0 :                     pObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle,
    1007           0 :                                      sin( a ), cos( a ) );
    1008             :                 }
    1009         148 :             }
    1010             :         }
    1011         478 :         else if( !pObj )
    1012             :         {
    1013             :             // simple rectangular objects are ignored by ImportObj()  :-(
    1014             :             // this is OK for Draw but not for Calc and Writer
    1015             :             // cause here these objects have a default border
    1016           4 :             pObj = new SdrRectObj(rTextRect);
    1017           4 :             pObj->SetModel( pSdrModel );
    1018           4 :             SfxItemSet aSet( pSdrModel->GetItemPool() );
    1019           4 :             ApplyAttributes( rSt, aSet, rObjData );
    1020             : 
    1021           4 :             const SfxPoolItem* pPoolItem=NULL;
    1022             :             SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
    1023           4 :                                                      false, &pPoolItem );
    1024           4 :             if( SfxItemState::DEFAULT == eState )
    1025             :                 aSet.Put( XFillColorItem( OUString(),
    1026           0 :                           Color( mnDefaultColor ) ) );
    1027           4 :             pObj->SetMergedItemSet(aSet);
    1028             :         }
    1029             : 
    1030             :         // Means that fBehindDocument is set
    1031         626 :         if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
    1032           0 :             pImpRec->bDrawHell = true;
    1033             :         else
    1034         626 :             pImpRec->bDrawHell = false;
    1035         626 :         if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
    1036           0 :             pImpRec->bHidden = true;
    1037         626 :         pImpRec->nNextShapeId   = GetPropertyValue( DFF_Prop_hspNext, 0 );
    1038             : 
    1039         626 :         if ( nTextId )
    1040             :         {
    1041         148 :             pImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 );
    1042         148 :             pImpRec->aTextId.nSequence = (sal_uInt16)nTextId;
    1043             :         }
    1044             : 
    1045             :         pImpRec->nDxWrapDistLeft = GetPropertyValue(
    1046         626 :                                     DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
    1047             :         pImpRec->nDyWrapDistTop = GetPropertyValue(
    1048         626 :                                     DFF_Prop_dyWrapDistTop, 0 ) / 635L;
    1049             :         pImpRec->nDxWrapDistRight = GetPropertyValue(
    1050         626 :                                     DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
    1051             :         pImpRec->nDyWrapDistBottom = GetPropertyValue(
    1052         626 :                                     DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
    1053             :         // 16.16 fraction times total image width or height, as appropriate.
    1054             : 
    1055         626 :         if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
    1056             :         {
    1057           0 :             delete pImpRec->pWrapPolygon;
    1058           0 :             pImpRec->pWrapPolygon = NULL;
    1059             : 
    1060           0 :             sal_uInt16 nNumElemVert(0), nNumElemMemVert(0), nElemSizeVert(0);
    1061           0 :             rSt.ReadUInt16( nNumElemVert ).ReadUInt16( nNumElemMemVert ).ReadUInt16( nElemSizeVert );
    1062           0 :             bool bOk = false;
    1063           0 :             if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
    1064             :             {
    1065             :                 //check if there is enough data in the file to make the
    1066             :                 //record sane
    1067           0 :                 bOk = rSt.remainingSize() / nElemSizeVert >= nNumElemVert;
    1068             :             }
    1069           0 :             if (bOk)
    1070             :             {
    1071           0 :                 pImpRec->pWrapPolygon = new Polygon(nNumElemVert);
    1072           0 :                 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
    1073             :                 {
    1074           0 :                     sal_Int32 nX(0), nY(0);
    1075           0 :                     if (nElemSizeVert == 8)
    1076           0 :                         rSt.ReadInt32( nX ).ReadInt32( nY );
    1077             :                     else
    1078             :                     {
    1079           0 :                         sal_Int16 nSmallX(0), nSmallY(0);
    1080           0 :                         rSt.ReadInt16( nSmallX ).ReadInt16( nSmallY );
    1081           0 :                         nX = nSmallX;
    1082           0 :                         nY = nSmallY;
    1083             :                     }
    1084           0 :                     (*(pImpRec->pWrapPolygon))[i].X() = nX;
    1085           0 :                     (*(pImpRec->pWrapPolygon))[i].Y() = nY;
    1086             :                 }
    1087             :             }
    1088             :         }
    1089             : 
    1090             :         pImpRec->nCropFromTop = GetPropertyValue(
    1091         626 :                                     DFF_Prop_cropFromTop, 0 );
    1092             :         pImpRec->nCropFromBottom = GetPropertyValue(
    1093         626 :                                     DFF_Prop_cropFromBottom, 0 );
    1094             :         pImpRec->nCropFromLeft = GetPropertyValue(
    1095         626 :                                     DFF_Prop_cropFromLeft, 0 );
    1096             :         pImpRec->nCropFromRight = GetPropertyValue(
    1097         626 :                                     DFF_Prop_cropFromRight, 0 );
    1098             : 
    1099         626 :         sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
    1100             : 
    1101         778 :         if ( !IsHardAttribute( DFF_Prop_fLine ) &&
    1102         152 :              pImpRec->eShapeType == mso_sptPictureFrame )
    1103             :         {
    1104           0 :             nLineFlags &= ~0x08;
    1105             :         }
    1106             : 
    1107         626 :         pImpRec->eLineStyle = (nLineFlags & 8)
    1108             :                               ? (MSO_LineStyle)GetPropertyValue(
    1109             :                                                     DFF_Prop_lineStyle,
    1110         422 :                                                     mso_lineSimple )
    1111        1048 :                               : (MSO_LineStyle)USHRT_MAX;
    1112             :         pImpRec->eLineDashing = (MSO_LineDashing)GetPropertyValue(
    1113         626 :                                         DFF_Prop_lineDashing, mso_lineSolid );
    1114             : 
    1115         626 :         pImpRec->nFlags = rObjData.nSpFlags;
    1116             : 
    1117         626 :         if( pImpRec->nShapeId )
    1118             :         {
    1119             :             // Complement Import Record List
    1120         624 :             pImpRec->pObj = pObj;
    1121         624 :             rImportData.aRecords.insert( pImpRec );
    1122             : 
    1123             :             // Complement entry in Z Order List with a pointer to this Object
    1124             :             // Only store objects which are not deep inside the tree
    1125         624 :             if( ( rObjData.nCalledByGroup == 0 )
    1126         398 :                 ||
    1127         398 :                 ( (rObjData.nSpFlags & SP_FGROUP)
    1128          30 :                  && (rObjData.nCalledByGroup < 2) )
    1129             :               )
    1130             :                 StoreShapeOrder( pImpRec->nShapeId,
    1131         256 :                                 ( ( (sal_uLong)pImpRec->aTextId.nTxBxS ) << 16 )
    1132         512 :                                     + pImpRec->aTextId.nSequence, pObj );
    1133             :         }
    1134             :         else
    1135           2 :             delete pImpRec;
    1136             :     }
    1137             : 
    1138         626 :     sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
    1139         626 :      if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rSt ) )
    1140             :     {
    1141           2 :         SvMemoryStream aMemStream;
    1142           4 :         struct HyperLinksTable hlStr;
    1143             :         sal_uInt16 mnRawRecId,mnRawRecSize;
    1144           2 :         aMemStream.WriteUInt16( 0 ).WriteUInt16( nBufferSize );
    1145             : 
    1146             :         // copy from DFF stream to memory stream
    1147           4 :         ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
    1148           2 :         sal_uInt8* pnData = &aBuffer.front();
    1149             :         sal_uInt8 mnStreamSize;
    1150           2 :         if( pnData && rSt.Read( pnData, nBufferSize ) == nBufferSize )
    1151             :         {
    1152           2 :             aMemStream.Write( pnData, nBufferSize );
    1153           2 :             aMemStream.Seek( STREAM_SEEK_TO_END );
    1154           2 :             mnStreamSize = aMemStream.Tell();
    1155           2 :             aMemStream.Seek( STREAM_SEEK_TO_BEGIN );
    1156           2 :             bool bRet =  4 <= mnStreamSize;
    1157           2 :             if( bRet )
    1158           2 :                 aMemStream.ReadUInt16( mnRawRecId ).ReadUInt16( mnRawRecSize );
    1159           2 :             SwDocShell* pDocShell = rReader.mpDocShell;
    1160           2 :             if(pDocShell)
    1161             :             {
    1162           2 :                 SwWW8ImplReader::ReadEmbeddedData( aMemStream, pDocShell, hlStr);
    1163             :             }
    1164             :         }
    1165             : 
    1166           2 :         if (pObj && !hlStr.hLinkAddr.isEmpty())
    1167             :         {
    1168           2 :             SwMacroInfo* pInfo = GetMacroInfo( pObj, true );
    1169           2 :             if( pInfo )
    1170             :             {
    1171           2 :                 pInfo->SetShapeId( rObjData.nShapeId );
    1172           2 :                 pInfo->SetHlink( hlStr.hLinkAddr );
    1173           2 :                 if (!hlStr.tarFrm.isEmpty())
    1174           0 :                     pInfo->SetTarFrm( hlStr.tarFrm );
    1175           2 :                 OUString aNameStr = GetPropertyString( DFF_Prop_wzName, rSt );
    1176           2 :                 if (!aNameStr.isEmpty())
    1177           0 :                     pInfo->SetName( aNameStr );
    1178             :             }
    1179           2 :         }
    1180             :     }
    1181             : 
    1182         626 :     return pObj;
    1183             : }
    1184             : 
    1185             : /**
    1186             :  * Special FastSave - Attributes
    1187             :  */
    1188           0 : void SwWW8ImplReader::Read_StyleCode( sal_uInt16, const sal_uInt8* pData, short nLen )
    1189             : {
    1190           0 :     if (nLen < 0)
    1191             :     {
    1192           0 :         bCpxStyle = false;
    1193           0 :         return;
    1194             :     }
    1195           0 :     sal_uInt16 nColl = 0;
    1196           0 :     if (pWwFib->GetFIBVersion() <= ww::eWW2)
    1197           0 :         nColl = *pData;
    1198             :     else
    1199           0 :         nColl = SVBT16ToShort(pData);
    1200           0 :     if (nColl < vColl.size())
    1201             :     {
    1202           0 :         SetTxtFmtCollAndListLevel( *pPaM, vColl[nColl] );
    1203           0 :         bCpxStyle = true;
    1204             :     }
    1205             : }
    1206             : 
    1207             : /**
    1208             :  * Read_Majority is for Majority (103) and Majority50 (108)
    1209             :  */
    1210           0 : void SwWW8ImplReader::Read_Majority( sal_uInt16, const sal_uInt8* , short )
    1211             : {
    1212           0 : }
    1213             : 
    1214             : /**
    1215             :  * Stack
    1216             :  */
    1217       52372 : void SwWW8FltControlStack::NewAttr(const SwPosition& rPos,
    1218             :     const SfxPoolItem& rAttr)
    1219             : {
    1220             :     OSL_ENSURE(RES_TXTATR_FIELD != rAttr.Which(), "probably don't want to put"
    1221             :         "fields into the control stack");
    1222             :     OSL_ENSURE(RES_TXTATR_INPUTFIELD != rAttr.Which(), "probably don't want to put"
    1223             :         "input fields into the control stack");
    1224             :     OSL_ENSURE(RES_TXTATR_ANNOTATION != rAttr.Which(), "probably don't want to put"
    1225             :         "annotations into the control stack");
    1226             :     OSL_ENSURE(RES_FLTR_REDLINE != rAttr.Which(), "probably don't want to put"
    1227             :         "redlines into the control stack");
    1228       52372 :     SwFltControlStack::NewAttr(rPos, rAttr);
    1229       52372 : }
    1230             : 
    1231      104362 : SwFltStackEntry* SwWW8FltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
    1232             :     bool bTstEnde, long nHand, bool )
    1233             : {
    1234      104362 :     SwFltStackEntry *pRet = NULL;
    1235             :     // Doing a textbox, and using the control stack only as a temporary
    1236             :     // collection point for properties which will are not to be set into
    1237             :     // the real document
    1238      104362 :     if (rReader.pPlcxMan && rReader.pPlcxMan->GetDoingDrawTextBox())
    1239             :     {
    1240        2690 :         size_t nCnt = size();
    1241       12712 :         for (size_t i=0; i < nCnt; ++i)
    1242             :         {
    1243       10022 :             SwFltStackEntry& rEntry = (*this)[i];
    1244       10022 :             if (nAttrId == rEntry.pAttr->Which())
    1245             :             {
    1246         808 :                 DeleteAndDestroy(i--);
    1247         808 :                 --nCnt;
    1248             :             }
    1249             :         }
    1250             :     }
    1251             :     else // Normal case, set the attribute into the document
    1252      101672 :         pRet = SwFltControlStack::SetAttr(rPos, nAttrId, bTstEnde, nHand);
    1253      104362 :     return pRet;
    1254             : }
    1255             : 
    1256           0 : long GetListFirstLineIndent(const SwNumFmt &rFmt)
    1257             : {
    1258             :     OSL_ENSURE( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION,
    1259             :             "<GetListFirstLineIndent> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
    1260             : 
    1261           0 :     SvxAdjust eAdj = rFmt.GetNumAdjust();
    1262             :     long nReverseListIndented;
    1263           0 :     if (eAdj == SVX_ADJUST_RIGHT)
    1264           0 :         nReverseListIndented = -rFmt.GetCharTextDistance();
    1265           0 :     else if (eAdj == SVX_ADJUST_CENTER)
    1266           0 :         nReverseListIndented = rFmt.GetFirstLineOffset()/2;
    1267             :     else
    1268           0 :         nReverseListIndented = rFmt.GetFirstLineOffset();
    1269           0 :     return nReverseListIndented;
    1270             : }
    1271             : 
    1272           0 : static long lcl_GetTrueMargin(const SvxLRSpaceItem &rLR, const SwNumFmt &rFmt,
    1273             :     long &rFirstLinePos)
    1274             : {
    1275             :     OSL_ENSURE( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION,
    1276             :             "<lcl_GetTrueMargin> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
    1277             : 
    1278           0 :     const long nBodyIndent = rLR.GetTxtLeft();
    1279           0 :     const long nFirstLineDiff = rLR.GetTxtFirstLineOfst();
    1280           0 :     rFirstLinePos = nBodyIndent + nFirstLineDiff;
    1281             : 
    1282           0 :     const long nPseudoListBodyIndent = rFmt.GetAbsLSpace();
    1283           0 :     const long nReverseListIndented = GetListFirstLineIndent(rFmt);
    1284           0 :     long nExtraListIndent = nPseudoListBodyIndent + nReverseListIndented;
    1285             : 
    1286           0 :     return nExtraListIndent > 0 ? nExtraListIndent : 0;
    1287             : }
    1288             : 
    1289             : // #i103711#
    1290             : // #i105414#
    1291         184 : void SyncIndentWithList( SvxLRSpaceItem &rLR,
    1292             :                          const SwNumFmt &rFmt,
    1293             :                          const bool bFirstLineOfstSet,
    1294             :                          const bool bLeftIndentSet )
    1295             : {
    1296         184 :     if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    1297             :     {
    1298             :         long nWantedFirstLinePos;
    1299           0 :         long nExtraListIndent = lcl_GetTrueMargin(rLR, rFmt, nWantedFirstLinePos);
    1300           0 :         rLR.SetTxtLeft(nWantedFirstLinePos - nExtraListIndent);
    1301           0 :         rLR.SetTxtFirstLineOfst(0);
    1302             :     }
    1303         184 :     else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    1304             :     {
    1305         280 :         if ( !bFirstLineOfstSet && bLeftIndentSet &&
    1306          96 :              rFmt.GetFirstLineIndent() != 0 )
    1307             :         {
    1308           0 :             rLR.SetTxtFirstLineOfst( rFmt.GetFirstLineIndent() );
    1309             :         }
    1310         184 :         else if ( bFirstLineOfstSet && !bLeftIndentSet &&
    1311           0 :                   rFmt.GetIndentAt() != 0 )
    1312             :         {
    1313           0 :             rLR.SetTxtLeft( rFmt.GetIndentAt() );
    1314             :         }
    1315         184 :         else if (!bFirstLineOfstSet && !bLeftIndentSet )
    1316             :         {
    1317          10 :             if ( rFmt.GetFirstLineIndent() != 0 )
    1318             :             {
    1319          10 :                 rLR.SetTxtFirstLineOfst( rFmt.GetFirstLineIndent() );
    1320             :             }
    1321          10 :             if ( rFmt.GetIndentAt() != 0 )
    1322             :             {
    1323          10 :                 rLR.SetTxtLeft( rFmt.GetIndentAt() );
    1324             :             }
    1325             :         }
    1326             :     }
    1327         184 : }
    1328             : 
    1329        2204 : const SwNumFmt* SwWW8FltControlStack::GetNumFmtFromStack(const SwPosition &rPos,
    1330             :     const SwTxtNode &rTxtNode)
    1331             : {
    1332        2204 :     const SwNumFmt *pRet = 0;
    1333        2204 :     const SfxPoolItem *pItem = GetStackAttr(rPos, RES_FLTR_NUMRULE);
    1334        2204 :     if (pItem && rTxtNode.GetNumRule())
    1335             :     {
    1336           0 :         if (rTxtNode.IsCountedInList())
    1337             :         {
    1338           0 :             OUString sName(((SfxStringItem*)pItem)->GetValue());
    1339           0 :             const SwNumRule *pRule = pDoc->FindNumRulePtr(sName);
    1340           0 :             if (pRule)
    1341           0 :                 pRet = GetNumFmtFromSwNumRuleLevel(*pRule, rTxtNode.GetActualListLevel());
    1342             :         }
    1343             :     }
    1344        2204 :     return pRet;
    1345             : }
    1346             : 
    1347      101360 : sal_Int32 SwWW8FltControlStack::GetCurrAttrCP() const
    1348             : {
    1349      101360 :     return rReader.GetCurrAttrCP();
    1350             : }
    1351             : 
    1352       45148 : bool SwWW8FltControlStack::IsParaEndInCPs(sal_Int32 nStart,sal_Int32 nEnd,bool bSdOD) const
    1353             : {
    1354       45148 :     return rReader.IsParaEndInCPs(nStart,nEnd,bSdOD);
    1355             : }
    1356             : 
    1357             : /**
    1358             :  * Clear the para end position recorded in reader intermittently
    1359             :  * for the least impact on loading performance.
    1360             :  */
    1361         274 : void SwWW8FltControlStack::ClearParaEndPosition()
    1362             : {
    1363         274 :     if ( !empty() )
    1364         274 :         return;
    1365             : 
    1366         274 :     rReader.ClearParaEndPosition();
    1367             : }
    1368             : 
    1369         412 : bool SwWW8FltControlStack::CheckSdOD(sal_Int32 nStart,sal_Int32 nEnd)
    1370             : {
    1371         412 :     return rReader.IsParaEndInCPs(nStart,nEnd);
    1372             : }
    1373             : 
    1374          48 : void SwWW8ReferencedFltEndStack::SetAttrInDoc( const SwPosition& rTmpPos,
    1375             :                                                SwFltStackEntry& rEntry )
    1376             : {
    1377          48 :     switch( rEntry.pAttr->Which() )
    1378             :     {
    1379             :     case RES_FLTR_BOOKMARK:
    1380             :         {
    1381             :             // suppress insertion of bookmark, which is recognized as an internal bookmark used for table-of-content
    1382             :             // and which is not referenced.
    1383          48 :             bool bInsertBookmarkIntoDoc = true;
    1384             : 
    1385          48 :             SwFltBookmark* pFltBookmark = dynamic_cast<SwFltBookmark*>(rEntry.pAttr);
    1386          48 :             if ( pFltBookmark != 0 && pFltBookmark->IsTOCBookmark() )
    1387             :             {
    1388           0 :                 const OUString& rName = pFltBookmark->GetName();
    1389           0 :                 ::std::set< OUString, SwWW8::ltstr >::const_iterator aResult = aReferencedTOCBookmarks.find(rName);
    1390           0 :                 if ( aResult == aReferencedTOCBookmarks.end() )
    1391             :                 {
    1392           0 :                     bInsertBookmarkIntoDoc = false;
    1393             :                 }
    1394             :             }
    1395          48 :             if ( bInsertBookmarkIntoDoc )
    1396             :             {
    1397          48 :                 SwFltEndStack::SetAttrInDoc( rTmpPos, rEntry );
    1398             :             }
    1399          48 :             break;
    1400             :         }
    1401             :     default:
    1402           0 :         SwFltEndStack::SetAttrInDoc( rTmpPos, rEntry );
    1403           0 :         break;
    1404             :     }
    1405             : 
    1406          48 : }
    1407             : 
    1408       48504 : void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
    1409             :     SwFltStackEntry& rEntry)
    1410             : {
    1411       48504 :     switch (rEntry.pAttr->Which())
    1412             :     {
    1413             :         case RES_LR_SPACE:
    1414             :             {
    1415             :                 /*
    1416             :                  Loop over the affected nodes and
    1417             :                  a) convert the word style absolute indent to indent relative
    1418             :                     to any numbering indent active on the nodes
    1419             :                  b) adjust the writer style tabstops relative to the old
    1420             :                     paragraph indent to be relative to the new paragraph indent
    1421             :                 */
    1422             :                 using namespace sw::util;
    1423        3342 :                 SwPaM aRegion(rTmpPos);
    1424        3342 :                 if (rEntry.MakeRegion(pDoc, aRegion, false))
    1425             :                 {
    1426        2204 :                     SvxLRSpaceItem aNewLR( *(SvxLRSpaceItem*)rEntry.pAttr );
    1427        2204 :                     sal_uLong nStart = aRegion.Start()->nNode.GetIndex();
    1428        2204 :                     sal_uLong nEnd   = aRegion.End()->nNode.GetIndex();
    1429        4408 :                     for(; nStart <= nEnd; ++nStart)
    1430             :                     {
    1431        2204 :                         SwNode* pNode = pDoc->GetNodes()[ nStart ];
    1432        2204 :                         if (!pNode || !pNode->IsTxtNode())
    1433         210 :                             continue;
    1434             : 
    1435        2204 :                         SwCntntNode* pNd = (SwCntntNode*)pNode;
    1436        2204 :                         SvxLRSpaceItem aOldLR = (const SvxLRSpaceItem&)pNd->GetAttr(RES_LR_SPACE);
    1437             : 
    1438        2204 :                         SwTxtNode *pTxtNode = (SwTxtNode*)pNode;
    1439             : 
    1440        2204 :                         const SwNumFmt *pNum = 0;
    1441        2204 :                         pNum = GetNumFmtFromStack( *aRegion.GetPoint(), *pTxtNode );
    1442        2204 :                         if (!pNum)
    1443             :                         {
    1444        2204 :                             pNum = GetNumFmtFromTxtNode(*pTxtNode);
    1445             :                         }
    1446             : 
    1447        2204 :                         if ( pNum )
    1448             :                         {
    1449             :                             // #i103711#
    1450             :                             const bool bFirstLineIndentSet =
    1451         368 :                                 ( rReader.maTxtNodesHavingFirstLineOfstSet.end() !=
    1452         552 :                                     rReader.maTxtNodesHavingFirstLineOfstSet.find( pNode ) );
    1453             :                             // #i105414#
    1454             :                             const bool bLeftIndentSet =
    1455         368 :                                 (  rReader.maTxtNodesHavingLeftIndentSet.end() !=
    1456         552 :                                     rReader.maTxtNodesHavingLeftIndentSet.find( pNode ) );
    1457             :                             SyncIndentWithList( aNewLR, *pNum,
    1458             :                                                 bFirstLineIndentSet,
    1459         184 :                                                 bLeftIndentSet );
    1460             :                         }
    1461             : 
    1462        2204 :                         if (aNewLR == aOldLR)
    1463         210 :                             continue;
    1464             : 
    1465        1994 :                         pNd->SetAttr(aNewLR);
    1466             : 
    1467        4198 :                     }
    1468        3342 :                 }
    1469             :             }
    1470        3342 :             break;
    1471             : 
    1472             :         case RES_TXTATR_FIELD:
    1473             :             OSL_ENSURE(false, "What is a field doing in the control stack,"
    1474             :                 "probably should have been in the endstack");
    1475           0 :             break;
    1476             : 
    1477             :         case RES_TXTATR_ANNOTATION:
    1478             :             OSL_ENSURE(false, "What is a annotation doing in the control stack,"
    1479             :                 "probably should have been in the endstack");
    1480           0 :             break;
    1481             : 
    1482             :         case RES_TXTATR_INPUTFIELD:
    1483             :             OSL_ENSURE(false, "What is a input field doing in the control stack,"
    1484             :                 "probably should have been in the endstack");
    1485           0 :             break;
    1486             : 
    1487             :         case RES_TXTATR_INETFMT:
    1488             :             {
    1489          14 :                 SwPaM aRegion(rTmpPos);
    1490          14 :                 if (rEntry.MakeRegion(pDoc, aRegion, false))
    1491             :                 {
    1492             :                     SwFrmFmt *pFrm;
    1493             :                     // If we have just one single inline graphic then
    1494             :                     // don't insert a field for the single frame, set
    1495             :                     // the frames hyperlink field attribute directly.
    1496          14 :                     if (0 != (pFrm = rReader.ContainsSingleInlineGraphic(aRegion)))
    1497             :                     {
    1498             :                         const SwFmtINetFmt *pAttr = (const SwFmtINetFmt *)
    1499           0 :                             rEntry.pAttr;
    1500           0 :                         SwFmtURL aURL;
    1501           0 :                         aURL.SetURL(pAttr->GetValue(), false);
    1502           0 :                         aURL.SetTargetFrameName(pAttr->GetTargetFrame());
    1503           0 :                         pFrm->SetFmtAttr(aURL);
    1504             :                     }
    1505             :                     else
    1506             :                     {
    1507          14 :                         pDoc->getIDocumentContentOperations().InsertPoolItem(aRegion, *rEntry.pAttr, 0);
    1508             :                     }
    1509          14 :                 }
    1510             :             }
    1511          14 :             break;
    1512             :         default:
    1513       45148 :             SwFltControlStack::SetAttrInDoc(rTmpPos, rEntry);
    1514       45148 :             break;
    1515             :     }
    1516       48504 : }
    1517             : 
    1518       34850 : const SfxPoolItem* SwWW8FltControlStack::GetFmtAttr(const SwPosition& rPos,
    1519             :     sal_uInt16 nWhich)
    1520             : {
    1521       34850 :     const SfxPoolItem *pItem = GetStackAttr(rPos, nWhich);
    1522       34850 :     if (!pItem)
    1523             :     {
    1524       26832 :         SwCntntNode const*const pNd = rPos.nNode.GetNode().GetCntntNode();
    1525       26832 :         if (!pNd)
    1526           0 :             pItem = &pDoc->GetAttrPool().GetDefaultItem(nWhich);
    1527             :         else
    1528             :         {
    1529             :             /*
    1530             :             If we're hunting for the indent on a paragraph and need to use the
    1531             :             parent style indent, then return the indent in msword format, and
    1532             :             not writer format, because that's the style that the filter works
    1533             :             in (naturally)
    1534             :             */
    1535       26832 :             if (nWhich == RES_LR_SPACE)
    1536             :             {
    1537        1790 :                 SfxItemState eState = SfxItemState::DEFAULT;
    1538        1790 :                 if (const SfxItemSet *pSet = pNd->GetpSwAttrSet())
    1539         634 :                     eState = pSet->GetItemState(RES_LR_SPACE, false);
    1540        1790 :                 if (eState != SfxItemState::SET && rReader.nAktColl < rReader.vColl.size())
    1541        1790 :                     pItem = &(rReader.vColl[rReader.nAktColl].maWordLR);
    1542             :             }
    1543             : 
    1544             :             /*
    1545             :             If we're hunting for a character property, try and exact position
    1546             :             within the text node for lookup
    1547             :             */
    1548       26832 :             if (pNd->IsTxtNode())
    1549             :             {
    1550       26832 :                 const sal_Int32 nPos = rPos.nContent.GetIndex();
    1551       26832 :                 SfxItemSet aSet(pDoc->GetAttrPool(), nWhich, nWhich);
    1552       26832 :                 if (static_cast<const SwTxtNode*>(pNd)->GetAttr(aSet, nPos, nPos))
    1553       18632 :                     pItem = aSet.GetItem(nWhich);
    1554             :             }
    1555             : 
    1556       26832 :             if (!pItem)
    1557        6724 :                 pItem = &pNd->GetAttr(nWhich);
    1558             :         }
    1559             :     }
    1560       34850 :     return pItem;
    1561             : }
    1562             : 
    1563       40202 : const SfxPoolItem* SwWW8FltControlStack::GetStackAttr(const SwPosition& rPos,
    1564             :     sal_uInt16 nWhich)
    1565             : {
    1566       40202 :     SwFltPosition aFltPos(rPos);
    1567             : 
    1568       40202 :     size_t nSize = size();
    1569      760676 :     while (nSize)
    1570             :     {
    1571      689768 :         const SwFltStackEntry& rEntry = (*this)[ --nSize ];
    1572      689768 :         if (rEntry.pAttr->Which() == nWhich)
    1573             :         {
    1574       54456 :             if ( (rEntry.bOpen) ||
    1575             :                  (
    1576       35464 :                   (rEntry.m_aMkPos.m_nNode <= aFltPos.m_nNode) &&
    1577       34608 :                   (rEntry.m_aPtPos.m_nNode >= aFltPos.m_nNode) &&
    1578       33726 :                   (rEntry.m_aMkPos.m_nCntnt <= aFltPos.m_nCntnt) &&
    1579       16850 :                   (rEntry.m_aPtPos.m_nCntnt > aFltPos.m_nCntnt)
    1580             :                  )
    1581             :                )
    1582             :                 /*
    1583             :                  * e.g. half-open range [0-3) so asking for properties at 3
    1584             :                  * means props that end at 3 are not included
    1585             :                  */
    1586             :             {
    1587        9496 :                 return rEntry.pAttr;
    1588             :             }
    1589             :         }
    1590             :     }
    1591       30706 :     return 0;
    1592             : }
    1593             : 
    1594           0 : bool SwWW8FltRefStack::IsFtnEdnBkmField(
    1595             :     const SwFmtFld& rFmtFld,
    1596             :     sal_uInt16& rBkmNo)
    1597             : {
    1598           0 :     const SwField* pFld = rFmtFld.GetField();
    1599             :     sal_uInt16 nSubType;
    1600           0 :     if(pFld && (RES_GETREFFLD == pFld->Which())
    1601           0 :         && ((REF_FOOTNOTE == (nSubType = pFld->GetSubType())) || (REF_ENDNOTE  == nSubType))
    1602           0 :         && !((SwGetRefField*)pFld)->GetSetRefName().isEmpty())
    1603             :     {
    1604           0 :         const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    1605             :         IDocumentMarkAccess::const_iterator_t ppBkmk =
    1606           0 :             pMarkAccess->findMark( ((SwGetRefField*)pFld)->GetSetRefName() );
    1607           0 :         if(ppBkmk != pMarkAccess->getAllMarksEnd())
    1608             :         {
    1609             :             // find Sequence No of corresponding Foot-/Endnote
    1610           0 :             rBkmNo = ppBkmk - pMarkAccess->getAllMarksBegin();
    1611           0 :             return true;
    1612             :         }
    1613             :     }
    1614           0 :     return false;
    1615             : }
    1616             : 
    1617           0 : void SwWW8FltRefStack::SetAttrInDoc(const SwPosition& rTmpPos,
    1618             :     SwFltStackEntry& rEntry)
    1619             : {
    1620           0 :     switch (rEntry.pAttr->Which())
    1621             :     {
    1622             :         /*
    1623             :         Look up these in our lists of bookmarks that were changed to
    1624             :         variables, and replace the ref field with a var field, otherwise
    1625             :         do normal (?) strange stuff
    1626             :         */
    1627             :         case RES_TXTATR_FIELD:
    1628             :         case RES_TXTATR_ANNOTATION:
    1629             :         case RES_TXTATR_INPUTFIELD:
    1630             :         {
    1631           0 :             SwNodeIndex aIdx(rEntry.m_aMkPos.m_nNode, 1);
    1632           0 :             SwPaM aPaM(aIdx, rEntry.m_aMkPos.m_nCntnt);
    1633             : 
    1634           0 :             SwFmtFld& rFmtFld   = *(SwFmtFld*)rEntry.pAttr;
    1635           0 :             SwField* pFld = rFmtFld.GetField();
    1636             : 
    1637           0 :             if (!RefToVar(pFld, rEntry))
    1638             :             {
    1639             :                 sal_uInt16 nBkmNo;
    1640           0 :                 if( IsFtnEdnBkmField(rFmtFld, nBkmNo) )
    1641             :                 {
    1642           0 :                     ::sw::mark::IMark const * const pMark = (pDoc->getIDocumentMarkAccess()->getAllMarksBegin() + nBkmNo)->get();
    1643             : 
    1644           0 :                     const SwPosition& rBkMrkPos = pMark->GetMarkPos();
    1645             : 
    1646           0 :                     SwTxtNode* pTxt = rBkMrkPos.nNode.GetNode().GetTxtNode();
    1647           0 :                     if( pTxt && rBkMrkPos.nContent.GetIndex() )
    1648             :                     {
    1649             :                         SwTxtAttr* const pFtn = pTxt->GetTxtAttrForCharAt(
    1650           0 :                             rBkMrkPos.nContent.GetIndex()-1, RES_TXTATR_FTN );
    1651           0 :                         if( pFtn )
    1652             :                         {
    1653           0 :                             sal_uInt16 nRefNo = ((SwTxtFtn*)pFtn)->GetSeqRefNo();
    1654             : 
    1655           0 :                             ((SwGetRefField*)pFld)->SetSeqNo( nRefNo );
    1656             : 
    1657           0 :                             if( pFtn->GetFtn().IsEndNote() )
    1658           0 :                                 ((SwGetRefField*)pFld)->SetSubType(REF_ENDNOTE);
    1659             :                         }
    1660             :                     }
    1661             :                 }
    1662             :             }
    1663             : 
    1664           0 :             pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, *rEntry.pAttr, 0);
    1665           0 :             MoveAttrs(*aPaM.GetPoint());
    1666             :         }
    1667           0 :         break;
    1668             :         case RES_FLTR_TOX:
    1669           0 :             SwFltEndStack::SetAttrInDoc(rTmpPos, rEntry);
    1670           0 :             break;
    1671             :         default:
    1672             :         case RES_FLTR_BOOKMARK:
    1673             :             OSL_ENSURE(false, "EndStck used with non field, not what we want");
    1674           0 :             SwFltEndStack::SetAttrInDoc(rTmpPos, rEntry);
    1675           0 :             break;
    1676             :     }
    1677           0 : }
    1678             : 
    1679             : /*
    1680             :  For styles we will do our tabstop arithmetic in word style and adjust them to
    1681             :  writer style after all the styles have been finished and the dust settles as
    1682             :  to what affects what.
    1683             : 
    1684             :  For explicit attributes we turn the adjusted writer tabstops back into 0 based
    1685             :  word indexes and we'll turn them back into writer indexes when setting them
    1686             :  into the document. If explicit left indent exist which affects them, then this
    1687             :  is handled when the explicit left indent is set into the document
    1688             : */
    1689         984 : void SwWW8ImplReader::Read_Tab(sal_uInt16 , const sal_uInt8* pData, short nLen)
    1690             : {
    1691         984 :     if (nLen < 0)
    1692             :     {
    1693         388 :         pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_PARATR_TABSTOP);
    1694        1372 :         return;
    1695             :     }
    1696             : 
    1697         596 :     sal_uInt8 nDel = (nLen > 0) ? pData[0] : 0;
    1698         596 :     const sal_uInt8* pDel = pData + 1;                   // Del - Array
    1699             : 
    1700         596 :     sal_uInt8 nIns = (nLen > nDel*2+1) ? pData[nDel*2+1] : 0;
    1701         596 :     const sal_uInt8* pIns = pData + 2*nDel + 2;          // Ins - Array
    1702             : 
    1703         596 :     short nRequiredLength = 2 + 2*nDel + 2*nIns + 1*nIns;
    1704         596 :     if (nRequiredLength > nLen)
    1705             :     {
    1706             :         // would require more data than available to describe!
    1707             :         // discard invalid record
    1708           0 :         nIns = 0;
    1709           0 :         nDel = 0;
    1710             :     }
    1711             : 
    1712         596 :     WW8_TBD* pTyp = (WW8_TBD*)(pData + 2*nDel + 2*nIns + 2); // Type Array
    1713             : 
    1714         596 :     SvxTabStopItem aAttr(0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP);
    1715             : 
    1716         596 :     const SwTxtFmtColl* pSty = 0;
    1717             :     sal_uInt16 nTabBase;
    1718         596 :     if (pAktColl && nAktColl < vColl.size()) // StyleDef
    1719             :     {
    1720         208 :         nTabBase = vColl[nAktColl].nBase;
    1721         208 :         if (nTabBase < vColl.size())  // Based On
    1722         194 :             pSty = (const SwTxtFmtColl*)vColl[nTabBase].pFmt;
    1723             :     }
    1724             :     else
    1725             :     { // Text
    1726         388 :         nTabBase = nAktColl;
    1727         388 :         if (nAktColl < vColl.size())
    1728         388 :             pSty = (const SwTxtFmtColl*)vColl[nAktColl].pFmt;
    1729             :         //TODO: figure out else here
    1730             :     }
    1731             : 
    1732         596 :     bool bFound = false;
    1733        1192 :     ::boost::unordered_set<size_t> aLoopWatch;
    1734        1892 :     while (pSty && !bFound)
    1735             :     {
    1736             :         const SfxPoolItem* pTabs;
    1737         700 :         bFound = pSty->GetAttrSet().GetItemState(RES_PARATR_TABSTOP, false,
    1738         700 :             &pTabs) == SfxItemState::SET;
    1739         700 :         if( bFound )
    1740          74 :             aAttr = *((const SvxTabStopItem*)pTabs);
    1741             :         else
    1742             :         {
    1743         626 :             sal_uInt16 nOldTabBase = nTabBase;
    1744             :             // If based on another
    1745         626 :             if (nTabBase < vColl.size())
    1746         626 :                 nTabBase = vColl[nTabBase].nBase;
    1747             : 
    1748         626 :             if (
    1749         798 :                     nTabBase < vColl.size() &&
    1750         798 :                     nOldTabBase != nTabBase &&
    1751             :                     nTabBase != ww::stiNil
    1752             :                )
    1753             :             {
    1754             :                 // #i61789: Stop searching when next style is the same as the
    1755             :                 // current one (prevent loop)
    1756         172 :                 aLoopWatch.insert(reinterpret_cast<size_t>(pSty));
    1757         172 :                 if (nTabBase < vColl.size())
    1758         172 :                     pSty = (const SwTxtFmtColl*)vColl[nTabBase].pFmt;
    1759             :                 //TODO figure out the else branch
    1760             : 
    1761         172 :                 if (aLoopWatch.find(reinterpret_cast<size_t>(pSty)) !=
    1762             :                     aLoopWatch.end())
    1763           0 :                     pSty = 0;
    1764             :             }
    1765             :             else
    1766         454 :                 pSty = 0; // Give up on the search
    1767             :         }
    1768             :     }
    1769             : 
    1770         596 :     SvxTabStop aTabStop;
    1771         932 :     for (short i=0; i < nDel; ++i)
    1772             :     {
    1773         336 :         sal_uInt16 nPos = aAttr.GetPos(SVBT16ToShort(pDel + i*2));
    1774         336 :         if( nPos != SVX_TAB_NOTFOUND )
    1775         116 :             aAttr.Remove( nPos, 1 );
    1776             :     }
    1777             : 
    1778        1862 :     for (short i=0; i < nIns; ++i)
    1779             :     {
    1780        1266 :         short nPos = SVBT16ToShort(pIns + i*2);
    1781        1266 :         aTabStop.GetTabPos() = nPos;
    1782        1266 :         switch( pTyp[i].aBits1 & 0x7 ) // pTyp[i].jc
    1783             :         {
    1784             :             case 0:
    1785         658 :                 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
    1786         658 :                 break;
    1787             :             case 1:
    1788         204 :                 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER;
    1789         204 :                 break;
    1790             :             case 2:
    1791         286 :                 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
    1792         286 :                 break;
    1793             :             case 3:
    1794           0 :                 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL;
    1795           0 :                 break;
    1796             :             case 4:
    1797           0 :                 continue; // Ignore Bar
    1798             :         }
    1799             : 
    1800        1266 :         switch( pTyp[i].aBits1 >> 3 & 0x7 )
    1801             :         {
    1802             :             case 0:
    1803        1242 :                 aTabStop.GetFill() = ' ';
    1804        1242 :                 break;
    1805             :             case 1:
    1806          24 :                 aTabStop.GetFill() = '.';
    1807          24 :                 break;
    1808             :             case 2:
    1809           0 :                 aTabStop.GetFill() = '-';
    1810           0 :                 break;
    1811             :             case 3:
    1812             :             case 4:
    1813           0 :                 aTabStop.GetFill() = '_';
    1814           0 :                 break;
    1815             :         }
    1816             : 
    1817        1266 :         sal_uInt16 nPos2 = aAttr.GetPos( nPos );
    1818        1266 :         if (nPos2 != SVX_TAB_NOTFOUND)
    1819           0 :             aAttr.Remove(nPos2, 1); // Or else Insert() refuses
    1820        1266 :         aAttr.Insert(aTabStop);
    1821             :     }
    1822             : 
    1823         596 :     if (nIns || nDel)
    1824         596 :         NewAttr(aAttr);
    1825             :     else
    1826             :     {
    1827             :         // Here we have a tab definition which inserts no extra tabs, or deletes
    1828             :         // no existing tabs. An older version of writer is probably the creater
    1829             :         // of the document  :-( . So if we are importing a style we can just
    1830             :         // ignore it. But if we are importing into text we cannot as during
    1831             :         // text SwWW8ImplReader::Read_Tab is called at the begin and end of
    1832             :         // the range the attrib affects, and ignoring it would upset the
    1833             :         // balance
    1834           0 :         if (!pAktColl) // not importing into a style
    1835             :         {
    1836             :             using namespace sw::util;
    1837             :             SvxTabStopItem aOrig = pSty ?
    1838           0 :             ItemGet<SvxTabStopItem>(*pSty, RES_PARATR_TABSTOP) :
    1839           0 :             DefaultItemGet<SvxTabStopItem>(rDoc, RES_PARATR_TABSTOP);
    1840           0 :             NewAttr(aOrig);
    1841             :         }
    1842         596 :     }
    1843             : }
    1844             : 
    1845             : /**
    1846             :  * DOP
    1847             : */
    1848         186 : void SwWW8ImplReader::ImportDop()
    1849             : {
    1850             :     // correct the LastPrinted date in DocumentProperties
    1851             :     uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    1852         186 :         mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
    1853             :     uno::Reference<document::XDocumentProperties> xDocuProps(
    1854         372 :         xDPS->getDocumentProperties());
    1855             :     OSL_ENSURE(xDocuProps.is(), "DocumentProperties is null");
    1856         186 :     if (xDocuProps.is())
    1857             :     {
    1858             :         DateTime aLastPrinted(
    1859         186 :             msfilter::util::DTTM2DateTime(pWDop->dttmLastPrint));
    1860         186 :        ::util::DateTime uDT(aLastPrinted.GetNanoSec(),
    1861         372 :             aLastPrinted.GetSec(), aLastPrinted.GetMin(),
    1862         372 :             aLastPrinted.GetHour(), aLastPrinted.GetDay(),
    1863        1116 :             aLastPrinted.GetMonth(), aLastPrinted.GetYear(), false);
    1864         186 :         xDocuProps->setPrintDate(uDT);
    1865             :     }
    1866             : 
    1867             :     // COMPATIBILITY FLAGS START
    1868             : 
    1869             :     // #i78951# - remember the unknown compatibility options
    1870             :     // so as to export them out
    1871         186 :     rDoc.getIDocumentSettingAccess().Setn32DummyCompatibilityOptions1( pWDop->GetCompatibilityOptions());
    1872         186 :     rDoc.getIDocumentSettingAccess().Setn32DummyCompatibilityOptions2( pWDop->GetCompatibilityOptions2());
    1873             : 
    1874             :     // The distance between two paragraphs is the sum of the bottom distance of
    1875             :     // the first paragraph and the top distance of the second one
    1876         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::PARA_SPACE_MAX, pWDop->fDontUseHTMLAutoSpacing);
    1877         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true );
    1878             :     // move tabs on alignment
    1879         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::TAB_COMPAT, true);
    1880             :     // #i24363# tab stops relative to indent
    1881         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT, false);
    1882             : 
    1883             :     // Import Default Tabs
    1884         186 :     long nDefTabSiz = pWDop->dxaTab;
    1885         186 :     if( nDefTabSiz < 56 )
    1886           2 :         nDefTabSiz = 709;
    1887             : 
    1888             :     // We want exactly one DefaultTab
    1889         372 :     SvxTabStopItem aNewTab( 1, sal_uInt16(nDefTabSiz), SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
    1890         186 :     ((SvxTabStop&)aNewTab[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
    1891             : 
    1892         186 :     rDoc.GetAttrPool().SetPoolDefaultItem( aNewTab );
    1893             : 
    1894             :     // Import zoom factor
    1895         186 :     if (pWDop->wScaleSaved)
    1896             :     {
    1897         182 :         uno::Sequence<beans::PropertyValue> aViewProps(3);
    1898         182 :         aViewProps[0].Name = "ZoomFactor";
    1899         182 :         aViewProps[0].Value <<= sal_Int16(pWDop->wScaleSaved);
    1900         182 :         aViewProps[1].Name = "VisibleBottom";
    1901         182 :         aViewProps[1].Value <<= sal_Int32(0);
    1902         182 :         aViewProps[2].Name = "ZoomType";
    1903         182 :         aViewProps[2].Value <<= sal_Int16(0);
    1904             : 
    1905         364 :         uno::Reference< uno::XComponentContext > xComponentContext(comphelper::getProcessComponentContext());
    1906         364 :         uno::Reference<container::XIndexContainer> xBox = document::IndexedPropertyValues::create(xComponentContext);
    1907         182 :         xBox->insertByIndex(sal_Int32(0), uno::makeAny(aViewProps));
    1908         364 :         uno::Reference<container::XIndexAccess> xIndexAccess(xBox, uno::UNO_QUERY);
    1909         364 :         uno::Reference<document::XViewDataSupplier> xViewDataSupplier(mpDocShell->GetModel(), uno::UNO_QUERY);
    1910         364 :         xViewDataSupplier->setViewData(xIndexAccess);
    1911             :     }
    1912             : 
    1913         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, !pWDop->fUsePrinterMetrics);
    1914         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true);
    1915         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true );
    1916         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::ADD_EXT_LEADING, !pWDop->fNoLeading);
    1917         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::OLD_NUMBERING, false);
    1918         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false); // #i47448#
    1919         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, !pWDop->fExpShRtn); // #i49277#, #i56856#
    1920         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false);  // #i53199#
    1921         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::OLD_LINE_SPACING, false);
    1922             : 
    1923             :     // #i25901# - set new compatibility option
    1924             :     //      'Add paragraph and table spacing at bottom of table cells'
    1925         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, true);
    1926             : 
    1927             :     // #i11860# - set new compatibility option
    1928             :     //      'Use former object positioning' to <sal_False>
    1929         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, false);
    1930             : 
    1931             :     // #i27767# - set new compatibility option
    1932             :     //      'Conder Wrapping mode when positioning object' to <sal_True>
    1933         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true);
    1934             : 
    1935         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false); // #i13832#, #i24135#
    1936             : 
    1937         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::TABLE_ROW_KEEP, true); //SetTableRowKeep( true );
    1938             : 
    1939         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true); // #i3952#
    1940             : 
    1941         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::INVERT_BORDER_SPACING, true);
    1942         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::COLLAPSE_EMPTY_CELL_PARA, true);
    1943         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::TAB_OVERFLOW, true);
    1944         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::UNBREAKABLE_NUMBERINGS, true);
    1945         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::CLIPPED_PICTURES, true);
    1946         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::TAB_OVER_MARGIN, true);
    1947         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::SURROUND_TEXT_WRAP_SMALL, true);
    1948         186 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::PROP_LINE_SPACING_SHRINKS_FIRST_LINE, true);
    1949             : 
    1950             :     // COMPATIBILITY FLAGS END
    1951             : 
    1952             :     // Import magic doptypography information, if its there
    1953         186 :     if (pWwFib->nFib > 105)
    1954         182 :         ImportDopTypography(pWDop->doptypography);
    1955             : 
    1956             :     // disable form design mode to be able to use imported controls directly
    1957             :     // #i31239# always disable form design mode, not only in protected docs
    1958             :     {
    1959             :         using namespace com::sun::star;
    1960             : 
    1961             :         uno::Reference<lang::XComponent> xModelComp(mpDocShell->GetModel(),
    1962         186 :            uno::UNO_QUERY);
    1963             :         uno::Reference<beans::XPropertySet> xDocProps(xModelComp,
    1964         372 :            uno::UNO_QUERY);
    1965         186 :         if (xDocProps.is())
    1966             :         {
    1967             :             uno::Reference<beans::XPropertySetInfo> xInfo =
    1968         186 :                 xDocProps->getPropertySetInfo();
    1969         186 :             bool bValue = false;
    1970         186 :             if (xInfo.is())
    1971             :             {
    1972         186 :                 if (xInfo->hasPropertyByName("ApplyFormDesignMode"))
    1973             :                 {
    1974         186 :                     xDocProps->setPropertyValue("ApplyFormDesignMode", css::uno::makeAny(bValue));
    1975             :                 }
    1976         186 :             }
    1977         186 :         }
    1978             :     }
    1979             : 
    1980             :     // Still allow editing of form fields.
    1981         186 :     if (!pWDop->fProtEnabled)
    1982         182 :         mpDocShell->SetModifyPasswordHash(pWDop->lKeyProtDoc);
    1983             : 
    1984         186 :     const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
    1985         186 :     if (rOpt.IsUseEnhancedFields())
    1986         372 :         rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::PROTECT_FORM, pWDop->fProtEnabled );
    1987         186 : }
    1988             : 
    1989         182 : void SwWW8ImplReader::ImportDopTypography(const WW8DopTypography &rTypo)
    1990             : {
    1991             :     using namespace com::sun::star;
    1992         182 :     switch (rTypo.iLevelOfKinsoku)
    1993             :     {
    1994             :         case 2: // custom
    1995             :             {
    1996             :                 i18n::ForbiddenCharacters aForbidden(rTypo.rgxchFPunct,
    1997           0 :                     rTypo.rgxchLPunct);
    1998           0 :                 rDoc.getIDocumentSettingAccess().setForbiddenCharacters(rTypo.GetConvertedLang(),
    1999           0 :                         aForbidden);
    2000             :                 // Obviously cannot set the standard level 1 for japanese, so
    2001             :                 // bail out now while we can.
    2002           0 :                 if (rTypo.GetConvertedLang() == LANGUAGE_JAPANESE)
    2003         182 :                     return;
    2004             :             }
    2005           0 :             break;
    2006             :         default:
    2007         182 :             break;
    2008             :     }
    2009             : 
    2010             :     /*
    2011             :     This MS hack means that level 2 of japanese is not in operation, so we put
    2012             :     in what we know are the MS defaults, there is a complementary reverse
    2013             :     hack in the writer. Its our default as well, but we can set it anyway
    2014             :     as a flag for later.
    2015             :     */
    2016         182 :     if (!rTypo.reserved2)
    2017             :     {
    2018             :         i18n::ForbiddenCharacters aForbidden(WW8DopTypography::GetJapanNotBeginLevel1(),
    2019         144 :             WW8DopTypography::GetJapanNotEndLevel1());
    2020         144 :         rDoc.getIDocumentSettingAccess().setForbiddenCharacters(LANGUAGE_JAPANESE,aForbidden);
    2021             :     }
    2022             : 
    2023         182 :     rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION, rTypo.fKerningPunct);
    2024         182 :     rDoc.getIDocumentSettingAccess().setCharacterCompressionType(static_cast<SwCharCompressType>(rTypo.iJustification));
    2025             : }
    2026             : 
    2027             : /**
    2028             :  * Footnotes and Endnotes
    2029             :  */
    2030         488 : WW8ReaderSave::WW8ReaderSave(SwWW8ImplReader* pRdr ,WW8_CP nStartCp) :
    2031         488 :     maTmpPos(*pRdr->pPaM->GetPoint()),
    2032             :     mpOldStck(pRdr->pCtrlStck),
    2033             :     mpOldAnchorStck(pRdr->pAnchorStck),
    2034             :     mpOldRedlines(pRdr->mpRedlineStack),
    2035             :     mpOldPlcxMan(pRdr->pPlcxMan),
    2036             :     mpWFlyPara(pRdr->pWFlyPara),
    2037             :     mpSFlyPara(pRdr->pSFlyPara),
    2038             :     mpPreviousNumPaM(pRdr->pPreviousNumPaM),
    2039             :     mpPrevNumRule(pRdr->pPrevNumRule),
    2040             :     mpTableDesc(pRdr->pTableDesc),
    2041             :     mnInTable(pRdr->nInTable),
    2042             :     mnAktColl(pRdr->nAktColl),
    2043             :     mcSymbol(pRdr->cSymbol),
    2044             :     mbIgnoreText(pRdr->bIgnoreText),
    2045             :     mbSymbol(pRdr->bSymbol),
    2046             :     mbHdFtFtnEdn(pRdr->bHdFtFtnEdn),
    2047             :     mbTxbxFlySection(pRdr->bTxbxFlySection),
    2048             :     mbAnl(pRdr->bAnl),
    2049             :     mbInHyperlink(pRdr->bInHyperlink),
    2050             :     mbPgSecBreak(pRdr->bPgSecBreak),
    2051             :     mbWasParaEnd(pRdr->bWasParaEnd),
    2052             :     mbHasBorder(pRdr->bHasBorder),
    2053         976 :     mbFirstPara(pRdr->bFirstPara)
    2054             : {
    2055         488 :     pRdr->bSymbol = false;
    2056         488 :     pRdr->bHdFtFtnEdn = true;
    2057             :     pRdr->bTxbxFlySection = pRdr->bAnl = pRdr->bPgSecBreak = pRdr->bWasParaEnd
    2058         488 :         = pRdr->bHasBorder = false;
    2059         488 :     pRdr->bFirstPara = true;
    2060         488 :     pRdr->nInTable = 0;
    2061         488 :     pRdr->pWFlyPara = 0;
    2062         488 :     pRdr->pSFlyPara = 0;
    2063         488 :     pRdr->pPreviousNumPaM = 0;
    2064         488 :     pRdr->pPrevNumRule = 0;
    2065         488 :     pRdr->pTableDesc = 0;
    2066         488 :     pRdr->nAktColl = 0;
    2067             : 
    2068             :     pRdr->pCtrlStck = new SwWW8FltControlStack(&pRdr->rDoc, pRdr->nFieldFlags,
    2069         488 :         *pRdr);
    2070             : 
    2071         488 :     pRdr->mpRedlineStack = new sw::util::RedlineStack(pRdr->rDoc);
    2072             : 
    2073         488 :     pRdr->pAnchorStck = new SwWW8FltAnchorStack(&pRdr->rDoc, pRdr->nFieldFlags);
    2074             : 
    2075             :     // Save the attribute manager: we need this as the newly created PLCFx Manager
    2076             :     // access the same FKPs as the old one and their Start-End position changes.
    2077         488 :     if (pRdr->pPlcxMan)
    2078         202 :         pRdr->pPlcxMan->SaveAllPLCFx(maPLCFxSave);
    2079             : 
    2080         488 :     if (nStartCp != -1)
    2081             :     {
    2082             :         pRdr->pPlcxMan = new WW8PLCFMan(pRdr->pSBase,
    2083          14 :             mpOldPlcxMan->GetManType(), nStartCp);
    2084             :     }
    2085             : 
    2086         488 :     maOldApos.push_back(false);
    2087         488 :     maOldApos.swap(pRdr->maApos);
    2088         488 :     maOldFieldStack.swap(pRdr->maFieldStack);
    2089         488 : }
    2090             : 
    2091         488 : void WW8ReaderSave::Restore( SwWW8ImplReader* pRdr )
    2092             : {
    2093         488 :     pRdr->pWFlyPara = mpWFlyPara;
    2094         488 :     pRdr->pSFlyPara = mpSFlyPara;
    2095         488 :     pRdr->pPreviousNumPaM = mpPreviousNumPaM;
    2096         488 :     pRdr->pPrevNumRule = mpPrevNumRule;
    2097         488 :     pRdr->pTableDesc = mpTableDesc;
    2098         488 :     pRdr->cSymbol = mcSymbol;
    2099         488 :     pRdr->bSymbol = mbSymbol;
    2100         488 :     pRdr->bIgnoreText = mbIgnoreText;
    2101         488 :     pRdr->bHdFtFtnEdn = mbHdFtFtnEdn;
    2102         488 :     pRdr->bTxbxFlySection = mbTxbxFlySection;
    2103         488 :     pRdr->nInTable = mnInTable;
    2104         488 :     pRdr->bAnl = mbAnl;
    2105         488 :     pRdr->bInHyperlink = mbInHyperlink;
    2106         488 :     pRdr->bWasParaEnd = mbWasParaEnd;
    2107         488 :     pRdr->bPgSecBreak = mbPgSecBreak;
    2108         488 :     pRdr->nAktColl = mnAktColl;
    2109         488 :     pRdr->bHasBorder = mbHasBorder;
    2110         488 :     pRdr->bFirstPara = mbFirstPara;
    2111             : 
    2112             :     // Close all attributes as attributes could be created that extend the Fly
    2113         488 :     pRdr->DeleteCtrlStk();
    2114         488 :     pRdr->pCtrlStck = mpOldStck;
    2115             : 
    2116         488 :     pRdr->mpRedlineStack->closeall(*pRdr->pPaM->GetPoint());
    2117         488 :     delete pRdr->mpRedlineStack;
    2118         488 :     pRdr->mpRedlineStack = mpOldRedlines;
    2119             : 
    2120         488 :     pRdr->DeleteAnchorStk();
    2121         488 :     pRdr->pAnchorStck = mpOldAnchorStck;
    2122             : 
    2123         488 :     *pRdr->pPaM->GetPoint() = maTmpPos;
    2124             : 
    2125         488 :     if (mpOldPlcxMan != pRdr->pPlcxMan)
    2126             :     {
    2127         202 :         delete pRdr->pPlcxMan;
    2128         202 :         pRdr->pPlcxMan = mpOldPlcxMan;
    2129             :     }
    2130         488 :     if (pRdr->pPlcxMan)
    2131         202 :         pRdr->pPlcxMan->RestoreAllPLCFx(maPLCFxSave);
    2132         488 :     pRdr->maApos.swap(maOldApos);
    2133         488 :     pRdr->maFieldStack.swap(maOldFieldStack);
    2134         488 : }
    2135             : 
    2136         288 : void SwWW8ImplReader::Read_HdFtFtnText( const SwNodeIndex* pSttIdx,
    2137             :     long nStartCp, long nLen, ManTypes nType )
    2138             : {
    2139             :     // Saves Flags (amongst other things) and resets them
    2140         288 :     WW8ReaderSave aSave( this );
    2141             : 
    2142         288 :     pPaM->GetPoint()->nNode = pSttIdx->GetIndex() + 1;
    2143         288 :     pPaM->GetPoint()->nContent.Assign( pPaM->GetCntntNode(), 0 );
    2144             : 
    2145             :     // Read Text for Header, Footer or Footnote
    2146         288 :     ReadText( nStartCp, nLen, nType ); // Ignore Sepx when doing so
    2147         288 :     aSave.Restore( this );
    2148         288 : }
    2149             : 
    2150             : /**
    2151             :  * Use authornames, if not available fall back to initials.
    2152             :  */
    2153          30 : long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
    2154             : {
    2155          30 :     WW8PLCFx_SubDoc* pSD = pPlcxMan->GetAtn();
    2156          30 :     if( !pSD )
    2157           0 :         return 0;
    2158             : 
    2159          30 :     OUString sAuthor;
    2160          60 :     OUString sInitials;
    2161          30 :     if( bVer67 )
    2162             :     {
    2163           0 :         const WW67_ATRD* pDescri = (const WW67_ATRD*)pSD->GetData();
    2164           0 :         const OUString* pA = GetAnnotationAuthor(SVBT16ToShort(pDescri->ibst));
    2165           0 :         if (pA)
    2166           0 :             sAuthor = *pA;
    2167             :         else
    2168           0 :             sAuthor = OUString(pDescri->xstUsrInitl + 1, pDescri->xstUsrInitl[0],
    2169           0 :                 RTL_TEXTENCODING_MS_1252);
    2170             :     }
    2171             :     else
    2172             :     {
    2173          30 :         const WW8_ATRD* pDescri = (const WW8_ATRD*)pSD->GetData();
    2174             : 
    2175             :         {
    2176          30 :             const sal_uInt16 nLen = SVBT16ToShort(pDescri->xstUsrInitl[0]);
    2177          30 :             OUStringBuffer aBuf;
    2178          30 :             aBuf.setLength(nLen);
    2179          48 :             for(sal_uInt16 nIdx = 1; nIdx <= nLen; ++nIdx)
    2180          18 :                 aBuf[nIdx-1] = SVBT16ToShort(pDescri->xstUsrInitl[nIdx]);
    2181          30 :             sInitials = aBuf.makeStringAndClear();
    2182             :         }
    2183             : 
    2184          30 :         if (const OUString* pA = GetAnnotationAuthor(SVBT16ToShort(pDescri->ibst)))
    2185          30 :             sAuthor = *pA;
    2186             :         else
    2187           0 :             sAuthor = sInitials;
    2188             : 
    2189             :         // If there is a bookmark tag, a text range should be commented.
    2190          30 :         sal_uInt32 nTagBkmk = SVBT32ToUInt32(pDescri->ITagBkmk);
    2191          30 :         if (nTagBkmk != 0xFFFFFFFF)
    2192             :         {
    2193          24 :             int nAtnIndex = GetAnnotationIndex(nTagBkmk);
    2194          24 :             if (nAtnIndex != -1)
    2195             :             {
    2196          24 :                 WW8_CP nStart = GetAnnotationStart(nAtnIndex);
    2197          24 :                 WW8_CP nEnd = GetAnnotationEnd(GetAnnotationEndIndex(nAtnIndex));
    2198             :                 //It is unfortunately fragile and wrong to assume that two
    2199             :                 //character positions in the original word document, which is
    2200             :                 //what nStart and nEnd are, will equate to the same length in
    2201             :                 //the destination writer document.
    2202             :                 //
    2203             :                 //Better would be, while writing the content into the writer
    2204             :                 //document to store the equivalent writer document positions
    2205             :                 //that relate to each annotation index as the parser passes
    2206             :                 //those points.
    2207          24 :                 sal_Int32 nLen = nEnd - nStart;
    2208             :                 // the start and end positions are apparently stored in
    2209             :                 // different arrays, so in an invalid file only one could exist
    2210          24 :                 if(SAL_MAX_INT32 != nEnd && SAL_MAX_INT32 != nStart && nLen > 0)
    2211             :                 {
    2212          24 :                     if (pPaM->GetPoint()->nContent.GetIndex() >= nLen)
    2213             :                     {
    2214          18 :                         pPaM->SetMark();
    2215          18 :                         pPaM->GetPoint()->nContent -= nLen;
    2216             :                     }
    2217           6 :                     else if (pPaM->GetPoint()->nNode.GetNode().IsTxtNode() )
    2218             :                     {
    2219           6 :                         pPaM->SetMark();
    2220           6 :                         nLen -= pPaM->GetPoint()->nContent.GetIndex();
    2221             : 
    2222           6 :                         SwTxtNode* pTxtNode = 0;
    2223             : 
    2224             :                         // Find first text node which is affected by the comment
    2225          12 :                         while (nLen > 0)
    2226             :                         {
    2227             :                             // Move to previous content node
    2228           6 :                             bool bSuccess = pPaM->Move(fnMoveBackward, fnGoNode);
    2229             : 
    2230           6 :                             if (!bSuccess)
    2231             :                             {
    2232           0 :                                 nLen = 0;
    2233           0 :                                 break;
    2234             :                             }
    2235             : 
    2236           6 :                             --nLen; // End line character
    2237             : 
    2238           6 :                             SwNode& rNode = pPaM->GetPoint()->nNode.GetNode();
    2239             : 
    2240             :                             // Subtract previous text node's length
    2241           6 :                             if (rNode.IsTxtNode())
    2242             :                             {
    2243           6 :                                 pTxtNode = rNode.GetTxtNode();
    2244           6 :                                 if (nLen < pTxtNode->Len())
    2245           6 :                                     break;
    2246             :                                 else
    2247           0 :                                     nLen -= pTxtNode->Len();
    2248             :                             }
    2249             :                         }
    2250             : 
    2251             :                         // Set position of the text range's first character
    2252           6 :                         if( pTxtNode )
    2253             :                         {
    2254           6 :                             pTxtNode->MakeStartIndex(&pPaM->GetPoint()->nContent);
    2255           6 :                             pPaM->GetPoint()->nContent += pTxtNode->Len() - nLen;
    2256             :                         }
    2257             :                     }
    2258             :                 }
    2259             :             }
    2260             :         }
    2261             :     }
    2262             : 
    2263          30 :     sal_uInt32 nDateTime = 0;
    2264             : 
    2265          30 :     if (sal_uInt8 * pExtended = pPlcxMan->GetExtendedAtrds()) // Word < 2002 has no date data for comments
    2266             :     {
    2267          30 :         sal_uLong nIndex = pSD->GetIdx() & 0xFFFF; // Index is (stupidly) multiplexed for WW8PLCFx_SubDocs
    2268          30 :         if (pWwFib->lcbAtrdExtra/18 > nIndex)
    2269          30 :             nDateTime = SVBT32ToUInt32(*(SVBT32*)(pExtended+(nIndex*18)));
    2270             :     }
    2271             : 
    2272          30 :     DateTime aDate = msfilter::util::DTTM2DateTime(nDateTime);
    2273             : 
    2274          60 :     OUString sTxt;
    2275             :     OutlinerParaObject *pOutliner = ImportAsOutliner( sTxt, pRes->nCp2OrIdx,
    2276          30 :         pRes->nCp2OrIdx + pRes->nMemLen, MAN_AND );
    2277             : 
    2278          30 :     this->pFmtOfJustInsertedApo = 0;
    2279             :     SwPostItField aPostIt(
    2280          30 :         (SwPostItFieldType*)rDoc.getIDocumentFieldsAccess().GetSysFldType(RES_POSTITFLD), sAuthor,
    2281          90 :         sTxt, sInitials, OUString(), aDate );
    2282          30 :     aPostIt.SetTextObject(pOutliner);
    2283             : 
    2284          60 :     SwPaM aEnd(*pPaM->End(), *pPaM->End());
    2285          30 :     pCtrlStck->NewAttr(*aEnd.GetPoint(), SvxCharHiddenItem(false, RES_CHRATR_HIDDEN));
    2286          30 :     rDoc.getIDocumentContentOperations().InsertPoolItem(aEnd, SwFmtFld(aPostIt), 0);
    2287          30 :     pCtrlStck->SetAttr(*aEnd.GetPoint(), RES_CHRATR_HIDDEN);
    2288             : 
    2289             :     // If this is a range, create the associated fieldmark.
    2290          30 :     if (pPaM->HasMark())
    2291             :     {
    2292          24 :         IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess();
    2293          24 :         pMarksAccess->makeAnnotationMark(*pPaM, aPostIt.GetName());
    2294          24 :         pPaM->Exchange();
    2295          24 :         pPaM->DeleteMark();
    2296             :     }
    2297             : 
    2298          60 :     return 0;
    2299             : }
    2300             : 
    2301           0 : void SwWW8ImplReader::Read_HdFtTextAsHackedFrame(long nStart, long nLen,
    2302             :     SwFrmFmt &rHdFtFmt, sal_uInt16 nPageWidth)
    2303             : {
    2304           0 :     const SwNodeIndex* pSttIdx = rHdFtFmt.GetCntnt().GetCntntIdx();
    2305             :     OSL_ENSURE(pSttIdx, "impossible");
    2306           0 :     if (!pSttIdx)
    2307           0 :         return;
    2308             : 
    2309           0 :     SwPosition aTmpPos(*pPaM->GetPoint());
    2310             : 
    2311           0 :     pPaM->GetPoint()->nNode = pSttIdx->GetIndex() + 1;
    2312           0 :     pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
    2313             : 
    2314           0 :     SwFlyFrmFmt *pFrame = rDoc.MakeFlySection(FLY_AT_PARA, pPaM->GetPoint());
    2315             : 
    2316           0 :     SwFmtAnchor aAnch( pFrame->GetAnchor() );
    2317           0 :     aAnch.SetType( FLY_AT_PARA );
    2318           0 :     pFrame->SetFmtAttr( aAnch );
    2319           0 :     SwFmtFrmSize aSz(ATT_MIN_SIZE, nPageWidth, MINLAY);
    2320           0 :     SwFrmSize eFrmSize = ATT_MIN_SIZE;
    2321           0 :     if( eFrmSize != aSz.GetWidthSizeType() )
    2322           0 :         aSz.SetWidthSizeType( eFrmSize );
    2323           0 :     pFrame->SetFmtAttr(aSz);
    2324           0 :     pFrame->SetFmtAttr(SwFmtSurround(SURROUND_THROUGHT));
    2325           0 :     pFrame->SetFmtAttr(SwFmtHoriOrient(0, text::HoriOrientation::LEFT)); //iFOO
    2326             : 
    2327             :     // #i43427# - send frame for header/footer into background.
    2328           0 :     pFrame->SetFmtAttr( SvxOpaqueItem( RES_OPAQUE, false ) );
    2329           0 :     SdrObject* pFrmObj = CreateContactObject( pFrame );
    2330             :     OSL_ENSURE( pFrmObj,
    2331             :             "<SwWW8ImplReader::Read_HdFtTextAsHackedFrame(..)> - missing SdrObject instance" );
    2332           0 :     if ( pFrmObj )
    2333             :     {
    2334           0 :         pFrmObj->SetOrdNum( 0L );
    2335             :     }
    2336           0 :     MoveInsideFly(pFrame);
    2337             : 
    2338           0 :     const SwNodeIndex* pHackIdx = pFrame->GetCntnt().GetCntntIdx();
    2339             : 
    2340           0 :     Read_HdFtFtnText(pHackIdx, nStart, nLen - 1, MAN_HDFT);
    2341             : 
    2342           0 :     MoveOutsideFly(pFrame, aTmpPos);
    2343             : }
    2344             : 
    2345         286 : void SwWW8ImplReader::Read_HdFtText(long nStart, long nLen, SwFrmFmt* pHdFtFmt)
    2346             : {
    2347         286 :     const SwNodeIndex* pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
    2348         286 :     if (!pSttIdx)
    2349         286 :         return;
    2350             : 
    2351         286 :     SwPosition aTmpPos( *pPaM->GetPoint() ); // Remember old cursor position
    2352             : 
    2353         286 :     Read_HdFtFtnText(pSttIdx, nStart, nLen - 1, MAN_HDFT);
    2354             : 
    2355         286 :     *pPaM->GetPoint() = aTmpPos;
    2356             : }
    2357             : 
    2358         282 : bool SwWW8ImplReader::isValid_HdFt_CP(WW8_CP nHeaderCP) const
    2359             : {
    2360             :     // Each CP of Plcfhdd MUST be less than FibRgLw97.ccpHdd
    2361         282 :     return (nHeaderCP < pWwFib->ccpHdr);
    2362             : }
    2363             : 
    2364           0 : bool SwWW8ImplReader::HasOwnHeaderFooter(sal_uInt8 nWhichItems, sal_uInt8 grpfIhdt,
    2365             :     int nSect)
    2366             : {
    2367           0 :     if (pHdFt)
    2368             :     {
    2369             :         WW8_CP start;
    2370             :         long nLen;
    2371           0 :         sal_uInt8 nNumber = 5;
    2372             : 
    2373           0 :         for( sal_uInt8 nI = 0x20; nI; nI >>= 1, nNumber-- )
    2374             :         {
    2375           0 :             if (nI & nWhichItems)
    2376             :             {
    2377           0 :                 bool bOk = true;
    2378           0 :                 if( bVer67 )
    2379           0 :                     bOk = ( pHdFt->GetTextPos(grpfIhdt, nI, start, nLen ) && nLen >= 2 );
    2380             :                 else
    2381             :                 {
    2382           0 :                     pHdFt->GetTextPosExact( static_cast< short >(nNumber + (nSect+1)*6), start, nLen);
    2383           0 :                     bOk = ( 2 <= nLen ) && isValid_HdFt_CP(start);
    2384             :                 }
    2385             : 
    2386           0 :                 if (bOk)
    2387           0 :                     return true;
    2388             :             }
    2389             :         }
    2390             :     }
    2391           0 :     return false;
    2392             : }
    2393             : 
    2394          86 : void SwWW8ImplReader::Read_HdFt(int nSect, const SwPageDesc *pPrev,
    2395             :     const wwSection &rSection)
    2396             : {
    2397          86 :     sal_uInt8 grpfIhdt = rSection.maSep.grpfIhdt;
    2398          86 :     SwPageDesc *pPD = rSection.mpPage;
    2399             : 
    2400          86 :     if( pHdFt )
    2401             :     {
    2402             :         WW8_CP start;
    2403             :         long nLen;
    2404          86 :         sal_uInt8 nNumber = 5;
    2405             : 
    2406             :         // This loops through the 6 flags WW8_{FOOTER,HEADER}_{ODD,EVEN,FIRST}
    2407             :         // corresponding to bit fields in grpfIhdt indicating which
    2408             :         // header/footer(s) are present in this section
    2409         602 :         for( sal_uInt8 nI = 0x20; nI; nI >>= 1, nNumber-- )
    2410             :         {
    2411         516 :             if (nI & grpfIhdt)
    2412             :             {
    2413         318 :                 bool bOk = true;
    2414         318 :                 if( bVer67 )
    2415           4 :                     bOk = ( pHdFt->GetTextPos(grpfIhdt, nI, start, nLen ) && nLen >= 2 );
    2416             :                 else
    2417             :                 {
    2418         314 :                     pHdFt->GetTextPosExact( static_cast< short >(nNumber + (nSect+1)*6), start, nLen);
    2419         314 :                     bOk = ( 2 <= nLen ) && isValid_HdFt_CP(start);
    2420             :                 }
    2421             : 
    2422             :                 bool bUseLeft
    2423         318 :                     = (nI & ( WW8_HEADER_EVEN | WW8_FOOTER_EVEN )) ? true: false;
    2424             :                 bool bUseFirst
    2425         318 :                     = (nI & ( WW8_HEADER_FIRST | WW8_FOOTER_FIRST )) ? true: false;
    2426             : 
    2427             :                 // If we are loading a first-page header/footer which is not
    2428             :                 // actually enabled in this section (it still needs to be
    2429             :                 // loaded as it may be inherited by a later section)
    2430         318 :                 bool bDisabledFirst = bUseFirst && !rSection.HasTitlePage();
    2431             : 
    2432             :                 bool bFooter
    2433         318 :                     = (nI & ( WW8_FOOTER_EVEN | WW8_FOOTER_ODD | WW8_FOOTER_FIRST )) ? true: false;
    2434             : 
    2435             :                 SwFrmFmt& rFmt = bUseLeft ? pPD->GetLeft()
    2436             :                     : bUseFirst ? pPD->GetFirstMaster()
    2437         318 :                     : pPD->GetMaster();
    2438             : 
    2439             :                 SwFrmFmt* pHdFtFmt;
    2440             :                 // If we have empty first page header and footer.
    2441         318 :                 bool bNoFirst = !(grpfIhdt & WW8_HEADER_FIRST) && !(grpfIhdt & WW8_FOOTER_FIRST);
    2442         318 :                 if (bFooter)
    2443             :                 {
    2444         158 :                     bIsFooter = true;
    2445             :                     //#i17196# Cannot have left without right
    2446         316 :                     if (!bDisabledFirst
    2447         158 :                             && !pPD->GetMaster().GetFooter().GetFooterFmt())
    2448          74 :                         pPD->GetMaster().SetFmtAttr(SwFmtFooter(true));
    2449         158 :                     if (bUseLeft)
    2450          26 :                         pPD->GetLeft().SetFmtAttr(SwFmtFooter(true));
    2451         158 :                     if (bUseFirst || (rSection.maSep.fTitlePage && bNoFirst))
    2452          62 :                         pPD->GetFirstMaster().SetFmtAttr(SwFmtFooter(true));
    2453         158 :                     pHdFtFmt = const_cast<SwFrmFmt*>(rFmt.GetFooter().GetFooterFmt());
    2454             :                 }
    2455             :                 else
    2456             :                 {
    2457         160 :                     bIsHeader = true;
    2458             :                     //#i17196# Cannot have left without right
    2459         320 :                     if (!bDisabledFirst
    2460         160 :                             && !pPD->GetMaster().GetHeader().GetHeaderFmt())
    2461          72 :                         pPD->GetMaster().SetFmtAttr(SwFmtHeader(true));
    2462         160 :                     if (bUseLeft)
    2463          24 :                         pPD->GetLeft().SetFmtAttr(SwFmtHeader(true));
    2464         160 :                     if (bUseFirst || (rSection.maSep.fTitlePage && bNoFirst))
    2465          68 :                         pPD->GetFirstMaster().SetFmtAttr(SwFmtHeader(true));
    2466         160 :                     pHdFtFmt = const_cast<SwFrmFmt*>(rFmt.GetHeader().GetHeaderFmt());
    2467             :                 }
    2468             : 
    2469         318 :                 if (bOk)
    2470             :                 {
    2471         286 :                     bool bHackRequired = false;
    2472         286 :                     if (bIsHeader && rSection.IsFixedHeightHeader())
    2473           0 :                         bHackRequired = true;
    2474         286 :                     else if (bIsFooter && rSection.IsFixedHeightFooter())
    2475           0 :                         bHackRequired = true;
    2476             : 
    2477         286 :                     if (bHackRequired)
    2478             :                     {
    2479             :                         Read_HdFtTextAsHackedFrame(start, nLen, *pHdFtFmt,
    2480           0 :                             static_cast< sal_uInt16 >(rSection.GetTextAreaWidth()) );
    2481             :                     }
    2482             :                     else
    2483         286 :                         Read_HdFtText(start, nLen, pHdFtFmt);
    2484             :                 }
    2485          32 :                 else if (!bOk && pPrev)
    2486          32 :                     CopyPageDescHdFt(pPrev, pPD, nI);
    2487             : 
    2488         318 :                 bIsHeader = bIsFooter = false;
    2489             :             }
    2490             :         }
    2491             :     }
    2492          86 : }
    2493             : 
    2494         228 : bool wwSectionManager::SectionIsProtected(const wwSection &rSection) const
    2495             : {
    2496         228 :     return (mrReader.pWwFib->fReadOnlyRecommended && !rSection.IsNotProtected());
    2497             : }
    2498             : 
    2499         220 : void wwSectionManager::SetHdFt(wwSection &rSection, int nSect,
    2500             :     const wwSection *pPrevious)
    2501             : {
    2502             :     // Header/Footer not present
    2503         220 :     if (!rSection.maSep.grpfIhdt)
    2504         354 :         return;
    2505             : 
    2506             :     OSL_ENSURE(rSection.mpPage, "makes no sense to call with a main page");
    2507          86 :     if (rSection.mpPage)
    2508             :     {
    2509             :         mrReader.Read_HdFt(nSect, pPrevious ? pPrevious->mpPage : 0,
    2510          86 :                 rSection);
    2511             :     }
    2512             : 
    2513             :     // Header/Footer - Update Index
    2514             :     // So that the index is still valid later on
    2515          86 :     if (mrReader.pHdFt)
    2516          86 :         mrReader.pHdFt->UpdateIndex(rSection.maSep.grpfIhdt);
    2517             : 
    2518             : }
    2519             : 
    2520        5542 : void SwWW8ImplReader::AppendTxtNode(SwPosition& rPos)
    2521             : {
    2522        5542 :     SwTxtNode* pTxt = pPaM->GetNode().GetTxtNode();
    2523             : 
    2524        5542 :     const SwNumRule* pRule = NULL;
    2525             : 
    2526        5542 :     if (pTxt != NULL)
    2527        5542 :         pRule = sw::util::GetNumRuleFromTxtNode(*pTxt);
    2528             : 
    2529        5542 :     if (
    2530         674 :          pRule && !pWDop->fDontUseHTMLAutoSpacing &&
    2531         224 :          (bParaAutoBefore || bParaAutoAfter)
    2532             :        )
    2533             :     {
    2534             :         // If after spacing is set to auto, set the after space to 0
    2535           0 :         if (bParaAutoAfter)
    2536           0 :             SetLowerSpacing(*pPaM, 0);
    2537             : 
    2538             :         // If the previous textnode had numbering and
    2539             :         // and before spacing is set to auto, set before space to 0
    2540           0 :         if(pPrevNumRule && bParaAutoBefore)
    2541           0 :             SetUpperSpacing(*pPaM, 0);
    2542             : 
    2543             :         // If the previous numbering rule was different we need
    2544             :         // to insert a space after the previous paragraph
    2545           0 :         if((pRule != pPrevNumRule) && pPreviousNumPaM)
    2546           0 :             SetLowerSpacing(*pPreviousNumPaM, GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
    2547             : 
    2548             :         // cache current paragraph
    2549           0 :         if(pPreviousNumPaM)
    2550           0 :             delete pPreviousNumPaM, pPreviousNumPaM = 0;
    2551             : 
    2552           0 :         pPreviousNumPaM = new SwPaM(*pPaM);
    2553           0 :         pPrevNumRule = pRule;
    2554             :     }
    2555        5542 :     else if(!pRule && pPreviousNumPaM)
    2556             :     {
    2557             :         // If the previous paragraph has numbering but the current one does not
    2558             :         // we need to add a space after the previous paragraph
    2559           0 :         SetLowerSpacing(*pPreviousNumPaM, GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
    2560           0 :         delete pPreviousNumPaM, pPreviousNumPaM = 0;
    2561           0 :         pPrevNumRule = 0;
    2562             :     }
    2563             :     else
    2564             :     {
    2565             :         // clear paragraph cache
    2566        5542 :         if(pPreviousNumPaM)
    2567           0 :             delete pPreviousNumPaM, pPreviousNumPaM = 0;
    2568        5542 :         pPrevNumRule = pRule;
    2569             :     }
    2570             : 
    2571             :     // If this is the first paragraph in the document and
    2572             :     // Auto-spacing before paragraph is set,
    2573             :     // set the upper spacing value to 0
    2574        5542 :     if(bParaAutoBefore && bFirstPara && !pWDop->fDontUseHTMLAutoSpacing)
    2575           0 :         SetUpperSpacing(*pPaM, 0);
    2576             : 
    2577        5542 :     bFirstPara = false;
    2578             : 
    2579        5542 :     rDoc.getIDocumentContentOperations().AppendTxtNode(rPos);
    2580             : 
    2581             :     // We can flush all anchored graphics at the end of a paragraph.
    2582        5542 :     pAnchorStck->Flush();
    2583        5542 : }
    2584             : 
    2585           0 : bool SwWW8ImplReader::SetSpacing(SwPaM &rMyPam, int nSpace, bool bIsUpper )
    2586             : {
    2587           0 :         bool bRet = false;
    2588           0 :         const SwPosition* pSpacingPos = rMyPam.GetPoint();
    2589             : 
    2590           0 :         const SvxULSpaceItem* pULSpaceItem = (const SvxULSpaceItem*)pCtrlStck->GetFmtAttr(*pSpacingPos, RES_UL_SPACE);
    2591             : 
    2592           0 :         if(pULSpaceItem != 0)
    2593             :         {
    2594           0 :             SvxULSpaceItem aUL(*pULSpaceItem);
    2595             : 
    2596           0 :             if(bIsUpper)
    2597           0 :                 aUL.SetUpper( static_cast< sal_uInt16 >(nSpace) );
    2598             :             else
    2599           0 :                 aUL.SetLower( static_cast< sal_uInt16 >(nSpace) );
    2600             : 
    2601           0 :             const sal_Int32 nEnd = pSpacingPos->nContent.GetIndex();
    2602           0 :             rMyPam.GetPoint()->nContent.Assign(rMyPam.GetCntntNode(), 0);
    2603           0 :             pCtrlStck->NewAttr(*pSpacingPos, aUL);
    2604           0 :             rMyPam.GetPoint()->nContent.Assign(rMyPam.GetCntntNode(), nEnd);
    2605           0 :             pCtrlStck->SetAttr(*pSpacingPos, RES_UL_SPACE);
    2606           0 :             bRet = true;
    2607             :         }
    2608           0 :         return bRet;
    2609             : }
    2610             : 
    2611           0 : bool SwWW8ImplReader::SetLowerSpacing(SwPaM &rMyPam, int nSpace)
    2612             : {
    2613           0 :     return SetSpacing(rMyPam, nSpace, false);
    2614             : }
    2615             : 
    2616           0 : bool SwWW8ImplReader::SetUpperSpacing(SwPaM &rMyPam, int nSpace)
    2617             : {
    2618           0 :     return SetSpacing(rMyPam, nSpace, true);
    2619             : }
    2620             : 
    2621       41258 : sal_uInt16 SwWW8ImplReader::TabRowSprm(int nLevel) const
    2622             : {
    2623       41258 :     if (bVer67)
    2624           0 :         return 25;
    2625       41258 :     return nLevel ? 0x244C : 0x2417;
    2626             : }
    2627             : 
    2628         486 : void SwWW8ImplReader::EndSpecial()
    2629             : {
    2630             :     // Frame/Table/Anl
    2631         486 :     if (bAnl)
    2632           0 :         StopAllAnl(); // -> bAnl = false
    2633             : 
    2634         972 :     while(maApos.size() > 1)
    2635             :     {
    2636           0 :         StopTable();
    2637           0 :         maApos.pop_back();
    2638           0 :         --nInTable;
    2639           0 :         if (maApos[nInTable] == true)
    2640           0 :             StopApo();
    2641             :     }
    2642             : 
    2643         486 :     if (maApos[0] == true)
    2644           0 :         StopApo();
    2645             : 
    2646             :     OSL_ENSURE(!nInTable, "unclosed table!");
    2647         486 : }
    2648             : 
    2649        7982 : bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
    2650             : {
    2651             :     // Frame/Table/Anl
    2652        7982 :     if (bInHyperlink)
    2653           0 :         return false;
    2654             : 
    2655        7982 :     rbReSync = false;
    2656             : 
    2657             :     OSL_ENSURE(nInTable >= 0,"nInTable < 0!");
    2658             : 
    2659             :     // TabRowEnd
    2660        7982 :     bool bTableRowEnd = (pPlcxMan->HasParaSprm(bVer67 ? 25 : 0x2417) != 0 );
    2661             : 
    2662             : // Unfortunately, for every paragraph we need to check first whether
    2663             : // they contain a sprm 29 (0x261B), which starts an APO.
    2664             : // All other sprms then refer to that APO and not to the normal text
    2665             : // surrounding it.
    2666             : // The same holds true for a Table (sprm 24 (0x2416)) and Anls (sprm 13).
    2667             : 
    2668             : // WW: Table in APO is possible (Both Start-Ends occur at the same time)
    2669             : // WW: APO in Table not possible
    2670             : 
    2671             : // This mean that of a Table is the content of a APO, the APO start needs
    2672             : // to be edited first, so that the Table remains in the APO and not the
    2673             : // other way around.
    2674             : // At the End, however, we need to edit the Table End first as the APO
    2675             : // must end after that Table (or else we never find the APO End).
    2676             : 
    2677             : // The same holds true for Fly / Anl, Tab / Anl, Fly / Tab / Anl.
    2678             : 
    2679             : // If the Table is within an APO the TabRowEnd Area misses the
    2680             : // APO settings.
    2681             : // To not end the APO there, we do not call ProcessApo
    2682             : 
    2683             : // KHZ: When there is a table inside the Apo the Apo-flags are also
    2684             : //      missing for the 2nd, 3rd... paragraphs of each cell.
    2685             : 
    2686             : //  1st look for in-table flag, for 2000+ there is a subtable flag to
    2687             : //  be considered, the sprm 6649 gives the level of the table
    2688        7982 :     sal_uInt8 nCellLevel = 0;
    2689             : 
    2690        7982 :     if (bVer67)
    2691         150 :         nCellLevel = 0 != pPlcxMan->HasParaSprm(24);
    2692             :     else
    2693             :     {
    2694        7832 :         nCellLevel = 0 != pPlcxMan->HasParaSprm(0x2416);
    2695        7832 :         if (!nCellLevel)
    2696        4650 :             nCellLevel = 0 != pPlcxMan->HasParaSprm(0x244B);
    2697             :     }
    2698        7988 :     do
    2699             :     {
    2700        7988 :         WW8_TablePos *pTabPos=0;
    2701             :         WW8_TablePos aTabPos;
    2702        7988 :         if(nCellLevel && !bVer67)
    2703             :         {
    2704             :             WW8PLCFxSave1 aSave;
    2705        3188 :             pPlcxMan->GetPap()->Save( aSave );
    2706        3188 :             rbReSync = true;
    2707        3188 :             WW8PLCFx_Cp_FKP* pPap = pPlcxMan->GetPapPLCF();
    2708        3188 :             WW8_CP nMyStartCp=nStartCp;
    2709             : 
    2710        3188 :             if (const sal_uInt8 *pLevel = pPlcxMan->HasParaSprm(0x6649))
    2711        3188 :                 nCellLevel = *pLevel;
    2712             : 
    2713        3188 :             bool bHasRowEnd = SearchRowEnd(pPap, nMyStartCp, (nInTable<nCellLevel?nInTable:nCellLevel-1));
    2714             : 
    2715             :             // Bad Table, remain unchanged in level, e.g. #i19667#
    2716        3188 :             if (!bHasRowEnd)
    2717           2 :                 nCellLevel = static_cast< sal_uInt8 >(nInTable);
    2718             : 
    2719        3188 :             if (bHasRowEnd && ParseTabPos(&aTabPos,pPap))
    2720         202 :                 pTabPos = &aTabPos;
    2721             : 
    2722        3188 :             pPlcxMan->GetPap()->Restore( aSave );
    2723             :         }
    2724             : 
    2725             :         // Then look if we are in an Apo
    2726             : 
    2727        7988 :         ApoTestResults aApo = TestApo(nCellLevel, bTableRowEnd, pTabPos);
    2728             : 
    2729             :         // Look to see if we are in a Table, but Table in foot/end note not allowed
    2730        7988 :         bool bStartTab = (nInTable < nCellLevel) && !bFtnEdn;
    2731             : 
    2732        7988 :         bool bStopTab = bWasTabRowEnd && (nInTable > nCellLevel) && !bFtnEdn;
    2733             : 
    2734        7988 :         bWasTabRowEnd = false;  // must be deactivated right here to prevent next
    2735             :                                 // WW8TabDesc::TableCellEnd() from making nonsense
    2736             : 
    2737        7988 :         if (nInTable && !bTableRowEnd && !bStopTab && (nInTable == nCellLevel && aApo.HasStartStop()))
    2738           2 :             bStopTab = bStartTab = true; // Required to stop and start table
    2739             : 
    2740             :         //  Test for Anl (Numbering) and process all events in the right order
    2741        7988 :         if( bAnl && !bTableRowEnd )
    2742             :         {
    2743           0 :             const sal_uInt8* pSprm13 = pPlcxMan->HasParaSprm( 13 );
    2744           0 :             if( pSprm13 )
    2745             :             {   // Still Anl left?
    2746           0 :                 sal_uInt8 nT = static_cast< sal_uInt8 >(GetNumType( *pSprm13 ));
    2747           0 :                 if( ( nT != WW8_Pause && nT != nWwNumType ) // Anl change
    2748           0 :                     || aApo.HasStartStop()                  // Forced Anl end
    2749           0 :                     || bStopTab || bStartTab )
    2750             :                 {
    2751           0 :                     StopAnlToRestart(nT);  // Anl-Restart (= change) over sprms
    2752             :                 }
    2753             :                 else
    2754             :                 {
    2755           0 :                     NextAnlLine( pSprm13 ); // Next Anl Line
    2756             :                 }
    2757             :             }
    2758             :             else
    2759             :             {   // Regular Anl end
    2760           0 :                 StopAllAnl(); // Actual end
    2761             :             }
    2762             :         }
    2763        7988 :         if (bStopTab)
    2764             :         {
    2765         140 :             StopTable();
    2766         140 :             maApos.pop_back();
    2767         140 :             --nInTable;
    2768             :         }
    2769        7988 :         if (aApo.mbStopApo)
    2770             :         {
    2771          24 :             StopApo();
    2772          24 :             maApos[nInTable] = false;
    2773             :         }
    2774             : 
    2775             :         // So that SwWW8ImplReader::StartApo() can write into this, and
    2776             :         // WW8TabDesc::CreateSwTable() can read it, if necessary.
    2777        7988 :         SvxULSpaceItem aULSpaceItem(RES_UL_SPACE);
    2778             : 
    2779        7988 :         if (aApo.mbStartApo)
    2780             :         {
    2781          24 :             maApos[nInTable] = StartApo(aApo, pTabPos, &aULSpaceItem);
    2782             :             // We need an ReSync after StartApo
    2783             :             // (actually only if the Apo extends past a FKP border)
    2784          24 :             rbReSync = true;
    2785             :         }
    2786        7988 :         if (bStartTab)
    2787             :         {
    2788             :             WW8PLCFxSave1 aSave;
    2789         140 :             pPlcxMan->GetPap()->Save( aSave );
    2790             : 
    2791             :            // Numbering for cell borders causes a crash -> no Anls in Tables
    2792         140 :            if (bAnl)
    2793           0 :                StopAllAnl();
    2794             : 
    2795         140 :             if(nInTable < nCellLevel)
    2796             :             {
    2797         140 :                 if (StartTable(nStartCp, &aULSpaceItem))
    2798         140 :                     ++nInTable;
    2799             :                 else
    2800           0 :                     break;
    2801         140 :                 maApos.push_back(false);
    2802             :             }
    2803             : 
    2804         140 :             if(nInTable >= nCellLevel)
    2805             :             {
    2806             :                 // We need an ReSync after StartTable
    2807             :                 // (actually only if the Apo extends past a FKP border)
    2808         134 :                 rbReSync = true;
    2809         134 :                 pPlcxMan->GetPap()->Restore( aSave );
    2810             :             }
    2811        7988 :         }
    2812       15974 :     } while (!bFtnEdn && (nInTable < nCellLevel));
    2813        7982 :     return bTableRowEnd;
    2814             : }
    2815             : 
    2816         622 : rtl_TextEncoding SwWW8ImplReader::GetCharSetFromLanguage()
    2817             : {
    2818             :     /*
    2819             :      #i22206#/#i52786#
    2820             :      The (default) character set used for a run of text is the default
    2821             :      character set for the version of Word that last saved the document.
    2822             : 
    2823             :      This is a bit tentative, more might be required if the concept is correct.
    2824             :      When later version of word write older 6/95 documents the charset is
    2825             :      correctly set in the character runs involved, so its hard to reproduce
    2826             :      documents that require this to be sure of the process involved.
    2827             :     */
    2828         622 :     const SvxLanguageItem *pLang = (const SvxLanguageItem*)GetFmtAttr(RES_CHRATR_LANGUAGE);
    2829         622 :     LanguageType eLang = pLang ? pLang->GetLanguage() : LANGUAGE_SYSTEM;
    2830         622 :     ::com::sun::star::lang::Locale aLocale(LanguageTag::convertToLocale(eLang));
    2831         622 :     return msfilter::util::getBestTextEncodingFromLocale(aLocale);
    2832             : }
    2833             : 
    2834         622 : rtl_TextEncoding SwWW8ImplReader::GetCJKCharSetFromLanguage()
    2835             : {
    2836             :     /*
    2837             :      #i22206#/#i52786#
    2838             :      The (default) character set used for a run of text is the default
    2839             :      character set for the version of Word that last saved the document.
    2840             : 
    2841             :      This is a bit tentative, more might be required if the concept is correct.
    2842             :      When later version of word write older 6/95 documents the charset is
    2843             :      correctly set in the character runs involved, so its hard to reproduce
    2844             :      documents that require this to be sure of the process involved.
    2845             :     */
    2846         622 :     const SvxLanguageItem *pLang = (const SvxLanguageItem*)GetFmtAttr(RES_CHRATR_CJK_LANGUAGE);
    2847         622 :     LanguageType eLang = pLang ? pLang->GetLanguage() : LANGUAGE_SYSTEM;
    2848         622 :     ::com::sun::star::lang::Locale aLocale(LanguageTag::convertToLocale(eLang));
    2849         622 :     return msfilter::util::getBestTextEncodingFromLocale(aLocale);
    2850             : }
    2851             : 
    2852         800 : rtl_TextEncoding SwWW8ImplReader::GetCurrentCharSet()
    2853             : {
    2854             :     /*
    2855             :     #i2015
    2856             :     If the hard charset is set use it, if not see if there is an open
    2857             :     character run that has set the charset, if not then fallback to the
    2858             :     current underlying paragraph style.
    2859             :     */
    2860         800 :     rtl_TextEncoding eSrcCharSet = eHardCharSet;
    2861         800 :     if (eSrcCharSet == RTL_TEXTENCODING_DONTKNOW)
    2862             :     {
    2863         800 :         if (!maFontSrcCharSets.empty())
    2864         130 :             eSrcCharSet = maFontSrcCharSets.top();
    2865         800 :         if ((eSrcCharSet == RTL_TEXTENCODING_DONTKNOW) && nCharFmt >= 0 && (size_t)nCharFmt < vColl.size() )
    2866           0 :             eSrcCharSet = vColl[nCharFmt].GetCharSet();
    2867         800 :         if ((eSrcCharSet == RTL_TEXTENCODING_DONTKNOW) && StyleExists(nAktColl) && nAktColl < vColl.size())
    2868         670 :             eSrcCharSet = vColl[nAktColl].GetCharSet();
    2869         800 :         if (eSrcCharSet == RTL_TEXTENCODING_DONTKNOW)
    2870         622 :             eSrcCharSet = GetCharSetFromLanguage();
    2871             :     }
    2872         800 :     return eSrcCharSet;
    2873             : }
    2874             : 
    2875             : //Takashi Ono for CJK
    2876         622 : rtl_TextEncoding SwWW8ImplReader::GetCurrentCJKCharSet()
    2877             : {
    2878             :     /*
    2879             :     #i2015
    2880             :     If the hard charset is set use it, if not see if there is an open
    2881             :     character run that has set the charset, if not then fallback to the
    2882             :     current underlying paragraph style.
    2883             :     */
    2884         622 :     rtl_TextEncoding eSrcCharSet = eHardCharSet;
    2885         622 :     if (eSrcCharSet == RTL_TEXTENCODING_DONTKNOW)
    2886             :     {
    2887         622 :         if (!maFontSrcCJKCharSets.empty())
    2888           0 :             eSrcCharSet = maFontSrcCJKCharSets.top();
    2889         622 :         if ((eSrcCharSet == RTL_TEXTENCODING_DONTKNOW) && nCharFmt >= 0 && (size_t)nCharFmt < vColl.size() )
    2890           0 :             eSrcCharSet = vColl[nCharFmt].GetCJKCharSet();
    2891         622 :         if (eSrcCharSet == RTL_TEXTENCODING_DONTKNOW && StyleExists(nAktColl) && nAktColl < vColl.size())
    2892         622 :             eSrcCharSet = vColl[nAktColl].GetCJKCharSet();
    2893         622 :         if (eSrcCharSet == RTL_TEXTENCODING_DONTKNOW)
    2894         622 :             eSrcCharSet = GetCJKCharSetFromLanguage();
    2895             :     }
    2896         622 :     return eSrcCharSet;
    2897             : }
    2898             : 
    2899           0 : void SwWW8ImplReader::PostProcessAttrs()
    2900             : {
    2901           0 :     if (mpPostProcessAttrsInfo != NULL)
    2902             :     {
    2903           0 :         SfxItemIter aIter(mpPostProcessAttrsInfo->mItemSet);
    2904             : 
    2905           0 :         const SfxPoolItem * pItem = aIter.GetCurItem();
    2906           0 :         if (pItem != NULL)
    2907             :         {
    2908           0 :             do
    2909             :             {
    2910           0 :                 pCtrlStck->NewAttr(*mpPostProcessAttrsInfo->mPaM.GetPoint(),
    2911           0 :                                    *pItem);
    2912           0 :                 pCtrlStck->SetAttr(*mpPostProcessAttrsInfo->mPaM.GetMark(),
    2913           0 :                                    pItem->Which(), true);
    2914             :             }
    2915           0 :             while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
    2916             :         }
    2917             : 
    2918           0 :         delete mpPostProcessAttrsInfo;
    2919           0 :         mpPostProcessAttrsInfo = NULL;
    2920             :     }
    2921           0 : }
    2922             : 
    2923             : /*
    2924             :  #i9241#
    2925             :  It appears that some documents that are in a baltic 8 bit encoding which has
    2926             :  some undefined characters can have use made of those characters, in which
    2927             :  case they default to CP1252. If not then its perhaps that the font encoding
    2928             :  is only in use for 6/7 and for 8+ if we are in 8bit mode then the encoding
    2929             :  is always 1252.
    2930             : 
    2931             :  So a encoding converter that on an undefined character attempts to
    2932             :  convert from 1252 on the undefined character
    2933             : */
    2934        3904 : sal_Size Custom8BitToUnicode(rtl_TextToUnicodeConverter hConverter,
    2935             :     sal_Char *pIn, sal_Size nInLen, sal_Unicode *pOut, sal_Size nOutLen)
    2936             : {
    2937             :     const sal_uInt32 nFlags =
    2938             :         RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
    2939             :         RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
    2940             :         RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE |
    2941        3904 :         RTL_TEXTTOUNICODE_FLAGS_FLUSH;
    2942             : 
    2943             :     const sal_uInt32 nFlags2 =
    2944             :         RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE |
    2945             :         RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_IGNORE |
    2946             :         RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE |
    2947        3904 :         RTL_TEXTTOUNICODE_FLAGS_FLUSH;
    2948             : 
    2949        3904 :     sal_Size nDestChars=0;
    2950        3904 :     sal_Size nConverted=0;
    2951             : 
    2952        3904 :     do
    2953             :     {
    2954        3904 :         sal_uInt32 nInfo = 0;
    2955        3904 :         sal_Size nThisConverted=0;
    2956             : 
    2957             :         nDestChars += rtl_convertTextToUnicode(hConverter, 0,
    2958             :             pIn+nConverted, nInLen-nConverted,
    2959             :             pOut+nDestChars, nOutLen-nDestChars,
    2960        3904 :             nFlags, &nInfo, &nThisConverted);
    2961             : 
    2962             :         OSL_ENSURE(nInfo == 0, "A character conversion failed!");
    2963             : 
    2964        3904 :         nConverted += nThisConverted;
    2965             : 
    2966        3904 :         if (
    2967        7808 :             nInfo & RTL_TEXTTOUNICODE_INFO_UNDEFINED ||
    2968        3904 :             nInfo & RTL_TEXTTOUNICODE_INFO_MBUNDEFINED
    2969             :            )
    2970             :         {
    2971             :             sal_Size nOtherConverted;
    2972             :             rtl_TextToUnicodeConverter hCP1252Converter =
    2973           0 :                 rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_MS_1252);
    2974             :             nDestChars += rtl_convertTextToUnicode(hCP1252Converter, 0,
    2975             :                 pIn+nConverted, 1,
    2976             :                 pOut+nDestChars, nOutLen-nDestChars,
    2977           0 :                 nFlags2, &nInfo, &nOtherConverted);
    2978           0 :             rtl_destroyTextToUnicodeConverter(hCP1252Converter);
    2979           0 :             nConverted+=1;
    2980             :         }
    2981             :     } while (nConverted < nInLen);
    2982             : 
    2983        3904 :     return nDestChars;
    2984             : }
    2985             : 
    2986           0 : bool SwWW8ImplReader::LangUsesHindiNumbers(sal_uInt16 nLang)
    2987             : {
    2988           0 :     bool bResult = false;
    2989             : 
    2990           0 :     switch (nLang)
    2991             :     {
    2992             :         case 0x1401: // Arabic(Algeria)
    2993             :         case 0x3c01: // Arabic(Bahrain)
    2994             :         case 0xc01: // Arabic(Egypt)
    2995             :         case 0x801: // Arabic(Iraq)
    2996             :         case 0x2c01: // Arabic (Jordan)
    2997             :         case 0x3401: // Arabic(Kuwait)
    2998             :         case 0x3001: // Arabic(Lebanon)
    2999             :         case 0x1001: // Arabic(Libya)
    3000             :         case 0x1801: // Arabic(Morocco)
    3001             :         case 0x2001: // Arabic(Oman)
    3002             :         case 0x4001: // Arabic(Qatar)
    3003             :         case 0x401: // Arabic(Saudi Arabia)
    3004             :         case 0x2801: // Arabic(Syria)
    3005             :         case 0x1c01: // Arabic(Tunisia)
    3006             :         case 0x3801: // Arabic(U.A.E)
    3007             :         case 0x2401: // Arabic(Yemen)
    3008           0 :             bResult = true;
    3009           0 :             break;
    3010             :         default:
    3011           0 :             break;
    3012             :     }
    3013             : 
    3014           0 :     return bResult;
    3015             : }
    3016             : 
    3017           0 : sal_Unicode SwWW8ImplReader::TranslateToHindiNumbers(sal_Unicode nChar)
    3018             : {
    3019           0 :     if (nChar >= 0x0030 && nChar <= 0x0039)
    3020           0 :         return nChar + 0x0630;
    3021             : 
    3022           0 :     return nChar;
    3023             : }
    3024             : 
    3025             : /**
    3026             :  * Return value: true for non special chars
    3027             :  */
    3028       16734 : bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, sal_Int32 nEnd, sal_Int32 nCpOfs)
    3029             : {
    3030       16734 :     sal_Int32 nRequestedStrLen = nEnd - rPos;
    3031             : 
    3032             :     OSL_ENSURE(nRequestedStrLen, "String is 0");
    3033       16734 :     if (nRequestedStrLen <= 0)
    3034           0 :         return true;
    3035             : 
    3036       16734 :     sal_Int32 nRequestedPos = pSBase->WW8Cp2Fc(nCpOfs+rPos, &bIsUnicode);
    3037       16734 :     bool bValidPos = checkSeek(*pStrm, nRequestedPos);
    3038             :     OSL_ENSURE(bValidPos, "Document claimed to have more text than available");
    3039       16734 :     if (!bValidPos)
    3040             :     {
    3041             :         // Swallow missing range, e.g. #i95550#
    3042           0 :         rPos+=nRequestedStrLen;
    3043           0 :         return true;
    3044             :     }
    3045             : 
    3046       16734 :     sal_Size nAvailableStrLen = pStrm->remainingSize() / (bIsUnicode ? 2 : 1);
    3047             :     OSL_ENSURE(nAvailableStrLen, "Document claimed to have more text than available");
    3048       16734 :     if (!nAvailableStrLen)
    3049             :     {
    3050             :         // Swallow missing range, e.g. #i95550#
    3051           0 :         rPos+=nRequestedStrLen;
    3052           0 :         return true;
    3053             :     }
    3054             : 
    3055       16734 :     sal_Int32 nValidStrLen = std::min<sal_Size>(nRequestedStrLen, nAvailableStrLen);
    3056             : 
    3057             :     // Reset Unicode flag and correct FilePos if needed.
    3058             :     // Note: Seek is not expensive, as we're checking inline whether or not
    3059             :     // the correct FilePos has already been reached.
    3060       16734 :     const sal_Int32 nStrLen = std::min(nValidStrLen, SAL_MAX_INT32-1);
    3061             : 
    3062             :     rtl_TextEncoding eSrcCharSet = bVer67 ? GetCurrentCharSet() :
    3063       16734 :         RTL_TEXTENCODING_MS_1252;
    3064       16734 :     if (bVer67 && eSrcCharSet == RTL_TEXTENCODING_MS_932)
    3065             :     {
    3066             :         /*
    3067             :          fdo#82904
    3068             : 
    3069             :          Older documents exported as word 95 that use unicode aware fonts will
    3070             :          have the charset of those fonts set to RTL_TEXTENCODING_MS_932 on
    3071             :          export as the conversion from RTL_TEXTENCODING_UNICODE. This is a serious
    3072             :          pain.
    3073             : 
    3074             :          We will try and use a fallback encoding if the conversion from
    3075             :          RTL_TEXTENCODING_MS_932 fails, but you can get unlucky and get a document
    3076             :          which isn't really in RTL_TEXTENCODING_MS_932 but parts of it form
    3077             :          valid RTL_TEXTENCODING_MS_932 by chance :-(
    3078             : 
    3079             :          We're not the only ones that struggle with this: Here's the help from
    3080             :          MSOffice 2003 on the topic:
    3081             : 
    3082             :          <<
    3083             :           Earlier versions of Microsoft Word were sometimes used in conjunction with
    3084             :           third-party language-processing add-in programs designed to support Chinese or
    3085             :           Korean on English versions of Microsoft Windows. Use of these add-ins sometimes
    3086             :           results in incorrect text display in more recent versions of Word.
    3087             : 
    3088             :           However, you can set options to convert these documents so that text is
    3089             :           displayed correctly. On the Tools menu, click Options, and then click the
    3090             :           General tab. In the English Word 6.0/95 documents list, select Contain Asian
    3091             :           text (to have Word interpret the text as Asian code page data, regardless of
    3092             :           its font) or Automatically detect Asian text (to have Word attempt to determine
    3093             :           which parts of the text are meant to be Asian).
    3094             :         >>
    3095             : 
    3096             :         What we can try here is to ignore a RTL_TEXTENCODING_MS_932 codepage if
    3097             :         the language is not Japanese
    3098             :         */
    3099             : 
    3100           0 :         const SfxPoolItem * pItem = GetFmtAttr(RES_CHRATR_CJK_LANGUAGE);
    3101           0 :         if (pItem != NULL && LANGUAGE_JAPANESE != static_cast<const SvxLanguageItem *>(pItem)->GetLanguage())
    3102             :         {
    3103             :             SAL_WARN("sw.ww8", "discarding word95 RTL_TEXTENCODING_MS_932 encoding");
    3104           0 :             eSrcCharSet = GetCharSetFromLanguage();
    3105             :         }
    3106             :     }
    3107             :     const rtl_TextEncoding eSrcCJKCharSet = bVer67 ? GetCurrentCJKCharSet() :
    3108       16734 :         RTL_TEXTENCODING_MS_1252;
    3109             : 
    3110             :     // allocate unicode string data
    3111       16734 :     rtl_uString *pStr = rtl_uString_alloc(nStrLen);
    3112       16734 :     sal_Unicode* pBuffer = pStr->buffer;
    3113       16734 :     sal_Unicode* pWork = pBuffer;
    3114             : 
    3115       16734 :     sal_Char* p8Bits = NULL;
    3116             : 
    3117       16734 :     rtl_TextToUnicodeConverter hConverter = 0;
    3118       16734 :     if (!bIsUnicode || bVer67)
    3119       10496 :         hConverter = rtl_createTextToUnicodeConverter(eSrcCharSet);
    3120             : 
    3121       16734 :     if (!bIsUnicode)
    3122       10496 :         p8Bits = new sal_Char[nStrLen];
    3123             : 
    3124             :     // read the stream data
    3125       16734 :     sal_uInt8   nBCode = 0;
    3126             :     sal_uInt16 nUCode;
    3127             : 
    3128       16734 :     sal_uInt16 nCTLLang = 0;
    3129       16734 :     const SfxPoolItem * pItem = GetFmtAttr(RES_CHRATR_CTL_LANGUAGE);
    3130       16734 :     if (pItem != NULL)
    3131       16734 :         nCTLLang = static_cast<const SvxLanguageItem *>(pItem)->GetLanguage();
    3132             : 
    3133             :     sal_Int32 nL2;
    3134      363528 :     for( nL2 = 0; nL2 < nStrLen; ++nL2, ++pWork )
    3135             :     {
    3136      357224 :         if (bIsUnicode)
    3137       35518 :             pStrm->ReadUInt16( nUCode ); // unicode  --> read 2 bytes
    3138             :         else
    3139             :         {
    3140      321706 :             pStrm->ReadUChar( nBCode ); // old code --> read 1 byte
    3141      321706 :             nUCode = nBCode;
    3142             :         }
    3143             : 
    3144      357224 :         if (pStrm->GetError())
    3145             :         {
    3146           0 :             rPos = WW8_CP_MAX-10; // -> eof or other error
    3147           0 :             rtl_freeMemory(pStr);
    3148           0 :             delete [] p8Bits;
    3149           0 :             return true;
    3150             :         }
    3151             : 
    3152      357224 :         if ((32 > nUCode) || (0xa0 == nUCode))
    3153             :         {
    3154       10430 :             pStrm->SeekRel( bIsUnicode ? -2 : -1 );
    3155       10430 :             break; // Special character < 32, == 0xa0 found
    3156             :         }
    3157             : 
    3158      346794 :         if (bIsUnicode)
    3159             :         {
    3160       32148 :             if (!bVer67)
    3161       32148 :                 *pWork = nUCode;
    3162             :             else
    3163             :             {
    3164           0 :                 if (nUCode >= 0x3000) //0x8000 ?
    3165             :                 {
    3166             :                     sal_Char aTest[2];
    3167           0 :                     aTest[0] = static_cast< sal_Char >((nUCode & 0xFF00) >> 8);
    3168           0 :                     aTest[1] = static_cast< sal_Char >(nUCode & 0x00FF);
    3169           0 :                     OUString aTemp(aTest, 2, eSrcCJKCharSet);
    3170             :                     OSL_ENSURE(aTemp.getLength() == 1, "so much for that theory");
    3171           0 :                     *pWork = aTemp[0];
    3172             :                 }
    3173             :                 else
    3174             :                 {
    3175           0 :                     sal_Char cTest = static_cast< sal_Char >(nUCode & 0x00FF);
    3176           0 :                     Custom8BitToUnicode(hConverter, &cTest, 1, pWork, 1);
    3177             :                 }
    3178             :             }
    3179             :         }
    3180             :         else
    3181      314646 :             p8Bits[nL2] = nBCode;
    3182             :     }
    3183             : 
    3184       16734 :     if (nL2)
    3185             :     {
    3186        6788 :         const sal_Int32 nEndUsed = !bIsUnicode
    3187        3904 :             ? Custom8BitToUnicode(hConverter, p8Bits, nL2, pBuffer, nStrLen)
    3188       10692 :             : nL2;
    3189             : 
    3190      402764 :         for( sal_Int32 nI = 0; nI < nStrLen; ++nI, ++pBuffer )
    3191      395976 :             if (m_bRegardHindiDigits && bBidi && LangUsesHindiNumbers(nCTLLang))
    3192           0 :                 *pBuffer = TranslateToHindiNumbers(*pBuffer);
    3193             : 
    3194        6788 :         pStr->buffer[nEndUsed] = 0;
    3195        6788 :         pStr->length = nEndUsed;
    3196             : 
    3197        6788 :         emulateMSWordAddTextToParagraph(OUString(pStr, SAL_NO_ACQUIRE));
    3198        6788 :         pStr = NULL;
    3199        6788 :         rPos += nL2;
    3200        6788 :         if (!maApos.back()) // a para end in apo doesn't count
    3201        6778 :             bWasParaEnd = false; // No CR
    3202             :     }
    3203             : 
    3204       16734 :     if (hConverter)
    3205       10496 :         rtl_destroyTextToUnicodeConverter(hConverter);
    3206       16734 :     if (pStr)
    3207        9946 :         rtl_uString_release(pStr);
    3208       16734 :     delete [] p8Bits;
    3209       16734 :     return nL2 >= nStrLen;
    3210             : }
    3211             : 
    3212             : #define MSASCII SAL_MAX_INT16
    3213             : 
    3214             : namespace
    3215             : {
    3216             :     // We want to force weak chars inside 0x0020 to 0x007F to LATIN
    3217      544938 :     sal_Int16 lcl_getScriptType(
    3218             :         const uno::Reference<i18n::XBreakIterator>& rBI,
    3219             :         const OUString &rString, sal_Int32 nPos)
    3220             :     {
    3221      544938 :         sal_Int16 nScript = rBI->getScriptType(rString, nPos);
    3222      544938 :         if (nScript == i18n::ScriptType::WEAK && rString[nPos] >= 0x0020 && rString[nPos] <= 0x007F)
    3223      144548 :             nScript = MSASCII;
    3224      544938 :         return nScript;
    3225             :     }
    3226             : 
    3227             :     // We want to know about WEAK segments, so endOfScript isn't
    3228             :     // useful, and see lcl_getScriptType anyway
    3229      102466 :     sal_Int32 lcl_endOfScript(
    3230             :         const uno::Reference<i18n::XBreakIterator>& rBI,
    3231             :         const OUString &rString, sal_Int32 nPos, sal_Int16 nScript)
    3232             :     {
    3233      552676 :         while (nPos < rString.getLength())
    3234             :         {
    3235      442472 :             sal_Int16 nNewScript = lcl_getScriptType(rBI, rString, nPos);
    3236      442472 :             if (nScript != nNewScript)
    3237       94728 :                 break;
    3238      347744 :             ++nPos;
    3239             :         }
    3240      102466 :         return nPos;
    3241             :     }
    3242             : 
    3243       48464 :     sal_Int32 lcl_getWriterScriptType(
    3244             :         const uno::Reference<i18n::XBreakIterator>& rBI,
    3245             :         const OUString &rString, sal_Int32 nPos)
    3246             :     {
    3247       48464 :         sal_Int16 nScript = i18n::ScriptType::WEAK;
    3248             : 
    3249       48464 :         if (rString.isEmpty())
    3250           0 :             return nScript;
    3251             : 
    3252      145764 :         while (nPos >= 0)
    3253             :         {
    3254       97210 :             nScript = rBI->getScriptType(rString, nPos);
    3255       97210 :             if (nScript != i18n::ScriptType::WEAK)
    3256       48374 :                 break;
    3257       48836 :             --nPos;
    3258             :         }
    3259             : 
    3260       48464 :         return nScript;
    3261             :     }
    3262             : 
    3263           2 :     bool samePitchIgnoreUnknown(FontPitch eA, FontPitch eB)
    3264             :     {
    3265           2 :         return (eA == eB || eA == PITCH_DONTKNOW || eB == PITCH_DONTKNOW);
    3266             :     }
    3267             : 
    3268        1444 :     bool sameFontIgnoringIrrelevantFields(const SvxFontItem &rA, const SvxFontItem &rB)
    3269             :     {
    3270             :         // Ignoring CharSet, and ignoring unknown pitch
    3271        1446 :         return rA.GetFamilyName() == rB.GetFamilyName() &&
    3272           4 :             rA.GetStyleName() == rB.GetStyleName() &&
    3273        1448 :             rA.GetFamily() == rB.GetFamily() &&
    3274        1446 :             samePitchIgnoreUnknown(rA.GetPitch(), rB.GetPitch());
    3275             :     }
    3276             : }
    3277             : 
    3278             : // In writer we categorize text into CJK, CTL and "Western" for everything else.
    3279             : // Microsoft Word basically categorizes text into East Asian, Complex, ASCII,
    3280             : // NonEastAsian/HighAnsi, with some shared characters and some properties to
    3281             : // hint as to which way to bias those shared characters.
    3282             : 
    3283             : // That's four categories, we however have three categories. Given that problem
    3284             : // here we would ideally find out "what would word do" to see what font/language
    3285             : // word would assign to characters based on the unicode range they fall into and
    3286             : // hack the word one onto the range we use. However it's unclear what word's
    3287             : // categorization is. So we don't do that here yet.
    3288             : 
    3289             : // Additional to the categorization, when word encounters weak text for ambigious
    3290             : // chars it uses idcthint to indicate which way to bias. We don't have a idcthint
    3291             : // feature in writer.
    3292             : 
    3293             : // So what we currently do here then is to split our text into non-weak/weak
    3294             : // sections and uses word's idcthint to determine what font it would use and
    3295             : // force that on for the segment. Following what we *do* know about word's
    3296             : // categorization, we know that the range 0x0020 and 0x007F is sprmCRgFtc0 in
    3297             : // word, something we map to LATIN, so we consider all weaks chars in that range
    3298             : // to auto-bias to LATIN.
    3299             : 
    3300             : // See https://bugs.libreoffice.org/show_bug.cgi?id=34319 for an example
    3301             : //
    3302             : // TO-DO: revisit this after the fix of #i119612# which retains the
    3303             : // idcthint feature on import from word and has it available for reexport
    3304             : // but we don't use it yet for the actual rendering and layout
    3305        7738 : void SwWW8ImplReader::emulateMSWordAddTextToParagraph(const OUString& rAddString)
    3306             : {
    3307        7738 :     if (rAddString.isEmpty())
    3308           0 :         return;
    3309             : 
    3310        7738 :     uno::Reference<i18n::XBreakIterator> xBI(g_pBreakIt->GetBreakIter());
    3311        7738 :     if (!xBI.is())
    3312             :     {
    3313           0 :         simpleAddTextToParagraph(rAddString);
    3314           0 :         return;
    3315             :     }
    3316             : 
    3317        7738 :     sal_Int16 nScript = lcl_getScriptType(xBI, rAddString, 0);
    3318        7738 :     sal_Int32 nLen = rAddString.getLength();
    3319             : 
    3320       15476 :     OUString sParagraphText;
    3321        7738 :     const SwCntntNode *pCntNd = pPaM->GetCntntNode();
    3322        7738 :     const SwTxtNode* pNd = pCntNd ? pCntNd->GetTxtNode() : NULL;
    3323        7738 :     if (pNd)
    3324        7738 :         sParagraphText = pNd->GetTxt();
    3325        7738 :     sal_Int32 nParaOffset = sParagraphText.getLength();
    3326        7738 :     sParagraphText = sParagraphText + rAddString;
    3327             : 
    3328        7738 :     sal_Int32 nPos = 0;
    3329      117942 :     while (nPos < nLen)
    3330             :     {
    3331      102466 :         sal_Int32 nEnd = lcl_endOfScript(xBI, rAddString, nPos, nScript);
    3332      102466 :         if (nEnd < 0)
    3333           0 :             break;
    3334             : 
    3335      102466 :         OUString sChunk(rAddString.copy(nPos, nEnd-nPos));
    3336      102466 :         const sal_uInt16 aIds[] = {RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT};
    3337      102466 :         const SvxFontItem *pOverriddenItems[] = {NULL, NULL, NULL};
    3338      102466 :         bool aForced[] = {false, false, false};
    3339             : 
    3340      102466 :         int nLclIdctHint = 0xFF;
    3341      102466 :         if (nScript == i18n::ScriptType::WEAK)
    3342         398 :             nLclIdctHint = nIdctHint;
    3343      102068 :         else if (nScript == MSASCII) // Force weak chars in ascii range to use LATIN font
    3344       48066 :             nLclIdctHint = 0;
    3345             : 
    3346      102466 :         sal_uInt16 nForceFromFontId = 0;
    3347      102466 :         if (nLclIdctHint != 0xFF)
    3348             :         {
    3349       48464 :             switch (nLclIdctHint)
    3350             :             {
    3351             :                 case 0:
    3352       48464 :                     nForceFromFontId = RES_CHRATR_FONT;
    3353       48464 :                     break;
    3354             :                 case 1:
    3355           0 :                     nForceFromFontId = RES_CHRATR_CJK_FONT;
    3356           0 :                     break;
    3357             :                 case 2:
    3358           0 :                     nForceFromFontId = RES_CHRATR_CTL_FONT;
    3359           0 :                     break;
    3360             :                 default:
    3361           0 :                     break;
    3362             :             }
    3363             :         }
    3364             : 
    3365      102466 :         if (nForceFromFontId != 0)
    3366             :         {
    3367             :             // Now we know that word would use the nForceFromFontId font for this range
    3368             :             // Try and determine what script writer would assign this range to
    3369             : 
    3370             :             sal_Int32 nWriterScript = lcl_getWriterScriptType(xBI, sParagraphText,
    3371       48464 :                 nPos + nParaOffset);
    3372             : 
    3373       48464 :             bool bWriterWillUseSameFontAsWordAutomatically = false;
    3374             : 
    3375       48464 :             if (nWriterScript != i18n::ScriptType::WEAK)
    3376             :             {
    3377       48374 :                 if (
    3378           0 :                      (nWriterScript == i18n::ScriptType::ASIAN && nForceFromFontId == RES_CHRATR_CJK_FONT) ||
    3379        1444 :                      (nWriterScript == i18n::ScriptType::COMPLEX && nForceFromFontId == RES_CHRATR_CTL_FONT) ||
    3380       46930 :                      (nWriterScript == i18n::ScriptType::LATIN && nForceFromFontId == RES_CHRATR_FONT)
    3381             :                    )
    3382             :                 {
    3383       46930 :                     bWriterWillUseSameFontAsWordAutomatically = true;
    3384             :                 }
    3385             :                 else
    3386             :                 {
    3387        1444 :                     const SvxFontItem *pSourceFont = (const SvxFontItem*)GetFmtAttr(nForceFromFontId);
    3388        1444 :                     sal_uInt16 nDestId = aIds[nWriterScript-1];
    3389        1444 :                     const SvxFontItem *pDestFont = (const SvxFontItem*)GetFmtAttr(nDestId);
    3390        1444 :                     bWriterWillUseSameFontAsWordAutomatically = sameFontIgnoringIrrelevantFields(*pSourceFont, *pDestFont);
    3391             :                 }
    3392             :             }
    3393             : 
    3394             :             // Writer won't use the same font as word, so force the issue
    3395       48464 :             if (!bWriterWillUseSameFontAsWordAutomatically)
    3396             :             {
    3397        1532 :                 const SvxFontItem *pSourceFont = (const SvxFontItem*)GetFmtAttr(nForceFromFontId);
    3398             : 
    3399        6128 :                 for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
    3400             :                 {
    3401        4596 :                     const SvxFontItem *pDestFont = (const SvxFontItem*)GetFmtAttr(aIds[i]);
    3402        4596 :                     aForced[i] = aIds[i] != nForceFromFontId && *pSourceFont != *pDestFont;
    3403        4596 :                     if (aForced[i])
    3404             :                     {
    3405             :                         pOverriddenItems[i] =
    3406        2932 :                             (const SvxFontItem*)pCtrlStck->GetStackAttr(*pPaM->GetPoint(), aIds[i]);
    3407             : 
    3408        2932 :                         SvxFontItem aForceFont(*pSourceFont);
    3409        2932 :                         aForceFont.SetWhich(aIds[i]);
    3410        2932 :                         pCtrlStck->NewAttr(*pPaM->GetPoint(), aForceFont);
    3411             :                     }
    3412             :                 }
    3413             :             }
    3414             :         }
    3415             : 
    3416      102466 :         simpleAddTextToParagraph(sChunk);
    3417             : 
    3418      409864 :         for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
    3419             :         {
    3420      307398 :             if (aForced[i])
    3421             :             {
    3422        2932 :                 pCtrlStck->SetAttr(*pPaM->GetPoint(), aIds[i]);
    3423        2932 :                 if (pOverriddenItems[i])
    3424        1448 :                     pCtrlStck->NewAttr(*pPaM->GetPoint(), *(pOverriddenItems[i]));
    3425             :             }
    3426             :         }
    3427             : 
    3428      102466 :         nPos = nEnd;
    3429      102466 :         if (nPos < nLen)
    3430       94728 :             nScript = lcl_getScriptType(xBI, rAddString, nPos);
    3431      110204 :     }
    3432             : }
    3433             : 
    3434      102466 : void SwWW8ImplReader::simpleAddTextToParagraph(const OUString& rAddString)
    3435             : {
    3436      102466 :     if (rAddString.isEmpty())
    3437           0 :         return;
    3438             : 
    3439             : #if OSL_DEBUG_LEVEL > 1
    3440             :         {
    3441             :             OString sText(OUStringToOString(rAddString, RTL_TEXTENCODING_UTF8));
    3442             :             SAL_INFO("sw.ww8", "<addTextToParagraph>" << sText.getStr() << "</addTextToParagraph>");
    3443             :         }
    3444             : #endif
    3445             : 
    3446      102466 :     const SwCntntNode *pCntNd = pPaM->GetCntntNode();
    3447      102466 :     const SwTxtNode* pNd = pCntNd ? pCntNd->GetTxtNode() : NULL;
    3448             : 
    3449             :     OSL_ENSURE(pNd, "What the hell, where's my text node");
    3450             : 
    3451      102466 :     if (!pNd)
    3452           0 :         return;
    3453             : 
    3454      102466 :     const sal_Int32 nCharsLeft = SAL_MAX_INT32 - pNd->GetTxt().getLength();
    3455      102466 :     if (nCharsLeft > 0)
    3456             :     {
    3457      102466 :         if (rAddString.getLength() <= nCharsLeft)
    3458             :         {
    3459      102466 :             rDoc.getIDocumentContentOperations().InsertString(*pPaM, rAddString);
    3460             :         }
    3461             :         else
    3462             :         {
    3463           0 :             rDoc.getIDocumentContentOperations().InsertString(*pPaM, rAddString.copy(0, nCharsLeft));
    3464           0 :             AppendTxtNode(*pPaM->GetPoint());
    3465           0 :             rDoc.getIDocumentContentOperations().InsertString(*pPaM, rAddString.copy(nCharsLeft));
    3466             :         }
    3467             :     }
    3468             :     else
    3469             :     {
    3470           0 :         AppendTxtNode(*pPaM->GetPoint());
    3471           0 :         rDoc.getIDocumentContentOperations().InsertString(*pPaM, rAddString);
    3472             :     }
    3473             : 
    3474      102466 :     bReadTable = false;
    3475             : }
    3476             : 
    3477             : /**
    3478             :  * Return value: true for para end
    3479             :  */
    3480       15066 : bool SwWW8ImplReader::ReadChars(WW8_CP& rPos, WW8_CP nNextAttr, long nTextEnd,
    3481             :     long nCpOfs)
    3482             : {
    3483       15066 :     long nEnd = ( nNextAttr < nTextEnd ) ? nNextAttr : nTextEnd;
    3484             : 
    3485       15066 :     if (bSymbol || bIgnoreText)
    3486             :     {
    3487           8 :         if( bSymbol ) // Insert special chars
    3488             :         {
    3489           0 :             for(sal_uInt16 nCh = 0; nCh < nEnd - rPos; ++nCh)
    3490             :             {
    3491           0 :                 rDoc.getIDocumentContentOperations().InsertString( *pPaM, OUString(cSymbol) );
    3492             :             }
    3493           0 :             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_FONT );
    3494             :         }
    3495           8 :         pStrm->SeekRel( nEnd- rPos );
    3496           8 :         rPos = nEnd; // Ignore until attribute end
    3497           8 :         return false;
    3498             :     }
    3499             : 
    3500             :     while (true)
    3501             :     {
    3502       16734 :         if (ReadPlainChars(rPos, nEnd, nCpOfs))
    3503        6304 :             return false; // Done
    3504             : 
    3505       10430 :         bool bStartLine = ReadChar(rPos, nCpOfs);
    3506       10430 :         rPos++;
    3507       10430 :         if (bPgSecBreak || bStartLine || rPos == nEnd) // CR or Done
    3508             :         {
    3509        8754 :             return bStartLine;
    3510             :         }
    3511        1676 :     }
    3512             : }
    3513             : 
    3514         124 : bool SwWW8ImplReader::HandlePageBreakChar()
    3515             : {
    3516         124 :     bool bParaEndAdded = false;
    3517             :     // #i1909# section/page breaks should not occur in tables, word
    3518             :     // itself ignores them in this case.
    3519         124 :     if (!nInTable)
    3520             :     {
    3521         124 :         bool IsTemp=true;
    3522         124 :         SwTxtNode* pTemp = pPaM->GetNode().GetTxtNode();
    3523         248 :         if (pTemp && pTemp->GetTxt().isEmpty()
    3524         232 :                 && (bFirstPara || bFirstParaOfPage))
    3525             :         {
    3526           6 :             IsTemp = false;
    3527           6 :             AppendTxtNode(*pPaM->GetPoint());
    3528           6 :             pTemp->SetAttr(*GetDfltAttr(RES_PARATR_NUMRULE));
    3529             :         }
    3530             : 
    3531         124 :         bPgSecBreak = true;
    3532         124 :         pCtrlStck->KillUnlockedAttrs(*pPaM->GetPoint());
    3533             :         /*
    3534             :         If it's a 0x0c without a paragraph end before it, act like a
    3535             :         paragraph end, but nevertheless, numbering (and perhaps other
    3536             :         similar constructs) do not exist on the para.
    3537             :         */
    3538         124 :         if (!bWasParaEnd && IsTemp)
    3539             :         {
    3540          20 :             bParaEndAdded = true;
    3541          20 :             if (0 >= pPaM->GetPoint()->nContent.GetIndex())
    3542             :             {
    3543           4 :                 if (SwTxtNode* pTxtNode = pPaM->GetNode().GetTxtNode())
    3544             :                 {
    3545             :                     pTxtNode->SetAttr(
    3546           4 :                         *GetDfltAttr(RES_PARATR_NUMRULE));
    3547             :                 }
    3548             :             }
    3549             :         }
    3550             :     }
    3551         124 :     return bParaEndAdded;
    3552             : }
    3553             : 
    3554       10430 : bool SwWW8ImplReader::ReadChar(long nPosCp, long nCpOfs)
    3555             : {
    3556       10430 :     bool bNewParaEnd = false;
    3557             :     // Reset Unicode flag and correct FilePos if needed.
    3558             :     // Note: Seek is not expensive, as we're checking inline whether or not
    3559             :     // the correct FilePos has already been reached.
    3560       10430 :     sal_Size nRequestedPos = pSBase->WW8Cp2Fc(nCpOfs+nPosCp, &bIsUnicode);
    3561       10430 :     if (!checkSeek(*pStrm, nRequestedPos))
    3562           0 :         return false;
    3563             : 
    3564       10430 :     sal_uInt8 nBCode(0);
    3565       10430 :     sal_uInt16 nWCharVal(0);
    3566       10430 :     if( bIsUnicode )
    3567        3370 :         pStrm->ReadUInt16( nWCharVal ); // unicode  --> read 2 bytes
    3568             :     else
    3569             :     {
    3570        7060 :         pStrm -> ReadUChar( nBCode ); // old code --> read 1 byte
    3571        7060 :         nWCharVal = nBCode;
    3572             :     }
    3573             : 
    3574       10430 :     sal_Unicode cInsert = '\x0';
    3575       10430 :     bool bRet = false;
    3576             : 
    3577       10430 :     if ( 0xc != nWCharVal )
    3578       10306 :         bFirstParaOfPage = false;
    3579             : 
    3580       10430 :     switch (nWCharVal)
    3581             :     {
    3582             :         case 0:
    3583             :             {
    3584             :                 // Page number
    3585             :                 SwPageNumberField aFld(
    3586         940 :                     (SwPageNumberFieldType*)rDoc.getIDocumentFieldsAccess().GetSysFldType(
    3587         940 :                     RES_PAGENUMBERFLD ), PG_RANDOM, SVX_NUM_ARABIC);
    3588         940 :                 rDoc.getIDocumentContentOperations().InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
    3589             :             }
    3590         940 :             break;
    3591             :         case 0xe:
    3592             :             // if there is only one column word treats a column break like a pagebreak.
    3593           0 :             if (maSectionManager.CurrentSectionColCount() < 2)
    3594           0 :                 bRet = HandlePageBreakChar();
    3595           0 :             else if (!nInTable)
    3596             :             {
    3597             :                 // Always insert a txtnode for a column break, e.g. ##
    3598           0 :                 SwCntntNode *pCntNd=pPaM->GetCntntNode();
    3599           0 :                 if (pCntNd!=NULL && pCntNd->Len()>0) // if par is empty not break is needed
    3600           0 :                     AppendTxtNode(*pPaM->GetPoint());
    3601           0 :                 rDoc.getIDocumentContentOperations().InsertPoolItem(*pPaM, SvxFmtBreakItem(SVX_BREAK_COLUMN_BEFORE, RES_BREAK), 0);
    3602             :             }
    3603           0 :             break;
    3604             :         case 0x7:
    3605        2192 :             bNewParaEnd = true;
    3606        2192 :             TabCellEnd();       // Table cell end (query flags!)
    3607        2192 :             break;
    3608             :         case 0xf:
    3609           0 :             if( !bSpec )        // "Satellite"
    3610           0 :                 cInsert = sal_Unicode('\xa4');
    3611           0 :             break;
    3612             :         case 0x14:
    3613          40 :             if( !bSpec )        // "Para End" char
    3614           0 :                 cInsert = sal_Unicode('\xb5');
    3615          40 :             break;
    3616             :         case 0x15:
    3617          42 :             if( !bSpec )        // Juristenparagraph
    3618             :             {
    3619           0 :                 cp_set::iterator aItr = maTOXEndCps.find((WW8_CP)nPosCp);
    3620           0 :                 if (aItr == maTOXEndCps.end())
    3621           0 :                     cInsert = sal_Unicode('\xa7');
    3622             :                 else
    3623           0 :                     maTOXEndCps.erase(aItr);
    3624             :             }
    3625          42 :             break;
    3626             :         case 0x9:
    3627         912 :             cInsert = '\x9';    // Tab
    3628         912 :             break;
    3629             :         case 0xb:
    3630          32 :             cInsert = '\xa';    // Hard NewLine
    3631          32 :             break;
    3632             :         case 0xc:
    3633         124 :             bRet = HandlePageBreakChar();
    3634         124 :             break;
    3635             :         case 0x1e:              // Non-breaking hyphen
    3636           0 :             rDoc.getIDocumentContentOperations().InsertString( *pPaM, OUString(CHAR_HARDHYPHEN) );
    3637           0 :             break;
    3638             :         case 0x1f:              // Non-required hyphens
    3639           0 :             rDoc.getIDocumentContentOperations().InsertString( *pPaM, OUString(CHAR_SOFTHYPHEN) );
    3640           0 :             break;
    3641             :         case 0xa0:              // Non-breaking spaces
    3642           4 :             rDoc.getIDocumentContentOperations().InsertString( *pPaM, OUString(CHAR_HARDBLANK)  );
    3643           4 :             break;
    3644             :         case 0x1:
    3645             :             /*
    3646             :             Current thinking is that if bObj is set then we have a
    3647             :             straightforward "traditional" ole object, otherwise we have a
    3648             :             graphic preview of an associated ole2 object (or a simple
    3649             :             graphic of course)
    3650             : 
    3651             :             normally in the canvas field, the code is 0x8 0x1.
    3652             :             in a special case, the code is 0x1 0x1, which yields a simple picture
    3653             :             */
    3654             :             {
    3655          50 :                 bool bReadObj = IsInlineEscherHack();
    3656          50 :                 if( bReadObj )
    3657             :                 {
    3658           6 :                     long nCurPos = pStrm->Tell();
    3659           6 :                     sal_uInt16 nWordCode(0);
    3660             : 
    3661           6 :                     if( bIsUnicode )
    3662           4 :                         pStrm->ReadUInt16( nWordCode );
    3663             :                     else
    3664             :                     {
    3665           2 :                         sal_uInt8 nByteCode(0);
    3666           2 :                         pStrm->ReadUChar( nByteCode );
    3667           2 :                         nWordCode = nByteCode;
    3668             :                     }
    3669           6 :                     if( nWordCode == 0x1 )
    3670           0 :                         bReadObj = false;
    3671           6 :                     pStrm->Seek( nCurPos );
    3672             :                 }
    3673          50 :                 if( !bReadObj )
    3674             :                 {
    3675          44 :                     SwFrmFmt *pResult = 0;
    3676          44 :                     if (bObj)
    3677           0 :                         pResult = ImportOle();
    3678          44 :                     else if (bSpec)
    3679          42 :                         pResult = ImportGraf();
    3680             : 
    3681             :                     // If we have a bad 0x1 insert a space instead.
    3682          44 :                     if (!pResult)
    3683             :                     {
    3684           2 :                         cInsert = ' ';
    3685             :                         OSL_ENSURE(!bObj && !bEmbeddObj && !nObjLocFc,
    3686             :                             "WW8: Please report this document, it may have a "
    3687             :                             "missing graphic");
    3688             :                     }
    3689             :                     else
    3690             :                     {
    3691             :                         // reset the flags.
    3692          42 :                         bObj = bEmbeddObj = false;
    3693          42 :                         nObjLocFc = 0;
    3694             :                     }
    3695             :                 }
    3696             :             }
    3697          50 :             break;
    3698             :         case 0x8:
    3699         184 :             if( !bObj )
    3700         184 :                 Read_GrafLayer( nPosCp );
    3701         184 :             break;
    3702             :         case 0xd:
    3703        5728 :             bNewParaEnd = bRet = true;
    3704        5728 :             if (nInTable > 1)
    3705             :             {
    3706             :                 /*
    3707             :                 #i9666#/#i23161#
    3708             :                 Yes complex, if there is an entry in the undocumented PLCF
    3709             :                 which I believe to be a record of cell and row boundaries
    3710             :                 see if the magic bit which I believe to mean cell end is
    3711             :                 set. I also think btw that the third byte of the 4 byte
    3712             :                 value is the level of the cell
    3713             :                 */
    3714         216 :                 WW8PLCFspecial* pTest = pPlcxMan->GetMagicTables();
    3715         432 :                 if (pTest && pTest->SeekPosExact(nPosCp+1+nCpOfs) &&
    3716         216 :                     pTest->Where() == nPosCp+1+nCpOfs)
    3717             :                 {
    3718             :                     WW8_FC nPos;
    3719             :                     void *pData;
    3720         216 :                     pTest->Get(nPos, pData);
    3721         216 :                     sal_uInt32 nData = SVBT32ToUInt32(*(SVBT32*)pData);
    3722         216 :                     if (nData & 0x2) // Might be how it works
    3723             :                     {
    3724         216 :                         TabCellEnd();
    3725         216 :                         bRet = false;
    3726             :                     }
    3727             :                 }
    3728           0 :                 else if (bWasTabCellEnd)
    3729             :                 {
    3730           0 :                     TabCellEnd();
    3731           0 :                     bRet = false;
    3732             :                 }
    3733             :             }
    3734             : 
    3735        5728 :             bWasTabCellEnd = false;
    3736             : 
    3737        5728 :             break;              // line end
    3738             :         case 0x5:               // Annotation reference
    3739             :         case 0x13:
    3740          32 :             break;
    3741             :         case 0x2:               // TODO: Auto-Footnote-Number, should be replaced by SwWW8ImplReader::End_Ftn later
    3742           4 :             if (!maFtnStack.empty())
    3743           4 :                 cInsert = 0x2;
    3744           4 :             break;
    3745             :         default:
    3746             :             SAL_INFO( "sw.ww8.level2", "<unknownValue val=\"" << nWCharVal << "\">" );
    3747         146 :             break;
    3748             :     }
    3749             : 
    3750       10430 :     if( '\x0' != cInsert )
    3751             :     {
    3752         950 :         OUString sInsert(cInsert);
    3753         950 :         emulateMSWordAddTextToParagraph(sInsert);
    3754             :     }
    3755       10430 :     if (!maApos.back()) // a para end in apo doesn't count
    3756       10418 :         bWasParaEnd = bNewParaEnd;
    3757       10430 :     return bRet;
    3758             : }
    3759             : 
    3760       13064 : void SwWW8ImplReader::ProcessAktCollChange(WW8PLCFManResult& rRes,
    3761             :     bool* pStartAttr, bool bCallProcessSpecial)
    3762             : {
    3763       13064 :     sal_uInt16 nOldColl = nAktColl;
    3764       13064 :     nAktColl = pPlcxMan->GetColl();
    3765             : 
    3766             :     // Invalid Style-Id
    3767       13064 :     if (nAktColl >= vColl.size() || !vColl[nAktColl].pFmt || !vColl[nAktColl].bColl)
    3768             :     {
    3769           0 :         nAktColl = 0;
    3770           0 :         bParaAutoBefore = false;
    3771           0 :         bParaAutoAfter = false;
    3772             :     }
    3773             :     else
    3774             :     {
    3775       13064 :         bParaAutoBefore = vColl[nAktColl].bParaAutoBefore;
    3776       13064 :         bParaAutoAfter = vColl[nAktColl].bParaAutoAfter;
    3777             :     }
    3778             : 
    3779       13064 :     if (nOldColl >= vColl.size())
    3780           0 :         nOldColl = 0; // guess! TODO make sure this is what we want
    3781             : 
    3782       13064 :     bool bTabRowEnd = false;
    3783       13064 :     if( pStartAttr && bCallProcessSpecial && !bInHyperlink )
    3784             :     {
    3785             :         bool bReSync;
    3786             :         // Frame/Table/Autonumbering List Level
    3787        7982 :         bTabRowEnd = ProcessSpecial(bReSync, rRes.nAktCp+pPlcxMan->GetCpOfs());
    3788        7982 :         if( bReSync )
    3789        3190 :             *pStartAttr = pPlcxMan->Get( &rRes ); // Get Attribut-Pos again
    3790             :     }
    3791             : 
    3792       13064 :     if (!bTabRowEnd && StyleExists(nAktColl))
    3793             :     {
    3794       12520 :         SetTxtFmtCollAndListLevel( *pPaM, vColl[ nAktColl ]);
    3795       12520 :         ChkToggleAttr(vColl[ nOldColl ].n81Flags, vColl[ nAktColl ].n81Flags);
    3796       12520 :         ChkToggleBiDiAttr(vColl[nOldColl].n81BiDiFlags,
    3797       25040 :             vColl[nAktColl].n81BiDiFlags);
    3798             :     }
    3799       13064 : }
    3800             : 
    3801      189870 : long SwWW8ImplReader::ReadTextAttr(WW8_CP& rTxtPos, bool& rbStartLine)
    3802             : {
    3803      189870 :     long nSkipChars = 0;
    3804             :     WW8PLCFManResult aRes;
    3805             : 
    3806             :     OSL_ENSURE(pPaM->GetNode().GetTxtNode(), "Missing txtnode");
    3807      189870 :     bool bStartAttr = pPlcxMan->Get(&aRes); // Get Attribute position again
    3808      189870 :     aRes.nAktCp = rTxtPos;                  // Current Cp position
    3809             : 
    3810      189870 :     bool bNewSection = (aRes.nFlags & MAN_MASK_NEW_SEP) && !bIgnoreText;
    3811      189870 :     if ( bNewSection ) // New Section
    3812             :     {
    3813             :         OSL_ENSURE(pPaM->GetNode().GetTxtNode(), "Missing txtnode");
    3814             :         // Create PageDesc and fill it
    3815         222 :         maSectionManager.CreateSep(rTxtPos, bPgSecBreak);
    3816             :         // -> 0xc was a Sectionbreak, but not a Pagebreak;
    3817             :         // Create PageDesc and fill it
    3818         222 :         bPgSecBreak = false;
    3819             :         OSL_ENSURE(pPaM->GetNode().GetTxtNode(), "Missing txtnode");
    3820             :     }
    3821             : 
    3822             :     // New paragraph over Plcx.Fkp.papx
    3823      189870 :     if ( (aRes.nFlags & MAN_MASK_NEW_PAP)|| rbStartLine )
    3824             :     {
    3825             :         ProcessAktCollChange( aRes, &bStartAttr,
    3826       21046 :             MAN_MASK_NEW_PAP == (aRes.nFlags & MAN_MASK_NEW_PAP) &&
    3827       21046 :             !bIgnoreText );
    3828       13064 :         rbStartLine = false;
    3829             :     }
    3830             : 
    3831             :     // position of last CP that's to be ignored
    3832      189870 :     long nSkipPos = -1;
    3833             : 
    3834      189870 :     if( 0 < aRes.nSprmId ) // Ignore empty Attrs
    3835             :     {
    3836      158372 :         if( ( eFTN > aRes.nSprmId ) || ( 0x0800 <= aRes.nSprmId ) )
    3837             :         {
    3838      315788 :             if( bStartAttr ) // WW attributes
    3839             :             {
    3840       79940 :                 if( aRes.nMemLen >= 0 )
    3841       79940 :                     ImportSprm(aRes.pMemPos, aRes.nSprmId);
    3842             :             }
    3843             :             else
    3844       77954 :                 EndSprm( aRes.nSprmId ); // Switch off Attr
    3845             :         }
    3846         478 :         else if( aRes.nSprmId < 0x800 ) // Own helper attributes
    3847             :         {
    3848         478 :             if (bStartAttr)
    3849             :             {
    3850         288 :                 nSkipChars = ImportExtSprm(&aRes);
    3851         288 :                 if (
    3852         860 :                     (aRes.nSprmId == eFTN) || (aRes.nSprmId == eEDN) ||
    3853         412 :                     (aRes.nSprmId == eFLD) || (aRes.nSprmId == eAND)
    3854             :                    )
    3855             :                 {
    3856             :                     // Skip Field/Ftn-/End-Note here
    3857         192 :                     rTxtPos += nSkipChars;
    3858         192 :                     nSkipPos = rTxtPos-1;
    3859             :                 }
    3860             :             }
    3861             :             else
    3862         190 :                 EndExtSprm( aRes.nSprmId );
    3863             :         }
    3864             :     }
    3865             : 
    3866      189870 :     pStrm->Seek(pSBase->WW8Cp2Fc( pPlcxMan->GetCpOfs() + rTxtPos, &bIsUnicode));
    3867             : 
    3868             :     // Find next Attr position (and Skip attributes of field contents if needed)
    3869      189870 :     if (nSkipChars && !bIgnoreText)
    3870          68 :         pCtrlStck->MarkAllAttrsOld();
    3871      189870 :     bool bOldIgnoreText = bIgnoreText;
    3872      189870 :     bIgnoreText = true;
    3873      189870 :     sal_uInt16 nOldColl = nAktColl;
    3874      189870 :     bool bDoPlcxManPlusPLus = true;
    3875             :     long nNext;
    3876      192110 :     do
    3877             :     {
    3878      192110 :         if( bDoPlcxManPlusPLus )
    3879      189870 :             pPlcxMan->advance();
    3880      192110 :         nNext = pPlcxMan->Where();
    3881             : 
    3882      192110 :         if (mpPostProcessAttrsInfo &&
    3883           0 :             mpPostProcessAttrsInfo->mnCpStart == nNext)
    3884             :         {
    3885           0 :             mpPostProcessAttrsInfo->mbCopy = true;
    3886             :         }
    3887             : 
    3888      192110 :         if( (0 <= nNext) && (nSkipPos >= nNext) )
    3889             :         {
    3890        2330 :             nNext = ReadTextAttr( rTxtPos, rbStartLine );
    3891        2330 :             bDoPlcxManPlusPLus = false;
    3892        2330 :             bIgnoreText = true;
    3893             :         }
    3894             : 
    3895      192110 :         if (mpPostProcessAttrsInfo &&
    3896           0 :             nNext > mpPostProcessAttrsInfo->mnCpEnd)
    3897             :         {
    3898           0 :             mpPostProcessAttrsInfo->mbCopy = false;
    3899             :         }
    3900             :     }
    3901             :     while( nSkipPos >= nNext );
    3902      189870 :     bIgnoreText    = bOldIgnoreText;
    3903      189870 :     if( nSkipChars )
    3904             :     {
    3905          68 :         pCtrlStck->KillUnlockedAttrs( *pPaM->GetPoint() );
    3906          68 :         if( nOldColl != pPlcxMan->GetColl() )
    3907           0 :             ProcessAktCollChange(aRes, 0, false);
    3908             :     }
    3909             : 
    3910      189870 :     return nNext;
    3911             : }
    3912             : 
    3913             : //Revised 2012.8.16 for the complex attribute presentation of 0x0D in MS
    3914       45560 : bool SwWW8ImplReader::IsParaEndInCPs(sal_Int32 nStart, sal_Int32 nEnd,bool bSdOD) const
    3915             : {
    3916             :     //Revised for performance consideration
    3917       45560 :     if (nStart == -1 || nEnd == -1 || nEnd < nStart )
    3918           0 :         return false;
    3919             : 
    3920     1669214 :     for (cp_vector::const_reverse_iterator aItr = maEndParaPos.rbegin(); aItr!= maEndParaPos.rend(); ++aItr)
    3921             :     {
    3922             :         //Revised 2012.8.16,to the 0x0D,the attribute will have two situations
    3923             :         //*********within***********exact******
    3924             :         //*********but also sample with only left and the position of 0x0d is the edge of the right side***********
    3925     1629540 :         if ( bSdOD && ( (nStart < *aItr && nEnd > *aItr) || ( nStart == nEnd && *aItr == nStart)) )
    3926        7250 :             return true;
    3927     1628176 :         else if ( !bSdOD &&  (nStart < *aItr && nEnd >= *aItr) )
    3928        4522 :             return true;
    3929             :     }
    3930             : 
    3931       39674 :     return false;
    3932             : }
    3933             : 
    3934             : //Clear the para end position recorded in reader intermittently for the least impact on loading performance
    3935         274 : void SwWW8ImplReader::ClearParaEndPosition()
    3936             : {
    3937         274 :     if ( maEndParaPos.size() > 0 )
    3938          22 :         maEndParaPos.clear();
    3939         274 : }
    3940             : 
    3941       15066 : void SwWW8ImplReader::ReadAttrs(WW8_CP& rNext, WW8_CP& rTxtPos, bool& rbStartLine)
    3942             : {
    3943             :     // Dow we have attributes?
    3944       15066 :     if( rTxtPos >= rNext )
    3945             :     {
    3946      187540 :         do
    3947             :         {
    3948      187540 :             maCurrAttrCP = rTxtPos;
    3949      187540 :             rNext = ReadTextAttr( rTxtPos, rbStartLine );
    3950             :         }
    3951      187540 :         while( rTxtPos >= rNext );
    3952             : 
    3953             :     }
    3954          78 :     else if ( rbStartLine )
    3955             :     {
    3956             :     /* No attributes, but still a new line.
    3957             :      * If a line ends with a line break and paragraph attributes or paragraph templates
    3958             :      * do NOT change the line end was not added to the Plcx.Fkp.papx i.e. (nFlags & MAN_MASK_NEW_PAP)
    3959             :      * is false.
    3960             :      * Due to this we need to set the template here as a kind of special treatment.
    3961             :      */
    3962          48 :     if (!bCpxStyle && nAktColl < vColl.size())
    3963          48 :             SetTxtFmtCollAndListLevel(*pPaM, vColl[nAktColl]);
    3964          48 :         rbStartLine = false;
    3965             :     }
    3966       15066 : }
    3967             : 
    3968             : /**
    3969             :  * CloseAttrEnds to only read the attribute ends at the end of a text or a
    3970             :  * text area (Header, Footnote, ...).
    3971             :  * We ignore attribute starts and fields.
    3972             :  */
    3973         486 : void SwWW8ImplReader::CloseAttrEnds()
    3974             : {
    3975             :     // If there are any unclosed sprms then copy them to
    3976             :     // another stack and close the ones that must be closed
    3977         486 :     std::stack<sal_uInt16> aStack;
    3978         486 :     pPlcxMan->TransferOpenSprms(aStack);
    3979             : 
    3980        3646 :     while (!aStack.empty())
    3981             :     {
    3982        2674 :         sal_uInt16 nSprmId = aStack.top();
    3983        2674 :         if ((0 < nSprmId) && (( eFTN > nSprmId) || (0x0800 <= nSprmId)))
    3984        1986 :             EndSprm(nSprmId);
    3985        2674 :         aStack.pop();
    3986             :     }
    3987             : 
    3988         486 :     EndSpecial();
    3989         486 : }
    3990             : 
    3991         486 : bool SwWW8ImplReader::ReadText(long nStartCp, long nTextLen, ManTypes nType)
    3992             : {
    3993         486 :     bool bJoined=false;
    3994             : 
    3995         486 :     bool bStartLine = true;
    3996         486 :     short nCrCount = 0;
    3997         486 :     short nDistance = 0;
    3998             : 
    3999         486 :     bWasParaEnd = false;
    4000         486 :     nAktColl    =  0;
    4001         486 :     pAktItemSet =  0;
    4002         486 :     nCharFmt    = -1;
    4003         486 :     bSpec = false;
    4004         486 :     bPgSecBreak = false;
    4005             : 
    4006         486 :     pPlcxMan = new WW8PLCFMan( pSBase, nType, nStartCp );
    4007         486 :     long nCpOfs = pPlcxMan->GetCpOfs(); // Offset for Header/Footer, Footnote
    4008             : 
    4009         486 :     WW8_CP nNext = pPlcxMan->Where();
    4010         486 :     SwTxtNode* pPreviousNode = 0;
    4011         486 :     sal_uInt8 nDropLines = 0;
    4012         486 :     SwCharFmt* pNewSwCharFmt = 0;
    4013         486 :     const SwCharFmt* pFmt = 0;
    4014         486 :     pStrm->Seek( pSBase->WW8Cp2Fc( nStartCp + nCpOfs, &bIsUnicode ) );
    4015             : 
    4016         486 :     WW8_CP l = nStartCp;
    4017       16038 :     while ( l<nStartCp+nTextLen )
    4018             :     {
    4019       15066 :         ReadAttrs( nNext, l, bStartLine );// Takes SectionBreaks into account, too
    4020             :         OSL_ENSURE(pPaM->GetNode().GetTxtNode(), "Missing txtnode");
    4021             : 
    4022       15066 :         if (mpPostProcessAttrsInfo != NULL)
    4023           0 :             PostProcessAttrs();
    4024             : 
    4025       15066 :         if( l>= nStartCp + nTextLen )
    4026           0 :             break;
    4027             : 
    4028       15066 :         bStartLine = ReadChars(l, nNext, nStartCp+nTextLen, nCpOfs);
    4029             : 
    4030             :         // If the previous paragraph was a dropcap then do not
    4031             :         // create a new txtnode and join the two paragraphs together
    4032       15066 :         if (bStartLine && !pPreviousNode) // Line end
    4033             :         {
    4034        5532 :             bool bSplit = true;
    4035        5532 :             if (mbCareFirstParaEndInToc)
    4036             :             {
    4037           0 :                 mbCareFirstParaEndInToc = false;
    4038           0 :                 if (pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() &&  pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0)
    4039           0 :                     bSplit = false;
    4040             :             }
    4041        5532 :             if (mbCareLastParaEndInToc)
    4042             :             {
    4043           0 :                 mbCareLastParaEndInToc = false;
    4044           0 :                 if (pPaM->End() && pPaM->End()->nNode.GetNode().GetTxtNode() &&  pPaM->End()->nNode.GetNode().GetTxtNode()->Len() == 0)
    4045           0 :                     bSplit = false;
    4046             :             }
    4047        5532 :             if (bSplit)
    4048             :             {
    4049             :                 // We will record the CP of a paragraph end ('0x0D'), if current loading contents is from main stream;
    4050        5532 :                 if (mbOnLoadingMain)
    4051        5204 :                     maEndParaPos.push_back(l-1);
    4052        5532 :                 AppendTxtNode(*pPaM->GetPoint());
    4053             :             }
    4054             :         }
    4055             : 
    4056       15066 :         if (pPreviousNode && bStartLine)
    4057             :         {
    4058           0 :             SwTxtNode* pEndNd = pPaM->GetNode().GetTxtNode();
    4059           0 :             const sal_Int32 nDropCapLen = pPreviousNode->GetTxt().getLength();
    4060             : 
    4061             :             // Need to reset the font size and text position for the dropcap
    4062             :             {
    4063           0 :                 SwPaM aTmp(*pEndNd, 0, *pEndNd, nDropCapLen+1);
    4064           0 :                 pCtrlStck->Delete(aTmp);
    4065             :             }
    4066             : 
    4067             :             // Get the default document dropcap which we can use as our template
    4068             :             const SwFmtDrop* defaultDrop =
    4069           0 :                 (const SwFmtDrop*) GetFmtAttr(RES_PARATR_DROP);
    4070           0 :             SwFmtDrop aDrop(*defaultDrop);
    4071             : 
    4072           0 :             aDrop.GetLines() = nDropLines;
    4073           0 :             aDrop.GetDistance() = nDistance;
    4074           0 :             aDrop.GetChars() = writer_cast<sal_uInt8>(nDropCapLen);
    4075             :             // Word has no concept of a "whole word dropcap"
    4076           0 :             aDrop.GetWholeWord() = false;
    4077             : 
    4078           0 :             if (pFmt)
    4079           0 :                 aDrop.SetCharFmt(const_cast<SwCharFmt*>(pFmt));
    4080           0 :             else if(pNewSwCharFmt)
    4081           0 :                 aDrop.SetCharFmt(const_cast<SwCharFmt*>(pNewSwCharFmt));
    4082             : 
    4083           0 :             SwPosition aStart(*pEndNd);
    4084           0 :             pCtrlStck->NewAttr(aStart, aDrop);
    4085           0 :             pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_PARATR_DROP);
    4086           0 :             pPreviousNode = 0;
    4087             :         }
    4088       15066 :         else if (bDropCap)
    4089             :         {
    4090             :             // If we have found a dropcap store the textnode
    4091           0 :             pPreviousNode = pPaM->GetNode().GetTxtNode();
    4092             : 
    4093             :             const sal_uInt8 *pDCS;
    4094             : 
    4095           0 :             if (bVer67)
    4096           0 :                 pDCS = pPlcxMan->GetPapPLCF()->HasSprm(46);
    4097             :             else
    4098           0 :                 pDCS = pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
    4099             : 
    4100           0 :             if (pDCS)
    4101           0 :                 nDropLines = (*pDCS) >> 3;
    4102             :             else    // There is no Drop Cap Specifier hence no dropcap
    4103           0 :                 pPreviousNode = 0;
    4104             : 
    4105           0 :             if (const sal_uInt8 *pDistance = pPlcxMan->GetPapPLCF()->HasSprm(0x842F))
    4106           0 :                 nDistance = SVBT16ToShort( pDistance );
    4107             :             else
    4108           0 :                 nDistance = 0;
    4109             : 
    4110           0 :             const SwFmtCharFmt *pSwFmtCharFmt = 0;
    4111             : 
    4112           0 :             if(pAktItemSet)
    4113           0 :                 pSwFmtCharFmt = &(ItemGet<SwFmtCharFmt>(*pAktItemSet, RES_TXTATR_CHARFMT));
    4114             : 
    4115           0 :             if(pSwFmtCharFmt)
    4116           0 :                 pFmt = pSwFmtCharFmt->GetCharFmt();
    4117             : 
    4118           0 :             if(pAktItemSet && !pFmt)
    4119             :             {
    4120           0 :                 OUString sPrefix(OUStringBuffer("WW8Dropcap").append(nDropCap++).makeStringAndClear());
    4121           0 :                 pNewSwCharFmt = rDoc.MakeCharFmt(sPrefix, (SwCharFmt*)rDoc.GetDfltCharFmt());
    4122           0 :                  pAktItemSet->ClearItem(RES_CHRATR_ESCAPEMENT);
    4123           0 :                 pNewSwCharFmt->SetFmtAttr( *pAktItemSet );
    4124             :             }
    4125             : 
    4126           0 :             delete pAktItemSet;
    4127           0 :             pAktItemSet = 0;
    4128           0 :             bDropCap=false;
    4129             :         }
    4130             : 
    4131       15066 :         if (bStartLine || bWasTabRowEnd)
    4132             :         {
    4133             :             // Call all 64 CRs; not for Header and the like
    4134        6112 :             if ((nCrCount++ & 0x40) == 0 && nType == MAN_MAINTEXT)
    4135             :             {
    4136        3710 :                 nProgress = (sal_uInt16)( l * 100 / nTextLen );
    4137        3710 :                 ::SetProgressState(nProgress, mpDocShell); // Update
    4138             :             }
    4139             :         }
    4140             : 
    4141             :         // If we have encountered a 0x0c which indicates either section of
    4142             :         // pagebreak then look it up to see if it is a section break, and
    4143             :         // if it is not then insert a page break. If it is a section break
    4144             :         // it will be handled as such in the ReadAttrs of the next loop
    4145       15066 :         if (bPgSecBreak)
    4146             :         {
    4147             :             // We need only to see if a section is ending at this cp,
    4148             :             // the plcf will already be sitting on the correct location
    4149             :             // if it is there.
    4150         124 :             WW8PLCFxDesc aTemp;
    4151         124 :             aTemp.nStartPos = aTemp.nEndPos = WW8_CP_MAX;
    4152         124 :             if (pPlcxMan->GetSepPLCF())
    4153         124 :                 pPlcxMan->GetSepPLCF()->GetSprms(&aTemp);
    4154         124 :             if ((aTemp.nStartPos != l) && (aTemp.nEndPos != l))
    4155             :             {
    4156             :                 // #i39251# - insert text node for page break, if no one inserted.
    4157             :                 // #i43118# - refine condition: the anchor
    4158             :                 // control stack has to have entries, otherwise it's not needed
    4159             :                 // to insert a text node.
    4160          86 :                 if (!bStartLine && !pAnchorStck->empty())
    4161             :                 {
    4162           0 :                     AppendTxtNode(*pPaM->GetPoint());
    4163             :                 }
    4164          86 :                 rDoc.getIDocumentContentOperations().InsertPoolItem(*pPaM,
    4165          86 :                     SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
    4166          86 :                 bFirstParaOfPage = true;
    4167          86 :                 bPgSecBreak = false;
    4168             :             }
    4169             :         }
    4170             :     }
    4171             : 
    4172         486 :     if (pPaM->GetPoint()->nContent.GetIndex())
    4173           2 :         AppendTxtNode(*pPaM->GetPoint());
    4174             : 
    4175         486 :     if (!bInHyperlink)
    4176         486 :         bJoined = JoinNode(*pPaM);
    4177             : 
    4178         486 :     CloseAttrEnds();
    4179             : 
    4180         486 :     delete pPlcxMan, pPlcxMan = 0;
    4181         486 :     return bJoined;
    4182             : }
    4183             : 
    4184         190 : SwWW8ImplReader::SwWW8ImplReader(sal_uInt8 nVersionPara, SvStorage* pStorage,
    4185             :     SvStream* pSt, SwDoc& rD, const OUString& rBaseURL, bool bNewDoc)
    4186         190 :     : mpDocShell(rD.GetDocShell())
    4187             :     , pStg(pStorage)
    4188             :     , pStrm(pSt)
    4189             :     , pTableStream(0)
    4190             :     , pDataStream(0)
    4191             :     , rDoc(rD)
    4192             :     , pPaM(0)
    4193             :     , pCtrlStck(0)
    4194             :     , mpRedlineStack(0)
    4195             :     , pReffedStck(0)
    4196             :     , pReffingStck(0)
    4197             :     , pAnchorStck(0)
    4198             :     , maSectionManager(*this)
    4199             :     , m_aExtraneousParas(rD)
    4200             :     , maInsertedTables(rD)
    4201             :     , maSectionNameGenerator(rD, OUString("WW"))
    4202             :     , mpSprmParser(NULL)
    4203             :     , maGrfNameGenerator(bNewDoc, OUString('G'))
    4204             :     , maParaStyleMapper(rD)
    4205             :     , maCharStyleMapper(rD)
    4206             :     , pFormImpl(0)
    4207             :     , pFlyFmtOfJustInsertedGraphic(0)
    4208             :     , pFmtOfJustInsertedApo(0)
    4209             :     , pPreviousNumPaM(0)
    4210             :     , pPrevNumRule(0)
    4211             :     , mpPostProcessAttrsInfo(0)
    4212             :     , pWwFib(0)
    4213             :     , pFonts(0)
    4214             :     , pWDop(0)
    4215             :     , pLstManager(0)
    4216             :     , pSBase(0)
    4217             :     , pPlcxMan(0)
    4218             :     , maTxtNodesHavingFirstLineOfstSet()
    4219             :     , maTxtNodesHavingLeftIndentSet()
    4220             :     , pStyles(0)
    4221             :     , pAktColl(0)
    4222             :     , pAktItemSet(0)
    4223             :     , pDfltTxtFmtColl(0)
    4224             :     , pStandardFmtColl(0)
    4225             :     , pHdFt(0)
    4226             :     , pWFlyPara(0)
    4227             :     , pSFlyPara(0)
    4228             :     , pTableDesc(0)
    4229             :     , pNumOlst(0)
    4230             :     , pNode_FLY_AT_PARA(0)
    4231             :     , pDrawModel(0)
    4232             :     , pDrawPg(0)
    4233             :     , mpDrawEditEngine(0)
    4234             :     , pWWZOrder(0)
    4235             :     , pNumFldType(0)
    4236             :     , pMSDffManager(0)
    4237             :     , mpAtnNames(0)
    4238             :     , sBaseURL(rBaseURL)
    4239             :     , nIniFlags(0)
    4240             :     , nIniFlags1(0)
    4241             :     , nFieldFlags(0)
    4242             :     , m_bRegardHindiDigits( false )
    4243             :     , nDrawCpO(0)
    4244             :     , nPicLocFc(0)
    4245             :     , nObjLocFc(0)
    4246             :     , nIniFlyDx(0)
    4247             :     , nIniFlyDy(0)
    4248             :     , eTextCharSet(RTL_TEXTENCODING_ASCII_US)
    4249             :     , eStructCharSet(RTL_TEXTENCODING_ASCII_US)
    4250             :     , eHardCharSet(RTL_TEXTENCODING_DONTKNOW)
    4251             :     , nProgress(0)
    4252             :     , nAktColl(0)
    4253             :     , nFldNum(0)
    4254             :     , nLFOPosition(USHRT_MAX)
    4255             :     , nCharFmt(0)
    4256             :     , nDrawXOfs(0)
    4257             :     , nDrawYOfs(0)
    4258             :     , nDrawXOfs2(0)
    4259             :     , nDrawYOfs2(0)
    4260             :     , cSymbol(0)
    4261             :     , nWantedVersion(nVersionPara)
    4262             :     , nSwNumLevel(0xff)
    4263             :     , nWwNumType(0xff)
    4264             :     , nListLevel(WW8ListManager::nMaxLevel)
    4265             :     , nPgChpDelim(0)
    4266             :     , nPgChpLevel(0)
    4267             :     , mbNewDoc(bNewDoc)
    4268             :     , bReadNoTbl(false)
    4269             :     , bPgSecBreak(false)
    4270             :     , bSpec(false)
    4271             :     , bObj(false)
    4272             :     , bTxbxFlySection(false)
    4273             :     , bHasBorder(false)
    4274             :     , bSymbol(false)
    4275             :     , bIgnoreText(false)
    4276             :     , nInTable(0)
    4277             :     , bWasTabRowEnd(false)
    4278             :     , bWasTabCellEnd(false)
    4279             :     , bShdTxtCol(false)
    4280             :     , bCharShdTxtCol(false)
    4281             :     , bAnl(false)
    4282             :     , bHdFtFtnEdn(false)
    4283             :     , bFtnEdn(false)
    4284             :     , bIsHeader(false)
    4285             :     , bIsFooter(false)
    4286             :     , bIsUnicode(false)
    4287             :     , bCpxStyle(false)
    4288             :     , bStyNormal(false)
    4289             :     , bWWBugNormal(false)
    4290             :     , bNoAttrImport(false)
    4291             :     , bInHyperlink(false)
    4292             :     , bWasParaEnd(false)
    4293             :     , bVer67(false)
    4294             :     , bVer6(false)
    4295             :     , bVer7(false)
    4296             :     , bVer8(false)
    4297             :     , bEmbeddObj(false)
    4298             :     , bAktAND_fNumberAcross(false)
    4299             :     , bNoLnNumYet(true)
    4300             :     , bFirstPara(true)
    4301             :     , bFirstParaOfPage(false)
    4302             :     , bParaAutoBefore(false)
    4303             :     , bParaAutoAfter(false)
    4304             :     , bDropCap(false)
    4305             :     , nDropCap(0)
    4306             :     , nIdctHint(0)
    4307             :     , bBidi(false)
    4308             :     , bReadTable(false)
    4309             :     , mbLoadingTOXCache(false)
    4310             :     , mnEmbeddedTOXLevel(0)
    4311             :     , mbLoadingTOXHyperlink(false)
    4312             :     , mpPosAfterTOC(0)
    4313             :     , mbCareFirstParaEndInToc(false)
    4314             :     , mbCareLastParaEndInToc(false)
    4315             :     , maTOXEndCps()
    4316             :     , maCurrAttrCP(-1)
    4317         190 :     , mbOnLoadingMain(false)
    4318             : {
    4319         190 :     pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    4320         190 :     maApos.push_back(false);
    4321         190 : }
    4322             : 
    4323        1744 : void SwWW8ImplReader::DeleteStk(SwFltControlStack* pStck)
    4324             : {
    4325        1744 :     if( pStck )
    4326             :     {
    4327        1744 :         pStck->SetAttr( *pPaM->GetPoint(), 0, false);
    4328        1744 :         pStck->SetAttr( *pPaM->GetPoint(), 0, false);
    4329        1744 :         delete pStck;
    4330             :     }
    4331             :     else
    4332             :     {
    4333             :         OSL_ENSURE( false, "WW-Stack bereits geloescht" );
    4334             :     }
    4335        1744 : }
    4336             : 
    4337         220 : void wwSectionManager::SetSegmentToPageDesc(const wwSection &rSection,
    4338             :     bool bIgnoreCols)
    4339             : {
    4340         220 :     SwPageDesc &rPage = *rSection.mpPage;
    4341             : 
    4342         220 :     SetNumberingType(rSection, rPage);
    4343             : 
    4344         220 :     SwFrmFmt &rFmt = rPage.GetMaster();
    4345             : 
    4346         220 :     if(mrReader.pWDop->fUseBackGroundInAllmodes) // #i56806# Make sure mrReader is initialized
    4347          68 :         mrReader.GrafikCtor();
    4348             : 
    4349         220 :     if (mrReader.pWDop->fUseBackGroundInAllmodes && mrReader.pMSDffManager)
    4350             :     {
    4351          68 :         Rectangle aRect(0, 0, 100, 100); // A dummy, we don't care about the size
    4352          68 :         SvxMSDffImportData aData(aRect);
    4353          68 :         SdrObject* pObject = 0;
    4354          68 :         if (mrReader.pMSDffManager->GetShape(0x401, pObject, aData))
    4355             :         {
    4356             :             // Only handle shape if it is a background shape
    4357          24 :             if ((aData.begin()->nFlags & 0x400) != 0)
    4358             :             {
    4359          22 :                 SfxItemSet aSet(rFmt.GetAttrSet());
    4360             :                 mrReader.MatchSdrItemsIntoFlySet(pObject, aSet, mso_lineSimple,
    4361          22 :                                                  mso_lineSolid, mso_sptRectangle, aRect);
    4362          22 :                 rFmt.SetFmtAttr(aSet.Get(RES_BACKGROUND));
    4363             :             }
    4364             :         }
    4365          68 :         SdrObject::Free(pObject);
    4366             :     }
    4367         220 :     wwULSpaceData aULData;
    4368         220 :     GetPageULData(rSection, aULData);
    4369         220 :     SetPageULSpaceItems(rFmt, aULData, rSection);
    4370             : 
    4371         220 :     SetPage(rPage, rFmt, rSection, bIgnoreCols);
    4372             : 
    4373         220 :     if (!(rSection.maSep.pgbApplyTo & 1))
    4374         220 :         mrReader.SetPageBorder(rFmt, rSection);
    4375         220 :     if (!(rSection.maSep.pgbApplyTo & 2))
    4376         220 :         mrReader.SetPageBorder(rPage.GetFirstMaster(), rSection);
    4377             : 
    4378         220 :     mrReader.SetDocumentGrid(rFmt, rSection);
    4379         220 : }
    4380             : 
    4381         220 : void wwSectionManager::SetUseOn(wwSection &rSection)
    4382             : {
    4383         220 :     bool bMirror = mrReader.pWDop->fMirrorMargins ||
    4384         220 :         mrReader.pWDop->doptypography.f2on1;
    4385             : 
    4386         220 :     UseOnPage eUseBase = bMirror ? nsUseOnPage::PD_MIRROR : nsUseOnPage::PD_ALL;
    4387         220 :     UseOnPage eUse = eUseBase;
    4388         220 :     if (!mrReader.pWDop->fFacingPages)
    4389         184 :         eUse = (UseOnPage)(eUse | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
    4390         220 :     if (!rSection.HasTitlePage())
    4391         196 :         eUse = (UseOnPage)(eUse | nsUseOnPage::PD_FIRSTSHARE);
    4392             : 
    4393             :     OSL_ENSURE(rSection.mpPage, "Makes no sense to call me with no pages to set");
    4394         220 :     if (rSection.mpPage)
    4395         220 :         rSection.mpPage->WriteUseOn(eUse);
    4396         220 : }
    4397             : 
    4398             : /**
    4399             :  * Set the page descriptor on this node, handle the different cases for a text
    4400             :  * node or a table
    4401             :  */
    4402         220 : void GiveNodePageDesc(SwNodeIndex &rIdx, const SwFmtPageDesc &rPgDesc,
    4403             :     SwDoc &rDoc)
    4404             : {
    4405             :     /*
    4406             :     If it's a table here, apply the pagebreak to the table
    4407             :     properties, otherwise we add it to the para at this
    4408             :     position
    4409             :     */
    4410         220 :     if (rIdx.GetNode().IsTableNode())
    4411             :     {
    4412             :         SwTable& rTable =
    4413          30 :             rIdx.GetNode().GetTableNode()->GetTable();
    4414          30 :         SwFrmFmt* pApply = rTable.GetFrmFmt();
    4415             :         OSL_ENSURE(pApply, "impossible");
    4416          30 :         if (pApply)
    4417          30 :             pApply->SetFmtAttr(rPgDesc);
    4418             :     }
    4419             :     else
    4420             :     {
    4421         190 :         SwPosition aPamStart(rIdx);
    4422             :         aPamStart.nContent.Assign(
    4423         190 :             rIdx.GetNode().GetCntntNode(), 0);
    4424         380 :         SwPaM aPage(aPamStart);
    4425             : 
    4426         380 :         rDoc.getIDocumentContentOperations().InsertPoolItem(aPage, rPgDesc, 0);
    4427             :     }
    4428         220 : }
    4429             : 
    4430             : /**
    4431             :  * Map a word section to a writer page descriptor
    4432             :  */
    4433         220 : SwFmtPageDesc wwSectionManager::SetSwFmtPageDesc(mySegIter &rIter,
    4434             :     mySegIter &rStart, bool bIgnoreCols)
    4435             : {
    4436         220 :     if (IsNewDoc() && rIter == rStart)
    4437             :     {
    4438         184 :         rIter->mpPage =
    4439         184 :             mrReader.rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD);
    4440             :     }
    4441             :     else
    4442             :     {
    4443          36 :         rIter->mpPage = mrReader.rDoc.MakePageDesc(
    4444             :             SwViewShell::GetShellRes()->GetPageDescName(mnDesc, ShellResource::NORMAL_PAGE),
    4445          36 :             0, false);
    4446             :     }
    4447             :     OSL_ENSURE(rIter->mpPage, "no page!");
    4448         220 :     if (!rIter->mpPage)
    4449           0 :         return SwFmtPageDesc();
    4450             : 
    4451             :     // Set page before hd/ft
    4452         220 :     const wwSection *pPrevious = 0;
    4453         220 :     if (rIter != rStart)
    4454          36 :         pPrevious = &(*(rIter-1));
    4455         220 :     SetHdFt(*rIter, std::distance(rStart, rIter), pPrevious);
    4456         220 :     SetUseOn(*rIter);
    4457             : 
    4458             :     // Set hd/ft after set page
    4459         220 :     SetSegmentToPageDesc(*rIter, bIgnoreCols);
    4460             : 
    4461         220 :     SwFmtPageDesc aRet(rIter->mpPage);
    4462             : 
    4463         220 :     rIter->mpPage->SetFollow(rIter->mpPage);
    4464             : 
    4465         220 :     if (rIter->PageRestartNo())
    4466          10 :         aRet.SetNumOffset(rIter->PageStartAt());
    4467             : 
    4468         220 :     ++mnDesc;
    4469         220 :     return aRet;
    4470             : }
    4471             : 
    4472         220 : bool wwSectionManager::IsNewDoc() const
    4473             : {
    4474         220 :     return mrReader.mbNewDoc;
    4475             : }
    4476             : 
    4477         186 : void wwSectionManager::InsertSegments()
    4478             : {
    4479         186 :     const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
    4480         186 :     bool bUseEnhFields = rOpt.IsUseEnhancedFields();
    4481         186 :     mySegIter aEnd = maSegments.end();
    4482         186 :     mySegIter aStart = maSegments.begin();
    4483         408 :     for (mySegIter aIter = aStart; aIter != aEnd; ++aIter)
    4484             :     {
    4485             :         // If the section is of type "New column" (0x01), then simply insert a column break.
    4486             :         // But only if there actually are columns on the page, otherwise a column break
    4487             :         // seems to be handled like a page break by MSO.
    4488         222 :         if ( aIter->maSep.bkc == 1 && aIter->maSep.ccolM1 > 0 )
    4489             :         {
    4490           2 :             SwPaM start( aIter->maStart );
    4491           2 :             mrReader.rDoc.getIDocumentContentOperations().InsertPoolItem( start, SvxFmtBreakItem(SVX_BREAK_COLUMN_BEFORE, RES_BREAK), 0);
    4492           2 :             continue;
    4493             :         }
    4494             : 
    4495         220 :         mySegIter aNext = aIter+1;
    4496         220 :         mySegIter aPrev = (aIter == aStart) ? aIter : aIter-1;
    4497             : 
    4498             :         // If two following sections are different in following properties, Word will interprete a continuous
    4499             :         // section break between them as if it was a section break next page.
    4500         438 :         bool bThisAndPreviousAreCompatible = ((aIter->GetPageWidth() == aPrev->GetPageWidth()) &&
    4501         438 :             (aIter->GetPageHeight() == aPrev->GetPageHeight()) && (aIter->IsLandScape() == aPrev->IsLandScape()));
    4502             : 
    4503         220 :         bool bInsertSection = (aIter != aStart) && aIter->IsContinuous() &&  bThisAndPreviousAreCompatible;
    4504         220 :         bool bInsertPageDesc = !bInsertSection;
    4505             :         // HACK Force new pagedesc if margins change, otherwise e.g. floating tables may be anchored improperly.
    4506         646 :         if( aIter->maSep.dyaTop != aPrev->maSep.dyaTop || aIter->maSep.dyaBottom != aPrev->maSep.dyaBottom
    4507         426 :             || aIter->maSep.dxaLeft != aPrev->maSep.dxaLeft || aIter->maSep.dxaRight != aPrev->maSep.dxaRight )
    4508          14 :             bInsertPageDesc = true;
    4509         220 :         bool bProtected = SectionIsProtected(*aIter); // do we really  need this ?? I guess I have a different logic in editshell which disables this...
    4510         220 :         if (bUseEnhFields && mrReader.pWDop->fProtEnabled && aIter->IsNotProtected())
    4511             :         {
    4512             :             // here we have the special case that the whole document is protected, with the exception of this section.
    4513             :             // I want to address this when I do the section rework, so for the moment we disable the overall protection then...
    4514           0 :             mrReader.rDoc.getIDocumentSettingAccess().set(IDocumentSettingAccess::PROTECT_FORM, false );
    4515             :         }
    4516             : 
    4517         220 :         if (bInsertPageDesc)
    4518             :         {
    4519             :             /*
    4520             :              If a cont section follows this section then we won't be
    4521             :              creating a page desc with 2+ cols as we cannot host a one
    4522             :              col section in a 2+ col pagedesc and make it look like
    4523             :              word. But if the current section actually has columns then
    4524             :              we are forced to insert a section here as well as a page
    4525             :              descriptor.
    4526             :             */
    4527             : 
    4528         220 :             bool bIgnoreCols = false;
    4529         294 :             bool bThisAndNextAreCompatible = (aNext != aEnd) ? ((aIter->GetPageWidth() == aNext->GetPageWidth()) &&
    4530         294 :                 (aIter->GetPageHeight() == aNext->GetPageHeight()) && (aIter->IsLandScape() == aNext->IsLandScape())) : true;
    4531             : 
    4532         220 :             if (((aNext != aEnd && aNext->IsContinuous() && bThisAndNextAreCompatible) || bProtected))
    4533             :             {
    4534           6 :                 bIgnoreCols = true;
    4535           6 :                 if ((aIter->NoCols() > 1) || bProtected)
    4536           2 :                     bInsertSection = true;
    4537             :             }
    4538             : 
    4539         220 :             SwFmtPageDesc aDesc(SetSwFmtPageDesc(aIter, aStart, bIgnoreCols));
    4540         220 :             if (!aDesc.GetPageDesc())
    4541           0 :                 continue;
    4542             : 
    4543             :             // special case handling for odd/even section break
    4544             :             // a) as before create a new page style for the section break
    4545             :             // b) set Layout of generated page style to right/left ( according
    4546             :             //    to section break odd/even )
    4547             :             // c) create a new style to follow the break page style
    4548         220 :             if ( aIter->maSep.bkc == 3 || aIter->maSep.bkc == 4 )
    4549             :             {
    4550             :                 // SetSwFmtPageDesc calls some methods that could
    4551             :                 // modify aIter (e.g. wwSection ).
    4552             :                 // Since  we call SetSwFmtPageDesc below to generate the
    4553             :                 // 'Following' style of the Break style, it is safer
    4554             :                 // to take  a copy of the contents of aIter.
    4555           0 :                 wwSection aTmpSection = *aIter;
    4556             :                 // create a new following page style
    4557           0 :                 SwFmtPageDesc aFollow(SetSwFmtPageDesc(aIter, aStart, bIgnoreCols));
    4558             :                 // restore any contents of aIter trashed by SetSwFmtPageDesc
    4559           0 :                 *aIter = aTmpSection;
    4560             : 
    4561             :                 // Handle the section break
    4562           0 :                 UseOnPage eUseOnPage = nsUseOnPage::PD_LEFT;
    4563           0 :                 if ( aIter->maSep.bkc == 4 ) // Odd ( right ) Section break
    4564           0 :                     eUseOnPage = nsUseOnPage::PD_RIGHT;
    4565             : 
    4566           0 :                 aDesc.GetPageDesc()->WriteUseOn( eUseOnPage );
    4567           0 :                 aDesc.GetPageDesc()->SetFollow( aFollow.GetPageDesc() );
    4568             :             }
    4569             : 
    4570         220 :             GiveNodePageDesc(aIter->maStart, aDesc, mrReader.rDoc);
    4571             :         }
    4572             : 
    4573         220 :         SwTxtNode* pTxtNd = 0;
    4574         220 :         if (bInsertSection)
    4575             :         {
    4576             :             // Start getting the bounds of this section
    4577           8 :             SwPaM aSectPaM(*mrReader.pPaM);
    4578          16 :             SwNodeIndex aAnchor(aSectPaM.GetPoint()->nNode);
    4579           8 :             if (aNext != aEnd)
    4580             :             {
    4581           2 :                 aAnchor = aNext->maStart;
    4582           2 :                 aSectPaM.GetPoint()->nNode = aAnchor;
    4583           2 :                 aSectPaM.GetPoint()->nContent.Assign(
    4584           4 :                     aNext->maStart.GetNode().GetCntntNode(), 0);
    4585           2 :                 aSectPaM.Move(fnMoveBackward);
    4586             :             }
    4587             : 
    4588           8 :             const SwPosition* pPos  = aSectPaM.GetPoint();
    4589           8 :             SwTxtNode const*const pSttNd = pPos->nNode.GetNode().GetTxtNode();
    4590           8 :             const SwTableNode* pTableNd = pSttNd ? pSttNd->FindTableNode() : 0;
    4591           8 :             if (pTableNd)
    4592             :             {
    4593             :                 pTxtNd =
    4594           0 :                     mrReader.rDoc.GetNodes().MakeTxtNode(aAnchor,
    4595           0 :                     mrReader.rDoc.getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_TEXT ));
    4596             : 
    4597           0 :                 aSectPaM.GetPoint()->nNode = SwNodeIndex(*pTxtNd);
    4598           0 :                 aSectPaM.GetPoint()->nContent.Assign(
    4599           0 :                     aSectPaM.GetCntntNode(), 0);
    4600             :             }
    4601             : 
    4602           8 :             aSectPaM.SetMark();
    4603             : 
    4604           8 :             aSectPaM.GetPoint()->nNode = aIter->maStart;
    4605           8 :             aSectPaM.GetPoint()->nContent.Assign(
    4606          16 :                 aSectPaM.GetCntntNode(), 0);
    4607             : 
    4608           8 :             bool bHasOwnHdFt = false;
    4609             :             /*
    4610             :              In this nightmare scenario the continuous section has its own
    4611             :              headers and footers so we will try and find a hard page break
    4612             :              between here and the end of the section and put the headers and
    4613             :              footers there.
    4614             :             */
    4615           8 :             if (!bInsertPageDesc)
    4616             :             {
    4617             :                bHasOwnHdFt =
    4618             :                 mrReader.HasOwnHeaderFooter(
    4619           0 :                  aIter->maSep.grpfIhdt & ~(WW8_HEADER_FIRST | WW8_FOOTER_FIRST),
    4620           0 :                  aIter->maSep.grpfIhdt, std::distance(aStart, aIter)
    4621           0 :                 );
    4622             :             }
    4623           8 :             if (bHasOwnHdFt)
    4624             :             {
    4625             :                 // #i40766# Need to cache the page descriptor in case there is
    4626             :                 // no page break in the section
    4627           0 :                 SwPageDesc *pOrig = aIter->mpPage;
    4628           0 :                 bool bFailed = true;
    4629           0 :                 SwFmtPageDesc aDesc(SetSwFmtPageDesc(aIter, aStart, true));
    4630           0 :                 if (aDesc.GetPageDesc())
    4631             :                 {
    4632           0 :                     sal_uLong nStart = aSectPaM.Start()->nNode.GetIndex();
    4633           0 :                     sal_uLong nEnd   = aSectPaM.End()->nNode.GetIndex();
    4634           0 :                     for(; nStart <= nEnd; ++nStart)
    4635             :                     {
    4636           0 :                         SwNode* pNode = mrReader.rDoc.GetNodes()[nStart];
    4637           0 :                         if (!pNode)
    4638           0 :                             continue;
    4639           0 :                         if (sw::util::HasPageBreak(*pNode))
    4640             :                         {
    4641           0 :                             SwNodeIndex aIdx(*pNode);
    4642           0 :                             GiveNodePageDesc(aIdx, aDesc, mrReader.rDoc);
    4643           0 :                             bFailed = false;
    4644           0 :                             break;
    4645             :                         }
    4646             :                     }
    4647             :                 }
    4648           0 :                 if(bFailed)
    4649             :                 {
    4650           0 :                     aIter->mpPage = pOrig;
    4651           0 :                 }
    4652             :             }
    4653             : 
    4654             :             // End getting the bounds of this section, quite a job eh?
    4655           8 :             SwSectionFmt *pRet = InsertSection(aSectPaM, *aIter);
    4656             :             // The last section if continuous is always unbalanced
    4657           8 :             if (pRet)
    4658             :             {
    4659             :                 // Set the columns to be UnBalanced if that compatibility option is set
    4660           8 :                 if (mrReader.pWDop->fNoColumnBalance)
    4661           0 :                     pRet->SetFmtAttr(SwFmtNoBalancedColumns(true));
    4662             :                 else
    4663             :                 {
    4664             :                     // Otherwise set to unbalanced if the following section is
    4665             :                     // not continuous, (which also means that the last section
    4666             :                     // is unbalanced)
    4667           8 :                     if (aNext == aEnd || !aNext->IsContinuous())
    4668           6 :                         pRet->SetFmtAttr(SwFmtNoBalancedColumns(true));
    4669             :                 }
    4670           8 :             }
    4671             :         }
    4672             : 
    4673         220 :         if (pTxtNd)
    4674             :         {
    4675           0 :             SwNodeIndex aIdx(*pTxtNd);
    4676           0 :             SwPaM aTest(aIdx);
    4677           0 :             mrReader.rDoc.getIDocumentContentOperations().DelFullPara(aTest);
    4678           0 :             pTxtNd = 0;
    4679             :         }
    4680             :     }
    4681         186 : }
    4682             : 
    4683         376 : void wwExtraneousParas::delete_all_from_doc()
    4684             : {
    4685             :     typedef std::vector<SwTxtNode*>::iterator myParaIter;
    4686         376 :     myParaIter aEnd = m_aTxtNodes.end();
    4687         382 :     for (myParaIter aI = m_aTxtNodes.begin(); aI != aEnd; ++aI)
    4688             :     {
    4689           6 :         SwTxtNode *pTxtNode = *aI;
    4690           6 :         SwNodeIndex aIdx(*pTxtNode);
    4691          12 :         SwPaM aTest(aIdx);
    4692           6 :         m_rDoc.getIDocumentContentOperations().DelFullPara(aTest);
    4693           6 :     }
    4694         376 :     m_aTxtNodes.clear();
    4695         376 : }
    4696             : 
    4697         182 : void SwWW8ImplReader::StoreMacroCmds()
    4698             : {
    4699         182 :     if (pWwFib->lcbCmds)
    4700             :     {
    4701         142 :         pTableStream->Seek(pWwFib->fcCmds);
    4702             : 
    4703         142 :         uno::Reference < embed::XStorage > xRoot(mpDocShell->GetStorage());
    4704             : 
    4705         142 :         if (!xRoot.is())
    4706         238 :             return;
    4707             : 
    4708             :         try
    4709             :         {
    4710             :             uno::Reference < io::XStream > xStream =
    4711          86 :                     xRoot->openStreamElement( OUString(SL::aMSMacroCmds), embed::ElementModes::READWRITE );
    4712          86 :             SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
    4713             : 
    4714          86 :             sal_uInt8 *pBuffer = new sal_uInt8[pWwFib->lcbCmds];
    4715          86 :             pWwFib->lcbCmds = pTableStream->Read(pBuffer, pWwFib->lcbCmds);
    4716          86 :             pStream->Write(pBuffer, pWwFib->lcbCmds);
    4717          86 :             delete[] pBuffer;
    4718          86 :             delete pStream;
    4719             :         }
    4720           0 :         catch ( const uno::Exception& )
    4721             :         {
    4722          86 :         }
    4723             :     }
    4724             : }
    4725             : 
    4726         186 : void SwWW8ImplReader::ReadDocVars()
    4727             : {
    4728         186 :     std::vector<OUString> aDocVarStrings;
    4729         372 :     std::vector<ww::bytes> aDocVarStringIds;
    4730         372 :     std::vector<OUString> aDocValueStrings;
    4731         186 :     WW8ReadSTTBF(!bVer67, *pTableStream, pWwFib->fcStwUser,
    4732             :         pWwFib->lcbStwUser, bVer67 ? 2 : 0, eStructCharSet,
    4733         372 :         aDocVarStrings, &aDocVarStringIds, &aDocValueStrings);
    4734         186 :     if (!bVer67) {
    4735             :         using namespace ::com::sun::star;
    4736             : 
    4737             :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    4738         182 :             mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
    4739             :         uno::Reference<document::XDocumentProperties> xDocProps(
    4740         364 :             xDPS->getDocumentProperties());
    4741             :         OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
    4742             :         uno::Reference<beans::XPropertyContainer> xUserDefinedProps =
    4743         364 :             xDocProps->getUserDefinedProperties();
    4744             :         OSL_ENSURE(xUserDefinedProps.is(), "UserDefinedProperties is null");
    4745             : 
    4746         222 :         for(size_t i=0; i<aDocVarStrings.size(); i++)
    4747             :         {
    4748          40 :             const OUString &rName = aDocVarStrings[i];
    4749          40 :             uno::Any aValue;
    4750          40 :             aValue <<= OUString(aDocValueStrings[i]);
    4751             :             try {
    4752          40 :                 xUserDefinedProps->addProperty( rName,
    4753             :                     beans::PropertyAttribute::REMOVABLE,
    4754          40 :                     aValue );
    4755           0 :             } catch (const uno::Exception &) {
    4756             :                 // ignore
    4757             :             }
    4758         222 :         }
    4759         186 :     }
    4760         186 : }
    4761             : 
    4762             : /**
    4763             :  * Document Info
    4764             :  */
    4765         182 : void SwWW8ImplReader::ReadDocInfo()
    4766             : {
    4767         182 :     if( pStg )
    4768             :     {
    4769             :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    4770         182 :             mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
    4771             :         uno::Reference<document::XDocumentProperties> xDocProps(
    4772         364 :             xDPS->getDocumentProperties());
    4773             :         OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
    4774             : 
    4775         182 :         if (xDocProps.is()) {
    4776         182 :             if ( pWwFib->fDot )
    4777             :             {
    4778           0 :                 OUString sTemplateURL;
    4779           0 :                 SfxMedium* pMedium = mpDocShell->GetMedium();
    4780           0 :                 if ( pMedium )
    4781             :                 {
    4782           0 :                     OUString aName = pMedium->GetName();
    4783           0 :                     INetURLObject aURL( aName );
    4784           0 :                     sTemplateURL = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
    4785           0 :                     if ( !sTemplateURL.isEmpty() )
    4786           0 :                         xDocProps->setTemplateURL( sTemplateURL );
    4787           0 :                 }
    4788             :             }
    4789         182 :             else if (pWwFib->lcbSttbfAssoc) // not a template, and has a SttbfAssoc
    4790             :             {
    4791         144 :                 long nCur = pTableStream->Tell();
    4792         144 :                 Sttb aSttb;
    4793         144 :                 pTableStream->Seek( pWwFib->fcSttbfAssoc ); // point at tgc record
    4794         144 :                 if (!aSttb.Read( *pTableStream ) )
    4795             :                     OSL_TRACE("** Read of SttbAssoc data failed!!!! ");
    4796         144 :                 pTableStream->Seek( nCur ); // return to previous position, is that necessary?
    4797             : #if OSL_DEBUG_LEVEL > 1
    4798             :                 aSttb.Print( stderr );
    4799             : #endif
    4800         288 :                 OUString sPath = aSttb.getStringAtIndex( 0x1 );
    4801         288 :                 OUString aURL;
    4802             :                 // attempt to convert to url (won't work for obvious reasons on linux)
    4803         144 :                 if ( !sPath.isEmpty() )
    4804           2 :                     ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPath, aURL );
    4805         144 :                 if (aURL.isEmpty())
    4806         142 :                     xDocProps->setTemplateURL( aURL );
    4807             :                 else
    4808         146 :                     xDocProps->setTemplateURL( sPath );
    4809             : 
    4810             :             }
    4811         182 :             sfx2::LoadOlePropertySet(xDocProps, pStg);
    4812         182 :         }
    4813             :     }
    4814         182 : }
    4815             : 
    4816         182 : static void lcl_createTemplateToProjectEntry( const uno::Reference< container::XNameContainer >& xPrjNameCache, const OUString& sTemplatePathOrURL, const OUString& sVBAProjName )
    4817             : {
    4818         182 :     if ( xPrjNameCache.is() )
    4819             :     {
    4820         134 :         INetURLObject aObj;
    4821         134 :         aObj.SetURL( sTemplatePathOrURL );
    4822         134 :         bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
    4823         268 :         OUString aURL;
    4824         134 :         if ( bIsURL )
    4825           0 :             aURL = sTemplatePathOrURL;
    4826             :         else
    4827             :         {
    4828         134 :             osl::FileBase::getFileURLFromSystemPath( sTemplatePathOrURL, aURL );
    4829         134 :             aObj.SetURL( aURL );
    4830             :         }
    4831             :         try
    4832             :         {
    4833         134 :             OUString templateNameWithExt = aObj.GetLastName();
    4834         268 :             OUString templateName;
    4835         134 :             sal_Int32 nIndex =  templateNameWithExt.lastIndexOf( '.' );
    4836         134 :             if ( nIndex != -1 )
    4837             :             {
    4838           0 :                 templateName = templateNameWithExt.copy( 0, nIndex );
    4839           0 :                 xPrjNameCache->insertByName( templateName, uno::makeAny( sVBAProjName ) );
    4840         134 :             }
    4841             :         }
    4842           0 :         catch( const uno::Exception& )
    4843             :         {
    4844         134 :         }
    4845             :     }
    4846         182 : }
    4847             : 
    4848             : class WW8Customizations
    4849             : {
    4850             :     SvStream* mpTableStream;
    4851             :     WW8Fib mWw8Fib;
    4852             : public:
    4853             :     WW8Customizations( SvStream*, WW8Fib& );
    4854             :     bool  Import( SwDocShell* pShell );
    4855             : };
    4856             : 
    4857         182 : WW8Customizations::WW8Customizations( SvStream* pTableStream, WW8Fib& rFib ) : mpTableStream(pTableStream), mWw8Fib( rFib )
    4858             : {
    4859         182 : }
    4860             : 
    4861         182 : bool WW8Customizations::Import( SwDocShell* pShell )
    4862             : {
    4863         182 :     if ( mWw8Fib.lcbCmds == 0 || !IsEightPlus(mWw8Fib.GetFIBVersion()) )
    4864          40 :         return false;
    4865             :     try
    4866             :     {
    4867         142 :         Tcg aTCG;
    4868         142 :         long nCur = mpTableStream->Tell();
    4869         142 :         mpTableStream->Seek( mWw8Fib.fcCmds ); // point at tgc record
    4870         142 :         bool bReadResult = aTCG.Read( *mpTableStream );
    4871         142 :         mpTableStream->Seek( nCur ); // return to previous position, is that necessary?
    4872         142 :         if ( !bReadResult )
    4873             :         {
    4874             :             SAL_WARN("sw.ww8", "** Read of Customization data failed!!!! ");
    4875           6 :             return false;
    4876             :         }
    4877             : #if OSL_DEBUG_LEVEL > 1
    4878             :         aTCG.Print( stderr );
    4879             : #endif
    4880         136 :         return aTCG.ImportCustomToolBar( *pShell );
    4881             :     }
    4882           0 :     catch(...)
    4883             :     {
    4884             :         SAL_WARN("sw.ww8", "** Read of Customization data failed!!!! epically");
    4885           0 :         return false;
    4886             :     }
    4887             : }
    4888             : 
    4889         182 : bool SwWW8ImplReader::ReadGlobalTemplateSettings( const OUString& sCreatedFrom, const uno::Reference< container::XNameContainer >& xPrjNameCache )
    4890             : {
    4891         182 :     SvtPathOptions aPathOpt;
    4892         364 :     OUString aAddinPath = aPathOpt.GetAddinPath();
    4893         364 :     uno::Sequence< OUString > sGlobalTemplates;
    4894             : 
    4895             :     // first get the autoload addins in the directory STARTUP
    4896         364 :     uno::Reference<ucb::XSimpleFileAccess3> xSFA(ucb::SimpleFileAccess::create(::comphelper::getProcessComponentContext()));
    4897             : 
    4898         182 :     if( xSFA->isFolder( aAddinPath ) )
    4899           0 :         sGlobalTemplates = xSFA->getFolderContents( aAddinPath, sal_False );
    4900             : 
    4901         182 :     sal_Int32 nEntries = sGlobalTemplates.getLength();
    4902         182 :     bool bRes = true;
    4903         182 :     for ( sal_Int32 i=0; i<nEntries; ++i )
    4904             :     {
    4905           0 :         INetURLObject aObj;
    4906           0 :         aObj.SetURL( sGlobalTemplates[ i ] );
    4907           0 :         bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
    4908           0 :         OUString aURL;
    4909           0 :         if ( bIsURL )
    4910           0 :                 aURL = sGlobalTemplates[ i ];
    4911             :         else
    4912           0 :                 osl::FileBase::getFileURLFromSystemPath( sGlobalTemplates[ i ], aURL );
    4913           0 :         if ( !aURL.endsWithIgnoreAsciiCase( ".dot" ) || ( !sCreatedFrom.isEmpty() && sCreatedFrom.equals( aURL ) ) )
    4914           0 :             continue; // don't try and read the same document as ourselves
    4915             : 
    4916           0 :         SotStorageRef rRoot = new SotStorage( aURL, STREAM_STD_READWRITE, STORAGE_TRANSACTED );
    4917             : 
    4918           0 :         BasicProjImportHelper aBasicImporter( *mpDocShell );
    4919             :         // Import vba via oox filter
    4920           0 :         aBasicImporter.import( mpDocShell->GetMedium()->GetInputStream() );
    4921           0 :         lcl_createTemplateToProjectEntry( xPrjNameCache, aURL, aBasicImporter.getProjectName() );
    4922             :         // Read toolbars & menus
    4923           0 :         SvStorageStreamRef refMainStream = rRoot->OpenSotStream( OUString( "WordDocument" ));
    4924           0 :         refMainStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
    4925           0 :         WW8Fib aWwFib( *refMainStream, 8 );
    4926           0 :         SvStorageStreamRef xTableStream = rRoot->OpenSotStream(OUString::createFromAscii( aWwFib.fWhichTblStm ? SL::a1Table : SL::a0Table), STREAM_STD_READ);
    4927             : 
    4928           0 :         if (xTableStream.Is() && SVSTREAM_OK == xTableStream->GetError())
    4929             :         {
    4930           0 :             xTableStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
    4931           0 :             WW8Customizations aGblCustomisations( xTableStream, aWwFib );
    4932           0 :             aGblCustomisations.Import( mpDocShell );
    4933             :         }
    4934           0 :     }
    4935         364 :     return bRes;
    4936             : }
    4937             : 
    4938         186 : sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos)
    4939             : {
    4940         186 :     sal_uLong nErrRet = 0;
    4941             : 
    4942         186 :     rDoc.SetDocumentType( SwDoc::DOCTYPE_MSWORD );
    4943         186 :     if (mbNewDoc && pStg && !pGloss)
    4944         182 :         ReadDocInfo();
    4945             : 
    4946         186 :     ::ww8::WW8FibData * pFibData = new ::ww8::WW8FibData();
    4947             : 
    4948         186 :     if (pWwFib->fReadOnlyRecommended)
    4949           0 :         pFibData->setReadOnlyRecommended(true);
    4950             :     else
    4951         186 :         pFibData->setReadOnlyRecommended(false);
    4952             : 
    4953         186 :     if (pWwFib->fWriteReservation)
    4954           0 :         pFibData->setWriteReservation(true);
    4955             :     else
    4956         186 :         pFibData->setWriteReservation(false);
    4957             : 
    4958         186 :     ::sw::tExternalDataPointer pExternalFibData(pFibData);
    4959             : 
    4960         186 :     rDoc.getIDocumentExternalData().setExternalData(::sw::FIB, pExternalFibData);
    4961             : 
    4962             :     ::sw::tExternalDataPointer pSttbfAsoc
    4963         372 :           (new ::ww8::WW8Sttb<ww8::WW8Struct>(*pTableStream, pWwFib->fcSttbfAssoc, pWwFib->lcbSttbfAssoc));
    4964             : 
    4965         186 :     rDoc.getIDocumentExternalData().setExternalData(::sw::STTBF_ASSOC, pSttbfAsoc);
    4966             : 
    4967         186 :     if (pWwFib->fWriteReservation || pWwFib->fReadOnlyRecommended)
    4968             :     {
    4969           0 :         SwDocShell * pDocShell = rDoc.GetDocShell();
    4970           0 :         if (pDocShell)
    4971           0 :             pDocShell->SetReadOnlyUI(true);
    4972             :     }
    4973             : 
    4974         186 :     pPaM = rDoc.CreateUnoCrsr(rPos);
    4975             : 
    4976         186 :     pCtrlStck = new SwWW8FltControlStack( &rDoc, nFieldFlags, *this );
    4977             : 
    4978         186 :     mpRedlineStack = new sw::util::RedlineStack(rDoc);
    4979             : 
    4980             :     /*
    4981             :         RefFldStck: Keeps track of bookmarks which may be inserted as
    4982             :         variables intstead.
    4983             :     */
    4984         186 :     pReffedStck = new SwWW8ReferencedFltEndStack(&rDoc, nFieldFlags);
    4985         186 :     pReffingStck = new SwWW8FltRefStack(&rDoc, nFieldFlags);
    4986             : 
    4987         186 :     pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags);
    4988             : 
    4989         186 :     sal_uInt16 nPageDescOffset = rDoc.GetPageDescCnt();
    4990             : 
    4991         372 :     SwNodeIndex aSttNdIdx( rDoc.GetNodes() );
    4992         372 :     SwRelNumRuleSpaces aRelNumRule(rDoc, mbNewDoc);
    4993             : 
    4994         186 :     sal_uInt16 eMode = nsRedlineMode_t::REDLINE_SHOW_INSERT;
    4995             : 
    4996         186 :     mpSprmParser = new wwSprmParser(pWwFib->GetFIBVersion());
    4997             : 
    4998             :     // Set handy helper variables
    4999         186 :     bVer6  = (6 == pWwFib->nVersion);
    5000         186 :     bVer7  = (7 == pWwFib->nVersion);
    5001         186 :     bVer67 = bVer6 || bVer7;
    5002         186 :     bVer8  = (8 == pWwFib->nVersion);
    5003             : 
    5004         186 :     eTextCharSet = WW8Fib::GetFIBCharset(pWwFib->chse);
    5005         186 :     eStructCharSet = WW8Fib::GetFIBCharset(pWwFib->chseTables);
    5006             : 
    5007         186 :     bWWBugNormal = pWwFib->nProduct == 0xc03d;
    5008             : 
    5009         186 :     if (!mbNewDoc)
    5010           0 :         aSttNdIdx = pPaM->GetPoint()->nNode;
    5011             : 
    5012         186 :     ::StartProgress(STR_STATSTR_W4WREAD, 0, 100, mpDocShell);
    5013             : 
    5014             :     // read Font Table
    5015         186 :     pFonts = new WW8Fonts( *pTableStream, *pWwFib );
    5016             : 
    5017             :     // Document Properties
    5018             :     pWDop = new WW8Dop( *pTableStream, pWwFib->nFib, pWwFib->fcDop,
    5019         186 :         pWwFib->lcbDop );
    5020             : 
    5021         186 :     if (mbNewDoc)
    5022         186 :         ImportDop();
    5023             : 
    5024             :     /*
    5025             :         Import revisioning data: author names
    5026             :     */
    5027         186 :     if( pWwFib->lcbSttbfRMark )
    5028             :     {
    5029             :         ReadRevMarkAuthorStrTabl( *pTableStream,
    5030             :                                     pWwFib->fcSttbfRMark,
    5031         120 :                                     pWwFib->lcbSttbfRMark, rDoc );
    5032             :     }
    5033             : 
    5034             :     // Initialize our String/ID map for Linked Sections
    5035         372 :     std::vector<OUString> aLinkStrings;
    5036         372 :     std::vector<ww::bytes> aStringIds;
    5037             : 
    5038         186 :     WW8ReadSTTBF(!bVer67, *pTableStream, pWwFib->fcSttbFnm,
    5039             :         pWwFib->lcbSttbFnm, bVer67 ? 2 : 0, eStructCharSet,
    5040         372 :         aLinkStrings, &aStringIds);
    5041             : 
    5042         186 :     for (size_t i=0; i < aLinkStrings.size() && i < aStringIds.size(); ++i)
    5043             :     {
    5044           0 :         ww::bytes stringId = aStringIds[i];
    5045           0 :         WW8_STRINGID *stringIdStruct = (WW8_STRINGID*)(&stringId[0]);
    5046           0 :         aLinkStringMap[SVBT16ToShort(stringIdStruct->nStringId)] =
    5047           0 :             aLinkStrings[i];
    5048           0 :     }
    5049             : 
    5050         186 :     ReadDocVars(); // import document variables as meta information.
    5051             : 
    5052         186 :     ::SetProgressState(nProgress, mpDocShell);    // Update
    5053             : 
    5054         186 :     pLstManager = new WW8ListManager( *pTableStream, *this );
    5055             : 
    5056             :     /*
    5057             :         zuerst(!) alle Styles importieren   (siehe WW8PAR2.CXX)
    5058             :             VOR dem Import der Listen !!
    5059             :     */
    5060         186 :     ::SetProgressState(nProgress, mpDocShell);    // Update
    5061         186 :     pStyles = new WW8RStyle( *pWwFib, this );     // Styles
    5062         186 :     pStyles->Import();
    5063             : 
    5064             :     /*
    5065             :         In the end: (also see WW8PAR3.CXX)
    5066             : 
    5067             :         Go through all Styles and attach respective List Format
    5068             :         AFTER we imported the Styles and AFTER we imported the Lists!
    5069             :     */
    5070         186 :     ::SetProgressState(nProgress, mpDocShell); // Update
    5071         186 :     pStyles->PostProcessStyles();
    5072             : 
    5073         186 :     if (!vColl.empty())
    5074         186 :         SetOutlineStyles();
    5075             : 
    5076         186 :     pSBase = new WW8ScannerBase(pStrm,pTableStream,pDataStream,pWwFib);
    5077             : 
    5078             :     static const SvxExtNumType eNumTA[16] =
    5079             :     {
    5080             :         SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER,
    5081             :         SVX_NUM_CHARS_UPPER_LETTER_N, SVX_NUM_CHARS_LOWER_LETTER_N,
    5082             :         SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_ARABIC,
    5083             :         SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_ARABIC,
    5084             :         SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_ARABIC,
    5085             :         SVX_NUM_ARABIC, SVX_NUM_ARABIC
    5086             :     };
    5087             : 
    5088         186 :     if (pSBase->AreThereFootnotes())
    5089             :     {
    5090             :         static const SwFtnNum eNumA[4] =
    5091             :         {
    5092             :             FTNNUM_DOC, FTNNUM_CHAPTER, FTNNUM_PAGE, FTNNUM_DOC
    5093             :         };
    5094             : 
    5095           2 :         SwFtnInfo aInfo;
    5096           2 :         aInfo = rDoc.GetFtnInfo(); // Copy-Ctor private
    5097             : 
    5098           2 :         aInfo.ePos = FTNPOS_PAGE;
    5099           2 :         aInfo.eNum = eNumA[pWDop->rncFtn];
    5100           2 :         aInfo.aFmt.SetNumberingType( static_cast< sal_uInt16 >(eNumTA[pWDop->nfcFtnRef]) );
    5101           2 :         if( pWDop->nFtn )
    5102           2 :             aInfo.nFtnOffset = pWDop->nFtn - 1;
    5103           2 :         rDoc.SetFtnInfo( aInfo );
    5104             :     }
    5105         186 :     if( pSBase->AreThereEndnotes() )
    5106             :     {
    5107           0 :         SwEndNoteInfo aInfo;
    5108           0 :         aInfo = rDoc.GetEndNoteInfo(); // Same as for Ftn
    5109             : 
    5110           0 :         aInfo.aFmt.SetNumberingType( static_cast< sal_uInt16 >(eNumTA[pWDop->nfcEdnRef]) );
    5111           0 :         if( pWDop->nEdn )
    5112           0 :             aInfo.nFtnOffset = pWDop->nEdn - 1;
    5113           0 :         rDoc.SetEndNoteInfo( aInfo );
    5114             :     }
    5115             : 
    5116         186 :     if( pWwFib->lcbPlcfhdd )
    5117          78 :         pHdFt = new WW8PLCF_HdFt( pTableStream, *pWwFib, *pWDop );
    5118             : 
    5119         186 :     if (!mbNewDoc)
    5120             :     {
    5121             :         // inserting into an existing document:
    5122             :         // As only complete paragraphs are inserted, the current one
    5123             :         // needs to be splitted - once or even twice.
    5124           0 :         const SwPosition* pPos = pPaM->GetPoint();
    5125             : 
    5126             :         // split current paragraph to get new paragraph for the insertion
    5127           0 :         rDoc.getIDocumentContentOperations().SplitNode( *pPos, false );
    5128             : 
    5129             :         // another split, if insertion position was not at the end of the current paragraph.
    5130           0 :         SwTxtNode const*const pTxtNd = pPos->nNode.GetNode().GetTxtNode();
    5131           0 :         if ( pTxtNd->GetTxt().getLength() )
    5132             :         {
    5133           0 :             rDoc.getIDocumentContentOperations().SplitNode( *pPos, false );
    5134             :             // move PaM back to the newly empty paragraph
    5135           0 :             pPaM->Move( fnMoveBackward );
    5136             :         }
    5137             : 
    5138             :         // suppress insertion of tables inside footnotes.
    5139           0 :         const sal_uLong nNd = pPos->nNode.GetIndex();
    5140           0 :         bReadNoTbl = ( nNd < rDoc.GetNodes().GetEndOfInserts().GetIndex() &&
    5141           0 :                        rDoc.GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
    5142             :     }
    5143             : 
    5144         186 :     ::SetProgressState(nProgress, mpDocShell); // Update
    5145             : 
    5146             :     // loop for each glossary entry and add dummy section node
    5147         186 :     if (pGloss)
    5148             :     {
    5149           0 :         WW8PLCF aPlc(*pTableStream, pWwFib->fcPlcfglsy, pWwFib->lcbPlcfglsy, 0);
    5150             : 
    5151             :         WW8_CP nStart, nEnd;
    5152             :         void* pDummy;
    5153             : 
    5154           0 :         for (int i = 0; i < pGloss->GetNoStrings(); ++i, aPlc.advance())
    5155             :         {
    5156           0 :             SwNodeIndex aIdx( rDoc.GetNodes().GetEndOfContent());
    5157             :             SwTxtFmtColl* pColl =
    5158           0 :                 rDoc.getIDocumentStylePoolAccess().GetTxtCollFromPool(RES_POOLCOLL_STANDARD,
    5159           0 :                 false);
    5160             :             SwStartNode *pNode =
    5161           0 :                 rDoc.GetNodes().MakeTextSection(aIdx,
    5162           0 :                 SwNormalStartNode,pColl);
    5163           0 :             pPaM->GetPoint()->nNode = pNode->GetIndex()+1;
    5164           0 :             pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(),0);
    5165           0 :             aPlc.Get( nStart, nEnd, pDummy );
    5166           0 :             ReadText(nStart,nEnd-nStart-1,MAN_MAINTEXT);
    5167           0 :         }
    5168             :     }
    5169             :     else // ordinary case
    5170             :     {
    5171         186 :         if (mbNewDoc && pStg && !pGloss) /*meaningless for a glossary, cmc*/
    5172             :         {
    5173         182 :             mpDocShell->SetIsTemplate( pWwFib->fDot ); // point at tgc record
    5174             :             uno::Reference<document::XDocumentPropertiesSupplier> const
    5175         182 :                 xDocPropSupp(mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
    5176         364 :             uno::Reference< document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW );
    5177             : 
    5178         364 :             OUString sCreatedFrom = xDocProps->getTemplateURL();
    5179         364 :             uno::Reference< container::XNameContainer > xPrjNameCache;
    5180         364 :             uno::Reference< lang::XMultiServiceFactory> xSF(mpDocShell->GetModel(), uno::UNO_QUERY);
    5181         182 :             if ( xSF.is() )
    5182         182 :                 xPrjNameCache.set( xSF->createInstance( "ooo.vba.VBAProjectNameProvider" ), uno::UNO_QUERY );
    5183             : 
    5184             :             // Read Global templates
    5185         182 :             ReadGlobalTemplateSettings( sCreatedFrom, xPrjNameCache );
    5186             : 
    5187             :             // Create and insert Word vba Globals
    5188         364 :             uno::Any aGlobs;
    5189         364 :             uno::Sequence< uno::Any > aArgs(1);
    5190         182 :             aArgs[ 0 ] <<= mpDocShell->GetModel();
    5191         182 :             aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( "ooo.vba.word.Globals", aArgs );
    5192             : 
    5193             : #if HAVE_FEATURE_SCRIPTING
    5194         182 :             BasicManager *pBasicMan = mpDocShell->GetBasicManager();
    5195         182 :             if (pBasicMan)
    5196         182 :                 pBasicMan->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
    5197             : #endif
    5198         364 :             BasicProjImportHelper aBasicImporter( *mpDocShell );
    5199             :             // Import vba via oox filter
    5200         182 :             bool bRet = aBasicImporter.import( mpDocShell->GetMedium()->GetInputStream() );
    5201             : 
    5202         182 :             lcl_createTemplateToProjectEntry( xPrjNameCache, sCreatedFrom, aBasicImporter.getProjectName() );
    5203         182 :             WW8Customizations aCustomisations( pTableStream, *pWwFib );
    5204         182 :             aCustomisations.Import( mpDocShell );
    5205             : 
    5206         182 :             if( bRet )
    5207           2 :                 rDoc.SetContainsMSVBasic(true);
    5208             : 
    5209         364 :             StoreMacroCmds();
    5210             :         }
    5211         186 :         mbOnLoadingMain = true;
    5212         186 :         ReadText(0, pWwFib->ccpText, MAN_MAINTEXT);
    5213         186 :         mbOnLoadingMain = false;
    5214             :     }
    5215             : 
    5216         186 :     ::SetProgressState(nProgress, mpDocShell); // Update
    5217             : 
    5218         186 :     if (pDrawPg && pMSDffManager && pMSDffManager->GetShapeOrders())
    5219             :     {
    5220             :         // Helper array to chain the inserted frames (instead of SdrTxtObj)
    5221          56 :         SvxMSDffShapeTxBxSort aTxBxSort;
    5222             : 
    5223             :         // Ensure correct z-order of read Escher objects
    5224          56 :         sal_uInt16 nShapeCount = pMSDffManager->GetShapeOrders()->size();
    5225             : 
    5226         716 :         for (sal_uInt16 nShapeNum=0; nShapeNum < nShapeCount; nShapeNum++)
    5227             :         {
    5228             :             SvxMSDffShapeOrder *pOrder =
    5229         660 :                 &(*pMSDffManager->GetShapeOrders())[nShapeNum];
    5230             :             // Insert Pointer into new Sort array
    5231         660 :             if (pOrder->nTxBxComp && pOrder->pFly)
    5232          12 :                 aTxBxSort.insert(pOrder);
    5233             :         }
    5234             :         // Chain Frames
    5235          56 :         if( !aTxBxSort.empty() )
    5236             :         {
    5237          12 :             SwFmtChain aChain;
    5238          24 :             for( SvxMSDffShapeTxBxSort::iterator it = aTxBxSort.begin(); it != aTxBxSort.end(); ++it )
    5239             :             {
    5240          12 :                 SvxMSDffShapeOrder *pOrder = *it;
    5241             : 
    5242             :                 // Initialize FlyFrame Formats
    5243          12 :                 SwFlyFrmFmt* pFlyFmt     = pOrder->pFly;
    5244          12 :                 SwFlyFrmFmt* pNextFlyFmt = 0;
    5245          12 :                 SwFlyFrmFmt* pPrevFlyFmt = 0;
    5246             : 
    5247             :                 // Determine successor, if we can
    5248          12 :                 SvxMSDffShapeTxBxSort::iterator tmpIter1 = it;
    5249          12 :                 ++tmpIter1;
    5250          12 :                 if( tmpIter1 != aTxBxSort.end() )
    5251             :                 {
    5252           0 :                     SvxMSDffShapeOrder *pNextOrder = *tmpIter1;
    5253           0 :                     if ((0xFFFF0000 & pOrder->nTxBxComp)
    5254           0 :                            == (0xFFFF0000 & pNextOrder->nTxBxComp))
    5255           0 :                         pNextFlyFmt = pNextOrder->pFly;
    5256             :                 }
    5257             :                 // Determine precessor, if we can
    5258          12 :                 if( it != aTxBxSort.begin() )
    5259             :                 {
    5260           0 :                     SvxMSDffShapeTxBxSort::iterator tmpIter2 = it;
    5261           0 :                     --tmpIter2;
    5262           0 :                     SvxMSDffShapeOrder *pPrevOrder = *tmpIter2;
    5263           0 :                     if ((0xFFFF0000 & pOrder->nTxBxComp)
    5264           0 :                            == (0xFFFF0000 & pPrevOrder->nTxBxComp))
    5265           0 :                         pPrevFlyFmt = pPrevOrder->pFly;
    5266             :                 }
    5267             :                 // If successor or predecessor present, insert the
    5268             :                 // chain at the FlyFrame Format
    5269          12 :                 if (pNextFlyFmt || pPrevFlyFmt)
    5270             :                 {
    5271           0 :                     aChain.SetNext( pNextFlyFmt );
    5272           0 :                     aChain.SetPrev( pPrevFlyFmt );
    5273           0 :                     pFlyFmt->SetFmtAttr( aChain );
    5274             :                 }
    5275          12 :             }
    5276          56 :         }
    5277             :     }
    5278             : 
    5279         186 :     if (mbNewDoc)
    5280             :     {
    5281         186 :         if( pWDop->fRevMarking )
    5282           0 :             eMode |= nsRedlineMode_t::REDLINE_ON;
    5283         186 :         if( pWDop->fRMView )
    5284         178 :             eMode |= nsRedlineMode_t::REDLINE_SHOW_DELETE;
    5285             :     }
    5286             : 
    5287         186 :     maInsertedTables.DelAndMakeTblFrms();
    5288         186 :     maSectionManager.InsertSegments();
    5289             : 
    5290         186 :     vColl.clear();
    5291             : 
    5292         186 :     DELETEZ( pStyles );
    5293             : 
    5294         186 :     if( pFormImpl )
    5295         106 :         DeleteFormImpl();
    5296         186 :     GrafikDtor();
    5297         186 :     DELETEZ( pMSDffManager );
    5298         186 :     DELETEZ( pHdFt );
    5299         186 :     DELETEZ( pSBase );
    5300         186 :     delete pWDop;
    5301         186 :     DELETEZ( pFonts );
    5302         186 :     delete mpAtnNames;
    5303         186 :     delete mpSprmParser;
    5304         186 :     ::EndProgress(mpDocShell);
    5305             : 
    5306         186 :     pDataStream = 0;
    5307         186 :     pTableStream = 0;
    5308             : 
    5309         186 :     DeleteCtrlStk();
    5310         186 :     mpRedlineStack->closeall(*pPaM->GetPoint());
    5311         186 :     delete mpRedlineStack;
    5312         186 :     DeleteAnchorStk();
    5313         186 :     DeleteRefStks();
    5314             : 
    5315             :     // For i120928,achieve the graphics from the special bookmark with is for graphic bullet
    5316             :     {
    5317         186 :         std::vector<const SwGrfNode*> vecBulletGrf;
    5318         372 :         std::vector<SwFrmFmt*> vecFrmFmt;
    5319             : 
    5320         186 :         IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
    5321         186 :         if ( pMarkAccess )
    5322             :         {
    5323         186 :             IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findBookmark( "_PictureBullets" );
    5324         186 :             if ( ppBkmk != pMarkAccess->getBookmarksEnd() &&
    5325           0 :                        IDocumentMarkAccess::GetType( *(ppBkmk->get()) ) == IDocumentMarkAccess::BOOKMARK )
    5326             :             {
    5327           0 :                 SwTxtNode* pTxtNode = ppBkmk->get()->GetMarkStart().nNode.GetNode().GetTxtNode();
    5328             : 
    5329           0 :                 if ( pTxtNode )
    5330             :                 {
    5331           0 :                     const SwpHints* pHints = pTxtNode->GetpSwpHints();
    5332           0 :                     for( size_t nHintPos = 0; pHints && nHintPos < pHints->Count(); ++nHintPos)
    5333             :                     {
    5334           0 :                         const SwTxtAttr *pHt = (*pHints)[nHintPos];
    5335           0 :                         const sal_Int32 st = pHt->GetStart();
    5336           0 :                         if( pHt
    5337           0 :                             && pHt->Which() == RES_TXTATR_FLYCNT
    5338           0 :                             && (st >= ppBkmk->get()->GetMarkStart().nContent.GetIndex()) )
    5339             :                         {
    5340           0 :                             SwFrmFmt* pFrmFmt = pHt->GetFlyCnt().GetFrmFmt();
    5341           0 :                             vecFrmFmt.push_back(pFrmFmt);
    5342           0 :                             const SwNodeIndex* pNdIdx = pFrmFmt->GetCntnt().GetCntntIdx();
    5343             :                             const SwNodes* pNodesArray = (pNdIdx != NULL)
    5344             :                                                          ? &(pNdIdx->GetNodes())
    5345           0 :                                                          : NULL;
    5346             :                             const SwGrfNode *pGrf = (pNodesArray != NULL)
    5347           0 :                                                     ? dynamic_cast<const SwGrfNode*>((*pNodesArray)[pNdIdx->GetIndex() + 1])
    5348           0 :                                                     : NULL;
    5349           0 :                             vecBulletGrf.push_back(pGrf);
    5350             :                         }
    5351             :                     }
    5352             :                     // update graphic bullet information
    5353           0 :                     size_t nCount = pLstManager->GetWW8LSTInfoNum();
    5354           0 :                     for (size_t i = 0; i < nCount; ++i)
    5355             :                     {
    5356           0 :                         SwNumRule* pRule = pLstManager->GetNumRule(i);
    5357           0 :                         for (sal_uInt16 j = 0; j < MAXLEVEL; ++j)
    5358             :                         {
    5359           0 :                             SwNumFmt aNumFmt(pRule->Get(j));
    5360           0 :                             const sal_Int16 nType = aNumFmt.GetNumberingType();
    5361           0 :                             const sal_uInt16 nGrfBulletCP = aNumFmt.GetGrfBulletCP();
    5362           0 :                             if ( nType == SVX_NUM_BITMAP
    5363           0 :                                  && vecBulletGrf.size() > nGrfBulletCP
    5364           0 :                                  && vecBulletGrf[nGrfBulletCP] != NULL )
    5365             :                             {
    5366           0 :                                 Graphic aGraphic = vecBulletGrf[nGrfBulletCP]->GetGrf();
    5367           0 :                                 SvxBrushItem aBrush(aGraphic, GPOS_AREA, SID_ATTR_BRUSH);
    5368           0 :                                 vcl::Font aFont = numfunc::GetDefBulletFont();
    5369           0 :                                 int nHeight = aFont.GetHeight() * 12;
    5370           0 :                                 Size aPrefSize( aGraphic.GetPrefSize());
    5371           0 :                                 if (aPrefSize.Height() * aPrefSize.Width() != 0 )
    5372             :                                 {
    5373           0 :                                     int nWidth = (nHeight * aPrefSize.Width()) / aPrefSize.Height();
    5374           0 :                                     Size aSize(nWidth, nHeight);
    5375           0 :                                     aNumFmt.SetGraphicBrush(&aBrush, &aSize);
    5376             :                                 }
    5377             :                                 else
    5378             :                                 {
    5379           0 :                                     aNumFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
    5380           0 :                                     aNumFmt.SetBulletChar(0x2190);
    5381             :                                 }
    5382           0 :                                 pRule->Set( j, aNumFmt );
    5383             :                             }
    5384           0 :                         }
    5385             :                     }
    5386             :                     // Remove additional pictures
    5387           0 :                     for (sal_uInt16 i = 0; i < vecFrmFmt.size(); ++i)
    5388             :                     {
    5389           0 :                         rDoc.getIDocumentLayoutAccess().DelLayoutFmt(vecFrmFmt[i]);
    5390             :                     }
    5391             :                 }
    5392             :             }
    5393             :         }
    5394         372 :         DELETEZ( pLstManager );
    5395             :     }
    5396             : 
    5397             :     // remove extra paragraphs after attribute ctrl
    5398             :     // stacks etc. are destroyed, and before fields
    5399             :     // are updated
    5400         186 :     m_aExtraneousParas.delete_all_from_doc();
    5401             : 
    5402         186 :     UpdateFields();
    5403             : 
    5404             :     // delete the pam before the call for hide all redlines (Bug 73683)
    5405         186 :     if (mbNewDoc)
    5406         186 :       rDoc.getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)( eMode ));
    5407             : 
    5408             :     SAL_WARN_IF(mpTableEndPaM, "sw.ww8", "document ended without table ending");
    5409         186 :     mpTableEndPaM.reset();  //ensure this is deleted before pPaM
    5410         186 :     delete pPaM, pPaM = 0;
    5411         186 :     mpLastAnchorPos.reset();//ensure this is deleted before UpdatePageDescs
    5412             : 
    5413         186 :     UpdatePageDescs(rDoc, nPageDescOffset);
    5414             : 
    5415         372 :     return nErrRet;
    5416             : }
    5417             : 
    5418         186 : sal_uLong SwWW8ImplReader::SetSubStreams(SvStorageStreamRef &rTableStream,
    5419             :     SvStorageStreamRef &rDataStream)
    5420             : {
    5421         186 :     sal_uLong nErrRet = 0;
    5422             :     // 6 stands for "6 OR 7", 7 stands for "ONLY 7"
    5423         186 :     switch (pWwFib->nVersion)
    5424             :     {
    5425             :         case 6:
    5426             :         case 7:
    5427           4 :             pTableStream = pStrm;
    5428           4 :             pDataStream = pStrm;
    5429           4 :             break;
    5430             :         case 8:
    5431         182 :             if(!pStg)
    5432             :             {
    5433             :                 OSL_ENSURE( pStg, "Version 8 always needs to have a Storage!!" );
    5434           0 :                 nErrRet = ERR_SWG_READ_ERROR;
    5435           0 :                 break;
    5436             :             }
    5437             : 
    5438         364 :             rTableStream = pStg->OpenSotStream( OUString::createFromAscii(
    5439             :                 pWwFib->fWhichTblStm ? SL::a1Table : SL::a0Table),
    5440         182 :                 STREAM_STD_READ);
    5441             : 
    5442         182 :             pTableStream = &rTableStream;
    5443         182 :             pTableStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    5444             : 
    5445         364 :             rDataStream = pStg->OpenSotStream(OUString(SL::aData),
    5446         182 :                 STREAM_STD_READ | STREAM_NOCREATE );
    5447             : 
    5448         182 :             if (rDataStream.Is() && SVSTREAM_OK == rDataStream->GetError())
    5449             :             {
    5450          70 :                 pDataStream = &rDataStream;
    5451          70 :                 pDataStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
    5452             :             }
    5453             :             else
    5454         112 :                 pDataStream = pStrm;
    5455         182 :             break;
    5456             :         default:
    5457             :             // Program error!
    5458             :             OSL_ENSURE( false, "We forgot to encode nVersion!" );
    5459           0 :             nErrRet = ERR_SWG_READ_ERROR;
    5460           0 :             break;
    5461             :     }
    5462         186 :     return nErrRet;
    5463             : }
    5464             : 
    5465             : namespace
    5466             : {
    5467           0 :     utl::TempFile *MakeTemp(SvFileStream &rSt)
    5468             :     {
    5469           0 :         utl::TempFile *pT = new utl::TempFile;
    5470           0 :         pT->EnableKillingFile();
    5471           0 :         rSt.Open(pT->GetFileName(), STREAM_READWRITE | STREAM_SHARE_DENYWRITE);
    5472           0 :         return pT;
    5473             :     }
    5474             : 
    5475             : #define WW_BLOCKSIZE 0x200
    5476             : 
    5477           0 :     void DecryptRC4(msfilter::MSCodec_Std97& rCtx, SvStream &rIn, SvStream &rOut)
    5478             :     {
    5479           0 :         rIn.Seek(STREAM_SEEK_TO_END);
    5480           0 :         const sal_Size nLen = rIn.Tell();
    5481           0 :         rIn.Seek(0);
    5482             : 
    5483             :         sal_uInt8 in[WW_BLOCKSIZE];
    5484           0 :         for (sal_Size nI = 0, nBlock = 0; nI < nLen; nI += WW_BLOCKSIZE, ++nBlock)
    5485             :         {
    5486           0 :             sal_Size nBS = (nLen - nI > WW_BLOCKSIZE) ? WW_BLOCKSIZE : nLen - nI;
    5487           0 :             nBS = rIn.Read(in, nBS);
    5488           0 :             rCtx.InitCipher(nBlock);
    5489           0 :             rCtx.Decode(in, nBS, in, nBS);
    5490           0 :             rOut.Write(in, nBS);
    5491             :         }
    5492           0 :     }
    5493             : 
    5494           0 :     void DecryptXOR(msfilter::MSCodec_XorWord95 &rCtx, SvStream &rIn, SvStream &rOut)
    5495             :     {
    5496           0 :         sal_Size nSt = rIn.Tell();
    5497           0 :         rIn.Seek(STREAM_SEEK_TO_END);
    5498           0 :         sal_Size nLen = rIn.Tell();
    5499           0 :         rIn.Seek(nSt);
    5500             : 
    5501           0 :         rCtx.InitCipher();
    5502           0 :         rCtx.Skip(nSt);
    5503             : 
    5504             :         sal_uInt8 in[0x4096];
    5505           0 :         for (sal_Size nI = nSt; nI < nLen; nI += 0x4096)
    5506             :         {
    5507           0 :             sal_Size nBS = (nLen - nI > 0x4096 ) ? 0x4096 : nLen - nI;
    5508           0 :             nBS = rIn.Read(in, nBS);
    5509           0 :             rCtx.Decode(in, nBS);
    5510           0 :             rOut.Write(in, nBS);
    5511             :         }
    5512           0 :     }
    5513             : 
    5514             :     // moan, copy and paste :-(
    5515           0 :     OUString QueryPasswordForMedium(SfxMedium& rMedium)
    5516             :     {
    5517           0 :         OUString aPassw;
    5518             : 
    5519             :         using namespace com::sun::star;
    5520             : 
    5521           0 :         const SfxItemSet* pSet = rMedium.GetItemSet();
    5522             :         const SfxPoolItem *pPasswordItem;
    5523             : 
    5524           0 :         if(pSet && SfxItemState::SET == pSet->GetItemState(SID_PASSWORD, true, &pPasswordItem))
    5525           0 :             aPassw = ((const SfxStringItem *)pPasswordItem)->GetValue();
    5526             :         else
    5527             :         {
    5528             :             try
    5529             :             {
    5530           0 :                 uno::Reference< task::XInteractionHandler > xHandler( rMedium.GetInteractionHandler() );
    5531           0 :                 if( xHandler.is() )
    5532             :                 {
    5533             :                     ::comphelper::DocPasswordRequest* pRequest = new ::comphelper::DocPasswordRequest(
    5534             :                         ::comphelper::DocPasswordRequestType_MS, task::PasswordRequestMode_PASSWORD_ENTER,
    5535           0 :                         INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET ) );
    5536           0 :                     uno::Reference< task::XInteractionRequest > xRequest( pRequest );
    5537             : 
    5538           0 :                     xHandler->handle( xRequest );
    5539             : 
    5540           0 :                     if( pRequest->isPassword() )
    5541           0 :                         aPassw = pRequest->getPassword();
    5542           0 :                 }
    5543             :             }
    5544           0 :             catch( const uno::Exception& )
    5545             :             {
    5546             :             }
    5547             :         }
    5548             : 
    5549           0 :         return aPassw;
    5550             :     }
    5551             : 
    5552           0 :     uno::Sequence< beans::NamedValue > InitXorWord95Codec( ::msfilter::MSCodec_XorWord95& rCodec, SfxMedium& rMedium, WW8Fib* pWwFib )
    5553             :     {
    5554           0 :         uno::Sequence< beans::NamedValue > aEncryptionData;
    5555           0 :         SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionData, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
    5556           0 :         if ( pEncryptionData && ( pEncryptionData->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) )
    5557           0 :             aEncryptionData.realloc( 0 );
    5558             : 
    5559           0 :         if ( !aEncryptionData.getLength() )
    5560             :         {
    5561           0 :             OUString sUniPassword = QueryPasswordForMedium( rMedium );
    5562             : 
    5563             :             OString sPassword(OUStringToOString(sUniPassword,
    5564           0 :                 WW8Fib::GetFIBCharset(pWwFib->chseTables)));
    5565             : 
    5566           0 :             sal_Int32 nLen = sPassword.getLength();
    5567           0 :             if( nLen <= 15 )
    5568             :             {
    5569             :                 sal_uInt8 pPassword[16];
    5570           0 :                 memcpy(pPassword, sPassword.getStr(), nLen);
    5571           0 :                 memset(pPassword+nLen, 0, sizeof(pPassword)-nLen);
    5572             : 
    5573           0 :                 rCodec.InitKey( pPassword );
    5574           0 :                 aEncryptionData = rCodec.GetEncryptionData();
    5575             : 
    5576             :                 // the export supports RC4 algorithm only, so we have to
    5577             :                 // generate the related EncryptionData as well, so that Save
    5578             :                 // can export the document without asking for a password;
    5579             :                 // as result there will be EncryptionData for both algorithms
    5580             :                 // in the MediaDescriptor
    5581           0 :                 ::msfilter::MSCodec_Std97 aCodec97;
    5582             : 
    5583             :                 // Generate random number with a seed of time as salt.
    5584             :                 TimeValue aTime;
    5585           0 :                 osl_getSystemTime( &aTime );
    5586           0 :                 rtlRandomPool aRandomPool = rtl_random_createPool();
    5587           0 :                 rtl_random_addBytes ( aRandomPool, &aTime, 8 );
    5588             : 
    5589             :                 sal_uInt8 pDocId[ 16 ];
    5590           0 :                 rtl_random_getBytes( aRandomPool, pDocId, 16 );
    5591             : 
    5592           0 :                 rtl_random_destroyPool( aRandomPool );
    5593             : 
    5594             :                 sal_uInt16 pStd97Pass[16];
    5595           0 :                 memset( pStd97Pass, 0, sizeof( pStd97Pass ) );
    5596           0 :                 for( sal_Int32 nChar = 0; nChar < nLen; ++nChar )
    5597           0 :                     pStd97Pass[nChar] = sUniPassword[nChar];
    5598             : 
    5599           0 :                 aCodec97.InitKey( pStd97Pass, pDocId );
    5600             : 
    5601             :                 // merge the EncryptionData, there should be no conflicts
    5602           0 :                 ::comphelper::SequenceAsHashMap aEncryptionHash( aEncryptionData );
    5603           0 :                 aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) );
    5604           0 :                 aEncryptionHash >> aEncryptionData;
    5605           0 :             }
    5606             :         }
    5607             : 
    5608           0 :         return aEncryptionData;
    5609             :     }
    5610             : 
    5611           0 :     uno::Sequence< beans::NamedValue > InitStd97Codec( ::msfilter::MSCodec_Std97& rCodec, sal_uInt8 pDocId[16], SfxMedium& rMedium )
    5612             :     {
    5613           0 :         uno::Sequence< beans::NamedValue > aEncryptionData;
    5614           0 :         SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionData, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
    5615           0 :         if ( pEncryptionData && ( pEncryptionData->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) )
    5616           0 :             aEncryptionData.realloc( 0 );
    5617             : 
    5618           0 :         if ( !aEncryptionData.getLength() )
    5619             :         {
    5620           0 :             OUString sUniPassword = QueryPasswordForMedium( rMedium );
    5621             : 
    5622           0 :             sal_Int32 nLen = sUniPassword.getLength();
    5623           0 :             if ( nLen <= 15 )
    5624             :             {
    5625             :                 sal_Unicode pPassword[16];
    5626           0 :                 memset( pPassword, 0, sizeof( pPassword ) );
    5627           0 :                 for( sal_Int32 nChar = 0; nChar < nLen; ++nChar )
    5628           0 :                     pPassword[nChar] = sUniPassword[nChar];
    5629             : 
    5630           0 :                 rCodec.InitKey( pPassword, pDocId );
    5631           0 :                 aEncryptionData = rCodec.GetEncryptionData();
    5632           0 :             }
    5633             :         }
    5634             : 
    5635           0 :         return aEncryptionData;
    5636             :     }
    5637             : }
    5638             : 
    5639         186 : sal_uLong SwWW8ImplReader::LoadThroughDecryption(SwPaM& rPaM ,WW8Glossary *pGloss)
    5640             : {
    5641         186 :     sal_uLong nErrRet = 0;
    5642         186 :     if (pGloss)
    5643           0 :         pWwFib = pGloss->GetFib();
    5644             :     else
    5645         186 :         pWwFib = new WW8Fib(*pStrm, nWantedVersion);
    5646             : 
    5647         186 :     if (pWwFib->nFibError)
    5648           0 :         nErrRet = ERR_SWG_READ_ERROR;
    5649             : 
    5650         372 :     SvStorageStreamRef xTableStream, xDataStream;
    5651             : 
    5652         186 :     if (!nErrRet)
    5653         186 :         nErrRet = SetSubStreams(xTableStream, xDataStream);
    5654             : 
    5655         186 :     utl::TempFile *pTempMain = 0;
    5656         186 :     utl::TempFile *pTempTable = 0;
    5657         186 :     utl::TempFile *pTempData = 0;
    5658         372 :     SvFileStream aDecryptMain;
    5659         372 :     SvFileStream aDecryptTable;
    5660         372 :     SvFileStream aDecryptData;
    5661             : 
    5662         186 :     bool bDecrypt = false;
    5663         186 :     enum {RC4, XOR, Other} eAlgo = Other;
    5664         186 :     if (pWwFib->fEncrypted && !nErrRet)
    5665             :     {
    5666           0 :         if (!pGloss)
    5667             :         {
    5668           0 :             bDecrypt = true;
    5669           0 :             if (8 != pWwFib->nVersion)
    5670           0 :                 eAlgo = XOR;
    5671             :             else
    5672             :             {
    5673           0 :                 if (pWwFib->nKey != 0)
    5674           0 :                     eAlgo = XOR;
    5675             :                 else
    5676             :                 {
    5677           0 :                     pTableStream->Seek(0);
    5678             :                     sal_uInt32 nEncType;
    5679           0 :                     pTableStream->ReadUInt32( nEncType );
    5680           0 :                     if (nEncType == 0x10001)
    5681           0 :                         eAlgo = RC4;
    5682             :                 }
    5683             :             }
    5684             :         }
    5685             :     }
    5686             : 
    5687         186 :     if (bDecrypt)
    5688             :     {
    5689           0 :         nErrRet = ERRCODE_SVX_WRONGPASS;
    5690           0 :         SfxMedium* pMedium = mpDocShell->GetMedium();
    5691             : 
    5692           0 :         if ( pMedium )
    5693             :         {
    5694           0 :             switch (eAlgo)
    5695             :             {
    5696             :                 default:
    5697           0 :                     nErrRet = ERRCODE_SVX_READ_FILTER_CRYPT;
    5698           0 :                     break;
    5699             :                 case XOR:
    5700             :                 {
    5701           0 :                     msfilter::MSCodec_XorWord95 aCtx;
    5702           0 :                     uno::Sequence< beans::NamedValue > aEncryptionData = InitXorWord95Codec( aCtx, *pMedium, pWwFib );
    5703             : 
    5704             :                     // if initialization has failed the EncryptionData should be empty
    5705           0 :                     if ( aEncryptionData.getLength() && aCtx.VerifyKey( pWwFib->nKey, pWwFib->nHash ) )
    5706             :                     {
    5707           0 :                         nErrRet = 0;
    5708           0 :                         pTempMain = MakeTemp(aDecryptMain);
    5709             : 
    5710           0 :                         pStrm->Seek(0);
    5711             :                         size_t nUnencryptedHdr =
    5712           0 :                             (8 == pWwFib->nVersion) ? 0x44 : 0x34;
    5713           0 :                         sal_uInt8 *pIn = new sal_uInt8[nUnencryptedHdr];
    5714           0 :                         nUnencryptedHdr = pStrm->Read(pIn, nUnencryptedHdr);
    5715           0 :                         aDecryptMain.Write(pIn, nUnencryptedHdr);
    5716           0 :                         delete [] pIn;
    5717             : 
    5718           0 :                         DecryptXOR(aCtx, *pStrm, aDecryptMain);
    5719             : 
    5720           0 :                         if (!pTableStream || pTableStream == pStrm)
    5721           0 :                             pTableStream = &aDecryptMain;
    5722             :                         else
    5723             :                         {
    5724           0 :                             pTempTable = MakeTemp(aDecryptTable);
    5725           0 :                             DecryptXOR(aCtx, *pTableStream, aDecryptTable);
    5726           0 :                             pTableStream = &aDecryptTable;
    5727             :                         }
    5728             : 
    5729           0 :                         if (!pDataStream || pDataStream == pStrm)
    5730           0 :                             pDataStream = &aDecryptMain;
    5731             :                         else
    5732             :                         {
    5733           0 :                             pTempData = MakeTemp(aDecryptData);
    5734           0 :                             DecryptXOR(aCtx, *pDataStream, aDecryptData);
    5735           0 :                             pDataStream = &aDecryptData;
    5736             :                         }
    5737             : 
    5738           0 :                         pMedium->GetItemSet()->ClearItem( SID_PASSWORD );
    5739           0 :                         pMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
    5740           0 :                     }
    5741             :                 }
    5742           0 :                 break;
    5743             :                 case RC4:
    5744             :                 {
    5745             :                     sal_uInt8 aDocId[ 16 ];
    5746             :                     sal_uInt8 aSaltData[ 16 ];
    5747             :                     sal_uInt8 aSaltHash[ 16 ];
    5748             : 
    5749             :                     bool bCouldReadHeaders =
    5750           0 :                         checkRead(*pTableStream, aDocId, 16) &&
    5751           0 :                         checkRead(*pTableStream, aSaltData, 16) &&
    5752           0 :                         checkRead(*pTableStream, aSaltHash, 16);
    5753             : 
    5754           0 :                     msfilter::MSCodec_Std97 aCtx;
    5755             :                     // if initialization has failed the EncryptionData should be empty
    5756           0 :                     uno::Sequence< beans::NamedValue > aEncryptionData;
    5757           0 :                     if (bCouldReadHeaders)
    5758           0 :                         aEncryptionData = InitStd97Codec( aCtx, aDocId, *pMedium );
    5759           0 :                     if ( aEncryptionData.getLength() && aCtx.VerifyKey( aSaltData, aSaltHash ) )
    5760             :                     {
    5761           0 :                         nErrRet = 0;
    5762             : 
    5763           0 :                         pTempMain = MakeTemp(aDecryptMain);
    5764             : 
    5765           0 :                         pStrm->Seek(0);
    5766           0 :                         sal_Size nUnencryptedHdr = 0x44;
    5767           0 :                         sal_uInt8 *pIn = new sal_uInt8[nUnencryptedHdr];
    5768           0 :                         nUnencryptedHdr = pStrm->Read(pIn, nUnencryptedHdr);
    5769             : 
    5770           0 :                         DecryptRC4(aCtx, *pStrm, aDecryptMain);
    5771             : 
    5772           0 :                         aDecryptMain.Seek(0);
    5773           0 :                         aDecryptMain.Write(pIn, nUnencryptedHdr);
    5774           0 :                         delete [] pIn;
    5775             : 
    5776           0 :                         pTempTable = MakeTemp(aDecryptTable);
    5777           0 :                         DecryptRC4(aCtx, *pTableStream, aDecryptTable);
    5778           0 :                         pTableStream = &aDecryptTable;
    5779             : 
    5780           0 :                         if (!pDataStream || pDataStream == pStrm)
    5781           0 :                             pDataStream = &aDecryptMain;
    5782             :                         else
    5783             :                         {
    5784           0 :                             pTempData = MakeTemp(aDecryptData);
    5785           0 :                             DecryptRC4(aCtx, *pDataStream, aDecryptData);
    5786           0 :                             pDataStream = &aDecryptData;
    5787             :                         }
    5788             : 
    5789           0 :                         pMedium->GetItemSet()->ClearItem( SID_PASSWORD );
    5790           0 :                         pMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
    5791           0 :                     }
    5792             :                 }
    5793           0 :                 break;
    5794             :             }
    5795             :         }
    5796             : 
    5797           0 :         if (nErrRet == 0)
    5798             :         {
    5799           0 :             pStrm = &aDecryptMain;
    5800             : 
    5801           0 :             delete pWwFib;
    5802           0 :             pWwFib = new WW8Fib(*pStrm, nWantedVersion);
    5803           0 :             if (pWwFib->nFibError)
    5804           0 :                 nErrRet = ERR_SWG_READ_ERROR;
    5805             :         }
    5806             :     }
    5807             : 
    5808         186 :     if (!nErrRet)
    5809         186 :         nErrRet = CoreLoad(pGloss, *rPaM.GetPoint());
    5810             : 
    5811         186 :     delete pTempMain;
    5812         186 :     delete pTempTable;
    5813         186 :     delete pTempData;
    5814             : 
    5815         186 :     if (!pGloss)
    5816         186 :         delete pWwFib;
    5817         372 :     return nErrRet;
    5818             : }
    5819             : 
    5820         186 : void SwWW8ImplReader::SetOutlineStyles()
    5821             : {
    5822             :     // If we are inserted into a document then don't clobber existing outline
    5823             :     // levels.
    5824         186 :     sal_uInt16 nOutlineStyleListLevelWithAssignment = 0;
    5825         186 :     if (!mbNewDoc)
    5826             :     {
    5827           0 :         sw::ParaStyles aOutLined(sw::util::GetParaStyles(rDoc));
    5828           0 :         sw::util::SortByAssignedOutlineStyleListLevel(aOutLined);
    5829           0 :         sw::ParaStyles::reverse_iterator aEnd = aOutLined.rend();
    5830           0 :         for ( sw::ParaStyles::reverse_iterator aIter = aOutLined.rbegin(); aIter < aEnd; ++aIter)
    5831             :         {
    5832           0 :             if ((*aIter)->IsAssignedToListLevelOfOutlineStyle())
    5833           0 :                 nOutlineStyleListLevelWithAssignment |= 1 << (*aIter)->GetAssignedOutlineStyleLevel();
    5834             :             else
    5835           0 :                 break;
    5836           0 :         }
    5837             :     }
    5838             : 
    5839             :     // Check applied WW8 list styles at WW8 Built-In Heading Styles
    5840             :     // - Choose the list style which occurs most often as the one which provides
    5841             :     //   the list level properties for the Outline Style.
    5842             :     // - Populate temporary list of WW8 Built-In Heading Styles for further
    5843             :     // iteration
    5844         186 :     std::vector<SwWW8StyInf*> aWW8BuiltInHeadingStyles;
    5845         186 :     const SwNumRule* pChosenWW8ListStyle = NULL;
    5846             :     {
    5847         186 :         std::map<const SwNumRule*, int> aWW8ListStyleCounts;
    5848        6096 :         for (sal_uInt16 nI = 0; nI < vColl.size(); ++nI)
    5849             :         {
    5850        5910 :             SwWW8StyInf& rSI = vColl[nI];
    5851             : 
    5852        5910 :             if (!rSI.IsWW8BuiltInHeadingStyle() || !rSI.HasWW8OutlineLevel())
    5853             :             {
    5854        5702 :                 continue;
    5855             :             }
    5856             : 
    5857         208 :             aWW8BuiltInHeadingStyles.push_back(&rSI);
    5858             : 
    5859         208 :             const SwNumRule* pWW8ListStyle = rSI.GetOutlineNumrule();
    5860         208 :             if (pWW8ListStyle != NULL)
    5861             :             {
    5862             :                 std::map<const SwNumRule*, int>::iterator aCountIter
    5863          60 :                     = aWW8ListStyleCounts.find(pWW8ListStyle);
    5864          60 :                 if (aCountIter == aWW8ListStyleCounts.end())
    5865             :                 {
    5866          22 :                     aWW8ListStyleCounts[pWW8ListStyle] = 1;
    5867             :                 }
    5868             :                 else
    5869             :                 {
    5870          38 :                     ++(aCountIter->second);
    5871             :                 }
    5872             :             }
    5873             :         }
    5874             : 
    5875         186 :         int nCurrentMaxCount = 0;
    5876             :         std::map<const SwNumRule*, int>::iterator aCountIterEnd
    5877         186 :             = aWW8ListStyleCounts.end();
    5878         208 :         for (std::map<const SwNumRule*, int>::iterator aIter
    5879         186 :              = aWW8ListStyleCounts.begin();
    5880             :              aIter != aCountIterEnd; ++aIter)
    5881             :         {
    5882          22 :             if (aIter->second > nCurrentMaxCount)
    5883             :             {
    5884          22 :                 nCurrentMaxCount = aIter->second;
    5885          22 :                 pChosenWW8ListStyle = aIter->first;
    5886             :             }
    5887         186 :         }
    5888             :     }
    5889             : 
    5890             :     // - set list level properties of Outline Style - ODF's list style applied
    5891             :     // by default to headings
    5892             :     // - assign corresponding Heading Paragraph Styles to the Outline Style
    5893             :     // - If a heading Paragraph Styles is not applying the WW8 list style which
    5894             :     // had been chosen as
    5895             :     //   the one which provides the list level properties for the Outline Style,
    5896             :     // its assignment to
    5897             :     //   the Outline Style is removed. A potential applied WW8 list style is
    5898             :     // assigned directly and
    5899             :     //   its default outline level is applied.
    5900         372 :     SwNumRule aOutlineRule(*rDoc.GetOutlineNumRule());
    5901         186 :     bool bAppliedChangedOutlineStyle = false;
    5902             :     std::vector<SwWW8StyInf*>::iterator aStylesIterEnd
    5903         186 :         = aWW8BuiltInHeadingStyles.end();
    5904         394 :     for (std::vector<SwWW8StyInf*>::iterator aStyleIter
    5905         186 :          = aWW8BuiltInHeadingStyles.begin();
    5906             :          aStyleIter != aStylesIterEnd; ++aStyleIter)
    5907             :     {
    5908         208 :         SwWW8StyInf* pStyleInf = (*aStyleIter);
    5909             : 
    5910         208 :         if (!pStyleInf->bColl) //Character Style
    5911           0 :             continue;
    5912             : 
    5913             :         const sal_uInt16 nOutlineStyleListLevelOfWW8BuiltInHeadingStyle
    5914         208 :             = 1 << pStyleInf->mnWW8OutlineLevel;
    5915         208 :         if (nOutlineStyleListLevelOfWW8BuiltInHeadingStyle
    5916             :             & nOutlineStyleListLevelWithAssignment)
    5917             :         {
    5918           0 :             continue;
    5919             :         }
    5920             : 
    5921         276 :         if (pChosenWW8ListStyle != NULL && pStyleInf->mnWW8OutlineLevel
    5922          68 :                                            == pStyleInf->nListLevel)
    5923             :         {
    5924             :             const SwNumFmt& rRule
    5925          52 :                 = pChosenWW8ListStyle->Get(pStyleInf->mnWW8OutlineLevel);
    5926          52 :             aOutlineRule.Set(pStyleInf->mnWW8OutlineLevel, rRule);
    5927          52 :             bAppliedChangedOutlineStyle = true;
    5928             :         }
    5929             : 
    5930             :         // in case that there are more styles on this level ignore them
    5931             :         nOutlineStyleListLevelWithAssignment
    5932         208 :             |= nOutlineStyleListLevelOfWW8BuiltInHeadingStyle;
    5933             : 
    5934         208 :         SwTxtFmtColl* pTxtFmtColl = static_cast<SwTxtFmtColl*>(pStyleInf->pFmt);
    5935         416 :         if (pStyleInf->GetOutlineNumrule() != pChosenWW8ListStyle
    5936         224 :             || (pStyleInf->nListLevel < WW8ListManager::nMaxLevel
    5937          60 :                 && pStyleInf->mnWW8OutlineLevel != pStyleInf->nListLevel))
    5938             :         {
    5939             :             // WW8 Built-In Heading Style does not apply the chosen one.
    5940             :             // --> delete assignment to OutlineStyle, but keep its current
    5941             :             // outline level
    5942          16 :             pTxtFmtColl->DeleteAssignmentToListLevelOfOutlineStyle(false);
    5943             :             // Apply existing WW8 list style a normal list style at the
    5944             :             // Paragraph Style
    5945          16 :             if (pStyleInf->GetOutlineNumrule() != NULL)
    5946             :             {
    5947             :                 pTxtFmtColl->SetFmtAttr(
    5948           8 :                     SwNumRuleItem(pStyleInf->GetOutlineNumrule()->GetName()));
    5949             :             }
    5950             :             // apply default outline level of WW8 Built-in Heading Style
    5951             :             const sal_uInt8 nOutlineLevel
    5952             :                 = SwWW8StyInf::WW8OutlineLevelToOutlinelevel(
    5953          16 :                     pStyleInf->mnWW8OutlineLevel);
    5954             :             pTxtFmtColl->SetFmtAttr(
    5955          16 :                 SfxUInt16Item(RES_PARATR_OUTLINELEVEL, nOutlineLevel));
    5956             :         }
    5957             :         else
    5958             :         {
    5959             :             pTxtFmtColl->AssignToListLevelOfOutlineStyle(
    5960         192 :                 pStyleInf->mnWW8OutlineLevel);
    5961             :         }
    5962             :     }
    5963             : 
    5964         186 :     if (bAppliedChangedOutlineStyle)
    5965             :     {
    5966          22 :         rDoc.SetOutlineNumRule(aOutlineRule);
    5967         186 :     }
    5968         186 : }
    5969             : 
    5970          30 : const OUString* SwWW8ImplReader::GetAnnotationAuthor(sal_uInt16 nIdx)
    5971             : {
    5972          30 :     if (!mpAtnNames && pWwFib->lcbGrpStAtnOwners)
    5973             :     {
    5974             :         // Determine authors: can be found in the TableStream
    5975          12 :         mpAtnNames = new ::std::vector<OUString>;
    5976          12 :         SvStream& rStrm = *pTableStream;
    5977             : 
    5978          12 :         long nOldPos = rStrm.Tell();
    5979          12 :         rStrm.Seek( pWwFib->fcGrpStAtnOwners );
    5980             : 
    5981          12 :         long nRead = 0, nCount = pWwFib->lcbGrpStAtnOwners;
    5982          48 :         while (nRead < nCount)
    5983             :         {
    5984          24 :             if( bVer67 )
    5985             :             {
    5986             :                 mpAtnNames->push_back(read_uInt8_PascalString(rStrm,
    5987           0 :                     RTL_TEXTENCODING_MS_1252));
    5988           0 :                 nRead += mpAtnNames->rbegin()->getLength() + 1; // Length + sal_uInt8 count
    5989             :             }
    5990             :             else
    5991             :             {
    5992          24 :                 mpAtnNames->push_back(read_uInt16_PascalString(rStrm));
    5993             :                 // Unicode: double the length + sal_uInt16 count
    5994          24 :                 nRead += (mpAtnNames->rbegin()->getLength() + 1)*2;
    5995             :             }
    5996             :         }
    5997          12 :         rStrm.Seek( nOldPos );
    5998             :     }
    5999             : 
    6000          30 :     const OUString *pRet = 0;
    6001          30 :     if (mpAtnNames && nIdx < mpAtnNames->size())
    6002          30 :         pRet = &((*mpAtnNames)[nIdx]);
    6003          30 :     return pRet;
    6004             : }
    6005             : 
    6006          24 : int SwWW8ImplReader::GetAnnotationIndex(sal_uInt32 nTag)
    6007             : {
    6008          24 :     if (!mpAtnIndexes.get() && pWwFib->lcbSttbfAtnbkmk)
    6009             :     {
    6010          12 :         mpAtnIndexes.reset(new std::map<sal_uInt32, int>());
    6011          12 :         std::vector<OUString> aStrings;
    6012          24 :         std::vector<ww::bytes> aEntries;
    6013          12 :         WW8ReadSTTBF(!bVer67, *pTableStream, pWwFib->fcSttbfAtnbkmk, pWwFib->lcbSttbfAtnbkmk, sizeof(struct WW8_ATNBE), eStructCharSet, aStrings, &aEntries);
    6014          36 :         for (size_t i = 0; i < aStrings.size() && i < aEntries.size(); ++i)
    6015             :         {
    6016          24 :             ww::bytes aEntry = aEntries[i];
    6017          24 :             WW8_ATNBE* pAtnbeStruct = (WW8_ATNBE*)(&aEntry[0]);
    6018          24 :             mpAtnIndexes->insert(std::pair<sal_uInt32, int>(SVBT32ToUInt32(pAtnbeStruct->nTag), i));
    6019          36 :         }
    6020             :     }
    6021          24 :     if (mpAtnIndexes.get())
    6022             :     {
    6023          24 :         std::map<sal_uInt32, int>::iterator it = mpAtnIndexes->find(nTag);
    6024          24 :         if (it != mpAtnIndexes->end())
    6025          24 :             return it->second;
    6026             :     }
    6027           0 :     return -1;
    6028             : }
    6029             : 
    6030          24 : sal_uInt16 SwWW8ImplReader::GetAnnotationEndIndex(sal_uInt16 nStart)
    6031             : {
    6032             :     WW8_CP nStartAkt;
    6033             :     void* p;
    6034          24 :     if (mpAtnStarts->GetData(nStart, nStartAkt, p) && p)
    6035             :     {
    6036             :         // p is an FBKF, and its first 2 bytes is the ibkl member, which is the end index.
    6037          24 :         return SVBT16ToShort(*((SVBT16*)p));
    6038             :     }
    6039           0 :     return nStart;
    6040             : }
    6041             : 
    6042          24 : WW8_CP SwWW8ImplReader::GetAnnotationStart(int nIndex)
    6043             : {
    6044          24 :     if (!mpAtnStarts.get() && pWwFib->lcbPlcfAtnbkf)
    6045             :         // A PLCFBKF is a PLC whose data elements are FBKF structures (4 bytes each).
    6046          12 :         mpAtnStarts.reset(new WW8PLCFspecial(pTableStream, pWwFib->fcPlcfAtnbkf, pWwFib->lcbPlcfAtnbkf, 4));
    6047             : 
    6048          24 :     if (mpAtnStarts.get())
    6049          24 :         return mpAtnStarts->GetPos(nIndex);
    6050             :     else
    6051           0 :         return SAL_MAX_INT32;
    6052             : }
    6053             : 
    6054          24 : WW8_CP SwWW8ImplReader::GetAnnotationEnd(int nIndex)
    6055             : {
    6056          24 :     if (!mpAtnEnds.get() && pWwFib->lcbPlcfAtnbkl)
    6057             :         // The Plcfbkl structure is a PLC that contains only CPs and no additional data.
    6058          12 :         mpAtnEnds.reset(new WW8PLCFspecial(pTableStream, pWwFib->fcPlcfAtnbkl, pWwFib->lcbPlcfAtnbkl, 0));
    6059             : 
    6060          24 :     if (mpAtnEnds.get())
    6061          24 :         return mpAtnEnds->GetPos(nIndex);
    6062             :     else
    6063           0 :         return SAL_MAX_INT32;
    6064             : }
    6065             : 
    6066         190 : sal_uLong SwWW8ImplReader::LoadDoc( SwPaM& rPaM,WW8Glossary *pGloss)
    6067             : {
    6068         190 :     sal_uLong nErrRet = 0;
    6069             : 
    6070             :     {
    6071             :         static const sal_Char* aNames[ 13 ] = {
    6072             :             "WinWord/WW", "WinWord/WW8", "WinWord/WWFT",
    6073             :             "WinWord/WWFLX", "WinWord/WWFLY",
    6074             :             "WinWord/WWF",
    6075             :             "WinWord/WWFA0", "WinWord/WWFA1", "WinWord/WWFA2",
    6076             :             "WinWord/WWFB0", "WinWord/WWFB1", "WinWord/WWFB2",
    6077             :             "WinWord/RegardHindiDigits"
    6078             :         };
    6079             :         sal_uInt32 aVal[ 13 ];
    6080             : 
    6081         190 :         SwFilterOptions aOpt( 13, aNames, aVal );
    6082             : 
    6083         190 :         nIniFlags = aVal[ 0 ];
    6084         190 :         nIniFlags1= aVal[ 1 ];
    6085             :         // Moves Flys by x twips to the right or left
    6086         190 :         nIniFlyDx = aVal[ 3 ];
    6087         190 :         nIniFlyDy = aVal[ 4 ];
    6088             : 
    6089         190 :         nFieldFlags = aVal[ 5 ];
    6090         190 :         nFieldTagAlways[0] = aVal[ 6 ];
    6091         190 :         nFieldTagAlways[1] = aVal[ 7 ];
    6092         190 :         nFieldTagAlways[2] = aVal[ 8 ];
    6093         190 :         nFieldTagBad[0] = aVal[ 9 ];
    6094         190 :         nFieldTagBad[1] = aVal[ 10 ];
    6095         190 :         nFieldTagBad[2] = aVal[ 11 ];
    6096         190 :         m_bRegardHindiDigits = aVal[ 12 ] > 0;
    6097             :     }
    6098             : 
    6099         190 :     sal_uInt16 nMagic(0);
    6100         190 :     pStrm->ReadUInt16( nMagic );
    6101             : 
    6102             :     // Remember: 6 means "6 OR 7", 7 means "JUST 7"
    6103         190 :     switch (nWantedVersion)
    6104             :     {
    6105             :         case 6:
    6106             :         case 7:
    6107           4 :             if (
    6108           8 :                  0xa59b != nMagic && 0xa59c != nMagic &&
    6109           4 :                  0xa5dc != nMagic && 0xa5db != nMagic &&
    6110           0 :                  (nMagic < 0xa697 || nMagic > 0xa699)
    6111             :                )
    6112             :             {
    6113             :                 // Test for own 97 fake!
    6114           0 :                 if (pStg && 0xa5ec == nMagic)
    6115             :                 {
    6116           0 :                     sal_uLong nCurPos = pStrm->Tell();
    6117           0 :                     if (pStrm->Seek(nCurPos + 22))
    6118             :                     {
    6119             :                         sal_uInt32 nfcMin;
    6120           0 :                         pStrm->ReadUInt32( nfcMin );
    6121           0 :                         if (0x300 != nfcMin)
    6122           0 :                             nErrRet = ERR_WW6_NO_WW6_FILE_ERR;
    6123             :                     }
    6124           0 :                     pStrm->Seek( nCurPos );
    6125             :                 }
    6126             :                 else
    6127           0 :                     nErrRet = ERR_WW6_NO_WW6_FILE_ERR;
    6128             :             }
    6129           4 :             break;
    6130             :         case 8:
    6131         186 :             if (0xa5ec != nMagic)
    6132           4 :                 nErrRet = ERR_WW8_NO_WW8_FILE_ERR;
    6133         186 :             break;
    6134             :         default:
    6135           0 :             nErrRet = ERR_WW8_NO_WW8_FILE_ERR;
    6136             :             OSL_ENSURE( false, "We forgot to encode nVersion!" );
    6137           0 :             break;
    6138             :     }
    6139             : 
    6140         190 :     if (!nErrRet)
    6141         186 :         nErrRet = LoadThroughDecryption(rPaM ,pGloss);
    6142             : 
    6143         190 :     rDoc.PropagateOutlineRule();
    6144             : 
    6145         190 :     return nErrRet;
    6146             : }
    6147             : 
    6148          16 : extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportDOC()
    6149             : {
    6150          16 :     return new WW8Reader();
    6151             : }
    6152             : 
    6153         186 : sal_uLong WW8Reader::OpenMainStream( SvStorageStreamRef& rRef, sal_uInt16& rBuffSize )
    6154             : {
    6155         186 :     sal_uLong nRet = ERR_SWG_READ_ERROR;
    6156             :     OSL_ENSURE( pStg, "Where is my Storage?" );
    6157         186 :     rRef = pStg->OpenSotStream( OUString("WordDocument"), STREAM_READ | STREAM_SHARE_DENYALL);
    6158             : 
    6159         186 :     if( rRef.Is() )
    6160             :     {
    6161         186 :         if( SVSTREAM_OK == rRef->GetError() )
    6162             :         {
    6163         186 :             sal_uInt16 nOld = rRef->GetBufferSize();
    6164         186 :             rRef->SetBufferSize( rBuffSize );
    6165         186 :             rBuffSize = nOld;
    6166         186 :             nRet = 0;
    6167             :         }
    6168             :         else
    6169           0 :             nRet = rRef->GetError();
    6170             :     }
    6171         186 :     return nRet;
    6172             : }
    6173             : 
    6174         192 : sal_uLong WW8Reader::Read(SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPam, const OUString & /* FileName */)
    6175             : {
    6176         192 :     sal_uInt16 nOldBuffSize = 32768;
    6177         192 :     bool bNew = !bInsertMode; // New Doc (no inserting)
    6178             : 
    6179         192 :     SvStorageStreamRef refStrm; // So that no one else can steal the Stream
    6180         192 :     SvStream* pIn = pStrm;
    6181             : 
    6182         192 :     sal_uLong nRet = 0;
    6183         192 :     sal_uInt8 nVersion = 8;
    6184             : 
    6185         384 :     const OUString sFltName = GetFltName();
    6186         192 :     if ( sFltName=="WW6" )
    6187             :     {
    6188           4 :         if (pStrm)
    6189           4 :             nVersion = 6;
    6190             :         else
    6191             :         {
    6192             :             OSL_ENSURE(false, "WinWord 95 Reader-Read without Stream");
    6193           0 :             nRet = ERR_SWG_READ_ERROR;
    6194             :         }
    6195             :     }
    6196             :     else
    6197             :     {
    6198         188 :         if ( sFltName=="CWW6" )
    6199           0 :             nVersion = 6;
    6200         188 :         else if ( sFltName=="CWW7" )
    6201           0 :             nVersion = 7;
    6202             : 
    6203         188 :         if( pStg )
    6204             :         {
    6205         186 :             nRet = OpenMainStream( refStrm, nOldBuffSize );
    6206         186 :             pIn = &refStrm;
    6207             :         }
    6208             :         else
    6209             :         {
    6210             :             OSL_ENSURE(false, "WinWord 95/97 Reader-Read without Storage");
    6211           2 :             nRet = ERR_SWG_READ_ERROR;
    6212             :         }
    6213             :     }
    6214             : 
    6215         192 :     if( !nRet )
    6216             :     {
    6217         190 :         if (bNew)
    6218             :         {
    6219             :             // Remove Frame and offsets from Frame Template
    6220         190 :             Reader::ResetFrmFmts( rDoc );
    6221             :         }
    6222             :         SwWW8ImplReader* pRdr = new SwWW8ImplReader(nVersion, pStg, pIn, rDoc,
    6223         190 :             rBaseURL, bNew);
    6224             :         try
    6225             :         {
    6226         190 :             nRet = pRdr->LoadDoc( rPam );
    6227             :         }
    6228           0 :         catch( const std::exception& )
    6229             :         {
    6230           0 :             nRet = ERR_WW8_NO_WW8_FILE_ERR;
    6231             :         }
    6232         190 :         delete pRdr;
    6233             : 
    6234         190 :         if( refStrm.Is() )
    6235             :         {
    6236         186 :             refStrm->SetBufferSize( nOldBuffSize );
    6237         186 :             refStrm.Clear();
    6238             :         }
    6239             :         else
    6240             :         {
    6241           4 :             pIn->ResetError();
    6242             :         }
    6243             : 
    6244             :     }
    6245         384 :     return nRet;
    6246             : }
    6247             : 
    6248         576 : int WW8Reader::GetReaderType()
    6249             : {
    6250         576 :     return SW_STORAGE_READER | SW_STREAM_READER;
    6251             : }
    6252             : 
    6253           0 : bool WW8Reader::HasGlossaries() const
    6254             : {
    6255           0 :     return true;
    6256             : }
    6257             : 
    6258           0 : bool WW8Reader::ReadGlossaries(SwTextBlocks& rBlocks, bool bSaveRelFiles) const
    6259             : {
    6260           0 :     bool bRet=false;
    6261             : 
    6262           0 :     WW8Reader *pThis = const_cast<WW8Reader *>(this);
    6263             : 
    6264           0 :     sal_uInt16 nOldBuffSize = 32768;
    6265           0 :     SvStorageStreamRef refStrm;
    6266           0 :     if (!pThis->OpenMainStream(refStrm, nOldBuffSize))
    6267             :     {
    6268           0 :         WW8Glossary aGloss( refStrm, 8, pStg );
    6269           0 :         bRet = aGloss.Load( rBlocks, bSaveRelFiles );
    6270             :     }
    6271           0 :     return bRet;
    6272             : }
    6273             : 
    6274          24 : bool SwMSDffManager::GetOLEStorageName(long nOLEId, OUString& rStorageName,
    6275             :     SvStorageRef& rSrcStorage, uno::Reference < embed::XStorage >& rDestStorage) const
    6276             : {
    6277          24 :     bool bRet = false;
    6278             : 
    6279          24 :     sal_Int32 nPictureId = 0;
    6280          24 :     if (rReader.pStg)
    6281             :     {
    6282             :         // Via the TextBox-PLCF we get the right char Start-End positions
    6283             :         // We should then find the EmbedField and the corresponding Sprms
    6284             :         // in that Area.
    6285             :         // We only need the Sprm for the Picture Id.
    6286          24 :         long nOldPos = rReader.pStrm->Tell();
    6287             :         {
    6288             :             // #i32596# - consider return value of method
    6289             :             // <rReader.GetTxbxTextSttEndCp(..)>. If it returns false, method
    6290             :             // wasn't successful. Thus, continue in this case.
    6291             :             // Note: Ask MM for initialization of <nStartCp> and <nEndCp>.
    6292             :             // Note: Ask MM about assertions in method <rReader.GetTxbxTextSttEndCp(..)>.
    6293             :             WW8_CP nStartCp, nEndCp;
    6294          24 :             if ( rReader.GetTxbxTextSttEndCp(nStartCp, nEndCp,
    6295          24 :                             static_cast<sal_uInt16>((nOLEId >> 16) & 0xFFFF),
    6296          48 :                             static_cast<sal_uInt16>(nOLEId & 0xFFFF)) )
    6297             :             {
    6298          24 :                 WW8PLCFxSaveAll aSave;
    6299          24 :                 memset( &aSave, 0, sizeof( aSave ) );
    6300          24 :                 rReader.pPlcxMan->SaveAllPLCFx( aSave );
    6301             : 
    6302          24 :                 nStartCp += rReader.nDrawCpO;
    6303          24 :                 nEndCp   += rReader.nDrawCpO;
    6304          24 :                 WW8PLCFx_Cp_FKP* pChp = rReader.pPlcxMan->GetChpPLCF();
    6305          24 :                 wwSprmParser aSprmParser(rReader.pWwFib->GetFIBVersion());
    6306         120 :                 while (nStartCp <= nEndCp && !nPictureId)
    6307             :                 {
    6308          72 :                     if (!pChp->SeekPos( nStartCp))
    6309           0 :                         break;
    6310          72 :                     WW8PLCFxDesc aDesc;
    6311          72 :                     pChp->GetSprms( &aDesc );
    6312             : 
    6313          72 :                     if (aDesc.nSprmsLen && aDesc.pMemPos) // Attributes present
    6314             :                     {
    6315          48 :                         long nLen = aDesc.nSprmsLen;
    6316          48 :                         const sal_uInt8* pSprm = aDesc.pMemPos;
    6317             : 
    6318         168 :                         while (nLen >= 2 && !nPictureId)
    6319             :                         {
    6320          72 :                             sal_uInt16 nId = aSprmParser.GetSprmId(pSprm);
    6321          72 :                             sal_uInt16 nSL = aSprmParser.GetSprmSize(nId, pSprm);
    6322             : 
    6323          72 :                             if( nLen < nSL )
    6324           0 :                                 break; // Not enough Bytes left
    6325             : 
    6326          72 :                             if( 0x6A03 == nId && 0 < nLen )
    6327             :                             {
    6328             :                                 nPictureId = SVBT32ToUInt32(pSprm +
    6329          44 :                                     aSprmParser.DistanceToData(nId));
    6330          44 :                                 bRet = true;
    6331             :                             }
    6332          72 :                             pSprm += nSL;
    6333          72 :                             nLen -= nSL;
    6334             :                         }
    6335             :                     }
    6336          72 :                     nStartCp = aDesc.nEndPos;
    6337             :                 }
    6338             : 
    6339          24 :                 rReader.pPlcxMan->RestoreAllPLCFx( aSave );
    6340             :             }
    6341             :         }
    6342          24 :         rReader.pStrm->Seek( nOldPos );
    6343             :     }
    6344             : 
    6345          24 :     if( bRet )
    6346             :     {
    6347          24 :         rStorageName = OUString('_');
    6348          24 :         rStorageName += OUString::number(nPictureId);
    6349          48 :         rSrcStorage = rReader.pStg->OpenSotStorage(OUString(
    6350          24 :             SL::aObjectPool));
    6351          24 :         if (!rReader.mpDocShell)
    6352           0 :             bRet=false;
    6353             :         else
    6354          24 :             rDestStorage = rReader.mpDocShell->GetStorage();
    6355             :     }
    6356          24 :     return bRet;
    6357             : }
    6358             : 
    6359             : /**
    6360             :  * When reading a single Box (which possibly is part of a group), we do
    6361             :  * not yet have enough information to decide whether we need it as a TextField
    6362             :  * or not.
    6363             :  * So convert all of them as a precaution.
    6364             :  * FIXME: Actually implement this!
    6365             :  */
    6366          96 : bool SwMSDffManager::ShapeHasText(sal_uLong, sal_uLong) const
    6367             : {
    6368          96 :     return true;
    6369             : }
    6370             : 
    6371        5844 : bool SwWW8ImplReader::InEqualOrHigherApo(int nLvl) const
    6372             : {
    6373        5844 :     if (nLvl)
    6374        1060 :         --nLvl;
    6375             :     // #i60827# - check size of <maApos> to assure that <maApos.begin() + nLvl> can be performed.
    6376        5844 :     if ( sal::static_int_cast< sal_Int32>(nLvl) >= sal::static_int_cast< sal_Int32>(maApos.size()) )
    6377             :     {
    6378           6 :         return false;
    6379             :     }
    6380        5838 :     mycApoIter aIter = std::find(maApos.begin() + nLvl, maApos.end(), true);
    6381        5838 :     if (aIter != maApos.end())
    6382          94 :         return true;
    6383             :     else
    6384        5744 :         return false;
    6385             : }
    6386             : 
    6387         628 : bool SwWW8ImplReader::InEqualApo(int nLvl) const
    6388             : {
    6389             :     // If we are in a table, see if an apo was inserted at the level below the table.
    6390         628 :     if (nLvl)
    6391          66 :         --nLvl;
    6392         628 :     if (nLvl < 0 || static_cast<size_t>(nLvl) >= maApos.size())
    6393           0 :         return false;
    6394         628 :     return maApos[nLvl];
    6395             : }
    6396             : 
    6397             : namespace sw
    6398             : {
    6399             :     namespace hack
    6400             :     {
    6401          76 :         Position::Position(const SwPosition &rPos)
    6402          76 :             : maPtNode(rPos.nNode), mnPtCntnt(rPos.nContent.GetIndex())
    6403             :         {
    6404          76 :         }
    6405             : 
    6406          76 :         Position::Position(const Position &rPos)
    6407          76 :             : maPtNode(rPos.maPtNode), mnPtCntnt(rPos.mnPtCntnt)
    6408             :         {
    6409          76 :         }
    6410             : 
    6411          18 :         Position::operator SwPosition() const
    6412             :         {
    6413          18 :             SwPosition aRet(maPtNode);
    6414          18 :             aRet.nContent.Assign(maPtNode.GetNode().GetCntntNode(), mnPtCntnt);
    6415          18 :             return aRet;
    6416             :         }
    6417             :     }
    6418             : }
    6419             : 
    6420           2 : SwMacroInfo::SwMacroInfo()
    6421             :     : SdrObjUserData( SW_DRAWLAYER, SW_UD_IMAPDATA, 0 )
    6422           2 :     , mnShapeId(-1)
    6423             : 
    6424             : {
    6425           2 : }
    6426             : 
    6427           4 : SwMacroInfo::~SwMacroInfo()
    6428             : {
    6429           4 : }
    6430             : 
    6431           0 : SdrObjUserData* SwMacroInfo::Clone( SdrObject* /*pObj*/ ) const
    6432             : {
    6433           0 :    return new SwMacroInfo( *this );
    6434         102 : }
    6435             : 
    6436             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10