1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
31 #include <hintids.hxx>
32 #include <tools/list.hxx>
33 #include <tools/cachestr.hxx>
34 #include <svtools/rtftoken.h>
35 #include <svl/itemiter.hxx>
36 #include <editeng/prntitem.hxx>
37 #include <editeng/opaqitem.hxx>
38 #include <editeng/protitem.hxx>
39 #include <editeng/ulspitem.hxx>
40 #include <editeng/lrspitem.hxx>
41 #include <editeng/boxitem.hxx>
42 #include <editeng/frmdiritem.hxx>
43 #include <fmtfsize.hxx>
44 #include <fmtanchr.hxx>
45 #include <fmtpdsc.hxx>
46 #include <fmtsrnd.hxx>
47 #include <fmtclds.hxx>
48 #include <fmtcntnt.hxx>
53 #include <shellio.hxx>
54 #include <swparrtf.hxx>
59 #include <pagedesc.hxx>
60 #include <swtable.hxx>
61 #include <txtflcnt.hxx>
62 #include <fmtflcnt.hxx>
67 // --> OD 2004-06-30 #i27767#
68 #include <fmtwrapinfluenceonobjpos.hxx>
70 #include <editeng/brshitem.hxx>
71 #include <fmtfollowtextflow.hxx>
72 // --> OD, FLR 2006-02-16 #131205#
73 #include "dcontact.hxx"
77 using namespace ::com::sun::star
;
79 #define ANCHOR(p) ((SwFmtAnchor*)p)
81 // steht in shellio.hxx
82 extern SwCntntNode
* GoNextNds( SwNodeIndex
* pIdx
, BOOL bChk
);
84 SV_IMPL_PTRARR( SwFlySaveArr
, SwFlySave
* )
86 inline const SwFmtFrmSize
GetFrmSize(const SfxItemSet
& rSet
, BOOL bInP
=TRUE
)
88 return (const SwFmtFrmSize
&)rSet
.Get(RES_FRM_SIZE
,bInP
);
91 SwFlySave::SwFlySave(const SwPaM
& rPam
, SfxItemSet
& rSet
)
92 : aFlySet(rSet
), nSttNd(rPam
.GetPoint()->nNode
), nEndNd(nSttNd
), nEndCnt(0),
93 nPageWidth(ATT_MIN_SIZE
), nDropLines(0), nDropAnchor(0)
97 int SwFlySave::IsEqualFly( const SwPaM
& rPos
, SfxItemSet
& rSet
)
99 if( rSet
.Count() != aFlySet
.Count() || nDropAnchor
)
102 // nur TextNodes zusammenfassen
103 if( nSttNd
== nEndNd
&& nEndNd
.GetNode().IsNoTxtNode() )
106 // teste auf gleiche / naechste Position
107 if( rPos
.GetPoint()->nNode
.GetIndex() == nEndNd
.GetIndex() )
109 if( 1 < (rPos
.GetPoint()->nContent
.GetIndex() - nEndCnt
) )
112 else if( rPos
.GetPoint()->nContent
.GetIndex() )
116 SwNodeIndex
aIdx( nEndNd
);
117 SwCntntNode
* pCNd
= rPos
.GetDoc()->GetNodes()[ aIdx
]->GetCntntNode();
118 if( !GoNextNds( &aIdx
, TRUE
) ||
119 aIdx
.GetIndex() != rPos
.GetPoint()->nNode
.GetIndex() ||
120 ( pCNd
&& pCNd
->Len() != nEndCnt
))
128 SfxItemIter
aIter( rSet
);
129 const SfxPoolItem
*pItem
, *pCurr
= aIter
.GetCurItem();
132 if( SFX_ITEM_SET
!= aFlySet
.GetItemState( pCurr
->Which(),
134 // Ankerattribute gesondert behandeln
135 ( RES_ANCHOR
== pCurr
->Which()
136 ? (ANCHOR(pCurr
)->GetAnchorId() != ANCHOR(pItem
)->GetAnchorId() ||
137 ANCHOR(pCurr
)->GetPageNum() != ANCHOR(pItem
)->GetPageNum())
138 : *pItem
!= *pCurr
))
141 if( aIter
.IsAtEnd() )
143 pCurr
= aIter
.NextItem();
149 void SwFlySave::SetFlySize( const SwTableNode
& rTblNd
)
151 // sollte der Fly kleiner als diese Tabelle sein, dann
152 // korrigiere diesen (nur bei abs. Angaben!)
153 SwTwips nWidth
= rTblNd
.GetTable().GetFrmFmt()->GetFrmSize().GetWidth();
154 const SwFmtFrmSize
& rSz
= GetFrmSize( aFlySet
);
155 if( nWidth
> rSz
.GetWidth() )
156 aFlySet
.Put( SwFmtFrmSize( rSz
.GetHeightSizeType(), nWidth
, rSz
.GetHeight() ));
159 BOOL
lcl_HasBreakAttrs( const SwCntntNode
& rNd
)
162 const SfxItemSet
& rSet
= rNd
.GetSwAttrSet();
163 const SfxPoolItem
* pItem
;
164 if( SFX_ITEM_SET
== rSet
.GetItemState( RES_BREAK
, TRUE
, &pItem
) &&
165 SVX_BREAK_NONE
!= ((SvxFmtBreakItem
*)pItem
)->GetBreak() )
167 else if( SFX_ITEM_SET
== rSet
.GetItemState( RES_PAGEDESC
, TRUE
, &pItem
)&&
168 0 != ((SwFmtPageDesc
*)pItem
)->GetPageDesc() )
174 void lcl_CpyBreakAttrs( SwCntntNode
* pSrcNd
, SwCntntNode
* pDstNd
,
175 SwNodeIndex
* pNewIdx
)
177 const SfxItemSet
* pSet
;
178 if( pSrcNd
&& pDstNd
&& 0 != ( pSet
= pSrcNd
->GetpSwAttrSet() ) )
180 const SfxPoolItem
*pDescItem
, *pBreakItem
;
182 if( SFX_ITEM_SET
!= pSet
->GetItemState( RES_BREAK
,
183 FALSE
, &pBreakItem
) )
186 if( SFX_ITEM_SET
!= pSet
->GetItemState( RES_PAGEDESC
,
187 FALSE
, &pDescItem
) )
190 if( pDescItem
|| pBreakItem
)
192 if( lcl_HasBreakAttrs( *pDstNd
))
194 SwPosition
aPos( *pDstNd
, SwIndex( pDstNd
));
196 pDstNd
->GetDoc()->AppendTxtNode( aPos
);
198 *pNewIdx
= aPos
.nNode
;
200 SwCntntNode
* pOldNd
= pDstNd
;
201 pDstNd
= aPos
.nNode
.GetNode().GetCntntNode();
202 pDstNd
->ChgFmtColl( pOldNd
->GetFmtColl() );
203 if( pDstNd
->HasSwAttrSet() )
205 SfxItemSet
aSet( *pDstNd
->GetpSwAttrSet() );
206 aSet
.ClearItem( RES_BREAK
);
207 aSet
.ClearItem( RES_PAGEDESC
);
208 pDstNd
->SetAttr( aSet
);
213 pDstNd
->SetAttr( *pBreakItem
);
214 pSrcNd
->ResetAttr( RES_BREAK
);
218 pDstNd
->SetAttr( *pDescItem
);
219 pSrcNd
->ResetAttr( RES_PAGEDESC
);
225 void SwRTFParser::SetFlysInDoc()
227 // !! von Oben abarbeiten, CntntPos ist kein Index !
228 SwNodes
& rNds
= pDoc
->GetNodes();
229 typedef std::pair
<SwFlyFrmFmt
*, SwFmtAnchor
> frameEntry
;
230 typedef std::deque
<frameEntry
> rtfframesAtIndex
;
231 typedef std::map
<const SwNode
*, rtfframesAtIndex
> rtfFmtMap
;
234 SwFrmFmt
* pParent
= pDoc
->GetFrmFmtFromPool( RES_POOLFRM_FRAME
);
235 for( USHORT n
= 0; n
< aFlyArr
.Count(); ++n
)
237 SwFlySave
* pFlySave
= aFlyArr
[ n
];
239 ASSERT( !pFlySave
->nSttNd
.GetNode().FindFlyStartNode(),
240 "Content vom Fly steht in einem Fly" );
241 ASSERT( pFlySave
->nSttNd
.GetIndex() <= pFlySave
->nEndNd
.GetIndex(),
242 "Fly hat falschen Bereich" );
246 //JP 21.09.98: wenn ein DropCap ist, dann Text im Node belassen, am
247 // Absatz das Absatz Attribut setzen. Ggfs noch die
248 // FontSize zuruecksetzen, damit das DropCap nicht zu
250 if( pFlySave
->nDropAnchor
)
252 SwTxtNode
* pSttNd
= pFlySave
->nSttNd
.GetNode().GetTxtNode();
253 SwTxtNode
* pEndNd
= pFlySave
->nEndNd
.GetNode().GetTxtNode();
254 if( pSttNd
&& pEndNd
&&
255 pSttNd
->GetIndex() + 1 == pEndNd
->GetIndex()
256 && pSttNd
->GetTxt().Len()>0 /* #i38227# leave drop caps with no content as fly frames */ )
258 ULONG nPos
= pSttNd
->GetIndex();
259 SwDoc
* pDoc1
= pSttNd
->GetDoc();
263 SwPaM
aTmp( *pSttNd
, pSttNd
->GetTxt().Len(), *pEndNd
, 0 );
264 bJoined
= pDoc1
->DeleteAndJoin( aTmp
);
267 SwTxtNode
* pNd
= (pDoc1
->GetNodes()[nPos
])->GetTxtNode();
269 if( bJoined
&& pNd
!= NULL
)
272 aDropCap
.GetLines() = (BYTE
)pFlySave
->nDropLines
;
273 aDropCap
.GetChars() = 1;
275 SwIndex
aIdx( pEndNd
);
276 pNd
->RstAttr( aIdx
, 1, RES_CHRATR_FONTSIZE
);
277 pNd
->SetAttr( aDropCap
);
284 // liegt Ende und Start vom Naechsten im gleichen Node, dann muss
286 if( n
+ 1 < aFlyArr
.Count() && pFlySave
->nEndCnt
&&
287 pFlySave
->nEndNd
== aFlyArr
[ n
+ 1 ]->nSttNd
)
289 SwCntntNode
* pCNd
= rNds
[ pFlySave
->nEndNd
]->GetCntntNode();
292 SwPosition
aPos( pFlySave
->nEndNd
,
293 SwIndex( pCNd
, pFlySave
->nEndCnt
));
294 pDoc
->SplitNode( aPos
, false );
298 pFlySave
->nEndCnt
= 0;
301 // verschiebe den Inhalt von diesem Anchor in den Auto-TextBereich
302 // und erzeuge dadurch den richtigen SwG-Rahmen
303 SwNodeRange
aRg(pFlySave
->nSttNd
, 0, pFlySave
->nEndNd
, 0);
304 //Make a new section, unless there is no content at all
305 const bool bMakeEmptySection
= aRg
.aStart
< aRg
.aEnd
|| ((aRg
.aStart
== aRg
.aEnd
) && pFlySave
->nEndCnt
);
308 // Nur TextNodes koennen in Tabellen stehen !!
309 const SwNode
* pNd
= &pFlySave
->nSttNd
.GetNode();
310 if( pNd
->IsNoTxtNode() )
312 // die Size muss noch korrigiert werden!
313 nAktPageDesc
= 0; // Standart PageDesc
314 if( SFX_ITEM_SET
!= pFlySave
->aFlySet
.GetItemState(
315 RES_FRM_SIZE
, FALSE
) )
316 _SetPictureSize( *(SwNoTxtNode
*)pNd
, aRg
.aStart
,
318 if( 0 != ( pNd
= pNd
->FindTableNode() ) )
319 pFlySave
->SetFlySize( *(SwTableNode
*)pNd
);
323 // Take care for table nodes
324 pNd
= pNd
->GetNodes()[ pNd
->GetIndex() - 2 ]->GetTableNode();
325 if( pNd
) // if the table starts imediately before aRg -> expand aRg
328 if( bMakeEmptySection
)
330 pNd
= &aRg
.aEnd
.GetNode();
331 ULONG nSectEnd
= pNd
->EndOfSectionIndex()+1;
333 if (!pNd
->IsTableNode() && 0 !=(pNd
= pNd
->FindTableNode())
334 && (pNd
->GetIndex() >= aRg
.aStart
.GetNode().GetIndex()) )
336 const SwNode
* pTblBxNd
;
338 // Ende der Tabelle ist hinter dieser Box ??
339 if( pNd
->EndOfSectionIndex() == nSectEnd
)
340 aRg
.aEnd
= nSectEnd
+1;
341 // is the end in the first box of the table, then
342 // move before the table (Bug 67663)
343 // but the range must not become emtpy, i.e. aStart==aEnd
344 // because otherwise we will get a crash (126506) later on
345 else if( 0 != ( pTblBxNd
= aRg
.aEnd
.GetNode().
346 FindTableBoxStartNode()) &&
347 pTblBxNd
->GetIndex() - 1 == pNd
->GetIndex() &&
348 &aRg
.aStart
.GetNode() != pNd
)
352 // Tabelle ist noch groesser, also splitte sie hier.
353 rNds
.SplitTable( aRg
.aEnd
, TRUE
);
354 aRg
.aEnd
= pNd
->EndOfSectionIndex() + 1;
361 // vorm verschieben muss sich der Index auf die alte Position
362 // gemerkt werden, der Index wird mit verschoben !!!
364 SwNodeIndex
aTmpIdx( rNds
.GetEndOfAutotext() );
365 SwStartNode
* pSttNd
= bMakeEmptySection
366 ? rNds
.MakeEmptySection( aTmpIdx
, SwFlyStartNode
)
367 : rNds
.MakeTextSection( aTmpIdx
, SwFlyStartNode
,
368 (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
370 // das ist die Verankerungs-Position (fuers Layout!)
371 pFlySave
->nSttNd
= aRg
.aStart
.GetIndex()-1;
372 if( bMakeEmptySection
)
374 // check: the move does not clear the surrounded section. If all
375 // nodes moved away, then create a new TxtNode
377 // i76403: an empty selection is not a good idea
378 if( aRg
.aStart
== aRg
.aEnd
&& aRg
.aStart
.GetNode().GetTxtNode() )
380 SwNodeIndex
aPrev( aRg
.aStart
, -1 );
381 if( aPrev
.GetNode().IsStartNode() &&
382 aPrev
.GetNode().EndOfSectionNode() == &aRg
.aEnd
.GetNode())
384 // create new txtnode, because the section does never be empty
385 pDoc
->GetNodes().MakeTxtNode( aRg
.aEnd
,
386 (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
390 aTmpIdx
= *pSttNd
->EndOfSectionNode();
391 pDoc
->MoveNodeRange( aRg
, aTmpIdx
,
392 IDocumentContentOperations::DOC_MOVEDEFAULT
);
395 // patch from cmc for #i52542#
396 if (pSttNd
->GetIndex() + 1 == pSttNd
->EndOfSectionIndex())
398 ASSERT(!this, "nothing in this frame, not legal");
403 pFlySave
->aFlySet
.Put( SwFmtCntnt( pSttNd
));
405 CalculateFlySize( pFlySave
->aFlySet
, pFlySave
->nSttNd
,
406 pFlySave
->nPageWidth
);
409 // if the section only contains one Node and this has a
410 // border or backgorund, then put it to the frame
411 // Not in our own RTF-Format!
412 // <<<<< DOES NOT MAKE SENSE TO ME (flr)
413 // #102781#. Added support for transparent frames.
414 if( pSttNd
->GetIndex() + 1 != pSttNd
->EndOfSectionIndex() &&
417 SwCntntNode
* pSrcNd
= pDoc
->GetNodes()[ pSttNd
->GetIndex() + 1 ]->GetCntntNode();
418 SfxItemSet
aTmpSet( pDoc
->GetAttrPool(),
419 RES_BACKGROUND
, RES_BOX
);
420 const SvxBrushItem
* pBackgroundBrush
= (const SvxBrushItem
*)pFlySave
->aFlySet
.GetItem(RES_BACKGROUND
, FALSE
);
421 if( pSrcNd
&& pSrcNd
->HasSwAttrSet() )
422 aTmpSet
.Put( *pSrcNd
->GetpSwAttrSet() );
423 if (pBackgroundBrush
)
425 aTmpSet
.Put(*pBackgroundBrush
, RES_BACKGROUND
);
429 pBackgroundBrush
= (const SvxBrushItem
*)aTmpSet
.GetItem(RES_BACKGROUND
, FALSE
);
430 if (pBackgroundBrush
)
432 Color
& rBackgroundColor
= const_cast<SvxBrushItem
*>(pBackgroundBrush
)->GetColor();
433 rBackgroundColor
.SetTransparency(0xFE);
437 Color aColor
= Color(0xff, 0xff, 0xff);
438 aColor
.SetTransparency( 0xFE);
439 SvxBrushItem
aBrush(aColor
, RES_BACKGROUND
);
440 aTmpSet
.Put(aBrush
, RES_BACKGROUND
);
444 pFlySave
->aFlySet
.Put( aTmpSet
);
445 if( pSrcNd
&& pSrcNd
->HasSwAttrSet() )
447 pSrcNd
->ResetAttr( RES_BACKGROUND
, RES_BOX
);
451 SwFlyFrmFmt
* pFmt
= pDoc
->MakeFlyFrmFmt( aEmptyStr
, pParent
);
452 pFmt
->SetFmtAttr( pFlySave
->aFlySet
);
453 const SwFmtAnchor
& rAnchor
= pFmt
->GetAnchor();
454 if (FLY_AS_CHAR
!= rAnchor
.GetAnchorId())
456 // korrigiere noch den Absatz, ist immer der vorhergehende !
457 // JP 20.09.95: wenn es diesen gibt! (DocAnfang!)
459 //JP 02.08.99: that is wrong. The anchor is ever the NEXT!
460 //JP 05.08.99: there are an Bug in the ExportFilter which will
461 // be fixed in the Version 517 - by SWG-Export
462 // the fly will be after the paragraph - but in RTF
463 // the flys will be before the paragraph.
464 if( !bSwPageDesc
|| 5430 < GetVersionNo() )
467 // if( !pFlySave->nSttNd.GetNode().IsCntntNode() )
469 // Seitenumbrueche in den Bodybereich verschieben!
470 SwCntntNode
* pSrcNd
= aRg
.aStart
.GetNode().GetCntntNode();
471 SwCntntNode
* pDstNd
= pFlySave
->nSttNd
.GetNode().GetCntntNode();
473 pDstNd
= pDoc
->GetNodes().GoNext( &pFlySave
->nSttNd
);
475 ::lcl_CpyBreakAttrs( pSrcNd
, pDstNd
, &pFlySave
->nSttNd
);
478 const SwNodeIndex
aSttNd(*pSttNd
);
479 SwNodeIndex
aEndNd(*pSttNd
->EndOfSectionNode());
482 SwPosition
aPos( pFlySave
->nSttNd
);
483 SwFmtAnchor
aAnchor(rAnchor
);
484 aAnchor
.SetAnchor(&aPos
);
486 const SwNode
*pCurrentAnchor
= &(pFlySave
->nSttNd
.GetNode());
487 aPrevFmts
[pCurrentAnchor
].push_back(frameEntry(pFmt
, aAnchor
));
489 while (aEndNd
> aSttNd
)
491 typedef rtfframesAtIndex::iterator myIter
;
492 rtfframesAtIndex
&rDeque
= aPrevFmts
[&(aEndNd
.GetNode())];
493 myIter aEnd
= rDeque
.end();
494 for (myIter aIter
= rDeque
.begin(); aIter
!= aEnd
; ++aIter
)
496 aIter
->second
.SetAnchor(&aPos
);
497 // --> OD 2004-06-30 #i27767# - push on front to keep order
498 // of objects for the correct object positioning
499 //aPrevFmts[pCurrentAnchor].push_back(*aIter);
500 aPrevFmts
[pCurrentAnchor
].push_front(*aIter
);
507 // --> OD, FLR 2006-02-16 #131205#
508 // Create draw contact object, which also creates a <SdrObject> instance,
509 // in order to set the order number.
510 // The order number is assumed to be the order of the text flow.
511 SwFlyDrawContact
* pContact
=
512 new SwFlyDrawContact( pFmt
,
513 pFmt
->GetDoc()->GetOrCreateDrawModel() );
514 pContact
->GetMaster()->SetOrdNum( n
);
520 typedef rtfFmtMap::reverse_iterator myriter
;
521 myriter aEnd
= aPrevFmts
.rend();
522 for(myriter aIter
= aPrevFmts
.rbegin(); aIter
!= aEnd
; ++aIter
)
524 rtfframesAtIndex
&rDeque
= aIter
->second
;
525 typedef rtfframesAtIndex::iterator myIter
;
526 myIter aQEnd
= rDeque
.end();
527 for (myIter aQIter
= rDeque
.begin(); aQIter
!= aQEnd
; ++aQIter
)
529 frameEntry
&rEntry
= *aQIter
;
530 SwFlyFrmFmt
*pFrm
= rEntry
.first
;
531 SwFmtAnchor
&rAnchor
= rEntry
.second
;
532 pFrm
->SetFmtAttr(rAnchor
);
536 aFlyArr
.Remove(0, aFlyArr
.Count());
539 // clips the text box to the min or max position if it is outside our min or max boundry
540 long SwRTFParser::GetSafePos(long nPos
)
544 else if(nPos
< SHRT_MIN
)
550 void SwRTFParser::ReadFly( int nToken
, SfxItemSet
* pSet
)
552 // ein Set fuer die FrmFmt-Attribute
553 SfxItemSet
aSet( pDoc
->GetAttrPool(), RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
555 Reader::ResetFrmFmtAttrs( aSet
);
557 // der Fly beginnt immer in einem neuen Absatz
558 if( pPam
->GetPoint()->nContent
.GetIndex() )
561 // RTF-Defaults setzen:
562 // --> OD 2004-06-24 #i27767#
563 SwFmtAnchor
aAnchor( FLY_AT_PARA
);
565 SwFmtHoriOrient
aHori( 0, text::HoriOrientation::LEFT
, text::RelOrientation::FRAME
);
566 SwFmtVertOrient
aVert( 0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
);
568 SvxFrameDirectionItem
aFrmDir( FRMDIR_HORI_LEFT_TOP
, RES_FRAMEDIR
);
570 USHORT nCols
= USHRT_MAX
, nColSpace
= USHRT_MAX
, nAktCol
= 0;
573 BOOL bChkDropCap
= 0 == pSet
;
574 USHORT nDropCapLines
= 0, nDropCapAnchor
= 0;
575 int nNumOpenBrakets
= GetOpenBrakets();
583 // die Werte aus dem uebergebenen!
584 aAnchor
= (SwFmtAnchor
&)pSet
->Get( RES_ANCHOR
);
585 aHori
= (SwFmtHoriOrient
&)pSet
->Get( RES_HORI_ORIENT
);
586 aVert
= (SwFmtVertOrient
&)pSet
->Get( RES_VERT_ORIENT
);
589 // dann sammel mal alle Attribute zusammen
593 USHORT nVal
= USHORT(nTokenValue
);
596 Assume that a property genuinely contributes towards creating a frame,
597 and if turns out to be a non contributing one reduce the count.
604 SwFmtFrmSize
aSz( ATT_MIN_SIZE
, nTokenValue
, 0 );
605 const SfxPoolItem
* pItem
;
606 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_FRM_SIZE
, TRUE
,
609 aSz
.SetHeightSizeType( ((SwFmtFrmSize
*)pItem
)->GetHeightSizeType() );
610 aSz
.SetHeight( ((SwFmtFrmSize
*)pItem
)->GetHeight() );
612 if( MINFLY
> nTokenValue
) nTokenValue
= MINFLY
;
618 SwFmtFrmSize
aSz( ATT_MIN_SIZE
, 0, MINFLY
);
619 const SfxPoolItem
* pItem
;
620 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_FRM_SIZE
, TRUE
,
623 aSz
.SetWidth( ((SwFmtFrmSize
*)pItem
)->GetWidth() );
626 if( 0 > nTokenValue
)
628 nTokenValue
= -nTokenValue
;
629 aSz
.SetHeightSizeType( ATT_FIX_SIZE
);
631 if( MINFLY
> nTokenValue
) nTokenValue
= MINFLY
;
632 aSz
.SetHeight( nTokenValue
);
639 pSet
->Put( SwFmtSurround( SURROUND_NONE
));
644 SvxULSpaceItem
aUL( RES_UL_SPACE
);
645 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
646 aUL
.SetUpper( nVal
); aUL
.SetLower( nVal
);
647 aLR
.SetLeft( nVal
); aLR
.SetRight( nVal
);
655 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
656 aLR
.SetLeft( nVal
); aLR
.SetRight( nVal
);
662 SvxULSpaceItem
aUL( RES_UL_SPACE
);
663 aUL
.SetUpper( nVal
); aUL
.SetLower( nVal
);
669 case RTF_POSX
: aHori
.SetHoriOrient( text::HoriOrientation::NONE
);
670 aHori
.SetPos( GetSafePos((long)nTokenValue
) );
672 case RTF_POSXC
: aHori
.SetHoriOrient( text::HoriOrientation::CENTER
); break;
673 case RTF_POSXI
: aHori
.SetHoriOrient( text::HoriOrientation::LEFT
);
674 aHori
.SetPosToggle( TRUE
);
676 case RTF_POSXO
: aHori
.SetHoriOrient( text::HoriOrientation::RIGHT
);
677 aHori
.SetPosToggle( TRUE
);
679 case RTF_POSXL
: aHori
.SetHoriOrient( text::HoriOrientation::LEFT
); break;
680 case RTF_POSXR
: aHori
.SetHoriOrient( text::HoriOrientation::RIGHT
); break;
683 case RTF_POSY
: aVert
.SetVertOrient( text::VertOrientation::NONE
);
684 aVert
.SetPos( GetSafePos((long)nTokenValue
) );
686 case RTF_POSYT
: aVert
.SetVertOrient( text::VertOrientation::TOP
); break;
687 case RTF_POSYB
: aVert
.SetVertOrient( text::VertOrientation::BOTTOM
); break;
688 case RTF_POSYC
: aVert
.SetVertOrient( text::VertOrientation::CENTER
); break;
690 case RTF_PHMRG
: aHori
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
); break;
691 case RTF_PVMRG
: aVert
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
); break;
692 case RTF_PHPG
: aHori
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
); break;
693 case RTF_PVPG
: aVert
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);break;
694 case RTF_PHCOL
: aHori
.SetRelationOrient( text::RelOrientation::FRAME
); break;
695 case RTF_PVPARA
: aVert
.SetRelationOrient( text::RelOrientation::FRAME
); break;
702 Not sufficient to make a frame at least word won't do it with just
708 aFrmDir
.SetValue( FRMDIR_HORI_LEFT_TOP
);
711 aFrmDir
.SetValue( FRMDIR_HORI_RIGHT_TOP
);
714 aFrmDir
.SetValue( FRMDIR_VERT_TOP_LEFT
);
717 aFrmDir
.SetValue( FRMDIR_VERT_TOP_RIGHT
);
720 case RTF_DROPCAPLI
: // Dropcaps !!
723 nDropCapLines
= USHORT( nTokenValue
);
724 if( !nDropCapAnchor
)
731 nDropCapAnchor
= USHORT( nTokenValue
);
738 // fuer die "alten" Writer - haben die Spaltigkeit falsch heraus-
740 case RTF_COLS
: nCols
= USHORT( nTokenValue
); break;
741 case RTF_COLSX
: nColSpace
= USHORT( nTokenValue
); break;
743 nAktCol
= USHORT( nTokenValue
);
744 if( RTF_COLW
== GetNextToken() )
746 USHORT nWidth
= USHORT( nTokenValue
), nSpace
= 0;
747 if( RTF_COLSR
== GetNextToken() )
748 nSpace
= USHORT( nTokenValue
);
750 SkipToken( -1 ); // wieder zurueck
752 if( --nAktCol
== ( aColumns
.Count() / 2 ) )
754 aColumns
.Insert( nWidth
+ nSpace
, aColumns
.Count() );
755 aColumns
.Insert( nSpace
, aColumns
.Count() );
763 if( RTF_IGNOREFLAG
!= ( nToken
= GetNextToken() ))
765 if( RTF_SHADINGDEF
== (nToken
& ~0xff) )
767 ReadBackgroundAttr( nToken
, aSet
);
768 GetNextToken(); // Klammer ueberlesen
773 else if( RTF_APOCTL
==
774 ((nToken
= GetNextToken() ) & ~(0xff | RTF_SWGDEFS
)) )
776 bReadSwFly
= true; // alles kommt in den akt. Fly
777 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
778 SvxULSpaceItem
aUL( RES_UL_SPACE
);
779 nCols
= USHRT_MAX
; // neu aufsetzen
780 nColSpace
= USHRT_MAX
;
782 nVal
= USHORT(nTokenValue
);
788 pSet
->Put( SvxPrintItem( RES_PRINT
, FALSE
));
793 pSet
->Put( SvxOpaqueItem( RES_OPAQUE
, FALSE
));
799 RTFProtect
aP( (BYTE
)nTokenValue
);
800 SvxProtectItem
aProtectItem( RES_PROTECT
);
801 aProtectItem
.SetCntntProtect( aP
.GetCntnt() );
802 aProtectItem
.SetSizeProtect( aP
.GetSize() );
803 aProtectItem
.SetPosProtect( aP
.GetPos() );
804 pSet
->Put( aProtectItem
);
810 RTFSurround
aMC( (BYTE
)nTokenValue
);
811 SwFmtSurround
aSurr( (SwSurround
)aMC
.GetOrder());
812 if( aMC
.GetGoldCut() )
813 aSurr
.SetSurround( SURROUND_IDEAL
);
819 RTFVertOrient
aVO( nVal
);
820 aVert
.SetVertOrient( aVO
.GetOrient() );
821 aVert
.SetRelationOrient( aVO
.GetRelation() );
826 RTFHoriOrient
aHO( nVal
);
827 aHori
.SetHoriOrient( aHO
.GetOrient() );
828 aHori
.SetRelationOrient( aHO
.GetRelation() );
831 case RTF_FLYOUTLEFT
: aLR
.SetLeft( nVal
); break;
832 case RTF_FLYOUTRIGHT
: aLR
.SetRight( nVal
); break;
833 case RTF_FLYOUTUPPER
: aUL
.SetUpper( nVal
); break;
834 case RTF_FLYOUTLOWER
: aUL
.SetLower( nVal
); break;
836 switch( GetNextToken() )
839 aAnchor
.SetType( FLY_AT_PAGE
);
840 aAnchor
.SetPageNum( USHORT(nTokenValue
));
841 aAnchor
.SetAnchor( 0 );
846 SwNodeIndex
aIdx( pPam
->GetPoint()->nNode
);
847 pDoc
->GetNodes().GoPrevious( &aIdx
);
848 SwPosition
aPos( aIdx
);
849 aAnchor
.SetType( FLY_AT_PARA
);
850 aAnchor
.SetAnchor( &aPos
);
854 // JP 26.09.94: die Bindung an die Spalte gibt es nicht mehr !!
855 // case RTF_FLY_COLUMN:
858 case RTF_COLS
: nCols
= USHORT( nTokenValue
); break;
859 case RTF_COLSX
: nColSpace
= USHORT( nTokenValue
); break;
861 nAktCol
= USHORT( nTokenValue
);
862 if( RTF_COLW
== GetNextToken() )
864 USHORT nWidth
= USHORT( nTokenValue
), nSpace
= 0;
865 if( RTF_COLSR
== GetNextToken() )
866 nSpace
= USHORT( nTokenValue
);
868 SkipToken( -1 ); // wieder zurueck
870 if( --nAktCol
== ( aColumns
.Count() / 2 ) )
872 aColumns
.Insert( nWidth
+ nSpace
, aColumns
.Count() );
873 aColumns
.Insert( nSpace
, aColumns
.Count() );
879 if( RTF_BRDBOX
== ( nToken
= GetNextToken() ) )
880 ReadBorderAttr( nToken
, aSet
);
881 else if( RTF_SHADINGDEF
== (nToken
& ~0xff ) )
882 ReadBackgroundAttr( nToken
, aSet
);
883 else if( RTF_IGNOREFLAG
== nToken
)
886 switch( nToken
= GetNextToken() )
890 ReadAttr( SkipToken( -2 ), &aSet
);
899 ReadBorderAttr( SkipToken( -2 ), aSet
);
903 // keine weitere Klammer mehr ueberlesen!!!
911 GetNextToken(); // Klammer ueberlesen
914 } while( IsParserWorking() &&
915 '}' != ( nToken
= GetNextToken() ));
917 if( aUL
.GetUpper() || aUL
.GetLower() )
919 if( aLR
.GetLeft() || aLR
.GetRight() )
922 else if( RTF_BRDBOX
== nToken
)
923 ReadBorderAttr( nToken
, aSet
);
924 else if( RTF_SHADOW
== nToken
)
925 ReadAttr( SkipToken( -2 ), &aSet
);
926 else if( RTF_SHADINGDEF
== (nToken
& ~0xff ) )
927 ReadBackgroundAttr( nToken
, aSet
);
928 else if( RTF_UNKNOWNCONTROL
== nToken
)
935 nToken
= SkipToken( nSkip
);
942 --nAppliedProps
; //Not sufficient to make a frame
947 nToken
= GetNextToken();
948 } while( bWeiter
&& IsParserWorking() );
950 pSet
->Put( aAnchor
);
954 // --> OD 2004-06-30 #i27767# - set wrapping style influence
955 // --> OD 2004-10-18 #i35017# - constant name has changed
956 pSet
->Put( SwFmtWrapInfluenceOnObjPos(
957 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE
));
960 SwFmtFollowTextFlow
aFollowTextFlow( FALSE
);
961 pSet
->Put( aFollowTextFlow
);
963 if( !( aFrmDir
== pSet
->Get( RES_FRAMEDIR
)) )
964 pSet
->Put( aFrmDir
);
966 if( nCols
&& USHRT_MAX
!= nCols
)
969 if( USHRT_MAX
== nColSpace
)
972 ULONG nWidth
= USHRT_MAX
;
973 aCol
.Init( nCols
, nColSpace
, USHORT( nWidth
) );
974 if( nCols
== ( aColumns
.Count() / 2 ) )
976 for( USHORT n
= 0, i
= 0; n
< aColumns
.Count(); n
+= 2, ++i
)
978 SwColumn
* pCol
= aCol
.GetColumns()[ i
];
979 ULONG nTmp
= aColumns
[ n
];
982 pCol
->SetWishWidth( USHORT(nTmp
) );
984 JP 07.07.95: der Dialog kennt nur eine Breite fuer alle Spalten
985 darum hier nicht weiter beachten
986 nTmp = aColumns[ n+1 ];
988 pCol->SetRight( USHORT(nTmp) );
998 if( pSet
!= &aSet
) // wurde der Set uebergeben, dann wars das
1001 // ein neues FlyFormat anlegen oder das alte benutzen ?
1002 // (teste ob es die selben Attribute besitzt!)
1003 SwFlySave
* pFlySave
= 0;
1004 USHORT nFlyArrCnt
= aFlyArr
.Count();
1007 There were not enough frame properties found to actually justify creating
1008 an absolutely positioned frame.
1013 !( pFlySave
= aFlyArr
[ nFlyArrCnt
-1 ])->IsEqualFly( *pPam
, aSet
))
1015 pFlySave
= new SwFlySave( *pPam
, aSet
);
1017 GetPageSize( aPgSize
);
1018 pFlySave
->nPageWidth
= aPgSize
.Width();
1020 if( nDropCapAnchor
)
1022 pFlySave
->nDropAnchor
= nDropCapAnchor
;
1023 pFlySave
->nDropLines
= nDropCapLines
;
1026 SwFlySave
* pFlySavePrev
= aFlyArr
[nFlyArrCnt
-1];
1027 if (pFlySave
->nSttNd
.GetIndex() < pFlySavePrev
->nEndNd
.GetIndex())
1029 pFlySavePrev
->nEndNd
=pFlySave
->nSttNd
;
1032 aFlyArr
.Insert( pFlySave
, nFlyArrCnt
++ );
1033 // --> OD 2008-12-22 #i83368# - reset
1034 mbReadCellWhileReadSwFly
= false;
1039 SetPardTokenRead( FALSE
);
1040 const SwTableNode
* pTblNd
= pPam
->GetNode()->FindTableNode();
1042 while( !IsPardTokenRead() && IsParserWorking() )
1044 if( RTF_PARD
== nToken
|| nNumOpenBrakets
> GetOpenBrakets() )
1047 NextToken( nToken
);
1049 if( !IsPardTokenRead() )
1051 // #102781#. Added support for transparent frames.
1052 if (nToken
== RTF_CBPAT
&& nFlyArrCnt
> 0)
1054 USHORT _index
=USHORT(nTokenValue
);
1055 const Color
& rColor
= GetColor(_index
);
1056 SvxBrushItem
aBrush(rColor
, RES_BACKGROUND
);
1057 SwFlySave
* pFS
= aFlyArr
[nFlyArrCnt
-1];
1058 pFS
->aFlySet
.Put(aBrush
, RES_BACKGROUND
);
1061 nToken
= GetNextToken();
1063 // BUG 22036: kommt zwischen Fly-Attributen ein unbekanntes,
1064 // dann erzeuge nie 2 FlyFrames, sondern fasse
1065 // beide zusammen !!!
1066 while( RTF_APOCTL
== ( nToken
& ~(0xff | RTF_SWGDEFS
) ))
1068 if( RTF_FLY_INPARA
== nToken
)
1071 if( RTF_IGNOREFLAG
== SkipToken( -1 ) )
1073 if( '{' == SkipToken( -1 ) )
1081 ReadFly( nToken
, pFlySave
? &pFlySave
->aFlySet
: 0);
1082 nToken
= GetNextToken();
1089 There were enough frame properties found to actually justify creating
1090 an absolutely positioned frame.
1099 if( pTblNd
&& !pPam
->GetPoint()->nContent
.GetIndex() &&
1100 pTblNd
->EndOfSectionIndex() + 1 ==
1101 pPam
->GetPoint()->nNode
.GetIndex() )
1103 // nicht mehr in der Tabelle, sondern dahinter ?
1104 // Dann aber wieder zurueck in die Tabelle
1105 pPam
->Move( fnMoveBackward
);
1110 // wurde garnichts eingefuegt?
1112 pPam
->GetPoint()->nNode
== pFlySave
->nSttNd
&&
1113 !pPam
->GetPoint()->nContent
.GetIndex() )
1115 // // dann erzeuge mindestens einen leeren TextNode
1116 // pDoc->AppendTxtNode(*pPam);
1117 // dann zerstoere den FlySave wieder.
1118 aFlyArr
.DeleteAndDestroy( --nFlyArrCnt
);
1123 BOOL bMovePaM
= 0 != pTblNd
;
1125 pFlySave
->nEndNd
= pPam
->GetPoint()->nNode
;
1126 pFlySave
->nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
1129 pPam
->Move( fnMoveForward
);
1131 pTblNd
= pFlySave
->nSttNd
.GetNode().FindTableNode();
1132 if( pTblNd
&& !pFlySave
->nEndCnt
&&
1133 pTblNd
== pFlySave
->nEndNd
.GetNode().FindTableNode() )
1135 // dann teste mal, ob das \pard nicht zu spaet kam und
1136 // eigentlich in die vorherige Zelle gehoert
1137 const SwStartNode
* pSttBoxNd
= pFlySave
->nSttNd
.GetNode().
1138 FindTableBoxStartNode(),
1139 * pEndBoxNd
= pFlySave
->nEndNd
.GetNode().
1140 FindTableBoxStartNode();
1141 if( pSttBoxNd
&& pEndBoxNd
&&
1142 bMovePaM
? ( pSttBoxNd
== pEndBoxNd
)
1143 : ( pSttBoxNd
->EndOfSectionIndex() + 1 ==
1144 pEndBoxNd
->GetIndex() &&
1145 pEndBoxNd
->GetIndex() + 1 ==
1146 pFlySave
->nEndNd
.GetIndex() ))
1148 // dann gehoert das Ende in die vorherige Box!
1149 SwPosition
aPos( *pPam
->GetPoint() );
1150 pPam
->GetPoint()->nNode
= *pSttBoxNd
->EndOfSectionNode();
1151 pPam
->Move( fnMoveBackward
, fnGoNode
);
1155 pPam
->GetPoint()->nNode
= *pSttBoxNd
->EndOfSectionNode();
1156 pPam
->Move( fnMoveBackward
, fnGoNode
);
1158 pFlySave
->nEndNd
= pPam
->GetPoint()->nNode
;
1159 pFlySave
->nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
1161 *pPam
->GetPoint() = aPos
;
1164 else if( !bReadSwFly
&& !pFlySave
->nEndCnt
&&
1165 pFlySave
->nSttNd
.GetIndex() + 1 == pFlySave
->nEndNd
.GetIndex() &&
1166 pFlySave
->nSttNd
.GetNode().IsTxtNode() )
1169 SwTxtNode
* pTxtNd
= pFlySave
->nSttNd
.GetNode().GetTxtNode();
1170 SwTxtFlyCnt
* pFlyCnt
= 0;
1171 if( 1 == pTxtNd
->GetTxt().Len() &&
1172 0 != (pFlyCnt
= static_cast<SwTxtFlyCnt
*>(
1173 pTxtNd
->GetTxtAttrForCharAt(0, RES_TXTATR_FLYCNT
))) &&
1174 pFlyCnt
->GetFlyCnt().GetFrmFmt() )
1176 // then move the content into the surrounded fly
1177 SwFrmFmt
* pFlyFmt
= pFlyCnt
->GetFlyCnt().GetFrmFmt();
1178 const SwNodeIndex
* pFlySNd
= pFlyFmt
->GetCntnt().GetCntntIdx();
1179 SwNodeRange
aRg( *pFlySNd
, 1,
1180 *pFlySNd
->GetNode().EndOfSectionNode(), 0 );
1182 // merge the itemsets
1183 SwFmtFrmSize
aSz1( (SwFmtFrmSize
&)pFlyFmt
->GetAttrSet().
1184 Get( RES_FRM_SIZE
));
1185 SwFmtFrmSize
aSz2( (SwFmtFrmSize
&)pFlySave
->aFlySet
.
1186 Get( RES_FRM_SIZE
));
1188 if( !aRg
.aStart
.GetNode().IsNoTxtNode() ||
1189 !aSz1
.GetHeight() || !aSz1
.GetWidth() ||
1190 !aSz2
.GetHeight() || !aSz2
.GetWidth() ||
1191 ( aSz1
.GetHeight() == aSz2
.GetHeight() &&
1192 aSz1
.GetWidth() == aSz2
.GetWidth() ) )
1194 SfxItemSet
aDiffs( pFlyFmt
->GetAttrSet() );
1195 aDiffs
.ClearItem( RES_ANCHOR
);
1196 aDiffs
.ClearItem( RES_FRM_SIZE
);
1197 aDiffs
.ClearItem( RES_CNTNT
);
1198 aDiffs
.Differentiate( pFlySave
->aFlySet
);
1199 pFlySave
->aFlySet
.Put( aDiffs
);
1202 if( aSz1
.GetHeight() && !aSz2
.GetHeight() )
1205 aSz2
.SetHeight( aSz1
.GetHeight() );
1207 if( aSz1
.GetWidth() && !aSz2
.GetWidth() )
1210 aSz2
.SetWidth( aSz1
.GetWidth() );
1213 pFlySave
->aFlySet
.Put( aSz2
);
1215 // move any PageBreak/Desc Attr to the next Para
1217 SwCntntNode
* pSrcNd
= pFlySave
->nSttNd
.GetNode().GetCntntNode();
1218 SwCntntNode
* pDstNd
= pFlySave
->nEndNd
.GetNode().GetCntntNode();
1220 ::lcl_CpyBreakAttrs( pSrcNd
, pDstNd
, &pFlySave
->nEndNd
);
1223 // create new txtnode, because the section does never be empty
1224 pDoc
->GetNodes().MakeTxtNode( aRg
.aStart
,
1225 (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
1227 SwNodeIndex
aTmp( pFlySave
->nSttNd
, +1 );
1228 pDoc
->MoveNodeRange( aRg
, aTmp
,
1229 IDocumentContentOperations::DOC_MOVEDEFAULT
);
1231 // now delete the redundant txtnode
1232 pDoc
->GetNodes().Delete( pFlySave
->nSttNd
, 1 );
1243 void SwRTFParser::InsPicture( const String
& rGrfNm
, const Graphic
* pGrf
,
1244 const SvxRTFPictureType
* pPicType
)
1246 // kennzeichen fuer Swg-Dokumente:
1247 // (dann ist das FlyFmt fuer die Grafik!)
1249 // --> OD 2008-12-22 #i83368#
1250 // Assure that graphic node is enclosed by fly frame node.
1252 if ( bReadSwFly
&& !mbReadCellWhileReadSwFly
)
1255 // erzeuge nur einen normalen GrafikNode und ersetze diesen gegen
1256 // den vorhandenen Textnode
1257 SwNodeIndex
& rIdx
= pPam
->GetPoint()->nNode
;
1258 pGrfNd
= pDoc
->GetNodes().MakeGrfNode( rIdx
,
1259 rGrfNm
, aEmptyStr
, // Name der Graphic !!
1261 (SwGrfFmtColl
*)pDoc
->GetDfltGrfFmtColl() );
1264 pGrfNd
->SetAttr( *pGrfAttrSet
);
1266 SwFlySave
* pFlySave
= aFlyArr
[ aFlyArr
.Count()-1 ];
1267 pFlySave
->nSttNd
= rIdx
.GetIndex() - 1;
1269 if( 1 < aFlyArr
.Count() )
1271 pFlySave
= aFlyArr
[ aFlyArr
.Count() - 2 ];
1272 if( pFlySave
->nEndNd
== rIdx
)
1273 pFlySave
->nEndNd
= rIdx
.GetIndex() - 1;
1278 // wenn normale RTF-Grafik, dann steht diese im Textfluss !
1279 SwAttrSet
aFlySet( pDoc
->GetAttrPool(), RES_OPAQUE
, /*RES_OPAQUE,
1280 RES_VERT_ORIENT,*/ RES_ANCHOR
);
1281 const SwPosition
* pPos
= pPam
->GetPoint();
1283 SwFmtAnchor
aAnchor( FLY_AS_CHAR
);
1284 aAnchor
.SetAnchor( pPos
);
1285 aFlySet
.Put( aAnchor
);
1286 aFlySet
.Put( SwFmtVertOrient( 0, text::VertOrientation::TOP
));
1288 if (pDoc
->IsInHeaderFooter(pPos
->nNode
))
1290 SvxOpaqueItem
aOpaqueItem(RES_OPAQUE
, FALSE
);
1291 SwFmtSurround
aSurroundItem(SURROUND_THROUGHT
);
1292 aFlySet
.Put(aOpaqueItem
);
1293 aFlySet
.Put(aSurroundItem
);
1296 SwFrmFmt
* pFlyFmt
= pDoc
->Insert( *pPam
,
1297 rGrfNm
, aEmptyStr
, // Name der Graphic !!
1299 &aFlySet
, // Attribute fuer den FlyFrm
1300 pGrfAttrSet
, NULL
); // Attribute fuer die Grafik
1302 pGrfNd
= pDoc
->GetNodes()[ pFlyFmt
->GetCntnt().GetCntntIdx()->
1303 GetIndex()+1 ]->GetGrfNode();
1305 _SetPictureSize( *pGrfNd
, pPos
->nNode
,
1306 (SfxItemSet
&)pFlyFmt
->GetAttrSet(),
1311 DELETEZ( pGrfAttrSet
);
1314 void SwRTFParser::_SetPictureSize( const SwNoTxtNode
& rNd
,
1315 const SwNodeIndex
& rAnchor
,
1317 const SvxRTFPictureType
* pPicType
)
1319 Size
aSize( ((SwNoTxtNode
&)rNd
).GetTwipSize() );
1322 if( rNd
.IsGrfNode() )
1324 if( SvxRTFPictureType::WIN_METAFILE
!= pPicType
->eStyle
&&
1325 pPicType
->nGoalWidth
&& pPicType
->nGoalHeight
)
1327 aSize
.Width() = pPicType
->nGoalWidth
;
1328 aSize
.Height() =pPicType
->nGoalHeight
;
1330 else if( SvxRTFPictureType::MAC_QUICKDRAW
== pPicType
->eStyle
)
1332 // IMMER auf 72 DPI bezogen, also 1pt == 20 Twip !!
1333 aSize
.Width() = pPicType
->nWidth
* 20;
1334 aSize
.Height() = pPicType
->nHeight
* 20;
1338 // von 100TH_MM nach TWIP umrechenen!
1339 // #117879# when \picwgoal resp \pichgoal are present, then use them.
1340 // The values of \picwgoal and \picwgoal are already given in twips.
1341 aSize
.Width() = (pPicType
->nGoalWidth
?pPicType
->nGoalWidth
:(pPicType
->nWidth
*144)/254);
1342 aSize
.Height() = (pPicType
->nGoalHeight
?pPicType
->nGoalHeight
:(pPicType
->nHeight
*144)/254);
1344 ((SwGrfNode
&)rNd
).SetTwipSize( aSize
);
1347 if( 100 != pPicType
->nScalX
)
1348 aSize
.Width() = (((long)pPicType
->nScalX
) * ( aSize
.Width() -
1349 ( pPicType
->nCropL
+ pPicType
->nCropR
))) / 100L;
1351 if( 100 != pPicType
->nScalY
)
1352 aSize
.Height() = (((long)pPicType
->nScalY
) * ( aSize
.Height() -
1353 ( pPicType
->nCropT
+ pPicType
->nCropB
))) / 100L;
1356 //steht der Fly etwa in einer Tabelle ?
1357 const SwNode
* pAnchorNd
= pDoc
->GetNodes()[ rAnchor
];
1358 const SwTableNode
* pTblNd
= pAnchorNd
->FindTableNode();
1362 const SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox(
1363 pAnchorNd
->StartOfSectionIndex() );
1366 long nBoxWidth
= pBox
->GetFrmFmt()->GetFrmSize().GetWidth();
1367 if( aSize
.Width() > nBoxWidth
)
1368 aSize
.Width() = nBoxWidth
;
1372 //JP 8.11.2001: bug 94450 - if no size exist, then the size is set by
1373 // the swapin of the graphic.
1375 if( !aSize
.Width() && !aSize
.Height() &&
1376 0 != (pGrfNd
= (SwGrfNode
*)rNd
.GetGrfNode() ) && pGrfNd
->IsGrfLink() )
1377 pGrfNd
->SetChgTwipSize( TRUE
);
1379 // min. Werte einhalten !!
1380 if( aSize
.Width() < MINFLY
)
1381 aSize
.Width() = MINFLY
;
1382 if( aSize
.Height() < MINFLY
)
1383 aSize
.Height() = MINFLY
;
1391 JP 28.07.99: Bug 67800 - no crop by MAC_QUICKDRAW. At time i dont know why
1392 it has been coded. But this has used for any
1393 RTF-File, but i dont found them.
1394 if( SvxRTFPictureType::MAC_QUICKDRAW == pPicType->eStyle )
1396 // evt. ein wenig Croppen ??
1397 // IMMER auf 72 DPI bezogen, also 1pt == 20 Twip !!
1398 long nTmp = pPicType->nWidth * 20;
1399 if( nTmp != aSize.Width() )
1401 // in der Breite (also rechts) croppen
1402 aCrop.Right() = nTmp - aSize.Width();
1403 aSize.Width() = nTmp;
1407 nTmp = pPicType->nHeight * 20;
1408 if( nTmp != aSize.Height() )
1410 // in der Hoehe (also unten) croppen
1411 aCrop.Bottom() = nTmp - aSize.Height();
1412 aSize.Height() = nTmp;
1417 if( pPicType
->nCropT
)
1419 aCrop
.SetTop( pPicType
->nCropT
);
1422 if( pPicType
->nCropB
)
1424 aCrop
.SetBottom( pPicType
->nCropB
);
1427 if( pPicType
->nCropL
)
1429 aCrop
.SetLeft( pPicType
->nCropL
);
1432 if( pPicType
->nCropR
)
1434 aCrop
.SetRight( pPicType
->nCropR
);
1440 // dann mal an die CropWerte an die GrafikSize anpassen.
1441 ((SwNoTxtNode
&)rNd
).SetAttr( aCrop
);
1444 rSet
.Put( SwFmtFrmSize( ATT_FIX_SIZE
, aSize
.Width(), aSize
.Height() ));
1447 void SwRTFParser::GetPageSize( Size
& rSize
)
1449 ASSERT(!maSegments
.empty(), "not possible");
1450 if (maSegments
.empty())
1452 rSize
.Width() = 12240 - 1800 - 1800;
1453 rSize
.Height() = 15840 - 1440 - 1440;
1457 const rtfSection
&rSect
= maSegments
.back();
1459 rSize
.Width() = rSect
.maPageInfo
.mnPgwsxn
- rSect
.maPageInfo
.mnMarglsxn
- rSect
.maPageInfo
.mnMargrsxn
;
1460 rSize
.Height() = rSect
.maPageInfo
.mnPghsxn
- rSect
.maPageInfo
.mnMargtsxn
- rSect
.maPageInfo
.mnMargbsxn
;
1462 long nCols
= rSect
.NoCols();
1465 rSize
.Width() /= nCols
;
1466 rSize
.Height() /= nCols
;
1470 void SwRTFParser::ReadBitmapData()
1473 SvxRTFPictureType aPicType
;
1474 if( ReadBmpData( aGrf
, aPicType
) )
1475 InsPicture( aEmptyStr
, &aGrf
, &aPicType
);
1478 #ifdef READ_OLE_OBJECT
1479 void SwRTFParser::ReadOLEData()
1481 SvCacheStream
aTmpFile( 0xA000 );
1483 SvxRTFPictureType aPicType
, aOleType
;
1485 int nToken
, bValidOle
= TRUE
, bWeiter
= TRUE
;
1486 int nOpenBrakets
= 1; // die erste wurde schon vorher erkannt !!
1489 String sObjClass
, sObjName
, sObjData
;
1491 while( nOpenBrakets
&& IsParserWorking() && bWeiter
&& bValidOle
)
1493 nToken
= GetNextToken();
1494 USHORT nVal
= USHORT( nTokenValue
);
1497 case '}': --nOpenBrakets
; pStr
= 0; break;
1500 if( RTF_IGNOREFLAG
!= GetNextToken() )
1501 nToken
= SkipToken( -1 );
1502 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
1503 nToken
= SkipToken( -2 );
1506 // gleich herausfiltern
1508 nToken
= GetNextToken();
1510 eState
= SVPAR_ERROR
;
1518 case RTF_OBJEMB
: // default ist embedded
1519 case RTF_LINKSELF
: // ??
1520 case RTF_OBJLOCK
: // ??
1521 case RTF_OBJUPDATE
: // ??
1522 case RTF_OBJTIME
: // ??
1523 case RTF_OBJSETSIZE
:
1529 case RTF_OBJLINK
: // ?? welche Daten sind das ??
1530 case RTF_OBJAUTLINK
: // ?? -""- ??
1538 bValidOle
= FALSE
; // diese Typen koennen wir nicht
1557 // hier weitermachen, wenn das OLE-Object ungueltig ist
1561 case RTF_RSLTBMP
: // diese sollten wir ignorieren
1568 case RTF_OBJW
: aOleType
.nWidth
= nVal
; break;
1569 case RTF_OBJH
: aOleType
.nHeight
= nVal
; break;
1570 case RTF_OBJCROPT
: aOleType
.nCropT
= (short)nTokenValue
; break;
1571 case RTF_OBJCROPB
: aOleType
.nCropB
= (short)nTokenValue
; break;
1572 case RTF_OBJCROPL
: aOleType
.nCropL
= (short)nTokenValue
; break;
1573 case RTF_OBJCROPR
: aOleType
.nCropR
= (short)nTokenValue
; break;
1574 case RTF_OBJSCALEX
: aOleType
.nScalX
= nVal
; break;
1575 case RTF_OBJSCALEY
: aOleType
.nScalY
= nVal
; break;
1578 if( 1 < nOpenBrakets
&& pStr
)
1580 if( pStr
== &sObjData
)
1582 xub_StrLen nHexLen
= HexToBin( aToken
);
1583 if( STRING_NOTFOUND
!= nHexLen
)
1587 aTmpFile
.Write( (sal_Char
*)aToken
.GetBuffer(), nHexLen
);
1588 bValidOle
= 0 == aTmpFile
.GetError();
1600 bValidOle
= FALSE
; // erstmal
1603 if( !bWeiter
) // dann stehen wir noch im Result
1605 // ist das Ole-Object Ok?
1606 // -> dann solange SkipGroup rufen, bis zur letzten
1607 // schliessenden Klammer
1608 // ansonsten alle Token verarbeiten, bis zur letzten
1609 // schliessenden Klammer
1612 while( nOpenBrakets
&& IsParserWorking() && bWeiter
)
1614 switch( nToken
= GetNextToken() )
1616 case '}': --nOpenBrakets
; break;
1617 case '{': ++nOpenBrakets
; break;
1619 if( nOpenBrakets
&& !bValidOle
)
1620 NextToken( nToken
);
1624 if( !bValidOle
&& '}' != nToken
)
1627 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
1631 /* vi:set tabstop=4 shiftwidth=4 expandtab: */