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: dview.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"
34 #include "hintids.hxx"
35 #include <svx/protitem.hxx>
36 #include <svx/svdpagv.hxx>
37 #ifndef _FM_FMMODEL_HXX
38 #include <svx/fmmodel.hxx>
41 #include "swtypes.hxx"
42 #include "pagefrm.hxx"
43 #include "rootfrm.hxx"
47 #include "dflyobj.hxx"
48 #include "dcontact.hxx"
51 #include "viewimp.hxx"
57 #include <fmtanchr.hxx>
58 #include "shellres.hxx"
61 #include <svx/outliner.hxx>
63 #include <com/sun/star/embed/EmbedMisc.hpp>
65 using namespace com::sun::star
;
67 // OD 18.06.2003 #108784#
68 //#ifndef _SVDVMARK_HXX //autogen
69 //#include <svx/svdvmark.hxx>
72 // --> OD 2004-06-24 #i28701#
73 #include <sortedobjs.hxx>
74 #include <flyfrms.hxx>
77 class SwSdrHdl
: public SdrHdl
80 SwSdrHdl(const Point
& rPnt
, bool bTopRight
) :
81 SdrHdl( rPnt
, bTopRight
? HDL_ANCHOR_TR
: HDL_ANCHOR
) {}
82 virtual BOOL
IsFocusHdl() const;
85 BOOL
SwSdrHdl::IsFocusHdl() const
87 if( HDL_ANCHOR
== eKind
|| HDL_ANCHOR_TR
== eKind
)
89 return SdrHdl::IsFocusHdl();
92 const SwFrm
*lcl_FindAnchor( const SdrObject
*pObj
, BOOL bAll
)
94 const SwVirtFlyDrawObj
*pVirt
= pObj
->ISA(SwVirtFlyDrawObj
) ?
95 (SwVirtFlyDrawObj
*)pObj
: 0;
98 if ( bAll
|| !pVirt
->GetFlyFrm()->IsFlyInCntFrm() )
99 return pVirt
->GetFlyFrm()->GetAnchorFrm();
103 const SwDrawContact
*pCont
= (const SwDrawContact
*)GetUserCall(pObj
);
105 return pCont
->GetAnchorFrm( pObj
);
110 /*************************************************************************
114 |* Ersterstellung OK 18.11.94
115 |* Letzte Aenderung MA 22. Jul. 96
117 *************************************************************************/
121 SwDrawView::SwDrawView( SwViewImp
&rI
, SdrModel
*pMd
, OutputDevice
*pOutDev
) :
122 FmFormView( (FmFormModel
*)pMd
, pOutDev
),
125 SetPageVisible( FALSE
);
126 SetBordVisible( FALSE
);
127 SetGridVisible( FALSE
);
128 SetHlplVisible( FALSE
);
129 SetGlueVisible( FALSE
);
130 SetFrameDragSingles( TRUE
);
131 SetVirtualObjectBundling( TRUE
);
132 SetSwapAsynchron( TRUE
);
134 EnableExtendedKeyInputDispatcher( FALSE
);
135 EnableExtendedMouseEventDispatcher( FALSE
);
136 EnableExtendedCommandEventDispatcher( FALSE
);
138 SetHitTolerancePixel( GetMarkHdlSizePixel()/2 );
140 SetPrintPreview( rI
.GetShell()->IsPreView() );
142 // #i73602# Use default from the configuration
143 SetBufferedOverlayAllowed(getOptionsDrawinglayer().IsOverlayBuffer_Writer());
145 // #i74769#, #i75172# Use default from the configuration
146 SetBufferedOutputAllowed(getOptionsDrawinglayer().IsPaintBuffer_Writer());
149 // --> OD 2009-03-05 #i99665#
150 sal_Bool
SwDrawView::IsAntiAliasing() const
152 return getOptionsDrawinglayer().IsAntiAliasing();
156 //////////////////////////////////////////////////////////////////////////////
158 SdrObject
* impLocalHitCorrection(SdrObject
* pRetval
, const Point
& rPnt
, USHORT nTol
, const SdrMarkList
&rMrkList
)
162 // the old method forced back to outer bounds test when nTol == 0, so
163 // do not try to correct when nTol is not set (used from HelpContent)
167 // rebuild logic from former SwVirtFlyDrawObj::CheckSdrObjectHit. This is needed since
168 // the SdrObject-specific CheckHit implementations are now replaced with primitives and
169 // 'tricks' like in the old implementation (e.g. using a view from a model-data class to
170 // detect if object is selected) are no longer valid.
171 // The standard primitive hit-test for SwVirtFlyDrawObj now is the outer bound. The old
172 // implementation reduced this excluding the inner bound when the object was not selected.
173 SwVirtFlyDrawObj
* pSwVirtFlyDrawObj
= dynamic_cast< SwVirtFlyDrawObj
* >(pRetval
);
175 if(pSwVirtFlyDrawObj
)
177 if(pSwVirtFlyDrawObj
->GetFlyFrm()->Lower() && pSwVirtFlyDrawObj
->GetFlyFrm()->Lower()->IsNoTxtFrm())
179 // the old method used IsNoTxtFrm (should be for SW's own OLE and
180 // graphic's) to accept hit only based on outer bounds; nothing to do
184 // check if the object is selected in this view
185 const sal_uInt32
nMarkCount(rMrkList
.GetMarkCount());
186 bool bSelected(false);
188 for(sal_uInt32
a(0); !bSelected
&& a
< nMarkCount
; a
++)
190 if(pSwVirtFlyDrawObj
== rMrkList
.GetMark(a
)->GetMarkedSdrObj())
198 // when not selected, the object is not hit when hit position is inside
199 // inner range. Get and shrink inner range
200 basegfx::B2DRange
aInnerBound(pSwVirtFlyDrawObj
->getInnerBound());
202 aInnerBound
.grow(-1.0 * nTol
);
204 if(aInnerBound
.isInside(basegfx::B2DPoint(rPnt
.X(), rPnt
.Y())))
217 SdrObject
* SwDrawView::CheckSingleSdrObjectHit(const Point
& rPnt
, USHORT nTol
, SdrObject
* pObj
, SdrPageView
* pPV
, ULONG nOptions
, const SetOfByte
* pMVisLay
) const
220 SdrObject
* pRetval
= FmFormView::CheckSingleSdrObjectHit(rPnt
, nTol
, pObj
, pPV
, nOptions
, pMVisLay
);
224 // overloaded to allow extra handling when picking SwVirtFlyDrawObj's
225 pRetval
= impLocalHitCorrection(pRetval
, rPnt
, nTol
, GetMarkedObjectList());
231 /*************************************************************************
233 |* SwDrawView::AddCustomHdl()
235 |* Gets called every time the handles need to be build
237 |* Ersterstellung AW 06. Sep. 99
238 |* Letzte Aenderung AW 06. Sep. 99
240 *************************************************************************/
242 void SwDrawView::AddCustomHdl()
244 const SdrMarkList
&rMrkList
= GetMarkedObjectList();
246 if(rMrkList
.GetMarkCount() != 1 || !GetUserCall(rMrkList
.GetMark( 0 )->GetMarkedSdrObj()))
249 SdrObject
*pObj
= rMrkList
.GetMark(0)->GetMarkedSdrObj();
250 // --> OD 2006-11-06 #130889# - make code robust
251 // const SwFmtAnchor &rAnchor = ::FindFrmFmt(pObj)->GetAnchor();
252 SwFrmFmt
* pFrmFmt( ::FindFrmFmt( pObj
) );
255 ASSERT( false, "<SwDrawView::AddCustomHdl()> - missing frame format!" );
258 const SwFmtAnchor
&rAnchor
= pFrmFmt
->GetAnchor();
261 if(FLY_IN_CNTNT
== rAnchor
.GetAnchorId())
265 if(0 == (pAnch
= CalcAnchor()))
268 Point
aPos(aAnchorPoint
);
270 if ( FLY_AUTO_CNTNT
== rAnchor
.GetAnchorId() )
272 // --> OD 2004-06-24 #i28701# - use last character rectangle saved at object
273 // in order to avoid a format of the anchor frame
274 SwAnchoredObject
* pAnchoredObj
= ::GetUserCall( pObj
)->GetAnchoredObj( pObj
);
275 SwRect aAutoPos
= pAnchoredObj
->GetLastCharRect();
276 if ( aAutoPos
.Height() )
278 aPos
= aAutoPos
.Pos();
282 // add anchor handle:
283 aHdl
.AddHdl( new SwSdrHdl( aPos
, pAnch
->IsVertical() ||
284 pAnch
->IsRightToLeft() ) );
287 /*************************************************************************
289 |* SwDrawView::GetMaxToTopObj(), _GetMaxToTopObj()
291 |* Ersterstellung MA 13. Jan. 95
292 |* Letzte Aenderung MA 18. Mar. 97
294 *************************************************************************/
297 SdrObject
* SwDrawView::GetMaxToTopObj( SdrObject
* pObj
) const
299 if ( GetUserCall(pObj
) )
301 const SwFrm
*pAnch
= ::lcl_FindAnchor( pObj
, FALSE
);
304 //Das oberste Obj innerhalb des Ankers darf nicht ueberholt
306 const SwFlyFrm
*pFly
= pAnch
->FindFlyFrm();
309 const SwPageFrm
*pPage
= pFly
->FindPageFrm();
310 if ( pPage
->GetSortedObjs() )
313 for ( USHORT i
= 0; i
< pPage
->GetSortedObjs()->Count(); ++i
)
315 const SdrObject
*pO
=
316 (*pPage
->GetSortedObjs())[i
]->GetDrawObj();
318 if ( pO
->GetOrdNumDirect() > nOrdNum
)
320 const SwFrm
*pTmpAnch
= ::lcl_FindAnchor( pO
, FALSE
);
321 if ( pFly
->IsAnLower( pTmpAnch
) )
323 nOrdNum
= pO
->GetOrdNumDirect();
329 SdrPage
*pTmpPage
= GetModel()->GetPage( 0 );
331 if ( nOrdNum
< pTmpPage
->GetObjCount() )
333 return pTmpPage
->GetObj( nOrdNum
);
343 /*************************************************************************
345 |* SwDrawView::GetMaxToBtmObj()
347 |* Ersterstellung MA 13. Jan. 95
348 |* Letzte Aenderung MA 05. Sep. 96
350 *************************************************************************/
353 SdrObject
* SwDrawView::GetMaxToBtmObj(SdrObject
* pObj
) const
355 if ( GetUserCall(pObj
) )
357 const SwFrm
*pAnch
= ::lcl_FindAnchor( pObj
, FALSE
);
360 //Der Fly des Ankers darf nicht "unterflogen" werden.
361 const SwFlyFrm
*pFly
= pAnch
->FindFlyFrm();
364 SdrObject
*pRet
= (SdrObject
*)pFly
->GetVirtDrawObj();
365 return pRet
!= pObj
? pRet
: 0;
372 /*************************************************************************
374 |* SwDrawView::ObjOrderChanged()
376 |* Ersterstellung MA 31. Jul. 95
377 |* Letzte Aenderung MA 18. Mar. 97
379 *************************************************************************/
381 inline BOOL
lcl_IsChild( SdrObject
*pParent
, SdrObject
*pChild
)
383 if ( pParent
->ISA(SwVirtFlyDrawObj
) )
385 const SwFrm
*pAnch
= lcl_FindAnchor( pChild
, FALSE
);
386 if ( pAnch
&& ((SwVirtFlyDrawObj
*)pParent
)->GetFlyFrm()->IsAnLower( pAnch
))
394 inline SdrObject
*lcl_FindParent( SdrObject
*pObj
)
396 const SwFrm
*pAnch
= lcl_FindAnchor( pObj
, FALSE
);
397 if ( pAnch
&& pAnch
->IsInFly() )
398 return (SdrObject
*)pAnch
->FindFlyFrm()->GetVirtDrawObj();
402 /** determine maximal order number for a 'child' object of given 'parent' object
404 OD 2004-08-20 #110810#
408 sal_uInt32
SwDrawView::_GetMaxChildOrdNum( const SwFlyFrm
& _rParentObj
,
409 const SdrObject
* _pExclChildObj
) const
411 sal_uInt32 nMaxChildOrdNum
= _rParentObj
.GetDrawObj()->GetOrdNum();
413 const SdrPage
* pDrawPage
= _rParentObj
.GetDrawObj()->GetPage();
415 "<SwDrawView::_GetMaxChildOrdNum(..) - missing drawing page at parent object - crash!" );
417 sal_uInt32 nObjCount
= pDrawPage
->GetObjCount();
418 for ( sal_uInt32 i
= nObjCount
-1; i
> _rParentObj
.GetDrawObj()->GetOrdNum() ; --i
)
420 const SdrObject
* pObj
= pDrawPage
->GetObj( i
);
422 // Don't consider 'child' object <_pExclChildObj>
423 if ( pObj
== _pExclChildObj
)
428 if ( pObj
->GetOrdNum() > nMaxChildOrdNum
&&
429 _rParentObj
.IsAnLower( lcl_FindAnchor( pObj
, TRUE
) ) )
431 nMaxChildOrdNum
= pObj
->GetOrdNum();
436 return nMaxChildOrdNum
;
439 /** method to move 'repeated' objects of the given moved object to the
442 OD 2004-08-23 #110810#
446 void SwDrawView::_MoveRepeatedObjs( const SwAnchoredObject
& _rMovedAnchoredObj
,
447 const std::vector
<SdrObject
*>& _rMovedChildObjs
) const
449 // determine 'repeated' objects of already moved object <_rMovedAnchoredObj>
450 std::vector
<SwAnchoredObject
*> aAnchoredObjs
;
452 const SwContact
* pContact
= ::GetUserCall( _rMovedAnchoredObj
.GetDrawObj() );
454 "SwDrawView::_MoveRepeatedObjs(..) - missing contact object -> crash." );
455 pContact
->GetAnchoredObjs( aAnchoredObjs
);
458 // check, if 'repeated' objects exists.
459 if ( aAnchoredObjs
.size() > 1 )
461 SdrPage
* pDrawPage
= GetModel()->GetPage( 0 );
463 // move 'repeated' ones to the same order number as the already moved one.
464 sal_uInt32 nNewPos
= _rMovedAnchoredObj
.GetDrawObj()->GetOrdNum();
465 while ( !aAnchoredObjs
.empty() )
467 SwAnchoredObject
* pAnchoredObj
= aAnchoredObjs
.back();
468 if ( pAnchoredObj
!= &_rMovedAnchoredObj
)
470 pDrawPage
->SetObjectOrdNum( pAnchoredObj
->GetDrawObj()->GetOrdNum(),
472 pDrawPage
->RecalcObjOrdNums();
473 // adjustments for accessibility API
474 if ( pAnchoredObj
->ISA(SwFlyFrm
) )
476 const SwFlyFrm
*pTmpFlyFrm
= static_cast<SwFlyFrm
*>(pAnchoredObj
);
477 rImp
.DisposeAccessibleFrm( pTmpFlyFrm
);
478 rImp
.AddAccessibleFrm( pTmpFlyFrm
);
482 rImp
.DisposeAccessibleObj( pAnchoredObj
->GetDrawObj() );
483 rImp
.AddAccessibleObj( pAnchoredObj
->GetDrawObj() );
486 aAnchoredObjs
.pop_back();
489 // move 'repeated' ones of 'child' objects
490 for ( std::vector
<SdrObject
*>::const_iterator aObjIter
= _rMovedChildObjs
.begin();
491 aObjIter
!= _rMovedChildObjs
.end(); ++aObjIter
)
493 SdrObject
* pChildObj
= (*aObjIter
);
495 const SwContact
* pContact
= ::GetUserCall( pChildObj
);
497 "SwDrawView::_MoveRepeatedObjs(..) - missing contact object -> crash." );
498 pContact
->GetAnchoredObjs( aAnchoredObjs
);
500 // move 'repeated' ones to the same order number as the already moved one.
501 const sal_uInt32 nTmpNewPos
= pChildObj
->GetOrdNum();
502 while ( !aAnchoredObjs
.empty() )
504 SwAnchoredObject
* pAnchoredObj
= aAnchoredObjs
.back();
505 if ( pAnchoredObj
->GetDrawObj() != pChildObj
)
507 pDrawPage
->SetObjectOrdNum( pAnchoredObj
->GetDrawObj()->GetOrdNum(),
509 pDrawPage
->RecalcObjOrdNums();
510 // adjustments for accessibility API
511 if ( pAnchoredObj
->ISA(SwFlyFrm
) )
513 const SwFlyFrm
*pTmpFlyFrm
= static_cast<SwFlyFrm
*>(pAnchoredObj
);
514 rImp
.DisposeAccessibleFrm( pTmpFlyFrm
);
515 rImp
.AddAccessibleFrm( pTmpFlyFrm
);
519 rImp
.DisposeAccessibleObj( pAnchoredObj
->GetDrawObj() );
520 rImp
.AddAccessibleObj( pAnchoredObj
->GetDrawObj() );
523 aAnchoredObjs
.pop_back();
529 // --> OD 2004-08-20 #110810# - adjustment and re-factoring of method
530 void SwDrawView::ObjOrderChanged( SdrObject
* pObj
, ULONG nOldPos
,
533 // --> OD 2004-08-17 #110810# - nothing to do for group members
534 if ( pObj
->GetUpGroup() )
540 // determine drawing page and assure that the order numbers are correct.
541 SdrPage
* pDrawPage
= GetModel()->GetPage( 0 );
542 if ( pDrawPage
->IsObjOrdNumsDirty() )
543 pDrawPage
->RecalcObjOrdNums();
544 const sal_uInt32 nObjCount
= pDrawPage
->GetObjCount();
546 SwAnchoredObject
* pMovedAnchoredObj
=
547 ::GetUserCall( pObj
)->GetAnchoredObj( pObj
);
548 const SwFlyFrm
* pParentAnchoredObj
=
549 pMovedAnchoredObj
->GetAnchorFrm()->FindFlyFrm();
551 const bool bMovedForward
= nOldPos
< nNewPos
;
553 // assure for a 'child' object, that it doesn't exceed the limits of its 'parent'
554 if ( pParentAnchoredObj
)
558 sal_uInt32 nMaxChildOrdNumWithoutMoved
=
559 _GetMaxChildOrdNum( *pParentAnchoredObj
, pMovedAnchoredObj
->GetDrawObj() );
560 if ( nNewPos
> nMaxChildOrdNumWithoutMoved
+1 )
562 // set position to the top of the 'child' object group
563 pDrawPage
->SetObjectOrdNum( nNewPos
, nMaxChildOrdNumWithoutMoved
+1 );
564 nNewPos
= nMaxChildOrdNumWithoutMoved
+1;
569 const sal_uInt32 nParentOrdNum
= pParentAnchoredObj
->GetDrawObj()->GetOrdNum();
570 if ( nNewPos
< nParentOrdNum
)
572 // set position to the bottom of the 'child' object group
573 pDrawPage
->SetObjectOrdNum( nNewPos
, nParentOrdNum
);
574 nNewPos
= nParentOrdNum
;
577 if ( pDrawPage
->IsObjOrdNumsDirty() )
578 pDrawPage
->RecalcObjOrdNums();
581 // Assure, that object isn't positioned between 'repeated' ones
582 if ( ( bMovedForward
&& nNewPos
< nObjCount
- 1 ) ||
583 ( !bMovedForward
&& nNewPos
> 0 ) )
585 const SdrObject
* pTmpObj
=
586 pDrawPage
->GetObj( bMovedForward
? nNewPos
- 1 : nNewPos
+ 1 );
589 sal_uInt32
nTmpNewPos( nNewPos
);
592 // move before the top 'repeated' object
593 const sal_uInt32 nTmpMaxOrdNum
=
594 ::GetUserCall( pTmpObj
)->GetMaxOrdNum();
595 if ( nTmpMaxOrdNum
> nNewPos
)
596 nTmpNewPos
= nTmpMaxOrdNum
;
600 // move behind the bottom 'repeated' object
601 const sal_uInt32 nTmpMinOrdNum
=
602 ::GetUserCall( pTmpObj
)->GetMinOrdNum();
603 if ( nTmpMinOrdNum
< nNewPos
)
604 nTmpNewPos
= nTmpMinOrdNum
;
606 if ( nTmpNewPos
!= nNewPos
)
608 pDrawPage
->SetObjectOrdNum( nNewPos
, nTmpNewPos
);
609 nNewPos
= nTmpNewPos
;
610 pDrawPage
->RecalcObjOrdNums();
615 // On move forward, assure that object is moved before its own childs.
616 // Only Writer fly frames can have childs.
617 if ( pMovedAnchoredObj
->ISA(SwFlyFrm
) &&
618 bMovedForward
&& nNewPos
< nObjCount
- 1 )
620 sal_uInt32 nMaxChildOrdNum
=
621 _GetMaxChildOrdNum( *(static_cast<const SwFlyFrm
*>(pMovedAnchoredObj
)) );
622 if ( nNewPos
< nMaxChildOrdNum
)
624 // determine position before the object before its top 'child' object
625 const SdrObject
* pTmpObj
= pDrawPage
->GetObj( nMaxChildOrdNum
);
626 sal_uInt32 nTmpNewPos
= ::GetUserCall( pTmpObj
)->GetMaxOrdNum() + 1;
627 if ( nTmpNewPos
>= nObjCount
)
631 // assure, that determined position isn't between 'repeated' objects
632 pTmpObj
= pDrawPage
->GetObj( nTmpNewPos
);
633 nTmpNewPos
= ::GetUserCall( pTmpObj
)->GetMaxOrdNum();
634 // apply new position
635 pDrawPage
->SetObjectOrdNum( nNewPos
, nTmpNewPos
);
636 nNewPos
= nTmpNewPos
;
637 pDrawPage
->RecalcObjOrdNums();
641 // Assure, that object isn't positioned between nested objects
642 if ( ( bMovedForward
&& nNewPos
< nObjCount
- 1 ) ||
643 ( !bMovedForward
&& nNewPos
> 0 ) )
645 sal_uInt32
nTmpNewPos( nNewPos
);
646 const SwFrmFmt
* pParentFrmFmt
=
647 pParentAnchoredObj
? &(pParentAnchoredObj
->GetFrmFmt()) : 0L;
648 const SdrObject
* pTmpObj
= pDrawPage
->GetObj( nNewPos
+ 1 );
651 // --> OD 2004-12-07 #i38563# - assure, that anchor frame exists.
652 // If object is anchored inside a invisible part of the document
653 // (e.g. page header, whose page style isn't applied, or hidden
654 // section), no anchor frame exists.
655 const SwFrm
* pTmpAnchorFrm
= lcl_FindAnchor( pTmpObj
, TRUE
);
656 const SwFlyFrm
* pTmpParentObj
= pTmpAnchorFrm
657 ? pTmpAnchorFrm
->FindFlyFrm() : 0L;
659 if ( pTmpParentObj
&&
660 &(pTmpParentObj
->GetFrmFmt()) != pParentFrmFmt
)
664 nTmpNewPos
= ::GetUserCall( pTmpObj
)->GetMaxOrdNum();
665 pTmpObj
= pDrawPage
->GetObj( nTmpNewPos
+ 1 );
669 nTmpNewPos
= ::GetUserCall( pTmpParentObj
->GetDrawObj() )
671 pTmpObj
= pTmpParentObj
->GetDrawObj();
677 if ( nTmpNewPos
!= nNewPos
)
679 pDrawPage
->SetObjectOrdNum( nNewPos
, nTmpNewPos
);
680 nNewPos
= nTmpNewPos
;
681 pDrawPage
->RecalcObjOrdNums();
685 // setup collection of moved 'child' objects to move its 'repeated' objects.
686 std::vector
< SdrObject
* > aMovedChildObjs
;
688 // move 'childs' accordingly
689 if ( pMovedAnchoredObj
->ISA(SwFlyFrm
) )
691 const SwFlyFrm
* pFlyFrm
= static_cast<SwFlyFrm
*>(pMovedAnchoredObj
);
693 // adjustments for accessibility API
694 rImp
.DisposeAccessibleFrm( pFlyFrm
);
695 rImp
.AddAccessibleFrm( pFlyFrm
);
697 const sal_uInt32 nChildNewPos
= bMovedForward
? nNewPos
: nNewPos
+1;
698 sal_uInt32 i
= bMovedForward
? nOldPos
: nObjCount
-1;
701 SdrObject
* pTmpObj
= pDrawPage
->GetObj( i
);
702 if ( pTmpObj
== pObj
)
705 // --> OD 2004-12-07 #i38563# - assure, that anchor frame exists.
706 // If object is anchored inside a invisible part of the document
707 // (e.g. page header, whose page style isn't applied, or hidden
708 // section), no anchor frame exists.
709 const SwFrm
* pTmpAnchorFrm
= lcl_FindAnchor( pTmpObj
, TRUE
);
710 const SwFlyFrm
* pTmpParentObj
= pTmpAnchorFrm
711 ? pTmpAnchorFrm
->FindFlyFrm() : 0L;
713 if ( pTmpParentObj
&&
714 ( ( pTmpParentObj
== pFlyFrm
) ||
715 ( pFlyFrm
->IsUpperOf( *pTmpParentObj
) ) ) )
717 // move child object.,
718 pDrawPage
->SetObjectOrdNum( i
, nChildNewPos
);
719 pDrawPage
->RecalcObjOrdNums();
720 // collect 'child' object
721 aMovedChildObjs
.push_back( pTmpObj
);
722 // adjustments for accessibility API
723 if ( pTmpObj
->ISA(SwVirtFlyDrawObj
) )
725 const SwFlyFrm
*pTmpFlyFrm
=
726 static_cast<SwVirtFlyDrawObj
*>(pTmpObj
)->GetFlyFrm();
727 rImp
.DisposeAccessibleFrm( pTmpFlyFrm
);
728 rImp
.AddAccessibleFrm( pTmpFlyFrm
);
732 rImp
.DisposeAccessibleObj( pTmpObj
);
733 rImp
.AddAccessibleObj( pTmpObj
);
738 // adjust loop counter
741 else if ( !bMovedForward
&& i
> 0 )
745 } while ( ( bMovedForward
&& i
< ( nObjCount
- aMovedChildObjs
.size() ) ) ||
746 ( !bMovedForward
&& i
> ( nNewPos
+ aMovedChildObjs
.size() ) ) );
750 // adjustments for accessibility API
751 rImp
.DisposeAccessibleObj( pObj
);
752 rImp
.AddAccessibleObj( pObj
);
755 _MoveRepeatedObjs( *pMovedAnchoredObj
, aMovedChildObjs
);
759 /*************************************************************************
761 |* SwDrawView::TakeDragLimit()
763 |* Ersterstellung AMA 26. Apr. 96
764 |* Letzte Aenderung MA 03. May. 96
766 *************************************************************************/
769 BOOL
SwDrawView::TakeDragLimit( SdrDragMode eMode
,
770 Rectangle
& rRect
) const
772 const SdrMarkList
&rMrkList
= GetMarkedObjectList();
774 if( 1 == rMrkList
.GetMarkCount() )
776 const SdrObject
*pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
778 if( ::CalcClipRect( pObj
, aRect
, eMode
== SDRDRAG_MOVE
) )
780 rRect
= aRect
.SVRect();
787 /*************************************************************************
789 |* SwDrawView::CalcAnchor()
791 |* Ersterstellung MA 13. Jan. 95
792 |* Letzte Aenderung MA 08. Nov. 96
794 *************************************************************************/
797 const SwFrm
* SwDrawView::CalcAnchor()
799 const SdrMarkList
&rMrkList
= GetMarkedObjectList();
800 if ( rMrkList
.GetMarkCount() != 1 )
803 SdrObject
* pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
805 //Fuer Absatzgebundene Objekte suchen, andernfalls einfach nur
806 //der aktuelle Anker. Nur suchen wenn wir gerade draggen.
809 const BOOL bFly
= pObj
->ISA(SwVirtFlyDrawObj
);
812 pAnch
= ((SwVirtFlyDrawObj
*)pObj
)->GetFlyFrm()->GetAnchorFrm();
813 aMyRect
= ((SwVirtFlyDrawObj
*)pObj
)->GetFlyFrm()->Frm().SVRect();
817 SwDrawContact
*pC
= (SwDrawContact
*)GetUserCall(pObj
);
818 // OD 17.06.2003 #108784# - determine correct anchor position for
819 // 'virtual' drawing objects.
820 // OD 2004-03-25 #i26791#
821 pAnch
= pC
->GetAnchorFrm( pObj
);
824 pC
->ConnectToLayout();
825 // OD 17.06.2003 #108784# - determine correct anchor position for
826 // 'virtual' drawing objects.
827 // OD 2004-03-25 #i26791#
828 pAnch
= pC
->GetAnchorFrm( pObj
);
830 aMyRect
= pObj
->GetSnapRect();
833 const sal_Bool bTopRight
= pAnch
&& ( pAnch
->IsVertical() ||
834 pAnch
->IsRightToLeft() );
836 const Point aMyPt
= bTopRight
? aMyRect
.TopRight() : aMyRect
.TopLeft();
841 if ( !TakeDragObjAnchorPos( aPt
, bTopRight
) )
846 Rectangle aRect
= pObj
->GetSnapRect();
847 aPt
= bTopRight
? aRect
.TopRight() : aRect
.TopLeft();
852 if ( pAnch
->IsCntntFrm() )
854 // OD 26.06.2003 #108784# - allow drawing objects in header/footer,
855 // but exclude control objects.
856 bool bBodyOnly
= CheckControlLayer( pObj
);
857 pAnch
= ::FindAnchor( (SwCntntFrm
*)pAnch
, aPt
, bBodyOnly
);
861 const SwRect
aRect( aPt
.X(), aPt
.Y(), 1, 1 );
863 SwDrawContact
* pContact
= (SwDrawContact
*)GetUserCall(pObj
);
864 if ( pContact
->GetAnchorFrm( pObj
) &&
865 pContact
->GetAnchorFrm( pObj
)->IsPageFrm() )
866 pAnch
= pContact
->GetPageFrm();
868 pAnch
= pContact
->FindPage( aRect
);
871 if( pAnch
&& !pAnch
->IsProtected() )
872 aAnchorPoint
= pAnch
->GetFrmAnchorPos( ::HasWrap( pObj
) );
878 /*************************************************************************
880 |* SwDrawView::ShowDragXor(), HideDragXor()
882 |* Ersterstellung MA 17. Jan. 95
883 |* Letzte Aenderung MA 27. Jan. 95
885 *************************************************************************/
888 void SwDrawView::ShowDragAnchor()
890 SdrHdl
* pHdl
= aHdl
.GetHdl(HDL_ANCHOR
);
892 pHdl
= aHdl
.GetHdl(HDL_ANCHOR_TR
);
897 pHdl
->SetPos(aAnchorPoint
);
898 //OLMRefreshAllIAOManagers();
902 /*************************************************************************
904 |* SwDrawView::MarkListHasChanged()
906 |* Ersterstellung OM 02. Feb. 95
907 |* Letzte Aenderung OM 07. Jul. 95
909 *************************************************************************/
912 void SwDrawView::MarkListHasChanged()
914 Imp().GetShell()->DrawSelChanged();
915 FmFormView::MarkListHasChanged();
919 void SwDrawView::ModelHasChanged()
921 // The ModelHasChanged() call in DrawingLayer also updates
922 // a eventually active text edit view (OutlinerView). This also leads
923 // to newly setting the background color for that edit view. Thus,
924 // this method rescues the current background color if a OutlinerView
925 // exists and re-establishes it then. To be more safe, the OutlinerView
926 // will be fetched again (maybe textedit has ended).
927 OutlinerView
* pView
= GetTextEditOutlinerView();
929 sal_Bool
bColorWasSaved(sal_False
);
933 aBackColor
= pView
->GetBackgroundColor();
934 bColorWasSaved
= sal_True
;
938 FmFormView::ModelHasChanged();
942 pView
= GetTextEditOutlinerView();
946 pView
->SetBackgroundColor(aBackColor
);
951 void SwDrawView::MakeVisible( const Rectangle
&rRect
, Window
& )
953 ASSERT( rImp
.GetShell()->GetWin(), "MakeVisible, unknown Window");
954 rImp
.GetShell()->MakeVisible( SwRect( rRect
) );
957 void SwDrawView::CheckPossibilities()
959 FmFormView::CheckPossibilities();
961 //Zusaetzlich zu den bestehenden Flags der Objekte selbst, die von der
962 //DrawingEngine ausgewertet werden, koennen weitere Umstaende zu einem
964 //Objekte, die in Rahmen verankert sind, muessen genau dann geschuetzt
965 //sein, wenn der Inhalt des Rahmens geschuetzt ist.
966 //OLE-Objekte konnen selbst einen Resize-Schutz wuenschen (StarMath)
968 const SdrMarkList
&rMrkList
= GetMarkedObjectList();
969 BOOL bProtect
= FALSE
,
971 for ( USHORT i
= 0; !bProtect
&& i
< rMrkList
.GetMarkCount(); ++i
)
973 const SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
974 const SwFrm
*pFrm
= NULL
;
975 if ( pObj
->ISA(SwVirtFlyDrawObj
) )
977 const SwFlyFrm
*pFly
= ((SwVirtFlyDrawObj
*)pObj
)->GetFlyFrm();
980 pFrm
= pFly
->GetAnchorFrm();
981 if ( pFly
->Lower() && pFly
->Lower()->IsNoTxtFrm() )
983 SwOLENode
*pNd
= ((SwCntntFrm
*)pFly
->Lower())->GetNode()->GetOLENode();
986 uno::Reference
< embed::XEmbeddedObject
> xObj
= pNd
->GetOLEObj().GetOleRef();
989 // --> OD 2004-08-16 #110810# - improvement for
990 // the future, when more than one Writer fly frame
993 // TODO/LATER: retrieve Aspect - from where?!
994 bSzProtect
|= ( embed::EmbedMisc::EMBED_NEVERRESIZE
& xObj
->getStatus( embed::Aspects::MSOLE_CONTENT
) ) ? TRUE
: FALSE
;
1004 SwDrawContact
*pC
= (SwDrawContact
*)GetUserCall(pObj
);
1006 pFrm
= pC
->GetAnchorFrm( pObj
);
1009 bProtect
= pFrm
->IsProtected(); //Rahmen, Bereiche usw.
1010 // --> OD 2006-11-06 #130889# - make code robust
1011 // if ( FLY_IN_CNTNT == ::FindFrmFmt( (SdrObject*)pObj )->GetAnchor().GetAnchorId() &&
1012 // rMrkList.GetMarkCount() > 1 )
1015 SwFrmFmt
* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject
*>(pObj
) ) );
1019 "<SwDrawView::CheckPossibilities()> - missing frame format" );
1022 else if ( FLY_IN_CNTNT
== pFrmFmt
->GetAnchor().GetAnchorId() &&
1023 rMrkList
.GetMarkCount() > 1 )
1030 bMoveProtect
|= bProtect
;
1031 bResizeProtect
|= bProtect
| bSzProtect
;
1034 /** replace marked <SwDrawVirtObj>-objects by its reference object for delete
1037 OD 18.06.2003 #108784#
1041 void SwDrawView::ReplaceMarkedDrawVirtObjs( SdrMarkView
& _rMarkView
)
1043 SdrPageView
* pDrawPageView
= _rMarkView
.GetSdrPageView();
1044 const SdrMarkList
& rMarkList
= _rMarkView
.GetMarkedObjectList();
1046 if( rMarkList
.GetMarkCount() )
1048 // collect marked objects in a local data structure
1049 std::vector
<SdrObject
*> aMarkedObjs
;
1050 for( sal_uInt32 i
= 0; i
< rMarkList
.GetMarkCount(); ++i
)
1052 SdrObject
* pMarkedObj
= rMarkList
.GetMark( i
)->GetMarkedSdrObj();
1053 aMarkedObjs
.push_back( pMarkedObj
);
1055 // unmark all objects
1056 _rMarkView
.UnmarkAllObj();
1057 // re-mark objects, but for marked <SwDrawVirtObj>-objects marked its
1058 // reference object.
1059 while ( !aMarkedObjs
.empty() )
1061 SdrObject
* pMarkObj
= aMarkedObjs
.back();
1062 if ( pMarkObj
->ISA(SwDrawVirtObj
) )
1064 SdrObject
* pRefObj
= &(static_cast<SwDrawVirtObj
*>(pMarkObj
)->ReferencedObj());
1065 if ( !_rMarkView
.IsObjMarked( pRefObj
) )
1067 _rMarkView
.MarkObj( pRefObj
, pDrawPageView
);
1072 _rMarkView
.MarkObj( pMarkObj
, pDrawPageView
);
1075 aMarkedObjs
.pop_back();
1077 // sort marked list in order to assure consistent state in drawing layer
1078 _rMarkView
.SortMarkedObjects();
1082 void SwDrawView::DeleteMarked()
1084 SwDoc
* pDoc
= Imp().GetShell()->GetDoc();
1085 if ( pDoc
->GetRootFrm() )
1086 pDoc
->GetRootFrm()->StartAllAction();
1087 pDoc
->StartUndo(UNDO_EMPTY
, NULL
);
1088 // OD 18.06.2003 #108784# - replace marked <SwDrawVirtObj>-objects by its
1089 // reference objects.
1091 SdrPageView
* pDrawPageView
= rImp
.GetPageView();
1092 if ( pDrawPageView
)
1094 SdrMarkView
* pMarkView
= PTR_CAST( SdrMarkView
, &(pDrawPageView
->GetView()) );
1097 ReplaceMarkedDrawVirtObjs( *pMarkView
);
1101 if ( pDoc
->DeleteSelection( *this ) )
1103 FmFormView::DeleteMarked();
1104 ::FrameNotify( Imp().GetShell(), FLY_DRAG_END
);
1106 pDoc
->EndUndo(UNDO_EMPTY
, NULL
);
1107 if( pDoc
->GetRootFrm() )
1108 pDoc
->GetRootFrm()->EndAllAction();
1112 JP 02.10.98: sollte als Fix fuer 57153 gelten, hatte aber Nebenwirkungen,
1114 const SdrMarkList& SwDrawView::GetMarkedObjectList() const
1116 FlushComeBackTimer();
1117 return FmFormView::GetMarkedObjectList();