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: frmmgr.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"
37 #include "hintids.hxx"
40 #include <svtools/stritem.hxx>
41 #include <svx/protitem.hxx>
42 #include <svx/boxitem.hxx>
43 #include <svx/opaqitem.hxx>
44 #include <svx/lrspitem.hxx>
45 #include <svx/ulspitem.hxx>
46 #include <svx/shaditem.hxx>
47 #include <svx/swframevalidation.hxx>
48 #include <fmtclds.hxx>
51 #include "viewopt.hxx"
56 #include "poolfmt.hxx"
57 #include <com/sun/star/text/TextContentAnchorType.hpp>
58 #include <com/sun/star/text/HoriOrientation.hpp>
59 #include <com/sun/star/text/VertOrientation.hpp>
60 #include <com/sun/star/text/RelOrientation.hpp>
62 using namespace ::com::sun::star
;
63 //using namespace text;
65 static USHORT __FAR_DATA aFrmMgrRange
[] = {
66 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1,
67 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
,
68 FN_SET_FRM_NAME
, FN_SET_FRM_NAME
,
71 /*--------------------------------------------------------------------
72 Beschreibung: Rahmen-Attribute ueber Shell ermitteln
73 --------------------------------------------------------------------*/
75 SwFlyFrmAttrMgr::SwFlyFrmAttrMgr( BOOL bNew
, SwWrtShell
* pSh
, BYTE nType
) :
76 aSet( (SwAttrPool
&)pSh
->GetAttrPool(), aFrmMgrRange
),
80 bIsInVertical( FALSE
)
84 // Defaults einstellen:
88 case FRMMGR_TYPE_TEXT
: nId
= RES_POOLFRM_FRAME
; break;
89 case FRMMGR_TYPE_OLE
: nId
= RES_POOLFRM_OLE
; break;
90 case FRMMGR_TYPE_GRF
: nId
= RES_POOLFRM_GRAPHIC
; break;
92 aSet
.SetParent( &pOwnSh
->GetFmtFromPool( nId
)->GetAttrSet());
93 aSet
.Put( SwFmtFrmSize( ATT_MIN_SIZE
, DFLT_WIDTH
, DFLT_HEIGHT
));
94 if ( 0 != ::GetHtmlMode(pSh
->GetView().GetDocShell()) )
95 aSet
.Put( SwFmtHoriOrient( 0, text::HoriOrientation::LEFT
, text::RelOrientation::PRINT_AREA
) );
97 else if ( nType
== FRMMGR_TYPE_NONE
)
99 pOwnSh
->GetFlyFrmAttr( aSet
);
101 bIsInVertical
= pOwnSh
->IsFrmVertical(TRUE
, bRightToLeft
);
103 ::PrepareBoxInfo( aSet
, *pOwnSh
);
106 SwFlyFrmAttrMgr::SwFlyFrmAttrMgr( BOOL bNew
, SwWrtShell
* pSh
, const SfxItemSet
&rSet
) :
116 bIsInVertical
= pSh
->IsFrmVertical(TRUE
, bRightToLeft
);
121 /*--------------------------------------------------------------------
122 Beschreibung: Initialisieren
123 --------------------------------------------------------------------*/
125 void SwFlyFrmAttrMgr::UpdateAttrMgr()
127 if ( !bNewFrm
&& pOwnSh
->IsFrmSelected() )
128 pOwnSh
->GetFlyFrmAttr( aSet
);
129 ::PrepareBoxInfo( aSet
, *pOwnSh
);
132 void SwFlyFrmAttrMgr::_UpdateFlyFrm()
134 const SfxPoolItem
* pItem
= 0;
136 if (aSet
.GetItemState(FN_SET_FRM_NAME
, FALSE
, &pItem
) == SFX_ITEM_SET
)
137 pOwnSh
->SetFlyName(((SfxStringItem
*)pItem
)->GetValue());
139 pOwnSh
->SetModified();
143 pOwnSh
->SetFlyPos( aAbsPos
);
148 /*--------------------------------------------------------------------
149 Beschreibung: Bestehenden Fly-Frame aendern
150 --------------------------------------------------------------------*/
152 void SwFlyFrmAttrMgr::UpdateFlyFrm()
154 ASSERT( pOwnSh
->IsFrmSelected(),
155 "Kein Rahmen selektiert oder keine Shell, Update nicht moeglich");
157 if( pOwnSh
->IsFrmSelected() )
159 //JP 6.8.2001: set never an invalid anchor into the core.
160 const SfxPoolItem
*pGItem
, *pItem
;
161 if( SFX_ITEM_SET
== aSet
.GetItemState( RES_ANCHOR
, FALSE
, &pItem
))
163 SfxItemSet
aGetSet( *aSet
.GetPool(), RES_ANCHOR
, RES_ANCHOR
);
164 if( pOwnSh
->GetFlyFrmAttr( aGetSet
) && 1 == aGetSet
.Count() &&
165 SFX_ITEM_SET
== aGetSet
.GetItemState( RES_ANCHOR
, FALSE
, &pGItem
)
166 && ((SwFmtAnchor
*)pGItem
)->GetAnchorId() ==
167 ((SwFmtAnchor
*)pItem
)->GetAnchorId() )
168 aSet
.ClearItem( RES_ANCHOR
);
174 pOwnSh
->StartAllAction();
175 pOwnSh
->SetFlyFrmAttr( aSet
);
177 pOwnSh
->EndAllAction();
182 /*--------------------------------------------------------------------
183 Beschreibung: Rahmen einfuegen
184 --------------------------------------------------------------------*/
186 BOOL
SwFlyFrmAttrMgr::InsertFlyFrm()
188 pOwnSh
->StartAllAction();
190 BOOL bRet
= 0 != pOwnSh
->NewFlyFrm( aSet
);
192 // richtigen Mode an der Shell einschalten, Rahmen wurde aut. selektiert.
196 pOwnSh
->EnterSelFrmMode();
197 FrameNotify(pOwnSh
, FLY_DRAG_START
);
199 pOwnSh
->EndAllAction();
203 /*------------------------------------------------------------------------
204 Beschreibung: Rahmen des Typs eAnchorType einfuegen. Position und
205 Groesse werden explizit angegeben.
206 Nicht erlaubte Werte des Aufzaehlungstypes werden
208 ------------------------------------------------------------------------*/
210 void SwFlyFrmAttrMgr::InsertFlyFrm(RndStdIds eAnchorType
,
215 ASSERT( eAnchorType
== FLY_PAGE
||
216 eAnchorType
== FLY_AT_CNTNT
||
217 eAnchorType
== FLY_AUTO_CNTNT
||
218 eAnchorType
== FLY_AT_FLY
||
219 eAnchorType
== FLY_IN_CNTNT
, "Rahmentyp nicht erlaubt" );
227 SetAnchor( eAnchorType
);
231 /*--------------------------------------------------------------------
232 Beschreibung: Anker setzen
233 --------------------------------------------------------------------*/
235 void SwFlyFrmAttrMgr::SetAnchor( RndStdIds eId
)
237 USHORT nPhyPageNum
, nVirtPageNum
;
238 pOwnSh
->GetPageNum( nPhyPageNum
, nVirtPageNum
);
240 aSet
.Put( SwFmtAnchor( eId
, nPhyPageNum
) );
241 if( FLY_PAGE
== eId
|| FLY_AT_CNTNT
== eId
|| FLY_AUTO_CNTNT
== eId
242 || FLY_AT_FLY
== eId
)
244 SwFmtVertOrient
aVertOrient( GetVertOrient() );
245 SwFmtHoriOrient
aHoriOrient( GetHoriOrient() );
246 aHoriOrient
.SetRelationOrient( text::RelOrientation::FRAME
);
247 aVertOrient
.SetRelationOrient( text::RelOrientation::FRAME
);
248 aSet
.Put( aVertOrient
);
249 aSet
.Put( aHoriOrient
);
253 /*------------------------------------------------------------------------
254 Beschreibung: Setzen des Attributs fuer Spalten
255 ------------------------------------------------------------------------*/
257 void SwFlyFrmAttrMgr::SetCol( const SwFmtCol
&rCol
)
261 /*--------------------------------------------------------------------
262 Beschreibung: Absolute Position setzen
263 --------------------------------------------------------------------*/
265 void SwFlyFrmAttrMgr::SetAbsPos( const Point
& rPoint
)
270 SwFmtVertOrient
aVertOrient( GetVertOrient() );
271 SwFmtHoriOrient
aHoriOrient( GetHoriOrient() );
272 aHoriOrient
.SetHoriOrient( text::HoriOrientation::NONE
);
273 aVertOrient
.SetVertOrient( text::VertOrientation::NONE
);
274 aSet
.Put( aVertOrient
);
275 aSet
.Put( aHoriOrient
);
278 /*--------------------------------------------------------------------
279 Beschreibung: Metriken auf Korrektheit pruefen
280 --------------------------------------------------------------------*/
281 void SwFlyFrmAttrMgr::ValidateMetrics( SvxSwFrameValidation
& rVal
,
282 const SwPosition
* pToCharCntntPos
,
283 BOOL bOnlyPercentRefValue
)
285 if (!bOnlyPercentRefValue
)
287 rVal
.nMinHeight
= MINFLY
+ CalcTopSpace() + CalcBottomSpace();
288 rVal
.nMinWidth
= MINFLY
+ CalcLeftSpace()+ CalcRightSpace();
293 // OD 18.09.2003 #i18732# - adjustment for allowing vertical position
294 // aligned to page for fly frame anchored to paragraph or to character.
295 const RndStdIds eAnchorType
= static_cast<RndStdIds
>(rVal
.nAnchorType
);
296 pOwnSh
->CalcBoundRect( aBoundRect
, eAnchorType
,
300 rVal
.bFollowTextFlow
,
301 rVal
.bMirror
, NULL
, &rVal
.aPercentSize
);
303 if (bOnlyPercentRefValue
)
308 Point
aPos(aBoundRect
.Pos());
309 long nTmp
= aPos
.X();
312 Size
aSize(aBoundRect
.SSize());
313 nTmp
= aSize
.Width();
314 aSize
.Width() = aSize
.Height();
315 aSize
.Height() = nTmp
;
316 aBoundRect
.Chg( aPos
, aSize
);
317 //exchange width/height to enable correct values
319 rVal
.nWidth
= rVal
.nHeight
;
322 if ( eAnchorType
== FLY_PAGE
|| eAnchorType
== FLY_AT_FLY
)
325 rVal
.nMinHPos
= aBoundRect
.Left();
326 rVal
.nMinVPos
= aBoundRect
.Top();
327 SwTwips nH
= rVal
.nHPos
;
328 SwTwips nV
= rVal
.nVPos
;
330 if (rVal
.nHPos
+ rVal
.nWidth
> aBoundRect
.Right())
332 if (rVal
.nHoriOrient
== text::HoriOrientation::NONE
)
334 rVal
.nHPos
-= ((rVal
.nHPos
+ rVal
.nWidth
) - aBoundRect
.Right());
338 rVal
.nWidth
= aBoundRect
.Right() - rVal
.nHPos
;
341 if (rVal
.nHPos
+ rVal
.nWidth
> aBoundRect
.Right())
342 rVal
.nWidth
= aBoundRect
.Right() - rVal
.nHPos
;
344 if (rVal
.nVPos
+ rVal
.nHeight
> aBoundRect
.Bottom())
346 if (rVal
.nVertOrient
== text::VertOrientation::NONE
)
348 rVal
.nVPos
-= ((rVal
.nVPos
+ rVal
.nHeight
) - aBoundRect
.Bottom());
352 rVal
.nHeight
= aBoundRect
.Bottom() - rVal
.nVPos
;
355 if (rVal
.nVPos
+ rVal
.nHeight
> aBoundRect
.Bottom())
356 rVal
.nHeight
= aBoundRect
.Bottom() - rVal
.nVPos
;
358 if ( rVal
.nVertOrient
!= text::VertOrientation::NONE
)
359 nV
= aBoundRect
.Top();
361 if ( rVal
.nHoriOrient
!= text::HoriOrientation::NONE
)
362 nH
= aBoundRect
.Left();
364 rVal
.nMaxHPos
= aBoundRect
.Right() - rVal
.nWidth
;
365 rVal
.nMaxHeight
= aBoundRect
.Bottom() - nV
;
367 rVal
.nMaxVPos
= aBoundRect
.Bottom() - rVal
.nHeight
;
368 rVal
.nMaxWidth
= aBoundRect
.Right() - nH
;
370 // OD 12.11.2003 #i22341# - handle to character anchored objects vertical
371 // aligned at character or top of line in a special case
372 else if ( eAnchorType
== FLY_AT_CNTNT
||
373 ( eAnchorType
== FLY_AUTO_CNTNT
&&
374 !(rVal
.nVRelOrient
== text::RelOrientation::CHAR
) &&
375 !(rVal
.nVRelOrient
== text::RelOrientation::TEXT_LINE
) ) )
377 if (rVal
.nHPos
+ rVal
.nWidth
> aBoundRect
.Right())
379 if (rVal
.nHoriOrient
== text::HoriOrientation::NONE
)
381 rVal
.nHPos
-= ((rVal
.nHPos
+ rVal
.nWidth
) - aBoundRect
.Right());
384 rVal
.nWidth
= aBoundRect
.Right() - rVal
.nHPos
;
387 // OD 29.09.2003 #i17567#, #i18732# - consider following the text flow
388 // and alignment at page areas.
389 const bool bMaxVPosAtBottom
= !rVal
.bFollowTextFlow
||
390 rVal
.nVRelOrient
== text::RelOrientation::PAGE_FRAME
||
391 rVal
.nVRelOrient
== text::RelOrientation::PAGE_PRINT_AREA
;
393 SwTwips nTmpMaxVPos
= ( bMaxVPosAtBottom
394 ? aBoundRect
.Bottom()
395 : aBoundRect
.Height() ) -
397 if ( rVal
.nVPos
> nTmpMaxVPos
)
399 if (rVal
.nVertOrient
== text::VertOrientation::NONE
)
401 rVal
.nVPos
= nTmpMaxVPos
;
405 rVal
.nHeight
= ( bMaxVPosAtBottom
406 ? aBoundRect
.Bottom()
407 : aBoundRect
.Height() ) - rVal
.nVPos
;
412 rVal
.nMinHPos
= aBoundRect
.Left();
413 rVal
.nMaxHPos
= aBoundRect
.Right() - rVal
.nWidth
;
415 rVal
.nMinVPos
= aBoundRect
.Top();
416 // OD 26.09.2003 #i17567#, #i18732# - determine maximum vertical position
417 if ( bMaxVPosAtBottom
)
419 rVal
.nMaxVPos
= aBoundRect
.Bottom() - rVal
.nHeight
;
423 rVal
.nMaxVPos
= aBoundRect
.Height() - rVal
.nHeight
;
426 // Maximale Breite Hoehe
427 const SwTwips nH
= ( rVal
.nHoriOrient
!= text::HoriOrientation::NONE
)
430 const SwTwips nV
= ( rVal
.nVertOrient
!= text::VertOrientation::NONE
)
433 rVal
.nMaxHeight
= rVal
.nMaxVPos
+ rVal
.nHeight
- nV
;
434 rVal
.nMaxWidth
= rVal
.nMaxHPos
+ rVal
.nWidth
- nH
;
436 // OD 12.11.2003 #i22341# - special case for to character anchored objects
437 // vertical aligned at character or top of line.
438 // Note: (1) positive vertical values are positions above the top of line
439 // (2) negative vertical values are positions below the top of line
440 else if ( eAnchorType
== FLY_AUTO_CNTNT
&&
441 ( rVal
.nVRelOrient
== text::RelOrientation::CHAR
||
442 rVal
.nVRelOrient
== text::RelOrientation::TEXT_LINE
) )
444 // determine horizontal values
445 rVal
.nMinHPos
= aBoundRect
.Left();
447 rVal
.nMaxHPos
= aBoundRect
.Right() - rVal
.nWidth
;
448 if (rVal
.nHPos
+ rVal
.nWidth
> aBoundRect
.Right())
450 if (rVal
.nHoriOrient
== text::HoriOrientation::NONE
)
452 rVal
.nHPos
-= ((rVal
.nHPos
+ rVal
.nWidth
) - aBoundRect
.Right());
455 rVal
.nWidth
= aBoundRect
.Right() - rVal
.nHPos
;
458 const SwTwips nH
= ( rVal
.nHoriOrient
!= text::HoriOrientation::NONE
)
461 rVal
.nMaxWidth
= rVal
.nMaxHPos
+ rVal
.nWidth
- nH
;
463 // determine vertical values
464 rVal
.nMinVPos
= -( aBoundRect
.Bottom() - rVal
.nHeight
);
465 if ( rVal
.nVPos
< rVal
.nMinVPos
&&
466 rVal
.nVertOrient
== text::VertOrientation::NONE
)
468 rVal
.nVPos
= rVal
.nMinVPos
;
471 rVal
.nMaxVPos
= -aBoundRect
.Top();
472 if ( rVal
.nVPos
> rVal
.nMaxVPos
&&
473 rVal
.nVertOrient
== text::VertOrientation::NONE
)
475 rVal
.nVPos
= rVal
.nMaxVPos
;
478 if ( rVal
.nVertOrient
== text::VertOrientation::NONE
)
480 rVal
.nMaxHeight
= aBoundRect
.Bottom() + rVal
.nVPos
;
484 rVal
.nMaxHeight
= aBoundRect
.Height();
487 else if ( eAnchorType
== FLY_IN_CNTNT
)
492 rVal
.nMaxHeight
= aBoundRect
.Height();
493 rVal
.nMaxWidth
= aBoundRect
.Width();
495 rVal
.nMaxVPos
= aBoundRect
.Height();
496 rVal
.nMinVPos
= -aBoundRect
.Height() + rVal
.nHeight
;
497 if (rVal
.nMaxVPos
< rVal
.nMinVPos
)
499 rVal
.nMinVPos
= rVal
.nMaxVPos
;
500 rVal
.nMaxVPos
= -aBoundRect
.Height();
505 //restore width/height exchange
506 long nTmp
= rVal
.nWidth
;
507 rVal
.nWidth
= rVal
.nHeight
;
511 if (rVal
.nMaxWidth
< rVal
.nWidth
)
512 rVal
.nWidth
= rVal
.nMaxWidth
;
513 if (rVal
.nMaxHeight
< rVal
.nHeight
)
514 rVal
.nHeight
= rVal
.nMaxHeight
;
517 /*--------------------------------------------------------------------
518 Beschreibung: Korrektur fuer Umrandung
519 --------------------------------------------------------------------*/
521 SwTwips
SwFlyFrmAttrMgr::CalcTopSpace()
523 const SvxShadowItem
& rShadow
= GetShadow();
524 const SvxBoxItem
& rBox
= GetBox();
525 return rShadow
.CalcShadowSpace(SHADOW_TOP
) + rBox
.CalcLineSpace(BOX_LINE_TOP
);
528 SwTwips
SwFlyFrmAttrMgr::CalcBottomSpace()
530 const SvxShadowItem
& rShadow
= GetShadow();
531 const SvxBoxItem
& rBox
= GetBox();
532 return rShadow
.CalcShadowSpace(SHADOW_BOTTOM
) + rBox
.CalcLineSpace(BOX_LINE_BOTTOM
);
535 SwTwips
SwFlyFrmAttrMgr::CalcLeftSpace()
537 const SvxShadowItem
& rShadow
= GetShadow();
538 const SvxBoxItem
& rBox
= GetBox();
539 return rShadow
.CalcShadowSpace(SHADOW_LEFT
) + rBox
.CalcLineSpace(BOX_LINE_LEFT
);
542 SwTwips
SwFlyFrmAttrMgr::CalcRightSpace()
544 const SvxShadowItem
& rShadow
= GetShadow();
545 const SvxBoxItem
& rBox
= GetBox();
546 return rShadow
.CalcShadowSpace(SHADOW_RIGHT
) + rBox
.CalcLineSpace(BOX_LINE_RIGHT
);
550 /*--------------------------------------------------------------------
551 Beschreibung: Attribut aus dem Set loeschen
552 --------------------------------------------------------------------*/
553 void SwFlyFrmAttrMgr::DelAttr( USHORT nId
)
555 aSet
.ClearItem( nId
);
558 void SwFlyFrmAttrMgr::SetLRSpace( long nLeft
, long nRight
)
560 ASSERT( LONG_MAX
!= nLeft
&& LONG_MAX
!= nRight
, "Welchen Raend setzen?" );
562 SvxLRSpaceItem
aTmp( (SvxLRSpaceItem
&)aSet
.Get( RES_LR_SPACE
) );
563 if( LONG_MAX
!= nLeft
)
564 aTmp
.SetLeft( USHORT(nLeft
) );
565 if( LONG_MAX
!= nRight
)
566 aTmp
.SetRight( USHORT(nRight
) );
570 void SwFlyFrmAttrMgr::SetULSpace( long nTop
, long nBottom
)
572 ASSERT(LONG_MAX
!= nTop
&& LONG_MAX
!= nBottom
, "Welchen Raend setzen?" );
574 SvxULSpaceItem
aTmp( (SvxULSpaceItem
&)aSet
.Get( RES_UL_SPACE
) );
575 if( LONG_MAX
!= nTop
)
576 aTmp
.SetUpper( USHORT(nTop
) );
577 if( LONG_MAX
!= nBottom
)
578 aTmp
.SetLower( USHORT(nBottom
) );
582 void SwFlyFrmAttrMgr::SetPos( const Point
& rPoint
)
584 SwFmtVertOrient
aVertOrient( GetVertOrient() );
585 SwFmtHoriOrient
aHoriOrient( GetHoriOrient() );
587 aHoriOrient
.SetPos ( rPoint
.X() );
588 aHoriOrient
.SetHoriOrient( text::HoriOrientation::NONE
);
590 aVertOrient
.SetPos ( rPoint
.Y() );
591 aVertOrient
.SetVertOrient( text::VertOrientation::NONE
);
593 aSet
.Put( aVertOrient
);
594 aSet
.Put( aHoriOrient
);
597 void SwFlyFrmAttrMgr::SetHorzOrientation( sal_Int16 eOrient
)
599 SwFmtHoriOrient
aHoriOrient( GetHoriOrient() );
600 aHoriOrient
.SetHoriOrient( eOrient
);
601 aSet
.Put( aHoriOrient
);
604 void SwFlyFrmAttrMgr::SetVertOrientation( sal_Int16 eOrient
)
606 SwFmtVertOrient
aVertOrient( GetVertOrient() );
607 aVertOrient
.SetVertOrient( eOrient
);
608 aSet
.Put( aVertOrient
);
611 void SwFlyFrmAttrMgr::SetHeightSizeType( SwFrmSize eType
)
613 SwFmtFrmSize
aSize( GetFrmSize() );
614 aSize
.SetHeightSizeType( eType
);
618 void SwFlyFrmAttrMgr::SetSize( const Size
& rSize
)
620 SwFmtFrmSize
aSize( GetFrmSize() );
621 aSize
.SetSize(Size(Max(rSize
.Width(), long(MINFLY
)), Max(rSize
.Height(), long(MINFLY
))));
625 void SwFlyFrmAttrMgr::SetAttrSet(const SfxItemSet
& rSet
)