LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/filter/ww8 - ww8par.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1908 2854 66.9 %
Date: 2013-07-09 Functions: 108 133 81.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10