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: rtffly.cxx,v $
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 -*- */
34 #include <hintids.hxx>
35 #include <tools/list.hxx>
36 #include <tools/cachestr.hxx>
37 #include <svtools/rtftoken.h>
38 #include <svtools/itemiter.hxx>
39 #include <svx/prntitem.hxx>
40 #include <svx/opaqitem.hxx>
41 #include <svx/protitem.hxx>
42 #include <svx/ulspitem.hxx>
43 #include <svx/lrspitem.hxx>
44 #include <svx/boxitem.hxx>
45 #include <svx/frmdiritem.hxx>
46 #include <fmtfsize.hxx>
47 #include <fmtanchr.hxx>
48 #include <fmtpdsc.hxx>
49 #include <fmtsrnd.hxx>
50 #include <fmtclds.hxx>
51 #include <fmtcntnt.hxx>
56 #include <shellio.hxx>
57 #include <swparrtf.hxx>
62 #include <pagedesc.hxx>
63 #include <swtable.hxx>
64 #include <txtflcnt.hxx>
65 #include <fmtflcnt.hxx>
67 #ifndef __SGI_STL_DEQUE
73 #ifndef __SGI_STL_UTILITY
76 // --> OD 2004-06-30 #i27767#
77 #include <fmtwrapinfluenceonobjpos.hxx>
79 #include <svx/brshitem.hxx>
80 #include <fmtfollowtextflow.hxx>
81 // --> OD, FLR 2006-02-16 #131205#
82 #include "dcontact.hxx"
85 using namespace ::com::sun::star
;
87 #define ANCHOR(p) ((SwFmtAnchor*)p)
89 // steht in shellio.hxx
90 extern SwCntntNode
* GoNextNds( SwNodeIndex
* pIdx
, BOOL bChk
);
92 SV_IMPL_PTRARR( SwFlySaveArr
, SwFlySave
* )
94 inline const SwFmtFrmSize
GetFrmSize(const SfxItemSet
& rSet
, BOOL bInP
=TRUE
)
96 return (const SwFmtFrmSize
&)rSet
.Get(RES_FRM_SIZE
,bInP
);
99 SwFlySave::SwFlySave(const SwPaM
& rPam
, SfxItemSet
& rSet
)
100 : aFlySet(rSet
), nSttNd(rPam
.GetPoint()->nNode
), nEndNd(nSttNd
), nEndCnt(0),
101 nPageWidth(ATT_MIN_SIZE
), nDropLines(0), nDropAnchor(0)
105 int SwFlySave::IsEqualFly( const SwPaM
& rPos
, SfxItemSet
& rSet
)
107 if( rSet
.Count() != aFlySet
.Count() || nDropAnchor
)
110 // nur TextNodes zusammenfassen
111 if( nSttNd
== nEndNd
&& nEndNd
.GetNode().IsNoTxtNode() )
114 // teste auf gleiche / naechste Position
115 if( rPos
.GetPoint()->nNode
.GetIndex() == nEndNd
.GetIndex() )
117 if( 1 < (rPos
.GetPoint()->nContent
.GetIndex() - nEndCnt
) )
120 else if( rPos
.GetPoint()->nContent
.GetIndex() )
124 SwNodeIndex
aIdx( nEndNd
);
125 SwCntntNode
* pCNd
= rPos
.GetDoc()->GetNodes()[ aIdx
]->GetCntntNode();
126 if( !GoNextNds( &aIdx
, TRUE
) ||
127 aIdx
.GetIndex() != rPos
.GetPoint()->nNode
.GetIndex() ||
128 ( pCNd
&& pCNd
->Len() != nEndCnt
))
136 SfxItemIter
aIter( rSet
);
137 const SfxPoolItem
*pItem
, *pCurr
= aIter
.GetCurItem();
140 if( SFX_ITEM_SET
!= aFlySet
.GetItemState( pCurr
->Which(),
142 // Ankerattribute gesondert behandeln
143 ( RES_ANCHOR
== pCurr
->Which()
144 ? (ANCHOR(pCurr
)->GetAnchorId() != ANCHOR(pItem
)->GetAnchorId() ||
145 ANCHOR(pCurr
)->GetPageNum() != ANCHOR(pItem
)->GetPageNum())
146 : *pItem
!= *pCurr
))
149 if( aIter
.IsAtEnd() )
151 pCurr
= aIter
.NextItem();
157 void SwFlySave::SetFlySize( const SwTableNode
& rTblNd
)
159 // sollte der Fly kleiner als diese Tabelle sein, dann
160 // korrigiere diesen (nur bei abs. Angaben!)
161 SwTwips nWidth
= rTblNd
.GetTable().GetFrmFmt()->GetFrmSize().GetWidth();
162 const SwFmtFrmSize
& rSz
= GetFrmSize( aFlySet
);
163 if( nWidth
> rSz
.GetWidth() )
164 aFlySet
.Put( SwFmtFrmSize( rSz
.GetHeightSizeType(), nWidth
, rSz
.GetHeight() ));
167 BOOL
lcl_HasBreakAttrs( const SwCntntNode
& rNd
)
170 const SfxItemSet
& rSet
= rNd
.GetSwAttrSet();
171 const SfxPoolItem
* pItem
;
172 if( SFX_ITEM_SET
== rSet
.GetItemState( RES_BREAK
, TRUE
, &pItem
) &&
173 SVX_BREAK_NONE
!= ((SvxFmtBreakItem
*)pItem
)->GetBreak() )
175 else if( SFX_ITEM_SET
== rSet
.GetItemState( RES_PAGEDESC
, TRUE
, &pItem
)&&
176 0 != ((SwFmtPageDesc
*)pItem
)->GetPageDesc() )
182 void lcl_CpyBreakAttrs( SwCntntNode
* pSrcNd
, SwCntntNode
* pDstNd
,
183 SwNodeIndex
* pNewIdx
)
185 const SfxItemSet
* pSet
;
186 if( pSrcNd
&& pDstNd
&& 0 != ( pSet
= pSrcNd
->GetpSwAttrSet() ) )
188 const SfxPoolItem
*pDescItem
, *pBreakItem
;
190 if( SFX_ITEM_SET
!= pSet
->GetItemState( RES_BREAK
,
191 FALSE
, &pBreakItem
) )
194 if( SFX_ITEM_SET
!= pSet
->GetItemState( RES_PAGEDESC
,
195 FALSE
, &pDescItem
) )
198 if( pDescItem
|| pBreakItem
)
200 if( lcl_HasBreakAttrs( *pDstNd
))
202 SwPosition
aPos( *pDstNd
, SwIndex( pDstNd
));
204 pDstNd
->GetDoc()->AppendTxtNode( aPos
);
206 *pNewIdx
= aPos
.nNode
;
208 SwCntntNode
* pOldNd
= pDstNd
;
209 pDstNd
= aPos
.nNode
.GetNode().GetCntntNode();
210 pDstNd
->ChgFmtColl( pOldNd
->GetFmtColl() );
211 if( pDstNd
->HasSwAttrSet() )
213 SfxItemSet
aSet( *pDstNd
->GetpSwAttrSet() );
214 aSet
.ClearItem( RES_BREAK
);
215 aSet
.ClearItem( RES_PAGEDESC
);
216 pDstNd
->SetAttr( aSet
);
221 pDstNd
->SetAttr( *pBreakItem
);
222 pSrcNd
->ResetAttr( RES_BREAK
);
226 pDstNd
->SetAttr( *pDescItem
);
227 pSrcNd
->ResetAttr( RES_PAGEDESC
);
233 void SwRTFParser::SetFlysInDoc()
235 // !! von Oben abarbeiten, CntntPos ist kein Index !
236 SwNodes
& rNds
= pDoc
->GetNodes();
237 typedef std::pair
<SwFlyFrmFmt
*, SwFmtAnchor
> frameEntry
;
238 typedef std::deque
<frameEntry
> rtfframesAtIndex
;
239 typedef std::map
<const SwNode
*, rtfframesAtIndex
> rtfFmtMap
;
242 SwFrmFmt
* pParent
= pDoc
->GetFrmFmtFromPool( RES_POOLFRM_FRAME
);
243 for( USHORT n
= 0; n
< aFlyArr
.Count(); ++n
)
245 SwFlySave
* pFlySave
= aFlyArr
[ n
];
247 ASSERT( !pFlySave
->nSttNd
.GetNode().FindFlyStartNode(),
248 "Content vom Fly steht in einem Fly" );
249 ASSERT( pFlySave
->nSttNd
.GetIndex() <= pFlySave
->nEndNd
.GetIndex(),
250 "Fly hat falschen Bereich" );
254 //JP 21.09.98: wenn ein DropCap ist, dann Text im Node belassen, am
255 // Absatz das Absatz Attribut setzen. Ggfs noch die
256 // FontSize zuruecksetzen, damit das DropCap nicht zu
258 if( pFlySave
->nDropAnchor
)
260 SwTxtNode
* pSttNd
= pFlySave
->nSttNd
.GetNode().GetTxtNode();
261 SwTxtNode
* pEndNd
= pFlySave
->nEndNd
.GetNode().GetTxtNode();
262 if( pSttNd
&& pEndNd
&&
263 pSttNd
->GetIndex() + 1 == pEndNd
->GetIndex()
264 && pSttNd
->GetTxt().Len()>0 /* #i38227# leave drop caps with no content as fly frames */ )
266 ULONG nPos
= pSttNd
->GetIndex();
267 SwDoc
* pDoc1
= pSttNd
->GetDoc();
271 SwPaM
aTmp( *pSttNd
, pSttNd
->GetTxt().Len(), *pEndNd
, 0 );
272 bJoined
= pDoc1
->DeleteAndJoin( aTmp
);
275 SwTxtNode
* pNd
= (pDoc1
->GetNodes()[nPos
])->GetTxtNode();
277 if( bJoined
&& pNd
!= NULL
)
280 aDropCap
.GetLines() = (BYTE
)pFlySave
->nDropLines
;
281 aDropCap
.GetChars() = 1;
283 SwIndex
aIdx( pEndNd
);
284 pNd
->RstAttr( aIdx
, 1, RES_CHRATR_FONTSIZE
);
285 pNd
->SetAttr( aDropCap
);
292 // liegt Ende und Start vom Naechsten im gleichen Node, dann muss
294 if( n
+ 1 < aFlyArr
.Count() && pFlySave
->nEndCnt
&&
295 pFlySave
->nEndNd
== aFlyArr
[ n
+ 1 ]->nSttNd
)
297 SwCntntNode
* pCNd
= rNds
[ pFlySave
->nEndNd
]->GetCntntNode();
300 SwPosition
aPos( pFlySave
->nEndNd
,
301 SwIndex( pCNd
, pFlySave
->nEndCnt
));
302 pDoc
->SplitNode( aPos
, false );
306 pFlySave
->nEndCnt
= 0;
309 // verschiebe den Inhalt von diesem Anchor in den Auto-TextBereich
310 // und erzeuge dadurch den richtigen SwG-Rahmen
311 SwNodeRange
aRg(pFlySave
->nSttNd
, 0, pFlySave
->nEndNd
, 0);
312 //Make a new section, unless there is no content at all
313 const bool bMakeEmptySection
= aRg
.aStart
< aRg
.aEnd
|| ((aRg
.aStart
== aRg
.aEnd
) && pFlySave
->nEndCnt
);
316 // Nur TextNodes koennen in Tabellen stehen !!
317 const SwNode
* pNd
= &pFlySave
->nSttNd
.GetNode();
318 if( pNd
->IsNoTxtNode() )
320 // die Size muss noch korrigiert werden!
321 nAktPageDesc
= 0; // Standart PageDesc
322 if( SFX_ITEM_SET
!= pFlySave
->aFlySet
.GetItemState(
323 RES_FRM_SIZE
, FALSE
) )
324 _SetPictureSize( *(SwNoTxtNode
*)pNd
, aRg
.aStart
,
326 if( 0 != ( pNd
= pNd
->FindTableNode() ) )
327 pFlySave
->SetFlySize( *(SwTableNode
*)pNd
);
331 // Take care for table nodes
332 pNd
= pNd
->GetNodes()[ pNd
->GetIndex() - 2 ]->GetTableNode();
333 if( pNd
) // if the table starts imediately before aRg -> expand aRg
336 if( bMakeEmptySection
)
338 pNd
= &aRg
.aEnd
.GetNode();
339 ULONG nSectEnd
= pNd
->EndOfSectionIndex()+1;
341 if (!pNd
->IsTableNode() && 0 !=(pNd
= pNd
->FindTableNode())
342 && (pNd
->GetIndex() >= aRg
.aStart
.GetNode().GetIndex()) )
344 const SwNode
* pTblBxNd
;
346 // Ende der Tabelle ist hinter dieser Box ??
347 if( pNd
->EndOfSectionIndex() == nSectEnd
)
348 aRg
.aEnd
= nSectEnd
+1;
349 // is the end in the first box of the table, then
350 // move before the table (Bug 67663)
351 // but the range must not become emtpy, i.e. aStart==aEnd
352 // because otherwise we will get a crash (126506) later on
353 else if( 0 != ( pTblBxNd
= aRg
.aEnd
.GetNode().
354 FindTableBoxStartNode()) &&
355 pTblBxNd
->GetIndex() - 1 == pNd
->GetIndex() &&
356 &aRg
.aStart
.GetNode() != pNd
)
360 // Tabelle ist noch groesser, also splitte sie hier.
361 rNds
.SplitTable( aRg
.aEnd
, TRUE
);
362 aRg
.aEnd
= pNd
->EndOfSectionIndex() + 1;
369 // vorm verschieben muss sich der Index auf die alte Position
370 // gemerkt werden, der Index wird mit verschoben !!!
372 SwNodeIndex
aTmpIdx( rNds
.GetEndOfAutotext() );
373 SwStartNode
* pSttNd
= bMakeEmptySection
374 ? rNds
.MakeEmptySection( aTmpIdx
, SwFlyStartNode
)
375 : rNds
.MakeTextSection( aTmpIdx
, SwFlyStartNode
,
376 (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
378 // das ist die Verankerungs-Position (fuers Layout!)
379 pFlySave
->nSttNd
= aRg
.aStart
.GetIndex()-1;
380 if( bMakeEmptySection
)
382 // check: the move does not clear the surrounded section. If all
383 // nodes moved away, then create a new TxtNode
385 // i76403: an empty selection is not a good idea
386 if( aRg
.aStart
== aRg
.aEnd
&& aRg
.aStart
.GetNode().GetTxtNode() )
388 SwNodeIndex
aPrev( aRg
.aStart
, -1 );
389 if( aPrev
.GetNode().IsStartNode() &&
390 aPrev
.GetNode().EndOfSectionNode() == &aRg
.aEnd
.GetNode())
392 // create new txtnode, because the section does never be empty
393 pDoc
->GetNodes().MakeTxtNode( aRg
.aEnd
,
394 (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
398 aTmpIdx
= *pSttNd
->EndOfSectionNode();
399 pDoc
->MoveNodeRange( aRg
, aTmpIdx
,
400 IDocumentContentOperations::DOC_MOVEDEFAULT
);
403 // patch from cmc for #i52542#
404 if (pSttNd
->GetIndex() + 1 == pSttNd
->EndOfSectionIndex())
406 ASSERT(!this, "nothing in this frame, not legal");
411 pFlySave
->aFlySet
.Put( SwFmtCntnt( pSttNd
));
413 CalculateFlySize( pFlySave
->aFlySet
, pFlySave
->nSttNd
,
414 pFlySave
->nPageWidth
);
417 // if the section only contains one Node and this has a
418 // border or backgorund, then put it to the frame
419 // Not in our own RTF-Format!
420 // <<<<< DOES NOT MAKE SENSE TO ME (flr)
421 // #102781#. Added support for transparent frames.
422 if( pSttNd
->GetIndex() + 1 != pSttNd
->EndOfSectionIndex() &&
425 SwCntntNode
* pSrcNd
= pDoc
->GetNodes()[ pSttNd
->GetIndex() + 1 ]->GetCntntNode();
426 SfxItemSet
aTmpSet( pDoc
->GetAttrPool(),
427 RES_BACKGROUND
, RES_BOX
);
428 const SvxBrushItem
* pBackgroundBrush
= (const SvxBrushItem
*)pFlySave
->aFlySet
.GetItem(RES_BACKGROUND
, FALSE
);
429 if( pSrcNd
&& pSrcNd
->HasSwAttrSet() )
430 aTmpSet
.Put( *pSrcNd
->GetpSwAttrSet() );
431 if (pBackgroundBrush
)
433 aTmpSet
.Put(*pBackgroundBrush
, RES_BACKGROUND
);
437 pBackgroundBrush
= (const SvxBrushItem
*)aTmpSet
.GetItem(RES_BACKGROUND
, FALSE
);
438 if (pBackgroundBrush
)
440 Color
& rBackgroundColor
= const_cast<SvxBrushItem
*>(pBackgroundBrush
)->GetColor();
441 rBackgroundColor
.SetTransparency(0xFE);
445 Color aColor
= Color(0xff, 0xff, 0xff);
446 aColor
.SetTransparency( 0xFE);
447 SvxBrushItem
aBrush(aColor
, RES_BACKGROUND
);
448 aTmpSet
.Put(aBrush
, RES_BACKGROUND
);
452 pFlySave
->aFlySet
.Put( aTmpSet
);
453 if( pSrcNd
&& pSrcNd
->HasSwAttrSet() )
455 pSrcNd
->ResetAttr( RES_BACKGROUND
, RES_BOX
);
459 SwFlyFrmFmt
* pFmt
= pDoc
->MakeFlyFrmFmt( aEmptyStr
, pParent
);
460 pFmt
->SetFmtAttr( pFlySave
->aFlySet
);
461 const SwFmtAnchor
& rAnchor
= pFmt
->GetAnchor();
462 if( FLY_IN_CNTNT
!= rAnchor
.GetAnchorId() )
464 // korrigiere noch den Absatz, ist immer der vorhergehende !
465 // JP 20.09.95: wenn es diesen gibt! (DocAnfang!)
467 //JP 02.08.99: that is wrong. The anchor is ever the NEXT!
468 //JP 05.08.99: there are an Bug in the ExportFilter which will
469 // be fixed in the Version 517 - by SWG-Export
470 // the fly will be after the paragraph - but in RTF
471 // the flys will be before the paragraph.
472 if( !bSwPageDesc
|| 5430 < GetVersionNo() )
475 // if( !pFlySave->nSttNd.GetNode().IsCntntNode() )
477 // Seitenumbrueche in den Bodybereich verschieben!
478 SwCntntNode
* pSrcNd
= aRg
.aStart
.GetNode().GetCntntNode();
479 SwCntntNode
* pDstNd
= pFlySave
->nSttNd
.GetNode().GetCntntNode();
481 pDstNd
= pDoc
->GetNodes().GoNext( &pFlySave
->nSttNd
);
483 ::lcl_CpyBreakAttrs( pSrcNd
, pDstNd
, &pFlySave
->nSttNd
);
486 const SwNodeIndex
aSttNd(*pSttNd
);
487 SwNodeIndex
aEndNd(*pSttNd
->EndOfSectionNode());
490 SwPosition
aPos( pFlySave
->nSttNd
);
491 SwFmtAnchor
aAnchor(rAnchor
);
492 aAnchor
.SetAnchor(&aPos
);
494 const SwNode
*pCurrentAnchor
= &(pFlySave
->nSttNd
.GetNode());
495 aPrevFmts
[pCurrentAnchor
].push_back(frameEntry(pFmt
, aAnchor
));
497 while (aEndNd
> aSttNd
)
499 typedef rtfframesAtIndex::iterator myIter
;
500 rtfframesAtIndex
&rDeque
= aPrevFmts
[&(aEndNd
.GetNode())];
501 myIter aEnd
= rDeque
.end();
502 for (myIter aIter
= rDeque
.begin(); aIter
!= aEnd
; ++aIter
)
504 aIter
->second
.SetAnchor(&aPos
);
505 // --> OD 2004-06-30 #i27767# - push on front to keep order
506 // of objects for the correct object positioning
507 //aPrevFmts[pCurrentAnchor].push_back(*aIter);
508 aPrevFmts
[pCurrentAnchor
].push_front(*aIter
);
515 // --> OD, FLR 2006-02-16 #131205#
516 // Create draw contact object, which also creates a <SdrObject> instance,
517 // in order to set the order number.
518 // The order number is assumed to be the order of the text flow.
519 SwFlyDrawContact
* pContact
=
520 new SwFlyDrawContact( pFmt
,
521 pFmt
->GetDoc()->GetOrCreateDrawModel() );
522 pContact
->GetMaster()->SetOrdNum( n
);
528 typedef rtfFmtMap::reverse_iterator myriter
;
529 myriter aEnd
= aPrevFmts
.rend();
530 for(myriter aIter
= aPrevFmts
.rbegin(); aIter
!= aEnd
; ++aIter
)
532 rtfframesAtIndex
&rDeque
= aIter
->second
;
533 typedef rtfframesAtIndex::iterator myIter
;
534 myIter aQEnd
= rDeque
.end();
535 for (myIter aQIter
= rDeque
.begin(); aQIter
!= aQEnd
; ++aQIter
)
537 frameEntry
&rEntry
= *aQIter
;
538 SwFlyFrmFmt
*pFrm
= rEntry
.first
;
539 SwFmtAnchor
&rAnchor
= rEntry
.second
;
540 pFrm
->SetFmtAttr(rAnchor
);
544 aFlyArr
.Remove(0, aFlyArr
.Count());
547 // clips the text box to the min or max position if it is outside our min or max boundry
548 long SwRTFParser::GetSafePos(long nPos
)
552 else if(nPos
< SHRT_MIN
)
558 void SwRTFParser::ReadFly( int nToken
, SfxItemSet
* pSet
)
560 // ein Set fuer die FrmFmt-Attribute
561 SfxItemSet
aSet( pDoc
->GetAttrPool(), RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
563 Reader::ResetFrmFmtAttrs( aSet
);
565 // der Fly beginnt immer in einem neuen Absatz
566 if( pPam
->GetPoint()->nContent
.GetIndex() )
569 // RTF-Defaults setzen:
570 // --> OD 2004-06-24 #i27767#
571 SwFmtAnchor
aAnchor( FLY_AT_CNTNT
);
573 SwFmtHoriOrient
aHori( 0, text::HoriOrientation::LEFT
, text::RelOrientation::FRAME
);
574 SwFmtVertOrient
aVert( 0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
);
576 SvxFrameDirectionItem
aFrmDir( FRMDIR_HORI_LEFT_TOP
, RES_FRAMEDIR
);
578 USHORT nCols
= USHRT_MAX
, nColSpace
= USHRT_MAX
, nAktCol
= 0;
581 BOOL bChkDropCap
= 0 == pSet
;
582 USHORT nDropCapLines
= 0, nDropCapAnchor
= 0;
583 int nNumOpenBrakets
= GetOpenBrakets();
591 // die Werte aus dem uebergebenen!
592 aAnchor
= (SwFmtAnchor
&)pSet
->Get( RES_ANCHOR
);
593 aHori
= (SwFmtHoriOrient
&)pSet
->Get( RES_HORI_ORIENT
);
594 aVert
= (SwFmtVertOrient
&)pSet
->Get( RES_VERT_ORIENT
);
597 // dann sammel mal alle Attribute zusammen
601 USHORT nVal
= USHORT(nTokenValue
);
604 Assume that a property genuinely contributes towards creating a frame,
605 and if turns out to be a non contributing one reduce the count.
612 SwFmtFrmSize
aSz( ATT_MIN_SIZE
, nTokenValue
, 0 );
613 const SfxPoolItem
* pItem
;
614 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_FRM_SIZE
, TRUE
,
617 aSz
.SetHeightSizeType( ((SwFmtFrmSize
*)pItem
)->GetHeightSizeType() );
618 aSz
.SetHeight( ((SwFmtFrmSize
*)pItem
)->GetHeight() );
620 if( MINFLY
> nTokenValue
) nTokenValue
= MINFLY
;
626 SwFmtFrmSize
aSz( ATT_MIN_SIZE
, 0, MINFLY
);
627 const SfxPoolItem
* pItem
;
628 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_FRM_SIZE
, TRUE
,
631 aSz
.SetWidth( ((SwFmtFrmSize
*)pItem
)->GetWidth() );
634 if( 0 > nTokenValue
)
636 nTokenValue
= -nTokenValue
;
637 aSz
.SetHeightSizeType( ATT_FIX_SIZE
);
639 if( MINFLY
> nTokenValue
) nTokenValue
= MINFLY
;
640 aSz
.SetHeight( nTokenValue
);
647 pSet
->Put( SwFmtSurround( SURROUND_NONE
));
652 SvxULSpaceItem
aUL( RES_UL_SPACE
);
653 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
654 aUL
.SetUpper( nVal
); aUL
.SetLower( nVal
);
655 aLR
.SetLeft( nVal
); aLR
.SetRight( nVal
);
663 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
664 aLR
.SetLeft( nVal
); aLR
.SetRight( nVal
);
670 SvxULSpaceItem
aUL( RES_UL_SPACE
);
671 aUL
.SetUpper( nVal
); aUL
.SetLower( nVal
);
677 case RTF_POSX
: aHori
.SetHoriOrient( text::HoriOrientation::NONE
);
678 aHori
.SetPos( GetSafePos((long)nTokenValue
) );
680 case RTF_POSXC
: aHori
.SetHoriOrient( text::HoriOrientation::CENTER
); break;
681 case RTF_POSXI
: aHori
.SetHoriOrient( text::HoriOrientation::LEFT
);
682 aHori
.SetPosToggle( TRUE
);
684 case RTF_POSXO
: aHori
.SetHoriOrient( text::HoriOrientation::RIGHT
);
685 aHori
.SetPosToggle( TRUE
);
687 case RTF_POSXL
: aHori
.SetHoriOrient( text::HoriOrientation::LEFT
); break;
688 case RTF_POSXR
: aHori
.SetHoriOrient( text::HoriOrientation::RIGHT
); break;
691 case RTF_POSY
: aVert
.SetVertOrient( text::VertOrientation::NONE
);
692 aVert
.SetPos( GetSafePos((long)nTokenValue
) );
694 case RTF_POSYT
: aVert
.SetVertOrient( text::VertOrientation::TOP
); break;
695 case RTF_POSYB
: aVert
.SetVertOrient( text::VertOrientation::BOTTOM
); break;
696 case RTF_POSYC
: aVert
.SetVertOrient( text::VertOrientation::CENTER
); break;
698 case RTF_PHMRG
: aHori
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
); break;
699 case RTF_PVMRG
: aVert
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
); break;
700 case RTF_PHPG
: aHori
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
); break;
701 case RTF_PVPG
: aVert
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);break;
702 case RTF_PHCOL
: aHori
.SetRelationOrient( text::RelOrientation::FRAME
); break;
703 case RTF_PVPARA
: aVert
.SetRelationOrient( text::RelOrientation::FRAME
); break;
710 Not sufficient to make a frame at least word won't do it with just
716 aFrmDir
.SetValue( FRMDIR_HORI_LEFT_TOP
);
719 aFrmDir
.SetValue( FRMDIR_HORI_RIGHT_TOP
);
722 aFrmDir
.SetValue( FRMDIR_VERT_TOP_LEFT
);
725 aFrmDir
.SetValue( FRMDIR_VERT_TOP_RIGHT
);
728 case RTF_DROPCAPLI
: // Dropcaps !!
731 nDropCapLines
= USHORT( nTokenValue
);
732 if( !nDropCapAnchor
)
739 nDropCapAnchor
= USHORT( nTokenValue
);
746 // fuer die "alten" Writer - haben die Spaltigkeit falsch heraus-
748 case RTF_COLS
: nCols
= USHORT( nTokenValue
); break;
749 case RTF_COLSX
: nColSpace
= USHORT( nTokenValue
); break;
751 nAktCol
= USHORT( nTokenValue
);
752 if( RTF_COLW
== GetNextToken() )
754 USHORT nWidth
= USHORT( nTokenValue
), nSpace
= 0;
755 if( RTF_COLSR
== GetNextToken() )
756 nSpace
= USHORT( nTokenValue
);
758 SkipToken( -1 ); // wieder zurueck
760 if( --nAktCol
== ( aColumns
.Count() / 2 ) )
762 aColumns
.Insert( nWidth
+ nSpace
, aColumns
.Count() );
763 aColumns
.Insert( nSpace
, aColumns
.Count() );
771 if( RTF_IGNOREFLAG
!= ( nToken
= GetNextToken() ))
773 if( RTF_SHADINGDEF
== (nToken
& ~0xff) )
775 ReadBackgroundAttr( nToken
, aSet
);
776 GetNextToken(); // Klammer ueberlesen
781 else if( RTF_APOCTL
==
782 ((nToken
= GetNextToken() ) & ~(0xff | RTF_SWGDEFS
)) )
784 bReadSwFly
= true; // alles kommt in den akt. Fly
785 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
786 SvxULSpaceItem
aUL( RES_UL_SPACE
);
787 nCols
= USHRT_MAX
; // neu aufsetzen
788 nColSpace
= USHRT_MAX
;
790 nVal
= USHORT(nTokenValue
);
796 pSet
->Put( SvxPrintItem( RES_PRINT
, FALSE
));
801 pSet
->Put( SvxOpaqueItem( RES_OPAQUE
, FALSE
));
807 RTFProtect
aP( (BYTE
)nTokenValue
);
808 SvxProtectItem
aProtectItem( RES_PROTECT
);
809 aProtectItem
.SetCntntProtect( aP
.GetCntnt() );
810 aProtectItem
.SetSizeProtect( aP
.GetSize() );
811 aProtectItem
.SetPosProtect( aP
.GetPos() );
812 pSet
->Put( aProtectItem
);
818 RTFSurround
aMC( (BYTE
)nTokenValue
);
819 SwFmtSurround
aSurr( (SwSurround
)aMC
.GetOrder());
820 if( aMC
.GetGoldCut() )
821 aSurr
.SetSurround( SURROUND_IDEAL
);
827 RTFVertOrient
aVO( nVal
);
828 aVert
.SetVertOrient( aVO
.GetOrient() );
829 aVert
.SetRelationOrient( aVO
.GetRelation() );
834 RTFHoriOrient
aHO( nVal
);
835 aHori
.SetHoriOrient( aHO
.GetOrient() );
836 aHori
.SetRelationOrient( aHO
.GetRelation() );
839 case RTF_FLYOUTLEFT
: aLR
.SetLeft( nVal
); break;
840 case RTF_FLYOUTRIGHT
: aLR
.SetRight( nVal
); break;
841 case RTF_FLYOUTUPPER
: aUL
.SetUpper( nVal
); break;
842 case RTF_FLYOUTLOWER
: aUL
.SetLower( nVal
); break;
844 switch( GetNextToken() )
847 aAnchor
.SetType( FLY_PAGE
);
848 aAnchor
.SetPageNum( USHORT(nTokenValue
));
849 aAnchor
.SetAnchor( 0 );
854 SwNodeIndex
aIdx( pPam
->GetPoint()->nNode
);
855 pDoc
->GetNodes().GoPrevious( &aIdx
);
856 SwPosition
aPos( aIdx
);
857 aAnchor
.SetType( FLY_AT_CNTNT
);
858 aAnchor
.SetAnchor( &aPos
);
862 // JP 26.09.94: die Bindung an die Spalte gibt es nicht mehr !!
863 // case RTF_FLY_COLUMN:
866 case RTF_COLS
: nCols
= USHORT( nTokenValue
); break;
867 case RTF_COLSX
: nColSpace
= USHORT( nTokenValue
); break;
869 nAktCol
= USHORT( nTokenValue
);
870 if( RTF_COLW
== GetNextToken() )
872 USHORT nWidth
= USHORT( nTokenValue
), nSpace
= 0;
873 if( RTF_COLSR
== GetNextToken() )
874 nSpace
= USHORT( nTokenValue
);
876 SkipToken( -1 ); // wieder zurueck
878 if( --nAktCol
== ( aColumns
.Count() / 2 ) )
880 aColumns
.Insert( nWidth
+ nSpace
, aColumns
.Count() );
881 aColumns
.Insert( nSpace
, aColumns
.Count() );
887 if( RTF_BRDBOX
== ( nToken
= GetNextToken() ) )
888 ReadBorderAttr( nToken
, aSet
);
889 else if( RTF_SHADINGDEF
== (nToken
& ~0xff ) )
890 ReadBackgroundAttr( nToken
, aSet
);
891 else if( RTF_IGNOREFLAG
== nToken
)
894 switch( nToken
= GetNextToken() )
898 ReadAttr( SkipToken( -2 ), &aSet
);
907 ReadBorderAttr( SkipToken( -2 ), aSet
);
911 // keine weitere Klammer mehr ueberlesen!!!
919 GetNextToken(); // Klammer ueberlesen
922 } while( IsParserWorking() &&
923 '}' != ( nToken
= GetNextToken() ));
925 if( aUL
.GetUpper() || aUL
.GetLower() )
927 if( aLR
.GetLeft() || aLR
.GetRight() )
930 else if( RTF_BRDBOX
== nToken
)
931 ReadBorderAttr( nToken
, aSet
);
932 else if( RTF_SHADOW
== nToken
)
933 ReadAttr( SkipToken( -2 ), &aSet
);
934 else if( RTF_SHADINGDEF
== (nToken
& ~0xff ) )
935 ReadBackgroundAttr( nToken
, aSet
);
936 else if( RTF_UNKNOWNCONTROL
== nToken
)
943 nToken
= SkipToken( nSkip
);
950 --nAppliedProps
; //Not sufficient to make a frame
955 nToken
= GetNextToken();
956 } while( bWeiter
&& IsParserWorking() );
958 pSet
->Put( aAnchor
);
962 // --> OD 2004-06-30 #i27767# - set wrapping style influence
963 // --> OD 2004-10-18 #i35017# - constant name has changed
964 pSet
->Put( SwFmtWrapInfluenceOnObjPos(
965 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE
));
968 SwFmtFollowTextFlow
aFollowTextFlow( FALSE
);
969 pSet
->Put( aFollowTextFlow
);
971 if( !( aFrmDir
== pSet
->Get( RES_FRAMEDIR
)) )
972 pSet
->Put( aFrmDir
);
974 if( nCols
&& USHRT_MAX
!= nCols
)
977 if( USHRT_MAX
== nColSpace
)
980 ULONG nWidth
= USHRT_MAX
;
981 aCol
.Init( nCols
, nColSpace
, USHORT( nWidth
) );
982 if( nCols
== ( aColumns
.Count() / 2 ) )
984 for( USHORT n
= 0, i
= 0; n
< aColumns
.Count(); n
+= 2, ++i
)
986 SwColumn
* pCol
= aCol
.GetColumns()[ i
];
987 ULONG nTmp
= aColumns
[ n
];
990 pCol
->SetWishWidth( USHORT(nTmp
) );
992 JP 07.07.95: der Dialog kennt nur eine Breite fuer alle Spalten
993 darum hier nicht weiter beachten
994 nTmp = aColumns[ n+1 ];
996 pCol->SetRight( USHORT(nTmp) );
1006 if( pSet
!= &aSet
) // wurde der Set uebergeben, dann wars das
1009 // ein neues FlyFormat anlegen oder das alte benutzen ?
1010 // (teste ob es die selben Attribute besitzt!)
1011 SwFlySave
* pFlySave
= 0;
1012 USHORT nFlyArrCnt
= aFlyArr
.Count();
1015 There were not enough frame properties found to actually justify creating
1016 an absolutely positioned frame.
1021 !( pFlySave
= aFlyArr
[ nFlyArrCnt
-1 ])->IsEqualFly( *pPam
, aSet
))
1023 pFlySave
= new SwFlySave( *pPam
, aSet
);
1025 GetPageSize( aPgSize
);
1026 pFlySave
->nPageWidth
= aPgSize
.Width();
1028 if( nDropCapAnchor
)
1030 pFlySave
->nDropAnchor
= nDropCapAnchor
;
1031 pFlySave
->nDropLines
= nDropCapLines
;
1034 SwFlySave
* pFlySavePrev
= aFlyArr
[nFlyArrCnt
-1];
1035 if (pFlySave
->nSttNd
.GetIndex() < pFlySavePrev
->nEndNd
.GetIndex())
1037 pFlySavePrev
->nEndNd
=pFlySave
->nSttNd
;
1040 aFlyArr
.Insert( pFlySave
, nFlyArrCnt
++ );
1041 // --> OD 2008-12-22 #i83368# - reset
1042 mbReadCellWhileReadSwFly
= false;
1047 SetPardTokenRead( FALSE
);
1048 const SwTableNode
* pTblNd
= pPam
->GetNode()->FindTableNode();
1050 while( !IsPardTokenRead() && IsParserWorking() )
1052 if( RTF_PARD
== nToken
|| nNumOpenBrakets
> GetOpenBrakets() )
1055 NextToken( nToken
);
1057 if( !IsPardTokenRead() )
1059 // #102781#. Added support for transparent frames.
1060 if (nToken
== RTF_CBPAT
&& nFlyArrCnt
> 0)
1062 USHORT _index
=USHORT(nTokenValue
);
1063 const Color
& rColor
= GetColor(_index
);
1064 SvxBrushItem
aBrush(rColor
, RES_BACKGROUND
);
1065 SwFlySave
* pFS
= aFlyArr
[nFlyArrCnt
-1];
1066 pFS
->aFlySet
.Put(aBrush
, RES_BACKGROUND
);
1069 nToken
= GetNextToken();
1071 // BUG 22036: kommt zwischen Fly-Attributen ein unbekanntes,
1072 // dann erzeuge nie 2 FlyFrames, sondern fasse
1073 // beide zusammen !!!
1074 while( RTF_APOCTL
== ( nToken
& ~(0xff | RTF_SWGDEFS
) ))
1076 if( RTF_FLY_INPARA
== nToken
)
1079 if( RTF_IGNOREFLAG
== SkipToken( -1 ) )
1081 if( '{' == SkipToken( -1 ) )
1089 ReadFly( nToken
, pFlySave
? &pFlySave
->aFlySet
: 0);
1090 nToken
= GetNextToken();
1097 There were enough frame properties found to actually justify creating
1098 an absolutely positioned frame.
1107 if( pTblNd
&& !pPam
->GetPoint()->nContent
.GetIndex() &&
1108 pTblNd
->EndOfSectionIndex() + 1 ==
1109 pPam
->GetPoint()->nNode
.GetIndex() )
1111 // nicht mehr in der Tabelle, sondern dahinter ?
1112 // Dann aber wieder zurueck in die Tabelle
1113 pPam
->Move( fnMoveBackward
);
1118 // wurde garnichts eingefuegt?
1120 pPam
->GetPoint()->nNode
== pFlySave
->nSttNd
&&
1121 !pPam
->GetPoint()->nContent
.GetIndex() )
1123 // // dann erzeuge mindestens einen leeren TextNode
1124 // pDoc->AppendTxtNode(*pPam);
1125 // dann zerstoere den FlySave wieder.
1126 aFlyArr
.DeleteAndDestroy( --nFlyArrCnt
);
1131 BOOL bMovePaM
= 0 != pTblNd
;
1133 pFlySave
->nEndNd
= pPam
->GetPoint()->nNode
;
1134 pFlySave
->nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
1137 pPam
->Move( fnMoveForward
);
1139 pTblNd
= pFlySave
->nSttNd
.GetNode().FindTableNode();
1140 if( pTblNd
&& !pFlySave
->nEndCnt
&&
1141 pTblNd
== pFlySave
->nEndNd
.GetNode().FindTableNode() )
1143 // dann teste mal, ob das \pard nicht zu spaet kam und
1144 // eigentlich in die vorherige Zelle gehoert
1145 const SwStartNode
* pSttBoxNd
= pFlySave
->nSttNd
.GetNode().
1146 FindTableBoxStartNode(),
1147 * pEndBoxNd
= pFlySave
->nEndNd
.GetNode().
1148 FindTableBoxStartNode();
1149 if( pSttBoxNd
&& pEndBoxNd
&&
1150 bMovePaM
? ( pSttBoxNd
== pEndBoxNd
)
1151 : ( pSttBoxNd
->EndOfSectionIndex() + 1 ==
1152 pEndBoxNd
->GetIndex() &&
1153 pEndBoxNd
->GetIndex() + 1 ==
1154 pFlySave
->nEndNd
.GetIndex() ))
1156 // dann gehoert das Ende in die vorherige Box!
1157 SwPosition
aPos( *pPam
->GetPoint() );
1158 pPam
->GetPoint()->nNode
= *pSttBoxNd
->EndOfSectionNode();
1159 pPam
->Move( fnMoveBackward
, fnGoNode
);
1163 pPam
->GetPoint()->nNode
= *pSttBoxNd
->EndOfSectionNode();
1164 pPam
->Move( fnMoveBackward
, fnGoNode
);
1166 pFlySave
->nEndNd
= pPam
->GetPoint()->nNode
;
1167 pFlySave
->nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
1169 *pPam
->GetPoint() = aPos
;
1172 else if( !bReadSwFly
&& !pFlySave
->nEndCnt
&&
1173 pFlySave
->nSttNd
.GetIndex() + 1 == pFlySave
->nEndNd
.GetIndex() &&
1174 pFlySave
->nSttNd
.GetNode().IsTxtNode() )
1177 SwTxtNode
* pTxtNd
= pFlySave
->nSttNd
.GetNode().GetTxtNode();
1178 SwTxtFlyCnt
* pFlyCnt
= 0;
1179 if( 1 == pTxtNd
->GetTxt().Len() &&
1180 0 != ( pFlyCnt
= (SwTxtFlyCnt
*)pTxtNd
->GetTxtAttr(
1181 0, RES_TXTATR_FLYCNT
)) &&
1182 pFlyCnt
->GetFlyCnt().GetFrmFmt() )
1184 // then move the content into the surrounded fly
1185 SwFrmFmt
* pFlyFmt
= pFlyCnt
->GetFlyCnt().GetFrmFmt();
1186 const SwNodeIndex
* pFlySNd
= pFlyFmt
->GetCntnt().GetCntntIdx();
1187 SwNodeRange
aRg( *pFlySNd
, 1,
1188 *pFlySNd
->GetNode().EndOfSectionNode(), 0 );
1190 // merge the itemsets
1191 SwFmtFrmSize
aSz1( (SwFmtFrmSize
&)pFlyFmt
->GetAttrSet().
1192 Get( RES_FRM_SIZE
));
1193 SwFmtFrmSize
aSz2( (SwFmtFrmSize
&)pFlySave
->aFlySet
.
1194 Get( RES_FRM_SIZE
));
1196 if( !aRg
.aStart
.GetNode().IsNoTxtNode() ||
1197 !aSz1
.GetHeight() || !aSz1
.GetWidth() ||
1198 !aSz2
.GetHeight() || !aSz2
.GetWidth() ||
1199 ( aSz1
.GetHeight() == aSz2
.GetHeight() &&
1200 aSz1
.GetWidth() == aSz2
.GetWidth() ) )
1202 SfxItemSet
aDiffs( pFlyFmt
->GetAttrSet() );
1203 aDiffs
.ClearItem( RES_ANCHOR
);
1204 aDiffs
.ClearItem( RES_FRM_SIZE
);
1205 aDiffs
.ClearItem( RES_CNTNT
);
1206 aDiffs
.Differentiate( pFlySave
->aFlySet
);
1207 pFlySave
->aFlySet
.Put( aDiffs
);
1210 if( aSz1
.GetHeight() && !aSz2
.GetHeight() )
1213 aSz2
.SetHeight( aSz1
.GetHeight() );
1215 if( aSz1
.GetWidth() && !aSz2
.GetWidth() )
1218 aSz2
.SetWidth( aSz1
.GetWidth() );
1221 pFlySave
->aFlySet
.Put( aSz2
);
1223 // move any PageBreak/Desc Attr to the next Para
1225 SwCntntNode
* pSrcNd
= pFlySave
->nSttNd
.GetNode().GetCntntNode();
1226 SwCntntNode
* pDstNd
= pFlySave
->nEndNd
.GetNode().GetCntntNode();
1228 ::lcl_CpyBreakAttrs( pSrcNd
, pDstNd
, &pFlySave
->nEndNd
);
1231 // create new txtnode, because the section does never be empty
1232 pDoc
->GetNodes().MakeTxtNode( aRg
.aStart
,
1233 (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
1235 SwNodeIndex
aTmp( pFlySave
->nSttNd
, +1 );
1236 pDoc
->MoveNodeRange( aRg
, aTmp
,
1237 IDocumentContentOperations::DOC_MOVEDEFAULT
);
1239 // now delete the redundant txtnode
1240 pDoc
->GetNodes().Delete( pFlySave
->nSttNd
, 1 );
1251 void SwRTFParser::InsPicture( const String
& rGrfNm
, const Graphic
* pGrf
,
1252 const SvxRTFPictureType
* pPicType
)
1254 // kennzeichen fuer Swg-Dokumente:
1255 // (dann ist das FlyFmt fuer die Grafik!)
1257 // --> OD 2008-12-22 #i83368#
1258 // Assure that graphic node is enclosed by fly frame node.
1260 if ( bReadSwFly
&& !mbReadCellWhileReadSwFly
)
1263 // erzeuge nur einen normalen GrafikNode und ersetze diesen gegen
1264 // den vorhandenen Textnode
1265 SwNodeIndex
& rIdx
= pPam
->GetPoint()->nNode
;
1266 pGrfNd
= pDoc
->GetNodes().MakeGrfNode( rIdx
,
1267 rGrfNm
, aEmptyStr
, // Name der Graphic !!
1269 (SwGrfFmtColl
*)pDoc
->GetDfltGrfFmtColl() );
1272 pGrfNd
->SetAttr( *pGrfAttrSet
);
1274 SwFlySave
* pFlySave
= aFlyArr
[ aFlyArr
.Count()-1 ];
1275 pFlySave
->nSttNd
= rIdx
.GetIndex() - 1;
1277 if( 1 < aFlyArr
.Count() )
1279 pFlySave
= aFlyArr
[ aFlyArr
.Count() - 2 ];
1280 if( pFlySave
->nEndNd
== rIdx
)
1281 pFlySave
->nEndNd
= rIdx
.GetIndex() - 1;
1286 // wenn normale RTF-Grafik, dann steht diese im Textfluss !
1287 SwAttrSet
aFlySet( pDoc
->GetAttrPool(), RES_OPAQUE
, /*RES_OPAQUE,
1288 RES_VERT_ORIENT,*/ RES_ANCHOR
);
1289 const SwPosition
* pPos
= pPam
->GetPoint();
1291 SwFmtAnchor
aAnchor( FLY_IN_CNTNT
);
1292 aAnchor
.SetAnchor( pPos
);
1293 aFlySet
.Put( aAnchor
);
1294 aFlySet
.Put( SwFmtVertOrient( 0, text::VertOrientation::TOP
));
1296 if (pDoc
->IsInHeaderFooter(pPos
->nNode
))
1298 SvxOpaqueItem
aOpaqueItem(RES_OPAQUE
, FALSE
);
1299 SwFmtSurround
aSurroundItem(SURROUND_THROUGHT
);
1300 aFlySet
.Put(aOpaqueItem
);
1301 aFlySet
.Put(aSurroundItem
);
1304 SwFrmFmt
* pFlyFmt
= pDoc
->Insert( *pPam
,
1305 rGrfNm
, aEmptyStr
, // Name der Graphic !!
1307 &aFlySet
, // Attribute fuer den FlyFrm
1308 pGrfAttrSet
, NULL
); // Attribute fuer die Grafik
1310 pGrfNd
= pDoc
->GetNodes()[ pFlyFmt
->GetCntnt().GetCntntIdx()->
1311 GetIndex()+1 ]->GetGrfNode();
1313 _SetPictureSize( *pGrfNd
, pPos
->nNode
,
1314 (SfxItemSet
&)pFlyFmt
->GetAttrSet(),
1319 DELETEZ( pGrfAttrSet
);
1322 void SwRTFParser::_SetPictureSize( const SwNoTxtNode
& rNd
,
1323 const SwNodeIndex
& rAnchor
,
1325 const SvxRTFPictureType
* pPicType
)
1327 Size
aSize( ((SwNoTxtNode
&)rNd
).GetTwipSize() );
1330 if( rNd
.IsGrfNode() )
1332 if( SvxRTFPictureType::WIN_METAFILE
!= pPicType
->eStyle
&&
1333 pPicType
->nGoalWidth
&& pPicType
->nGoalHeight
)
1335 aSize
.Width() = pPicType
->nGoalWidth
;
1336 aSize
.Height() =pPicType
->nGoalHeight
;
1338 else if( SvxRTFPictureType::MAC_QUICKDRAW
== pPicType
->eStyle
)
1340 // IMMER auf 72 DPI bezogen, also 1pt == 20 Twip !!
1341 aSize
.Width() = pPicType
->nWidth
* 20;
1342 aSize
.Height() = pPicType
->nHeight
* 20;
1346 // von 100TH_MM nach TWIP umrechenen!
1347 // #117879# when \picwgoal resp \pichgoal are present, then use them.
1348 // The values of \picwgoal and \picwgoal are already given in twips.
1349 aSize
.Width() = (pPicType
->nGoalWidth
?pPicType
->nGoalWidth
:(pPicType
->nWidth
*144)/254);
1350 aSize
.Height() = (pPicType
->nGoalHeight
?pPicType
->nGoalHeight
:(pPicType
->nHeight
*144)/254);
1352 ((SwGrfNode
&)rNd
).SetTwipSize( aSize
);
1355 if( 100 != pPicType
->nScalX
)
1356 aSize
.Width() = (((long)pPicType
->nScalX
) * ( aSize
.Width() -
1357 ( pPicType
->nCropL
+ pPicType
->nCropR
))) / 100L;
1359 if( 100 != pPicType
->nScalY
)
1360 aSize
.Height() = (((long)pPicType
->nScalY
) * ( aSize
.Height() -
1361 ( pPicType
->nCropT
+ pPicType
->nCropB
))) / 100L;
1364 //steht der Fly etwa in einer Tabelle ?
1365 const SwNode
* pAnchorNd
= pDoc
->GetNodes()[ rAnchor
];
1366 const SwTableNode
* pTblNd
= pAnchorNd
->FindTableNode();
1370 const SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox(
1371 pAnchorNd
->StartOfSectionIndex() );
1374 long nBoxWidth
= pBox
->GetFrmFmt()->GetFrmSize().GetWidth();
1375 if( aSize
.Width() > nBoxWidth
)
1376 aSize
.Width() = nBoxWidth
;
1380 //JP 8.11.2001: bug 94450 - if no size exist, then the size is set by
1381 // the swapin of the graphic.
1383 if( !aSize
.Width() && !aSize
.Height() &&
1384 0 != (pGrfNd
= (SwGrfNode
*)rNd
.GetGrfNode() ) && pGrfNd
->IsGrfLink() )
1385 pGrfNd
->SetChgTwipSize( TRUE
);
1387 // min. Werte einhalten !!
1388 if( aSize
.Width() < MINFLY
)
1389 aSize
.Width() = MINFLY
;
1390 if( aSize
.Height() < MINFLY
)
1391 aSize
.Height() = MINFLY
;
1399 JP 28.07.99: Bug 67800 - no crop by MAC_QUICKDRAW. At time i dont know why
1400 it has been coded. But this has used for any
1401 RTF-File, but i dont found them.
1402 if( SvxRTFPictureType::MAC_QUICKDRAW == pPicType->eStyle )
1404 // evt. ein wenig Croppen ??
1405 // IMMER auf 72 DPI bezogen, also 1pt == 20 Twip !!
1406 long nTmp = pPicType->nWidth * 20;
1407 if( nTmp != aSize.Width() )
1409 // in der Breite (also rechts) croppen
1410 aCrop.Right() = nTmp - aSize.Width();
1411 aSize.Width() = nTmp;
1415 nTmp = pPicType->nHeight * 20;
1416 if( nTmp != aSize.Height() )
1418 // in der Hoehe (also unten) croppen
1419 aCrop.Bottom() = nTmp - aSize.Height();
1420 aSize.Height() = nTmp;
1425 if( pPicType
->nCropT
)
1427 aCrop
.SetTop( pPicType
->nCropT
);
1430 if( pPicType
->nCropB
)
1432 aCrop
.SetBottom( pPicType
->nCropB
);
1435 if( pPicType
->nCropL
)
1437 aCrop
.SetLeft( pPicType
->nCropL
);
1440 if( pPicType
->nCropR
)
1442 aCrop
.SetRight( pPicType
->nCropR
);
1448 // dann mal an die CropWerte an die GrafikSize anpassen.
1449 ((SwNoTxtNode
&)rNd
).SetAttr( aCrop
);
1452 rSet
.Put( SwFmtFrmSize( ATT_FIX_SIZE
, aSize
.Width(), aSize
.Height() ));
1455 void SwRTFParser::GetPageSize( Size
& rSize
)
1457 ASSERT(!maSegments
.empty(), "not possible");
1458 if (maSegments
.empty())
1460 rSize
.Width() = 12240 - 1800 - 1800;
1461 rSize
.Height() = 15840 - 1440 - 1440;
1465 const rtfSection
&rSect
= maSegments
.back();
1467 rSize
.Width() = rSect
.maPageInfo
.mnPgwsxn
- rSect
.maPageInfo
.mnMarglsxn
- rSect
.maPageInfo
.mnMargrsxn
;
1468 rSize
.Height() = rSect
.maPageInfo
.mnPghsxn
- rSect
.maPageInfo
.mnMargtsxn
- rSect
.maPageInfo
.mnMargbsxn
;
1470 long nCols
= rSect
.NoCols();
1473 rSize
.Width() /= nCols
;
1474 rSize
.Height() /= nCols
;
1478 void SwRTFParser::ReadBitmapData()
1481 SvxRTFPictureType aPicType
;
1482 if( ReadBmpData( aGrf
, aPicType
) )
1483 InsPicture( aEmptyStr
, &aGrf
, &aPicType
);
1486 #ifdef READ_OLE_OBJECT
1487 void SwRTFParser::ReadOLEData()
1489 SvCacheStream
aTmpFile( 0xA000 );
1491 SvxRTFPictureType aPicType
, aOleType
;
1493 int nToken
, bValidOle
= TRUE
, bWeiter
= TRUE
;
1494 int nOpenBrakets
= 1; // die erste wurde schon vorher erkannt !!
1497 String sObjClass
, sObjName
, sObjData
;
1499 while( nOpenBrakets
&& IsParserWorking() && bWeiter
&& bValidOle
)
1501 nToken
= GetNextToken();
1502 USHORT nVal
= USHORT( nTokenValue
);
1505 case '}': --nOpenBrakets
; pStr
= 0; break;
1508 if( RTF_IGNOREFLAG
!= GetNextToken() )
1509 nToken
= SkipToken( -1 );
1510 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
1511 nToken
= SkipToken( -2 );
1514 // gleich herausfiltern
1516 nToken
= GetNextToken();
1518 eState
= SVPAR_ERROR
;
1526 case RTF_OBJEMB
: // default ist embedded
1527 case RTF_LINKSELF
: // ??
1528 case RTF_OBJLOCK
: // ??
1529 case RTF_OBJUPDATE
: // ??
1530 case RTF_OBJTIME
: // ??
1531 case RTF_OBJSETSIZE
:
1537 case RTF_OBJLINK
: // ?? welche Daten sind das ??
1538 case RTF_OBJAUTLINK
: // ?? -""- ??
1546 bValidOle
= FALSE
; // diese Typen koennen wir nicht
1565 // hier weitermachen, wenn das OLE-Object ungueltig ist
1569 case RTF_RSLTBMP
: // diese sollten wir ignorieren
1576 case RTF_OBJW
: aOleType
.nWidth
= nVal
; break;
1577 case RTF_OBJH
: aOleType
.nHeight
= nVal
; break;
1578 case RTF_OBJCROPT
: aOleType
.nCropT
= (short)nTokenValue
; break;
1579 case RTF_OBJCROPB
: aOleType
.nCropB
= (short)nTokenValue
; break;
1580 case RTF_OBJCROPL
: aOleType
.nCropL
= (short)nTokenValue
; break;
1581 case RTF_OBJCROPR
: aOleType
.nCropR
= (short)nTokenValue
; break;
1582 case RTF_OBJSCALEX
: aOleType
.nScalX
= nVal
; break;
1583 case RTF_OBJSCALEY
: aOleType
.nScalY
= nVal
; break;
1586 if( 1 < nOpenBrakets
&& pStr
)
1588 if( pStr
== &sObjData
)
1590 xub_StrLen nHexLen
= HexToBin( aToken
);
1591 if( STRING_NOTFOUND
!= nHexLen
)
1595 aTmpFile
.Write( (sal_Char
*)aToken
.GetBuffer(), nHexLen
);
1596 bValidOle
= 0 == aTmpFile
.GetError();
1608 bValidOle
= FALSE
; // erstmal
1611 if( !bWeiter
) // dann stehen wir noch im Result
1613 // ist das Ole-Object Ok?
1614 // -> dann solange SkipGroup rufen, bis zur letzten
1615 // schliessenden Klammer
1616 // ansonsten alle Token verarbeiten, bis zur letzten
1617 // schliessenden Klammer
1620 while( nOpenBrakets
&& IsParserWorking() && bWeiter
)
1622 switch( nToken
= GetNextToken() )
1624 case '}': --nOpenBrakets
; break;
1625 case '{': ++nOpenBrakets
; break;
1627 if( nOpenBrakets
&& !bValidOle
)
1628 NextToken( nToken
);
1632 if( !bValidOle
&& '}' != nToken
)
1635 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
1639 /* vi:set tabstop=4 shiftwidth=4 expandtab: */