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