1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ww8par.cxx,v $
10 * $Revision: 1.199.12.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
36 #include <com/sun/star/embed/ElementModes.hpp>
37 #include <com/sun/star/embed/XStorage.hpp>
38 #include <unotools/ucbstreamhelper.hxx>
39 #include <tools/solar.h>
40 #include <rtl/tencinfo.h>
42 #include <sot/storage.hxx>
43 #include <sfx2/docinf.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <tools/urlobj.hxx>
46 #include <unotools/tempfile.hxx>
47 #include <svtools/sfxecode.hxx>
49 #include <comphelper/docpasswordrequest.hxx>
50 #include <hintids.hxx>
52 #include <svx/tstpitem.hxx>
53 #include <svx/cscoitem.hxx>
54 #include <svx/svdobj.hxx>
55 #include <svx/svdpage.hxx>
56 #include <svx/paperinf.hxx>
57 #include <svx/lrspitem.hxx> // SvxLRSpaceItem
58 #include <svx/ulspitem.hxx>
59 #include <svx/langitem.hxx>
60 // --> OD 2005-02-28 #i43427#
61 #include <svx/opaqitem.hxx>
63 #include <svx/svxmsbas.hxx>
64 #include <svx/unoapi.hxx>
65 #include <svx/svdoole2.hxx>
66 #include <svx/msdffimp.hxx>
67 #include <svx/svdoashp.hxx>
68 #include <svx/svxerr.hxx>
69 #include <svx/mscodec.hxx>
70 #include <svx/svdmodel.hxx>
71 #include <svx/svdogrp.hxx>
72 #include <svx/xflclit.hxx>
74 #include <svtools/fltrcfg.hxx>
77 #include <fmtinfmt.hxx>
80 #include <fmthdft.hxx>
81 #include <fmtcntnt.hxx>
82 #include <fmtcnct.hxx>
83 #include <fmtpdsc.hxx>
84 #include <fmthbsh.hxx>
85 #include <ftninfo.hxx>
88 #include <pam.hxx> // fuer SwPam
90 #include <ndtxt.hxx> // class SwTxtNode
91 #include <pagedesc.hxx> // class SwPageDesc
93 #include <fmtclds.hxx>
94 #include <fmtclbl.hxx>
95 #include <section.hxx>
97 #include <docufld.hxx>
98 #include <swfltopt.hxx>
100 #include <shellres.hxx>
101 #include <mdiexp.hxx> // Progress
102 #include <statstr.hrc> // ResId fuer Statusleiste
103 #include <swerror.h> // ERR_WW8_...
104 #include <swunodef.hxx>
105 #include <unodraw.hxx>
106 #include <swtable.hxx> // class SwTableLines, ...
108 #include <fmtfollowtextflow.hxx>
109 #include <fchrfmt.hxx>
110 #include <charfmt.hxx>
113 #include <com/sun/star/i18n/ForbiddenCharacters.hpp>
114 #include <comphelper/extract.hxx>
115 #include <fltini.hxx>
118 #include <functional>
119 #include "writerhelper.hxx"
120 #include "writerwordglue.hxx"
123 #include "ww8par2.hxx" // class WW8RStyle, class WW8AnchorPara
125 #include <frmatr.hxx>
128 #include <com/sun/star/beans/XPropertyContainer.hpp>
130 #include <com/sun/star/beans/PropertyAttribute.hpp>
131 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
132 #include <com/sun/star/document/XDocumentProperties.hpp>
133 #include <svtools/itemiter.hxx> //SfxItemIter
136 #include <comphelper/processfactory.hxx>
137 #include <basic/basmgr.hxx>
139 #include "ww8toolbar.hxx"
140 #include <osl/file.hxx>
141 #include <com/sun/star/document/XDocumentInfoSupplier.hpp>
145 #include <dbgoutsw.hxx>
147 #include <unotools/localfilehelper.hxx>
148 #include <comphelper/configurationhelper.hxx>
150 #define MM_250 1417 // WW-Default fuer Hor. Seitenraender: 2.5 cm
151 #define MM_200 1134 // WW-Default fuer u.Seitenrand: 2.0 cm
153 using namespace ::com::sun::star
;
154 using namespace sw::util
;
155 using namespace sw::types
;
156 using namespace nsHdFtFlags
;
158 #include <com/sun/star/document/XEventsSupplier.hpp>
159 #include <com/sun/star/container/XNameReplace.hpp>
160 #include <com/sun/star/frame/XModel.hpp>
161 #include <svx/msvbahelper.hxx>
162 #include <svtools/pathoptions.hxx>
163 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
165 const static String
sThisDocument( RTL_CONSTASCII_USTRINGPARAM("ThisDocument"));
167 struct DocEventNameTable
169 const sal_Char
* sEventName
;
170 const sal_Char
* sMacroName
;
173 const DocEventNameTable aEventNameTable
[] =
175 {"OnNew", "Document_New"},
176 {"OnLoad", "Document_Open"},
177 {"OnPrepareUnload", "Document_Close"},
181 bool registerDocEvent( SfxObjectShell
* pShell
)
184 const static rtl::OUString
sEvtType( RTL_CONSTASCII_USTRINGPARAM("EventType") );
185 const static rtl::OUString
sScript( RTL_CONSTASCII_USTRINGPARAM("Script") );
186 uno::Reference
< document::XEventsSupplier
> xEvtSupplier( pShell
->GetModel(), uno::UNO_QUERY
);
187 if( !xEvtSupplier
.is() )
189 uno::Reference
< container::XNameReplace
> xEvts( xEvtSupplier
->getEvents(), uno::UNO_QUERY
);
192 for( const DocEventNameTable
* pTable
= aEventNameTable
; pTable
->sEventName
!= NULL
; pTable
++ )
194 rtl::OUString sEvt
= rtl::OUString::createFromAscii( pTable
->sEventName
);
195 String sMacroName
= String::CreateFromAscii( pTable
->sMacroName
).Insert( '.', 0 ).Insert( sThisDocument
, 0);
196 // fail to search the macro if the module is not specified.
197 ooo::vba::VBAMacroResolvedInfo aMacroInfo
= ooo::vba::resolveVBAMacro( pShell
, sMacroName
);
198 if( !aMacroInfo
.IsResolved() )
201 uno::Sequence
< beans::PropertyValue
> aEvents
;
202 xEvts
->getByName( sEvt
) >>= aEvents
;
203 uno::Sequence
< beans::PropertyValue
> aOpenEvt( 2 );
204 aOpenEvt
[ 0 ].Name
= sEvtType
;
205 aOpenEvt
[ 0 ].Value
= uno::makeAny(sScript
);
206 aOpenEvt
[ 1 ].Name
= sScript
;
207 rtl::OUString sUrl
= ooo::vba::makeMacroURL( aMacroInfo
.ResolvedMacro() );
208 aOpenEvt
[ 1 ].Value
= uno::makeAny(sUrl
);
209 sal_Int32 nPos
= aEvents
.getLength();
211 sal_Int32 nNewSize
= aEvents
.getLength() + aOpenEvt
.getLength();
212 if ( nNewSize
> aEvents
.getLength() )
213 aEvents
.realloc( nNewSize
);
215 for ( sal_Int32 nIndex
= nPos
, nCpyIndex
= 0; nIndex
<nNewSize
; nIndex
++, nCpyIndex
++ )
216 aEvents
[ nIndex
] = aOpenEvt
[ nCpyIndex
];
218 uno::Any aParam
= uno::makeAny( aEvents
);
220 xEvts
->replaceByName( sEvt
, aParam
);
233 SBBItem() : cchData(0){}
239 std::vector
< SBBItem
> dataItems
;
242 Sttb
& operator = ( const Sttb
&);
246 bool Read(SvStream
*pS
);
247 void Print( FILE* fp
);
248 rtl::OUString
getStringAtIndex( sal_uInt32
);
251 Sttb::Sttb() : fExtend( 0 )
261 bool Sttb::Read( SvStream
* pS
)
263 OSL_TRACE("Sttb::Read() stream pos 0x%x", pS
->Tell() );
264 nOffSet
= pS
->Tell();
265 *pS
>> fExtend
>> cData
>> cbExtra
;
268 for ( sal_Int32 index
= 0; index
< cData
; ++index
)
271 *pS
>> aItem
.cchData
;
272 aItem
.data
= readUnicodeString( pS
, aItem
.cchData
);
273 dataItems
.push_back( aItem
);
279 void Sttb::Print( FILE* fp
)
281 fprintf( fp
, "[ 0x%x ] Sttb - dump\n", nOffSet
);
282 fprintf( fp
, " fExtend 0x%x [expected 0xFFFF ]\n", fExtend
);
283 fprintf( fp
, " cData no. or string data items %d (0x%x)\n", cData
, cData
);
287 for ( sal_Int32 index
= 0; index
< cData
; ++index
)
288 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() );
294 Sttb::getStringAtIndex( sal_uInt32 index
)
297 if ( index
< dataItems
.size() )
298 aRet
= dataItems
[ index
].data
;
302 SwMSDffManager::SwMSDffManager( SwWW8ImplReader
& rRdr
)
303 : SvxMSDffManager(*rRdr
.pTableStream
, rRdr
.GetBaseURL(), rRdr
.pWwFib
->fcDggInfo
,
304 rRdr
.pDataStream
, 0, 0, COL_WHITE
, 12, rRdr
.pStrm
,
305 rRdr
.maTracer
.GetTrace()),
306 rReader(rRdr
), pFallbackStream(0), pOldEscherBlipCache(0)
308 SetSvxMSDffSettings( GetSvxMSDffSettings() );
309 nSvxMSDffOLEConvFlags
= SwMSDffManager::GetFilterFlags();
312 UINT32
SwMSDffManager::GetFilterFlags()
315 if (const SvtFilterOptions
* pOpt
= SvtFilterOptions::Get())
317 if (pOpt
->IsMathType2Math())
318 nFlags
|= OLE_MATHTYPE_2_STARMATH
;
319 if (pOpt
->IsExcel2Calc())
320 nFlags
|= OLE_EXCEL_2_STARCALC
;
321 if (pOpt
->IsPowerPoint2Impress())
322 nFlags
|= OLE_POWERPOINT_2_STARIMPRESS
;
323 if (pOpt
->IsWinWord2Writer())
324 nFlags
|= OLE_WINWORD_2_STARWRITER
;
330 * I would like to override the default OLE importing to add a test
331 * and conversion of OCX controls from their native OLE type into our
332 * native nonOLE Form Control Objects.
336 // --> OD 2004-12-14 #i32596# - consider new parameter <_nCalledByGroup>
337 SdrObject
* SwMSDffManager::ImportOLE( long nOLEId
,
339 const Rectangle
& rBoundRect
,
340 const Rectangle
& rVisArea
,
341 const int _nCalledByGroup
,
342 sal_Int64 nAspect
) const
344 // --> OD 2004-12-14 #i32596# - no import of OLE object, if it's inside a group.
345 // NOTE: This can be undone, if grouping of Writer fly frames is possible or
346 // if drawing OLE objects are allowed in Writer.
347 if ( _nCalledByGroup
> 0 )
355 SotStorageRef xSrcStg
;
356 uno::Reference
< embed::XStorage
> xDstStg
;
357 if( GetOLEStorageName( nOLEId
, sStorageName
, xSrcStg
, xDstStg
))
359 SvStorageRef xSrc
= xSrcStg
->OpenSotStorage( sStorageName
,
360 STREAM_READWRITE
| STREAM_SHARE_DENYALL
);
361 ASSERT(rReader
.pFormImpl
, "No Form Implementation!");
362 STAR_REFERENCE( drawing::XShape
) xShape
;
363 if ( (!(rReader
.bIsHeader
|| rReader
.bIsFooter
)) &&
364 rReader
.pFormImpl
->ReadOCXStream(xSrc
,&xShape
,true))
366 pRet
= GetSdrObjectFromXShape(xShape
);
370 ErrCode nError
= ERRCODE_NONE
;
371 pRet
= CreateSdrOLEFromStorage( sStorageName
, xSrcStg
, xDstStg
,
372 rGrf
, rBoundRect
, rVisArea
, pStData
, nError
, nSvxMSDffOLEConvFlags
, nAspect
);
378 void SwMSDffManager::DisableFallbackStream()
380 ASSERT(!pFallbackStream
|| !pOldEscherBlipCache
,
381 "if you're recursive, you're broken");
382 pFallbackStream
= pStData2
;
383 pOldEscherBlipCache
= pEscherBlipCache
;
384 pEscherBlipCache
= 0;
388 void SwMSDffManager::EnableFallbackStream()
390 pStData2
= pFallbackStream
;
391 pEscherBlipCache
= pOldEscherBlipCache
;
392 pOldEscherBlipCache
= 0;
396 USHORT
SwWW8ImplReader::GetToggleAttrFlags() const
398 return pCtrlStck
? pCtrlStck
->GetToggleAttrFlags() : 0;
401 USHORT
SwWW8ImplReader::GetToggleBiDiAttrFlags() const
403 return pCtrlStck
? pCtrlStck
->GetToggleBiDiAttrFlags() : 0;
406 void SwWW8ImplReader::SetToggleAttrFlags(USHORT nFlags
)
409 pCtrlStck
->SetToggleAttrFlags(nFlags
);
412 void SwWW8ImplReader::SetToggleBiDiAttrFlags(USHORT nFlags
)
415 pCtrlStck
->SetToggleBiDiAttrFlags(nFlags
);
419 SdrObject
* SwMSDffManager::ProcessObj(SvStream
& rSt
,
420 DffObjData
& rObjData
,
422 Rectangle
& rTextRect
,
426 if( !rTextRect
.IsEmpty() )
428 SvxMSDffImportData
& rImportData
= *(SvxMSDffImportData
*)pData
;
429 SvxMSDffImportRec
* pImpRec
= new SvxMSDffImportRec
;
431 // fill Import Record with data
432 pImpRec
->nShapeId
= rObjData
.nShapeId
;
433 pImpRec
->eShapeType
= rObjData
.eShapeType
;
435 rObjData
.bClientAnchor
= maShapeRecords
.SeekToContent( rSt
,
436 DFF_msofbtClientAnchor
,
437 SEEK_FROM_CURRENT_AND_RESTART
);
438 if( rObjData
.bClientAnchor
)
439 ProcessClientAnchor( rSt
,
440 maShapeRecords
.Current()->nRecLen
,
441 pImpRec
->pClientAnchorBuffer
, pImpRec
->nClientAnchorLen
);
443 rObjData
.bClientData
= maShapeRecords
.SeekToContent( rSt
,
444 DFF_msofbtClientData
,
445 SEEK_FROM_CURRENT_AND_RESTART
);
446 if( rObjData
.bClientData
)
447 ProcessClientData( rSt
,
448 maShapeRecords
.Current()->nRecLen
,
449 pImpRec
->pClientDataBuffer
, pImpRec
->nClientDataLen
);
452 // process user (== Winword) defined parameters in 0xF122 record
453 // --> OD 2008-04-10 #i84783#
454 // set special value to determine, if property is provided or not.
455 pImpRec
->nLayoutInTableCell
= 0xFFFFFFFF;
457 if( maShapeRecords
.SeekToContent( rSt
,
459 SEEK_FROM_CURRENT_AND_RESTART
)
460 && maShapeRecords
.Current()->nRecLen
)
462 UINT32 nBytesLeft
= maShapeRecords
.Current()->nRecLen
;
465 while( 5 < nBytesLeft
)
468 if ( rSt
.GetError() != 0 )
473 case 0x038F: pImpRec
->nXAlign
= nUDData
; break;
474 case 0x0390: pImpRec
->nXRelTo
= nUDData
; break;
475 case 0x0391: pImpRec
->nYAlign
= nUDData
; break;
476 case 0x0392: pImpRec
->nYRelTo
= nUDData
; break;
477 case 0x03BF: pImpRec
->nLayoutInTableCell
= nUDData
; break;
479 if ( rSt
.GetError() != 0 )
481 pImpRec
->bHasUDefProp
= TRUE
;
486 // Textrahmen, auch Title oder Outline
487 UINT32 nTextId
= GetPropertyValue( DFF_Prop_lTxid
, 0 );
490 SfxItemSet
aSet( pSdrModel
->GetItemPool() );
492 //Originally anything that as a mso_sptTextBox was created as a
493 //textbox, this was changed for #88277# to be created as a simple
494 //rect to keep impress happy. For the rest of us we'd like to turn
495 //it back into a textbox again.
496 BOOL bIsSimpleDrawingTextBox
= (pImpRec
->eShapeType
== mso_sptTextBox
);
497 if (!bIsSimpleDrawingTextBox
)
500 //a) its a simple text object or
501 //b) its a rectangle with text and square wrapping.
502 bIsSimpleDrawingTextBox
=
504 (pImpRec
->eShapeType
== mso_sptTextSimple
) ||
506 (pImpRec
->eShapeType
== mso_sptRectangle
)
507 // && (eWrapMode == mso_wrapSquare)
508 && ShapeHasText(pImpRec
->nShapeId
, rObjData
.rSpHd
.GetRecBegFilePos() )
513 // Distance of Textbox to it's surrounding Autoshape
514 INT32 nTextLeft
= GetPropertyValue( DFF_Prop_dxTextLeft
, 91440L);
515 INT32 nTextRight
= GetPropertyValue( DFF_Prop_dxTextRight
, 91440L );
516 INT32 nTextTop
= GetPropertyValue( DFF_Prop_dyTextTop
, 45720L );
517 INT32 nTextBottom
= GetPropertyValue( DFF_Prop_dyTextBottom
, 45720L );
519 ScaleEmu( nTextLeft
);
520 ScaleEmu( nTextRight
);
521 ScaleEmu( nTextTop
);
522 ScaleEmu( nTextBottom
);
524 INT32 nTextRotationAngle
=0;
525 bool bVerticalText
= false;
526 if ( IsProperty( DFF_Prop_txflTextFlow
) )
528 MSO_TextFlow eTextFlow
= (MSO_TextFlow
)(GetPropertyValue(
529 DFF_Prop_txflTextFlow
) & 0xFFFF);
533 nTextRotationAngle
= 9000;
537 nTextRotationAngle
= 27000;
540 bVerticalText
= true;
543 bVerticalText
= true;
544 nTextRotationAngle
= 9000;
551 if (nTextRotationAngle
)
553 while (nTextRotationAngle
> 360000)
554 nTextRotationAngle
-=9000;
555 switch (nTextRotationAngle
)
559 long nWidth
= rTextRect
.GetWidth();
560 rTextRect
.Right() = rTextRect
.Left() + rTextRect
.GetHeight();
561 rTextRect
.Bottom() = rTextRect
.Top() + nWidth
;
563 INT32 nOldTextLeft
= nTextLeft
;
564 INT32 nOldTextRight
= nTextRight
;
565 INT32 nOldTextTop
= nTextTop
;
566 INT32 nOldTextBottom
= nTextBottom
;
568 nTextLeft
= nOldTextBottom
;
569 nTextRight
= nOldTextTop
;
570 nTextTop
= nOldTextLeft
;
571 nTextBottom
= nOldTextRight
;
576 long nWidth
= rTextRect
.GetWidth();
577 rTextRect
.Right() = rTextRect
.Left() + rTextRect
.GetHeight();
578 rTextRect
.Bottom() = rTextRect
.Top() + nWidth
;
580 INT32 nOldTextLeft
= nTextLeft
;
581 INT32 nOldTextRight
= nTextRight
;
582 INT32 nOldTextTop
= nTextTop
;
583 INT32 nOldTextBottom
= nTextBottom
;
585 nTextLeft
= nOldTextTop
;
586 nTextRight
= nOldTextBottom
;
587 nTextTop
= nOldTextRight
;
588 nTextBottom
= nOldTextLeft
;
596 if (bIsSimpleDrawingTextBox
)
598 SdrObject::Free( pObj
);
599 pObj
= new SdrRectObj(OBJ_TEXT
, rTextRect
);
602 // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
604 Rectangle
aNewRect(rTextRect
);
605 aNewRect
.Bottom() -= nTextTop
+ nTextBottom
;
606 aNewRect
.Right() -= nTextLeft
+ nTextRight
;
608 // Nur falls es eine einfache Textbox ist, darf der Writer
609 // das Objekt durch einen Rahmen ersetzen, ansonsten
610 if( bIsSimpleDrawingTextBox
)
612 SvxMSDffShapeInfo
aTmpRec( 0, pImpRec
->nShapeId
);
613 aTmpRec
.bSortByShapeId
= TRUE
;
616 if( GetShapeInfos()->Seek_Entry( &aTmpRec
, &nFound
) )
618 SvxMSDffShapeInfo
& rInfo
= *GetShapeInfos()->GetObject(nFound
);
619 pImpRec
->bReplaceByFly
= rInfo
.bReplaceByFly
;
620 pImpRec
->bLastBoxInChain
= rInfo
.bLastBoxInChain
;
624 if( bIsSimpleDrawingTextBox
)
625 ApplyAttributes( rSt
, aSet
, rObjData
);
627 bool bFitText
= false;
628 if (GetPropertyValue(DFF_Prop_FitTextToShape
) & 2)
630 aSet
.Put( SdrTextAutoGrowHeightItem( TRUE
) );
631 aSet
.Put( SdrTextMinFrameHeightItem(
632 aNewRect
.Bottom() - aNewRect
.Top() ) );
633 aSet
.Put( SdrTextMinFrameWidthItem(
634 aNewRect
.Right() - aNewRect
.Left() ) );
639 aSet
.Put( SdrTextAutoGrowHeightItem( FALSE
) );
640 aSet
.Put( SdrTextAutoGrowWidthItem( FALSE
) );
643 switch ( (MSO_WrapMode
)
644 GetPropertyValue( DFF_Prop_WrapText
, mso_wrapSquare
) )
647 aSet
.Put( SdrTextAutoGrowWidthItem( TRUE
) );
648 pImpRec
->bAutoWidth
= true;
650 case mso_wrapByPoints
:
651 aSet
.Put( SdrTextContourFrameItem( TRUE
) );
657 // Abstaende an den Raendern der Textbox setzen
658 aSet
.Put( SdrTextLeftDistItem( nTextLeft
) );
659 aSet
.Put( SdrTextRightDistItem( nTextRight
) );
660 aSet
.Put( SdrTextUpperDistItem( nTextTop
) );
661 aSet
.Put( SdrTextLowerDistItem( nTextBottom
) );
662 pImpRec
->nDxTextLeft
= nTextLeft
;
663 pImpRec
->nDyTextTop
= nTextTop
;
664 pImpRec
->nDxTextRight
= nTextRight
;
665 pImpRec
->nDyTextBottom
= nTextBottom
;
667 // --> SJ 2009-03-06 : taking the correct default (which is mso_anchorTop)
668 MSO_Anchor eTextAnchor
=
669 (MSO_Anchor
)GetPropertyValue( DFF_Prop_anchorText
, mso_anchorTop
);
671 SdrTextVertAdjust eTVA
= bVerticalText
672 ? SDRTEXTVERTADJUST_BLOCK
673 : SDRTEXTVERTADJUST_CENTER
;
674 SdrTextHorzAdjust eTHA
= bVerticalText
675 ? SDRTEXTHORZADJUST_CENTER
676 : SDRTEXTHORZADJUST_BLOCK
;
678 switch( eTextAnchor
)
683 eTHA
= SDRTEXTHORZADJUST_RIGHT
;
685 eTVA
= SDRTEXTVERTADJUST_TOP
;
688 case mso_anchorTopCentered
:
691 eTHA
= SDRTEXTHORZADJUST_RIGHT
;
693 eTVA
= SDRTEXTVERTADJUST_TOP
;
696 case mso_anchorMiddle
:
698 case mso_anchorMiddleCentered
:
700 case mso_anchorBottom
:
703 eTHA
= SDRTEXTHORZADJUST_LEFT
;
705 eTVA
= SDRTEXTVERTADJUST_BOTTOM
;
708 case mso_anchorBottomCentered
:
711 eTHA
= SDRTEXTHORZADJUST_LEFT
;
713 eTVA
= SDRTEXTVERTADJUST_BOTTOM
;
717 case mso_anchorTopBaseline:
718 case mso_anchorBottomBaseline:
719 case mso_anchorTopCenteredBaseline:
720 case mso_anchorBottomCenteredBaseline:
727 aSet
.Put( SdrTextVertAdjustItem( eTVA
) );
728 aSet
.Put( SdrTextHorzAdjustItem( eTHA
) );
730 pObj
->SetMergedItemSet(aSet
);
731 pObj
->SetModel(pSdrModel
);
733 if (bVerticalText
&& dynamic_cast< SdrTextObj
* >( pObj
) )
734 dynamic_cast< SdrTextObj
* >( pObj
)->SetVerticalWriting(sal_True
);
736 if ( bIsSimpleDrawingTextBox
)
738 if ( nTextRotationAngle
)
740 long nMinWH
= rTextRect
.GetWidth() < rTextRect
.GetHeight() ?
741 rTextRect
.GetWidth() : rTextRect
.GetHeight();
743 Point
aPivot(rTextRect
.TopLeft());
744 aPivot
.X() += nMinWH
;
745 aPivot
.Y() += nMinWH
;
746 double a
= nTextRotationAngle
* nPi180
;
747 pObj
->NbcRotate(aPivot
, nTextRotationAngle
, sin(a
), cos(a
));
751 if ( ( ( rObjData
.nSpFlags
& SP_FFLIPV
) || mnFix16Angle
|| nTextRotationAngle
) && dynamic_cast< SdrObjCustomShape
* >( pObj
) )
753 SdrObjCustomShape
* pCustomShape
= dynamic_cast< SdrObjCustomShape
* >( pObj
);
755 double fExtraTextRotation
= 0.0;
756 if ( mnFix16Angle
&& !( GetPropertyValue( DFF_Prop_FitTextToShape
) & 4 ) )
757 { // text is already rotated, we have to take back the object rotation if DFF_Prop_RotateText is false
758 fExtraTextRotation
= -mnFix16Angle
;
760 if ( rObjData
.nSpFlags
& SP_FFLIPV
) // sj: in ppt the text is flipped, whereas in word the text
761 { // remains unchanged, so we have to take back the flipping here
762 fExtraTextRotation
+= 18000.0; // because our core will flip text if the shape is flipped.
764 fExtraTextRotation
+= nTextRotationAngle
;
765 if ( !::basegfx::fTools::equalZero( fExtraTextRotation
) )
767 fExtraTextRotation
/= 100.0;
768 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)pCustomShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
769 const rtl::OUString
sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
770 com::sun::star::beans::PropertyValue aPropVal
;
771 aPropVal
.Name
= sTextRotateAngle
;
772 aPropVal
.Value
<<= fExtraTextRotation
;
773 aGeometryItem
.SetPropertyValue( aPropVal
);
774 pCustomShape
->SetMergedItem( aGeometryItem
);
777 else if ( mnFix16Angle
)
779 // rotate text with shape ?
780 double a
= mnFix16Angle
* nPi180
;
781 pObj
->NbcRotate( rObjData
.aBoundRect
.Center(), mnFix16Angle
,
782 sin( a
), cos( a
) );
787 // simple rectangular objects are ignored by ImportObj() :-(
788 // this is OK for Draw but not for Calc and Writer
789 // cause here these objects have a default border
790 pObj
= new SdrRectObj(rTextRect
);
791 pObj
->SetModel( pSdrModel
);
792 SfxItemSet
aSet( pSdrModel
->GetItemPool() );
793 ApplyAttributes( rSt
, aSet
, rObjData
);
795 const SfxPoolItem
* pPoolItem
=NULL
;
796 SfxItemState eState
= aSet
.GetItemState( XATTR_FILLCOLOR
,
798 if( SFX_ITEM_DEFAULT
== eState
)
799 aSet
.Put( XFillColorItem( String(),
800 Color( mnDefaultColor
) ) );
801 pObj
->SetMergedItemSet(aSet
);
804 //Means that fBehindDocument is set
805 if (GetPropertyValue(DFF_Prop_fPrint
) & 0x20)
806 pImpRec
->bDrawHell
= TRUE
;
808 pImpRec
->bDrawHell
= FALSE
;
809 if (GetPropertyValue(DFF_Prop_fPrint
) & 0x02)
810 pImpRec
->bHidden
= TRUE
;
811 pImpRec
->nNextShapeId
= GetPropertyValue( DFF_Prop_hspNext
, 0 );
815 pImpRec
->aTextId
.nTxBxS
= (UINT16
)( nTextId
>> 16 );
816 pImpRec
->aTextId
.nSequence
= (UINT16
)nTextId
;
819 pImpRec
->nDxWrapDistLeft
= GetPropertyValue(
820 DFF_Prop_dxWrapDistLeft
, 114935L ) / 635L;
821 pImpRec
->nDyWrapDistTop
= GetPropertyValue(
822 DFF_Prop_dyWrapDistTop
, 0 ) / 635L;
823 pImpRec
->nDxWrapDistRight
= GetPropertyValue(
824 DFF_Prop_dxWrapDistRight
, 114935L ) / 635L;
825 pImpRec
->nDyWrapDistBottom
= GetPropertyValue(
826 DFF_Prop_dyWrapDistBottom
, 0 ) / 635L;
827 // 16.16 fraction times total image width or height, as appropriate.
829 if (SeekToContent(DFF_Prop_pWrapPolygonVertices
, rSt
))
831 delete pImpRec
->pWrapPolygon
;
832 sal_uInt16 nNumElemVert
, nNumElemMemVert
, nElemSizeVert
;
833 rSt
>> nNumElemVert
>> nNumElemMemVert
>> nElemSizeVert
;
834 if (nNumElemVert
&& ((nElemSizeVert
== 8) || (nElemSizeVert
== 4)))
836 pImpRec
->pWrapPolygon
= new Polygon(nNumElemVert
);
837 for (sal_uInt16 i
= 0; i
< nNumElemVert
; ++i
)
840 if (nElemSizeVert
== 8)
844 sal_Int16 nSmallX
, nSmallY
;
845 rSt
>> nSmallX
>> nSmallY
;
849 (*(pImpRec
->pWrapPolygon
))[i
].X() = nX
;
850 (*(pImpRec
->pWrapPolygon
))[i
].Y() = nY
;
855 pImpRec
->nCropFromTop
= GetPropertyValue(
856 DFF_Prop_cropFromTop
, 0 );
857 pImpRec
->nCropFromBottom
= GetPropertyValue(
858 DFF_Prop_cropFromBottom
, 0 );
859 pImpRec
->nCropFromLeft
= GetPropertyValue(
860 DFF_Prop_cropFromLeft
, 0 );
861 pImpRec
->nCropFromRight
= GetPropertyValue(
862 DFF_Prop_cropFromRight
, 0 );
864 UINT32 nLineFlags
= GetPropertyValue( DFF_Prop_fNoLineDrawDash
);
865 // --> OD 2008-06-16 #156765#
866 if ( !IsHardAttribute( DFF_Prop_fLine
) &&
867 pImpRec
->eShapeType
== mso_sptPictureFrame
)
872 pImpRec
->eLineStyle
= (nLineFlags
& 8)
873 ? (MSO_LineStyle
)GetPropertyValue(
876 : (MSO_LineStyle
)USHRT_MAX
;
878 pImpRec
->nFlags
= rObjData
.nSpFlags
;
880 if( pImpRec
->nShapeId
)
882 // Import-Record-Liste ergaenzen
883 pImpRec
->pObj
= pObj
;
884 rImportData
.aRecords
.Insert( pImpRec
);
886 // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
887 /*Only store objects which are not deep inside the tree*/
888 if( ( rObjData
.nCalledByGroup
== 0 )
890 ( (rObjData
.nSpFlags
& SP_FGROUP
)
891 && (rObjData
.nCalledByGroup
< 2) )
893 StoreShapeOrder( pImpRec
->nShapeId
,
894 ( ( (ULONG
)pImpRec
->aTextId
.nTxBxS
) << 16 )
895 + pImpRec
->aTextId
.nSequence
, pObj
);
904 /***************************************************************************
905 # Spezial FastSave - Attribute
906 #**************************************************************************/
908 void SwWW8ImplReader::Read_StyleCode( USHORT
, const BYTE
* pData
, short nLen
)
916 if (pWwFib
->GetFIBVersion() <= ww::eWW2
)
919 nColl
= SVBT16ToShort(pData
);
922 SetTxtFmtCollAndListLevel( *pPaM
, pCollA
[nColl
] );
927 // Read_Majority ist fuer Majority ( 103 ) und Majority50 ( 108 )
928 void SwWW8ImplReader::Read_Majority( USHORT
, const BYTE
* , short )
932 //-----------------------------------------
934 //-----------------------------------------
935 void SwWW8FltControlStack::NewAttr(const SwPosition
& rPos
,
936 const SfxPoolItem
& rAttr
)
938 ASSERT(RES_TXTATR_FIELD
!= rAttr
.Which(), "probably don't want to put"
939 "fields into the control stack");
940 ASSERT(RES_FLTR_REDLINE
!= rAttr
.Which(), "probably don't want to put"
941 "redlines into the control stack");
942 SwFltControlStack::NewAttr(rPos
, rAttr
);
945 void SwWW8FltControlStack::SetAttr(const SwPosition
& rPos
, USHORT nAttrId
,
946 BOOL bTstEnde
, long nHand
, BOOL
)
948 //Doing a textbox, and using the control stack only as a temporary
949 //collection point for properties which will are not to be set into
951 if (rReader
.pPlcxMan
&& rReader
.pPlcxMan
->GetDoingDrawTextBox())
953 USHORT nCnt
= static_cast< USHORT
>(Count());
954 for (USHORT i
=0; i
< nCnt
; ++i
)
956 SwFltStackEntry
* pEntry
= (*this)[i
];
957 if (nAttrId
== pEntry
->pAttr
->Which())
959 DeleteAndDestroy(i
--);
964 else //Normal case, set the attribute into the document
965 SwFltControlStack::SetAttr(rPos
, nAttrId
, bTstEnde
, nHand
);
968 long GetListFirstLineIndent(const SwNumFmt
&rFmt
)
970 ASSERT( rFmt
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
,
971 "<GetListFirstLineIndent> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
973 SvxAdjust eAdj
= rFmt
.GetNumAdjust();
974 long nReverseListIndented
;
975 if (eAdj
== SVX_ADJUST_RIGHT
)
976 nReverseListIndented
= -rFmt
.GetCharTextDistance();
977 else if (eAdj
== SVX_ADJUST_CENTER
)
978 nReverseListIndented
= rFmt
.GetFirstLineOffset()/2;
980 nReverseListIndented
= rFmt
.GetFirstLineOffset();
981 return nReverseListIndented
;
984 long lcl_GetTrueMargin(const SvxLRSpaceItem
&rLR
, const SwNumFmt
&rFmt
,
987 ASSERT( rFmt
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
,
988 "<lcl_GetTrueMargin> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
990 const long nBodyIndent
= rLR
.GetTxtLeft();
991 const long nFirstLineDiff
= rLR
.GetTxtFirstLineOfst();
992 rFirstLinePos
= nBodyIndent
+ nFirstLineDiff
;
994 const long nPseudoListBodyIndent
= rFmt
.GetAbsLSpace();
995 const long nReverseListIndented
= GetListFirstLineIndent(rFmt
);
996 long nExtraListIndent
= nPseudoListBodyIndent
+ nReverseListIndented
;
998 return nExtraListIndent
> 0 ? nExtraListIndent
: 0;
1001 void SyncIndentWithList(SvxLRSpaceItem
&rLR
, const SwNumFmt
&rFmt
)
1003 long nWantedFirstLinePos
;
1004 long nExtraListIndent
= lcl_GetTrueMargin(rLR
, rFmt
, nWantedFirstLinePos
);
1005 rLR
.SetTxtLeft(nWantedFirstLinePos
- nExtraListIndent
);
1006 rLR
.SetTxtFirstLineOfst(0);
1009 const SwNumFmt
* SwWW8FltControlStack::GetNumFmtFromStack(const SwPosition
&rPos
,
1010 const SwTxtNode
&rTxtNode
)
1012 const SwNumFmt
*pRet
= 0;
1013 const SfxPoolItem
*pItem
= GetStackAttr(rPos
, RES_FLTR_NUMRULE
);
1014 if (pItem
&& rTxtNode
.GetNumRule())
1016 String
sName(((SfxStringItem
*)pItem
)->GetValue());
1017 if (rTxtNode
.IsCountedInList())
1019 const SwNumRule
*pRule
= pDoc
->FindNumRulePtr(sName
);
1020 BYTE nLvl
= static_cast< BYTE
>(rTxtNode
.GetActualListLevel());
1021 pRet
= &(pRule
->Get(nLvl
));
1027 void SwWW8FltControlStack::SetAttrInDoc(const SwPosition
& rTmpPos
,
1028 SwFltStackEntry
* pEntry
)
1030 switch( pEntry
->pAttr
->Which() )
1035 Loop over the affect nodes and
1036 a) convert the word style absolute indent to indent relative
1037 to any numbering indent active on the nodes
1038 b) adjust the writer style tabstops relative to the old
1039 paragraph indent to be relative to the new paragraph indent
1041 using namespace sw::util
;
1042 SwPaM
aRegion(rTmpPos
);
1043 if (pEntry
->MakeRegion(pDoc
, aRegion
, false))
1045 SvxLRSpaceItem
aNewLR( *(SvxLRSpaceItem
*)pEntry
->pAttr
);
1046 ULONG nStart
= aRegion
.Start()->nNode
.GetIndex();
1047 ULONG nEnd
= aRegion
.End()->nNode
.GetIndex();
1048 for(; nStart
<= nEnd
; ++nStart
)
1050 SwNode
* pNode
= pDoc
->GetNodes()[ nStart
];
1051 if (!pNode
|| !pNode
->IsTxtNode())
1054 SwCntntNode
* pNd
= (SwCntntNode
*)pNode
;
1055 SvxLRSpaceItem aOldLR
= (const SvxLRSpaceItem
&)
1056 pNd
->GetAttr(RES_LR_SPACE
);
1058 SwTxtNode
*pTxtNode
= (SwTxtNode
*)pNode
;
1060 const SwNumFmt
*pNum
= 0;
1061 pNum
= GetNumFmtFromStack(*aRegion
.GetPoint(),
1064 pNum
= GetNumFmtFromTxtNode(*pTxtNode
);
1066 // --> OD 2008-06-03 #i86652#
1069 pNum
->GetPositionAndSpaceMode() ==
1070 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
1073 SyncIndentWithList(aNewLR
, *pNum
);
1076 if (aNewLR
== aOldLR
)
1079 pNd
->SetAttr(aNewLR
);
1085 case RES_TXTATR_FIELD
:
1086 ASSERT(!this, "What is a field doing in the control stack,"
1087 "probably should have been in the endstack");
1089 case RES_TXTATR_INETFMT
:
1091 SwPaM
aRegion(rTmpPos
);
1092 if (pEntry
->MakeRegion(pDoc
, aRegion
, false))
1095 //If we have just one single inline graphic then
1096 //don't insert a field for the single frame, set
1097 //the frames hyperlink field attribute directly.
1098 if (0 != (pFrm
= rReader
.ContainsSingleInlineGraphic(aRegion
)))
1100 const SwFmtINetFmt
*pAttr
= (const SwFmtINetFmt
*)
1103 aURL
.SetURL(pAttr
->GetValue(), false);
1104 aURL
.SetTargetFrameName(pAttr
->GetTargetFrame());
1105 pFrm
->SetFmtAttr(aURL
);
1108 pDoc
->Insert(aRegion
, *pEntry
->pAttr
, 0);
1113 SwFltControlStack::SetAttrInDoc(rTmpPos
, pEntry
);
1118 const SfxPoolItem
* SwWW8FltControlStack::GetFmtAttr(const SwPosition
& rPos
,
1121 const SfxPoolItem
*pItem
= GetStackAttr(rPos
, nWhich
);
1124 const SwCntntNode
*pNd
= pDoc
->GetNodes()[ rPos
.nNode
]->GetCntntNode();
1126 pItem
= &pDoc
->GetAttrPool().GetDefaultItem(nWhich
);
1130 If we're hunting for the indent on a paragraph and need to use the
1131 parent style indent, then return the indent in msword format, and
1132 not writer format, because that's the style that the filter works
1135 if (nWhich
== RES_LR_SPACE
)
1137 SfxItemState eState
= SFX_ITEM_DEFAULT
;
1138 if (const SfxItemSet
*pSet
= pNd
->GetpSwAttrSet())
1139 eState
= pSet
->GetItemState(RES_LR_SPACE
, false);
1140 if (eState
!= SFX_ITEM_SET
)
1141 pItem
= &(rReader
.pCollA
[rReader
.nAktColl
].maWordLR
);
1145 pItem
= &pNd
->GetAttr(nWhich
);
1151 const SfxPoolItem
* SwWW8FltControlStack::GetStackAttr(const SwPosition
& rPos
,
1154 SwNodeIndex
aNode( rPos
.nNode
, -1 );
1155 USHORT nIdx
= rPos
.nContent
.GetIndex();
1157 USHORT nSize
= static_cast< USHORT
>(Count());
1160 const SwFltStackEntry
* pEntry
= (*this)[ --nSize
];
1161 if (pEntry
->pAttr
->Which() == nWhich
)
1163 if ( (pEntry
->bLocked
) || (
1164 (pEntry
->nMkNode
<= aNode
) && (pEntry
->nPtNode
>= aNode
) &&
1165 (pEntry
->nMkCntnt
<= nIdx
) && (pEntry
->nPtCntnt
>= nIdx
) ) )
1167 return (const SfxPoolItem
*)pEntry
->pAttr
;
1174 bool SwWW8FltRefStack::IsFtnEdnBkmField(const SwFmtFld
& rFmtFld
, USHORT
& rBkmNo
)
1176 const SwField
* pFld
= rFmtFld
.GetFld();
1178 if(pFld
&& (RES_GETREFFLD
== pFld
->Which())
1179 && ((REF_FOOTNOTE
== (nSubType
= pFld
->GetSubType())) || (REF_ENDNOTE
== nSubType
))
1180 && ((SwGetRefField
*)pFld
)->GetSetRefName().Len())
1182 const IDocumentMarkAccess
* const pMarkAccess
= pDoc
->getIDocumentMarkAccess();
1183 IDocumentMarkAccess::const_iterator_t ppBkmk
= pMarkAccess
->findMark(
1184 ((SwGetRefField
*)pFld
)->GetSetRefName());
1185 if(ppBkmk
!= pMarkAccess
->getMarksEnd())
1187 // find Sequence No of corresponding Foot-/Endnote
1188 rBkmNo
= ppBkmk
- pMarkAccess
->getMarksBegin();
1195 void SwWW8FltRefStack::SetAttrInDoc(const SwPosition
& rTmpPos
,
1196 SwFltStackEntry
* pEntry
)
1198 switch( pEntry
->pAttr
->Which() )
1201 Look up these in our lists of bookmarks that were changed to
1202 variables, and replace the ref field with a var field, otherwise
1203 do normal (?) strange stuff
1205 case RES_TXTATR_FIELD
:
1207 SwNodeIndex
aIdx(pEntry
->nMkNode
, 1);
1208 SwPaM
aPaM(aIdx
, pEntry
->nMkCntnt
);
1210 SwFmtFld
& rFmtFld
= *(SwFmtFld
*)pEntry
->pAttr
;
1211 SwField
* pFld
= rFmtFld
.GetFld();
1213 // OD 2004-03-19 - <NOT> got lost from revision 1.128 to 1.129
1214 if (!RefToVar(pFld
,pEntry
))
1217 if( IsFtnEdnBkmField(rFmtFld
, nBkmNo
) )
1219 ::sw::mark::IMark
const * const pMark
= (pDoc
->getIDocumentMarkAccess()->getMarksBegin() + nBkmNo
)->get();
1221 const SwPosition
& rBkMrkPos
= pMark
->GetMarkPos();
1223 SwTxtNode
* pTxt
= rBkMrkPos
.nNode
.GetNode().GetTxtNode();
1224 if( pTxt
&& rBkMrkPos
.nContent
.GetIndex() )
1226 SwTxtAttr
* pFtn
= pTxt
->GetTxtAttr(
1227 rBkMrkPos
.nContent
.GetIndex()-1, RES_TXTATR_FTN
);
1230 USHORT nRefNo
= ((SwTxtFtn
*)pFtn
)->GetSeqRefNo();
1232 ((SwGetRefField
*)pFld
)->SetSeqNo( nRefNo
);
1234 if( pFtn
->GetFtn().IsEndNote() )
1235 ((SwGetRefField
*)pFld
)->SetSubType(REF_ENDNOTE
);
1241 pDoc
->Insert(aPaM
, *pEntry
->pAttr
, 0);
1242 MoveAttrs(*aPaM
.GetPoint());
1246 SwFltEndStack::SetAttrInDoc(rTmpPos
, pEntry
);
1249 case RES_FLTR_BOOKMARK
:
1250 ASSERT(!this, "EndStck used with non field, not what we want");
1251 SwFltEndStack::SetAttrInDoc(rTmpPos
, pEntry
);
1257 For styles we will do our tabstop arithmetic in word style and adjust them to
1258 writer style after all the styles have been finished and the dust settles as
1259 to what affects what.
1261 For explicit attributes we turn the adjusted writer tabstops back into 0 based
1262 word indexes and we'll turn them back into writer indexes when setting them
1263 into the document. If explicit left indent exist which affects them, then this
1264 is handled when the explict left indent is set into the document
1266 void SwWW8ImplReader::Read_Tab(USHORT
, const BYTE
* pData
, short nLen
)
1270 pCtrlStck
->SetAttr(*pPaM
->GetPoint(), RES_PARATR_TABSTOP
);
1275 const BYTE
* pDel
= pData
+ 1; // Del - Array
1276 BYTE nDel
= pData
[0];
1277 const BYTE
* pIns
= pData
+ 2*nDel
+ 2; // Ins - Array
1278 BYTE nIns
= pData
[nDel
*2+1];
1279 WW8_TBD
* pTyp
= (WW8_TBD
*)(pData
+ 2*nDel
+ 2*nIns
+ 2);// Typ - Array
1281 SvxTabStopItem
aAttr(0, 0, SVX_TAB_ADJUST_DEFAULT
, RES_PARATR_TABSTOP
);
1283 const SwTxtFmtColl
* pSty
= 0;
1285 if (pAktColl
) // StyleDef
1287 nTabBase
= pCollA
[nAktColl
].nBase
;
1288 if (nTabBase
< nColls
) // Based On
1289 pSty
= (const SwTxtFmtColl
*)pCollA
[nTabBase
].pFmt
;
1293 nTabBase
= nAktColl
;
1294 pSty
= (const SwTxtFmtColl
*)pCollA
[nAktColl
].pFmt
;
1297 bool bFound
= false;
1298 ::std::hash_set
<size_t> aLoopWatch
;
1299 while (pSty
&& !bFound
)
1301 const SfxPoolItem
* pTabs
;
1302 bFound
= pSty
->GetAttrSet().GetItemState(RES_PARATR_TABSTOP
, false,
1303 &pTabs
) == SFX_ITEM_SET
;
1305 aAttr
= *((const SvxTabStopItem
*)pTabs
);
1309 USHORT nOldTabBase
= nTabBase
;
1310 // If based on another
1311 if (nTabBase
< nColls
)
1312 nTabBase
= pCollA
[nTabBase
].nBase
;
1315 nTabBase
< nColls
&&
1316 nOldTabBase
!= nTabBase
&&
1317 nTabBase
!= ww::stiNil
1320 // #i61789: Stop searching when next style is the same as the
1321 // current one (prevent loop)
1322 aLoopWatch
.insert(reinterpret_cast<size_t>(pSty
));
1323 pSty
= (const SwTxtFmtColl
*)pCollA
[nTabBase
].pFmt
;
1325 if (aLoopWatch
.find(reinterpret_cast<size_t>(pSty
)) !=
1330 pSty
= 0; // gib die Suche auf
1334 SvxTabStop aTabStop
;
1335 for (i
=0; i
< nDel
; ++i
)
1337 USHORT nPos
= aAttr
.GetPos(SVBT16ToShort(pDel
+ i
*2));
1338 if( nPos
!= SVX_TAB_NOTFOUND
)
1339 aAttr
.Remove( nPos
, 1 );
1342 for (i
=0; i
< nIns
; ++i
)
1344 short nPos
= SVBT16ToShort(pIns
+ i
*2);
1345 aTabStop
.GetTabPos() = nPos
;
1346 switch( SVBT8ToByte( pTyp
[i
].aBits1
) & 0x7 ) // pTyp[i].jc
1349 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_LEFT
;
1352 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_CENTER
;
1355 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_RIGHT
;
1358 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL
;
1361 continue; // ignoriere Bar
1364 switch( SVBT8ToByte( pTyp
[i
].aBits1
) >> 3 & 0x7 )
1367 aTabStop
.GetFill() = ' ';
1370 aTabStop
.GetFill() = '.';
1373 aTabStop
.GetFill() = '-';
1377 aTabStop
.GetFill() = '_';
1381 USHORT nPos2
= aAttr
.GetPos( nPos
);
1382 if (nPos2
!= SVX_TAB_NOTFOUND
)
1383 aAttr
.Remove(nPos2
, 1); // sonst weigert sich das Insert()
1384 aAttr
.Insert(aTabStop
);
1391 //Here we have a tab definition which inserts no extra tabs, or deletes
1392 //no existing tabs. An older version of writer is probably the creater
1393 //of the document :-( . So if we are importing a style we can just
1394 //ignore it. But if we are importing into text we cannot as during
1395 //text SwWW8ImplReader::Read_Tab is called at the begin and end of
1396 //the range the attrib affects, and ignoring it would upset the
1398 if (!pAktColl
) //not importing into a style
1400 using namespace sw::util
;
1401 SvxTabStopItem aOrig
= pSty
?
1402 ItemGet
<SvxTabStopItem
>(*pSty
, RES_PARATR_TABSTOP
) :
1403 DefaultItemGet
<SvxTabStopItem
>(rDoc
, RES_PARATR_TABSTOP
);
1409 //-----------------------------------------
1411 //-----------------------------------------
1413 void SwWW8ImplReader::ImportDop()
1415 maTracer
.EnterEnvironment(sw::log::eDocumentProperties
);
1416 // correct the LastPrinted date in DocumentInfo
1417 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
1418 mpDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
1419 uno::Reference
<document::XDocumentProperties
> xDocuProps(
1420 xDPS
->getDocumentProperties());
1421 DBG_ASSERT(xDocuProps
.is(), "DocumentProperties is null");
1422 if (xDocuProps
.is())
1424 DateTime
aLastPrinted(
1425 sw::ms::DTTM2DateTime(pWDop
->dttmLastPrint
));
1426 ::util::DateTime
uDT(aLastPrinted
.Get100Sec(),
1427 aLastPrinted
.GetSec(), aLastPrinted
.GetMin(),
1428 aLastPrinted
.GetHour(), aLastPrinted
.GetDay(),
1429 aLastPrinted
.GetMonth(), aLastPrinted
.GetYear());
1430 xDocuProps
->setPrintDate(uDT
);
1434 // COMPATIBILITY FLAGS START
1437 // i#78951, remember the unknown compatability options
1438 // so as to export them out
1439 rDoc
.Setn32DummyCompatabilityOptions1( pWDop
->GetCompatabilityOptions());
1440 rDoc
.Setn32DummyCompatabilityOptions2( pWDop
->GetCompatabilityOptions2());
1442 // Abstand zwischen zwei Absaetzen ist die SUMME von unterem
1443 // Abst. des ersten und oberem Abst. des zweiten
1444 rDoc
.set(IDocumentSettingAccess::PARA_SPACE_MAX
, pWDop
->fDontUseHTMLAutoSpacing
);
1445 rDoc
.set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES
, true );
1446 maTracer
.Log(sw::log::eDontUseHTMLAutoSpacing
);
1447 // move tabs on alignment
1448 rDoc
.set(IDocumentSettingAccess::TAB_COMPAT
, true);
1449 // #i24363# tab stops relative to indent
1450 rDoc
.set(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT
, false);
1451 maTracer
.Log(sw::log::eTabStopDistance
);
1452 // OD 14.10.2003 #i18732# - adjust default of option 'FollowTextFlow'
1453 rDoc
.SetDefault( SwFmtFollowTextFlow( FALSE
) );
1455 // Import Default-Tabs
1456 long nDefTabSiz
= pWDop
->dxaTab
;
1457 if( nDefTabSiz
< 56 )
1460 // wir wollen genau einen DefaultTab
1461 SvxTabStopItem
aNewTab( 1, USHORT(nDefTabSiz
), SVX_TAB_ADJUST_DEFAULT
, RES_PARATR_TABSTOP
);
1462 ((SvxTabStop
&)aNewTab
[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT
;
1464 rDoc
.GetAttrPool().SetPoolDefaultItem( aNewTab
);
1466 if (!pWDop
->fUsePrinterMetrics
)
1467 maTracer
.Log(sw::log::ePrinterMetrics
);
1469 if (!pWDop
->fNoLeading
)
1470 maTracer
.Log(sw::log::eExtraLeading
);
1472 rDoc
.set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE
, !pWDop
->fUsePrinterMetrics
);
1473 rDoc
.set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE
, true);
1474 rDoc
.set(IDocumentSettingAccess::ADD_FLY_OFFSETS
, true );
1475 rDoc
.set(IDocumentSettingAccess::ADD_EXT_LEADING
, !pWDop
->fNoLeading
);
1478 rDoc
.set(IDocumentSettingAccess::OLD_NUMBERING
, false);
1481 // --> FME 2005-05-27 #i47448#
1482 rDoc
.set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING
, false);
1485 // --> FME 2005-06-08 #i49277#
1486 rDoc
.set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK
, !pWDop
->fExpShRtn
); // #i56856#
1487 // --> FME 2005-08-11 #i53199#
1488 rDoc
.set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT
, false);
1490 rDoc
.set(IDocumentSettingAccess::OLD_LINE_SPACING
, false);
1492 // OD, MMAHER 2004-03-01 #i25901#- set new compatibility option
1493 // 'Add paragraph and table spacing at bottom of table cells'
1494 rDoc
.set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS
, true);
1496 // OD 2004-03-17 #i11860# - set new compatibility option
1497 // 'Use former object positioning' to <FALSE>
1498 rDoc
.set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS
, false);
1500 // OD 2004-05-10 #i27767# - set new compatibility option
1501 // 'Conder Wrapping mode when positioning object' to <TRUE>
1502 rDoc
.set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION
, true);
1504 // --> FME 2004-04-22 # #108724#, #i13832#, #i24135#
1505 rDoc
.set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING
, false);
1508 // --> FME 2006-02-10 #131283#
1509 rDoc
.set(IDocumentSettingAccess::TABLE_ROW_KEEP
, true); //SetTableRowKeep( true );
1512 // --> FME 2006-03-01 #i3952#
1513 rDoc
.set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION
, true);
1516 rDoc
.set(IDocumentSettingAccess::INVERT_BORDER_SPACING
, true);
1517 rDoc
.set(IDocumentSettingAccess::COLLAPSE_EMPTY_CELL_PARA
, true);
1520 // COMPATIBILITY FLAGS END
1523 if (!pWDop
->fNoLeading
)
1524 maTracer
.Log(sw::log::eExtraLeading
);
1526 //import magic doptypography information, if its there
1527 if (pWwFib
->nFib
> 105)
1528 ImportDopTypography(pWDop
->doptypography
);
1530 // #110055# disable form design mode to be able to use imported controls directly
1531 // #i31239# always disable form design mode, not only in protected docs
1532 // if (pWDop->fProtEnabled)
1534 using namespace com::sun::star
;
1536 uno::Reference
<lang::XComponent
> xModelComp(mpDocShell
->GetModel(),
1538 uno::Reference
<beans::XPropertySet
> xDocProps(xModelComp
,
1542 uno::Reference
<beans::XPropertySetInfo
> xInfo
=
1543 xDocProps
->getPropertySetInfo();
1544 sal_Bool bValue
= false;
1546 xInfo
->hasPropertyByName(C2U("ApplyFormDesignMode")))
1548 xDocProps
->setPropertyValue(C2U("ApplyFormDesignMode"),
1549 cppu::bool2any(bValue
));
1553 const SvtFilterOptions
* pOpt
= SvtFilterOptions::Get();
1554 sal_Bool bUseEnhFields
=(pOpt
&& pOpt
->IsUseEnhancedFields());
1555 if (bUseEnhFields
) {
1556 rDoc
.set(IDocumentSettingAccess::PROTECT_FORM
, pWDop
->fProtEnabled
);
1559 maTracer
.LeaveEnvironment(sw::log::eDocumentProperties
);
1562 void SwWW8ImplReader::ImportDopTypography(const WW8DopTypography
&rTypo
)
1564 using namespace com::sun::star
;
1565 switch (rTypo
.iLevelOfKinsoku
)
1569 i18n::ForbiddenCharacters
aForbidden(rTypo
.rgxchFPunct
,
1571 rDoc
.setForbiddenCharacters(rTypo
.GetConvertedLang(),
1573 //Obviously cannot set the standard level 1 for japanese, so
1574 //bail out now while we can.
1575 if (rTypo
.GetConvertedLang() == LANGUAGE_JAPANESE
)
1584 This MS hack means that level 2 of japanese is not in operation, so we put
1585 in what we know are the MS defaults, there is a complementary reverse
1586 hack in the writer. Its our default as well, but we can set it anyway
1587 as a flag for later.
1589 if (!rTypo
.reserved2
)
1591 i18n::ForbiddenCharacters
aForbidden(rTypo
.GetJapanNotBeginLevel1(),
1592 rTypo
.GetJapanNotEndLevel1());
1593 rDoc
.setForbiddenCharacters(LANGUAGE_JAPANESE
,aForbidden
);
1596 rDoc
.set(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION
, rTypo
.fKerningPunct
);
1597 rDoc
.setCharacterCompressionType(static_cast<SwCharCompressType
>(rTypo
.iJustification
));
1600 //-----------------------------------------
1601 // Fuss- und Endnoten
1603 //-----------------------------------------
1605 WW8ReaderSave::WW8ReaderSave(SwWW8ImplReader
* pRdr
,WW8_CP nStartCp
) :
1606 maTmpPos(*pRdr
->pPaM
->GetPoint()),
1607 mpOldStck(pRdr
->pCtrlStck
),
1608 mpOldAnchorStck(pRdr
->pAnchorStck
),
1609 mpOldRedlines(pRdr
->mpRedlineStack
),
1610 mpOldPlcxMan(pRdr
->pPlcxMan
),
1611 mpWFlyPara(pRdr
->pWFlyPara
),
1612 mpSFlyPara(pRdr
->pSFlyPara
),
1613 mpPreviousNumPaM(pRdr
->pPreviousNumPaM
),
1614 mpPrevNumRule(pRdr
->pPrevNumRule
),
1615 mpTableDesc(pRdr
->pTableDesc
),
1616 mnInTable(pRdr
->nInTable
),
1617 mnAktColl(pRdr
->nAktColl
),
1618 mcSymbol(pRdr
->cSymbol
),
1619 mbIgnoreText(pRdr
->bIgnoreText
),
1620 mbSymbol(pRdr
->bSymbol
),
1621 mbHdFtFtnEdn(pRdr
->bHdFtFtnEdn
),
1622 mbTxbxFlySection(pRdr
->bTxbxFlySection
),
1624 mbInHyperlink(pRdr
->bInHyperlink
),
1625 mbPgSecBreak(pRdr
->bPgSecBreak
),
1626 mbWasParaEnd(pRdr
->bWasParaEnd
),
1627 mbHasBorder(pRdr
->bHasBorder
),
1628 mbFirstPara(pRdr
->bFirstPara
)
1630 pRdr
->bSymbol
= false;
1631 pRdr
->bHdFtFtnEdn
= true;
1632 pRdr
->bTxbxFlySection
= pRdr
->bAnl
= pRdr
->bPgSecBreak
= pRdr
->bWasParaEnd
1633 = pRdr
->bHasBorder
= false;
1634 pRdr
->bFirstPara
= true;
1636 pRdr
->pWFlyPara
= 0;
1637 pRdr
->pSFlyPara
= 0;
1638 pRdr
->pPreviousNumPaM
= 0;
1639 pRdr
->pPrevNumRule
= 0;
1640 pRdr
->pTableDesc
= 0;
1644 pRdr
->pCtrlStck
= new SwWW8FltControlStack(&pRdr
->rDoc
, pRdr
->nFieldFlags
,
1647 pRdr
->mpRedlineStack
= new sw::util::RedlineStack(pRdr
->rDoc
);
1649 pRdr
->pAnchorStck
= new SwWW8FltAnchorStack(&pRdr
->rDoc
, pRdr
->nFieldFlags
);
1651 // rette die Attributverwaltung: dies ist noetig, da der neu anzulegende
1652 // PLCFx Manager natuerlich auf die gleichen FKPs zugreift, wie der alte
1653 // und deren Start-End-Positionen veraendert...
1655 pRdr
->pPlcxMan
->SaveAllPLCFx(maPLCFxSave
);
1659 pRdr
->pPlcxMan
= new WW8PLCFMan(pRdr
->pSBase
,
1660 mpOldPlcxMan
->GetManType(), nStartCp
);
1663 maOldApos
.push_back(false);
1664 maOldApos
.swap(pRdr
->maApos
);
1665 maOldFieldStack
.swap(pRdr
->maFieldStack
);
1668 void WW8ReaderSave::Restore( SwWW8ImplReader
* pRdr
)
1670 pRdr
->pWFlyPara
= mpWFlyPara
;
1671 pRdr
->pSFlyPara
= mpSFlyPara
;
1672 pRdr
->pPreviousNumPaM
= mpPreviousNumPaM
;
1673 pRdr
->pPrevNumRule
= mpPrevNumRule
;
1674 pRdr
->pTableDesc
= mpTableDesc
;
1675 pRdr
->cSymbol
= mcSymbol
;
1676 pRdr
->bSymbol
= mbSymbol
;
1677 pRdr
->bIgnoreText
= mbIgnoreText
;
1678 pRdr
->bHdFtFtnEdn
= mbHdFtFtnEdn
;
1679 pRdr
->bTxbxFlySection
= mbTxbxFlySection
;
1680 pRdr
->nInTable
= mnInTable
;
1682 pRdr
->bInHyperlink
= mbInHyperlink
;
1683 pRdr
->bWasParaEnd
= mbWasParaEnd
;
1684 pRdr
->bPgSecBreak
= mbPgSecBreak
;
1685 pRdr
->nAktColl
= mnAktColl
;
1686 pRdr
->bHasBorder
= mbHasBorder
;
1687 pRdr
->bFirstPara
= mbFirstPara
;
1689 // schliesse alle Attribute, da sonst Attribute
1690 // entstehen koennen, die aus dem Fly rausragen
1691 pRdr
->DeleteCtrlStk();
1692 pRdr
->pCtrlStck
= mpOldStck
;
1694 pRdr
->mpRedlineStack
->closeall(*pRdr
->pPaM
->GetPoint());
1695 delete pRdr
->mpRedlineStack
;
1696 pRdr
->mpRedlineStack
= mpOldRedlines
;
1698 pRdr
->DeleteAnchorStk();
1699 pRdr
->pAnchorStck
= mpOldAnchorStck
;
1701 *pRdr
->pPaM
->GetPoint() = maTmpPos
;
1703 if (mpOldPlcxMan
!= pRdr
->pPlcxMan
)
1705 delete pRdr
->pPlcxMan
;
1706 pRdr
->pPlcxMan
= mpOldPlcxMan
;
1709 pRdr
->pPlcxMan
->RestoreAllPLCFx(maPLCFxSave
);
1710 pRdr
->maApos
.swap(maOldApos
);
1711 pRdr
->maFieldStack
.swap(maOldFieldStack
);
1714 void SwWW8ImplReader::Read_HdFtFtnText( const SwNodeIndex
* pSttIdx
,
1715 long nStartCp
, long nLen
, ManTypes nType
)
1717 // rettet Flags u.ae. u. setzt sie zurueck
1718 WW8ReaderSave
aSave( this );
1720 pPaM
->GetPoint()->nNode
= pSttIdx
->GetIndex() + 1; //
1721 pPaM
->GetPoint()->nContent
.Assign( pPaM
->GetCntntNode(), 0 );
1723 // dann Text fuer Header, Footer o. Footnote einlesen
1725 ReadText( nStartCp
, nLen
, nType
); // Sepx dabei ignorieren
1726 aSave
.Restore( this );
1729 //Use authornames, if not available fall back to initials.
1730 long SwWW8ImplReader::Read_And(WW8PLCFManResult
* pRes
)
1732 WW8PLCFx_SubDoc
* pSD
= pPlcxMan
->GetAtn();
1739 const WW67_ATRD
* pDescri
= (const WW67_ATRD
*)pSD
->GetData();
1740 const String
* pA
= GetAnnotationAuthor(SVBT16ToShort(pDescri
->ibst
));
1744 sAuthor
= String(pDescri
->xstUsrInitl
+ 1, pDescri
->xstUsrInitl
[0],
1745 RTL_TEXTENCODING_MS_1252
);
1749 const WW8_ATRD
* pDescri
= (const WW8_ATRD
*)pSD
->GetData();
1751 if (const String
* pA
= GetAnnotationAuthor(SVBT16ToShort(pDescri
->ibst
)))
1755 sal_uInt16 nLen
= SVBT16ToShort(pDescri
->xstUsrInitl
[0]);
1756 for(sal_uInt16 nIdx
= 1; nIdx
<= nLen
; ++nIdx
)
1757 sAuthor
+= SVBT16ToShort(pDescri
->xstUsrInitl
[nIdx
]);
1761 sal_uInt32 nDateTime
= 0;
1763 if (BYTE
* pExtended
= pPlcxMan
->GetExtendedAtrds()) // Word < 2002 has no date data for comments
1765 ULONG nIndex
= pSD
->GetIdx() & 0xFFFF; //Index is (stupidly) multiplexed for WW8PLCFx_SubDocs
1766 if (pWwFib
->lcbAtrdExtra
/18 > nIndex
)
1767 nDateTime
= SVBT32ToUInt32(*(SVBT32
*)(pExtended
+(nIndex
*18)));
1770 DateTime aDate
= sw::ms::DTTM2DateTime(nDateTime
);
1773 OutlinerParaObject
*pOutliner
= ImportAsOutliner( sTxt
, pRes
->nCp2OrIdx
,
1774 pRes
->nCp2OrIdx
+ pRes
->nMemLen
, MAN_AND
);
1776 this->pFmtOfJustInsertedApo
= 0;
1777 SwPostItField
aPostIt(
1778 (SwPostItFieldType
*)rDoc
.GetSysFldType(RES_POSTITFLD
), sAuthor
,
1780 aPostIt
.SetTextObject(pOutliner
);
1782 rDoc
.Insert(*pPaM
, SwFmtFld(aPostIt
), 0);
1787 void SwWW8ImplReader::Read_HdFtTextAsHackedFrame(long nStart
, long nLen
,
1788 SwFrmFmt
&rHdFtFmt
, sal_uInt16 nPageWidth
)
1790 const SwNodeIndex
* pSttIdx
= rHdFtFmt
.GetCntnt().GetCntntIdx();
1791 ASSERT(pSttIdx
, "impossible");
1795 SwPosition
aTmpPos(*pPaM
->GetPoint());
1797 pPaM
->GetPoint()->nNode
= pSttIdx
->GetIndex() + 1;
1798 pPaM
->GetPoint()->nContent
.Assign(pPaM
->GetCntntNode(), 0);
1800 SwFlyFrmFmt
*pFrame
= rDoc
.MakeFlySection(FLY_AT_CNTNT
, pPaM
->GetPoint());
1802 pFrame
->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE
, nPageWidth
, MINLAY
));
1803 pFrame
->SetFmtAttr(SwFmtSurround(SURROUND_THROUGHT
));
1804 pFrame
->SetFmtAttr(SwFmtHoriOrient(0, text::HoriOrientation::RIGHT
)); //iFOO
1805 // --> OD 2005-02-28 #i43427# - send frame for header/footer into background.
1806 pFrame
->SetFmtAttr( SvxOpaqueItem( RES_OPAQUE
, false ) );
1807 SdrObject
* pFrmObj
= CreateContactObject( pFrame
);
1809 "<SwWW8ImplReader::Read_HdFtTextAsHackedFrame(..)> - missing SdrObject instance" );
1812 pFrmObj
->SetOrdNum( 0L );
1815 MoveInsideFly(pFrame
);
1817 const SwNodeIndex
* pHackIdx
= pFrame
->GetCntnt().GetCntntIdx();
1819 Read_HdFtFtnText(pHackIdx
, nStart
, nLen
- 1, MAN_HDFT
);
1821 MoveOutsideFly(pFrame
, aTmpPos
);
1824 void SwWW8ImplReader::Read_HdFtText(long nStart
, long nLen
, SwFrmFmt
* pHdFtFmt
)
1826 const SwNodeIndex
* pSttIdx
= pHdFtFmt
->GetCntnt().GetCntntIdx();
1830 SwPosition
aTmpPos( *pPaM
->GetPoint() ); // merke alte Cursorposition
1832 Read_HdFtFtnText(pSttIdx
, nStart
, nLen
- 1, MAN_HDFT
);
1834 *pPaM
->GetPoint() = aTmpPos
;
1837 bool SwWW8ImplReader::HasOwnHeaderFooter(BYTE nWhichItems
, BYTE grpfIhdt
,
1846 for( BYTE nI
= 0x20; nI
; nI
>>= 1, nNumber
-- )
1848 if (nI
& nWhichItems
)
1852 bOk
= ( pHdFt
->GetTextPos(grpfIhdt
, nI
, start
, nLen
) && nLen
>= 2 );
1855 pHdFt
->GetTextPosExact( static_cast< short >(nNumber
+ (nSect
+1)*6), start
, nLen
);
1856 bOk
= ( 2 <= nLen
);
1867 void SwWW8ImplReader::Read_HdFt(bool bIsTitle
, int nSect
,
1868 const SwPageDesc
*pPrev
, const wwSection
&rSection
)
1870 BYTE nWhichItems
= 0;
1871 SwPageDesc
*pPD
= 0;
1875 rSection
.maSep
.grpfIhdt
& ~(WW8_HEADER_FIRST
| WW8_FOOTER_FIRST
);
1876 pPD
= rSection
.mpPage
;
1880 // --> OD 2008-08-06 #150965#
1881 // Always read title page header/footer data - it could be used by following sections
1883 // rSection.maSep.grpfIhdt & (WW8_HEADER_FIRST | WW8_FOOTER_FIRST),
1884 nWhichItems
= ( WW8_HEADER_FIRST
| WW8_FOOTER_FIRST
);
1886 pPD
= rSection
.mpTitlePage
;
1889 BYTE grpfIhdt
= rSection
.maSep
.grpfIhdt
;
1898 for( BYTE nI
= 0x20; nI
; nI
>>= 1, nNumber
-- )
1900 if (nI
& nWhichItems
)
1904 bOk
= ( pHdFt
->GetTextPos(grpfIhdt
, nI
, start
, nLen
) && nLen
>= 2 );
1907 pHdFt
->GetTextPosExact( static_cast< short >(nNumber
+ (nSect
+1)*6), start
, nLen
);
1908 bOk
= ( 2 <= nLen
);
1912 = (nI
& ( WW8_HEADER_EVEN
| WW8_FOOTER_EVEN
)) ? true: false;
1914 = (nI
& ( WW8_FOOTER_EVEN
| WW8_FOOTER_ODD
| WW8_FOOTER_FIRST
)) ? true: false;
1916 SwFrmFmt
* pFmt
= bUseLeft
? &pPD
->GetLeft() : &pPD
->GetMaster();
1922 //#i17196# Cannot have left without right
1923 if (!pPD
->GetMaster().GetFooter().GetFooterFmt())
1924 pPD
->GetMaster().SetFmtAttr(SwFmtFooter(true));
1926 pPD
->GetLeft().SetFmtAttr(SwFmtFooter(true));
1927 pHdFtFmt
= (SwFrmFmt
*)pFmt
->GetFooter().GetFooterFmt();
1932 //#i17196# Cannot have left without right
1933 if (!pPD
->GetMaster().GetHeader().GetHeaderFmt())
1934 pPD
->GetMaster().SetFmtAttr(SwFmtHeader(true));
1936 pPD
->GetLeft().SetFmtAttr(SwFmtHeader(true));
1937 pHdFtFmt
= (SwFrmFmt
*)pFmt
->GetHeader().GetHeaderFmt();
1942 bool bHackRequired
= false;
1943 if (bIsHeader
&& rSection
.IsFixedHeightHeader())
1944 bHackRequired
= true;
1945 else if (bIsFooter
&& rSection
.IsFixedHeightFooter())
1946 bHackRequired
= true;
1950 Read_HdFtTextAsHackedFrame(start
, nLen
, *pHdFtFmt
,
1951 static_cast< sal_uInt16
>(rSection
.GetTextAreaWidth()) );
1954 Read_HdFtText(start
, nLen
, pHdFtFmt
);
1956 else if (!bOk
&& pPrev
)
1957 CopyPageDescHdFt(pPrev
, pPD
, nI
);
1959 bIsHeader
= bIsFooter
= false;
1963 maTracer
.LeaveEnvironment(sw::log::eDocumentProperties
);
1966 bool wwSectionManager::SectionIsProtected(const wwSection
&rSection
) const
1968 return (mrReader
.pWDop
->fProtEnabled
&& !rSection
.IsNotProtected());
1971 void wwSectionManager::SetHdFt(wwSection
&rSection
, int nSect
,
1972 const wwSection
*pPrevious
)
1974 // Header / Footer nicht da
1975 if (!rSection
.maSep
.grpfIhdt
)
1978 ASSERT(rSection
.mpPage
, "makes no sense to call with a main page");
1979 if (rSection
.mpPage
)
1981 mrReader
.Read_HdFt(false, nSect
, pPrevious
? pPrevious
->mpPage
: 0,
1985 if (rSection
.mpTitlePage
)
1987 // 2 Pagedescs noetig: 1.Seite und folgende
1988 // 1. Seite einlesen
1989 mrReader
.Read_HdFt(true, nSect
, pPrevious
? pPrevious
->mpTitlePage
: 0,
1993 // Kopf / Fuss - Index Updaten
1994 // Damit der Index auch spaeter noch stimmt
1996 mrReader
.pHdFt
->UpdateIndex(rSection
.maSep
.grpfIhdt
);
2000 class AttribHere
: public std::unary_function
<const xub_StrLen
*, bool>
2003 xub_StrLen nPosition
;
2005 AttribHere(xub_StrLen nPos
) : nPosition(nPos
) {}
2006 bool operator()(const xub_StrLen
*pPosition
) const
2008 return (*pPosition
>= nPosition
);
2012 void SwWW8ImplReader::AppendTxtNode(SwPosition
& rPos
)
2014 SwTxtNode
* pTxt
= pPaM
->GetNode()->GetTxtNode();
2016 const SwNumRule
* pRule
= NULL
;
2019 pRule
= sw::util::GetNumRuleFromTxtNode(*pTxt
);
2022 pRule
&& !pWDop
->fDontUseHTMLAutoSpacing
&&
2023 (bParaAutoBefore
|| bParaAutoAfter
)
2026 // If after spacing is set to auto, set the after space to 0
2028 SetLowerSpacing(*pPaM
, 0);
2030 // If the previous textnode had numbering and
2031 // and before spacing is set to auto, set before space to 0
2032 if(pPrevNumRule
&& bParaAutoBefore
)
2033 SetUpperSpacing(*pPaM
, 0);
2035 // If the previous numbering rule was different we need
2036 // to insert a space after the previous paragraph
2037 if((pRule
!= pPrevNumRule
) && pPreviousNumPaM
)
2038 SetLowerSpacing(*pPreviousNumPaM
, GetParagraphAutoSpace(pWDop
->fDontUseHTMLAutoSpacing
));
2040 // cache current paragraph
2042 delete pPreviousNumPaM
, pPreviousNumPaM
= 0;
2044 pPreviousNumPaM
= new SwPaM(*pPaM
);
2045 pPrevNumRule
= pRule
;
2047 else if(!pRule
&& pPreviousNumPaM
)
2049 // If the previous paragraph has numbering but the current one does not
2050 // we need to add a space after the previous paragraph
2051 SetLowerSpacing(*pPreviousNumPaM
, GetParagraphAutoSpace(pWDop
->fDontUseHTMLAutoSpacing
));
2052 delete pPreviousNumPaM
, pPreviousNumPaM
= 0;
2057 // clear paragraph cache
2059 delete pPreviousNumPaM
, pPreviousNumPaM
= 0;
2060 pPrevNumRule
= pRule
;
2063 // If this is the first paragraph in the document and
2064 // Auto-spacing before paragraph is set,
2065 // set the upper spacing value to 0
2066 if(bParaAutoBefore
&& bFirstPara
&& !pWDop
->fDontUseHTMLAutoSpacing
)
2067 SetUpperSpacing(*pPaM
, 0);
2071 rDoc
.AppendTxtNode(rPos
);
2073 //We can flush all anchored graphics at the end of a paragraph.
2074 pAnchorStck
->Flush();
2077 bool SwWW8ImplReader::SetSpacing(SwPaM
&rMyPam
, int nSpace
, bool bIsUpper
)
2080 const SwPosition
* pSpacingPos
= rMyPam
.GetPoint();
2082 const SvxULSpaceItem
* pULSpaceItem
= (const SvxULSpaceItem
*)pCtrlStck
->GetFmtAttr(*pSpacingPos
, RES_UL_SPACE
);
2084 if(pULSpaceItem
!= 0)
2086 SvxULSpaceItem
aUL(*pULSpaceItem
);
2089 aUL
.SetUpper( static_cast< USHORT
>(nSpace
) );
2091 aUL
.SetLower( static_cast< USHORT
>(nSpace
) );
2093 xub_StrLen nEnd
= pSpacingPos
->nContent
.GetIndex();
2094 rMyPam
.GetPoint()->nContent
.Assign(rMyPam
.GetCntntNode(), 0);
2095 pCtrlStck
->NewAttr(*pSpacingPos
, aUL
);
2096 rMyPam
.GetPoint()->nContent
.Assign(rMyPam
.GetCntntNode(), nEnd
);
2097 pCtrlStck
->SetAttr(*pSpacingPos
, RES_UL_SPACE
);
2103 bool SwWW8ImplReader::SetLowerSpacing(SwPaM
&rMyPam
, int nSpace
)
2105 return SetSpacing(rMyPam
, nSpace
, false);
2108 bool SwWW8ImplReader::SetUpperSpacing(SwPaM
&rMyPam
, int nSpace
)
2110 return SetSpacing(rMyPam
, nSpace
, true);
2113 USHORT
SwWW8ImplReader::TabRowSprm(int nLevel
) const
2117 return nLevel
? 0x244C : 0x2417;
2120 void SwWW8ImplReader::EndSpecial()
2122 // Frame / Table / Anl
2124 StopAllAnl(); // -> bAnl = false
2126 while(maApos
.size() > 1)
2131 if (maApos
[nInTable
] == true)
2135 if (maApos
[0] == true)
2138 ASSERT(!nInTable
, "unclosed table!");
2141 bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync
, WW8_CP nStartCp
)
2143 // Frame / Table / Anl
2149 ASSERT(nInTable
>= 0,"nInTable < 0!");
2152 bool bTableRowEnd
= (pPlcxMan
->HasParaSprm(bVer67
? 25 : 0x2417) != 0 );
2154 // es muss leider fuer jeden Absatz zuerst nachgesehen werden,
2155 // ob sich unter den sprms
2156 // das sprm 29 (bzw. 0x261B) befindet, das ein APO einleitet.
2157 // Alle weiteren sprms beziehen sich dann naemlich auf das APO und nicht
2158 // auf den normalen Text drumrum.
2159 // Dasselbe gilt fuer eine Tabelle ( sprm 24 (bzw. 0x2416) )
2160 // und Anls ( sprm 13 ).
2161 // WW: Tabelle in APO geht ( Beide Anfaende treten gleichzeitig auf )
2162 // WW: APO in Tabelle geht nicht
2163 // d.h. Wenn eine Tabelle Inhalt eines Apo ist, dann muss der
2164 // Apo-Anfang zuerst bearbeitet werden, damit die Tabelle im Apo steht
2165 // und nicht umgekehrt. Am Ende muss dagegen zuerst das Tabellenende
2166 // bearbeitet werden, da die Apo erst nach der Tabelle abgeschlossen
2167 // werden darf ( sonst wird das Apo-Ende nie gefunden ).
2168 // Dasselbe gilt fuer Fly / Anl, Tab / Anl, Fly / Tab / Anl.
2170 // Wenn die Tabelle in einem Apo steht, fehlen im TabRowEnd-Bereich
2171 // die Apo-Angaben. Damit hier die Apo nicht beendet wird, wird
2172 // ProcessApo dann nicht aufgerufen.
2174 // KHZ: When there is a table inside the Apo the Apo-flags are also
2175 // missing for the 2nd, 3rd... paragraphs of each cell.
2178 // 1st look for in-table flag, for 2000+ there is a subtable flag to
2179 // be considered, the sprm 6649 gives the level of the table
2180 BYTE nCellLevel
= 0;
2183 nCellLevel
= 0 != pPlcxMan
->HasParaSprm(24);
2186 nCellLevel
= 0 != pPlcxMan
->HasParaSprm(0x2416);
2188 nCellLevel
= 0 != pPlcxMan
->HasParaSprm(0x244B);
2193 WW8_TablePos
*pTabPos
=0;
2194 WW8_TablePos aTabPos
;
2195 if (nCellLevel
&& !bVer67
)
2197 WW8PLCFxSave1 aSave
;
2198 pPlcxMan
->GetPap()->Save( aSave
);
2200 WW8PLCFx_Cp_FKP
* pPap
= pPlcxMan
->GetPapPLCF();
2201 WW8_CP nMyStartCp
=nStartCp
;
2203 if (const BYTE
*pLevel
= pPlcxMan
->HasParaSprm(0x6649))
2204 nCellLevel
= *pLevel
;
2206 bool bHasRowEnd
= SearchRowEnd(pPap
, nMyStartCp
, (nInTable
<nCellLevel
?nInTable
:nCellLevel
-1));
2208 //Bad Table, remain unchanged in level, e.g. #i19667#
2210 nCellLevel
= static_cast< BYTE
>(nInTable
);
2212 if (bHasRowEnd
&& ParseTabPos(&aTabPos
,pPap
))
2215 pPlcxMan
->GetPap()->Restore( aSave
);
2218 // then look if we are in an Apo
2220 ApoTestResults aApo
= TestApo(nCellLevel
, bTableRowEnd
, pTabPos
);
2222 //look to see if we are in a Table, but Table in foot/end note not allowed
2223 bool bStartTab
= (nInTable
< nCellLevel
) && !bFtnEdn
;
2225 bool bStopTab
= bWasTabRowEnd
&& (nInTable
> nCellLevel
) && !bFtnEdn
;
2227 bWasTabRowEnd
= false; // must be deactivated right here to prevent next
2228 // WW8TabDesc::TableCellEnd() from making nonsense
2230 if (nInTable
&& !bTableRowEnd
&& !bStopTab
&& (nInTable
== nCellLevel
&& aApo
.HasStartStop()))
2231 bStopTab
= bStartTab
= true; // Required to stop and start table
2233 // Dann auf Anl (Nummerierung) testen
2234 // und dann alle Ereignisse in der richtigen Reihenfolge bearbeiten
2236 if( bAnl
&& !bTableRowEnd
)
2238 const BYTE
* pSprm13
= pPlcxMan
->HasParaSprm( 13 );
2241 BYTE nT
= static_cast< BYTE
>(GetNumType( *pSprm13
));
2242 if( ( nT
!= WW8_Pause
&& nT
!= nWwNumType
) // Anl-Wechsel
2243 || aApo
.HasStartStop() // erzwungenes Anl-Ende
2244 || bStopTab
|| bStartTab
)
2246 StopAnlToRestart(nT
); // Anl-Restart ( = Wechsel ) ueber sprms
2250 NextAnlLine( pSprm13
); // naechste Anl-Zeile
2254 { // Anl normal zuende
2255 StopAllAnl(); // Wirkliches Ende
2267 maApos
[nInTable
] = false;
2270 if (aApo
.mbStartApo
)
2272 maApos
[nInTable
] = StartApo(aApo
, pTabPos
);
2273 // nach StartApo ist ein ReSync noetig ( eigentlich nur, falls die Apo
2274 // ueber eine FKP-Grenze geht
2279 WW8PLCFxSave1 aSave
;
2280 pPlcxMan
->GetPap()->Save( aSave
);
2282 if (bAnl
) // Nummerierung ueber Zellengrenzen
2283 StopAllAnl(); // fuehrt zu Absturz -> keine Anls
2285 while (nInTable
< nCellLevel
)
2287 if (StartTable(nStartCp
)) {
2293 maApos
.push_back(false);
2294 if (nInTable
<nCellLevel
)
2298 // nach StartTable ist ein ReSync noetig ( eigentlich nur, falls die
2299 // Tabelle ueber eine FKP-Grenze geht
2301 pPlcxMan
->GetPap()->Restore( aSave
);
2303 return bTableRowEnd
;
2306 CharSet
SwWW8ImplReader::GetCurrentCharSet()
2310 If the hard charset is set use it, if not see if there is an open
2311 character run that has set the charset, if not then fallback to the
2312 current underlying paragraph style.
2314 CharSet eSrcCharSet
= eHardCharSet
;
2315 if (eSrcCharSet
== RTL_TEXTENCODING_DONTKNOW
)
2317 if (!maFontSrcCharSets
.empty())
2318 eSrcCharSet
= maFontSrcCharSets
.top();
2319 if ((eSrcCharSet
== RTL_TEXTENCODING_DONTKNOW
) && (nCharFmt
!= -1))
2320 eSrcCharSet
= pCollA
[nCharFmt
].GetCharSet();
2321 if (eSrcCharSet
== RTL_TEXTENCODING_DONTKNOW
)
2322 eSrcCharSet
= pCollA
[nAktColl
].GetCharSet();
2323 if (eSrcCharSet
== RTL_TEXTENCODING_DONTKNOW
)
2324 { // patch from cmc for #i52786#
2327 The (default) character set used for a run of text is the default
2328 character set for the version of Word that last saved the document.
2330 This is a bit tentative, more might be required if the concept is correct.
2331 When later version of word write older 6/95 documents the charset is
2332 correctly set in the character runs involved, so its hard to reproduce
2333 documents that require this to be sure of the process involved.
2335 const SvxLanguageItem
*pLang
=
2336 (const SvxLanguageItem
*)GetFmtAttr(RES_CHRATR_LANGUAGE
);
2339 switch (pLang
->GetLanguage())
2341 case LANGUAGE_CZECH
:
2342 eSrcCharSet
= RTL_TEXTENCODING_MS_1250
;
2345 eSrcCharSet
= RTL_TEXTENCODING_MS_1252
;
2354 void SwWW8ImplReader::PostProcessAttrs()
2356 if (mpPostProcessAttrsInfo
!= NULL
)
2358 SfxItemIter
aIter(mpPostProcessAttrsInfo
->mItemSet
);
2360 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
2365 pCtrlStck
->NewAttr(*mpPostProcessAttrsInfo
->mPaM
.GetPoint(),
2367 pCtrlStck
->SetAttr(*mpPostProcessAttrsInfo
->mPaM
.GetMark(),
2368 pItem
->Which(), true);
2370 while (!aIter
.IsAtEnd() && 0 != (pItem
= aIter
.NextItem()));
2373 delete mpPostProcessAttrsInfo
;
2374 mpPostProcessAttrsInfo
= NULL
;
2380 It appears that some documents that are in a baltic 8 bit encoding which has
2381 some undefined characters can have use made of those characters, in which
2382 case they default to CP1252. If not then its perhaps that the font encoding
2383 is only in use for 6/7 and for 8+ if we are in 8bit mode then the encoding
2386 So a encoding converter that on an undefined character attempts to
2387 convert from 1252 on the undefined character
2389 sal_Size
Custom8BitToUnicode(rtl_TextToUnicodeConverter hConverter
,
2390 sal_Char
*pIn
, sal_Size nInLen
, sal_Unicode
*pOut
, sal_Size nOutLen
)
2392 const sal_uInt32 nFlags
=
2393 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
|
2394 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
|
2395 RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE
|
2396 RTL_TEXTTOUNICODE_FLAGS_FLUSH
;
2398 const sal_uInt32 nFlags2
=
2399 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE
|
2400 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_IGNORE
|
2401 RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE
|
2402 RTL_TEXTTOUNICODE_FLAGS_FLUSH
;
2404 sal_Size nDestChars
=0;
2405 sal_Size nConverted
=0;
2409 sal_uInt32 nInfo
= 0;
2410 sal_Size nThisConverted
=0;
2412 nDestChars
+= rtl_convertTextToUnicode(hConverter
, 0,
2413 pIn
+nConverted
, nInLen
-nConverted
,
2414 pOut
+nDestChars
, nOutLen
-nDestChars
,
2415 nFlags
, &nInfo
, &nThisConverted
);
2417 ASSERT(nInfo
== 0, "A character conversion failed!");
2419 nConverted
+= nThisConverted
;
2422 nInfo
& RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
||
2423 nInfo
& RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
2426 sal_Size nOtherConverted
;
2427 rtl_TextToUnicodeConverter hCP1252Converter
=
2428 rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_MS_1252
);
2429 nDestChars
+= rtl_convertTextToUnicode(hCP1252Converter
, 0,
2431 pOut
+nDestChars
, nOutLen
-nDestChars
,
2432 nFlags2
, &nInfo
, &nOtherConverted
);
2433 rtl_destroyTextToUnicodeConverter(hCP1252Converter
);
2436 } while (nConverted
< nInLen
);
2441 bool SwWW8ImplReader::LangUsesHindiNumbers(USHORT nLang
)
2443 bool bResult
= false;
2447 case 0x1401: // Arabic(Algeria)
2448 case 0x3c01: // Arabic(Bahrain)
2449 case 0xc01: // Arabic(Egypt)
2450 case 0x801: // Arabic(Iraq)
2451 case 0x2c01: // Arabic (Jordan)
2452 case 0x3401: // Arabic(Kuwait)
2453 case 0x3001: // Arabic(Lebanon)
2454 case 0x1001: // Arabic(Libya)
2455 case 0x1801: // Arabic(Morocco)
2456 case 0x2001: // Arabic(Oman)
2457 case 0x4001: // Arabic(Qatar)
2458 case 0x401: // Arabic(Saudi Arabia)
2459 case 0x2801: // Arabic(Syria)
2460 case 0x1c01: // Arabic(Tunisia)
2461 case 0x3801: // Arabic(U.A.E)
2462 case 0x2401: // Arabic(Yemen)
2472 sal_Unicode
SwWW8ImplReader::TranslateToHindiNumbers(sal_Unicode nChar
)
2474 if (nChar
>= 0x0030 && nChar
<= 0x0039)
2475 return nChar
+ 0x0630;
2480 // Returnwert: true for no Sonderzeichen
2481 bool SwWW8ImplReader::ReadPlainChars(WW8_CP
& rPos
, long nEnd
, long nCpOfs
)
2483 // Unicode-Flag neu setzen und notfalls File-Pos korrigieren
2484 // merke: Seek kostet nicht viel, da inline geprueft wird,
2485 // ob die korrekte FilePos nicht schon erreicht ist.
2486 WW8_FC nStreamPos
= pSBase
->WW8Cp2Fc(nCpOfs
+rPos
, &bIsUnicode
);
2487 pStrm
->Seek( nStreamPos
);
2490 if (nEnd
- rPos
<= (STRING_MAXLEN
-1))
2491 nLen
= writer_cast
<xub_StrLen
>(nEnd
- rPos
);
2493 nLen
= STRING_MAXLEN
-1;
2494 ASSERT(nLen
, "String is 0");
2498 const CharSet eSrcCharSet
= bVer67
? GetCurrentCharSet() :
2499 RTL_TEXTENCODING_MS_1252
;
2501 // (re)alloc UniString data
2502 String sPlainCharsBuf
;
2504 sal_Unicode
* pBuffer
= sPlainCharsBuf
.AllocBuffer( nLen
);
2505 sal_Unicode
* pWork
= pBuffer
;
2507 sal_Char
* p8Bits
= NULL
;
2509 rtl_TextToUnicodeConverter hConverter
= 0;
2510 if (!bIsUnicode
|| bVer67
)
2511 hConverter
= rtl_createTextToUnicodeConverter(eSrcCharSet
);
2514 p8Bits
= new sal_Char
[nLen
];
2516 // read the stream data
2521 USHORT nCTLLang
= 0;
2522 const SfxPoolItem
* pItem
= GetFmtAttr(RES_CHRATR_CTL_LANGUAGE
);
2524 nCTLLang
= dynamic_cast<const SvxLanguageItem
*>(pItem
)->GetLanguage();
2526 for( nL2
= 0; nL2
< nLen
; ++nL2
, ++pWork
)
2529 *pStrm
>> nUCode
; // unicode --> read 2 bytes
2532 *pStrm
>> nBCode
; // old code --> read 1 byte
2536 if (pStrm
->GetError())
2538 rPos
= WW8_CP_MAX
-10; // -> eof or other error
2539 sPlainCharsBuf
.ReleaseBufferAccess( 0 );
2543 if ((32 > nUCode
) || (0xa0 == nUCode
))
2545 pStrm
->SeekRel( bIsUnicode
? -2 : -1 );
2546 break; // Sonderzeichen < 32, == 0xa0 gefunden
2555 if (nUCode
>= 0x3000) //0x8000 ?
2558 aTest
[0] = static_cast< sal_Char
>((nUCode
& 0xFF00) >> 8);
2559 aTest
[1] = static_cast< sal_Char
>(nUCode
& 0x00FF);
2560 String
aTemp(aTest
, 2, eSrcCharSet
);
2561 ASSERT(aTemp
.Len() == 1, "so much for that theory");
2562 *pWork
= aTemp
.GetChar(0);
2566 sal_Char cTest
= static_cast< sal_Char
>(nUCode
& 0x00FF);
2567 Custom8BitToUnicode(hConverter
, &cTest
, 1, pWork
, 1);
2572 p8Bits
[nL2
] = nBCode
;
2577 xub_StrLen nEndUsed
= nL2
;
2580 nEndUsed
= Custom8BitToUnicode(hConverter
, p8Bits
, nL2
, pBuffer
, nLen
);
2582 for( xub_StrLen nI
= 0; nI
< nLen
; ++nI
, ++pBuffer
)
2583 if (m_bRegardHindiDigits
&& bBidi
&& LangUsesHindiNumbers(nCTLLang
))
2584 *pBuffer
= TranslateToHindiNumbers(*pBuffer
);
2586 sPlainCharsBuf
.ReleaseBufferAccess( nEndUsed
);
2588 AddTextToParagraph(sPlainCharsBuf
);
2590 if (!maApos
.back()) //a para end in apo doesn't count
2591 bWasParaEnd
= false; //kein CR
2595 rtl_destroyTextToUnicodeConverter(hConverter
);
2600 bool SwWW8ImplReader::AddTextToParagraph(const String
& rAddString
)
2602 const SwTxtNode
* pNd
= pPaM
->GetCntntNode()->GetTxtNode();
2603 if (rAddString
.Len())
2607 //!! does not compile with debug=t -> unresolved external (dbg_out),
2608 //!! sommeone who knows what he wants to get should fix this
2609 // ::std::clog << "<addTextToParagraph>" << dbg_out(rAddString)
2610 // << "</addTextToParagraph>" << ::std::endl;
2613 if ((pNd
->GetTxt().Len() + rAddString
.Len()) < STRING_MAXLEN
-1)
2615 rDoc
.Insert (*pPaM
, rAddString
, true);
2620 if (pNd
->GetTxt().Len()< STRING_MAXLEN
-1)
2622 String
sTempStr (rAddString
,0,
2623 STRING_MAXLEN
- pNd
->GetTxt().Len() -1);
2624 rDoc
.Insert (*pPaM
, sTempStr
, true);
2625 sTempStr
= rAddString
.Copy(sTempStr
.Len(),
2626 rAddString
.Len() - sTempStr
.Len());
2627 AppendTxtNode(*pPaM
->GetPoint());
2628 rDoc
.Insert (*pPaM
,sTempStr
, true );
2632 AppendTxtNode(*pPaM
->GetPoint());
2633 rDoc
.Insert (*pPaM
, rAddString
, true);
2643 // Returnwert: true for para end
2644 bool SwWW8ImplReader::ReadChars(WW8_CP
& rPos
, WW8_CP nNextAttr
, long nTextEnd
,
2647 long nEnd
= ( nNextAttr
< nTextEnd
) ? nNextAttr
: nTextEnd
;
2649 if (bSymbol
|| bIgnoreText
)
2651 if( bSymbol
) // Spezialzeichen einfuegen
2653 for(USHORT nCh
= 0; nCh
< nEnd
- rPos
; ++nCh
)
2654 rDoc
.Insert( *pPaM
, cSymbol
);
2655 pCtrlStck
->SetAttr( *pPaM
->GetPoint(), RES_CHRATR_FONT
);
2657 pStrm
->SeekRel( nEnd
- rPos
);
2658 rPos
= nEnd
; // ignoriere bis Attributende
2664 if (ReadPlainChars(rPos
, nEnd
, nCpOfs
))
2665 return false; // Fertig
2667 bool bStartLine
= ReadChar(rPos
, nCpOfs
);
2669 if (bPgSecBreak
|| bStartLine
|| rPos
== nEnd
) // CR oder Fertig
2676 bool SwWW8ImplReader::HandlePageBreakChar()
2678 bool bParaEndAdded
= false;
2679 //#i1909# section/page breaks should not occur in tables, word
2680 //itself ignores them in this case.
2684 pCtrlStck
->KillUnlockedAttrs(*pPaM
->GetPoint());
2687 If its a 0x0c without a paragraph end before it, act like a
2688 paragraph end, but nevertheless, numbering (and perhaps other
2689 similiar constructs) do not exist on the para.
2693 bParaEndAdded
= true;
2694 if (0 >= pPaM
->GetPoint()->nContent
.GetIndex())
2696 if (SwTxtNode
* pTxtNode
= pPaM
->GetNode()->GetTxtNode())
2699 *GetDfltAttr(RES_PARATR_NUMRULE
));
2704 return bParaEndAdded
;
2707 bool SwWW8ImplReader::ReadChar(long nPosCp
, long nCpOfs
)
2709 bool bNewParaEnd
= false;
2710 // Unicode-Flag neu setzen und notfalls File-Pos korrigieren
2711 // merke: Seek kostet nicht viel, da inline geprueft wird,
2712 // ob die korrekte FilePos nicht schon erreicht ist.
2713 pStrm
->Seek( pSBase
->WW8Cp2Fc(nCpOfs
+nPosCp
, &bIsUnicode
) );
2718 *pStrm
>> nWCharVal
; // unicode --> read 2 bytes
2721 *pStrm
>> nBCode
; // old code --> read 1 byte
2725 sal_Char cInsert
= '\x0';
2732 SwPageNumberField
aFld(
2733 (SwPageNumberFieldType
*)rDoc
.GetSysFldType(
2734 RES_PAGENUMBERFLD
), PG_RANDOM
, SVX_NUM_ARABIC
);
2735 rDoc
.Insert(*pPaM
, SwFmtFld(aFld
), 0);
2739 //#108817# if there is only one column word treats a column
2740 //break like a pagebreak.
2741 if (maSectionManager
.CurrentSectionColCount() < 2)
2742 bRet
= HandlePageBreakChar();
2745 // Always insert a txtnode for a column break, e.g. ##
2746 SwCntntNode
*pCntNd
=pPaM
->GetCntntNode();
2747 if (pCntNd
!=NULL
&& pCntNd
->Len()>0) // if par is empty not break is needed
2748 AppendTxtNode(*pPaM
->GetPoint());
2749 rDoc
.Insert(*pPaM
, SvxFmtBreakItem(SVX_BREAK_COLUMN_BEFORE
, RES_BREAK
), 0);
2754 TabCellEnd(); // table cell end (Flags abfragen!)
2757 if( !bSpec
) // "Satellit"
2761 if( !bSpec
) // "Para-Ende"-Zeichen
2765 if( !bSpec
) // Juristenparagraph
2769 cInsert
= '\x9'; // Tab
2772 cInsert
= '\xa'; // Hard NewLine
2775 bRet
= HandlePageBreakChar();
2778 rDoc
.Insert( *pPaM
, CHAR_HARDHYPHEN
); // Non-breaking hyphen
2781 rDoc
.Insert( *pPaM
, CHAR_SOFTHYPHEN
); // Non-required hyphens
2784 rDoc
.Insert( *pPaM
, CHAR_HARDBLANK
); // Non-breaking spaces
2788 Current thinking is that if bObj is set then we have a
2789 straightforward "traditional" ole object, otherwise we have a
2790 graphic preview of an associated ole2 object (or a simple
2793 if (!IsInlineEscherHack())
2795 SwFrmFmt
*pResult
= 0;
2797 pResult
= ImportOle();
2799 pResult
= ImportGraf();
2801 //#102160# If we have a bad 0x1 insert a space instead.
2805 ASSERT(!bObj
&& !bEmbeddObj
&& !nObjLocFc
,
2806 "WW8: Please report this document, it may have a "
2812 bObj
= bEmbeddObj
= false;
2819 Read_GrafLayer( nPosCp
);
2822 bNewParaEnd
= bRet
= true;
2827 Yes complex, if there is an entry in the undocumented PLCF
2828 which I believe to be a record of cell and row boundaries
2829 see if the magic bit which I believe to mean cell end is
2830 set. I also think btw that the third byte of the 4 byte
2831 value is the level of the cell
2833 WW8PLCFspecial
* pTest
= pPlcxMan
->GetMagicTables();
2834 if (pTest
&& pTest
->SeekPosExact(nPosCp
+1+nCpOfs
) &&
2835 pTest
->Where() == nPosCp
+1+nCpOfs
)
2839 pTest
->Get(nPos
, pData
);
2840 sal_uInt32 nData
= SVBT32ToUInt32(*(SVBT32
*)pData
);
2841 if (nData
& 0x2) //Might be how it works
2847 else if (bWasTabCellEnd
)
2854 bWasTabCellEnd
= false;
2857 case 0x5: // Annotation reference
2861 if (!maFtnStack
.empty())
2863 break; // Auto-Fussnoten-Nummer
2864 #if OSL_DEBUG_LEVEL > 1
2866 ::std::clog
<< "<unknownValue val=\"" << nWCharVal
<< "\">" << ::std::endl
;
2871 if( '\x0' != cInsert
)
2873 String sInsert
= ByteString::ConvertToUnicode(cInsert
,
2874 RTL_TEXTENCODING_MS_1252
);
2875 AddTextToParagraph(sInsert
);
2877 if (!maApos
.back()) //a para end in apo doesn't count
2878 bWasParaEnd
= bNewParaEnd
;
2882 void SwWW8ImplReader::ProcessAktCollChange(WW8PLCFManResult
& rRes
,
2883 bool* pStartAttr
, bool bCallProcessSpecial
)
2885 USHORT nOldColl
= nAktColl
;
2886 nAktColl
= pPlcxMan
->GetColl();
2889 if (nAktColl
>= nColls
|| !pCollA
[nAktColl
].pFmt
|| !pCollA
[nAktColl
].bColl
)
2892 bParaAutoBefore
= false;
2893 bParaAutoAfter
= false;
2897 bParaAutoBefore
= pCollA
[nAktColl
].bParaAutoBefore
;
2898 bParaAutoAfter
= pCollA
[nAktColl
].bParaAutoAfter
;
2901 bool bTabRowEnd
= false;
2902 if( pStartAttr
&& bCallProcessSpecial
&& !bInHyperlink
)
2905 // Frame / Table / Autonumbering List Level
2906 bTabRowEnd
= ProcessSpecial(bReSync
, rRes
.nAktCp
+pPlcxMan
->GetCpOfs());
2908 *pStartAttr
= pPlcxMan
->Get( &rRes
); // hole Attribut-Pos neu
2911 if (!bTabRowEnd
&& StyleExists(nAktColl
))
2913 SetTxtFmtCollAndListLevel( *pPaM
, pCollA
[ nAktColl
]);
2914 ChkToggleAttr(pCollA
[ nOldColl
].n81Flags
, pCollA
[ nAktColl
].n81Flags
);
2915 ChkToggleBiDiAttr(pCollA
[nOldColl
].n81BiDiFlags
,
2916 pCollA
[nAktColl
].n81BiDiFlags
);
2920 long SwWW8ImplReader::ReadTextAttr(WW8_CP
& rTxtPos
, bool& rbStartLine
)
2922 long nSkipChars
= 0;
2923 WW8PLCFManResult aRes
;
2925 ASSERT(pPaM
->GetNode()->GetTxtNode(), "Missing txtnode");
2926 bool bStartAttr
= pPlcxMan
->Get(&aRes
); // hole Attribut-Pos
2927 aRes
.nAktCp
= rTxtPos
; // Akt. Cp-Pos
2929 bool bNewSection
= (aRes
.nFlags
& MAN_MASK_NEW_SEP
) && !bIgnoreText
;
2930 if ( bNewSection
) // neue Section
2932 ASSERT(pPaM
->GetNode()->GetTxtNode(), "Missing txtnode");
2933 // PageDesc erzeugen und fuellen
2934 maSectionManager
.CreateSep(rTxtPos
, bPgSecBreak
);
2935 // -> 0xc war ein Sectionbreak, aber
2937 bPgSecBreak
= false; // PageDesc erzeugen und fuellen
2938 ASSERT(pPaM
->GetNode()->GetTxtNode(), "Missing txtnode");
2941 // neuer Absatz ueber Plcx.Fkp.papx
2942 if ( (aRes
.nFlags
& MAN_MASK_NEW_PAP
)|| rbStartLine
)
2944 ProcessAktCollChange( aRes
, &bStartAttr
,
2945 MAN_MASK_NEW_PAP
== (aRes
.nFlags
& MAN_MASK_NEW_PAP
) &&
2947 rbStartLine
= false;
2950 // position of last CP that's to be ignored
2953 if( 0 < aRes
.nSprmId
) // leere Attrs ignorieren
2955 if( ( eFTN
> aRes
.nSprmId
) || ( 0x0800 <= aRes
.nSprmId
) )
2957 if( bStartAttr
) // WW-Attribute
2959 if( aRes
.nMemLen
>= 0 )
2960 ImportSprm(aRes
.pMemPos
, aRes
.nSprmId
);
2963 EndSprm( aRes
.nSprmId
); // Attr ausschalten
2965 else if( aRes
.nSprmId
< 0x800 ) // eigene Hilfs-Attribute
2969 nSkipChars
= ImportExtSprm(&aRes
);
2971 (aRes
.nSprmId
== eFTN
) || (aRes
.nSprmId
== eEDN
) ||
2972 (aRes
.nSprmId
== eFLD
) || (aRes
.nSprmId
== eAND
)
2975 // Felder/Ftn-/End-Note hier ueberlesen
2976 rTxtPos
+= nSkipChars
;
2977 nSkipPos
= rTxtPos
-1;
2981 EndExtSprm( aRes
.nSprmId
);
2985 pStrm
->Seek(pSBase
->WW8Cp2Fc( pPlcxMan
->GetCpOfs() + rTxtPos
, &bIsUnicode
));
2987 // Find next Attr position (and Skip attributes of field contents if needed)
2988 if (nSkipChars
&& !bIgnoreText
)
2989 pCtrlStck
->MarkAllAttrsOld();
2990 bool bOldIgnoreText
= bIgnoreText
;
2992 USHORT nOldColl
= nAktColl
;
2993 bool bDoPlcxManPlusPLus
= true;
2997 if( bDoPlcxManPlusPLus
)
2999 nNext
= pPlcxMan
->Where();
3001 if (mpPostProcessAttrsInfo
&&
3002 mpPostProcessAttrsInfo
->mnCpStart
== nNext
)
3004 mpPostProcessAttrsInfo
->mbCopy
= true;
3007 if( (0 <= nNext
) && (nSkipPos
>= nNext
) )
3009 nNext
= ReadTextAttr( rTxtPos
, rbStartLine
);
3010 bDoPlcxManPlusPLus
= false;
3014 if (mpPostProcessAttrsInfo
&&
3015 nNext
> mpPostProcessAttrsInfo
->mnCpEnd
)
3017 mpPostProcessAttrsInfo
->mbCopy
= false;
3020 while( nSkipPos
>= nNext
);
3021 bIgnoreText
= bOldIgnoreText
;
3024 pCtrlStck
->KillUnlockedAttrs( *pPaM
->GetPoint() );
3025 if( nOldColl
!= pPlcxMan
->GetColl() )
3026 ProcessAktCollChange(aRes
, 0, false);
3032 void SwWW8ImplReader::ReadAttrs(WW8_CP
& rNext
, WW8_CP
& rTxtPos
, bool& rbStartLine
)
3034 if( rTxtPos
>= rNext
)
3035 { // Stehen Attribute an ?
3039 rNext
= ReadTextAttr( rTxtPos
, rbStartLine
);
3041 while( rTxtPos
>= rNext
);
3044 else if ( rbStartLine
)
3046 // keine Attribute, aber trotzdem neue Zeile
3047 // wenn eine Zeile mit einem Seitenumbruch aufhoert und sich keine
3048 // Absatzattribute / Absatzvorlagen aendern, ist das Zeilenende
3049 // nicht im Plcx.Fkp.papx eingetragen, d.h. ( nFlags & MAN_MASK_NEW_PAP )
3050 // ist false. Deshalb muss als Sonderbehandlung hier die Vorlage gesetzt
3052 if (!bCpxStyle
&& nAktColl
< nColls
)
3053 SetTxtFmtCollAndListLevel(*pPaM
, pCollA
[nAktColl
]);
3054 rbStartLine
= false;
3058 // CloseAttrEnds zum Lesen nur der Attributenden am Ende eines Textes oder
3059 // Textbereiches ( Kopfzeile, Fussnote, ...). Attributanfaenge, Felder
3060 // werden ignoriert.
3061 void SwWW8ImplReader::CloseAttrEnds()
3063 //If there are any unclosed sprms then copy them to
3064 //another stack and close the ones that must be closed
3065 std::stack
<USHORT
> aStack
;
3066 pPlcxMan
->TransferOpenSprms(aStack
);
3068 while (!aStack
.empty())
3070 USHORT nSprmId
= aStack
.top();
3071 if ((0 < nSprmId
) && (( eFTN
> nSprmId
) || (0x0800 <= nSprmId
)))
3079 bool SwWW8ImplReader::ReadText(long nStartCp
, long nTextLen
, ManTypes nType
)
3081 sw::log::Environment eContext
= sw::log::eMainText
;
3082 if (nType
== MAN_MAINTEXT
)
3083 eContext
= sw::log::eMainText
;
3085 eContext
= sw::log::eSubDoc
;
3086 maTracer
.EnterEnvironment(eContext
);
3090 bool bStartLine
= true;
3092 short nDistance
= 0;
3094 bWasParaEnd
= false;
3099 bPgSecBreak
= false;
3101 pPlcxMan
= new WW8PLCFMan( pSBase
, nType
, nStartCp
);
3102 long nCpOfs
= pPlcxMan
->GetCpOfs(); // Offset fuer Header/Footer, Footnote
3104 WW8_CP nNext
= pPlcxMan
->Where();
3105 SwTxtNode
* pPreviousNode
= 0;
3106 BYTE nDropLines
= 0;
3107 SwCharFmt
* pNewSwCharFmt
= 0;
3108 const SwCharFmt
* pFmt
= 0;
3109 pStrm
->Seek( pSBase
->WW8Cp2Fc( nStartCp
+ nCpOfs
, &bIsUnicode
) );
3111 WW8_CP l
= nStartCp
;
3112 while ( l
<nStartCp
+nTextLen
)
3114 ReadAttrs( nNext
, l
, bStartLine
);// behandelt auch Section-Breaks
3115 ASSERT(pPaM
->GetNode()->GetTxtNode(), "Missing txtnode");
3117 if (mpPostProcessAttrsInfo
!= NULL
)
3120 if( l
>= nStartCp
+ nTextLen
)
3123 bStartLine
= ReadChars(l
, nNext
, nStartCp
+nTextLen
, nCpOfs
);
3125 // If the previous paragraph was a dropcap then do not
3126 // create a new txtnode and join the two paragraphs together
3128 if (bStartLine
&& !pPreviousNode
) // Zeilenende
3129 AppendTxtNode(*pPaM
->GetPoint());
3131 if (pPreviousNode
&& bStartLine
)
3133 SwTxtNode
* pEndNd
= pPaM
->GetNode()->GetTxtNode();
3134 const xub_StrLen nDropCapLen
= pPreviousNode
->GetTxt().Len();
3136 // Need to reset the font size and text position for the dropcap
3138 SwPaM
aTmp(*pEndNd
, 0, *pEndNd
, nDropCapLen
+1);
3139 pCtrlStck
->Delete(aTmp
);
3142 // Get the default document dropcap which we can use as our template
3143 const SwFmtDrop
* defaultDrop
=
3144 (const SwFmtDrop
*) GetFmtAttr(RES_PARATR_DROP
);
3145 SwFmtDrop
aDrop(*defaultDrop
);
3147 aDrop
.GetLines() = nDropLines
;
3148 aDrop
.GetDistance() = nDistance
;
3149 aDrop
.GetChars() = writer_cast
<BYTE
>(nDropCapLen
);
3150 // Word has no concept of a "whole word dropcap"
3151 aDrop
.GetWholeWord() = false;
3154 aDrop
.SetCharFmt(const_cast<SwCharFmt
*>(pFmt
));
3155 else if(pNewSwCharFmt
)
3156 aDrop
.SetCharFmt(const_cast<SwCharFmt
*>(pNewSwCharFmt
));
3158 SwPosition
aStart(*pEndNd
);
3159 pCtrlStck
->NewAttr(aStart
, aDrop
);
3160 pCtrlStck
->SetAttr(*pPaM
->GetPoint(), RES_PARATR_DROP
);
3165 // If we have found a dropcap store the textnode
3166 pPreviousNode
= pPaM
->GetNode()->GetTxtNode();
3171 pDCS
= pPlcxMan
->GetPapPLCF()->HasSprm(46);
3173 pDCS
= pPlcxMan
->GetPapPLCF()->HasSprm(0x442C);
3176 nDropLines
= (*pDCS
) >> 3;
3177 else // There is no Drop Cap Specifier hence no dropcap
3180 if (const BYTE
*pDistance
= pPlcxMan
->GetPapPLCF()->HasSprm(0x842F))
3181 nDistance
= SVBT16ToShort( pDistance
);
3185 const SwFmtCharFmt
*pSwFmtCharFmt
= 0;
3188 pSwFmtCharFmt
= &(ItemGet
<SwFmtCharFmt
>(*pAktItemSet
, RES_TXTATR_CHARFMT
));
3191 pFmt
= pSwFmtCharFmt
->GetCharFmt();
3193 if(pAktItemSet
&& !pFmt
)
3195 String
sPrefix(CREATE_CONST_ASC( "WW8Dropcap"));
3196 sPrefix
+= String::CreateFromInt32( nDropCap
++ );
3197 pNewSwCharFmt
= rDoc
.MakeCharFmt(sPrefix
, (SwCharFmt
*)rDoc
.GetDfltCharFmt());
3198 pAktItemSet
->ClearItem(RES_CHRATR_ESCAPEMENT
);
3199 pNewSwCharFmt
->SetFmtAttr( *pAktItemSet
);
3207 if (bStartLine
|| bWasTabRowEnd
)
3209 // alle 64 CRs aufrufen not for Header u. ae.
3210 if ((nCrCount
++ & 0x40) == 0 && nType
== MAN_MAINTEXT
)
3212 nProgress
= (USHORT
)( l
* 100 / nTextLen
);
3213 ::SetProgressState(nProgress
, mpDocShell
); // Update
3217 // If we have encountered a 0x0c which indicates either section of
3218 // pagebreak then look it up to see if it is a section break, and
3219 // if it is not then insert a page break. If it is a section break
3220 // it will be handled as such in the ReadAttrs of the next loop
3223 // We need only to see if a section is ending at this cp,
3224 // the plcf will already be sitting on the correct location
3227 aTemp
.nStartPos
= aTemp
.nEndPos
= WW8_CP_MAX
;
3228 if (pPlcxMan
->GetSepPLCF())
3229 pPlcxMan
->GetSepPLCF()->GetSprms(&aTemp
);
3230 if ((aTemp
.nStartPos
!= l
) && (aTemp
.nEndPos
!= l
))
3232 // --> OD 2005-01-07 #i39251# - insert text node for page break,
3233 // if no one inserted.
3234 // --> OD 2005-02-28 #i43118# - refine condition: the anchor
3235 // control stack has to have entries, otherwise it's not needed
3236 // to insert a text node.
3237 if ( !bStartLine
&& pAnchorStck
->Count() > 0 )
3239 AppendTxtNode(*pPaM
->GetPoint());
3242 rDoc
.Insert(*pPaM
, SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE
, RES_BREAK
), 0);
3243 bPgSecBreak
= false;
3248 if (pPaM
->GetPoint()->nContent
.GetIndex())
3249 AppendTxtNode(*pPaM
->GetPoint());
3252 bJoined
= JoinNode(*pPaM
);
3256 delete pPlcxMan
, pPlcxMan
= 0;
3257 maTracer
.LeaveEnvironment(eContext
);
3261 /***************************************************************************
3262 # class SwWW8ImplReader
3263 #**************************************************************************/
3265 SwWW8ImplReader::SwWW8ImplReader(BYTE nVersionPara
, SvStorage
* pStorage
,
3266 SvStream
* pSt
, SwDoc
& rD
, const String
& rBaseURL
, bool bNewDoc
) :
3267 mpDocShell(rD
.GetDocShell()),
3268 maTracer(*(mpDocShell
->GetMedium())),
3274 maSectionManager(*this),
3275 maInsertedTables(rD
),
3276 maSectionNameGenerator(rD
,CREATE_CONST_ASC("WW")),
3277 maGrfNameGenerator(bNewDoc
,String('G')),
3278 maParaStyleMapper(rD
),
3279 maCharStyleMapper(rD
),
3284 m_bRegardHindiDigits( false ),
3291 pStrm
->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
3292 nWantedVersion
= nVersionPara
;
3306 pDfltTxtFmtColl
= 0;
3307 pStandardFmtColl
= 0;
3311 pFlyFmtOfJustInsertedGraphic
= 0;
3312 pFmtOfJustInsertedApo
= 0;
3313 pPreviousNumPaM
= 0;
3315 nColls
= nAktColl
= 0;
3316 nObjLocFc
= nPicLocFc
= 0;
3318 bReadNoTbl
= bPgSecBreak
= bSpec
= bObj
= bTxbxFlySection
3319 = bHasBorder
= bSymbol
= bIgnoreText
3320 = bWasTabRowEnd
= bWasTabCellEnd
= false;
3321 bShdTxtCol
= bCharShdTxtCol
= bAnl
= bHdFtFtnEdn
= bFtnEdn
3322 = bIsHeader
= bIsFooter
= bIsUnicode
= bCpxStyle
= bStyNormal
=
3323 bWWBugNormal
= false;
3325 mpPostProcessAttrsInfo
= 0;
3327 bNoAttrImport
= bPgChpLevel
= bEmbeddObj
= false;
3328 bAktAND_fNumberAcross
= false;
3330 bInHyperlink
= false;
3331 bWasParaEnd
= false;
3334 bParaAutoBefore
= false;
3335 bParaAutoAfter
= false;
3337 nSwNumLevel
= nWwNumType
= 0xff;
3340 pNode_FLY_AT_CNTNT
= 0;
3343 mpDrawEditEngine
= 0;
3346 mpChosenOutlineNumRule
= 0;
3350 nLFOPosition
= USHRT_MAX
;
3351 nListLevel
= WW8ListManager::nMaxLevel
;
3352 eHardCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3354 nPgChpDelim
= nPgChpLevel
= 0;
3356 maApos
.push_back(false);
3359 void SwWW8ImplReader::DeleteStk(SwFltControlStack
* pStck
)
3363 pStck
->SetAttr( *pPaM
->GetPoint(), 0, false);
3364 pStck
->SetAttr( *pPaM
->GetPoint(), 0, false);
3369 ASSERT( !this, "WW-Stack bereits geloescht" );
3373 void wwSectionManager::SetSegmentToPageDesc(const wwSection
&rSection
,
3374 bool bTitlePage
, bool bIgnoreCols
)
3376 SwPageDesc
&rPage
= bTitlePage
? *rSection
.mpTitlePage
: *rSection
.mpPage
;
3378 SetNumberingType(rSection
, rPage
);
3380 SwFrmFmt
&rFmt
= rPage
.GetMaster();
3382 if (mrReader
.pWDop
->fUseBackGroundInAllmodes
&& mrReader
.pMSDffManager
)
3384 Rectangle
aRect(0, 0, 100, 100); //A dummy, we don't care about the size
3385 SvxMSDffImportData
aData(aRect
);
3386 SdrObject
* pObject
= 0;
3387 if (mrReader
.pMSDffManager
->GetShape(0x401, pObject
, aData
))
3389 SvxMSDffImportRec
* pRec
= aData
.GetRecord(0);
3391 // Only handle shape if it is a background shape
3392 if ((pRec
->nFlags
& 0x400) != 0)
3394 SfxItemSet
aSet(rFmt
.GetAttrSet());
3395 mrReader
.MatchSdrItemsIntoFlySet(pObject
, aSet
, mso_lineSimple
,
3396 mso_sptRectangle
, aRect
);
3397 rFmt
.SetFmtAttr(aSet
.Get(RES_BACKGROUND
));
3401 wwULSpaceData aULData
;
3402 GetPageULData(rSection
, bTitlePage
, aULData
);
3403 SetPageULSpaceItems(rFmt
, aULData
, rSection
);
3405 SetPage(rPage
, rFmt
, rSection
, bIgnoreCols
);
3407 bool bSetBorder
= false;
3408 switch (rSection
.maSep
.pgbApplyTo
)
3415 bSetBorder
= bTitlePage
;
3418 bSetBorder
= !bTitlePage
;
3422 mrReader
.SetPageBorder(rFmt
, rSection
);
3424 mrReader
.SetDocumentGrid(rFmt
, rSection
);
3427 void wwSectionManager::SetUseOn(wwSection
&rSection
)
3429 bool bEven
= (rSection
.maSep
.grpfIhdt
& (WW8_HEADER_EVEN
|WW8_FOOTER_EVEN
)) ?
3432 bool bMirror
= mrReader
.pWDop
->fMirrorMargins
||
3433 mrReader
.pWDop
->doptypography
.f2on1
;
3435 UseOnPage eUseBase
= bMirror
? nsUseOnPage::PD_MIRROR
: nsUseOnPage::PD_ALL
;
3436 UseOnPage eUse
= eUseBase
;
3438 eUse
= (UseOnPage
)(eUse
| nsUseOnPage::PD_HEADERSHARE
| nsUseOnPage::PD_FOOTERSHARE
);
3440 ASSERT(rSection
.mpPage
, "Makes no sense to call me with no pages to set");
3441 if (rSection
.mpPage
)
3442 rSection
.mpPage
->WriteUseOn(eUse
);
3443 if (rSection
.mpTitlePage
)
3445 rSection
.mpTitlePage
->WriteUseOn(
3446 (UseOnPage
) (eUseBase
| nsUseOnPage::PD_HEADERSHARE
| nsUseOnPage::PD_FOOTERSHARE
));
3450 //Set the page descriptor on this node, handle the different cases for a text
3452 void GiveNodePageDesc(SwNodeIndex
&rIdx
, const SwFmtPageDesc
&rPgDesc
,
3456 If its a table here, apply the pagebreak to the table
3457 properties, otherwise we add it to the para at this
3460 if (rIdx
.GetNode().IsTableNode())
3463 rIdx
.GetNode().GetTableNode()->GetTable();
3464 SwFrmFmt
* pApply
= rTable
.GetFrmFmt();
3465 ASSERT(pApply
, "impossible");
3467 pApply
->SetFmtAttr(rPgDesc
);
3471 SwPosition
aPamStart(rIdx
);
3472 aPamStart
.nContent
.Assign(
3473 rIdx
.GetNode().GetCntntNode(), 0);
3474 SwPaM
aPage(aPamStart
);
3476 rDoc
.Insert(aPage
, rPgDesc
, 0);
3480 //Map a word section with to either one or two writer page descriptors
3481 //depending on if the word section has a title page
3482 SwFmtPageDesc
wwSectionManager::SetSwFmtPageDesc(mySegIter
&rIter
,
3483 mySegIter
&rStart
, bool bIgnoreCols
)
3485 SwFmtPageDesc aEmpty
;
3486 // --> OD 2008-08-06 #150965#
3487 // Always read title page header/footer data - it could be used by following sections
3488 // if (rIter->HasTitlePage())
3491 if (IsNewDoc() && rIter
== rStart
)
3493 rIter
->mpTitlePage
=
3494 mrReader
.rDoc
.GetPageDescFromPool(RES_POOLPAGE_FIRST
);
3498 USHORT nPos
= mrReader
.rDoc
.MakePageDesc(
3499 ViewShell::GetShellRes()->GetPageDescName(mnDesc
)
3501 rIter
->mpTitlePage
= &mrReader
.rDoc
._GetPageDesc(nPos
);
3503 ASSERT(rIter
->mpTitlePage
, "no page!");
3504 if (!rIter
->mpTitlePage
)
3507 SetSegmentToPageDesc(*rIter
, true, bIgnoreCols
);
3510 if (IsNewDoc() && rIter
== rStart
)
3513 mrReader
.rDoc
.GetPageDescFromPool(RES_POOLPAGE_STANDARD
);
3517 USHORT nPos
= mrReader
.rDoc
.MakePageDesc(
3518 ViewShell::GetShellRes()->GetPageDescName(mnDesc
,
3519 false, rIter
->HasTitlePage()),
3520 rIter
->mpTitlePage
, false);
3521 rIter
->mpPage
= &mrReader
.rDoc
._GetPageDesc(nPos
);
3523 ASSERT(rIter
->mpPage
, "no page!");
3527 //Set page before hd/ft
3528 const wwSection
*pPrevious
= 0;
3529 if (rIter
!= rStart
)
3530 pPrevious
= &(*(rIter
-1));
3531 SetHdFt(*rIter
, std::distance(rStart
, rIter
), pPrevious
);
3534 //Set hd/ft after set page
3535 if (rIter
->mpTitlePage
)
3536 SetSegmentToPageDesc(*rIter
, true, bIgnoreCols
);
3537 SetSegmentToPageDesc(*rIter
, false, bIgnoreCols
);
3539 SwFmtPageDesc
aRet(rIter
->HasTitlePage() ?
3540 rIter
->mpTitlePage
: rIter
->mpPage
);
3542 rIter
->mpPage
->SetFollow(rIter
->mpPage
);
3544 if (rIter
->mpTitlePage
)
3545 rIter
->mpTitlePage
->SetFollow(rIter
->mpPage
);
3547 if (rIter
->PageRestartNo())
3548 aRet
.SetNumOffset(rIter
->PageStartAt());
3554 bool wwSectionManager::IsNewDoc() const
3556 return mrReader
.mbNewDoc
;
3559 void wwSectionManager::InsertSegments()
3561 const SvtFilterOptions
* pOpt
= SvtFilterOptions::Get();
3562 sal_Bool bUseEnhFields
=(pOpt
&& pOpt
->IsUseEnhancedFields());
3563 mySegIter aEnd
= maSegments
.end();
3564 mySegIter aStart
= maSegments
.begin();
3565 for (mySegIter aIter
= aStart
; aIter
!= aEnd
; ++aIter
)
3567 mySegIter aNext
= aIter
+1;
3568 mySegIter aPrev
= (aIter
== aStart
) ? aIter
: aIter
-1;
3570 // If two following sections are different in following properties, Word will interprete a continuous
3571 // section break between them as if it was a section break next page.
3572 bool bThisAndPreviousAreCompatible
= ((aIter
->GetPageWidth() == aPrev
->GetPageWidth()) &&
3573 (aIter
->GetPageHeight() == aPrev
->GetPageHeight()) && (aIter
->IsLandScape() == aPrev
->IsLandScape()));
3575 bool bInsertSection
= (aIter
!= aStart
) ? (aIter
->IsContinous() && bThisAndPreviousAreCompatible
): false;
3576 bool bInsertPageDesc
= !bInsertSection
;
3577 bool bProtected
= SectionIsProtected(*aIter
); // do we really need this ?? I guess I have a different logic in editshell which disales this...
3578 if (bUseEnhFields
&& mrReader
.pWDop
->fProtEnabled
&& aIter
->IsNotProtected()) {
3579 // here we have the special case that the whole document is protected, with the execption of this section.
3580 // I want to address this when I do the section rework, so for the moment we disable the overall protection then...
3581 mrReader
.rDoc
.set(IDocumentSettingAccess::PROTECT_FORM
, false );
3585 if (bInsertPageDesc
)
3588 If a cont section follows this section then we won't be
3589 creating a page desc with 2+ cols as we cannot host a one
3590 col section in a 2+ col pagedesc and make it look like
3591 word. But if the current section actually has columns then
3592 we are forced to insert a section here as well as a page
3596 bool bIgnoreCols
= false;
3597 bool bThisAndNextAreCompatible
= (aNext
!= aEnd
) ? ((aIter
->GetPageWidth() == aNext
->GetPageWidth()) &&
3598 (aIter
->GetPageHeight() == aNext
->GetPageHeight()) && (aIter
->IsLandScape() == aNext
->IsLandScape())) : true;
3600 if ((aNext
!= aEnd
&& aNext
->IsContinous() && bThisAndNextAreCompatible
) || bProtected
)
3603 if ((aIter
->NoCols() > 1) || bProtected
)
3604 bInsertSection
= true;
3607 SwFmtPageDesc
aDesc(SetSwFmtPageDesc(aIter
, aStart
, bIgnoreCols
));
3608 if (!aDesc
.GetPageDesc())
3610 GiveNodePageDesc(aIter
->maStart
, aDesc
, mrReader
.rDoc
);
3613 SwTxtNode
* pTxtNd
= 0;
3616 //Start getting the bounds of this section
3617 SwPaM
aSectPaM(*mrReader
.pPaM
);
3618 SwNodeIndex
aAnchor(aSectPaM
.GetPoint()->nNode
);
3621 aAnchor
= aNext
->maStart
;
3622 aSectPaM
.GetPoint()->nNode
= aAnchor
;
3623 aSectPaM
.GetPoint()->nContent
.Assign(
3624 aNext
->maStart
.GetNode().GetCntntNode(), 0);
3625 aSectPaM
.Move(fnMoveBackward
);
3628 const SwPosition
* pPos
= aSectPaM
.GetPoint();
3629 const SwTxtNode
* pSttNd
=
3630 mrReader
.rDoc
.GetNodes()[ pPos
->nNode
]->GetTxtNode();
3631 const SwTableNode
* pTableNd
= pSttNd
? pSttNd
->FindTableNode() : 0;
3635 mrReader
.rDoc
.GetNodes().MakeTxtNode(aAnchor
,
3636 mrReader
.rDoc
.GetTxtCollFromPool( RES_POOLCOLL_TEXT
));
3638 aSectPaM
.GetPoint()->nNode
= SwNodeIndex(*pTxtNd
);
3639 aSectPaM
.GetPoint()->nContent
.Assign(
3640 aSectPaM
.GetCntntNode(), 0);
3645 aSectPaM
.GetPoint()->nNode
= aIter
->maStart
;
3646 aSectPaM
.GetPoint()->nContent
.Assign(
3647 aSectPaM
.GetCntntNode(), 0);
3648 //End getting the bounds of this section, quite a job eh ?
3650 SwSectionFmt
*pRet
= InsertSection(aSectPaM
, *aIter
);
3651 //The last section if continous is always unbalanced
3654 //Set the columns to be UnBalanced if that compatability option
3656 if (mrReader
.pWDop
->fNoColumnBalance
)
3657 pRet
->SetFmtAttr(SwFmtNoBalancedColumns(true));
3660 //Otherwise set to unbalanced if the following section is
3661 //not continuous, (which also means that the last section
3663 if (aNext
== aEnd
|| !aNext
->IsContinous())
3664 pRet
->SetFmtAttr(SwFmtNoBalancedColumns(true));
3668 bool bHasOwnHdFt
= false;
3671 In this nightmare scenario the continuous section has its own
3672 headers and footers so we will try and find a hard page break
3673 between here and the end of the section and put the headers and
3676 if (!bInsertPageDesc
)
3679 mrReader
.HasOwnHeaderFooter(
3680 aIter
->maSep
.grpfIhdt
& ~(WW8_HEADER_FIRST
| WW8_FOOTER_FIRST
),
3681 aIter
->maSep
.grpfIhdt
, std::distance(aStart
, aIter
)
3686 // #i40766# Need to cache the page descriptor in case there is
3687 // no page break in the section
3688 SwPageDesc
*pOrig
= aIter
->mpPage
;
3689 SwPageDesc
*pOrigTitle
= aIter
->mpTitlePage
;
3690 bool bFailed
= true;
3691 SwFmtPageDesc
aDesc(SetSwFmtPageDesc(aIter
, aStart
, true));
3692 if (aDesc
.GetPageDesc())
3694 ULONG nStart
= aSectPaM
.Start()->nNode
.GetIndex();
3695 ULONG nEnd
= aSectPaM
.End()->nNode
.GetIndex();
3696 for(; nStart
<= nEnd
; ++nStart
)
3698 SwNode
* pNode
= mrReader
.rDoc
.GetNodes()[nStart
];
3701 if (sw::util::HasPageBreak(*pNode
))
3703 SwNodeIndex
aIdx(*pNode
);
3704 GiveNodePageDesc(aIdx
, aDesc
, mrReader
.rDoc
);
3712 aIter
->mpPage
= pOrig
;
3713 aIter
->mpTitlePage
= pOrigTitle
;
3720 SwNodeIndex
aIdx(*pTxtNd
);
3721 SwPosition
aPos(aIdx
);
3723 mrReader
.rDoc
.DelFullPara(aTest
);
3729 void SwWW8ImplReader::StoreMacroCmds()
3731 if (pWwFib
->lcbCmds
)
3733 maTracer
.Log(sw::log::eContainsWordBasic
);
3735 pTableStream
->Seek(pWwFib
->fcCmds
);
3737 uno::Reference
< embed::XStorage
> xRoot(mpDocShell
->GetStorage());
3740 uno::Reference
< io::XStream
> xStream
=
3741 xRoot
->openStreamElement( CREATE_CONST_ASC(SL::aMSMacroCmds
), embed::ElementModes::READWRITE
);
3742 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream( xStream
);
3744 sal_uInt8
*pBuffer
= new sal_uInt8
[pWwFib
->lcbCmds
];
3745 pTableStream
->Read(pBuffer
, pWwFib
->lcbCmds
);
3746 pStream
->Write(pBuffer
, pWwFib
->lcbCmds
);
3750 catch ( uno::Exception
& )
3756 void SwWW8ImplReader::ReadDocVars()
3758 std::vector
<String
> aDocVarStrings
;
3759 std::vector
<ww::bytes
> aDocVarStringIds
;
3760 std::vector
<String
> aDocValueStrings
;
3761 WW8ReadSTTBF(!bVer67
, *pTableStream
, pWwFib
->fcStwUser
,
3762 pWwFib
->lcbStwUser
, bVer67
? 2 : 0, eStructCharSet
,
3763 aDocVarStrings
, &aDocVarStringIds
, &aDocValueStrings
);
3765 using namespace ::com::sun::star
;
3767 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
3768 mpDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
3769 uno::Reference
<document::XDocumentProperties
> xDocProps(
3770 xDPS
->getDocumentProperties());
3771 DBG_ASSERT(xDocProps
.is(), "DocumentProperties is null");
3772 uno::Reference
<beans::XPropertyContainer
> xUserDefinedProps
=
3773 xDocProps
->getUserDefinedProperties();
3774 DBG_ASSERT(xUserDefinedProps
.is(), "UserDefinedProperties is null");
3776 for(size_t i
=0; i
<aDocVarStrings
.size(); i
++)
3778 uno::Any aDefaultValue
;
3779 ::rtl::OUString
name(aDocVarStrings
[i
]);
3781 aValue
<<= ::rtl::OUString(aDocValueStrings
[i
]);
3783 xUserDefinedProps
->addProperty( name
,
3784 beans::PropertyAttribute::REMOVEABLE
,
3786 } catch (uno::Exception
&) {
3793 //-----------------------------------------
3795 //-----------------------------------------
3797 void SwWW8ImplReader::ReadDocInfo()
3801 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
3802 mpDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
3803 uno::Reference
<document::XDocumentProperties
> xDocProps(
3804 xDPS
->getDocumentProperties());
3805 DBG_ASSERT(xDocProps
.is(), "DocumentProperties is null");
3807 if (xDocProps
.is()) {
3810 rtl::OUString sTemplateURL
;
3811 SfxMedium
* pMedium
= mpDocShell
->GetMedium();
3814 rtl::OUString aName
= pMedium
->GetName();
3815 INetURLObject
aURL( aName
);
3816 sTemplateURL
= aURL
.GetMainURL(INetURLObject::DECODE_TO_IURI
);
3817 if ( sTemplateURL
.getLength() > 0 )
3818 xDocProps
->setTemplateURL( sTemplateURL
);
3821 else // not a template
3823 long nCur
= pTableStream
->Tell();
3825 pTableStream
->Seek( pWwFib
->fcSttbfAssoc
); // point at tgc record
3826 if (!aSttb
.Read( pTableStream
) )
3827 OSL_TRACE("** Read of SttbAssoc data failed!!!! ");
3828 pTableStream
->Seek( nCur
); // return to previous position, is that necessary?
3830 aSttb
.Print( stderr
);
3832 String sPath
= aSttb
.getStringAtIndex( 0x1 );
3834 // attempt to convert to url ( won't work for obvious reasons on linux
3836 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPath
, aURL
);
3838 xDocProps
->setTemplateURL( aURL
);
3840 xDocProps
->setTemplateURL( sPath
);
3843 sfx2::LoadOlePropertySet(xDocProps
, pStg
);
3848 void lcl_createTemplateToProjectEntry( const uno::Reference
< container::XNameContainer
>& xPrjNameCache
, const rtl::OUString
& sTemplatePathOrURL
, const rtl::OUString
& sVBAProjName
)
3850 if ( xPrjNameCache
.is() )
3853 aObj
.SetURL( sTemplatePathOrURL
);
3854 bool bIsURL
= aObj
.GetProtocol() != INET_PROT_NOT_VALID
;
3857 aURL
= sTemplatePathOrURL
;
3860 osl::FileBase::getFileURLFromSystemPath( sTemplatePathOrURL
, aURL
);
3861 aObj
.SetURL( aURL
);
3865 rtl::OUString templateNameWithExt
= aObj
.GetLastName();
3866 rtl::OUString templateName
;
3867 sal_Int32 nIndex
= templateNameWithExt
.lastIndexOf( '.' );
3868 //xPrjNameCache->insertByName( templateNameWithExt, uno::makeAny( sVBAProjName ) );
3871 templateName
= templateNameWithExt
.copy( 0, nIndex
);
3872 xPrjNameCache
->insertByName( templateName
, uno::makeAny( sVBAProjName
) );
3875 catch( uno::Exception
& )
3881 class WW8Customizations
3883 SvStream
* mpTableStream
;
3886 WW8Customizations( SvStream
*, WW8Fib
& );
3887 bool Import( SwDocShell
* pShell
);
3890 WW8Customizations::WW8Customizations( SvStream
* pTableStream
, WW8Fib
& rFib
) : mpTableStream(pTableStream
), mWw8Fib( rFib
)
3894 bool WW8Customizations::Import( SwDocShell
* pShell
)
3896 if ( mWw8Fib
.lcbCmds
== 0 )
3899 long nCur
= mpTableStream
->Tell();
3900 mpTableStream
->Seek( mWw8Fib
.fcCmds
); // point at tgc record
3901 if (!aTCG
.Read( mpTableStream
) )
3902 OSL_TRACE("** Read of Customization data failed!!!! ");
3903 mpTableStream
->Seek( nCur
); // return to previous position, is that necessary?
3905 aTCG
.Print( stderr
);
3907 return aTCG
.ImportCustomToolBar( *pShell
);
3910 bool SwWW8ImplReader::ReadGlobalTemplateSettings( const rtl::OUString
& sCreatedFrom
, const uno::Reference
< container::XNameContainer
>& xPrjNameCache
)
3912 SvtPathOptions aPathOpt
;
3913 String aAddinPath
= aPathOpt
.GetAddinPath();
3914 uno::Sequence
< rtl::OUString
> sGlobalTemplates
;
3916 // first get the autoload addins in the directory STARTUP
3917 uno::Reference
< ucb::XSimpleFileAccess
> xSFA( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY_THROW
);
3919 if( xSFA
->isFolder( aAddinPath
) )
3920 sGlobalTemplates
= xSFA
->getFolderContents( aAddinPath
, sal_False
);
3922 sal_Int32 nEntries
= sGlobalTemplates
.getLength();
3924 const SvtFilterOptions
* pVBAFlags
= SvtFilterOptions::Get();
3925 for ( sal_Int32 i
=0; i
<nEntries
; ++i
)
3928 aObj
.SetURL( sGlobalTemplates
[ i
] );
3929 bool bIsURL
= aObj
.GetProtocol() != INET_PROT_NOT_VALID
;
3932 aURL
= sGlobalTemplates
[ i
];
3934 osl::FileBase::getFileURLFromSystemPath( sGlobalTemplates
[ i
], aURL
);
3935 if ( !aURL
.endsWithIgnoreAsciiCaseAsciiL( ".dot", 4 ) || ( sCreatedFrom
.getLength() && sCreatedFrom
.equals( aURL
) ) )
3936 continue; // don't try and read the same document as ourselves
3938 SotStorageRef rRoot
= new SotStorage( aURL
, STREAM_STD_READWRITE
, STORAGE_TRANSACTED
);
3940 // Read Macro Projects
3941 SvxImportMSVBasic
aVBasic(*mpDocShell
, *rRoot
,
3942 pVBAFlags
->IsLoadWordBasicCode(),
3943 pVBAFlags
->IsLoadWordBasicStorage() );
3946 String
s1(CREATE_CONST_ASC("Macros"));
3947 String
s2(CREATE_CONST_ASC("VBA"));
3948 int nRet
= aVBasic
.Import( s1
, s2
, ! pVBAFlags
->IsLoadWordBasicCode() );
3949 lcl_createTemplateToProjectEntry( xPrjNameCache
, aURL
, aVBasic
.GetVBAProjectName() );
3950 // Read toolbars & menus
3951 SvStorageStreamRef refMainStream
= rRoot
->OpenSotStream( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WordDocument") ) );
3952 refMainStream
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
3953 WW8Fib
aWwFib( *refMainStream
, 8 );
3954 SvStorageStreamRef xTableStream
= rRoot
->OpenSotStream(String::CreateFromAscii( aWwFib
.fWhichTblStm
? SL::a1Table
: SL::a0Table
), STREAM_STD_READ
);
3956 if (xTableStream
.Is() && SVSTREAM_OK
== xTableStream
->GetError())
3958 xTableStream
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
3959 WW8Customizations
aGblCustomisations( xTableStream
, aWwFib
);
3960 aGblCustomisations
.Import( mpDocShell
);
3966 ULONG
SwWW8ImplReader::CoreLoad(WW8Glossary
*pGloss
, const SwPosition
&rPos
)
3970 if (mbNewDoc
&& pStg
&& !pGloss
)
3973 pPaM
= new SwPaM(rPos
);
3975 pCtrlStck
= new SwWW8FltControlStack( &rDoc
, nFieldFlags
, *this );
3977 mpRedlineStack
= new sw::util::RedlineStack(rDoc
);
3980 RefFldStck: Keeps track of bookmarks which may be inserted as
3983 pReffedStck
= new SwFltEndStack(&rDoc
, nFieldFlags
);
3984 pReffingStck
= new SwWW8FltRefStack(&rDoc
, nFieldFlags
);
3986 pAnchorStck
= new SwWW8FltAnchorStack(&rDoc
, nFieldFlags
);
3988 sal_uInt16 nPageDescOffset
= rDoc
.GetPageDescCnt();
3990 SwNodeIndex
aSttNdIdx( rDoc
.GetNodes() );
3991 SwRelNumRuleSpaces
aRelNumRule(rDoc
, mbNewDoc
);
3993 USHORT eMode
= nsRedlineMode_t::REDLINE_SHOW_INSERT
;
3995 mpSprmParser
= new wwSprmParser(pWwFib
->GetFIBVersion());
3997 // praktische Hilfsvariablen besetzen:
3998 bVer6
= (6 == pWwFib
->nVersion
);
3999 bVer7
= (7 == pWwFib
->nVersion
);
4000 bVer67
= bVer6
|| bVer7
;
4001 bVer8
= (8 == pWwFib
->nVersion
);
4003 eTextCharSet
= WW8Fib::GetFIBCharset(pWwFib
->chse
);
4004 eStructCharSet
= WW8Fib::GetFIBCharset(pWwFib
->chseTables
);
4006 bWWBugNormal
= pWwFib
->nProduct
== 0xc03d;
4009 aSttNdIdx
= pPaM
->GetPoint()->nNode
;
4011 ::StartProgress(STR_STATSTR_W4WREAD
, 0, 100, mpDocShell
);
4014 //experimental embedded ttf dumper
4015 if (pWwFib
->lcbSttbttmbd
&& (7 < pWwFib
->nVersion
))
4017 pTableStream
->Seek(pWwFib
->fcSttbttmbd
);
4019 *pTableStream
>> nZeros
;
4020 sal_uInt16 nNoEntries
;
4021 *pTableStream
>> nNoEntries
;
4022 sal_uInt32 nUnknown1
;
4023 *pTableStream
>> nUnknown1
;
4024 sal_uInt16 nUnknown2
;
4025 *pTableStream
>> nUnknown2
;
4026 std::vector
<sal_uInt32
> aOffsets
;
4027 for (sal_uInt16 nI
= 0; nI
< nNoEntries
; ++nI
)
4030 *pTableStream
>> nOffset
;
4031 aOffsets
.push_back(nOffset
);
4032 sal_uInt32 nUnknown3
;
4033 *pTableStream
>> nUnknown3
;
4034 sal_uInt32 nUnknown4
;
4035 *pTableStream
>> nUnknown4
;
4037 typedef std::vector
<sal_uInt32
>::iterator myIter
;
4038 myIter aEnd
= aOffsets
.end();
4039 myIter aIter
= aOffsets
.begin();
4040 while (aIter
!= aEnd
)
4042 sal_uInt32 nOffset
= *aIter
;
4043 sal_uInt32 nLen
= STREAM_SEEK_TO_END
;
4045 pStrm
->Seek(nOffset
);
4047 nLen
= *aIter
- nOffset
;
4048 SvStream
*pDbg
= sw::hack::CreateDebuggingStream(CREATE_CONST_ASC(".ttf.dump"));
4049 sw::hack::DumpStream(*pStrm
, *pDbg
, nLen
);
4056 pFonts
= new WW8Fonts( *pTableStream
, *pWwFib
);
4058 // Document Properties
4059 pWDop
= new WW8Dop( *pTableStream
, pWwFib
->nFib
, pWwFib
->fcDop
,
4066 Import revisioning data: author names
4068 if( pWwFib
->lcbSttbfRMark
)
4070 ReadRevMarkAuthorStrTabl( *pTableStream
,
4071 pWwFib
->fcSttbfRMark
,
4072 pWwFib
->lcbSttbfRMark
, rDoc
);
4075 // M.M. Initialize our String/ID map for Linked Sections
4076 std::vector
<String
> aLinkStrings
;
4077 std::vector
<ww::bytes
> aStringIds
;
4079 WW8ReadSTTBF(!bVer67
, *pTableStream
, pWwFib
->fcSttbFnm
,
4080 pWwFib
->lcbSttbFnm
, bVer67
? 2 : 0, eStructCharSet
,
4081 aLinkStrings
, &aStringIds
);
4083 for (size_t i
=0; i
< aLinkStrings
.size(); ++i
)
4085 ww::bytes stringId
= aStringIds
[i
];
4086 WW8_STRINGID
*stringIdStruct
= (WW8_STRINGID
*)(&stringId
[0]);
4087 aLinkStringMap
[SVBT16ToShort(stringIdStruct
->nStringId
)] =
4091 ReadDocVars(); // #129053# import document variables as meta information.
4093 ::SetProgressState(nProgress
, mpDocShell
); // Update
4095 pLstManager
= new WW8ListManager( *pTableStream
, *this );
4098 zuerst(!) alle Styles importieren (siehe WW8PAR2.CXX)
4099 VOR dem Import der Listen !!
4101 ::SetProgressState(nProgress
, mpDocShell
); // Update
4102 pStyles
= new WW8RStyle( *pWwFib
, this ); // Styles
4106 zu guter Letzt: (siehe ebenfalls WW8PAR3.CXX)
4108 alle Styles durchgehen und ggfs. zugehoeriges Listen-Format
4109 anhaengen NACH dem Import der Styles und NACH dem Import der
4112 ::SetProgressState(nProgress
, mpDocShell
); // Update
4113 pStyles
->PostProcessStyles();
4118 pSBase
= new WW8ScannerBase(pStrm
,pTableStream
,pDataStream
,pWwFib
);
4120 static const SvxExtNumType eNumTA
[16] =
4122 SVX_NUM_ARABIC
, SVX_NUM_ROMAN_UPPER
, SVX_NUM_ROMAN_LOWER
,
4123 SVX_NUM_CHARS_UPPER_LETTER_N
, SVX_NUM_CHARS_LOWER_LETTER_N
,
4124 SVX_NUM_ARABIC
, SVX_NUM_ARABIC
, SVX_NUM_ARABIC
,
4125 SVX_NUM_ARABIC
, SVX_NUM_ARABIC
, SVX_NUM_ARABIC
,
4126 SVX_NUM_ARABIC
, SVX_NUM_ARABIC
, SVX_NUM_ARABIC
,
4127 SVX_NUM_ARABIC
, SVX_NUM_ARABIC
4130 if (pSBase
->AreThereFootnotes())
4132 static const SwFtnNum eNumA
[4] =
4134 FTNNUM_DOC
, FTNNUM_CHAPTER
, FTNNUM_PAGE
, FTNNUM_DOC
4138 aInfo
= rDoc
.GetFtnInfo(); // Copy-Ctor privat
4140 aInfo
.ePos
= FTNPOS_PAGE
;
4141 aInfo
.eNum
= eNumA
[pWDop
->rncFtn
];
4142 aInfo
.aFmt
.SetNumberingType( static_cast< sal_uInt16
>(eNumTA
[pWDop
->nfcFtnRef
]) );
4144 aInfo
.nFtnOffset
= pWDop
->nFtn
- 1;
4145 rDoc
.SetFtnInfo( aInfo
);
4147 if( pSBase
->AreThereEndnotes() )
4149 SwEndNoteInfo aInfo
;
4150 aInfo
= rDoc
.GetEndNoteInfo(); // parallel zu Ftn
4152 // Ich kann nicht setzen, wann neu nummerieren...
4153 // aInfo.eNum = eNumA[pWDop->pDop->rncEdn];
4154 aInfo
.aFmt
.SetNumberingType( static_cast< sal_uInt16
>(eNumTA
[pWDop
->nfcEdnRef
]) );
4156 aInfo
.nFtnOffset
= pWDop
->nEdn
- 1;
4157 rDoc
.SetEndNoteInfo( aInfo
);
4160 if( pWwFib
->lcbPlcfhdd
)
4161 pHdFt
= new WW8PLCF_HdFt( pTableStream
, *pWwFib
, *pWDop
);
4165 // in ein Dokument einfuegen ?
4166 // Da immer ganze Zeile eingelesen werden, muessen
4167 // evtl. Zeilen eingefuegt / aufgebrochen werden
4169 const SwPosition
* pPos
= pPaM
->GetPoint();
4170 const SwTxtNode
* pSttNd
=
4171 rDoc
.GetNodes()[ pPos
->nNode
]->GetTxtNode();
4173 USHORT nCntPos
= pPos
->nContent
.GetIndex();
4175 // EinfuegePos nicht in leerer Zeile
4176 if( nCntPos
&& pSttNd
->GetTxt().Len() )
4177 rDoc
.SplitNode( *pPos
, false ); // neue Zeile erzeugen
4179 if( pSttNd
->GetTxt().Len() )
4180 { // EinfuegePos nicht am Ende der Zeile
4181 rDoc
.SplitNode( *pPos
, false ); // neue Zeile
4182 pPaM
->Move( fnMoveBackward
); // gehe in leere Zeile
4185 // verhinder das Einlesen von Tabellen in Fussnoten / Tabellen
4186 ULONG nNd
= pPos
->nNode
.GetIndex();
4187 bReadNoTbl
= 0 != pSttNd
->FindTableNode() ||
4188 ( nNd
< rDoc
.GetNodes().GetEndOfInserts().GetIndex() &&
4189 rDoc
.GetNodes().GetEndOfInserts().StartOfSectionIndex()
4194 ::SetProgressState(nProgress
, mpDocShell
); // Update
4196 // loop for each glossary entry and add dummy section node
4199 WW8PLCF
aPlc(pTableStream
, pWwFib
->fcPlcfglsy
, pWwFib
->lcbPlcfglsy
, 0);
4201 WW8_CP nStart
, nEnd
;
4204 for (int i
=0;i
<pGloss
->GetNoStrings();i
++,aPlc
++)
4206 SwNodeIndex
aIdx( rDoc
.GetNodes().GetEndOfContent());
4207 SwTxtFmtColl
* pColl
=
4208 rDoc
.GetTxtCollFromPool(RES_POOLCOLL_STANDARD
,
4210 SwStartNode
*pNode
=
4211 rDoc
.GetNodes().MakeTextSection(aIdx
,
4212 SwNormalStartNode
,pColl
);
4213 pPaM
->GetPoint()->nNode
= pNode
->GetIndex()+1;
4214 pPaM
->GetPoint()->nContent
.Assign(pPaM
->GetCntntNode(),0);
4215 aPlc
.Get( nStart
, nEnd
, pDummy
);
4216 ReadText(nStart
,nEnd
-nStart
-1,MAN_MAINTEXT
);
4219 else //ordinary case
4221 if (mbNewDoc
&& pStg
&& !pGloss
) /*meaningless for a glossary, cmc*/
4223 mpDocShell
->SetIsTemplate( pWwFib
->fDot
); // point at tgc record
4224 const SvtFilterOptions
* pVBAFlags
= SvtFilterOptions::Get();
4225 maTracer
.EnterEnvironment(sw::log::eMacros
);
4226 // dissable below for 3.1 at the moment, 'cause it's kinda immature
4227 // similarly the project reference in svx/source/msvba
4229 uno::Reference
< document::XDocumentInfoSupplier
> xDocInfoSupp( mpDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
4230 uno::Reference
< document::XDocumentPropertiesSupplier
> xDocPropSupp( xDocInfoSupp
->getDocumentInfo(), uno::UNO_QUERY_THROW
);
4231 uno::Reference
< document::XDocumentProperties
> xDocProps( xDocPropSupp
->getDocumentProperties(), uno::UNO_QUERY_THROW
);
4233 rtl::OUString sCreatedFrom
= xDocProps
->getTemplateURL();
4234 uno::Reference
< container::XNameContainer
> xPrjNameCache
;
4235 uno::Reference
< lang::XMultiServiceFactory
> xSF(mpDocShell
->GetModel(), uno::UNO_QUERY
);
4237 xPrjNameCache
.set( xSF
->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAProjectNameProvider" ) ) ), uno::UNO_QUERY
);
4239 // Read Global templates
4240 ReadGlobalTemplateSettings( sCreatedFrom
, xPrjNameCache
);
4242 // Create and insert Word vba Globals
4244 uno::Sequence
< uno::Any
> aArgs(1);
4245 aArgs
[ 0 ] <<= mpDocShell
->GetModel();
4246 aGlobs
<<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "ooo.vba.word.Globals"), aArgs
);
4247 mpDocShell
->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs
);
4249 SvxImportMSVBasic
aVBasic(*mpDocShell
, *pStg
,
4250 pVBAFlags
->IsLoadWordBasicCode(),
4251 pVBAFlags
->IsLoadWordBasicStorage() );
4252 String
s1(CREATE_CONST_ASC("Macros"));
4253 String
s2(CREATE_CONST_ASC("VBA"));
4254 int nRet
= aVBasic
.Import( s1
, s2
, ! pVBAFlags
->IsLoadWordBasicCode() );
4255 // dissable below for 3.1 at the moment, 'cause it's kinda immature
4256 // similarly the project reference in svx/source/msvba
4258 lcl_createTemplateToProjectEntry( xPrjNameCache
, sCreatedFrom
, aVBasic
.GetVBAProjectName() );
4259 WW8Customizations
aCustomisations( pTableStream
, *pWwFib
);
4260 aCustomisations
.Import( mpDocShell
);
4264 maTracer
.Log(sw::log::eContainsVisualBasic
);
4265 rDoc
.SetContainsMSVBasic(true);
4270 // Hackly to register the document event.
4271 // should be find a better solution to share the codes with Excel Workbook event.
4272 registerDocEvent( mpDocShell
);
4274 maTracer
.LeaveEnvironment(sw::log::eMacros
);
4276 ReadText(0, pWwFib
->ccpText
, MAN_MAINTEXT
);
4280 ::SetProgressState(nProgress
, mpDocShell
); // Update
4282 if (pDrawPg
&& pMSDffManager
&& pMSDffManager
->GetShapeOrders())
4284 // Hilfsarray zum Verketten der (statt SdrTxtObj) eingefuegten
4286 SvxMSDffShapeTxBxSort aTxBxSort
;
4288 // korrekte Z-Order der eingelesen Escher-Objekte sicherstellen
4289 USHORT nShapeCount
= pMSDffManager
->GetShapeOrders()->Count();
4291 for (USHORT nShapeNum
=0; nShapeNum
< nShapeCount
; nShapeNum
++)
4293 SvxMSDffShapeOrder
*pOrder
=
4294 pMSDffManager
->GetShapeOrders()->GetObject(nShapeNum
);
4295 // Pointer in neues Sort-Array einfuegen
4296 if (pOrder
->nTxBxComp
&& pOrder
->pFly
)
4297 aTxBxSort
.Insert(pOrder
);
4299 // zu verkettende Rahmen jetzt verketten
4300 USHORT nTxBxCount
= aTxBxSort
.Count();
4304 for (USHORT nTxBxNum
=0; nTxBxNum
< nTxBxCount
; nTxBxNum
++)
4306 SvxMSDffShapeOrder
*pOrder
=
4307 aTxBxSort
.GetObject(nTxBxNum
);
4309 // Fly-Frame-Formate initialisieren
4310 SwFlyFrmFmt
* pFlyFmt
= pOrder
->pFly
;
4311 SwFlyFrmFmt
* pNextFlyFmt
= 0;
4312 SwFlyFrmFmt
* pPrevFlyFmt
= 0;
4313 // ggfs. Nachfolger ermitteln
4314 if( 1+nTxBxNum
< nTxBxCount
)
4316 SvxMSDffShapeOrder
*pNextOrder
=
4317 aTxBxSort
.GetObject(nTxBxNum
+1);
4318 if ((0xFFFF0000 & pOrder
->nTxBxComp
)
4319 == (0xFFFF0000 & pNextOrder
->nTxBxComp
))
4320 pNextFlyFmt
= pNextOrder
->pFly
;
4322 // ggfs. Vorgaenger ermitteln
4325 SvxMSDffShapeOrder
*pPrevOrder
=
4326 aTxBxSort
.GetObject(nTxBxNum
-1);
4327 if ((0xFFFF0000 & pOrder
->nTxBxComp
)
4328 == (0xFFFF0000 & pPrevOrder
->nTxBxComp
))
4329 pPrevFlyFmt
= pPrevOrder
->pFly
;
4331 // Falls Nachfolger oder Vorgaenger vorhanden,
4332 // die Verkettung am Fly-Frame-Format eintragen
4333 if (pNextFlyFmt
|| pPrevFlyFmt
)
4335 aChain
.SetNext( pNextFlyFmt
);
4336 aChain
.SetPrev( pPrevFlyFmt
);
4337 pFlyFmt
->SetFmtAttr( aChain
);
4347 if( pWDop
->fRevMarking
)
4348 eMode
|= nsRedlineMode_t::REDLINE_ON
;
4349 if( pWDop
->fRMView
)
4350 eMode
|= nsRedlineMode_t::REDLINE_SHOW_DELETE
;
4353 maInsertedTables
.DelAndMakeTblFrms();
4354 maSectionManager
.InsertSegments();
4364 DELETEZ( pMSDffManager
);
4366 DELETEZ( pLstManager
);
4371 DELETEZ( pAuthorInfos
);
4372 delete mpSprmParser
;
4373 ::EndProgress(mpDocShell
);
4379 mpRedlineStack
->closeall(*pPaM
->GetPoint());
4380 delete mpRedlineStack
;
4386 // delete the pam before the call for hide all redlines (Bug 73683)
4388 rDoc
.SetRedlineMode((RedlineMode_t
)( eMode
));
4390 UpdatePageDescs(rDoc
, nPageDescOffset
);
4392 delete pPaM
, pPaM
= 0;
4396 ULONG
SwWW8ImplReader::SetSubStreams(SvStorageStreamRef
&rTableStream
,
4397 SvStorageStreamRef
&rDataStream
)
4400 // 6 stands for "6 OR 7", 7 stand for "ONLY 7"
4401 switch (pWwFib
->nVersion
)
4405 pTableStream
= pStrm
;
4406 pDataStream
= pStrm
;
4411 ASSERT( pStg
, "Version 8 muss immer einen Storage haben!" );
4412 nErrRet
= ERR_SWG_READ_ERROR
;
4416 rTableStream
= pStg
->OpenSotStream( String::CreateFromAscii(
4417 pWwFib
->fWhichTblStm
? SL::a1Table
: SL::a0Table
),
4420 pTableStream
= &rTableStream
;
4421 pTableStream
->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
4423 rDataStream
= pStg
->OpenSotStream(CREATE_CONST_ASC(SL::aData
),
4424 STREAM_STD_READ
| STREAM_NOCREATE
);
4426 if (rDataStream
.Is() && SVSTREAM_OK
== rDataStream
->GetError())
4428 pDataStream
= &rDataStream
;
4429 pDataStream
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
4432 pDataStream
= pStrm
;
4436 ASSERT( !this, "Es wurde vergessen, nVersion zu kodieren!" );
4437 nErrRet
= ERR_SWG_READ_ERROR
;
4445 utl::TempFile
*MakeTemp(SvFileStream
&rSt
)
4447 utl::TempFile
*pT
= new utl::TempFile
;
4448 pT
->EnableKillingFile();
4449 rSt
.Open(pT
->GetFileName(), STREAM_READWRITE
| STREAM_SHARE_DENYWRITE
);
4453 #define WW_BLOCKSIZE 0x200
4455 void DecryptRC4(svx::MSCodec_Std97
& rCtx
, SvStream
&rIn
, SvStream
&rOut
)
4457 rIn
.Seek(STREAM_SEEK_TO_END
);
4458 ULONG nLen
= rIn
.Tell();
4461 sal_uInt8 in
[WW_BLOCKSIZE
];
4462 for (ULONG nI
= 0, nBlock
= 0; nI
< nLen
; nI
+= WW_BLOCKSIZE
, ++nBlock
)
4464 ULONG nBS
= (nLen
- nI
> WW_BLOCKSIZE
) ? WW_BLOCKSIZE
: nLen
- nI
;
4466 rCtx
.InitCipher(nBlock
);
4467 rCtx
.Decode(in
, nBS
, in
, nBS
);
4468 rOut
.Write(in
, nBS
);
4472 void DecryptXOR(svx::MSCodec_XorWord95
&rCtx
, SvStream
&rIn
, SvStream
&rOut
)
4474 ULONG nSt
= rIn
.Tell();
4475 rIn
.Seek(STREAM_SEEK_TO_END
);
4476 ULONG nLen
= rIn
.Tell();
4482 sal_uInt8 in
[0x4096];
4483 for (ULONG nI
= nSt
; nI
< nLen
; nI
+= 0x4096)
4485 ULONG nBS
= (nLen
- nI
> 0x4096 ) ? 0x4096 : nLen
- nI
;
4487 rCtx
.Decode(in
, nBS
);
4488 rOut
.Write(in
, nBS
);
4492 //moan, copy and paste :-(
4493 String
QueryPasswordForMedium(SfxMedium
& rMedium
)
4497 using namespace com::sun::star
;
4499 const SfxItemSet
* pSet
= rMedium
.GetItemSet();
4500 const SfxPoolItem
*pPasswordItem
;
4502 if(pSet
&& SFX_ITEM_SET
== pSet
->GetItemState(SID_PASSWORD
, TRUE
, &pPasswordItem
))
4503 aPassw
= ((const SfxStringItem
*)pPasswordItem
)->GetValue();
4508 uno::Reference
< task::XInteractionHandler
> xHandler( rMedium
.GetInteractionHandler() );
4511 ::comphelper::DocPasswordRequest
* pRequest
= new ::comphelper::DocPasswordRequest(
4512 ::comphelper::DocPasswordRequestType_MS
, task::PasswordRequestMode_PASSWORD_ENTER
,
4513 INetURLObject( rMedium
.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET
) );
4514 uno::Reference
< task::XInteractionRequest
> xRequest( pRequest
);
4516 xHandler
->handle( xRequest
);
4518 if( pRequest
->isPassword() )
4519 aPassw
= pRequest
->getPassword();
4522 catch( uno::Exception
& )
4532 ULONG
SwWW8ImplReader::LoadThroughDecryption(SwPaM
& rPaM
,WW8Glossary
*pGloss
)
4536 pWwFib
= pGloss
->GetFib();
4538 pWwFib
= new WW8Fib(*pStrm
, nWantedVersion
);
4540 if (pWwFib
->nFibError
)
4541 nErrRet
= ERR_SWG_READ_ERROR
;
4543 SvStorageStreamRef xTableStream
, xDataStream
;
4546 nErrRet
= SetSubStreams(xTableStream
, xDataStream
);
4548 utl::TempFile
*pTempMain
= 0;
4549 utl::TempFile
*pTempTable
= 0;
4550 utl::TempFile
*pTempData
= 0;
4551 SvFileStream aDecryptMain
;
4552 SvFileStream aDecryptTable
;
4553 SvFileStream aDecryptData
;
4555 bool bDecrypt
= false;
4556 enum {RC4
, XOR
, Other
} eAlgo
= Other
;
4557 if (pWwFib
->fEncrypted
&& !nErrRet
)
4562 if (8 != pWwFib
->nVersion
)
4566 if (pWwFib
->nKey
!= 0)
4570 pTableStream
->Seek(0);
4571 sal_uInt32 nEncType
;
4572 *pTableStream
>> nEncType
;
4573 if (nEncType
== 0x10001)
4582 nErrRet
= ERRCODE_SVX_WRONGPASS
;
4586 nErrRet
= ERRCODE_SVX_READ_FILTER_CRYPT
;
4590 String sUniPassword
=
4591 QueryPasswordForMedium(*(mpDocShell
->GetMedium()));
4593 ByteString
sPassword(sUniPassword
,
4594 WW8Fib::GetFIBCharset(pWwFib
->chseTables
));
4596 xub_StrLen nLen
= sPassword
.Len();
4597 // DR: do not cut a wrong (too long) password
4600 sal_uInt8 aPassword
[16] = {0};
4602 for (xub_StrLen nChar
= 0; nChar
< sPassword
.Len(); ++nChar
)
4603 aPassword
[nChar
] = sPassword
.GetChar(nChar
);
4605 svx::MSCodec_XorWord95 aCtx
;
4606 aCtx
.InitKey(aPassword
);
4607 if (aCtx
.VerifyKey(pWwFib
->nKey
, pWwFib
->nHash
))
4610 pTempMain
= MakeTemp(aDecryptMain
);
4613 size_t nUnencryptedHdr
=
4614 (8 == pWwFib
->nVersion
) ? 0x44 : 0x34;
4615 sal_uInt8
*pIn
= new sal_uInt8
[nUnencryptedHdr
];
4616 pStrm
->Read(pIn
, nUnencryptedHdr
);
4617 aDecryptMain
.Write(pIn
, nUnencryptedHdr
);
4620 DecryptXOR(aCtx
, *pStrm
, aDecryptMain
);
4622 if (!pTableStream
|| pTableStream
== pStrm
)
4623 pTableStream
= &aDecryptMain
;
4626 pTempTable
= MakeTemp(aDecryptTable
);
4627 DecryptXOR(aCtx
, *pTableStream
, aDecryptTable
);
4628 pTableStream
= &aDecryptTable
;
4631 if (!pDataStream
|| pDataStream
== pStrm
)
4632 pDataStream
= &aDecryptMain
;
4635 pTempData
= MakeTemp(aDecryptData
);
4636 DecryptXOR(aCtx
, *pDataStream
, aDecryptData
);
4637 pDataStream
= &aDecryptData
;
4645 String sUniPassword
=
4646 QueryPasswordForMedium(*(mpDocShell
->GetMedium()));
4648 xub_StrLen nLen
= sUniPassword
.Len();
4649 // DR: do not cut a wrong (too long) password
4652 sal_Unicode aPassword
[16] = {0};
4653 for (xub_StrLen nChar
= 0; nChar
< nLen
; ++nChar
)
4654 aPassword
[nChar
] = sUniPassword
.GetChar(nChar
);
4656 sal_uInt8 aDocId
[ 16 ];
4657 pTableStream
->Read(aDocId
, 16);
4658 sal_uInt8 aSaltData
[ 16 ];
4659 pTableStream
->Read(aSaltData
, 16);
4660 sal_uInt8 aSaltHash
[ 16 ];
4661 pTableStream
->Read(aSaltHash
, 16);
4663 svx::MSCodec_Std97 aCtx
;
4664 aCtx
.InitKey(aPassword
, aDocId
);
4665 if (aCtx
.VerifyKey(aSaltData
, aSaltHash
))
4669 pTempTable
= MakeTemp(aDecryptTable
);
4670 DecryptRC4(aCtx
, *pTableStream
, aDecryptTable
);
4671 pTableStream
= &aDecryptTable
;
4673 pTempMain
= MakeTemp(aDecryptMain
);
4674 DecryptRC4(aCtx
, *pStrm
, aDecryptMain
);
4676 if (!pDataStream
|| pDataStream
== pStrm
)
4677 pDataStream
= &aDecryptMain
;
4680 pTempData
= MakeTemp(aDecryptData
);
4681 DecryptRC4(aCtx
, *pDataStream
, aDecryptData
);
4682 pDataStream
= &aDecryptData
;
4684 SfxMedium
* pMedium
= mpDocShell
->GetMedium();
4687 SfxItemSet
* pSet
= pMedium
->GetItemSet();
4689 pSet
->Put( SfxStringItem(SID_PASSWORD
, sUniPassword
) );
4699 pStrm
= &aDecryptMain
;
4702 pWwFib
= new WW8Fib(*pStrm
, nWantedVersion
);
4703 if (pWwFib
->nFibError
)
4704 nErrRet
= ERR_SWG_READ_ERROR
;
4709 nErrRet
= CoreLoad(pGloss
, *rPaM
.GetPoint());
4720 class outlineeq
: public std::unary_function
<const SwTxtFmtColl
*, bool>
4725 outlineeq(BYTE nNum
) : mnNum(nNum
) {}
4726 bool operator()(const SwTxtFmtColl
*pTest
) const
4728 //return pTest->GetOutlineLevel() == mnNum; //#outline level,zhaojianwei
4729 return pTest
->IsAssignedToListLevelOfOutlineStyle() && pTest
->GetAssignedOutlineStyleLevel() == mnNum
; //<-end,zhaojianwei
4733 void SwWW8ImplReader::SetOutLineStyles()
4736 #i3674# & #101291# Load new document and insert document cases.
4738 SwNumRule
aOutlineRule(*rDoc
.GetOutlineNumRule());
4739 // --> OD 2005-10-14 #i53044,i53213#
4740 // <mpChosenOutlineNumRule> has to be set to point to local variable
4741 // <aOutlineRule>, because its used below to be compared this <&aOutlineRule>.
4742 // But at the end of the method <mpChosenOutlineNumRule> has to be set to
4743 // <rDoc.GetOutlineNumRule()>, because <aOutlineRule> will be destroyed.
4744 // mpChosenOutlineNumRule = rDoc.GetOutlineNumRule();
4745 mpChosenOutlineNumRule
= &aOutlineRule
;
4748 sw::ParaStyles
aOutLined(sw::util::GetParaStyles(rDoc
));
4749 // --> OD 2009-02-04 #i98791# - sorting algorithm adjusted
4750 sw::util::SortByAssignedOutlineStyleListLevel(aOutLined
);
4753 typedef sw::ParaStyleIter myParaStyleIter
;
4755 If we are inserted into a document then don't clobber existing existing
4758 USHORT nFlagsStyleOutlLevel
= 0;
4761 // --> OD 2008-12-16 #i70748#
4762 // backward iteration needed due to the outline level attribute
4763 sw::ParaStyles::reverse_iterator aEnd
= aOutLined
.rend();
4764 for ( sw::ParaStyles::reverse_iterator aIter
= aOutLined
.rbegin(); aIter
< aEnd
; ++aIter
)
4767 //if ((*aIter)->GetOutlineLevel() < MAXLEVEL) //#outline level,zhaojianwei,
4768 //nFlagsStyleOutlLevel |= 1 << (*aIter)->GetOutlineLevel();
4769 if ((*aIter
)->IsAssignedToListLevelOfOutlineStyle())
4770 nFlagsStyleOutlLevel
|= 1 << (*aIter
)->GetAssignedOutlineStyleLevel();//<-end,zhaojianwei
4779 Only import *one* of the possible multiple outline numbering rules, so
4780 pick the one that affects most styles. If we're not importing a new
4781 document, we got to stick with what is already there.
4783 // --> OD 2005-11-07 #127520# - use index in text format collection
4784 // array <pCollA> as key of the outline numbering map <aRuleMap>
4785 // instead of the memory pointer of the outline numbering rule
4786 // to assure that, if two outline numbering rule affect the same
4787 // count of text formats, always the same outline numbering rule is chosen.
4788 std::map
<USHORT
, int>aRuleMap
;
4789 typedef std::map
<USHORT
, int>::iterator myIter
;
4790 for (USHORT nI
= 0; nI
< nColls
; ++nI
)
4792 SwWW8StyInf
& rSI
= pCollA
[ nI
];
4794 (MAXLEVEL
> rSI
.nOutlineLevel
) && rSI
.pOutlineNumrule
&&
4798 // --> OD 2005-11-07 #127520#
4799 myIter aIter
= aRuleMap
.find(nI
);
4801 if (aIter
== aRuleMap
.end())
4803 // --> OD 2005-11-07 #127520#
4813 myIter aEnd2
= aRuleMap
.end();
4814 for (myIter aIter
= aRuleMap
.begin(); aIter
!= aEnd2
; ++aIter
++)
4816 if (aIter
->second
> nMax
)
4818 nMax
= aIter
->second
;
4819 // --> OD 2005-11-07 #127520#
4820 mpChosenOutlineNumRule
= pCollA
[ aIter
->first
].pOutlineNumrule
;
4826 ASSERT(mpChosenOutlineNumRule
, "Impossible");
4827 if (mpChosenOutlineNumRule
)
4828 aOutlineRule
= *mpChosenOutlineNumRule
;
4830 if (mpChosenOutlineNumRule
!= &aOutlineRule
)
4832 // --> OD 2008-12-16 #i70748#
4833 // backward iteration needed due to the outline level attribute
4834 sw::ParaStyles::reverse_iterator aEnd
= aOutLined
.rend();
4835 for ( sw::ParaStyles::reverse_iterator aIter
= aOutLined
.rbegin(); aIter
< aEnd
; ++aIter
)
4838 //if ((*aIter)->GetOutlineLevel() < MAXLEVEL)//#outline level,zhaojianwei
4839 // (*aIter)->SetOutlineLevel(NO_NUMBERING);
4840 if((*aIter
)->IsAssignedToListLevelOfOutlineStyle())
4841 (*aIter
)->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end
4849 USHORT nOldFlags
= nFlagsStyleOutlLevel
;
4851 for (USHORT nI
= 0; nI
< nColls
; ++nI
)
4853 SwWW8StyInf
& rSI
= pCollA
[nI
];
4855 if (rSI
.IsOutlineNumbered())
4857 USHORT nAktFlags
= 1 << rSI
.nOutlineLevel
;
4859 (nAktFlags
& nFlagsStyleOutlLevel
) ||
4860 (rSI
.pOutlineNumrule
!= mpChosenOutlineNumRule
)
4864 If our spot is already taken by something we can't replace
4865 then don't insert and remove our outline level.
4867 rSI
.pFmt
->SetFmtAttr(
4868 SwNumRuleItem( rSI
.pOutlineNumrule
->GetName() ) );
4869 //((SwTxtFmtColl*)rSI.pFmt)->SetOutlineLevel(NO_NUMBERING);
4870 ((SwTxtFmtColl
*)rSI
.pFmt
)->DeleteAssignmentToListLevelOfOutlineStyle();//#outline level,zhaojianwei
4875 If there is a style already set for this outline
4876 numbering level and its not a style set by us already
4877 then we can remove it outline numbering.
4878 (its one of the default headings in a new document
4879 so we can clobber it)
4880 Of course if we are being inserted into a document that
4881 already has some set we can't do this, thats covered by
4882 the list of level in nFlagsStyleOutlLevel to ignore.
4884 outlineeq
aCmp(rSI
.nOutlineLevel
);
4885 myParaStyleIter aResult
= std::find_if(aOutLined
.begin(),
4886 aOutLined
.end(), aCmp
);
4888 myParaStyleIter aEnd
= aOutLined
.end();
4889 while (aResult
!= aEnd
&& aCmp(*aResult
))
4891 //(*aResult)->SetOutlineLevel(NO_NUMBERING);//#outline level,zhaojianwei
4892 (*aResult
)->DeleteAssignmentToListLevelOfOutlineStyle();
4898 I believe that when a list is registered onto a winword
4899 style which is an outline numbering style (i.e.
4900 nOutlineLevel is set) that the style of numbering is for
4901 the level is indexed by the *list* level that was
4902 registered on that style, and not the outlinenumbering
4903 level, which is probably a logical sequencing, and not a
4904 physical mapping into the list style reged on that outline
4907 BYTE nFromLevel
= rSI
.nListLevel
;
4908 BYTE nToLevel
= rSI
.nOutlineLevel
;
4909 const SwNumFmt
& rRule
=rSI
.pOutlineNumrule
->Get(nFromLevel
);
4910 aOutlineRule
.Set(nToLevel
, rRule
);
4911 // Set my outline level
4912 //((SwTxtFmtColl*)rSI.pFmt)->SetOutlineLevel(nToLevel);//#outline level,zhaojianwei
4913 ((SwTxtFmtColl
*)rSI
.pFmt
)->AssignToListLevelOfOutlineStyle(nToLevel
); //<-end,zhaojianwei
4914 // If there are more styles on this level ignore them
4915 nFlagsStyleOutlLevel
|= nAktFlags
;
4919 if (nOldFlags
!= nFlagsStyleOutlLevel
)
4920 rDoc
.SetOutlineNumRule(aOutlineRule
);
4921 // --> OD 2005-10-14 #i53044,i53213#
4922 if ( mpChosenOutlineNumRule
== &aOutlineRule
)
4924 mpChosenOutlineNumRule
= rDoc
.GetOutlineNumRule();
4929 const String
* SwWW8ImplReader::GetAnnotationAuthor(sal_uInt16 nIdx
)
4931 if (!mpAtnNames
&& pWwFib
->lcbGrpStAtnOwners
)
4933 // Authoren bestimmen: steht im TableStream
4934 mpAtnNames
= new ::std::vector
<String
>;
4935 SvStream
& rStrm
= *pTableStream
;
4937 long nOldPos
= rStrm
.Tell();
4938 rStrm
.Seek( pWwFib
->fcGrpStAtnOwners
);
4940 long nRead
= 0, nCount
= pWwFib
->lcbGrpStAtnOwners
;
4941 while (nRead
< nCount
)
4945 mpAtnNames
->push_back(WW8ReadPString(rStrm
, false));
4946 nRead
+= mpAtnNames
->rbegin()->Len() + 1; // Laenge + BYTE Count
4950 mpAtnNames
->push_back(WW8Read_xstz(rStrm
, 0, false));
4951 // UNICode: doppelte Laenge + USHORT Count
4952 nRead
+= mpAtnNames
->rbegin()->Len() * 2 + 2;
4955 rStrm
.Seek( nOldPos
);
4958 const String
*pRet
= 0;
4959 if (mpAtnNames
&& nIdx
< mpAtnNames
->size())
4960 pRet
= &((*mpAtnNames
)[nIdx
]);
4964 ULONG
SwWW8ImplReader::LoadDoc( SwPaM
& rPaM
,WW8Glossary
*pGloss
)
4969 static const sal_Char
* aNames
[ 13 ] = {
4970 "WinWord/WW", "WinWord/WW8", "WinWord/WWFT",
4971 "WinWord/WWFLX", "WinWord/WWFLY",
4973 "WinWord/WWFA0", "WinWord/WWFA1", "WinWord/WWFA2",
4974 "WinWord/WWFB0", "WinWord/WWFB1", "WinWord/WWFB2",
4975 "WinWord/RegardHindiDigits"
4977 sal_uInt32 aVal
[ 13 ];
4979 SwFilterOptions
aOpt( 13, aNames
, aVal
);
4981 nIniFlags
= aVal
[ 0 ];
4982 nIniFlags1
= aVal
[ 1 ];
4983 // schiebt Flys um x twips nach rechts o. links
4984 nIniFlyDx
= aVal
[ 3 ];
4985 nIniFlyDy
= aVal
[ 4 ];
4987 nFieldFlags
= aVal
[ 5 ];
4988 nFieldTagAlways
[0] = aVal
[ 6 ];
4989 nFieldTagAlways
[1] = aVal
[ 7 ];
4990 nFieldTagAlways
[2] = aVal
[ 8 ];
4991 nFieldTagBad
[0] = aVal
[ 9 ];
4992 nFieldTagBad
[1] = aVal
[ 10 ];
4993 nFieldTagBad
[2] = aVal
[ 11 ];
4994 m_bRegardHindiDigits
= aVal
[ 12 ] > 0;
5000 // beachte: 6 steht fuer "6 ODER 7", 7 steht fuer "NUR 7"
5001 switch (nWantedVersion
)
5006 (0xa5dc != nMagic
&& 0xa5db != nMagic
) &&
5007 (nMagic
< 0xa697 || nMagic
> 0xa699)
5010 //JP 06.05.99: teste auf eigenen 97-Fake!
5011 if (pStg
&& 0xa5ec == nMagic
)
5013 ULONG nCurPos
= pStrm
->Tell();
5014 if (pStrm
->Seek(nCurPos
+ 22))
5018 if (0x300 != nfcMin
)
5019 nErrRet
= ERR_WW6_NO_WW6_FILE_ERR
;
5021 pStrm
->Seek( nCurPos
);
5024 nErrRet
= ERR_WW6_NO_WW6_FILE_ERR
;
5028 if (0xa5ec != nMagic
)
5029 nErrRet
= ERR_WW8_NO_WW8_FILE_ERR
;
5032 nErrRet
= ERR_WW8_NO_WW8_FILE_ERR
;
5033 ASSERT( !this, "Es wurde vergessen, nVersion zu kodieren!" );
5038 nErrRet
= LoadThroughDecryption(rPaM
,pGloss
);
5040 rDoc
.PropagateOutlineRule();
5045 extern "C" SAL_DLLPUBLIC_EXPORT Reader
* SAL_CALL
ImportDOC()
5047 return new WW8Reader();
5050 ULONG
WW8Reader::Read(SwDoc
&rDoc
, const String
& rBaseURL
, SwPaM
&rPam
, const String
& /* FileName */)
5052 USHORT nOldBuffSize
= 32768;
5053 bool bNew
= !bInsertMode
; // Neues Doc ( kein Einfuegen )
5056 SvStorageStreamRef refStrm
; // damit uns keiner den Stream klaut
5057 SvStream
* pIn
= pStrm
;
5062 String sFltName
= GetFltName();
5063 if( sFltName
.EqualsAscii( "WW6" ) )
5069 ASSERT(!this, "WinWord 95 Reader-Read ohne Stream");
5070 nRet
= ERR_SWG_READ_ERROR
;
5075 if( sFltName
.EqualsAscii( "CWW6" ) )
5077 else if( sFltName
.EqualsAscii( "CWW7" ) )
5082 nRet
= OpenMainStream( refStrm
, nOldBuffSize
);
5087 ASSERT(!this, "WinWord 95/97 Reader-Read ohne Storage");
5088 nRet
= ERR_SWG_READ_ERROR
;
5094 //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
5095 // Kapitelnummer. Darum hier explizit abschalten
5096 // weil das Default jetzt wieder auf AN ist.
5099 Reader::SetNoOutlineNum( rDoc
);
5100 // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf.
5101 Reader::ResetFrmFmts( rDoc
);
5103 SwWW8ImplReader
* pRdr
= new SwWW8ImplReader(nVersion
, pStg
, pIn
, rDoc
,
5105 nRet
= pRdr
->LoadDoc( rPam
);
5110 refStrm
->SetBufferSize( nOldBuffSize
);
5120 int WW8Reader::GetReaderType()
5122 return SW_STORAGE_READER
| SW_STREAM_READER
;
5125 BOOL
WW8Reader::HasGlossaries() const
5130 BOOL
WW8Reader::ReadGlossaries(SwTextBlocks
& rBlocks
, BOOL bSaveRelFiles
) const
5134 WW8Reader
*pThis
= const_cast<WW8Reader
*>(this);
5136 USHORT nOldBuffSize
= 32768;
5137 SvStorageStreamRef refStrm
;
5138 if (!pThis
->OpenMainStream(refStrm
, nOldBuffSize
))
5140 WW8Glossary
aGloss( refStrm
, 8, pStg
);
5141 bRet
= aGloss
.Load( rBlocks
, bSaveRelFiles
? true : false);
5143 return bRet
? true : false;
5146 BOOL
SwMSDffManager::GetOLEStorageName(long nOLEId
, String
& rStorageName
,
5147 SvStorageRef
& rSrcStorage
, uno::Reference
< embed::XStorage
>& rDestStorage
) const
5151 long nPictureId
= 0;
5154 // dann holen wir uns mal ueber den TextBox-PLCF die richtigen
5155 // Char Start-/End-Positionen. In dem Bereich sollte dann
5156 // das EinbettenFeld und die entsprechenden Sprms zu finden
5157 // sein. Wir brauchen hier aber nur das Sprm fuer die Picture Id
5158 long nOldPos
= rReader
.pStrm
->Tell();
5160 // --> OD 2004-12-08 #i32596# - consider return value of method
5161 // <rReader.GetTxbxTextSttEndCp(..)>. If it returns false, method
5162 // wasn't successful. Thus, continue in this case.
5163 // Note: Ask MM for initialization of <nStartCp> and <nEndCp>.
5164 // Note: Ask MM about assertions in method <rReader.GetTxbxTextSttEndCp(..)>.
5165 WW8_CP nStartCp
, nEndCp
;
5166 if ( rReader
.GetTxbxTextSttEndCp(nStartCp
, nEndCp
,
5167 static_cast<sal_uInt16
>((nOLEId
>> 16) & 0xFFFF),
5168 static_cast<sal_uInt16
>(nOLEId
& 0xFFFF)) )
5170 WW8PLCFxSaveAll aSave
;
5171 memset( &aSave
, 0, sizeof( aSave
) );
5172 rReader
.pPlcxMan
->SaveAllPLCFx( aSave
);
5174 nStartCp
+= rReader
.nDrawCpO
;
5175 nEndCp
+= rReader
.nDrawCpO
;
5176 WW8PLCFx_Cp_FKP
* pChp
= rReader
.pPlcxMan
->GetChpPLCF();
5177 wwSprmParser
aSprmParser(rReader
.pWwFib
->GetFIBVersion());
5178 while (nStartCp
<= nEndCp
&& !nPictureId
)
5181 pChp
->SeekPos( nStartCp
);
5182 pChp
->GetSprms( &aDesc
);
5184 if (aDesc
.nSprmsLen
&& aDesc
.pMemPos
) // Attribut(e) vorhanden
5186 long nLen
= aDesc
.nSprmsLen
;
5187 const BYTE
* pSprm
= aDesc
.pMemPos
;
5189 while (nLen
>= 2 && !nPictureId
)
5191 USHORT nId
= aSprmParser
.GetSprmId(pSprm
);
5192 USHORT nSL
= aSprmParser
.GetSprmSize(nId
, pSprm
);
5195 break; // nicht mehr genug Bytes uebrig
5197 if( 0x6A03 == nId
&& 0 < nLen
)
5199 nPictureId
= SVBT32ToUInt32(pSprm
+
5200 aSprmParser
.DistanceToData(nId
));
5207 nStartCp
= aDesc
.nEndPos
;
5210 rReader
.pPlcxMan
->RestoreAllPLCFx( aSave
);
5214 rReader
.pStrm
->Seek( nOldPos
);
5220 rStorageName
+= String::CreateFromInt32(nPictureId
);
5221 rSrcStorage
= rReader
.pStg
->OpenSotStorage(CREATE_CONST_ASC(
5223 if (!rReader
.mpDocShell
)
5226 rDestStorage
= rReader
.mpDocShell
->GetStorage();
5231 BOOL
SwMSDffManager::ShapeHasText(ULONG
, ULONG
) const
5233 // Zur Zeit des Einlesens einer einzelnen Box, die womoeglich Teil einer
5234 // Gruppe ist, liegen noch nicht genuegend Informationen vor, um
5235 // entscheiden zu koennen, ob wir sie nicht doch als Textfeld benoetigen.
5236 // Also vorsichtshalber mal alle umwandeln:
5240 bool SwWW8ImplReader::InEqualOrHigherApo(int nLvl
) const
5244 // --> OD 2006-01-19 #i60827#
5245 // check size of <maApos> to assure that <maApos.begin() + nLvl> can be performed.
5246 if ( sal::static_int_cast
< sal_Int32
>(nLvl
) >= sal::static_int_cast
< sal_Int32
>(maApos
.size()) )
5251 mycApoIter aIter
= std::find(maApos
.begin() + nLvl
, maApos
.end(), true);
5252 if (aIter
!= maApos
.end())
5258 bool SwWW8ImplReader::InEqualApo(int nLvl
) const
5260 //If we are in a table, see if an apo was inserted at the level below
5264 return maApos
[nLvl
];
5271 Position::Position(const SwPosition
&rPos
)
5272 : maPtNode(rPos
.nNode
), mnPtCntnt(rPos
.nContent
.GetIndex())
5276 Position::Position(const Position
&rPos
)
5277 : maPtNode(rPos
.maPtNode
), mnPtCntnt(rPos
.mnPtCntnt
)
5281 Position::operator SwPosition() const
5283 SwPosition
aRet(maPtNode
);
5284 aRet
.nContent
.Assign(maPtNode
.GetNode().GetCntntNode(), mnPtCntnt
);
5290 /* vi:set tabstop=4 shiftwidth=4 expandtab: */