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 74 : class BasicProjImportHelper
130 : {
131 : SwDocShell& mrDocShell;
132 : uno::Reference< uno::XComponentContext > mxCtx;
133 : public:
134 74 : BasicProjImportHelper( SwDocShell& rShell ) : mrDocShell( rShell )
135 : {
136 74 : mxCtx = comphelper::getProcessComponentContext();
137 74 : }
138 : bool import( const uno::Reference< io::XInputStream >& rxIn );
139 : rtl::OUString getProjectName();
140 : };
141 :
142 74 : bool BasicProjImportHelper::import( const uno::Reference< io::XInputStream >& rxIn )
143 : {
144 74 : bool bRet = false;
145 : try
146 : {
147 74 : oox::ole::OleStorage root( mxCtx, rxIn, false );
148 74 : oox::StorageRef vbaStg = root.openSubStorage( CREATE_OUSTRING( "Macros" ), false );
149 74 : if ( vbaStg.get() )
150 : {
151 2 : oox::ole::VbaProject aVbaPrj( mxCtx, mrDocShell.GetModel(), rtl::OUString("Writer") );
152 4 : bRet = aVbaPrj.importVbaProject( *vbaStg );
153 74 : }
154 : }
155 4 : catch( const uno::Exception& )
156 : {
157 2 : bRet = false;
158 : }
159 74 : return bRet;
160 : }
161 :
162 74 : rtl::OUString BasicProjImportHelper::getProjectName()
163 : {
164 74 : rtl::OUString sProjName( "Standard" );
165 74 : uno::Reference< beans::XPropertySet > xProps( mrDocShell.GetModel(), uno::UNO_QUERY );
166 74 : if ( xProps.is() )
167 : {
168 : try
169 : {
170 134 : uno::Reference< script::vba::XVBACompatibility > xVBA( xProps->getPropertyValue( "BasicLibraries" ), uno::UNO_QUERY_THROW );
171 14 : sProjName = xVBA->getProjectName();
172 :
173 : }
174 60 : catch( const uno::Exception& )
175 : {
176 : }
177 : }
178 74 : return sProjName;
179 : }
180 :
181 :
182 : class Sttb : TBBase
183 : {
184 6960 : struct SBBItem
185 : {
186 : sal_uInt16 cchData;
187 : rtl::OUString data;
188 1080 : 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 64 : Sttb::Sttb() : fExtend( 0 )
207 : ,cData( 0 )
208 64 : ,cbExtra( 0 )
209 : {
210 64 : }
211 :
212 64 : Sttb::~Sttb()
213 : {
214 64 : }
215 :
216 64 : bool Sttb::Read( SvStream& rS )
217 : {
218 : OSL_TRACE("Sttb::Read() stream pos 0x%x", rS.Tell() );
219 64 : nOffSet = rS.Tell();
220 64 : rS >> fExtend >> cData >> cbExtra;
221 64 : if ( cData )
222 : {
223 1140 : for ( sal_Int32 index = 0; index < cData; ++index )
224 : {
225 1080 : SBBItem aItem;
226 1080 : rS >> aItem.cchData;
227 1080 : aItem.data = read_uInt16s_ToOUString(rS, aItem.cchData);
228 1080 : dataItems.push_back( aItem );
229 1080 : }
230 : }
231 64 : 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 64 : Sttb::getStringAtIndex( sal_uInt32 index )
250 : {
251 64 : rtl::OUString aRet;
252 64 : if ( index < dataItems.size() )
253 60 : aRet = dataItems[ index ].data;
254 64 : return aRet;
255 : }
256 :
257 30 : SwMSDffManager::SwMSDffManager( SwWW8ImplReader& rRdr )
258 30 : : SvxMSDffManager(*rRdr.pTableStream, rRdr.GetBaseURL(), rRdr.pWwFib->fcDggInfo,
259 : rRdr.pDataStream, 0, 0, COL_WHITE, 12, rRdr.pStrm),
260 60 : rReader(rRdr), pFallbackStream(0)
261 : {
262 30 : SetSvxMSDffSettings( GetSvxMSDffSettings() );
263 30 : nSvxMSDffOLEConvFlags = SwMSDffManager::GetFilterFlags();
264 30 : }
265 :
266 30 : sal_uInt32 SwMSDffManager::GetFilterFlags()
267 : {
268 30 : sal_uInt32 nFlags(0);
269 30 : const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
270 30 : if (rOpt.IsMathType2Math())
271 30 : nFlags |= OLE_MATHTYPE_2_STARMATH;
272 30 : if (rOpt.IsExcel2Calc())
273 30 : nFlags |= OLE_EXCEL_2_STARCALC;
274 30 : if (rOpt.IsPowerPoint2Impress())
275 30 : nFlags |= OLE_POWERPOINT_2_STARIMPRESS;
276 30 : if (rOpt.IsWinWord2Writer())
277 30 : nFlags |= OLE_WINWORD_2_STARWRITER;
278 30 : 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 2 : 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 2 : if ( _nCalledByGroup > 0 )
300 : {
301 0 : return 0L;
302 : }
303 :
304 2 : SdrObject* pRet = 0;
305 2 : String sStorageName;
306 2 : SotStorageRef xSrcStg;
307 2 : uno::Reference < embed::XStorage > xDstStg;
308 2 : if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
309 : {
310 : SvStorageRef xSrc = xSrcStg->OpenSotStorage( sStorageName,
311 2 : STREAM_READWRITE| STREAM_SHARE_DENYALL );
312 : OSL_ENSURE(rReader.pFormImpl, "No Form Implementation!");
313 2 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape;
314 4 : if ( (!(rReader.bIsHeader || rReader.bIsFooter)) &&
315 2 : rReader.pFormImpl->ReadOCXStream(xSrc,&xShape,true))
316 : {
317 2 : 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 2 : }
325 : }
326 2 : return pRet;
327 : }
328 :
329 24 : void SwMSDffManager::DisableFallbackStream()
330 : {
331 : OSL_ENSURE(!pFallbackStream,
332 : "if you're recursive, you're broken");
333 24 : pFallbackStream = pStData2;
334 24 : aOldEscherBlipCache = aEscherBlipCache;
335 24 : aEscherBlipCache.clear();
336 24 : pStData2 = 0;
337 24 : }
338 :
339 24 : void SwMSDffManager::EnableFallbackStream()
340 : {
341 24 : pStData2 = pFallbackStream;
342 24 : aEscherBlipCache = aOldEscherBlipCache;
343 24 : aOldEscherBlipCache.clear();
344 24 : pFallbackStream = 0;
345 24 : }
346 :
347 3060 : sal_uInt16 SwWW8ImplReader::GetToggleAttrFlags() const
348 : {
349 3060 : return pCtrlStck ? pCtrlStck->GetToggleAttrFlags() : 0;
350 : }
351 :
352 3060 : sal_uInt16 SwWW8ImplReader::GetToggleBiDiAttrFlags() const
353 : {
354 3060 : return pCtrlStck ? pCtrlStck->GetToggleBiDiAttrFlags() : 0;
355 : }
356 :
357 3060 : void SwWW8ImplReader::SetToggleAttrFlags(sal_uInt16 nFlags)
358 : {
359 3060 : if (pCtrlStck)
360 3060 : pCtrlStck->SetToggleAttrFlags(nFlags);
361 3060 : }
362 :
363 3060 : void SwWW8ImplReader::SetToggleBiDiAttrFlags(sal_uInt16 nFlags)
364 : {
365 3060 : if (pCtrlStck)
366 3060 : pCtrlStck->SetToggleBiDiAttrFlags(nFlags);
367 3060 : }
368 :
369 :
370 416 : SdrObject* SwMSDffManager::ProcessObj(SvStream& rSt,
371 : DffObjData& rObjData,
372 : void* pData,
373 : Rectangle& rTextRect,
374 : SdrObject* pObj
375 : )
376 : {
377 416 : if( !rTextRect.IsEmpty() )
378 : {
379 416 : SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
380 416 : SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
381 :
382 : // fill Import Record with data
383 416 : pImpRec->nShapeId = rObjData.nShapeId;
384 416 : pImpRec->eShapeType = rObjData.eShapeType;
385 :
386 : rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
387 : DFF_msofbtClientAnchor,
388 416 : SEEK_FROM_CURRENT_AND_RESTART );
389 416 : if( rObjData.bClientAnchor )
390 : ProcessClientAnchor( rSt,
391 138 : maShapeRecords.Current()->nRecLen,
392 276 : pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
393 :
394 : rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
395 : DFF_msofbtClientData,
396 416 : SEEK_FROM_CURRENT_AND_RESTART );
397 416 : if( rObjData.bClientData )
398 : ProcessClientData( rSt,
399 392 : maShapeRecords.Current()->nRecLen,
400 784 : 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 416 : pImpRec->nLayoutInTableCell = 0xFFFFFFFF;
406 :
407 564 : if( maShapeRecords.SeekToContent( rSt,
408 : DFF_msofbtUDefProp,
409 416 : SEEK_FROM_CURRENT_AND_RESTART )
410 148 : && maShapeRecords.Current()->nRecLen )
411 : {
412 148 : sal_uInt32 nBytesLeft = maShapeRecords.Current()->nRecLen;
413 : sal_uInt32 nUDData;
414 : sal_uInt16 nPID;
415 2076 : while( 5 < nBytesLeft )
416 : {
417 1780 : rSt >> nPID;
418 1780 : if ( rSt.GetError() != 0 )
419 0 : break;
420 1780 : rSt >> nUDData;
421 1780 : switch( nPID )
422 : {
423 38 : case 0x038F: pImpRec->nXAlign = nUDData; break;
424 : case 0x0390:
425 16 : delete pImpRec->pXRelTo;
426 16 : pImpRec->pXRelTo = new sal_uInt32;
427 16 : *(pImpRec->pXRelTo) = nUDData;
428 16 : break;
429 38 : case 0x0391: pImpRec->nYAlign = nUDData; break;
430 : case 0x0392:
431 16 : delete pImpRec->pYRelTo;
432 16 : pImpRec->pYRelTo = new sal_uInt32;
433 16 : *(pImpRec->pYRelTo) = nUDData;
434 16 : break;
435 72 : 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 6 : pImpRec->relativeHorizontalWidth = nUDData;
441 6 : 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 8 : pImpRec->isHorizontalRule = true;
447 8 : break;
448 : }
449 1780 : if ( rSt.GetError() != 0 )
450 0 : break;
451 1780 : pImpRec->bHasUDefProp = sal_True;
452 1780 : nBytesLeft -= 6;
453 : }
454 : }
455 :
456 : // Textrahmen, auch Title oder Outline
457 416 : sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
458 416 : if( nTextId )
459 : {
460 116 : 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 116 : sal_Bool bIsSimpleDrawingTextBox = (pImpRec->eShapeType == mso_sptTextBox);
467 116 : 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 96 : && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
478 : )
479 208 : );
480 : }
481 :
482 : // Distance of Textbox to it's surrounding Autoshape
483 116 : sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
484 116 : sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
485 116 : sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L );
486 116 : sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
487 :
488 116 : ScaleEmu( nTextLeft );
489 116 : ScaleEmu( nTextRight );
490 116 : ScaleEmu( nTextTop );
491 116 : ScaleEmu( nTextBottom );
492 :
493 116 : sal_Int32 nTextRotationAngle=0;
494 116 : bool bVerticalText = false;
495 116 : 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 116 : 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 116 : if (bIsSimpleDrawingTextBox)
566 : {
567 100 : SdrObject::Free( pObj );
568 100 : pObj = new SdrRectObj(OBJ_TEXT, rTextRect);
569 : }
570 :
571 : // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
572 : // hier rausrechnen
573 116 : Rectangle aNewRect(rTextRect);
574 116 : aNewRect.Bottom() -= nTextTop + nTextBottom;
575 116 : 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 116 : if( bIsSimpleDrawingTextBox )
580 : {
581 : ::boost::shared_ptr<SvxMSDffShapeInfo> const pTmpRec(
582 100 : new SvxMSDffShapeInfo(0, pImpRec->nShapeId));
583 :
584 : SvxMSDffShapeInfos_ById::const_iterator const it =
585 100 : GetShapeInfos()->find(pTmpRec);
586 100 : if (it != GetShapeInfos()->end())
587 : {
588 100 : SvxMSDffShapeInfo& rInfo = **it;
589 100 : pImpRec->bReplaceByFly = rInfo.bReplaceByFly;
590 100 : pImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
591 100 : }
592 : }
593 :
594 116 : if( bIsSimpleDrawingTextBox )
595 100 : ApplyAttributes( rSt, aSet, rObjData );
596 :
597 116 : 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 116 : aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
608 116 : aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
609 : }
610 :
611 116 : switch ( (MSO_WrapMode)
612 116 : 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 116 : aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
627 116 : aSet.Put( SdrTextRightDistItem( nTextRight ) );
628 116 : aSet.Put( SdrTextUpperDistItem( nTextTop ) );
629 116 : aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
630 116 : pImpRec->nDxTextLeft = nTextLeft;
631 116 : pImpRec->nDyTextTop = nTextTop;
632 116 : pImpRec->nDxTextRight = nTextRight;
633 116 : pImpRec->nDyTextBottom = nTextBottom;
634 :
635 : // taking the correct default (which is mso_anchorTop)
636 : MSO_Anchor eTextAnchor =
637 116 : (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
638 :
639 : SdrTextVertAdjust eTVA = bVerticalText
640 : ? SDRTEXTVERTADJUST_BLOCK
641 116 : : SDRTEXTVERTADJUST_CENTER;
642 : SdrTextHorzAdjust eTHA = bVerticalText
643 : ? SDRTEXTHORZADJUST_CENTER
644 116 : : SDRTEXTHORZADJUST_BLOCK;
645 :
646 116 : switch( eTextAnchor )
647 : {
648 : case mso_anchorTop:
649 : {
650 100 : if ( bVerticalText )
651 0 : eTHA = SDRTEXTHORZADJUST_RIGHT;
652 : else
653 100 : eTVA = SDRTEXTVERTADJUST_TOP;
654 : }
655 100 : 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 16 : 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 116 : aSet.Put( SdrTextVertAdjustItem( eTVA ) );
689 116 : aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
690 :
691 116 : if (pObj != NULL)
692 : {
693 116 : pObj->SetMergedItemSet(aSet);
694 116 : pObj->SetModel(pSdrModel);
695 :
696 116 : if (bVerticalText && dynamic_cast< SdrTextObj* >( pObj ) )
697 0 : dynamic_cast< SdrTextObj* >( pObj )->SetVerticalWriting(sal_True);
698 :
699 116 : if ( bIsSimpleDrawingTextBox )
700 : {
701 100 : 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 116 : 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 116 : 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 116 : }
748 : }
749 300 : 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 4 : pObj = new SdrRectObj(rTextRect);
755 4 : pObj->SetModel( pSdrModel );
756 4 : SfxItemSet aSet( pSdrModel->GetItemPool() );
757 4 : ApplyAttributes( rSt, aSet, rObjData );
758 :
759 4 : const SfxPoolItem* pPoolItem=NULL;
760 : SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
761 4 : sal_False, &pPoolItem );
762 4 : if( SFX_ITEM_DEFAULT == eState )
763 : aSet.Put( XFillColorItem( String(),
764 0 : Color( mnDefaultColor ) ) );
765 4 : pObj->SetMergedItemSet(aSet);
766 : }
767 :
768 : //Means that fBehindDocument is set
769 416 : if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
770 0 : pImpRec->bDrawHell = sal_True;
771 : else
772 416 : pImpRec->bDrawHell = sal_False;
773 416 : if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
774 0 : pImpRec->bHidden = sal_True;
775 416 : pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 );
776 :
777 416 : if ( nTextId )
778 : {
779 116 : pImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 );
780 116 : pImpRec->aTextId.nSequence = (sal_uInt16)nTextId;
781 : }
782 :
783 : pImpRec->nDxWrapDistLeft = GetPropertyValue(
784 416 : DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
785 : pImpRec->nDyWrapDistTop = GetPropertyValue(
786 416 : DFF_Prop_dyWrapDistTop, 0 ) / 635L;
787 : pImpRec->nDxWrapDistRight = GetPropertyValue(
788 416 : DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
789 : pImpRec->nDyWrapDistBottom = GetPropertyValue(
790 416 : DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
791 : // 16.16 fraction times total image width or height, as appropriate.
792 :
793 416 : 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 416 : DFF_Prop_cropFromTop, 0 );
821 : pImpRec->nCropFromBottom = GetPropertyValue(
822 416 : DFF_Prop_cropFromBottom, 0 );
823 : pImpRec->nCropFromLeft = GetPropertyValue(
824 416 : DFF_Prop_cropFromLeft, 0 );
825 : pImpRec->nCropFromRight = GetPropertyValue(
826 416 : DFF_Prop_cropFromRight, 0 );
827 :
828 416 : sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
829 :
830 416 : if ( !IsHardAttribute( DFF_Prop_fLine ) &&
831 : pImpRec->eShapeType == mso_sptPictureFrame )
832 : {
833 50 : nLineFlags &= ~0x08;
834 : }
835 :
836 : pImpRec->eLineStyle = (nLineFlags & 8)
837 : ? (MSO_LineStyle)GetPropertyValue(
838 : DFF_Prop_lineStyle,
839 260 : mso_lineSimple )
840 676 : : (MSO_LineStyle)USHRT_MAX;
841 : pImpRec->eLineDashing = (MSO_LineDashing)GetPropertyValue(
842 416 : DFF_Prop_lineDashing, mso_lineSolid );
843 :
844 416 : pImpRec->nFlags = rObjData.nSpFlags;
845 :
846 416 : if( pImpRec->nShapeId )
847 : {
848 : // Import-Record-Liste ergaenzen
849 416 : pImpRec->pObj = pObj;
850 416 : 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 416 : 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 144 : + pImpRec->aTextId.nSequence, pObj );
862 : }
863 : else
864 0 : delete pImpRec;
865 : }
866 :
867 416 : 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 26584 : 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 26584 : SwFltControlStack::NewAttr(rPos, rAttr);
909 26584 : }
910 :
911 51960 : SwFltStackEntry* SwWW8FltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
912 : sal_Bool bTstEnde, long nHand, sal_Bool )
913 : {
914 51960 : 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 51960 : if (rReader.pPlcxMan && rReader.pPlcxMan->GetDoingDrawTextBox())
919 : {
920 1072 : size_t nCnt = size();
921 3296 : for (size_t i=0; i < nCnt; ++i)
922 : {
923 2224 : SwFltStackEntry& rEntry = (*this)[i];
924 2224 : if (nAttrId == rEntry.pAttr->Which())
925 : {
926 232 : DeleteAndDestroy(i--);
927 232 : --nCnt;
928 : }
929 : }
930 : }
931 : else //Normal case, set the attribute into the document
932 50888 : pRet = SwFltControlStack::SetAttr(rPos, nAttrId, bTstEnde, nHand);
933 51960 : 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 102 : void SyncIndentWithList( SvxLRSpaceItem &rLR,
972 : const SwNumFmt &rFmt,
973 : const bool bFirstLineOfstSet,
974 : const bool bLeftIndentSet )
975 : {
976 102 : 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 102 : else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
984 : {
985 198 : if ( !bFirstLineOfstSet && bLeftIndentSet &&
986 96 : rFmt.GetFirstLineIndent() != 0 )
987 : {
988 0 : rLR.SetTxtFirstLineOfst( rFmt.GetFirstLineIndent() );
989 : }
990 102 : else if ( bFirstLineOfstSet && !bLeftIndentSet &&
991 0 : rFmt.GetIndentAt() != 0 )
992 : {
993 0 : rLR.SetTxtLeft( rFmt.GetIndentAt() );
994 : }
995 : }
996 102 : }
997 :
998 1722 : const SwNumFmt* SwWW8FltControlStack::GetNumFmtFromStack(const SwPosition &rPos,
999 : const SwTxtNode &rTxtNode)
1000 : {
1001 1722 : const SwNumFmt *pRet = 0;
1002 1722 : const SfxPoolItem *pItem = GetStackAttr(rPos, RES_FLTR_NUMRULE);
1003 1722 : 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 1722 : return pRet;
1014 : }
1015 :
1016 25004 : void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
1017 : SwFltStackEntry& rEntry)
1018 : {
1019 25004 : 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 2586 : SwPaM aRegion(rTmpPos);
1032 2586 : if (rEntry.MakeRegion(pDoc, aRegion, false))
1033 : {
1034 1722 : SvxLRSpaceItem aNewLR( *(SvxLRSpaceItem*)rEntry.pAttr );
1035 1722 : sal_uLong nStart = aRegion.Start()->nNode.GetIndex();
1036 1722 : sal_uLong nEnd = aRegion.End()->nNode.GetIndex();
1037 3444 : for(; nStart <= nEnd; ++nStart)
1038 : {
1039 1722 : SwNode* pNode = pDoc->GetNodes()[ nStart ];
1040 1722 : if (!pNode || !pNode->IsTxtNode())
1041 0 : continue;
1042 :
1043 1722 : SwCntntNode* pNd = (SwCntntNode*)pNode;
1044 : SvxLRSpaceItem aOldLR = (const SvxLRSpaceItem&)
1045 1722 : pNd->GetAttr(RES_LR_SPACE);
1046 :
1047 1722 : SwTxtNode *pTxtNode = (SwTxtNode*)pNode;
1048 :
1049 1722 : const SwNumFmt *pNum = 0;
1050 1722 : pNum = GetNumFmtFromStack(*aRegion.GetPoint(),
1051 1722 : *pTxtNode);
1052 1722 : if (!pNum)
1053 : {
1054 1722 : pNum = GetNumFmtFromTxtNode(*pTxtNode);
1055 : }
1056 :
1057 1722 : if ( pNum )
1058 : {
1059 : // #i103711#
1060 : const bool bFirstLineIndentSet =
1061 102 : ( rReader.maTxtNodesHavingFirstLineOfstSet.end() !=
1062 204 : rReader.maTxtNodesHavingFirstLineOfstSet.find( pNode ) );
1063 : // #i105414#
1064 : const bool bLeftIndentSet =
1065 102 : ( rReader.maTxtNodesHavingLeftIndentSet.end() !=
1066 204 : rReader.maTxtNodesHavingLeftIndentSet.find( pNode ) );
1067 : SyncIndentWithList( aNewLR, *pNum,
1068 : bFirstLineIndentSet,
1069 102 : bLeftIndentSet );
1070 : }
1071 :
1072 1722 : if (aNewLR == aOldLR)
1073 872 : continue;
1074 :
1075 850 : pNd->SetAttr(aNewLR);
1076 :
1077 3444 : }
1078 2586 : }
1079 : }
1080 2586 : 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 6 : SwPaM aRegion(rTmpPos);
1088 6 : 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 6 : 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 6 : pDoc->InsertPoolItem(aRegion, *rEntry.pAttr, 0);
1106 : }
1107 6 : }
1108 : }
1109 6 : break;
1110 : default:
1111 22412 : SwFltControlStack::SetAttrInDoc(rTmpPos, rEntry);
1112 22412 : break;
1113 : }
1114 25004 : }
1115 :
1116 24754 : const SfxPoolItem* SwWW8FltControlStack::GetFmtAttr(const SwPosition& rPos,
1117 : sal_uInt16 nWhich)
1118 : {
1119 24754 : const SfxPoolItem *pItem = GetStackAttr(rPos, nWhich);
1120 24754 : if (!pItem)
1121 : {
1122 18664 : SwCntntNode const*const pNd = rPos.nNode.GetNode().GetCntntNode();
1123 18664 : 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 18664 : if (nWhich == RES_LR_SPACE)
1134 : {
1135 1436 : SfxItemState eState = SFX_ITEM_DEFAULT;
1136 1436 : if (const SfxItemSet *pSet = pNd->GetpSwAttrSet())
1137 460 : eState = pSet->GetItemState(RES_LR_SPACE, false);
1138 1436 : if (eState != SFX_ITEM_SET && rReader.nAktColl < rReader.vColl.size())
1139 1436 : 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 18664 : if (pNd->IsTxtNode())
1147 : {
1148 18664 : xub_StrLen nPos = rPos.nContent.GetIndex();
1149 18664 : SfxItemSet aSet(pDoc->GetAttrPool(), nWhich, nWhich);
1150 18664 : if (static_cast<const SwTxtNode*>(pNd)->GetAttr(aSet, nPos, nPos))
1151 13244 : pItem = aSet.GetItem(nWhich);
1152 : }
1153 :
1154 18664 : if (!pItem)
1155 4260 : pItem = &pNd->GetAttr(nWhich);
1156 : }
1157 : }
1158 24754 : return pItem;
1159 : }
1160 :
1161 29502 : const SfxPoolItem* SwWW8FltControlStack::GetStackAttr(const SwPosition& rPos,
1162 : sal_uInt16 nWhich)
1163 : {
1164 29502 : SwFltPosition aFltPos(rPos);
1165 :
1166 29502 : size_t nSize = size();
1167 479988 : while (nSize)
1168 : {
1169 428520 : const SwFltStackEntry& rEntry = (*this)[ --nSize ];
1170 428520 : if (rEntry.pAttr->Which() == nWhich)
1171 : {
1172 66750 : if ( (rEntry.bOpen) ||
1173 : (
1174 19738 : (rEntry.m_aMkPos.m_nNode <= aFltPos.m_nNode) &&
1175 19738 : (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 7536 : return rEntry.pAttr;
1186 : }
1187 : }
1188 : }
1189 21966 : 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 308 : void SwWW8ImplReader::Read_Tab(sal_uInt16 , const sal_uInt8* pData, short nLen)
1285 : {
1286 308 : if (nLen < 0)
1287 : {
1288 122 : pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_PARATR_TABSTOP);
1289 308 : return;
1290 : }
1291 :
1292 186 : sal_uInt8 nDel = (nLen > 0) ? pData[0] : 0;
1293 186 : const sal_uInt8* pDel = pData + 1; // Del - Array
1294 :
1295 186 : sal_uInt8 nIns = (nLen > nDel*2+1) ? pData[nDel*2+1] : 0;
1296 186 : const sal_uInt8* pIns = pData + 2*nDel + 2; // Ins - Array
1297 :
1298 186 : short nRequiredLength = 2 + 2*nDel + 2*nIns + 1*nIns;
1299 186 : 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 186 : WW8_TBD* pTyp = (WW8_TBD*)(pData + 2*nDel + 2*nIns + 2);// Typ - Array
1308 :
1309 186 : SvxTabStopItem aAttr(0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP);
1310 :
1311 186 : const SwTxtFmtColl* pSty = 0;
1312 : sal_uInt16 nTabBase;
1313 186 : if (pAktColl && nAktColl < vColl.size()) // StyleDef
1314 : {
1315 64 : nTabBase = vColl[nAktColl].nBase;
1316 64 : if (nTabBase < vColl.size()) // Based On
1317 60 : pSty = (const SwTxtFmtColl*)vColl[nTabBase].pFmt;
1318 : }
1319 : else
1320 : { // Text
1321 122 : nTabBase = nAktColl;
1322 122 : if (nAktColl < vColl.size())
1323 122 : pSty = (const SwTxtFmtColl*)vColl[nAktColl].pFmt;
1324 : //TODO figure else here
1325 : }
1326 :
1327 186 : bool bFound = false;
1328 186 : ::boost::unordered_set<size_t> aLoopWatch;
1329 574 : while (pSty && !bFound)
1330 : {
1331 : const SfxPoolItem* pTabs;
1332 202 : bFound = pSty->GetAttrSet().GetItemState(RES_PARATR_TABSTOP, false,
1333 202 : &pTabs) == SFX_ITEM_SET;
1334 202 : if( bFound )
1335 16 : aAttr = *((const SvxTabStopItem*)pTabs);
1336 : else
1337 : {
1338 186 : sal_uInt16 nOldTabBase = nTabBase;
1339 : // If based on another
1340 186 : if (nTabBase < vColl.size())
1341 186 : nTabBase = vColl[nTabBase].nBase;
1342 :
1343 372 : if (
1344 186 : 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 20 : aLoopWatch.insert(reinterpret_cast<size_t>(pSty));
1352 20 : if (nTabBase < vColl.size())
1353 20 : pSty = (const SwTxtFmtColl*)vColl[nTabBase].pFmt;
1354 : //TODO figure out the else branch
1355 :
1356 80 : if (aLoopWatch.find(reinterpret_cast<size_t>(pSty)) !=
1357 80 : aLoopWatch.end())
1358 0 : pSty = 0;
1359 : }
1360 : else
1361 166 : pSty = 0; // gib die Suche auf
1362 : }
1363 : }
1364 :
1365 186 : SvxTabStop aTabStop;
1366 316 : for (short i=0; i < nDel; ++i)
1367 : {
1368 130 : sal_uInt16 nPos = aAttr.GetPos(SVBT16ToShort(pDel + i*2));
1369 130 : if( nPos != SVX_TAB_NOTFOUND )
1370 26 : aAttr.Remove( nPos, 1 );
1371 : }
1372 :
1373 410 : for (short i=0; i < nIns; ++i)
1374 : {
1375 224 : short nPos = SVBT16ToShort(pIns + i*2);
1376 224 : aTabStop.GetTabPos() = nPos;
1377 224 : switch( SVBT8ToByte( pTyp[i].aBits1 ) & 0x7 ) // pTyp[i].jc
1378 : {
1379 : case 0:
1380 12 : aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
1381 12 : break;
1382 : case 1:
1383 48 : aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER;
1384 48 : break;
1385 : case 2:
1386 60 : aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
1387 60 : 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 224 : switch( SVBT8ToByte( pTyp[i].aBits1 ) >> 3 & 0x7 )
1396 : {
1397 : case 0:
1398 218 : aTabStop.GetFill() = ' ';
1399 218 : break;
1400 : case 1:
1401 6 : aTabStop.GetFill() = '.';
1402 6 : 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 224 : sal_uInt16 nPos2 = aAttr.GetPos( nPos );
1413 224 : if (nPos2 != SVX_TAB_NOTFOUND)
1414 0 : aAttr.Remove(nPos2, 1); // sonst weigert sich das Insert()
1415 224 : aAttr.Insert(aTabStop);
1416 : }
1417 :
1418 186 : if (nIns || nDel)
1419 186 : 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 186 : }
1438 : }
1439 :
1440 : //-----------------------------------------
1441 : // DOP
1442 : //-----------------------------------------
1443 :
1444 74 : void SwWW8ImplReader::ImportDop()
1445 : {
1446 : // correct the LastPrinted date in DocumentProperties
1447 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1448 74 : mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
1449 : uno::Reference<document::XDocumentProperties> xDocuProps(
1450 74 : xDPS->getDocumentProperties());
1451 : OSL_ENSURE(xDocuProps.is(), "DocumentProperties is null");
1452 74 : if (xDocuProps.is())
1453 : {
1454 : DateTime aLastPrinted(
1455 74 : msfilter::util::DTTM2DateTime(pWDop->dttmLastPrint));
1456 74 : ::util::DateTime uDT(aLastPrinted.Get100Sec(),
1457 148 : aLastPrinted.GetSec(), aLastPrinted.GetMin(),
1458 148 : aLastPrinted.GetHour(), aLastPrinted.GetDay(),
1459 444 : aLastPrinted.GetMonth(), aLastPrinted.GetYear());
1460 74 : 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 74 : rDoc.Setn32DummyCompatabilityOptions1( pWDop->GetCompatabilityOptions());
1470 74 : 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 74 : rDoc.set(IDocumentSettingAccess::PARA_SPACE_MAX, pWDop->fDontUseHTMLAutoSpacing);
1475 74 : rDoc.set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true );
1476 : // move tabs on alignment
1477 74 : rDoc.set(IDocumentSettingAccess::TAB_COMPAT, true);
1478 : // #i24363# tab stops relative to indent
1479 74 : rDoc.set(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT, false);
1480 : // #i18732# - adjust default of option 'FollowTextFlow'
1481 74 : rDoc.SetDefault( SwFmtFollowTextFlow( sal_False ) );
1482 :
1483 : // Import Default-Tabs
1484 74 : long nDefTabSiz = pWDop->dxaTab;
1485 74 : if( nDefTabSiz < 56 )
1486 2 : nDefTabSiz = 709;
1487 :
1488 : // wir wollen genau einen DefaultTab
1489 74 : SvxTabStopItem aNewTab( 1, sal_uInt16(nDefTabSiz), SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
1490 74 : ((SvxTabStop&)aNewTab[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
1491 :
1492 74 : rDoc.GetAttrPool().SetPoolDefaultItem( aNewTab );
1493 :
1494 74 : rDoc.set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, !pWDop->fUsePrinterMetrics);
1495 74 : rDoc.set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true);
1496 74 : rDoc.set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true );
1497 74 : rDoc.set(IDocumentSettingAccess::ADD_EXT_LEADING, !pWDop->fNoLeading);
1498 74 : rDoc.set(IDocumentSettingAccess::OLD_NUMBERING, false);
1499 74 : rDoc.set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false); // #i47448#
1500 74 : rDoc.set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, !pWDop->fExpShRtn); // #i49277#, #i56856#
1501 74 : rDoc.set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // #i53199#
1502 74 : 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 74 : 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 74 : 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 74 : rDoc.set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true);
1515 :
1516 74 : rDoc.set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false); // #i13832#, #i24135#
1517 :
1518 74 : rDoc.set(IDocumentSettingAccess::TABLE_ROW_KEEP, true); //SetTableRowKeep( true );
1519 :
1520 74 : rDoc.set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true); // #i3952#
1521 :
1522 74 : rDoc.set(IDocumentSettingAccess::INVERT_BORDER_SPACING, true);
1523 74 : rDoc.set(IDocumentSettingAccess::COLLAPSE_EMPTY_CELL_PARA, true);
1524 74 : rDoc.set(IDocumentSettingAccess::TAB_OVERFLOW, true);
1525 74 : rDoc.set(IDocumentSettingAccess::UNBREAKABLE_NUMBERINGS, true);
1526 74 : rDoc.set(IDocumentSettingAccess::CLIPPED_PICTURES, true);
1527 :
1528 : //
1529 : // COMPATIBILITY FLAGS END
1530 : //
1531 :
1532 : //import magic doptypography information, if its there
1533 74 : if (pWwFib->nFib > 105)
1534 74 : 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 74 : uno::UNO_QUERY);
1543 : uno::Reference<beans::XPropertySet> xDocProps(xModelComp,
1544 74 : uno::UNO_QUERY);
1545 74 : if (xDocProps.is())
1546 : {
1547 : uno::Reference<beans::XPropertySetInfo> xInfo =
1548 74 : xDocProps->getPropertySetInfo();
1549 74 : sal_Bool bValue = false;
1550 74 : if (xInfo.is())
1551 : {
1552 74 : if (xInfo->hasPropertyByName("ApplyFormDesignMode"))
1553 : {
1554 74 : xDocProps->setPropertyValue("ApplyFormDesignMode", cppu::bool2any(bValue));
1555 : }
1556 74 : }
1557 74 : }
1558 : }
1559 :
1560 74 : mpDocShell->SetModifyPasswordHash(pWDop->lKeyProtDoc);
1561 :
1562 74 : const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
1563 74 : if (rOpt.IsUseEnhancedFields())
1564 74 : rDoc.set(IDocumentSettingAccess::PROTECT_FORM, pWDop->fProtEnabled );
1565 74 : }
1566 :
1567 74 : void SwWW8ImplReader::ImportDopTypography(const WW8DopTypography &rTypo)
1568 : {
1569 : using namespace com::sun::star;
1570 74 : 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 74 : return;
1582 : }
1583 0 : break;
1584 : default:
1585 74 : 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 74 : if (!rTypo.reserved2)
1595 : {
1596 : i18n::ForbiddenCharacters aForbidden(rTypo.GetJapanNotBeginLevel1(),
1597 64 : rTypo.GetJapanNotEndLevel1());
1598 64 : rDoc.setForbiddenCharacters(LANGUAGE_JAPANESE,aForbidden);
1599 : }
1600 :
1601 74 : rDoc.set(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION, rTypo.fKerningPunct);
1602 74 : rDoc.setCharacterCompressionType(static_cast<SwCharCompressType>(rTypo.iJustification));
1603 : }
1604 :
1605 : //-----------------------------------------
1606 : // Fuss- und Endnoten
1607 :
1608 : //-----------------------------------------
1609 :
1610 194 : WW8ReaderSave::WW8ReaderSave(SwWW8ImplReader* pRdr ,WW8_CP nStartCp) :
1611 194 : 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 194 : mbFirstPara(pRdr->bFirstPara)
1634 : {
1635 194 : pRdr->bSymbol = false;
1636 194 : pRdr->bHdFtFtnEdn = true;
1637 : pRdr->bTxbxFlySection = pRdr->bAnl = pRdr->bPgSecBreak = pRdr->bWasParaEnd
1638 194 : = pRdr->bHasBorder = false;
1639 194 : pRdr->bFirstPara = true;
1640 194 : pRdr->nInTable = 0;
1641 194 : pRdr->pWFlyPara = 0;
1642 194 : pRdr->pSFlyPara = 0;
1643 194 : pRdr->pPreviousNumPaM = 0;
1644 194 : pRdr->pPrevNumRule = 0;
1645 194 : pRdr->pTableDesc = 0;
1646 194 : pRdr->nAktColl = 0;
1647 :
1648 :
1649 : pRdr->pCtrlStck = new SwWW8FltControlStack(&pRdr->rDoc, pRdr->nFieldFlags,
1650 194 : *pRdr);
1651 :
1652 194 : pRdr->mpRedlineStack = new sw::util::RedlineStack(pRdr->rDoc);
1653 :
1654 194 : 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 194 : if (pRdr->pPlcxMan)
1660 118 : pRdr->pPlcxMan->SaveAllPLCFx(maPLCFxSave);
1661 :
1662 194 : if (nStartCp != -1)
1663 : {
1664 : pRdr->pPlcxMan = new WW8PLCFMan(pRdr->pSBase,
1665 0 : mpOldPlcxMan->GetManType(), nStartCp);
1666 : }
1667 :
1668 194 : maOldApos.push_back(false);
1669 194 : maOldApos.swap(pRdr->maApos);
1670 194 : maOldFieldStack.swap(pRdr->maFieldStack);
1671 194 : }
1672 :
1673 194 : void WW8ReaderSave::Restore( SwWW8ImplReader* pRdr )
1674 : {
1675 194 : pRdr->pWFlyPara = mpWFlyPara;
1676 194 : pRdr->pSFlyPara = mpSFlyPara;
1677 194 : pRdr->pPreviousNumPaM = mpPreviousNumPaM;
1678 194 : pRdr->pPrevNumRule = mpPrevNumRule;
1679 194 : pRdr->pTableDesc = mpTableDesc;
1680 194 : pRdr->cSymbol = mcSymbol;
1681 194 : pRdr->bSymbol = mbSymbol;
1682 194 : pRdr->bIgnoreText = mbIgnoreText;
1683 194 : pRdr->bHdFtFtnEdn = mbHdFtFtnEdn;
1684 194 : pRdr->bTxbxFlySection = mbTxbxFlySection;
1685 194 : pRdr->nInTable = mnInTable;
1686 194 : pRdr->bAnl = mbAnl;
1687 194 : pRdr->bInHyperlink = mbInHyperlink;
1688 194 : pRdr->bWasParaEnd = mbWasParaEnd;
1689 194 : pRdr->bPgSecBreak = mbPgSecBreak;
1690 194 : pRdr->nAktColl = mnAktColl;
1691 194 : pRdr->bHasBorder = mbHasBorder;
1692 194 : pRdr->bFirstPara = mbFirstPara;
1693 :
1694 : // schliesse alle Attribute, da sonst Attribute
1695 : // entstehen koennen, die aus dem Fly rausragen
1696 194 : pRdr->DeleteCtrlStk();
1697 194 : pRdr->pCtrlStck = mpOldStck;
1698 :
1699 194 : pRdr->mpRedlineStack->closeall(*pRdr->pPaM->GetPoint());
1700 194 : delete pRdr->mpRedlineStack;
1701 194 : pRdr->mpRedlineStack = mpOldRedlines;
1702 :
1703 194 : pRdr->DeleteAnchorStk();
1704 194 : pRdr->pAnchorStck = mpOldAnchorStck;
1705 :
1706 194 : *pRdr->pPaM->GetPoint() = maTmpPos;
1707 :
1708 194 : if (mpOldPlcxMan != pRdr->pPlcxMan)
1709 : {
1710 118 : delete pRdr->pPlcxMan;
1711 118 : pRdr->pPlcxMan = mpOldPlcxMan;
1712 : }
1713 194 : if (pRdr->pPlcxMan)
1714 118 : pRdr->pPlcxMan->RestoreAllPLCFx(maPLCFxSave);
1715 194 : pRdr->maApos.swap(maOldApos);
1716 194 : pRdr->maFieldStack.swap(maOldFieldStack);
1717 194 : }
1718 :
1719 78 : 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 78 : WW8ReaderSave aSave( this );
1724 :
1725 78 : pPaM->GetPoint()->nNode = pSttIdx->GetIndex() + 1; //
1726 78 : pPaM->GetPoint()->nContent.Assign( pPaM->GetCntntNode(), 0 );
1727 :
1728 : // dann Text fuer Header, Footer o. Footnote einlesen
1729 :
1730 78 : ReadText( nStartCp, nLen, nType ); // Sepx dabei ignorieren
1731 78 : aSave.Restore( this );
1732 78 : }
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 76 : void SwWW8ImplReader::Read_HdFtText(long nStart, long nLen, SwFrmFmt* pHdFtFmt)
1831 : {
1832 76 : const SwNodeIndex* pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
1833 76 : if (!pSttIdx)
1834 76 : return;
1835 :
1836 76 : SwPosition aTmpPos( *pPaM->GetPoint() ); // merke alte Cursorposition
1837 :
1838 76 : Read_HdFtFtnText(pSttIdx, nStart, nLen - 1, MAN_HDFT);
1839 :
1840 76 : *pPaM->GetPoint() = aTmpPos;
1841 : }
1842 :
1843 :
1844 76 : bool SwWW8ImplReader::isValid_HdFt_CP(WW8_CP nHeaderCP) const
1845 : {
1846 : //each CP of Plcfhdd MUST be less than FibRgLw97.ccpHdd
1847 76 : 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 44 : void SwWW8ImplReader::Read_HdFt(bool bIsTitle, int nSect,
1881 : const SwPageDesc *pPrev, const wwSection &rSection)
1882 : {
1883 44 : sal_uInt8 nWhichItems = 0;
1884 44 : SwPageDesc *pPD = 0;
1885 44 : if (!bIsTitle)
1886 : {
1887 : nWhichItems =
1888 22 : rSection.maSep.grpfIhdt & ~(WW8_HEADER_FIRST | WW8_FOOTER_FIRST);
1889 22 : pPD = rSection.mpPage;
1890 : }
1891 : else
1892 : {
1893 : // Always read title page header/footer data - it could be used by following sections
1894 22 : nWhichItems = ( WW8_HEADER_FIRST | WW8_FOOTER_FIRST );
1895 :
1896 22 : pPD = rSection.mpTitlePage;
1897 : }
1898 :
1899 44 : sal_uInt8 grpfIhdt = rSection.maSep.grpfIhdt;
1900 :
1901 :
1902 44 : if( pHdFt )
1903 : {
1904 : WW8_CP start;
1905 : long nLen;
1906 44 : sal_uInt8 nNumber = 5;
1907 :
1908 308 : for( sal_uInt8 nI = 0x20; nI; nI >>= 1, nNumber-- )
1909 : {
1910 264 : if (nI & nWhichItems)
1911 : {
1912 96 : bool bOk = true;
1913 96 : if( bVer67 )
1914 0 : bOk = ( pHdFt->GetTextPos(grpfIhdt, nI, start, nLen ) && nLen >= 2 );
1915 : else
1916 : {
1917 96 : pHdFt->GetTextPosExact( static_cast< short >(nNumber + (nSect+1)*6), start, nLen);
1918 96 : bOk = ( 2 <= nLen ) && isValid_HdFt_CP(start);
1919 : }
1920 :
1921 : bool bUseLeft
1922 96 : = (nI & ( WW8_HEADER_EVEN | WW8_FOOTER_EVEN )) ? true: false;
1923 : bool bFooter
1924 96 : = (nI & ( WW8_FOOTER_EVEN | WW8_FOOTER_ODD | WW8_FOOTER_FIRST )) ? true: false;
1925 :
1926 96 : SwFrmFmt& rFmt = bUseLeft ? pPD->GetLeft() : pPD->GetMaster();
1927 :
1928 : SwFrmFmt* pHdFtFmt;
1929 96 : if (bFooter)
1930 : {
1931 52 : bIsFooter = true;
1932 : //#i17196# Cannot have left without right
1933 52 : if (!pPD->GetMaster().GetFooter().GetFooterFmt())
1934 44 : pPD->GetMaster().SetFmtAttr(SwFmtFooter(true));
1935 52 : if (bUseLeft)
1936 8 : pPD->GetLeft().SetFmtAttr(SwFmtFooter(true));
1937 52 : pHdFtFmt = const_cast<SwFrmFmt*>(rFmt.GetFooter().GetFooterFmt());
1938 : }
1939 : else
1940 : {
1941 44 : bIsHeader = true;
1942 : //#i17196# Cannot have left without right
1943 44 : if (!pPD->GetMaster().GetHeader().GetHeaderFmt())
1944 36 : pPD->GetMaster().SetFmtAttr(SwFmtHeader(true));
1945 44 : if (bUseLeft)
1946 8 : pPD->GetLeft().SetFmtAttr(SwFmtHeader(true));
1947 44 : pHdFtFmt = const_cast<SwFrmFmt*>(rFmt.GetHeader().GetHeaderFmt());
1948 : }
1949 :
1950 96 : if (bOk)
1951 : {
1952 76 : bool bHackRequired = false;
1953 76 : if (bIsHeader && rSection.IsFixedHeightHeader())
1954 0 : bHackRequired = true;
1955 76 : else if (bIsFooter && rSection.IsFixedHeightFooter())
1956 0 : bHackRequired = true;
1957 :
1958 76 : if (bHackRequired)
1959 : {
1960 : Read_HdFtTextAsHackedFrame(start, nLen, *pHdFtFmt,
1961 0 : static_cast< sal_uInt16 >(rSection.GetTextAreaWidth()) );
1962 : }
1963 : else
1964 76 : Read_HdFtText(start, nLen, pHdFtFmt);
1965 : }
1966 20 : else if (!bOk && pPrev)
1967 0 : CopyPageDescHdFt(pPrev, pPD, nI);
1968 :
1969 96 : bIsHeader = bIsFooter = false;
1970 : }
1971 : }
1972 : }
1973 44 : }
1974 :
1975 82 : bool wwSectionManager::SectionIsProtected(const wwSection &rSection) const
1976 : {
1977 82 : return (mrReader.pWwFib->fReadOnlyRecommended && !rSection.IsNotProtected());
1978 : }
1979 :
1980 82 : void wwSectionManager::SetHdFt(wwSection &rSection, int nSect,
1981 : const wwSection *pPrevious)
1982 : {
1983 : // Header / Footer nicht da
1984 82 : if (!rSection.maSep.grpfIhdt)
1985 142 : return;
1986 :
1987 : OSL_ENSURE(rSection.mpPage, "makes no sense to call with a main page");
1988 22 : if (rSection.mpPage)
1989 : {
1990 : mrReader.Read_HdFt(false, nSect, pPrevious ? pPrevious->mpPage : 0,
1991 22 : rSection);
1992 : }
1993 :
1994 22 : 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 22 : rSection);
2000 : }
2001 :
2002 : // Kopf / Fuss - Index Updaten
2003 : // Damit der Index auch spaeter noch stimmt
2004 22 : if (mrReader.pHdFt)
2005 22 : 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 3934 : void SwWW8ImplReader::AppendTxtNode(SwPosition& rPos)
2022 : {
2023 3934 : SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode();
2024 :
2025 3934 : const SwNumRule* pRule = NULL;
2026 :
2027 3934 : if (pTxt != NULL)
2028 3934 : pRule = sw::util::GetNumRuleFromTxtNode(*pTxt);
2029 :
2030 4500 : if (
2031 566 : 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 3934 : 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 3934 : if(pPreviousNumPaM)
2068 0 : delete pPreviousNumPaM, pPreviousNumPaM = 0;
2069 3934 : 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 3934 : if(bParaAutoBefore && bFirstPara && !pWDop->fDontUseHTMLAutoSpacing)
2076 0 : SetUpperSpacing(*pPaM, 0);
2077 :
2078 3934 : bFirstPara = false;
2079 :
2080 3934 : rDoc.AppendTxtNode(rPos);
2081 :
2082 : //We can flush all anchored graphics at the end of a paragraph.
2083 3934 : pAnchorStck->Flush();
2084 3934 : }
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 8444 : sal_uInt16 SwWW8ImplReader::TabRowSprm(int nLevel) const
2123 : {
2124 8444 : if (bVer67)
2125 0 : return 25;
2126 8444 : return nLevel ? 0x244C : 0x2417;
2127 : }
2128 :
2129 156 : void SwWW8ImplReader::EndSpecial()
2130 : {
2131 : // Frame / Table / Anl
2132 156 : if (bAnl)
2133 0 : StopAllAnl(); // -> bAnl = false
2134 :
2135 312 : 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 156 : if (maApos[0] == true)
2145 0 : StopApo();
2146 :
2147 : OSL_ENSURE(!nInTable, "unclosed table!");
2148 156 : }
2149 :
2150 5256 : bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
2151 : {
2152 : // Frame / Table / Anl
2153 5256 : if (bInHyperlink)
2154 0 : return false;
2155 :
2156 5256 : rbReSync = false;
2157 :
2158 : OSL_ENSURE(nInTable >= 0,"nInTable < 0!");
2159 :
2160 : // TabRowEnd
2161 5256 : 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 5256 : sal_uInt8 nCellLevel = 0;
2190 :
2191 5256 : if (bVer67)
2192 0 : nCellLevel = 0 != pPlcxMan->HasParaSprm(24);
2193 : else
2194 : {
2195 5256 : nCellLevel = 0 != pPlcxMan->HasParaSprm(0x2416);
2196 5256 : if (!nCellLevel)
2197 3942 : nCellLevel = 0 != pPlcxMan->HasParaSprm(0x244B);
2198 : }
2199 :
2200 5256 : WW8_TablePos *pTabPos=0;
2201 : WW8_TablePos aTabPos;
2202 5256 : if (nCellLevel && !bVer67)
2203 : {
2204 : WW8PLCFxSave1 aSave;
2205 1314 : pPlcxMan->GetPap()->Save( aSave );
2206 1314 : rbReSync = true;
2207 1314 : WW8PLCFx_Cp_FKP* pPap = pPlcxMan->GetPapPLCF();
2208 1314 : WW8_CP nMyStartCp=nStartCp;
2209 :
2210 1314 : if (const sal_uInt8 *pLevel = pPlcxMan->HasParaSprm(0x6649))
2211 1314 : nCellLevel = *pLevel;
2212 :
2213 1314 : bool bHasRowEnd = SearchRowEnd(pPap, nMyStartCp, nCellLevel-1);
2214 :
2215 : //Bad Table, remain unchanged in level, e.g. #i19667#
2216 1314 : if (!bHasRowEnd)
2217 2 : nCellLevel = static_cast< sal_uInt8 >(nInTable);
2218 :
2219 1314 : if (bHasRowEnd && ParseTabPos(&aTabPos,pPap))
2220 42 : pTabPos = &aTabPos;
2221 :
2222 1314 : pPlcxMan->GetPap()->Restore( aSave );
2223 : }
2224 :
2225 : // then look if we are in an Apo
2226 :
2227 5256 : 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 5256 : bool bStartTab = (nInTable < nCellLevel) && !bFtnEdn;
2231 :
2232 5256 : bool bStopTab = bWasTabRowEnd && (nInTable > nCellLevel) && !bFtnEdn;
2233 :
2234 5256 : bWasTabRowEnd = false; // must be deactivated right here to prevent next
2235 : // WW8TabDesc::TableCellEnd() from making nonsense
2236 :
2237 5256 : 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 5256 : 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 5256 : if (bStopTab)
2266 : {
2267 80 : StopTable();
2268 80 : maApos.pop_back();
2269 80 : --nInTable;
2270 : }
2271 5256 : if (aApo.mbStopApo)
2272 : {
2273 10 : StopApo();
2274 10 : maApos[nInTable] = false;
2275 : }
2276 :
2277 5256 : if (aApo.mbStartApo)
2278 : {
2279 10 : maApos[nInTable] = StartApo(aApo, pTabPos);
2280 : // nach StartApo ist ein ReSync noetig ( eigentlich nur, falls die Apo
2281 : // ueber eine FKP-Grenze geht
2282 10 : rbReSync = true;
2283 : }
2284 5256 : if (bStartTab)
2285 : {
2286 : WW8PLCFxSave1 aSave;
2287 74 : pPlcxMan->GetPap()->Save( aSave );
2288 :
2289 74 : if (bAnl) // Nummerierung ueber Zellengrenzen
2290 0 : StopAllAnl(); // fuehrt zu Absturz -> keine Anls
2291 : // in Tabellen
2292 228 : while (nInTable < nCellLevel)
2293 : {
2294 80 : if (StartTable(nStartCp))
2295 80 : ++nInTable;
2296 : else
2297 0 : break;
2298 :
2299 160 : maApos.push_back(false);
2300 : }
2301 : // nach StartTable ist ein ReSync noetig ( eigentlich nur, falls die
2302 : // Tabelle ueber eine FKP-Grenze geht
2303 74 : rbReSync = true;
2304 74 : pPlcxMan->GetPap()->Restore( aSave );
2305 : }
2306 5256 : return bTableRowEnd;
2307 : }
2308 :
2309 116 : 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 116 : CharSet eSrcCharSet = eHardCharSet;
2318 116 : if (eSrcCharSet == RTL_TEXTENCODING_DONTKNOW)
2319 : {
2320 116 : if (!maFontSrcCharSets.empty())
2321 112 : eSrcCharSet = maFontSrcCharSets.top();
2322 116 : if ((eSrcCharSet == RTL_TEXTENCODING_DONTKNOW) && nCharFmt >= 0 && (size_t)nCharFmt < vColl.size() )
2323 0 : eSrcCharSet = vColl[nCharFmt].GetCharSet();
2324 116 : if ((eSrcCharSet == RTL_TEXTENCODING_DONTKNOW) && StyleExists(nAktColl) && nAktColl < vColl.size())
2325 4 : eSrcCharSet = vColl[nAktColl].GetCharSet();
2326 116 : 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 116 : 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 2920 : 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 2920 : 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 2920 : RTL_TEXTTOUNICODE_FLAGS_FLUSH;
2448 :
2449 2920 : sal_Size nDestChars=0;
2450 2920 : sal_Size nConverted=0;
2451 :
2452 2920 : do
2453 : {
2454 2920 : sal_uInt32 nInfo = 0;
2455 2920 : sal_Size nThisConverted=0;
2456 :
2457 : nDestChars += rtl_convertTextToUnicode(hConverter, 0,
2458 : pIn+nConverted, nInLen-nConverted,
2459 : pOut+nDestChars, nOutLen-nDestChars,
2460 2920 : nFlags, &nInfo, &nThisConverted);
2461 :
2462 : OSL_ENSURE(nInfo == 0, "A character conversion failed!");
2463 :
2464 2920 : nConverted += nThisConverted;
2465 :
2466 2920 : 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 2920 : 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 11642 : bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, long nEnd, long nCpOfs)
2527 : {
2528 11642 : sal_Size nRequestedStrLen = nEnd - rPos;
2529 :
2530 : OSL_ENSURE(nRequestedStrLen, "String is 0");
2531 11642 : if (!nRequestedStrLen)
2532 0 : return true;
2533 :
2534 11642 : sal_Size nRequestedPos = pSBase->WW8Cp2Fc(nCpOfs+rPos, &bIsUnicode);
2535 11642 : bool bValidPos = checkSeek(*pStrm, nRequestedPos);
2536 : OSL_ENSURE(bValidPos, "Document claimed to have more text than available");
2537 11642 : if (!bValidPos)
2538 : {
2539 : //Swallow missing range, e.g. #i95550#
2540 0 : rPos+=nRequestedStrLen;
2541 0 : return true;
2542 : }
2543 :
2544 11642 : sal_Size nAvailableStrLen = pStrm->remainingSize() / (bIsUnicode ? 2 : 1);
2545 : OSL_ENSURE(nAvailableStrLen, "Document claimed to have more text than available");
2546 11642 : if (!nAvailableStrLen)
2547 : {
2548 : //Swallow missing range, e.g. #i95550#
2549 0 : rPos+=nRequestedStrLen;
2550 0 : return true;
2551 : }
2552 :
2553 11642 : 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 11642 : if (nValidStrLen <= (STRING_MAXLEN-1))
2560 11642 : nStrLen = writer_cast<xub_StrLen>(nValidStrLen);
2561 : else
2562 0 : nStrLen = STRING_MAXLEN-1;
2563 :
2564 : const CharSet eSrcCharSet = bVer67 ? GetCurrentCharSet() :
2565 11642 : RTL_TEXTENCODING_MS_1252;
2566 : const CharSet eSrcCJKCharSet = bVer67 ? GetCurrentCJKCharSet() :
2567 11642 : RTL_TEXTENCODING_MS_1252;
2568 :
2569 : // allocate unicode string data
2570 11642 : rtl_uString *pStr = rtl_uString_alloc(nStrLen);
2571 11642 : sal_Unicode* pBuffer = pStr->buffer;
2572 11642 : sal_Unicode* pWork = pBuffer;
2573 :
2574 11642 : sal_Char* p8Bits = NULL;
2575 :
2576 11642 : rtl_TextToUnicodeConverter hConverter = 0;
2577 11642 : if (!bIsUnicode || bVer67)
2578 8342 : hConverter = rtl_createTextToUnicodeConverter(eSrcCharSet);
2579 :
2580 11642 : if (!bIsUnicode)
2581 8342 : p8Bits = new sal_Char[nStrLen];
2582 :
2583 : // read the stream data
2584 11642 : sal_uInt8 nBCode = 0;
2585 : sal_uInt16 nUCode;
2586 : xub_StrLen nL2;
2587 :
2588 11642 : sal_uInt16 nCTLLang = 0;
2589 11642 : const SfxPoolItem * pItem = GetFmtAttr(RES_CHRATR_CTL_LANGUAGE);
2590 11642 : if (pItem != NULL)
2591 11642 : nCTLLang = dynamic_cast<const SvxLanguageItem *>(pItem)->GetLanguage();
2592 :
2593 289896 : for( nL2 = 0; nL2 < nStrLen; ++nL2, ++pWork )
2594 : {
2595 285316 : if (bIsUnicode)
2596 17540 : *pStrm >> nUCode; // unicode --> read 2 bytes
2597 : else
2598 : {
2599 267776 : *pStrm >> nBCode; // old code --> read 1 byte
2600 267776 : nUCode = nBCode;
2601 : }
2602 :
2603 285316 : 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 285316 : if ((32 > nUCode) || (0xa0 == nUCode))
2612 : {
2613 7062 : pStrm->SeekRel( bIsUnicode ? -2 : -1 );
2614 7062 : break; // Sonderzeichen < 32, == 0xa0 gefunden
2615 : }
2616 :
2617 278254 : if (bIsUnicode)
2618 : {
2619 16264 : if (!bVer67)
2620 16264 : *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 261990 : p8Bits[nL2] = nBCode;
2641 : }
2642 :
2643 11642 : if (nL2)
2644 : {
2645 4946 : xub_StrLen nEndUsed = nL2;
2646 :
2647 4946 : if (!bIsUnicode)
2648 2920 : nEndUsed = Custom8BitToUnicode(hConverter, p8Bits, nL2, pBuffer, nStrLen);
2649 :
2650 331914 : for( xub_StrLen nI = 0; nI < nStrLen; ++nI, ++pBuffer )
2651 326968 : if (m_bRegardHindiDigits && bBidi && LangUsesHindiNumbers(nCTLLang))
2652 0 : *pBuffer = TranslateToHindiNumbers(*pBuffer);
2653 :
2654 4946 : pStr->buffer[nEndUsed] = 0;
2655 4946 : pStr->length = nEndUsed;
2656 :
2657 4946 : emulateMSWordAddTextToParagraph(rtl::OUString(pStr, SAL_NO_ACQUIRE));
2658 4946 : pStr = NULL;
2659 4946 : rPos += nL2;
2660 4946 : if (!maApos.back()) //a para end in apo doesn't count
2661 4946 : bWasParaEnd = false; //kein CR
2662 : }
2663 :
2664 11642 : if (hConverter)
2665 8342 : rtl_destroyTextToUnicodeConverter(hConverter);
2666 11642 : if (pStr)
2667 6696 : rtl_uString_release(pStr);
2668 11642 : delete [] p8Bits;
2669 11642 : 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 439360 : sal_Int16 lcl_getScriptType(
2678 : const uno::Reference<i18n::XBreakIterator>& rBI,
2679 : const rtl::OUString &rString, sal_Int32 nPos)
2680 : {
2681 439360 : sal_Int16 nScript = rBI->getScriptType(rString, nPos);
2682 439360 : if (nScript == i18n::ScriptType::WEAK && rString[nPos] >= 0x0020 && rString[nPos] <= 0x007F)
2683 117690 : nScript = MSASCII;
2684 439360 : return nScript;
2685 : }
2686 :
2687 : //We want to know about WEAK segments, so endOfScript isn't
2688 : //useful, and see lcl_getScriptType anyway
2689 83026 : sal_Int32 lcl_endOfScript(
2690 : const uno::Reference<i18n::XBreakIterator>& rBI,
2691 : const rtl::OUString &rString, sal_Int32 nPos, sal_Int16 nScript)
2692 : {
2693 444948 : while (nPos < rString.getLength())
2694 : {
2695 356334 : sal_Int16 nNewScript = lcl_getScriptType(rBI, rString, nPos);
2696 356334 : if (nScript != nNewScript)
2697 77438 : break;
2698 278896 : ++nPos;
2699 : }
2700 83026 : return nPos;
2701 : }
2702 :
2703 39504 : sal_Int32 lcl_getWriterScriptType(
2704 : const uno::Reference<i18n::XBreakIterator>& rBI,
2705 : const rtl::OUString &rString, sal_Int32 nPos)
2706 : {
2707 39504 : sal_Int16 nScript = i18n::ScriptType::WEAK;
2708 :
2709 39504 : if (rString.isEmpty())
2710 0 : return nScript;
2711 :
2712 118756 : while (nPos >= 0)
2713 : {
2714 79206 : nScript = rBI->getScriptType(rString, nPos);
2715 79206 : if (nScript != i18n::ScriptType::WEAK)
2716 39458 : break;
2717 39748 : --nPos;
2718 : }
2719 :
2720 39504 : return nScript;
2721 : }
2722 :
2723 2 : bool samePitchIgnoreUnknown(FontPitch eA, FontPitch eB)
2724 : {
2725 2 : return (eA == eB || eA == PITCH_DONTKNOW || eB == PITCH_DONTKNOW);
2726 : }
2727 :
2728 1442 : bool sameFontIgnoringIrrelevantFields(const SvxFontItem &rA, const SvxFontItem &rB)
2729 : {
2730 : //Ignoring CharSet, and ignoring unknown pitch
2731 1442 : return rA.GetFamilyName() == rB.GetFamilyName() &&
2732 2 : rA.GetStyleName() == rB.GetStyleName() &&
2733 2 : rA.GetFamily() == rB.GetFamily() &&
2734 1446 : 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 5588 : void SwWW8ImplReader::emulateMSWordAddTextToParagraph(const rtl::OUString& rAddString)
2762 : {
2763 5588 : if (rAddString.isEmpty())
2764 : return;
2765 :
2766 5588 : uno::Reference<i18n::XBreakIterator> xBI(pBreakIt->GetBreakIter());
2767 5588 : if (!xBI.is())
2768 : {
2769 0 : simpleAddTextToParagraph(rAddString);
2770 : return;
2771 : }
2772 :
2773 5588 : sal_Int16 nScript = lcl_getScriptType(xBI, rAddString, 0);
2774 5588 : sal_Int32 nLen = rAddString.getLength();
2775 :
2776 5588 : rtl::OUString sParagraphText;
2777 5588 : const SwCntntNode *pCntNd = pPaM->GetCntntNode();
2778 5588 : const SwTxtNode* pNd = pCntNd ? pCntNd->GetTxtNode() : NULL;
2779 5588 : if (pNd)
2780 5588 : sParagraphText = pNd->GetTxt();
2781 5588 : sal_Int32 nParaOffset = sParagraphText.getLength();
2782 5588 : sParagraphText = sParagraphText + rAddString;
2783 :
2784 5588 : sal_Int32 nPos = 0;
2785 94202 : while (nPos < nLen)
2786 : {
2787 83026 : sal_Int32 nEnd = lcl_endOfScript(xBI, rAddString, nPos, nScript);
2788 83026 : if (nEnd < 0)
2789 : break;
2790 :
2791 83026 : rtl::OUString sChunk(rAddString.copy(nPos, nEnd-nPos));
2792 83026 : const sal_uInt16 aIds[] = {RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT};
2793 83026 : const SvxFontItem *pOverriddenItems[] = {NULL, NULL, NULL};
2794 83026 : bool aForced[] = {false, false, false};
2795 :
2796 83026 : int nLclIdctHint = 0xFF;
2797 83026 : if (nScript == i18n::ScriptType::WEAK)
2798 332 : nLclIdctHint = nIdctHint;
2799 82694 : else if (nScript == MSASCII) //Force weak chars in ascii range to use LATIN font
2800 39172 : nLclIdctHint = 0;
2801 :
2802 83026 : sal_uInt16 nForceFromFontId = 0;
2803 83026 : if (nLclIdctHint != 0xFF)
2804 : {
2805 39504 : switch (nLclIdctHint)
2806 : {
2807 : case 0:
2808 39502 : nForceFromFontId = RES_CHRATR_FONT;
2809 39502 : break;
2810 : case 1:
2811 0 : nForceFromFontId = RES_CHRATR_CJK_FONT;
2812 0 : break;
2813 : case 2:
2814 2 : nForceFromFontId = RES_CHRATR_CTL_FONT;
2815 2 : break;
2816 : default:
2817 0 : break;
2818 : }
2819 : }
2820 :
2821 83026 : 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 39504 : nPos + nParaOffset);
2828 :
2829 39504 : bool bWriterWillUseSameFontAsWordAutomatically = false;
2830 :
2831 39504 : if (nWriterScript != i18n::ScriptType::WEAK)
2832 : {
2833 39458 : 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 38016 : bWriterWillUseSameFontAsWordAutomatically = true;
2840 : }
2841 : else
2842 : {
2843 1442 : const SvxFontItem *pSourceFont = (const SvxFontItem*)GetFmtAttr(nForceFromFontId);
2844 1442 : sal_uInt16 nDestId = aIds[nWriterScript-1];
2845 1442 : const SvxFontItem *pDestFont = (const SvxFontItem*)GetFmtAttr(nDestId);
2846 1442 : bWriterWillUseSameFontAsWordAutomatically = sameFontIgnoringIrrelevantFields(*pSourceFont, *pDestFont);
2847 : }
2848 : }
2849 :
2850 : //Writer won't use the same font as word, so force the issue
2851 39504 : if (!bWriterWillUseSameFontAsWordAutomatically)
2852 : {
2853 1486 : const SvxFontItem *pSourceFont = (const SvxFontItem*)GetFmtAttr(nForceFromFontId);
2854 :
2855 5944 : for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
2856 : {
2857 4458 : const SvxFontItem *pDestFont = (const SvxFontItem*)GetFmtAttr(aIds[i]);
2858 4458 : aForced[i] = aIds[i] != nForceFromFontId && *pSourceFont != *pDestFont;
2859 4458 : if (aForced[i])
2860 : {
2861 : pOverriddenItems[i] =
2862 2914 : (const SvxFontItem*)pCtrlStck->GetStackAttr(*pPaM->GetPoint(), aIds[i]);
2863 :
2864 2914 : SvxFontItem aForceFont(*pSourceFont);
2865 2914 : aForceFont.SetWhich(aIds[i]);
2866 2914 : pCtrlStck->NewAttr(*pPaM->GetPoint(), aForceFont);
2867 : }
2868 : }
2869 : }
2870 : }
2871 :
2872 83026 : simpleAddTextToParagraph(sChunk);
2873 :
2874 332104 : for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
2875 : {
2876 249078 : if (aForced[i])
2877 : {
2878 2914 : pCtrlStck->SetAttr(*pPaM->GetPoint(), aIds[i]);
2879 2914 : if (pOverriddenItems[i])
2880 1446 : pCtrlStck->NewAttr(*pPaM->GetPoint(), *(pOverriddenItems[i]));
2881 : }
2882 : }
2883 :
2884 83026 : nPos = nEnd;
2885 83026 : if (nPos < nLen)
2886 77438 : nScript = lcl_getScriptType(xBI, rAddString, nPos);
2887 88614 : }
2888 : }
2889 :
2890 83026 : void SwWW8ImplReader::simpleAddTextToParagraph(const String& rAddString)
2891 : {
2892 83026 : 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 83026 : const SwCntntNode *pCntNd = pPaM->GetCntntNode();
2903 83026 : const SwTxtNode* pNd = pCntNd ? pCntNd->GetTxtNode() : NULL;
2904 :
2905 : OSL_ENSURE(pNd, "What the hell, where's my text node");
2906 :
2907 83026 : if (!pNd)
2908 0 : return;
2909 :
2910 83026 : if ((pNd->GetTxt().Len() + rAddString.Len()) < STRING_MAXLEN-1)
2911 : {
2912 83026 : 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 83026 : bReadTable = false;
2935 : }
2936 :
2937 : // Returnwert: true for para end
2938 10076 : bool SwWW8ImplReader::ReadChars(WW8_CP& rPos, WW8_CP nNextAttr, long nTextEnd,
2939 : long nCpOfs)
2940 : {
2941 10076 : long nEnd = ( nNextAttr < nTextEnd ) ? nNextAttr : nTextEnd;
2942 :
2943 10076 : if (bSymbol || bIgnoreText)
2944 : {
2945 2 : 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 2 : pStrm->SeekRel( nEnd- rPos );
2954 2 : rPos = nEnd; // ignoriere bis Attributende
2955 2 : return false;
2956 : }
2957 :
2958 1568 : while (true)
2959 : {
2960 11642 : if (ReadPlainChars(rPos, nEnd, nCpOfs))
2961 4580 : return false; // Fertig
2962 :
2963 7062 : bool bStartLine = ReadChar(rPos, nCpOfs);
2964 7062 : rPos++;
2965 7062 : if (bPgSecBreak || bStartLine || rPos == nEnd) // CR oder Fertig
2966 : {
2967 5494 : return bStartLine;
2968 : }
2969 : }
2970 : }
2971 :
2972 78 : bool SwWW8ImplReader::HandlePageBreakChar()
2973 : {
2974 78 : bool bParaEndAdded = false;
2975 : //#i1909# section/page breaks should not occur in tables, word
2976 : //itself ignores them in this case.
2977 78 : if (!nInTable)
2978 : {
2979 : //xushanchuan add for issue106569
2980 78 : sal_Bool IsTemp=sal_True;
2981 78 : SwTxtNode* pTemp = pPaM->GetNode()->GetTxtNode();
2982 78 : if ( pTemp && !( pTemp->GetTxt().Len() ) && ( bFirstPara || bFirstParaOfPage ) )
2983 : {
2984 2 : IsTemp = sal_False;
2985 2 : AppendTxtNode(*pPaM->GetPoint());
2986 2 : pTemp->SetAttr(*GetDfltAttr(RES_PARATR_NUMRULE));
2987 : }
2988 : //xushanchuan end
2989 78 : bPgSecBreak = true;
2990 78 : 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 78 : if (!bWasParaEnd && IsTemp)
2998 : //xushanchuan end
2999 : {
3000 6 : bParaEndAdded = true;
3001 6 : 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 78 : return bParaEndAdded;
3012 : }
3013 :
3014 7062 : bool SwWW8ImplReader::ReadChar(long nPosCp, long nCpOfs)
3015 : {
3016 7062 : 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 7062 : sal_Size nRequestedPos = pSBase->WW8Cp2Fc(nCpOfs+nPosCp, &bIsUnicode);
3021 7062 : if (!checkSeek(*pStrm, nRequestedPos))
3022 0 : return false;
3023 :
3024 7062 : sal_uInt8 nBCode(0);
3025 7062 : sal_uInt16 nWCharVal(0);
3026 7062 : if( bIsUnicode )
3027 1276 : *pStrm >> nWCharVal; // unicode --> read 2 bytes
3028 : else
3029 : {
3030 5786 : *pStrm >> nBCode; // old code --> read 1 byte
3031 5786 : nWCharVal = nBCode;
3032 : }
3033 :
3034 7062 : sal_Unicode cInsert = '\x0';
3035 7062 : bool bRet = false;
3036 : //xushanchuan add for issue106569
3037 7062 : if ( 0xc != nWCharVal )
3038 6984 : bFirstParaOfPage = false;
3039 : //xushanchuan end
3040 7062 : switch (nWCharVal)
3041 : {
3042 : case 0:
3043 : {
3044 : // Seitennummer
3045 : SwPageNumberField aFld(
3046 : (SwPageNumberFieldType*)rDoc.GetSysFldType(
3047 940 : RES_PAGENUMBERFLD ), PG_RANDOM, SVX_NUM_ARABIC);
3048 940 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
3049 : }
3050 940 : 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 1080 : bNewParaEnd = true;
3066 1080 : TabCellEnd(); // table cell end (Flags abfragen!)
3067 1080 : break;
3068 : case 0xf:
3069 0 : if( !bSpec ) // "Satellit"
3070 0 : cInsert = '\xa4';
3071 0 : break;
3072 : case 0x14:
3073 20 : if( !bSpec ) // "Para-Ende"-Zeichen
3074 0 : cInsert = '\xb5';
3075 20 : break;
3076 : case 0x15:
3077 20 : if( !bSpec ) // Juristenparagraph
3078 0 : cInsert = '\xa7';
3079 20 : break;
3080 : case 0x9:
3081 610 : cInsert = '\x9'; // Tab
3082 610 : break;
3083 : case 0xb:
3084 28 : cInsert = '\xa'; // Hard NewLine
3085 28 : break;
3086 : case 0xc:
3087 78 : bRet = HandlePageBreakChar();
3088 78 : 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 30 : if (!IsInlineEscherHack())
3106 : {
3107 24 : SwFrmFmt *pResult = 0;
3108 24 : if (bObj)
3109 0 : pResult = ImportOle();
3110 24 : else if (bSpec)
3111 24 : pResult = ImportGraf();
3112 :
3113 : // If we have a bad 0x1 insert a space instead.
3114 24 : 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 24 : bObj = bEmbeddObj = false;
3125 24 : nObjLocFc = 0;
3126 : }
3127 : }
3128 30 : break;
3129 : case 0x8:
3130 110 : if( !bObj )
3131 110 : Read_GrafLayer( nPosCp );
3132 110 : break;
3133 : case 0xd:
3134 4140 : bNewParaEnd = bRet = true;
3135 4140 : 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 216 : WW8PLCFspecial* pTest = pPlcxMan->GetMagicTables();
3146 432 : if (pTest && pTest->SeekPosExact(nPosCp+1+nCpOfs) &&
3147 216 : pTest->Where() == nPosCp+1+nCpOfs)
3148 : {
3149 : WW8_FC nPos;
3150 : void *pData;
3151 216 : pTest->Get(nPos, pData);
3152 216 : sal_uInt32 nData = SVBT32ToUInt32(*(SVBT32*)pData);
3153 216 : if (nData & 0x2) //Might be how it works
3154 : {
3155 216 : TabCellEnd();
3156 216 : bRet = false;
3157 : }
3158 : }
3159 0 : else if (bWasTabCellEnd)
3160 : {
3161 0 : TabCellEnd();
3162 0 : bRet = false;
3163 : }
3164 : }
3165 :
3166 4140 : bWasTabCellEnd = false;
3167 :
3168 4140 : break; // line end
3169 : case 0x5: // Annotation reference
3170 : case 0x13:
3171 2 : break;
3172 : case 0x2: // Auto-Footnote-Number, should be replaced by SwWW8ImplReader::End_Ftn later
3173 4 : if (!maFtnStack.empty())
3174 4 : cInsert = 0x2;
3175 4 : break;
3176 : default:
3177 : SAL_INFO( "sw.ww8.level2", "<unknownValue val=\"" << nWCharVal << "\">" );
3178 0 : break;
3179 : }
3180 :
3181 7062 : if( '\x0' != cInsert )
3182 : {
3183 642 : rtl::OUString sInsert(cInsert);
3184 642 : emulateMSWordAddTextToParagraph(sInsert);
3185 : }
3186 7062 : if (!maApos.back()) //a para end in apo doesn't count
3187 7056 : bWasParaEnd = bNewParaEnd;
3188 7062 : return bRet;
3189 : }
3190 :
3191 8734 : void SwWW8ImplReader::ProcessAktCollChange(WW8PLCFManResult& rRes,
3192 : bool* pStartAttr, bool bCallProcessSpecial)
3193 : {
3194 8734 : sal_uInt16 nOldColl = nAktColl;
3195 8734 : nAktColl = pPlcxMan->GetColl();
3196 :
3197 : // Invalid Style-Id
3198 8734 : 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 8734 : bParaAutoBefore = vColl[nAktColl].bParaAutoBefore;
3207 8734 : bParaAutoAfter = vColl[nAktColl].bParaAutoAfter;
3208 : }
3209 :
3210 8734 : if (nOldColl >= vColl.size())
3211 0 : nOldColl = 0; //guess! TODO make sure this is what we want
3212 :
3213 8734 : bool bTabRowEnd = false;
3214 8734 : if( pStartAttr && bCallProcessSpecial && !bInHyperlink )
3215 : {
3216 : bool bReSync;
3217 : // Frame / Table / Autonumbering List Level
3218 5256 : bTabRowEnd = ProcessSpecial(bReSync, rRes.nAktCp+pPlcxMan->GetCpOfs());
3219 5256 : if( bReSync )
3220 1320 : *pStartAttr = pPlcxMan->Get( &rRes ); // hole Attribut-Pos neu
3221 : }
3222 :
3223 8734 : if (!bTabRowEnd && StyleExists(nAktColl))
3224 : {
3225 8430 : SetTxtFmtCollAndListLevel( *pPaM, vColl[ nAktColl ]);
3226 8430 : ChkToggleAttr(vColl[ nOldColl ].n81Flags, vColl[ nAktColl ].n81Flags);
3227 8430 : ChkToggleBiDiAttr(vColl[nOldColl].n81BiDiFlags,
3228 16860 : vColl[nAktColl].n81BiDiFlags);
3229 : }
3230 8734 : }
3231 :
3232 120110 : long SwWW8ImplReader::ReadTextAttr(WW8_CP& rTxtPos, bool& rbStartLine)
3233 : {
3234 120110 : long nSkipChars = 0;
3235 : WW8PLCFManResult aRes;
3236 :
3237 : OSL_ENSURE(pPaM->GetNode()->GetTxtNode(), "Missing txtnode");
3238 120110 : bool bStartAttr = pPlcxMan->Get(&aRes); // hole Attribut-Pos
3239 120110 : aRes.nAktCp = rTxtPos; // Akt. Cp-Pos
3240 :
3241 120110 : bool bNewSection = (aRes.nFlags & MAN_MASK_NEW_SEP) && !bIgnoreText;
3242 120110 : if ( bNewSection ) // neue Section
3243 : {
3244 : OSL_ENSURE(pPaM->GetNode()->GetTxtNode(), "Missing txtnode");
3245 : // PageDesc erzeugen und fuellen
3246 84 : maSectionManager.CreateSep(rTxtPos, bPgSecBreak);
3247 : // -> 0xc war ein Sectionbreak, aber
3248 : // kein Pagebreak;
3249 84 : bPgSecBreak = false; // PageDesc erzeugen und fuellen
3250 : OSL_ENSURE(pPaM->GetNode()->GetTxtNode(), "Missing txtnode");
3251 : }
3252 :
3253 : // neuer Absatz ueber Plcx.Fkp.papx
3254 120110 : 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 8734 : !bIgnoreText );
3259 8734 : rbStartLine = false;
3260 : }
3261 :
3262 : // position of last CP that's to be ignored
3263 120110 : long nSkipPos = -1;
3264 :
3265 120110 : if( 0 < aRes.nSprmId ) // leere Attrs ignorieren
3266 : {
3267 98858 : if( ( eFTN > aRes.nSprmId ) || ( 0x0800 <= aRes.nSprmId ) )
3268 : {
3269 197376 : if( bStartAttr ) // WW-Attribute
3270 : {
3271 49588 : if( aRes.nMemLen >= 0 )
3272 49588 : ImportSprm(aRes.pMemPos, aRes.nSprmId);
3273 : }
3274 : else
3275 49100 : EndSprm( aRes.nSprmId ); // Attr ausschalten
3276 : }
3277 170 : else if( aRes.nSprmId < 0x800 ) // eigene Hilfs-Attribute
3278 : {
3279 170 : if (bStartAttr)
3280 : {
3281 98 : nSkipChars = ImportExtSprm(&aRes);
3282 98 : 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 74 : rTxtPos += nSkipChars;
3289 74 : nSkipPos = rTxtPos-1;
3290 : }
3291 : }
3292 : else
3293 72 : EndExtSprm( aRes.nSprmId );
3294 : }
3295 : }
3296 :
3297 120110 : pStrm->Seek(pSBase->WW8Cp2Fc( pPlcxMan->GetCpOfs() + rTxtPos, &bIsUnicode));
3298 :
3299 : // Find next Attr position (and Skip attributes of field contents if needed)
3300 120110 : if (nSkipChars && !bIgnoreText)
3301 30 : pCtrlStck->MarkAllAttrsOld();
3302 120110 : bool bOldIgnoreText = bIgnoreText;
3303 120110 : bIgnoreText = true;
3304 120110 : sal_uInt16 nOldColl = nAktColl;
3305 120110 : bool bDoPlcxManPlusPLus = true;
3306 : long nNext;
3307 121248 : do
3308 : {
3309 121248 : if( bDoPlcxManPlusPLus )
3310 120110 : pPlcxMan->advance();
3311 121248 : nNext = pPlcxMan->Where();
3312 :
3313 121248 : if (mpPostProcessAttrsInfo &&
3314 : mpPostProcessAttrsInfo->mnCpStart == nNext)
3315 : {
3316 0 : mpPostProcessAttrsInfo->mbCopy = true;
3317 : }
3318 :
3319 121248 : if( (0 <= nNext) && (nSkipPos >= nNext) )
3320 : {
3321 1176 : nNext = ReadTextAttr( rTxtPos, rbStartLine );
3322 1176 : bDoPlcxManPlusPLus = false;
3323 1176 : bIgnoreText = true;
3324 : }
3325 :
3326 121248 : if (mpPostProcessAttrsInfo &&
3327 : nNext > mpPostProcessAttrsInfo->mnCpEnd)
3328 : {
3329 0 : mpPostProcessAttrsInfo->mbCopy = false;
3330 : }
3331 : }
3332 : while( nSkipPos >= nNext );
3333 120110 : bIgnoreText = bOldIgnoreText;
3334 120110 : if( nSkipChars )
3335 : {
3336 30 : pCtrlStck->KillUnlockedAttrs( *pPaM->GetPoint() );
3337 30 : if( nOldColl != pPlcxMan->GetColl() )
3338 0 : ProcessAktCollChange(aRes, 0, false);
3339 : }
3340 :
3341 120110 : return nNext;
3342 : }
3343 :
3344 10076 : void SwWW8ImplReader::ReadAttrs(WW8_CP& rNext, WW8_CP& rTxtPos, bool& rbStartLine)
3345 : {
3346 10076 : if( rTxtPos >= rNext )
3347 : { // Stehen Attribute an ?
3348 :
3349 118934 : do
3350 : {
3351 118934 : rNext = ReadTextAttr( rTxtPos, rbStartLine );
3352 : }
3353 : while( rTxtPos >= rNext );
3354 :
3355 : }
3356 70 : 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 48 : if (!bCpxStyle && nAktColl < vColl.size())
3365 48 : SetTxtFmtCollAndListLevel(*pPaM, vColl[nAktColl]);
3366 48 : rbStartLine = false;
3367 : }
3368 10076 : }
3369 :
3370 : // CloseAttrEnds zum Lesen nur der Attributenden am Ende eines Textes oder
3371 : // Textbereiches ( Kopfzeile, Fussnote, ...). Attributanfaenge, Felder
3372 : // werden ignoriert.
3373 156 : 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 156 : std::stack<sal_uInt16> aStack;
3378 156 : pPlcxMan->TransferOpenSprms(aStack);
3379 :
3380 1002 : while (!aStack.empty())
3381 : {
3382 690 : sal_uInt16 nSprmId = aStack.top();
3383 690 : if ((0 < nSprmId) && (( eFTN > nSprmId) || (0x0800 <= nSprmId)))
3384 488 : EndSprm(nSprmId);
3385 690 : aStack.pop();
3386 : }
3387 :
3388 156 : EndSpecial();
3389 156 : }
3390 :
3391 156 : bool SwWW8ImplReader::ReadText(long nStartCp, long nTextLen, ManTypes nType)
3392 : {
3393 156 : bool bJoined=false;
3394 :
3395 156 : bool bStartLine = true;
3396 156 : short nCrCount = 0;
3397 156 : short nDistance = 0;
3398 :
3399 156 : bWasParaEnd = false;
3400 156 : nAktColl = 0;
3401 156 : pAktItemSet = 0;
3402 156 : nCharFmt = -1;
3403 156 : bSpec = false;
3404 156 : bPgSecBreak = false;
3405 :
3406 156 : pPlcxMan = new WW8PLCFMan( pSBase, nType, nStartCp );
3407 156 : long nCpOfs = pPlcxMan->GetCpOfs(); // Offset fuer Header/Footer, Footnote
3408 :
3409 156 : WW8_CP nNext = pPlcxMan->Where();
3410 156 : SwTxtNode* pPreviousNode = 0;
3411 156 : sal_uInt8 nDropLines = 0;
3412 156 : SwCharFmt* pNewSwCharFmt = 0;
3413 156 : const SwCharFmt* pFmt = 0;
3414 156 : pStrm->Seek( pSBase->WW8Cp2Fc( nStartCp + nCpOfs, &bIsUnicode ) );
3415 :
3416 156 : WW8_CP l = nStartCp;
3417 10388 : while ( l<nStartCp+nTextLen )
3418 : {
3419 10076 : ReadAttrs( nNext, l, bStartLine );// behandelt auch Section-Breaks
3420 : OSL_ENSURE(pPaM->GetNode()->GetTxtNode(), "Missing txtnode");
3421 :
3422 10076 : if (mpPostProcessAttrsInfo != NULL)
3423 0 : PostProcessAttrs();
3424 :
3425 10076 : if( l>= nStartCp + nTextLen )
3426 0 : break;
3427 :
3428 10076 : 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 10076 : if (bStartLine && !pPreviousNode) // Zeilenende
3434 3930 : AppendTxtNode(*pPaM->GetPoint());
3435 :
3436 10076 : 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 10076 : 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 10076 : if (bStartLine || bWasTabRowEnd)
3512 : {
3513 : // alle 64 CRs aufrufen not for Header u. ae.
3514 4270 : if ((nCrCount++ & 0x40) == 0 && nType == MAN_MAINTEXT)
3515 : {
3516 2538 : nProgress = (sal_uInt16)( l * 100 / nTextLen );
3517 2538 : ::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 10076 : 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 78 : WW8PLCFxDesc aTemp;
3531 78 : aTemp.nStartPos = aTemp.nEndPos = WW8_CP_MAX;
3532 78 : if (pPlcxMan->GetSepPLCF())
3533 78 : pPlcxMan->GetSepPLCF()->GetSprms(&aTemp);
3534 78 : 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 68 : if (!bStartLine && !pAnchorStck->empty())
3541 : {
3542 0 : AppendTxtNode(*pPaM->GetPoint());
3543 : }
3544 : rDoc.InsertPoolItem(*pPaM,
3545 68 : SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
3546 68 : bFirstParaOfPage = true;//xushanchuan add for issue106569
3547 68 : bPgSecBreak = false;
3548 : }
3549 : }
3550 : }
3551 :
3552 156 : if (pPaM->GetPoint()->nContent.GetIndex())
3553 2 : AppendTxtNode(*pPaM->GetPoint());
3554 :
3555 156 : if (!bInHyperlink)
3556 156 : bJoined = JoinNode(*pPaM);
3557 :
3558 156 : CloseAttrEnds();
3559 :
3560 156 : delete pPlcxMan, pPlcxMan = 0;
3561 156 : return bJoined;
3562 : }
3563 :
3564 : /***************************************************************************
3565 : # class SwWW8ImplReader
3566 : #**************************************************************************/
3567 :
3568 78 : SwWW8ImplReader::SwWW8ImplReader(sal_uInt8 nVersionPara, SvStorage* pStorage,
3569 : SvStream* pSt, SwDoc& rD, const String& rBaseURL, bool bNewDoc) :
3570 78 : 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 78 : bReadTable(false)
3594 : {
3595 78 : pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3596 78 : nWantedVersion = nVersionPara;
3597 78 : pCtrlStck = 0;
3598 78 : mpRedlineStack = 0;
3599 78 : pReffedStck = 0;
3600 78 : pReffingStck = 0;
3601 78 : pAnchorStck = 0;
3602 78 : pFonts = 0;
3603 78 : pSBase = 0;
3604 78 : pPlcxMan = 0;
3605 78 : pStyles = 0;
3606 78 : pAktColl = 0;
3607 78 : pLstManager = 0;
3608 78 : pAktItemSet = 0;
3609 78 : pDfltTxtFmtColl = 0;
3610 78 : pStandardFmtColl = 0;
3611 78 : pHdFt = 0;
3612 78 : pWFlyPara = 0;
3613 78 : pSFlyPara = 0;
3614 78 : pFlyFmtOfJustInsertedGraphic = 0;
3615 78 : pFmtOfJustInsertedApo = 0;
3616 78 : pPreviousNumPaM = 0;
3617 78 : pPrevNumRule = 0;
3618 78 : nAktColl = 0;
3619 78 : nObjLocFc = nPicLocFc = 0;
3620 78 : nInTable=0;
3621 : bReadNoTbl = bPgSecBreak = bSpec = bObj = bTxbxFlySection
3622 : = bHasBorder = bSymbol = bIgnoreText
3623 78 : = bWasTabRowEnd = bWasTabCellEnd = false;
3624 : bShdTxtCol = bCharShdTxtCol = bAnl = bHdFtFtnEdn = bFtnEdn
3625 : = bIsHeader = bIsFooter = bIsUnicode = bCpxStyle = bStyNormal =
3626 78 : bWWBugNormal = false;
3627 :
3628 78 : mpPostProcessAttrsInfo = 0;
3629 :
3630 78 : bNoAttrImport = bEmbeddObj = false;
3631 78 : bAktAND_fNumberAcross = false;
3632 78 : bNoLnNumYet = true;
3633 78 : bInHyperlink = false;
3634 78 : bWasParaEnd = false;
3635 78 : bDropCap = false;
3636 78 : bFirstPara = true;
3637 78 : bFirstParaOfPage = false;//xushanchuan add for issue106569
3638 78 : bParaAutoBefore = false;
3639 78 : bParaAutoAfter = false;
3640 78 : nProgress = 0;
3641 78 : nSwNumLevel = nWwNumType = 0xff;
3642 78 : pTableDesc = 0;
3643 78 : pNumOlst = 0;
3644 78 : pNode_FLY_AT_PARA = 0;
3645 78 : pDrawModel = 0;
3646 78 : pDrawPg = 0;
3647 78 : mpDrawEditEngine = 0;
3648 78 : pWWZOrder = 0;
3649 78 : pFormImpl = 0;
3650 78 : mpChosenOutlineNumRule = 0;
3651 78 : pNumFldType = 0;
3652 78 : nFldNum = 0;
3653 :
3654 78 : nLFOPosition = USHRT_MAX;
3655 78 : nListLevel = WW8ListManager::nMaxLevel;
3656 78 : eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
3657 :
3658 78 : nPgChpDelim = nPgChpLevel = 0;
3659 :
3660 78 : maApos.push_back(false);
3661 78 : }
3662 :
3663 694 : void SwWW8ImplReader::DeleteStk(SwFltControlStack* pStck)
3664 : {
3665 694 : if( pStck )
3666 : {
3667 694 : pStck->SetAttr( *pPaM->GetPoint(), 0, false);
3668 694 : pStck->SetAttr( *pPaM->GetPoint(), 0, false);
3669 694 : delete pStck;
3670 : }
3671 : else
3672 : {
3673 : OSL_ENSURE( !this, "WW-Stack bereits geloescht" );
3674 : }
3675 694 : }
3676 :
3677 246 : void wwSectionManager::SetSegmentToPageDesc(const wwSection &rSection,
3678 : bool bTitlePage, bool bIgnoreCols)
3679 : {
3680 246 : SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage;
3681 :
3682 246 : SetNumberingType(rSection, rPage);
3683 :
3684 246 : SwFrmFmt &rFmt = rPage.GetMaster();
3685 :
3686 246 : if (mrReader.pWDop->fUseBackGroundInAllmodes && mrReader.pMSDffManager)
3687 : {
3688 10 : Rectangle aRect(0, 0, 100, 100); //A dummy, we don't care about the size
3689 10 : SvxMSDffImportData aData(aRect);
3690 10 : SdrObject* pObject = 0;
3691 10 : if (mrReader.pMSDffManager->GetShape(0x401, pObject, aData))
3692 : {
3693 : // Only handle shape if it is a background shape
3694 10 : if ((aData.begin()->nFlags & 0x400) != 0)
3695 : {
3696 6 : SfxItemSet aSet(rFmt.GetAttrSet());
3697 : mrReader.MatchSdrItemsIntoFlySet(pObject, aSet, mso_lineSimple,
3698 6 : mso_lineSolid, mso_sptRectangle, aRect);
3699 6 : rFmt.SetFmtAttr(aSet.Get(RES_BACKGROUND));
3700 : }
3701 10 : }
3702 : }
3703 246 : wwULSpaceData aULData;
3704 246 : GetPageULData(rSection, bTitlePage, aULData);
3705 246 : SetPageULSpaceItems(rFmt, aULData, rSection);
3706 :
3707 246 : SetPage(rPage, rFmt, rSection, bIgnoreCols);
3708 :
3709 246 : bool bSetBorder = false;
3710 246 : switch (rSection.maSep.pgbApplyTo)
3711 : {
3712 : case 0:
3713 : case 3:
3714 246 : bSetBorder = true;
3715 246 : break;
3716 : case 1:
3717 0 : bSetBorder = bTitlePage;
3718 0 : break;
3719 : case 2:
3720 0 : bSetBorder = !bTitlePage;
3721 0 : break;
3722 : }
3723 246 : if (bSetBorder)
3724 246 : mrReader.SetPageBorder(rFmt, rSection);
3725 :
3726 246 : mrReader.SetDocumentGrid(rFmt, rSection);
3727 246 : }
3728 :
3729 82 : void wwSectionManager::SetUseOn(wwSection &rSection)
3730 : {
3731 : bool bEven = (rSection.maSep.grpfIhdt & (WW8_HEADER_EVEN|WW8_FOOTER_EVEN)) ?
3732 82 : true : false;
3733 :
3734 : bool bMirror = mrReader.pWDop->fMirrorMargins ||
3735 82 : mrReader.pWDop->doptypography.f2on1;
3736 :
3737 82 : UseOnPage eUseBase = bMirror ? nsUseOnPage::PD_MIRROR : nsUseOnPage::PD_ALL;
3738 82 : UseOnPage eUse = eUseBase;
3739 82 : if (!bEven)
3740 74 : eUse = (UseOnPage)(eUse | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
3741 82 : eUse = (UseOnPage)(eUse | nsUseOnPage::PD_FIRSTSHARE);
3742 :
3743 : OSL_ENSURE(rSection.mpPage, "Makes no sense to call me with no pages to set");
3744 82 : if (rSection.mpPage)
3745 82 : rSection.mpPage->WriteUseOn(eUse);
3746 82 : if (rSection.mpTitlePage)
3747 : {
3748 : rSection.mpTitlePage->WriteUseOn(
3749 82 : (UseOnPage) (eUseBase | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE | nsUseOnPage::PD_FIRSTSHARE));
3750 : }
3751 82 : }
3752 :
3753 : //Set the page descriptor on this node, handle the different cases for a text
3754 : //node or a table
3755 82 : 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 82 : if (rIdx.GetNode().IsTableNode())
3764 : {
3765 : SwTable& rTable =
3766 12 : rIdx.GetNode().GetTableNode()->GetTable();
3767 12 : SwFrmFmt* pApply = rTable.GetFrmFmt();
3768 : OSL_ENSURE(pApply, "impossible");
3769 12 : if (pApply)
3770 12 : pApply->SetFmtAttr(rPgDesc);
3771 : }
3772 : else
3773 : {
3774 70 : SwPosition aPamStart(rIdx);
3775 : aPamStart.nContent.Assign(
3776 70 : rIdx.GetNode().GetCntntNode(), 0);
3777 70 : SwPaM aPage(aPamStart);
3778 :
3779 70 : rDoc.InsertPoolItem(aPage, rPgDesc, 0);
3780 : }
3781 82 : }
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 82 : SwFmtPageDesc wwSectionManager::SetSwFmtPageDesc(mySegIter &rIter,
3786 : mySegIter &rStart, bool bIgnoreCols)
3787 : {
3788 82 : SwFmtPageDesc aEmpty;
3789 : // Always read title page header/footer data - it could be used by following sections
3790 : {
3791 82 : if (IsNewDoc() && rIter == rStart)
3792 : {
3793 74 : rIter->mpTitlePage =
3794 74 : 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 8 : , 0, false);
3801 8 : rIter->mpTitlePage = &mrReader.rDoc.GetPageDesc(nPos);
3802 : }
3803 : OSL_ENSURE(rIter->mpTitlePage, "no page!");
3804 82 : if (!rIter->mpTitlePage)
3805 0 : return aEmpty;
3806 :
3807 82 : SetSegmentToPageDesc(*rIter, true, bIgnoreCols);
3808 : }
3809 :
3810 82 : if (IsNewDoc() && rIter == rStart)
3811 : {
3812 74 : rIter->mpPage =
3813 74 : 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 8 : rIter->mpTitlePage, false);
3820 8 : rIter->mpPage = &mrReader.rDoc.GetPageDesc(nPos);
3821 : }
3822 : OSL_ENSURE(rIter->mpPage, "no page!");
3823 82 : if (!rIter->mpPage)
3824 0 : return aEmpty;
3825 :
3826 : //Set page before hd/ft
3827 82 : const wwSection *pPrevious = 0;
3828 82 : if (rIter != rStart)
3829 8 : pPrevious = &(*(rIter-1));
3830 82 : SetHdFt(*rIter, std::distance(rStart, rIter), pPrevious);
3831 82 : SetUseOn(*rIter);
3832 :
3833 : //Set hd/ft after set page
3834 82 : if (rIter->mpTitlePage)
3835 82 : SetSegmentToPageDesc(*rIter, true, bIgnoreCols);
3836 82 : SetSegmentToPageDesc(*rIter, false, bIgnoreCols);
3837 :
3838 82 : SwFmtPageDesc aRet(rIter->HasTitlePage() ?
3839 82 : rIter->mpTitlePage : rIter->mpPage);
3840 :
3841 82 : rIter->mpPage->SetFollow(rIter->mpPage);
3842 :
3843 82 : if (rIter->mpTitlePage)
3844 82 : rIter->mpTitlePage->SetFollow(rIter->mpPage);
3845 :
3846 82 : if (rIter->PageRestartNo())
3847 2 : aRet.SetNumOffset(rIter->PageStartAt());
3848 :
3849 82 : ++mnDesc;
3850 82 : return aRet;
3851 : }
3852 :
3853 164 : bool wwSectionManager::IsNewDoc() const
3854 : {
3855 164 : return mrReader.mbNewDoc;
3856 : }
3857 :
3858 74 : void wwSectionManager::InsertSegments()
3859 : {
3860 74 : const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
3861 74 : sal_Bool bUseEnhFields = rOpt.IsUseEnhancedFields();
3862 74 : mySegIter aEnd = maSegments.end();
3863 74 : mySegIter aStart = maSegments.begin();
3864 158 : 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 84 : if ( aIter->maSep.bkc == 1 && aIter->maSep.ccolM1 > 0 )
3870 : {
3871 2 : SwPaM start( aIter->maStart );
3872 2 : mrReader.rDoc.InsertPoolItem( start, SvxFmtBreakItem(SVX_BREAK_COLUMN_BEFORE, RES_BREAK), 0);
3873 2 : continue;
3874 : }
3875 :
3876 82 : mySegIter aNext = aIter+1;
3877 82 : 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 82 : bool bThisAndPreviousAreCompatible = ((aIter->GetPageWidth() == aPrev->GetPageWidth()) &&
3882 82 : (aIter->GetPageHeight() == aPrev->GetPageHeight()) && (aIter->IsLandScape() == aPrev->IsLandScape()));
3883 :
3884 82 : bool bInsertSection = (aIter != aStart) ? (aIter->IsContinous() && bThisAndPreviousAreCompatible): false;
3885 82 : bool bInsertPageDesc = !bInsertSection;
3886 82 : bool bProtected = SectionIsProtected(*aIter); // do we really need this ?? I guess I have a different logic in editshell which disables this...
3887 82 : 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 82 : 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 82 : bool bIgnoreCols = false;
3907 92 : bool bThisAndNextAreCompatible = (aNext != aEnd) ? ((aIter->GetPageWidth() == aNext->GetPageWidth()) &&
3908 92 : (aIter->GetPageHeight() == aNext->GetPageHeight()) && (aIter->IsLandScape() == aNext->IsLandScape())) : true;
3909 :
3910 82 : 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 82 : SwFmtPageDesc aDesc(SetSwFmtPageDesc(aIter, aStart, bIgnoreCols));
3918 82 : 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 82 : 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 82 : GiveNodePageDesc(aIter->maStart, aDesc, mrReader.rDoc);
3949 : }
3950 :
3951 82 : SwTxtNode* pTxtNd = 0;
3952 82 : 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 82 : 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 74 : }
4063 :
4064 152 : void wwExtraneousParas::delete_all_from_doc()
4065 : {
4066 : typedef std::vector<SwTxtNode*>::iterator myParaIter;
4067 152 : myParaIter aEnd = m_aTxtNodes.end();
4068 154 : for (myParaIter aI = m_aTxtNodes.begin(); aI != aEnd; ++aI)
4069 : {
4070 2 : SwTxtNode *pTxtNode = *aI;
4071 2 : SwNodeIndex aIdx(*pTxtNode);
4072 2 : SwPaM aTest(aIdx);
4073 2 : m_rDoc.DelFullPara(aTest);
4074 2 : }
4075 152 : m_aTxtNodes.clear();
4076 152 : }
4077 :
4078 74 : void SwWW8ImplReader::StoreMacroCmds()
4079 : {
4080 74 : if (pWwFib->lcbCmds)
4081 : {
4082 64 : pTableStream->Seek(pWwFib->fcCmds);
4083 :
4084 64 : uno::Reference < embed::XStorage > xRoot(mpDocShell->GetStorage());
4085 :
4086 64 : if (!xRoot.is())
4087 74 : return;
4088 :
4089 : try
4090 : {
4091 : uno::Reference < io::XStream > xStream =
4092 10 : xRoot->openStreamElement( rtl::OUString(SL::aMSMacroCmds), embed::ElementModes::READWRITE );
4093 10 : SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
4094 :
4095 10 : sal_uInt8 *pBuffer = new sal_uInt8[pWwFib->lcbCmds];
4096 10 : pWwFib->lcbCmds = pTableStream->Read(pBuffer, pWwFib->lcbCmds);
4097 10 : pStream->Write(pBuffer, pWwFib->lcbCmds);
4098 10 : delete[] pBuffer;
4099 10 : delete pStream;
4100 : }
4101 0 : catch ( const uno::Exception& )
4102 : {
4103 64 : }
4104 : }
4105 : }
4106 :
4107 74 : void SwWW8ImplReader::ReadDocVars()
4108 : {
4109 74 : std::vector<String> aDocVarStrings;
4110 74 : std::vector<ww::bytes> aDocVarStringIds;
4111 74 : std::vector<String> aDocValueStrings;
4112 74 : WW8ReadSTTBF(!bVer67, *pTableStream, pWwFib->fcStwUser,
4113 : pWwFib->lcbStwUser, bVer67 ? 2 : 0, eStructCharSet,
4114 148 : aDocVarStrings, &aDocVarStringIds, &aDocValueStrings);
4115 74 : if (!bVer67) {
4116 : using namespace ::com::sun::star;
4117 :
4118 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
4119 74 : mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
4120 : uno::Reference<document::XDocumentProperties> xDocProps(
4121 74 : xDPS->getDocumentProperties());
4122 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
4123 : uno::Reference<beans::XPropertyContainer> xUserDefinedProps =
4124 74 : xDocProps->getUserDefinedProperties();
4125 : OSL_ENSURE(xUserDefinedProps.is(), "UserDefinedProperties is null");
4126 :
4127 74 : 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 74 : }
4141 74 : }
4142 74 : }
4143 :
4144 : //-----------------------------------------
4145 : // Document Info
4146 : //-----------------------------------------
4147 :
4148 74 : void SwWW8ImplReader::ReadDocInfo()
4149 : {
4150 74 : if( pStg )
4151 : {
4152 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
4153 74 : mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
4154 : uno::Reference<document::XDocumentProperties> xDocProps(
4155 74 : xDPS->getDocumentProperties());
4156 : OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
4157 :
4158 74 : if (xDocProps.is()) {
4159 74 : 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 74 : else if (pWwFib->lcbSttbfAssoc) // not a template, and has a SttbfAssoc
4173 : {
4174 64 : long nCur = pTableStream->Tell();
4175 64 : Sttb aSttb;
4176 64 : pTableStream->Seek( pWwFib->fcSttbfAssoc ); // point at tgc record
4177 64 : if (!aSttb.Read( *pTableStream ) )
4178 : OSL_TRACE("** Read of SttbAssoc data failed!!!! ");
4179 64 : pTableStream->Seek( nCur ); // return to previous position, is that necessary?
4180 : #if DEBUG
4181 : aSttb.Print( stderr );
4182 : #endif
4183 64 : String sPath = aSttb.getStringAtIndex( 0x1 );
4184 64 : rtl::OUString aURL;
4185 : // attempt to convert to url ( won't work for obvious reasons on linux
4186 64 : if ( sPath.Len() )
4187 0 : ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPath, aURL );
4188 64 : if (aURL.isEmpty())
4189 64 : xDocProps->setTemplateURL( aURL );
4190 : else
4191 0 : xDocProps->setTemplateURL( sPath );
4192 :
4193 : }
4194 74 : sfx2::LoadOlePropertySet(xDocProps, pStg);
4195 74 : }
4196 : }
4197 74 : }
4198 :
4199 74 : static void lcl_createTemplateToProjectEntry( const uno::Reference< container::XNameContainer >& xPrjNameCache, const rtl::OUString& sTemplatePathOrURL, const rtl::OUString& sVBAProjName )
4200 : {
4201 74 : if ( xPrjNameCache.is() )
4202 : {
4203 28 : INetURLObject aObj;
4204 28 : aObj.SetURL( sTemplatePathOrURL );
4205 28 : bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
4206 28 : rtl::OUString aURL;
4207 28 : if ( bIsURL )
4208 0 : aURL = sTemplatePathOrURL;
4209 : else
4210 : {
4211 28 : osl::FileBase::getFileURLFromSystemPath( sTemplatePathOrURL, aURL );
4212 28 : aObj.SetURL( aURL );
4213 : }
4214 : try
4215 : {
4216 28 : rtl::OUString templateNameWithExt = aObj.GetLastName();
4217 28 : rtl::OUString templateName;
4218 28 : sal_Int32 nIndex = templateNameWithExt.lastIndexOf( '.' );
4219 28 : if ( nIndex != -1 )
4220 : {
4221 0 : templateName = templateNameWithExt.copy( 0, nIndex );
4222 0 : xPrjNameCache->insertByName( templateName, uno::makeAny( sVBAProjName ) );
4223 28 : }
4224 : }
4225 0 : catch( const uno::Exception& )
4226 : {
4227 28 : }
4228 : }
4229 74 : }
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 74 : WW8Customizations::WW8Customizations( SvStream* pTableStream, WW8Fib& rFib ) : mpTableStream(pTableStream), mWw8Fib( rFib )
4241 : {
4242 74 : }
4243 :
4244 74 : bool WW8Customizations::Import( SwDocShell* pShell )
4245 : {
4246 74 : if ( mWw8Fib.lcbCmds == 0 || !IsEightPlus(mWw8Fib.GetFIBVersion()) )
4247 10 : return false;
4248 : try
4249 : {
4250 64 : Tcg aTCG;
4251 64 : long nCur = mpTableStream->Tell();
4252 64 : mpTableStream->Seek( mWw8Fib.fcCmds ); // point at tgc record
4253 64 : bool bReadResult = aTCG.Read( *mpTableStream );
4254 64 : mpTableStream->Seek( nCur ); // return to previous position, is that necessary?
4255 64 : if ( !bReadResult )
4256 : {
4257 : SAL_WARN("sw.ww8", "** Read of Customization data failed!!!! ");
4258 6 : return false;
4259 : }
4260 : #if DEBUG
4261 : aTCG.Print( stderr );
4262 : #endif
4263 58 : 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 74 : bool SwWW8ImplReader::ReadGlobalTemplateSettings( const rtl::OUString& sCreatedFrom, const uno::Reference< container::XNameContainer >& xPrjNameCache )
4273 : {
4274 74 : SvtPathOptions aPathOpt;
4275 74 : String aAddinPath = aPathOpt.GetAddinPath();
4276 74 : uno::Sequence< rtl::OUString > sGlobalTemplates;
4277 :
4278 : // first get the autoload addins in the directory STARTUP
4279 74 : uno::Reference<ucb::XSimpleFileAccess3> xSFA(ucb::SimpleFileAccess::create(::comphelper::getProcessComponentContext()));
4280 :
4281 74 : if( xSFA->isFolder( aAddinPath ) )
4282 0 : sGlobalTemplates = xSFA->getFolderContents( aAddinPath, sal_False );
4283 :
4284 74 : sal_Int32 nEntries = sGlobalTemplates.getLength();
4285 74 : bool bRes = true;
4286 74 : 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 74 : return bRes;
4319 : }
4320 :
4321 74 : sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos)
4322 : {
4323 74 : sal_uLong nErrRet = 0;
4324 :
4325 74 : if (mbNewDoc && pStg && !pGloss)
4326 74 : ReadDocInfo();
4327 :
4328 74 : ::ww8::WW8FibData * pFibData = new ::ww8::WW8FibData();
4329 :
4330 74 : if (pWwFib->fReadOnlyRecommended)
4331 0 : pFibData->setReadOnlyRecommended(true);
4332 : else
4333 74 : pFibData->setReadOnlyRecommended(false);
4334 :
4335 74 : if (pWwFib->fWriteReservation)
4336 0 : pFibData->setWriteReservation(true);
4337 : else
4338 74 : pFibData->setWriteReservation(false);
4339 :
4340 74 : ::sw::tExternalDataPointer pExternalFibData(pFibData);
4341 :
4342 74 : rDoc.setExternalData(::sw::FIB, pExternalFibData);
4343 :
4344 : ::sw::tExternalDataPointer pSttbfAsoc
4345 74 : (new ::ww8::WW8Sttb<ww8::WW8Struct>(*pTableStream, pWwFib->fcSttbfAssoc, pWwFib->lcbSttbfAssoc));
4346 :
4347 74 : rDoc.setExternalData(::sw::STTBF_ASSOC, pSttbfAsoc);
4348 :
4349 74 : 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 74 : pPaM = new SwPaM(rPos);
4357 :
4358 74 : pCtrlStck = new SwWW8FltControlStack( &rDoc, nFieldFlags, *this );
4359 :
4360 74 : mpRedlineStack = new sw::util::RedlineStack(rDoc);
4361 :
4362 : /*
4363 : RefFldStck: Keeps track of bookmarks which may be inserted as
4364 : variables intstead.
4365 : */
4366 74 : pReffedStck = new SwFltEndStack(&rDoc, nFieldFlags);
4367 74 : pReffingStck = new SwWW8FltRefStack(&rDoc, nFieldFlags);
4368 :
4369 74 : pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags);
4370 :
4371 74 : sal_uInt16 nPageDescOffset = rDoc.GetPageDescCnt();
4372 :
4373 74 : SwNodeIndex aSttNdIdx( rDoc.GetNodes() );
4374 74 : SwRelNumRuleSpaces aRelNumRule(rDoc, mbNewDoc);
4375 :
4376 74 : sal_uInt16 eMode = nsRedlineMode_t::REDLINE_SHOW_INSERT;
4377 :
4378 74 : mpSprmParser = new wwSprmParser(pWwFib->GetFIBVersion());
4379 :
4380 : // praktische Hilfsvariablen besetzen:
4381 74 : bVer6 = (6 == pWwFib->nVersion);
4382 74 : bVer7 = (7 == pWwFib->nVersion);
4383 74 : bVer67 = bVer6 || bVer7;
4384 74 : bVer8 = (8 == pWwFib->nVersion);
4385 :
4386 74 : eTextCharSet = WW8Fib::GetFIBCharset(pWwFib->chse);
4387 74 : eStructCharSet = WW8Fib::GetFIBCharset(pWwFib->chseTables);
4388 :
4389 74 : bWWBugNormal = pWwFib->nProduct == 0xc03d;
4390 :
4391 74 : if (!mbNewDoc)
4392 0 : aSttNdIdx = pPaM->GetPoint()->nNode;
4393 :
4394 74 : ::StartProgress(STR_STATSTR_W4WREAD, 0, 100, mpDocShell);
4395 :
4396 : // read Font Table
4397 74 : pFonts = new WW8Fonts( *pTableStream, *pWwFib );
4398 :
4399 : // Document Properties
4400 : pWDop = new WW8Dop( *pTableStream, pWwFib->nFib, pWwFib->fcDop,
4401 74 : pWwFib->lcbDop );
4402 :
4403 74 : if (mbNewDoc)
4404 74 : ImportDop();
4405 :
4406 : /*
4407 : Import revisioning data: author names
4408 : */
4409 74 : if( pWwFib->lcbSttbfRMark )
4410 : {
4411 : ReadRevMarkAuthorStrTabl( *pTableStream,
4412 : pWwFib->fcSttbfRMark,
4413 52 : pWwFib->lcbSttbfRMark, rDoc );
4414 : }
4415 :
4416 : // M.M. Initialize our String/ID map for Linked Sections
4417 74 : std::vector<String> aLinkStrings;
4418 74 : std::vector<ww::bytes> aStringIds;
4419 :
4420 74 : WW8ReadSTTBF(!bVer67, *pTableStream, pWwFib->fcSttbFnm,
4421 : pWwFib->lcbSttbFnm, bVer67 ? 2 : 0, eStructCharSet,
4422 148 : aLinkStrings, &aStringIds);
4423 :
4424 74 : 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 74 : ReadDocVars(); // import document variables as meta information.
4433 :
4434 74 : ::SetProgressState(nProgress, mpDocShell); // Update
4435 :
4436 74 : pLstManager = new WW8ListManager( *pTableStream, *this );
4437 :
4438 : /*
4439 : zuerst(!) alle Styles importieren (siehe WW8PAR2.CXX)
4440 : VOR dem Import der Listen !!
4441 : */
4442 74 : ::SetProgressState(nProgress, mpDocShell); // Update
4443 74 : pStyles = new WW8RStyle( *pWwFib, this ); // Styles
4444 74 : 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 74 : ::SetProgressState(nProgress, mpDocShell); // Update
4454 74 : pStyles->PostProcessStyles();
4455 :
4456 74 : if (!vColl.empty())
4457 74 : SetOutLineStyles();
4458 :
4459 74 : 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 74 : if (pSBase->AreThereFootnotes())
4472 : {
4473 : static const SwFtnNum eNumA[4] =
4474 : {
4475 : FTNNUM_DOC, FTNNUM_CHAPTER, FTNNUM_PAGE, FTNNUM_DOC
4476 : };
4477 :
4478 2 : SwFtnInfo aInfo;
4479 2 : aInfo = rDoc.GetFtnInfo(); // Copy-Ctor privat
4480 :
4481 2 : aInfo.ePos = FTNPOS_PAGE;
4482 2 : aInfo.eNum = eNumA[pWDop->rncFtn];
4483 2 : aInfo.aFmt.SetNumberingType( static_cast< sal_uInt16 >(eNumTA[pWDop->nfcFtnRef]) );
4484 2 : if( pWDop->nFtn )
4485 2 : aInfo.nFtnOffset = pWDop->nFtn - 1;
4486 2 : rDoc.SetFtnInfo( aInfo );
4487 : }
4488 74 : 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 74 : if( pWwFib->lcbPlcfhdd )
4500 36 : pHdFt = new WW8PLCF_HdFt( pTableStream, *pWwFib, *pWDop );
4501 :
4502 74 : 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 74 : ::SetProgressState(nProgress, mpDocShell); // Update
4533 :
4534 : // loop for each glossary entry and add dummy section node
4535 74 : 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 74 : if (mbNewDoc && pStg && !pGloss) /*meaningless for a glossary, cmc*/
4560 : {
4561 74 : mpDocShell->SetIsTemplate( pWwFib->fDot ); // point at tgc record
4562 : uno::Reference<document::XDocumentPropertiesSupplier> const
4563 74 : xDocPropSupp(mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
4564 74 : uno::Reference< document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW );
4565 :
4566 74 : rtl::OUString sCreatedFrom = xDocProps->getTemplateURL();
4567 74 : uno::Reference< container::XNameContainer > xPrjNameCache;
4568 74 : uno::Reference< lang::XMultiServiceFactory> xSF(mpDocShell->GetModel(), uno::UNO_QUERY);
4569 74 : if ( xSF.is() )
4570 74 : xPrjNameCache.set( xSF->createInstance( "ooo.vba.VBAProjectNameProvider" ), uno::UNO_QUERY );
4571 :
4572 : // Read Global templates
4573 74 : ReadGlobalTemplateSettings( sCreatedFrom, xPrjNameCache );
4574 :
4575 : // Create and insert Word vba Globals
4576 74 : uno::Any aGlobs;
4577 74 : uno::Sequence< uno::Any > aArgs(1);
4578 74 : aArgs[ 0 ] <<= mpDocShell->GetModel();
4579 74 : aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( "ooo.vba.word.Globals", aArgs );
4580 :
4581 : #ifndef DISABLE_SCRIPTING
4582 74 : BasicManager *pBasicMan = mpDocShell->GetBasicManager();
4583 74 : if (pBasicMan)
4584 74 : pBasicMan->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
4585 : #endif
4586 74 : BasicProjImportHelper aBasicImporter( *mpDocShell );
4587 : // Import vba via oox filter
4588 74 : bool bRet = aBasicImporter.import( mpDocShell->GetMedium()->GetInputStream() );
4589 :
4590 74 : lcl_createTemplateToProjectEntry( xPrjNameCache, sCreatedFrom, aBasicImporter.getProjectName() );
4591 74 : WW8Customizations aCustomisations( pTableStream, *pWwFib );
4592 74 : aCustomisations.Import( mpDocShell );
4593 :
4594 74 : if( bRet )
4595 0 : rDoc.SetContainsMSVBasic(true);
4596 :
4597 74 : StoreMacroCmds();
4598 : }
4599 74 : ReadText(0, pWwFib->ccpText, MAN_MAINTEXT);
4600 :
4601 : }
4602 :
4603 74 : ::SetProgressState(nProgress, mpDocShell); // Update
4604 :
4605 74 : if (pDrawPg && pMSDffManager && pMSDffManager->GetShapeOrders())
4606 : {
4607 : // Hilfsarray zum Verketten der (statt SdrTxtObj) eingefuegten
4608 : // Rahmen
4609 20 : SvxMSDffShapeTxBxSort aTxBxSort;
4610 :
4611 : // korrekte Z-Order der eingelesen Escher-Objekte sicherstellen
4612 20 : sal_uInt16 nShapeCount = pMSDffManager->GetShapeOrders()->size();
4613 :
4614 440 : for (sal_uInt16 nShapeNum=0; nShapeNum < nShapeCount; nShapeNum++)
4615 : {
4616 : SvxMSDffShapeOrder *pOrder =
4617 420 : (*pMSDffManager->GetShapeOrders())[nShapeNum];
4618 : // Pointer in neues Sort-Array einfuegen
4619 420 : if (pOrder->nTxBxComp && pOrder->pFly)
4620 4 : aTxBxSort.insert(pOrder);
4621 : }
4622 : // zu verkettende Rahmen jetzt verketten
4623 20 : if( !aTxBxSort.empty() )
4624 : {
4625 4 : SwFmtChain aChain;
4626 8 : for( SvxMSDffShapeTxBxSort::iterator it = aTxBxSort.begin(); it != aTxBxSort.end(); ++it )
4627 : {
4628 4 : SvxMSDffShapeOrder *pOrder = *it;
4629 :
4630 : // Fly-Frame-Formate initialisieren
4631 4 : SwFlyFrmFmt* pFlyFmt = pOrder->pFly;
4632 4 : SwFlyFrmFmt* pNextFlyFmt = 0;
4633 4 : SwFlyFrmFmt* pPrevFlyFmt = 0;
4634 : // ggfs. Nachfolger ermitteln
4635 4 : SvxMSDffShapeTxBxSort::iterator tmpIter1 = it;
4636 4 : ++tmpIter1;
4637 4 : 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 4 : 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 4 : if (pNextFlyFmt || pPrevFlyFmt)
4657 : {
4658 0 : aChain.SetNext( pNextFlyFmt );
4659 0 : aChain.SetPrev( pPrevFlyFmt );
4660 0 : pFlyFmt->SetFmtAttr( aChain );
4661 : }
4662 4 : }
4663 :
4664 20 : }
4665 :
4666 : }
4667 :
4668 74 : if (mbNewDoc)
4669 : {
4670 74 : if( pWDop->fRevMarking )
4671 0 : eMode |= nsRedlineMode_t::REDLINE_ON;
4672 74 : if( pWDop->fRMView )
4673 72 : eMode |= nsRedlineMode_t::REDLINE_SHOW_DELETE;
4674 : }
4675 :
4676 74 : maInsertedTables.DelAndMakeTblFrms();
4677 74 : maSectionManager.InsertSegments();
4678 :
4679 74 : vColl.clear();
4680 :
4681 74 : DELETEZ( pStyles );
4682 :
4683 74 : if( pFormImpl )
4684 30 : DeleteFormImpl();
4685 74 : GrafikDtor();
4686 74 : DELETEZ( pMSDffManager );
4687 74 : DELETEZ( pHdFt );
4688 74 : DELETEZ( pLstManager );
4689 74 : DELETEZ( pSBase );
4690 74 : delete pWDop;
4691 74 : DELETEZ( pFonts );
4692 74 : delete mpAtnNames;
4693 74 : delete mpSprmParser;
4694 74 : ::EndProgress(mpDocShell);
4695 :
4696 74 : pDataStream = 0;
4697 74 : pTableStream = 0;
4698 :
4699 74 : DeleteCtrlStk();
4700 74 : mpRedlineStack->closeall(*pPaM->GetPoint());
4701 74 : delete mpRedlineStack;
4702 74 : DeleteAnchorStk();
4703 74 : DeleteRefStks();
4704 :
4705 : //remove extra paragraphs after attribute ctrl
4706 : //stacks etc. are destroyed, and before fields
4707 : //are updated
4708 74 : m_aExtraneousParas.delete_all_from_doc();
4709 :
4710 74 : UpdateFields();
4711 :
4712 : // delete the pam before the call for hide all redlines (Bug 73683)
4713 74 : if (mbNewDoc)
4714 74 : rDoc.SetRedlineMode((RedlineMode_t)( eMode ));
4715 :
4716 74 : UpdatePageDescs(rDoc, nPageDescOffset);
4717 :
4718 74 : delete pPaM, pPaM = 0;
4719 74 : return nErrRet;
4720 : }
4721 :
4722 74 : sal_uLong SwWW8ImplReader::SetSubStreams(SvStorageStreamRef &rTableStream,
4723 : SvStorageStreamRef &rDataStream)
4724 : {
4725 74 : sal_uLong nErrRet = 0;
4726 : // 6 stands for "6 OR 7", 7 stand for "ONLY 7"
4727 74 : 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 74 : 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 74 : STREAM_STD_READ);
4745 :
4746 74 : pTableStream = &rTableStream;
4747 74 : pTableStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
4748 :
4749 : rDataStream = pStg->OpenSotStream(rtl::OUString(SL::aData),
4750 74 : STREAM_STD_READ | STREAM_NOCREATE );
4751 :
4752 74 : if (rDataStream.Is() && SVSTREAM_OK == rDataStream->GetError())
4753 : {
4754 30 : pDataStream = &rDataStream;
4755 30 : pDataStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
4756 : }
4757 : else
4758 44 : pDataStream = pStrm;
4759 74 : 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 74 : 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 74 : sal_uLong SwWW8ImplReader::LoadThroughDecryption(SwPaM& rPaM ,WW8Glossary *pGloss)
4944 : {
4945 74 : sal_uLong nErrRet = 0;
4946 74 : if (pGloss)
4947 0 : pWwFib = pGloss->GetFib();
4948 : else
4949 74 : pWwFib = new WW8Fib(*pStrm, nWantedVersion);
4950 :
4951 74 : if (pWwFib->nFibError)
4952 0 : nErrRet = ERR_SWG_READ_ERROR;
4953 :
4954 74 : SvStorageStreamRef xTableStream, xDataStream;
4955 :
4956 74 : if (!nErrRet)
4957 74 : nErrRet = SetSubStreams(xTableStream, xDataStream);
4958 :
4959 74 : utl::TempFile *pTempMain = 0;
4960 74 : utl::TempFile *pTempTable = 0;
4961 74 : utl::TempFile *pTempData = 0;
4962 74 : SvFileStream aDecryptMain;
4963 74 : SvFileStream aDecryptTable;
4964 74 : SvFileStream aDecryptData;
4965 :
4966 74 : bool bDecrypt = false;
4967 74 : enum {RC4, XOR, Other} eAlgo = Other;
4968 74 : 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 74 : 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 74 : if (!nErrRet)
5114 74 : nErrRet = CoreLoad(pGloss, *rPaM.GetPoint());
5115 :
5116 74 : delete pTempMain;
5117 74 : delete pTempTable;
5118 74 : delete pTempData;
5119 :
5120 74 : if (!pGloss)
5121 74 : delete pWwFib;
5122 74 : return nErrRet;
5123 : }
5124 :
5125 : class outlineeq : public std::unary_function<const SwTxtFmtColl*, bool>
5126 : {
5127 : private:
5128 : sal_uInt8 mnNum;
5129 : public:
5130 22 : outlineeq(sal_uInt8 nNum) : mnNum(nNum) {}
5131 388 : bool operator()(const SwTxtFmtColl *pTest) const
5132 : {
5133 388 : return pTest->IsAssignedToListLevelOfOutlineStyle() && pTest->GetAssignedOutlineStyleLevel() == mnNum; //<-end,zhaojianwei
5134 : }
5135 : };
5136 :
5137 74 : void SwWW8ImplReader::SetOutLineStyles()
5138 : {
5139 : /*
5140 : #i3674# & #101291# Load new document and insert document cases.
5141 : */
5142 74 : 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 74 : mpChosenOutlineNumRule = &aOutlineRule;
5149 :
5150 74 : sw::ParaStyles aOutLined(sw::util::GetParaStyles(rDoc));
5151 : // #i98791# - sorting algorithm adjusted
5152 74 : 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 74 : sal_uInt16 nFlagsStyleOutlLevel = 0;
5160 74 : 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 74 : std::map<sal_uInt16, int>aRuleMap;
5185 : typedef std::map<sal_uInt16, int>::iterator myIter;
5186 1626 : for (sal_uInt16 nI = 0; nI < vColl.size(); ++nI)
5187 : {
5188 1552 : SwWW8StyInf& rSI = vColl[ nI ];
5189 1552 : if (
5190 : (MAXLEVEL > rSI.nOutlineLevel) && rSI.pOutlineNumrule &&
5191 : rSI.pFmt
5192 : )
5193 : {
5194 22 : myIter aIter = aRuleMap.find(nI);
5195 22 : if (aIter == aRuleMap.end())
5196 : {
5197 22 : aRuleMap[nI] = 1;
5198 : }
5199 : else
5200 0 : ++(aIter->second);
5201 : }
5202 : }
5203 :
5204 74 : int nMax = 0;
5205 74 : myIter aEnd2 = aRuleMap.end();
5206 96 : for (myIter aIter = aRuleMap.begin(); aIter != aEnd2; ++aIter)
5207 : {
5208 22 : if (aIter->second > nMax)
5209 : {
5210 10 : nMax = aIter->second;
5211 10 : if(aIter->first < vColl.size())
5212 10 : 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 74 : if (mpChosenOutlineNumRule)
5220 74 : aOutlineRule = *mpChosenOutlineNumRule;
5221 :
5222 74 : if (mpChosenOutlineNumRule != &aOutlineRule)
5223 : {
5224 : // #i70748# - backward iteration needed due to the outline level attribute
5225 10 : sw::ParaStyles::reverse_iterator aEnd = aOutLined.rend();
5226 40 : for ( sw::ParaStyles::reverse_iterator aIter = aOutLined.rbegin(); aIter < aEnd; ++aIter)
5227 : {
5228 40 : if((*aIter)->IsAssignedToListLevelOfOutlineStyle())
5229 30 : (*aIter)->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end
5230 :
5231 : else
5232 10 : break;
5233 : }
5234 74 : }
5235 : }
5236 :
5237 74 : sal_uInt16 nOldFlags = nFlagsStyleOutlLevel;
5238 :
5239 1626 : for (sal_uInt16 nI = 0; nI < vColl.size(); ++nI)
5240 : {
5241 1552 : SwWW8StyInf& rSI = vColl[nI];
5242 :
5243 1552 : if (rSI.IsOutlineNumbered())
5244 : {
5245 22 : sal_uInt16 nAktFlags = 1 << rSI.nOutlineLevel;
5246 22 : 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 22 : outlineeq aCmp(rSI.nOutlineLevel);
5272 : myParaStyleIter aResult = std::find_if(aOutLined.begin(),
5273 22 : aOutLined.end(), aCmp);
5274 :
5275 22 : myParaStyleIter aEnd = aOutLined.end();
5276 44 : 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 22 : sal_uInt8 nFromLevel = rSI.nListLevel;
5294 22 : sal_uInt8 nToLevel = rSI.nOutlineLevel;
5295 22 : const SwNumFmt& rRule=rSI.pOutlineNumrule->Get(nFromLevel);
5296 22 : aOutlineRule.Set(nToLevel, rRule);
5297 22 : ((SwTxtFmtColl*)rSI.pFmt)->AssignToListLevelOfOutlineStyle(nToLevel); //<-end,zhaojianwei
5298 : // If there are more styles on this level ignore them
5299 22 : nFlagsStyleOutlLevel |= nAktFlags;
5300 : }
5301 : }
5302 : }
5303 74 : if (nOldFlags != nFlagsStyleOutlLevel)
5304 10 : rDoc.SetOutlineNumRule(aOutlineRule);
5305 : // #i53044,i53213#
5306 74 : if ( mpChosenOutlineNumRule == &aOutlineRule )
5307 : {
5308 64 : mpChosenOutlineNumRule = rDoc.GetOutlineNumRule();
5309 74 : }
5310 74 : }
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 78 : sal_uLong SwWW8ImplReader::LoadDoc( SwPaM& rPaM,WW8Glossary *pGloss)
5349 : {
5350 78 : 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 78 : SwFilterOptions aOpt( 13, aNames, aVal );
5364 :
5365 78 : nIniFlags = aVal[ 0 ];
5366 78 : nIniFlags1= aVal[ 1 ];
5367 : // schiebt Flys um x twips nach rechts o. links
5368 78 : nIniFlyDx = aVal[ 3 ];
5369 78 : nIniFlyDy = aVal[ 4 ];
5370 :
5371 78 : nFieldFlags = aVal[ 5 ];
5372 78 : nFieldTagAlways[0] = aVal[ 6 ];
5373 78 : nFieldTagAlways[1] = aVal[ 7 ];
5374 78 : nFieldTagAlways[2] = aVal[ 8 ];
5375 78 : nFieldTagBad[0] = aVal[ 9 ];
5376 78 : nFieldTagBad[1] = aVal[ 10 ];
5377 78 : nFieldTagBad[2] = aVal[ 11 ];
5378 78 : m_bRegardHindiDigits = aVal[ 12 ] > 0;
5379 : }
5380 :
5381 78 : sal_uInt16 nMagic(0);
5382 78 : *pStrm >> nMagic;
5383 :
5384 : // beachte: 6 steht fuer "6 ODER 7", 7 steht fuer "NUR 7"
5385 78 : 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 78 : if (0xa5ec != nMagic)
5413 4 : nErrRet = ERR_WW8_NO_WW8_FILE_ERR;
5414 78 : 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 78 : if (!nErrRet)
5422 74 : nErrRet = LoadThroughDecryption(rPaM ,pGloss);
5423 :
5424 78 : rDoc.PropagateOutlineRule();
5425 :
5426 78 : return nErrRet;
5427 : }
5428 :
5429 8 : extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportDOC()
5430 : {
5431 8 : return new WW8Reader();
5432 : }
5433 :
5434 78 : sal_uLong WW8Reader::OpenMainStream( SvStorageStreamRef& rRef, sal_uInt16& rBuffSize )
5435 : {
5436 78 : sal_uLong nRet = ERR_SWG_READ_ERROR;
5437 : OSL_ENSURE( pStg, "wo ist mein Storage?" );
5438 78 : rRef = pStg->OpenSotStream( rtl::OUString("WordDocument"), STREAM_READ | STREAM_SHARE_DENYALL);
5439 :
5440 78 : if( rRef.Is() )
5441 : {
5442 78 : if( SVSTREAM_OK == rRef->GetError() )
5443 : {
5444 78 : sal_uInt16 nOld = rRef->GetBufferSize();
5445 78 : rRef->SetBufferSize( rBuffSize );
5446 78 : rBuffSize = nOld;
5447 78 : nRet = 0;
5448 : }
5449 : else
5450 0 : nRet = rRef->GetError();
5451 : }
5452 78 : return nRet;
5453 : }
5454 :
5455 80 : sal_uLong WW8Reader::Read(SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String & /* FileName */)
5456 : {
5457 80 : sal_uInt16 nOldBuffSize = 32768;
5458 80 : bool bNew = !bInsertMode; // Neues Doc ( kein Einfuegen )
5459 :
5460 :
5461 80 : SvStorageStreamRef refStrm; // damit uns keiner den Stream klaut
5462 80 : SvStream* pIn = pStrm;
5463 :
5464 80 : sal_uLong nRet = 0;
5465 80 : sal_uInt8 nVersion = 8;
5466 :
5467 80 : String sFltName = GetFltName();
5468 80 : 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 80 : if( sFltName.EqualsAscii( "CWW6" ) )
5481 0 : nVersion = 6;
5482 80 : else if( sFltName.EqualsAscii( "CWW7" ) )
5483 0 : nVersion = 7;
5484 :
5485 80 : if( pStg )
5486 : {
5487 78 : nRet = OpenMainStream( refStrm, nOldBuffSize );
5488 78 : pIn = &refStrm;
5489 : }
5490 : else
5491 : {
5492 : OSL_ENSURE(!this, "WinWord 95/97 Reader-Read ohne Storage");
5493 2 : nRet = ERR_SWG_READ_ERROR;
5494 : }
5495 : }
5496 :
5497 80 : if( !nRet )
5498 : {
5499 78 : if (bNew)
5500 : {
5501 : // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf.
5502 78 : Reader::ResetFrmFmts( rDoc );
5503 : }
5504 : SwWW8ImplReader* pRdr = new SwWW8ImplReader(nVersion, pStg, pIn, rDoc,
5505 78 : rBaseURL, bNew);
5506 : try
5507 : {
5508 78 : nRet = pRdr->LoadDoc( rPam );
5509 : }
5510 0 : catch( const std::exception& )
5511 : {
5512 0 : nRet = ERR_WW8_NO_WW8_FILE_ERR;
5513 : }
5514 78 : delete pRdr;
5515 :
5516 78 : if( refStrm.Is() )
5517 : {
5518 78 : refStrm->SetBufferSize( nOldBuffSize );
5519 78 : refStrm.Clear();
5520 : }
5521 0 : else if (pIn)
5522 0 : pIn->ResetError();
5523 :
5524 : }
5525 80 : return nRet;
5526 : }
5527 :
5528 240 : int WW8Reader::GetReaderType()
5529 : {
5530 240 : 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 2 : sal_Bool SwMSDffManager::GetOLEStorageName(long nOLEId, String& rStorageName,
5555 : SvStorageRef& rSrcStorage, uno::Reference < embed::XStorage >& rDestStorage) const
5556 : {
5557 2 : bool bRet = false;
5558 :
5559 2 : sal_Int32 nPictureId = 0;
5560 2 : 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 2 : 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 2 : if ( rReader.GetTxbxTextSttEndCp(nStartCp, nEndCp,
5575 : static_cast<sal_uInt16>((nOLEId >> 16) & 0xFFFF),
5576 2 : static_cast<sal_uInt16>(nOLEId & 0xFFFF)) )
5577 : {
5578 : WW8PLCFxSaveAll aSave;
5579 2 : memset( &aSave, 0, sizeof( aSave ) );
5580 2 : rReader.pPlcxMan->SaveAllPLCFx( aSave );
5581 :
5582 2 : nStartCp += rReader.nDrawCpO;
5583 2 : nEndCp += rReader.nDrawCpO;
5584 2 : WW8PLCFx_Cp_FKP* pChp = rReader.pPlcxMan->GetChpPLCF();
5585 2 : wwSprmParser aSprmParser(rReader.pWwFib->GetFIBVersion());
5586 10 : while (nStartCp <= nEndCp && !nPictureId)
5587 : {
5588 6 : WW8PLCFxDesc aDesc;
5589 6 : pChp->SeekPos( nStartCp );
5590 6 : pChp->GetSprms( &aDesc );
5591 :
5592 6 : if (aDesc.nSprmsLen && aDesc.pMemPos) // Attribut(e) vorhanden
5593 : {
5594 4 : long nLen = aDesc.nSprmsLen;
5595 4 : const sal_uInt8* pSprm = aDesc.pMemPos;
5596 :
5597 14 : while (nLen >= 2 && !nPictureId)
5598 : {
5599 6 : sal_uInt16 nId = aSprmParser.GetSprmId(pSprm);
5600 6 : sal_uInt16 nSL = aSprmParser.GetSprmSize(nId, pSprm);
5601 :
5602 6 : if( nLen < nSL )
5603 0 : break; // nicht mehr genug Bytes uebrig
5604 :
5605 6 : if( 0x6A03 == nId && 0 < nLen )
5606 : {
5607 : nPictureId = SVBT32ToUInt32(pSprm +
5608 2 : aSprmParser.DistanceToData(nId));
5609 2 : bRet = true;
5610 : }
5611 6 : pSprm += nSL;
5612 6 : nLen -= nSL;
5613 : }
5614 : }
5615 6 : nStartCp = aDesc.nEndPos;
5616 : }
5617 :
5618 2 : rReader.pPlcxMan->RestoreAllPLCFx( aSave );
5619 : }
5620 : }
5621 2 : rReader.pStrm->Seek( nOldPos );
5622 : }
5623 :
5624 2 : if( bRet )
5625 : {
5626 2 : rStorageName = '_';
5627 2 : rStorageName += rtl::OUString::valueOf(nPictureId);
5628 : rSrcStorage = rReader.pStg->OpenSotStorage(rtl::OUString(
5629 2 : SL::aObjectPool));
5630 2 : if (!rReader.mpDocShell)
5631 0 : bRet=false;
5632 : else
5633 2 : rDestStorage = rReader.mpDocShell->GetStorage();
5634 : }
5635 2 : return bRet;
5636 : }
5637 :
5638 96 : 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 96 : return true;
5645 : }
5646 :
5647 4566 : bool SwWW8ImplReader::InEqualOrHigherApo(int nLvl) const
5648 : {
5649 4566 : if (nLvl)
5650 632 : --nLvl;
5651 : // #i60827#
5652 : // check size of <maApos> to assure that <maApos.begin() + nLvl> can be performed.
5653 4566 : if ( sal::static_int_cast< sal_Int32>(nLvl) >= sal::static_int_cast< sal_Int32>(maApos.size()) )
5654 : {
5655 6 : return false;
5656 : }
5657 4560 : mycApoIter aIter = std::find(maApos.begin() + nLvl, maApos.end(), true);
5658 4560 : if (aIter != maApos.end())
5659 46 : return true;
5660 : else
5661 4514 : return false;
5662 : }
5663 :
5664 394 : 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 394 : if (nLvl)
5669 120 : --nLvl;
5670 394 : if (nLvl < 0 || static_cast<size_t>(nLvl) >= maApos.size())
5671 0 : return false;
5672 394 : return maApos[nLvl];
5673 : }
5674 :
5675 : namespace sw
5676 : {
5677 : namespace hack
5678 : {
5679 30 : Position::Position(const SwPosition &rPos)
5680 30 : : maPtNode(rPos.nNode), mnPtCntnt(rPos.nContent.GetIndex())
5681 : {
5682 30 : }
5683 :
5684 30 : Position::Position(const Position &rPos)
5685 30 : : maPtNode(rPos.maPtNode), mnPtCntnt(rPos.mnPtCntnt)
5686 : {
5687 30 : }
5688 :
5689 6 : Position::operator SwPosition() const
5690 : {
5691 6 : SwPosition aRet(maPtNode);
5692 6 : aRet.nContent.Assign(maPtNode.GetNode().GetCntntNode(), mnPtCntnt);
5693 6 : return aRet;
5694 : }
5695 : }
5696 36 : }
5697 :
5698 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|