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
->Move( aRg
, aTmpIdx
, IDocumentContentOperations::DOC_MOVEDEFAULT
);
402 // patch from cmc for #i52542#
403 if (pSttNd
->GetIndex() + 1 == pSttNd
->EndOfSectionIndex())
405 ASSERT(!this, "nothing in this frame, not legal");
410 pFlySave
->aFlySet
.Put( SwFmtCntnt( pSttNd
));
412 CalculateFlySize( pFlySave
->aFlySet
, pFlySave
->nSttNd
,
413 pFlySave
->nPageWidth
);
416 // if the section only contains one Node and this has a
417 // border or backgorund, then put it to the frame
418 // Not in our own RTF-Format!
419 // <<<<< DOES NOT MAKE SENSE TO ME (flr)
420 // #102781#. Added support for transparent frames.
421 if( pSttNd
->GetIndex() + 1 != pSttNd
->EndOfSectionIndex() &&
424 SwCntntNode
* pSrcNd
= pDoc
->GetNodes()[ pSttNd
->GetIndex() + 1 ]->GetCntntNode();
425 SfxItemSet
aTmpSet( pDoc
->GetAttrPool(),
426 RES_BACKGROUND
, RES_BOX
);
427 const SvxBrushItem
* pBackgroundBrush
= (const SvxBrushItem
*)pFlySave
->aFlySet
.GetItem(RES_BACKGROUND
, FALSE
);
428 if( pSrcNd
&& pSrcNd
->HasSwAttrSet() )
429 aTmpSet
.Put( *pSrcNd
->GetpSwAttrSet() );
430 if (pBackgroundBrush
)
432 aTmpSet
.Put(*pBackgroundBrush
, RES_BACKGROUND
);
436 pBackgroundBrush
= (const SvxBrushItem
*)aTmpSet
.GetItem(RES_BACKGROUND
, FALSE
);
437 if (pBackgroundBrush
)
439 Color
& rBackgroundColor
= const_cast<SvxBrushItem
*>(pBackgroundBrush
)->GetColor();
440 rBackgroundColor
.SetTransparency(0xFE);
444 Color aColor
= Color(0xff, 0xff, 0xff);
445 aColor
.SetTransparency( 0xFE);
446 SvxBrushItem
aBrush(aColor
, RES_BACKGROUND
);
447 aTmpSet
.Put(aBrush
, RES_BACKGROUND
);
451 pFlySave
->aFlySet
.Put( aTmpSet
);
452 if( pSrcNd
&& pSrcNd
->HasSwAttrSet() )
454 pSrcNd
->ResetAttr( RES_BACKGROUND
, RES_BOX
);
458 SwFlyFrmFmt
* pFmt
= pDoc
->MakeFlyFrmFmt( aEmptyStr
, pParent
);
459 pFmt
->SetFmtAttr( pFlySave
->aFlySet
);
460 const SwFmtAnchor
& rAnchor
= pFmt
->GetAnchor();
461 if( FLY_IN_CNTNT
!= rAnchor
.GetAnchorId() )
463 // korrigiere noch den Absatz, ist immer der vorhergehende !
464 // JP 20.09.95: wenn es diesen gibt! (DocAnfang!)
466 //JP 02.08.99: that is wrong. The anchor is ever the NEXT!
467 //JP 05.08.99: there are an Bug in the ExportFilter which will
468 // be fixed in the Version 517 - by SWG-Export
469 // the fly will be after the paragraph - but in RTF
470 // the flys will be before the paragraph.
471 if( !bSwPageDesc
|| 5430 < GetVersionNo() )
474 // if( !pFlySave->nSttNd.GetNode().IsCntntNode() )
476 // Seitenumbrueche in den Bodybereich verschieben!
477 SwCntntNode
* pSrcNd
= aRg
.aStart
.GetNode().GetCntntNode();
478 SwCntntNode
* pDstNd
= pFlySave
->nSttNd
.GetNode().GetCntntNode();
480 pDstNd
= pDoc
->GetNodes().GoNext( &pFlySave
->nSttNd
);
482 ::lcl_CpyBreakAttrs( pSrcNd
, pDstNd
, &pFlySave
->nSttNd
);
485 const SwNodeIndex
aSttNd(*pSttNd
);
486 SwNodeIndex
aEndNd(*pSttNd
->EndOfSectionNode());
489 SwPosition
aPos( pFlySave
->nSttNd
);
490 SwFmtAnchor
aAnchor(rAnchor
);
491 aAnchor
.SetAnchor(&aPos
);
493 const SwNode
*pCurrentAnchor
= &(pFlySave
->nSttNd
.GetNode());
494 aPrevFmts
[pCurrentAnchor
].push_back(frameEntry(pFmt
, aAnchor
));
496 while (aEndNd
> aSttNd
)
498 typedef rtfframesAtIndex::iterator myIter
;
499 rtfframesAtIndex
&rDeque
= aPrevFmts
[&(aEndNd
.GetNode())];
500 myIter aEnd
= rDeque
.end();
501 for (myIter aIter
= rDeque
.begin(); aIter
!= aEnd
; ++aIter
)
503 aIter
->second
.SetAnchor(&aPos
);
504 // --> OD 2004-06-30 #i27767# - push on front to keep order
505 // of objects for the correct object positioning
506 //aPrevFmts[pCurrentAnchor].push_back(*aIter);
507 aPrevFmts
[pCurrentAnchor
].push_front(*aIter
);
514 // --> OD, FLR 2006-02-16 #131205#
515 // Create draw contact object, which also creates a <SdrObject> instance,
516 // in order to set the order number.
517 // The order number is assumed to be the order of the text flow.
518 SwFlyDrawContact
* pContact
=
519 new SwFlyDrawContact( pFmt
,
520 pFmt
->GetDoc()->GetOrCreateDrawModel() );
521 pContact
->GetMaster()->SetOrdNum( n
);
527 typedef rtfFmtMap::reverse_iterator myriter
;
528 myriter aEnd
= aPrevFmts
.rend();
529 for(myriter aIter
= aPrevFmts
.rbegin(); aIter
!= aEnd
; ++aIter
)
531 rtfframesAtIndex
&rDeque
= aIter
->second
;
532 typedef rtfframesAtIndex::iterator myIter
;
533 myIter aQEnd
= rDeque
.end();
534 for (myIter aQIter
= rDeque
.begin(); aQIter
!= aQEnd
; ++aQIter
)
536 frameEntry
&rEntry
= *aQIter
;
537 SwFlyFrmFmt
*pFrm
= rEntry
.first
;
538 SwFmtAnchor
&rAnchor
= rEntry
.second
;
539 pFrm
->SetFmtAttr(rAnchor
);
543 aFlyArr
.Remove(0, aFlyArr
.Count());
546 // clips the text box to the min or max position if it is outside our min or max boundry
547 long SwRTFParser::GetSafePos(long nPos
)
551 else if(nPos
< SHRT_MIN
)
557 void SwRTFParser::ReadFly( int nToken
, SfxItemSet
* pSet
)
559 // ein Set fuer die FrmFmt-Attribute
560 SfxItemSet
aSet( pDoc
->GetAttrPool(), RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
562 Reader::ResetFrmFmtAttrs( aSet
);
564 // der Fly beginnt immer in einem neuen Absatz
565 if( pPam
->GetPoint()->nContent
.GetIndex() )
568 // RTF-Defaults setzen:
569 // --> OD 2004-06-24 #i27767#
570 SwFmtAnchor
aAnchor( FLY_AT_CNTNT
);
572 SwFmtHoriOrient
aHori( 0, text::HoriOrientation::LEFT
, text::RelOrientation::FRAME
);
573 SwFmtVertOrient
aVert( 0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
);
575 SvxFrameDirectionItem
aFrmDir( FRMDIR_HORI_LEFT_TOP
, RES_FRAMEDIR
);
577 USHORT nCols
= USHRT_MAX
, nColSpace
= USHRT_MAX
, nAktCol
= 0;
580 BOOL bChkDropCap
= 0 == pSet
;
581 USHORT nDropCapLines
= 0, nDropCapAnchor
= 0;
582 int nNumOpenBrakets
= GetOpenBrakets();
590 // die Werte aus dem uebergebenen!
591 aAnchor
= (SwFmtAnchor
&)pSet
->Get( RES_ANCHOR
);
592 aHori
= (SwFmtHoriOrient
&)pSet
->Get( RES_HORI_ORIENT
);
593 aVert
= (SwFmtVertOrient
&)pSet
->Get( RES_VERT_ORIENT
);
596 // dann sammel mal alle Attribute zusammen
600 USHORT nVal
= USHORT(nTokenValue
);
603 Assume that a property genuinely contributes towards creating a frame,
604 and if turns out to be a non contributing one reduce the count.
611 SwFmtFrmSize
aSz( ATT_MIN_SIZE
, nTokenValue
, 0 );
612 const SfxPoolItem
* pItem
;
613 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_FRM_SIZE
, TRUE
,
616 aSz
.SetHeightSizeType( ((SwFmtFrmSize
*)pItem
)->GetHeightSizeType() );
617 aSz
.SetHeight( ((SwFmtFrmSize
*)pItem
)->GetHeight() );
619 if( MINFLY
> nTokenValue
) nTokenValue
= MINFLY
;
625 SwFmtFrmSize
aSz( ATT_MIN_SIZE
, 0, MINFLY
);
626 const SfxPoolItem
* pItem
;
627 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_FRM_SIZE
, TRUE
,
630 aSz
.SetWidth( ((SwFmtFrmSize
*)pItem
)->GetWidth() );
633 if( 0 > nTokenValue
)
635 nTokenValue
= -nTokenValue
;
636 aSz
.SetHeightSizeType( ATT_FIX_SIZE
);
638 if( MINFLY
> nTokenValue
) nTokenValue
= MINFLY
;
639 aSz
.SetHeight( nTokenValue
);
646 pSet
->Put( SwFmtSurround( SURROUND_NONE
));
651 SvxULSpaceItem
aUL( RES_UL_SPACE
);
652 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
653 aUL
.SetUpper( nVal
); aUL
.SetLower( nVal
);
654 aLR
.SetLeft( nVal
); aLR
.SetRight( nVal
);
662 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
663 aLR
.SetLeft( nVal
); aLR
.SetRight( nVal
);
669 SvxULSpaceItem
aUL( RES_UL_SPACE
);
670 aUL
.SetUpper( nVal
); aUL
.SetLower( nVal
);
676 case RTF_POSX
: aHori
.SetHoriOrient( text::HoriOrientation::NONE
);
677 aHori
.SetPos( GetSafePos((long)nTokenValue
) );
679 case RTF_POSXC
: aHori
.SetHoriOrient( text::HoriOrientation::CENTER
); break;
680 case RTF_POSXI
: aHori
.SetHoriOrient( text::HoriOrientation::LEFT
);
681 aHori
.SetPosToggle( TRUE
);
683 case RTF_POSXO
: aHori
.SetHoriOrient( text::HoriOrientation::RIGHT
);
684 aHori
.SetPosToggle( TRUE
);
686 case RTF_POSXL
: aHori
.SetHoriOrient( text::HoriOrientation::LEFT
); break;
687 case RTF_POSXR
: aHori
.SetHoriOrient( text::HoriOrientation::RIGHT
); break;
690 case RTF_POSY
: aVert
.SetVertOrient( text::VertOrientation::NONE
);
691 aVert
.SetPos( GetSafePos((long)nTokenValue
) );
693 case RTF_POSYT
: aVert
.SetVertOrient( text::VertOrientation::TOP
); break;
694 case RTF_POSYB
: aVert
.SetVertOrient( text::VertOrientation::BOTTOM
); break;
695 case RTF_POSYC
: aVert
.SetVertOrient( text::VertOrientation::CENTER
); break;
697 case RTF_PHMRG
: aHori
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
); break;
698 case RTF_PVMRG
: aVert
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
); break;
699 case RTF_PHPG
: aHori
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
); break;
700 case RTF_PVPG
: aVert
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);break;
701 case RTF_PHCOL
: aHori
.SetRelationOrient( text::RelOrientation::FRAME
); break;
702 case RTF_PVPARA
: aVert
.SetRelationOrient( text::RelOrientation::FRAME
); break;
709 Not sufficient to make a frame at least word won't do it with just
715 aFrmDir
.SetValue( FRMDIR_HORI_LEFT_TOP
);
718 aFrmDir
.SetValue( FRMDIR_HORI_RIGHT_TOP
);
721 aFrmDir
.SetValue( FRMDIR_VERT_TOP_LEFT
);
724 aFrmDir
.SetValue( FRMDIR_VERT_TOP_RIGHT
);
727 case RTF_DROPCAPLI
: // Dropcaps !!
730 nDropCapLines
= USHORT( nTokenValue
);
731 if( !nDropCapAnchor
)
738 nDropCapAnchor
= USHORT( nTokenValue
);
745 // fuer die "alten" Writer - haben die Spaltigkeit falsch heraus-
747 case RTF_COLS
: nCols
= USHORT( nTokenValue
); break;
748 case RTF_COLSX
: nColSpace
= USHORT( nTokenValue
); break;
750 nAktCol
= USHORT( nTokenValue
);
751 if( RTF_COLW
== GetNextToken() )
753 USHORT nWidth
= USHORT( nTokenValue
), nSpace
= 0;
754 if( RTF_COLSR
== GetNextToken() )
755 nSpace
= USHORT( nTokenValue
);
757 SkipToken( -1 ); // wieder zurueck
759 if( --nAktCol
== ( aColumns
.Count() / 2 ) )
761 aColumns
.Insert( nWidth
+ nSpace
, aColumns
.Count() );
762 aColumns
.Insert( nSpace
, aColumns
.Count() );
770 if( RTF_IGNOREFLAG
!= ( nToken
= GetNextToken() ))
772 if( RTF_SHADINGDEF
== (nToken
& ~0xff) )
774 ReadBackgroundAttr( nToken
, aSet
);
775 GetNextToken(); // Klammer ueberlesen
780 else if( RTF_APOCTL
==
781 ((nToken
= GetNextToken() ) & ~(0xff | RTF_SWGDEFS
)) )
783 bReadSwFly
= true; // alles kommt in den akt. Fly
784 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
785 SvxULSpaceItem
aUL( RES_UL_SPACE
);
786 nCols
= USHRT_MAX
; // neu aufsetzen
787 nColSpace
= USHRT_MAX
;
789 nVal
= USHORT(nTokenValue
);
795 pSet
->Put( SvxPrintItem( RES_PRINT
, FALSE
));
800 pSet
->Put( SvxOpaqueItem( RES_OPAQUE
, FALSE
));
806 RTFProtect
aP( (BYTE
)nTokenValue
);
807 SvxProtectItem
aProtectItem( RES_PROTECT
);
808 aProtectItem
.SetCntntProtect( aP
.GetCntnt() );
809 aProtectItem
.SetSizeProtect( aP
.GetSize() );
810 aProtectItem
.SetPosProtect( aP
.GetPos() );
811 pSet
->Put( aProtectItem
);
817 RTFSurround
aMC( (BYTE
)nTokenValue
);
818 SwFmtSurround
aSurr( (SwSurround
)aMC
.GetOrder());
819 if( aMC
.GetGoldCut() )
820 aSurr
.SetSurround( SURROUND_IDEAL
);
826 RTFVertOrient
aVO( nVal
);
827 aVert
.SetVertOrient( aVO
.GetOrient() );
828 aVert
.SetRelationOrient( aVO
.GetRelation() );
833 RTFHoriOrient
aHO( nVal
);
834 aHori
.SetHoriOrient( aHO
.GetOrient() );
835 aHori
.SetRelationOrient( aHO
.GetRelation() );
838 case RTF_FLYOUTLEFT
: aLR
.SetLeft( nVal
); break;
839 case RTF_FLYOUTRIGHT
: aLR
.SetRight( nVal
); break;
840 case RTF_FLYOUTUPPER
: aUL
.SetUpper( nVal
); break;
841 case RTF_FLYOUTLOWER
: aUL
.SetLower( nVal
); break;
843 switch( GetNextToken() )
846 aAnchor
.SetType( FLY_PAGE
);
847 aAnchor
.SetPageNum( USHORT(nTokenValue
));
848 aAnchor
.SetAnchor( 0 );
853 SwNodeIndex
aIdx( pPam
->GetPoint()->nNode
);
854 pDoc
->GetNodes().GoPrevious( &aIdx
);
855 SwPosition
aPos( aIdx
);
856 aAnchor
.SetType( FLY_AT_CNTNT
);
857 aAnchor
.SetAnchor( &aPos
);
861 // JP 26.09.94: die Bindung an die Spalte gibt es nicht mehr !!
862 // case RTF_FLY_COLUMN:
865 case RTF_COLS
: nCols
= USHORT( nTokenValue
); break;
866 case RTF_COLSX
: nColSpace
= USHORT( nTokenValue
); break;
868 nAktCol
= USHORT( nTokenValue
);
869 if( RTF_COLW
== GetNextToken() )
871 USHORT nWidth
= USHORT( nTokenValue
), nSpace
= 0;
872 if( RTF_COLSR
== GetNextToken() )
873 nSpace
= USHORT( nTokenValue
);
875 SkipToken( -1 ); // wieder zurueck
877 if( --nAktCol
== ( aColumns
.Count() / 2 ) )
879 aColumns
.Insert( nWidth
+ nSpace
, aColumns
.Count() );
880 aColumns
.Insert( nSpace
, aColumns
.Count() );
886 if( RTF_BRDBOX
== ( nToken
= GetNextToken() ) )
887 ReadBorderAttr( nToken
, aSet
);
888 else if( RTF_SHADINGDEF
== (nToken
& ~0xff ) )
889 ReadBackgroundAttr( nToken
, aSet
);
890 else if( RTF_IGNOREFLAG
== nToken
)
893 switch( nToken
= GetNextToken() )
897 ReadAttr( SkipToken( -2 ), &aSet
);
906 ReadBorderAttr( SkipToken( -2 ), aSet
);
910 // keine weitere Klammer mehr ueberlesen!!!
918 GetNextToken(); // Klammer ueberlesen
921 } while( IsParserWorking() &&
922 '}' != ( nToken
= GetNextToken() ));
924 if( aUL
.GetUpper() || aUL
.GetLower() )
926 if( aLR
.GetLeft() || aLR
.GetRight() )
929 else if( RTF_BRDBOX
== nToken
)
930 ReadBorderAttr( nToken
, aSet
);
931 else if( RTF_SHADOW
== nToken
)
932 ReadAttr( SkipToken( -2 ), &aSet
);
933 else if( RTF_SHADINGDEF
== (nToken
& ~0xff ) )
934 ReadBackgroundAttr( nToken
, aSet
);
935 else if( RTF_UNKNOWNCONTROL
== nToken
)
942 nToken
= SkipToken( nSkip
);
949 --nAppliedProps
; //Not sufficient to make a frame
954 nToken
= GetNextToken();
955 } while( bWeiter
&& IsParserWorking() );
957 pSet
->Put( aAnchor
);
961 // --> OD 2004-06-30 #i27767# - set wrapping style influence
962 // --> OD 2004-10-18 #i35017# - constant name has changed
963 pSet
->Put( SwFmtWrapInfluenceOnObjPos(
964 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE
));
967 SwFmtFollowTextFlow
aFollowTextFlow( FALSE
);
968 pSet
->Put( aFollowTextFlow
);
970 if( !( aFrmDir
== pSet
->Get( RES_FRAMEDIR
)) )
971 pSet
->Put( aFrmDir
);
973 if( nCols
&& USHRT_MAX
!= nCols
)
976 if( USHRT_MAX
== nColSpace
)
979 ULONG nWidth
= USHRT_MAX
;
980 aCol
.Init( nCols
, nColSpace
, USHORT( nWidth
) );
981 if( nCols
== ( aColumns
.Count() / 2 ) )
983 for( USHORT n
= 0, i
= 0; n
< aColumns
.Count(); n
+= 2, ++i
)
985 SwColumn
* pCol
= aCol
.GetColumns()[ i
];
986 ULONG nTmp
= aColumns
[ n
];
989 pCol
->SetWishWidth( USHORT(nTmp
) );
991 JP 07.07.95: der Dialog kennt nur eine Breite fuer alle Spalten
992 darum hier nicht weiter beachten
993 nTmp = aColumns[ n+1 ];
995 pCol->SetRight( USHORT(nTmp) );
1005 if( pSet
!= &aSet
) // wurde der Set uebergeben, dann wars das
1008 // ein neues FlyFormat anlegen oder das alte benutzen ?
1009 // (teste ob es die selben Attribute besitzt!)
1010 SwFlySave
* pFlySave
= 0;
1011 USHORT nFlyArrCnt
= aFlyArr
.Count();
1014 There were not enough frame properties found to actually justify creating
1015 an absolutely positioned frame.
1020 !( pFlySave
= aFlyArr
[ nFlyArrCnt
-1 ])->IsEqualFly( *pPam
, aSet
))
1022 pFlySave
= new SwFlySave( *pPam
, aSet
);
1024 GetPageSize( aPgSize
);
1025 pFlySave
->nPageWidth
= aPgSize
.Width();
1027 if( nDropCapAnchor
)
1029 pFlySave
->nDropAnchor
= nDropCapAnchor
;
1030 pFlySave
->nDropLines
= nDropCapLines
;
1033 SwFlySave
* pFlySavePrev
= aFlyArr
[nFlyArrCnt
-1];
1034 if (pFlySave
->nSttNd
.GetIndex() < pFlySavePrev
->nEndNd
.GetIndex())
1036 pFlySavePrev
->nEndNd
=pFlySave
->nSttNd
;
1039 aFlyArr
.Insert( pFlySave
, nFlyArrCnt
++ );
1040 // --> OD 2008-12-22 #i83368# - reset
1041 mbReadCellWhileReadSwFly
= false;
1046 SetPardTokenRead( FALSE
);
1047 const SwTableNode
* pTblNd
= pPam
->GetNode()->FindTableNode();
1049 while( !IsPardTokenRead() && IsParserWorking() )
1051 if( RTF_PARD
== nToken
|| nNumOpenBrakets
> GetOpenBrakets() )
1054 NextToken( nToken
);
1056 if( !IsPardTokenRead() )
1058 // #102781#. Added support for transparent frames.
1059 if (nToken
== RTF_CBPAT
&& nFlyArrCnt
> 0)
1061 USHORT _index
=USHORT(nTokenValue
);
1062 const Color
& rColor
= GetColor(_index
);
1063 SvxBrushItem
aBrush(rColor
, RES_BACKGROUND
);
1064 SwFlySave
* pFS
= aFlyArr
[nFlyArrCnt
-1];
1065 pFS
->aFlySet
.Put(aBrush
, RES_BACKGROUND
);
1068 nToken
= GetNextToken();
1070 // BUG 22036: kommt zwischen Fly-Attributen ein unbekanntes,
1071 // dann erzeuge nie 2 FlyFrames, sondern fasse
1072 // beide zusammen !!!
1073 while( RTF_APOCTL
== ( nToken
& ~(0xff | RTF_SWGDEFS
) ))
1075 if( RTF_FLY_INPARA
== nToken
)
1078 if( RTF_IGNOREFLAG
== SkipToken( -1 ) )
1080 if( '{' == SkipToken( -1 ) )
1088 ReadFly( nToken
, pFlySave
? &pFlySave
->aFlySet
: 0);
1089 nToken
= GetNextToken();
1096 There were enough frame properties found to actually justify creating
1097 an absolutely positioned frame.
1106 if( pTblNd
&& !pPam
->GetPoint()->nContent
.GetIndex() &&
1107 pTblNd
->EndOfSectionIndex() + 1 ==
1108 pPam
->GetPoint()->nNode
.GetIndex() )
1110 // nicht mehr in der Tabelle, sondern dahinter ?
1111 // Dann aber wieder zurueck in die Tabelle
1112 pPam
->Move( fnMoveBackward
);
1117 // wurde garnichts eingefuegt?
1119 pPam
->GetPoint()->nNode
== pFlySave
->nSttNd
&&
1120 !pPam
->GetPoint()->nContent
.GetIndex() )
1122 // // dann erzeuge mindestens einen leeren TextNode
1123 // pDoc->AppendTxtNode(*pPam);
1124 // dann zerstoere den FlySave wieder.
1125 aFlyArr
.DeleteAndDestroy( --nFlyArrCnt
);
1130 BOOL bMovePaM
= 0 != pTblNd
;
1132 pFlySave
->nEndNd
= pPam
->GetPoint()->nNode
;
1133 pFlySave
->nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
1136 pPam
->Move( fnMoveForward
);
1138 pTblNd
= pFlySave
->nSttNd
.GetNode().FindTableNode();
1139 if( pTblNd
&& !pFlySave
->nEndCnt
&&
1140 pTblNd
== pFlySave
->nEndNd
.GetNode().FindTableNode() )
1142 // dann teste mal, ob das \pard nicht zu spaet kam und
1143 // eigentlich in die vorherige Zelle gehoert
1144 const SwStartNode
* pSttBoxNd
= pFlySave
->nSttNd
.GetNode().
1145 FindTableBoxStartNode(),
1146 * pEndBoxNd
= pFlySave
->nEndNd
.GetNode().
1147 FindTableBoxStartNode();
1148 if( pSttBoxNd
&& pEndBoxNd
&&
1149 bMovePaM
? ( pSttBoxNd
== pEndBoxNd
)
1150 : ( pSttBoxNd
->EndOfSectionIndex() + 1 ==
1151 pEndBoxNd
->GetIndex() &&
1152 pEndBoxNd
->GetIndex() + 1 ==
1153 pFlySave
->nEndNd
.GetIndex() ))
1155 // dann gehoert das Ende in die vorherige Box!
1156 SwPosition
aPos( *pPam
->GetPoint() );
1157 pPam
->GetPoint()->nNode
= *pSttBoxNd
->EndOfSectionNode();
1158 pPam
->Move( fnMoveBackward
, fnGoNode
);
1162 pPam
->GetPoint()->nNode
= *pSttBoxNd
->EndOfSectionNode();
1163 pPam
->Move( fnMoveBackward
, fnGoNode
);
1165 pFlySave
->nEndNd
= pPam
->GetPoint()->nNode
;
1166 pFlySave
->nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
1168 *pPam
->GetPoint() = aPos
;
1171 else if( !bReadSwFly
&& !pFlySave
->nEndCnt
&&
1172 pFlySave
->nSttNd
.GetIndex() + 1 == pFlySave
->nEndNd
.GetIndex() &&
1173 pFlySave
->nSttNd
.GetNode().IsTxtNode() )
1176 SwTxtNode
* pTxtNd
= pFlySave
->nSttNd
.GetNode().GetTxtNode();
1177 SwTxtFlyCnt
* pFlyCnt
;
1178 if( 1 == pTxtNd
->GetTxt().Len() &&
1179 0 != ( pFlyCnt
= (SwTxtFlyCnt
*)pTxtNd
->GetTxtAttr(
1180 0, RES_TXTATR_FLYCNT
)) &&
1181 pFlyCnt
->GetFlyCnt().GetFrmFmt() )
1183 // then move the content into the surrounded fly
1184 SwFrmFmt
* pFlyFmt
= pFlyCnt
->GetFlyCnt().GetFrmFmt();
1185 const SwNodeIndex
* pFlySNd
= pFlyFmt
->GetCntnt().GetCntntIdx();
1186 SwNodeRange
aRg( *pFlySNd
, 1,
1187 *pFlySNd
->GetNode().EndOfSectionNode(), 0 );
1189 // merge the itemsets
1190 SwFmtFrmSize
aSz1( (SwFmtFrmSize
&)pFlyFmt
->GetAttrSet().
1191 Get( RES_FRM_SIZE
));
1192 SwFmtFrmSize
aSz2( (SwFmtFrmSize
&)pFlySave
->aFlySet
.
1193 Get( RES_FRM_SIZE
));
1195 if( !aRg
.aStart
.GetNode().IsNoTxtNode() ||
1196 !aSz1
.GetHeight() || !aSz1
.GetWidth() ||
1197 !aSz2
.GetHeight() || !aSz2
.GetWidth() ||
1198 ( aSz1
.GetHeight() == aSz2
.GetHeight() &&
1199 aSz1
.GetWidth() == aSz2
.GetWidth() ) )
1201 SfxItemSet
aDiffs( pFlyFmt
->GetAttrSet() );
1202 aDiffs
.ClearItem( RES_ANCHOR
);
1203 aDiffs
.ClearItem( RES_FRM_SIZE
);
1204 aDiffs
.ClearItem( RES_CNTNT
);
1205 aDiffs
.Differentiate( pFlySave
->aFlySet
);
1206 pFlySave
->aFlySet
.Put( aDiffs
);
1209 if( aSz1
.GetHeight() && !aSz2
.GetHeight() )
1212 aSz2
.SetHeight( aSz1
.GetHeight() );
1214 if( aSz1
.GetWidth() && !aSz2
.GetWidth() )
1217 aSz2
.SetWidth( aSz1
.GetWidth() );
1220 pFlySave
->aFlySet
.Put( aSz2
);
1222 // move any PageBreak/Desc Attr to the next Para
1224 SwCntntNode
* pSrcNd
= pFlySave
->nSttNd
.GetNode().GetCntntNode();
1225 SwCntntNode
* pDstNd
= pFlySave
->nEndNd
.GetNode().GetCntntNode();
1227 ::lcl_CpyBreakAttrs( pSrcNd
, pDstNd
, &pFlySave
->nEndNd
);
1230 // create new txtnode, because the section does never be empty
1231 pDoc
->GetNodes().MakeTxtNode( aRg
.aStart
,
1232 (SwTxtFmtColl
*)pDoc
->GetDfltTxtFmtColl() );
1234 SwNodeIndex
aTmp( pFlySave
->nSttNd
, +1 );
1235 pDoc
->Move( aRg
, aTmp
, IDocumentContentOperations::DOC_MOVEDEFAULT
);
1237 // now delete the redundant txtnode
1238 pDoc
->GetNodes().Delete( pFlySave
->nSttNd
, 1 );
1249 void SwRTFParser::InsPicture( const String
& rGrfNm
, const Graphic
* pGrf
,
1250 const SvxRTFPictureType
* pPicType
)
1252 // kennzeichen fuer Swg-Dokumente:
1253 // (dann ist das FlyFmt fuer die Grafik!)
1255 // --> OD 2008-12-22 #i83368#
1256 // Assure that graphic node is enclosed by fly frame node.
1258 if ( bReadSwFly
&& !mbReadCellWhileReadSwFly
)
1261 // erzeuge nur einen normalen GrafikNode und ersetze diesen gegen
1262 // den vorhandenen Textnode
1263 SwNodeIndex
& rIdx
= pPam
->GetPoint()->nNode
;
1264 pGrfNd
= pDoc
->GetNodes().MakeGrfNode( rIdx
,
1265 rGrfNm
, aEmptyStr
, // Name der Graphic !!
1267 (SwGrfFmtColl
*)pDoc
->GetDfltGrfFmtColl() );
1270 pGrfNd
->SetAttr( *pGrfAttrSet
);
1272 SwFlySave
* pFlySave
= aFlyArr
[ aFlyArr
.Count()-1 ];
1273 pFlySave
->nSttNd
= rIdx
.GetIndex() - 1;
1275 if( 1 < aFlyArr
.Count() )
1277 pFlySave
= aFlyArr
[ aFlyArr
.Count() - 2 ];
1278 if( pFlySave
->nEndNd
== rIdx
)
1279 pFlySave
->nEndNd
= rIdx
.GetIndex() - 1;
1284 // wenn normale RTF-Grafik, dann steht diese im Textfluss !
1285 SwAttrSet
aFlySet( pDoc
->GetAttrPool(), RES_OPAQUE
, /*RES_OPAQUE,
1286 RES_VERT_ORIENT,*/ RES_ANCHOR
);
1287 const SwPosition
* pPos
= pPam
->GetPoint();
1289 SwFmtAnchor
aAnchor( FLY_IN_CNTNT
);
1290 aAnchor
.SetAnchor( pPos
);
1291 aFlySet
.Put( aAnchor
);
1292 aFlySet
.Put( SwFmtVertOrient( 0, text::VertOrientation::TOP
));
1294 if (pDoc
->IsInHeaderFooter(pPos
->nNode
))
1296 SvxOpaqueItem
aOpaqueItem(RES_OPAQUE
, FALSE
);
1297 SwFmtSurround
aSurroundItem(SURROUND_THROUGHT
);
1298 aFlySet
.Put(aOpaqueItem
);
1299 aFlySet
.Put(aSurroundItem
);
1302 SwFrmFmt
* pFlyFmt
= pDoc
->Insert( *pPam
,
1303 rGrfNm
, aEmptyStr
, // Name der Graphic !!
1305 &aFlySet
, // Attribute fuer den FlyFrm
1306 pGrfAttrSet
, NULL
); // Attribute fuer die Grafik
1308 pGrfNd
= pDoc
->GetNodes()[ pFlyFmt
->GetCntnt().GetCntntIdx()->
1309 GetIndex()+1 ]->GetGrfNode();
1311 _SetPictureSize( *pGrfNd
, pPos
->nNode
,
1312 (SfxItemSet
&)pFlyFmt
->GetAttrSet(),
1317 DELETEZ( pGrfAttrSet
);
1320 void SwRTFParser::_SetPictureSize( const SwNoTxtNode
& rNd
,
1321 const SwNodeIndex
& rAnchor
,
1323 const SvxRTFPictureType
* pPicType
)
1325 Size
aSize( ((SwNoTxtNode
&)rNd
).GetTwipSize() );
1328 if( rNd
.IsGrfNode() )
1330 if( SvxRTFPictureType::WIN_METAFILE
!= pPicType
->eStyle
&&
1331 pPicType
->nGoalWidth
&& pPicType
->nGoalHeight
)
1333 aSize
.Width() = pPicType
->nGoalWidth
;
1334 aSize
.Height() =pPicType
->nGoalHeight
;
1336 else if( SvxRTFPictureType::MAC_QUICKDRAW
== pPicType
->eStyle
)
1338 // IMMER auf 72 DPI bezogen, also 1pt == 20 Twip !!
1339 aSize
.Width() = pPicType
->nWidth
* 20;
1340 aSize
.Height() = pPicType
->nHeight
* 20;
1344 // von 100TH_MM nach TWIP umrechenen!
1345 // #117879# when \picwgoal resp \pichgoal are present, then use them.
1346 // The values of \picwgoal and \picwgoal are already given in twips.
1347 aSize
.Width() = (pPicType
->nGoalWidth
?pPicType
->nGoalWidth
:(pPicType
->nWidth
*144)/254);
1348 aSize
.Height() = (pPicType
->nGoalHeight
?pPicType
->nGoalHeight
:(pPicType
->nHeight
*144)/254);
1350 ((SwGrfNode
&)rNd
).SetTwipSize( aSize
);
1353 if( 100 != pPicType
->nScalX
)
1354 aSize
.Width() = (((long)pPicType
->nScalX
) * ( aSize
.Width() -
1355 ( pPicType
->nCropL
+ pPicType
->nCropR
))) / 100L;
1357 if( 100 != pPicType
->nScalY
)
1358 aSize
.Height() = (((long)pPicType
->nScalY
) * ( aSize
.Height() -
1359 ( pPicType
->nCropT
+ pPicType
->nCropB
))) / 100L;
1362 //steht der Fly etwa in einer Tabelle ?
1363 const SwNode
* pAnchorNd
= pDoc
->GetNodes()[ rAnchor
];
1364 const SwTableNode
* pTblNd
= pAnchorNd
->FindTableNode();
1368 const SwTableBox
* pBox
= pTblNd
->GetTable().GetTblBox(
1369 pAnchorNd
->StartOfSectionIndex() );
1372 long nBoxWidth
= pBox
->GetFrmFmt()->GetFrmSize().GetWidth();
1373 if( aSize
.Width() > nBoxWidth
)
1374 aSize
.Width() = nBoxWidth
;
1378 //JP 8.11.2001: bug 94450 - if no size exist, then the size is set by
1379 // the swapin of the graphic.
1381 if( !aSize
.Width() && !aSize
.Height() &&
1382 0 != (pGrfNd
= (SwGrfNode
*)rNd
.GetGrfNode() ) && pGrfNd
->IsGrfLink() )
1383 pGrfNd
->SetChgTwipSize( TRUE
);
1385 // min. Werte einhalten !!
1386 if( aSize
.Width() < MINFLY
)
1387 aSize
.Width() = MINFLY
;
1388 if( aSize
.Height() < MINFLY
)
1389 aSize
.Height() = MINFLY
;
1397 JP 28.07.99: Bug 67800 - no crop by MAC_QUICKDRAW. At time i dont know why
1398 it has been coded. But this has used for any
1399 RTF-File, but i dont found them.
1400 if( SvxRTFPictureType::MAC_QUICKDRAW == pPicType->eStyle )
1402 // evt. ein wenig Croppen ??
1403 // IMMER auf 72 DPI bezogen, also 1pt == 20 Twip !!
1404 long nTmp = pPicType->nWidth * 20;
1405 if( nTmp != aSize.Width() )
1407 // in der Breite (also rechts) croppen
1408 aCrop.Right() = nTmp - aSize.Width();
1409 aSize.Width() = nTmp;
1413 nTmp = pPicType->nHeight * 20;
1414 if( nTmp != aSize.Height() )
1416 // in der Hoehe (also unten) croppen
1417 aCrop.Bottom() = nTmp - aSize.Height();
1418 aSize.Height() = nTmp;
1423 if( pPicType
->nCropT
)
1425 aCrop
.SetTop( pPicType
->nCropT
);
1428 if( pPicType
->nCropB
)
1430 aCrop
.SetBottom( pPicType
->nCropB
);
1433 if( pPicType
->nCropL
)
1435 aCrop
.SetLeft( pPicType
->nCropL
);
1438 if( pPicType
->nCropR
)
1440 aCrop
.SetRight( pPicType
->nCropR
);
1446 // dann mal an die CropWerte an die GrafikSize anpassen.
1447 ((SwNoTxtNode
&)rNd
).SetAttr( aCrop
);
1450 rSet
.Put( SwFmtFrmSize( ATT_FIX_SIZE
, aSize
.Width(), aSize
.Height() ));
1453 void SwRTFParser::GetPageSize( Size
& rSize
)
1455 ASSERT(!maSegments
.empty(), "not possible");
1456 if (maSegments
.empty())
1458 rSize
.Width() = 12240 - 1800 - 1800;
1459 rSize
.Height() = 15840 - 1440 - 1440;
1463 const rtfSection
&rSect
= maSegments
.back();
1465 rSize
.Width() = rSect
.maPageInfo
.mnPgwsxn
- rSect
.maPageInfo
.mnMarglsxn
- rSect
.maPageInfo
.mnMargrsxn
;
1466 rSize
.Height() = rSect
.maPageInfo
.mnPghsxn
- rSect
.maPageInfo
.mnMargtsxn
- rSect
.maPageInfo
.mnMargbsxn
;
1468 long nCols
= rSect
.NoCols();
1471 rSize
.Width() /= nCols
;
1472 rSize
.Height() /= nCols
;
1476 void SwRTFParser::ReadBitmapData()
1479 SvxRTFPictureType aPicType
;
1480 if( ReadBmpData( aGrf
, aPicType
) )
1481 InsPicture( aEmptyStr
, &aGrf
, &aPicType
);
1484 #ifdef READ_OLE_OBJECT
1485 void SwRTFParser::ReadOLEData()
1487 SvCacheStream
aTmpFile( 0xA000 );
1489 SvxRTFPictureType aPicType
, aOleType
;
1491 int nToken
, bValidOle
= TRUE
, bWeiter
= TRUE
;
1492 int nOpenBrakets
= 1; // die erste wurde schon vorher erkannt !!
1495 String sObjClass
, sObjName
, sObjData
;
1497 while( nOpenBrakets
&& IsParserWorking() && bWeiter
&& bValidOle
)
1499 nToken
= GetNextToken();
1500 USHORT nVal
= USHORT( nTokenValue
);
1503 case '}': --nOpenBrakets
; pStr
= 0; break;
1506 if( RTF_IGNOREFLAG
!= GetNextToken() )
1507 nToken
= SkipToken( -1 );
1508 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
1509 nToken
= SkipToken( -2 );
1512 // gleich herausfiltern
1514 nToken
= GetNextToken();
1516 eState
= SVPAR_ERROR
;
1524 case RTF_OBJEMB
: // default ist embedded
1525 case RTF_LINKSELF
: // ??
1526 case RTF_OBJLOCK
: // ??
1527 case RTF_OBJUPDATE
: // ??
1528 case RTF_OBJTIME
: // ??
1529 case RTF_OBJSETSIZE
:
1535 case RTF_OBJLINK
: // ?? welche Daten sind das ??
1536 case RTF_OBJAUTLINK
: // ?? -""- ??
1544 bValidOle
= FALSE
; // diese Typen koennen wir nicht
1563 // hier weitermachen, wenn das OLE-Object ungueltig ist
1567 case RTF_RSLTBMP
: // diese sollten wir ignorieren
1574 case RTF_OBJW
: aOleType
.nWidth
= nVal
; break;
1575 case RTF_OBJH
: aOleType
.nHeight
= nVal
; break;
1576 case RTF_OBJCROPT
: aOleType
.nCropT
= (short)nTokenValue
; break;
1577 case RTF_OBJCROPB
: aOleType
.nCropB
= (short)nTokenValue
; break;
1578 case RTF_OBJCROPL
: aOleType
.nCropL
= (short)nTokenValue
; break;
1579 case RTF_OBJCROPR
: aOleType
.nCropR
= (short)nTokenValue
; break;
1580 case RTF_OBJSCALEX
: aOleType
.nScalX
= nVal
; break;
1581 case RTF_OBJSCALEY
: aOleType
.nScalY
= nVal
; break;
1584 if( 1 < nOpenBrakets
&& pStr
)
1586 if( pStr
== &sObjData
)
1588 xub_StrLen nHexLen
= HexToBin( aToken
);
1589 if( STRING_NOTFOUND
!= nHexLen
)
1593 aTmpFile
.Write( (sal_Char
*)aToken
.GetBuffer(), nHexLen
);
1594 bValidOle
= 0 == aTmpFile
.GetError();
1606 bValidOle
= FALSE
; // erstmal
1609 if( !bWeiter
) // dann stehen wir noch im Result
1611 // ist das Ole-Object Ok?
1612 // -> dann solange SkipGroup rufen, bis zur letzten
1613 // schliessenden Klammer
1614 // ansonsten alle Token verarbeiten, bis zur letzten
1615 // schliessenden Klammer
1618 while( nOpenBrakets
&& IsParserWorking() && bWeiter
)
1620 switch( nToken
= GetNextToken() )
1622 case '}': --nOpenBrakets
; break;
1623 case '{': ++nOpenBrakets
; break;
1625 if( nOpenBrakets
&& !bValidOle
)
1626 NextToken( nToken
);
1630 if( !bValidOle
&& '}' != nToken
)
1633 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
1637 /* vi:set tabstop=4 shiftwidth=4 expandtab: */