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

Generated by: LCOV version 1.10