LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - ww8par.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 2086 2980 70.0 %
Date: 2015-06-13 12:38:46 Functions: 118 141 83.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11