update dev300-m58
[ooovba.git] / sw / source / core / draw / dview.cxx
blob08051aa33dc90493e2c2a99c05778b60d0f6f5d8
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 $
10 * $Revision: 1.30 $
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>
39 #endif
41 #include "swtypes.hxx"
42 #include "pagefrm.hxx"
43 #include "rootfrm.hxx"
44 #include "cntfrm.hxx"
45 #include "flyfrm.hxx"
46 #include "frmfmt.hxx"
47 #include "dflyobj.hxx"
48 #include "dcontact.hxx"
49 #include "frmatr.hxx"
50 #include "viewsh.hxx"
51 #include "viewimp.hxx"
52 #include "dview.hxx"
53 #include "dpage.hxx"
54 #include "doc.hxx"
55 #include "mdiexp.hxx"
56 #include <ndole.hxx>
57 #include <fmtanchr.hxx>
58 #include "shellres.hxx"
60 // #i7672#
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>
70 //#endif
71 #include <vector>
72 // --> OD 2004-06-24 #i28701#
73 #include <sortedobjs.hxx>
74 #include <flyfrms.hxx>
75 // <--
77 class SwSdrHdl : public SdrHdl
79 public:
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 )
88 return TRUE;
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;
96 if ( pVirt )
98 if ( bAll || !pVirt->GetFlyFrm()->IsFlyInCntFrm() )
99 return pVirt->GetFlyFrm()->GetAnchorFrm();
101 else
103 const SwDrawContact *pCont = (const SwDrawContact*)GetUserCall(pObj);
104 if ( pCont )
105 return pCont->GetAnchorFrm( pObj );
107 return 0;
110 /*************************************************************************
112 |* SwDrawView::Ctor
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 ),
123 rImp( rI )
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();
154 // <--
156 //////////////////////////////////////////////////////////////////////////////
158 SdrObject* impLocalHitCorrection(SdrObject* pRetval, const Point& rPnt, USHORT nTol, const SdrMarkList &rMrkList)
160 if(!nTol)
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)
165 else
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
182 else
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())
192 bSelected = true;
196 if(!bSelected)
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())))
206 // exclude this hit
207 pRetval = 0;
214 return pRetval;
217 SdrObject* SwDrawView::CheckSingleSdrObjectHit(const Point& rPnt, USHORT nTol, SdrObject* pObj, SdrPageView* pPV, ULONG nOptions, const SetOfByte* pMVisLay) const
219 // call parent
220 SdrObject* pRetval = FmFormView::CheckSingleSdrObjectHit(rPnt, nTol, pObj, pPV, nOptions, pMVisLay);
222 if(pRetval)
224 // overloaded to allow extra handling when picking SwVirtFlyDrawObj's
225 pRetval = impLocalHitCorrection(pRetval, rPnt, nTol, GetMarkedObjectList());
228 return pRetval;
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()))
247 return;
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 ) );
253 if ( !pFrmFmt )
255 ASSERT( false, "<SwDrawView::AddCustomHdl()> - missing frame format!" );
256 return;
258 const SwFmtAnchor &rAnchor = pFrmFmt->GetAnchor();
259 // <--
261 if(FLY_IN_CNTNT == rAnchor.GetAnchorId())
262 return;
264 const SwFrm* pAnch;
265 if(0 == (pAnch = CalcAnchor()))
266 return;
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 );
302 if ( pAnch )
304 //Das oberste Obj innerhalb des Ankers darf nicht ueberholt
305 //werden.
306 const SwFlyFrm *pFly = pAnch->FindFlyFrm();
307 if ( pFly )
309 const SwPageFrm *pPage = pFly->FindPageFrm();
310 if ( pPage->GetSortedObjs() )
312 UINT32 nOrdNum = 0;
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();
327 if ( nOrdNum )
329 SdrPage *pTmpPage = GetModel()->GetPage( 0 );
330 ++nOrdNum;
331 if ( nOrdNum < pTmpPage->GetObjCount() )
333 return pTmpPage->GetObj( nOrdNum );
340 return 0;
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 );
358 if ( pAnch )
360 //Der Fly des Ankers darf nicht "unterflogen" werden.
361 const SwFlyFrm *pFly = pAnch->FindFlyFrm();
362 if ( pFly )
364 SdrObject *pRet = (SdrObject*)pFly->GetVirtDrawObj();
365 return pRet != pObj ? pRet : 0;
369 return 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 ))
388 return TRUE;
391 return FALSE;
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();
399 return 0;
402 /** determine maximal order number for a 'child' object of given 'parent' object
404 OD 2004-08-20 #110810#
406 @author OD
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();
414 ASSERT( pDrawPage,
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 )
425 continue;
428 if ( pObj->GetOrdNum() > nMaxChildOrdNum &&
429 _rParentObj.IsAnLower( lcl_FindAnchor( pObj, TRUE ) ) )
431 nMaxChildOrdNum = pObj->GetOrdNum();
432 break;
436 return nMaxChildOrdNum;
439 /** method to move 'repeated' objects of the given moved object to the
440 according level
442 OD 2004-08-23 #110810#
444 @author OD
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() );
453 ASSERT( pContact,
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(),
471 nNewPos );
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 );
480 else
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 );
496 ASSERT( pContact,
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(),
508 nTmpNewPos );
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 );
517 else
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,
531 ULONG nNewPos )
533 // --> OD 2004-08-17 #110810# - nothing to do for group members
534 if ( pObj->GetUpGroup() )
536 return;
538 // <--
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 )
556 if ( bMovedForward )
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;
567 else
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 );
587 if ( pTmpObj )
589 sal_uInt32 nTmpNewPos( nNewPos );
590 if ( bMovedForward )
592 // move before the top 'repeated' object
593 const sal_uInt32 nTmpMaxOrdNum =
594 ::GetUserCall( pTmpObj )->GetMaxOrdNum();
595 if ( nTmpMaxOrdNum > nNewPos )
596 nTmpNewPos = nTmpMaxOrdNum;
598 else
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 )
629 --nTmpNewPos;
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 );
649 while ( pTmpObj )
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;
658 // <--
659 if ( pTmpParentObj &&
660 &(pTmpParentObj->GetFrmFmt()) != pParentFrmFmt )
662 if ( bMovedForward )
664 nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum();
665 pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 );
667 else
669 nTmpNewPos = ::GetUserCall( pTmpParentObj->GetDrawObj() )
670 ->GetMinOrdNum();
671 pTmpObj = pTmpParentObj->GetDrawObj();
674 else
675 break;
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 )
703 break;
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;
712 // <--
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 );
730 else
732 rImp.DisposeAccessibleObj( pTmpObj );
733 rImp.AddAccessibleObj( pTmpObj );
736 else
738 // adjust loop counter
739 if ( bMovedForward )
740 ++i;
741 else if ( !bMovedForward && i > 0 )
742 --i;
745 } while ( ( bMovedForward && i < ( nObjCount - aMovedChildObjs.size() ) ) ||
746 ( !bMovedForward && i > ( nNewPos + aMovedChildObjs.size() ) ) );
748 else
750 // adjustments for accessibility API
751 rImp.DisposeAccessibleObj( pObj );
752 rImp.AddAccessibleObj( pObj );
755 _MoveRepeatedObjs( *pMovedAnchoredObj, aMovedChildObjs );
757 // <--
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();
773 BOOL bRet = FALSE;
774 if( 1 == rMrkList.GetMarkCount() )
776 const SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
777 SwRect aRect;
778 if( ::CalcClipRect( pObj, aRect, eMode == SDRDRAG_MOVE ) )
780 rRect = aRect.SVRect();
781 bRet = TRUE;
784 return bRet;
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 )
801 return NULL;
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.
807 const SwFrm* pAnch;
808 Rectangle aMyRect;
809 const BOOL bFly = pObj->ISA(SwVirtFlyDrawObj);
810 if ( bFly )
812 pAnch = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetAnchorFrm();
813 aMyRect = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Frm().SVRect();
815 else
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 );
822 if( !pAnch )
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();
838 Point aPt;
839 if ( IsAction() )
841 if ( !TakeDragObjAnchorPos( aPt, bTopRight ) )
842 return NULL;
844 else
846 Rectangle aRect = pObj->GetSnapRect();
847 aPt = bTopRight ? aRect.TopRight() : aRect.TopLeft();
850 if ( aPt != aMyPt )
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 );
859 else if ( !bFly )
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();
867 else
868 pAnch = pContact->FindPage( aRect );
871 if( pAnch && !pAnch->IsProtected() )
872 aAnchorPoint = pAnch->GetFrmAnchorPos( ::HasWrap( pObj ) );
873 else
874 pAnch = 0;
875 return pAnch;
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);
891 if ( ! pHdl )
892 pHdl = aHdl.GetHdl(HDL_ANCHOR_TR);
894 if(pHdl)
896 CalcAnchor();
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();
918 // #i7672#
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();
928 Color aBackColor;
929 sal_Bool bColorWasSaved(sal_False);
931 if(pView)
933 aBackColor = pView->GetBackgroundColor();
934 bColorWasSaved = sal_True;
937 // call parent
938 FmFormView::ModelHasChanged();
940 if(bColorWasSaved)
942 pView = GetTextEditOutlinerView();
944 if(pView)
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
963 //Schutz fuehren.
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,
970 bSzProtect = 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();
978 if ( pFly )
980 pFrm = pFly->GetAnchorFrm();
981 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
983 SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode();
984 if ( pNd )
986 uno::Reference < embed::XEmbeddedObject > xObj = pNd->GetOLEObj().GetOleRef();
987 if ( xObj.is() )
989 // --> OD 2004-08-16 #110810# - improvement for
990 // the future, when more than one Writer fly frame
991 // can be selected.
993 // TODO/LATER: retrieve Aspect - from where?!
994 bSzProtect |= ( embed::EmbedMisc::EMBED_NEVERRESIZE & xObj->getStatus( embed::Aspects::MSOLE_CONTENT ) ) ? TRUE : FALSE;
996 // <--
1002 else
1004 SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj);
1005 if ( pC )
1006 pFrm = pC->GetAnchorFrm( pObj );
1008 if ( pFrm )
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 )
1013 // bProtect = TRUE;
1015 SwFrmFmt* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject*>(pObj) ) );
1016 if ( !pFrmFmt )
1018 ASSERT( false,
1019 "<SwDrawView::CheckPossibilities()> - missing frame format" );
1020 bProtect = TRUE;
1022 else if ( FLY_IN_CNTNT == pFrmFmt->GetAnchor().GetAnchorId() &&
1023 rMrkList.GetMarkCount() > 1 )
1025 bProtect = TRUE;
1028 // <--
1030 bMoveProtect |= bProtect;
1031 bResizeProtect |= bProtect | bSzProtect;
1034 /** replace marked <SwDrawVirtObj>-objects by its reference object for delete
1035 marked objects.
1037 OD 18.06.2003 #108784#
1039 @author OD
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 );
1070 else
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()) );
1095 if ( pMarkView )
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();
1111 /********
1112 JP 02.10.98: sollte als Fix fuer 57153 gelten, hatte aber Nebenwirkungen,
1113 wie Bug 57475
1114 const SdrMarkList& SwDrawView::GetMarkedObjectList() const
1116 FlushComeBackTimer();
1117 return FmFormView::GetMarkedObjectList();
1119 *************/