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