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