Update ooo320-m1
[ooovba.git] / sd / source / ui / animations / motionpathtag.cxx
blob5f5ca8f9495bfaee30af59fb3bb26ab97a579774
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: motionpathtag.cxx,v $
10 * $Revision: 1.3 $
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_sd.hxx"
35 #include <com/sun/star/util/XChangesNotifier.hpp>
37 #include <basegfx/matrix/b2dhommatrix.hxx>
38 #include <basegfx/polygon/b2dpolygontools.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <sfx2/dispatch.hxx>
43 #include <svx/sdr/overlay/overlaymanager.hxx>
44 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
45 #include <svx/svdpagv.hxx>
46 #include <svx/sdrpagewindow.hxx>
47 #include <svx/sdrpaintwindow.hxx>
48 #include <svx/svdopath.hxx>
49 #include <svx/xlndsit.hxx>
50 #include <svx/xlnclit.hxx>
51 #include <svx/xlnstit.hxx>
52 #include <svx/xlnedit.hxx>
53 #include <svx/xlnstwit.hxx>
54 #include <svx/xlnedwit.hxx>
55 #include <svx/xlnstcit.hxx>
56 #include <svx/xlnedcit.hxx>
57 #include <svx/xlntrit.hxx>
58 #include <svx/svxids.hrc>
59 #include <svx/polypolygoneditor.hxx>
60 #include <svx/svddrgmt.hxx>
62 #include "CustomAnimationPane.hxx"
63 #include "View.hxx"
64 #include "motionpathtag.hxx"
65 #include "sdpage.hxx"
66 #include "ViewShell.hxx"
67 #include "app.hrc"
68 #include "Window.hxx"
70 #include <svx/sdr/contact/viewcontact.hxx>
71 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
73 using ::rtl::OUString;
74 using ::sdr::PolyPolygonEditor;
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::lang;
77 using namespace ::com::sun::star::util;
78 using namespace ::com::sun::star::drawing;
80 namespace sd
83 const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32;
84 static const int DRGPIX = 2; // Drag MinMove in Pixel
86 // --------------------------------------------------------------------
88 class PathDragMove : public SdrDragMove
90 private:
91 basegfx::B2DPolyPolygon maPathPolyPolygon;
93 protected:
94 virtual void createSdrDragEntries();
96 public:
97 PathDragMove(SdrDragView& rNewView,
98 const rtl::Reference <MotionPathTag >& xTag,
99 const basegfx::B2DPolyPolygon& rPathPolyPolygon)
100 : SdrDragMove(rNewView),
101 maPathPolyPolygon(rPathPolyPolygon),
102 mxTag( xTag )
105 PathDragMove(SdrDragView& rNewView,
106 const rtl::Reference <MotionPathTag >& xTag)
107 : SdrDragMove(rNewView),
108 maPathPolyPolygon(),
109 mxTag( xTag )
112 virtual bool BeginSdrDrag();
113 virtual bool EndSdrDrag(bool bCopy);
115 rtl::Reference <MotionPathTag > mxTag;
118 void PathDragMove::createSdrDragEntries()
120 // call parent
121 SdrDragMove::createSdrDragEntries();
123 if(maPathPolyPolygon.count())
125 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
129 bool PathDragMove::BeginSdrDrag()
131 if( mxTag.is() )
133 SdrPathObj* pPathObj = mxTag->getPathObj();
134 if( pPathObj )
136 DragStat().SetActionRect(pPathObj->GetCurrentBoundRect());
139 Show();
140 return TRUE;
143 bool PathDragMove::EndSdrDrag(bool /*bCopy*/)
145 Hide();
146 if( mxTag.is() )
147 mxTag->MovePath( DragStat().GetDX(), DragStat().GetDY() );
148 return TRUE;
150 // --------------------------------------------------------------------
152 class PathDragResize : public SdrDragResize
154 private:
155 basegfx::B2DPolyPolygon maPathPolyPolygon;
157 protected:
158 virtual void createSdrDragEntries();
160 public:
161 PathDragResize(SdrDragView& rNewView,
162 const rtl::Reference <MotionPathTag >& xTag,
163 const basegfx::B2DPolyPolygon& rPathPolyPolygon)
164 : SdrDragResize(rNewView),
165 maPathPolyPolygon(rPathPolyPolygon),
166 mxTag( xTag )
169 PathDragResize(SdrDragView& rNewView,
170 const rtl::Reference <MotionPathTag >& xTag)
171 : SdrDragResize(rNewView),
172 maPathPolyPolygon(),
173 mxTag( xTag )
176 virtual bool EndSdrDrag(bool bCopy);
177 rtl::Reference <MotionPathTag > mxTag;
180 void PathDragResize::createSdrDragEntries()
182 // call parent
183 SdrDragResize::createSdrDragEntries();
185 if(maPathPolyPolygon.count())
187 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
191 bool PathDragResize::EndSdrDrag(bool /*bCopy*/)
193 Hide();
194 if( mxTag.is() )
196 SdrPathObj* pPathObj = mxTag->getPathObj();
197 if( pPathObj )
199 basegfx::B2DHomMatrix aTrans;
200 const Point aRef( DragStat().Ref1() );
201 aTrans.translate(-aRef.X(), -aRef.Y());
202 aTrans.scale(double(aXFact), double(aYFact));
203 aTrans.translate(aRef.X(), aRef.Y());
204 basegfx::B2DPolyPolygon aDragPoly(pPathObj->GetPathPoly());
205 aDragPoly.transform(aTrans);
206 pPathObj->SetPathPoly( aDragPoly );
209 return TRUE;
212 // --------------------------------------------------------------------
214 class PathDragObjOwn : public SdrDragObjOwn
216 private:
217 basegfx::B2DPolyPolygon maPathPolyPolygon;
219 protected:
220 virtual void createSdrDragEntries();
222 public:
223 PathDragObjOwn(SdrDragView& rNewView,
224 const basegfx::B2DPolyPolygon& rPathPolyPolygon)
225 : SdrDragObjOwn(rNewView),
226 maPathPolyPolygon(rPathPolyPolygon)
229 PathDragObjOwn(SdrDragView& rNewView)
230 : SdrDragObjOwn(rNewView),
231 maPathPolyPolygon()
234 virtual bool EndSdrDrag(bool bCopy);
237 void PathDragObjOwn::createSdrDragEntries()
239 // call parent
240 SdrDragObjOwn::createSdrDragEntries();
242 if(maPathPolyPolygon.count())
244 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
248 bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/)
250 Hide();
252 SdrObject* pObj = GetDragObj();
254 if(pObj)
256 return pObj->applySpecialDrag(DragStat());
258 else
260 return false;
264 // --------------------------------------------------------------------
266 class SdPathHdl : public SmartHdl
268 public:
269 SdPathHdl( const SmartTagReference& xTag, SdrPathObj* mpPathObj );
270 virtual ~SdPathHdl();
271 virtual void CreateB2dIAObject();
272 virtual BOOL IsFocusHdl() const;
273 virtual Pointer GetSdrDragPointer() const;
274 virtual bool isMarkable() const;
276 private:
277 SdrPathObj* mpPathObj;
278 rtl::Reference< MotionPathTag > mxTag;
281 // --------------------------------------------------------------------
283 SdPathHdl::SdPathHdl( const SmartTagReference& xTag, SdrPathObj* pPathObj )
284 : SmartHdl( xTag, pPathObj->GetCurrentBoundRect().TopLeft() )
285 , mpPathObj( pPathObj )
286 , mxTag( dynamic_cast< MotionPathTag* >( xTag.get() ) )
290 // --------------------------------------------------------------------
292 SdPathHdl::~SdPathHdl()
296 // --------------------------------------------------------------------
298 void SdPathHdl::CreateB2dIAObject()
300 // first throw away old one
301 GetRidOfIAObject();
303 if(pHdlList)
305 SdrMarkView* pView = pHdlList->GetView();
307 if(pView && !pView->areMarkHandlesHidden())
309 SdrPageView* pPageView = pView->GetSdrPageView();
311 if(pPageView)
313 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
315 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
317 if(rPageWindow.GetPaintWindow().OutputToWindow())
319 if(rPageWindow.GetOverlayManager() && mpPathObj)
321 const sdr::contact::ViewContact& rVC = mpPathObj->GetViewContact();
322 const drawinglayer::primitive2d::Primitive2DSequence aSequence = rVC.getViewIndependentPrimitive2DSequence();
323 sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence);
325 rPageWindow.GetOverlayManager()->add(*pNew);
326 maOverlayGroup.append(*pNew);
335 // --------------------------------------------------------------------
337 BOOL SdPathHdl::IsFocusHdl() const
339 return FALSE;
342 // --------------------------------------------------------------------
344 bool SdPathHdl::isMarkable() const
346 return false;
349 // --------------------------------------------------------------------
351 Pointer SdPathHdl::GetSdrDragPointer() const
353 PointerStyle eStyle = POINTER_NOTALLOWED;
354 if( mxTag.is() )
356 if( mxTag->isSelected() )
358 if( !mxTag->getView().IsFrameDragSingles() && mxTag->getView().IsInsObjPointMode() )
359 eStyle = POINTER_CROSS;
360 else
361 eStyle = POINTER_MOVE;
363 else
365 eStyle = POINTER_ARROW;
369 return Pointer( eStyle );
372 // ====================================================================
374 MotionPathTag::MotionPathTag( CustomAnimationPane& rPane, ::sd::View& rView, const CustomAnimationEffectPtr& pEffect )
375 : SmartTag( rView )
376 , mrPane( rPane )
377 , mpEffect( pEffect )
378 , mxOrigin( pEffect->getTargetShape() )
379 , msLastPath( pEffect->getPath() )
380 , mbInUpdatePath( false )
382 mpPathObj = mpEffect->createSdrPathObjFromPath();
383 mxPolyPoly = mpPathObj->GetPathPoly();
384 maOriginPos = mxOrigin->getPosition();
386 SdrPage* pPage = mrView.GetSdrPageView()->GetPage();
387 if( pPage )
389 mpPathObj->SetPage( pPage );
390 mpPathObj->SetObjList( pPage );
393 XDash aDash( XDASH_RECT, 1, 80, 1, 80, 80);
394 String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") );
395 mpPathObj->SetMergedItem( XLineDashItem( aEmpty, aDash ) );
396 mpPathObj->SetMergedItem( XLineStyleItem( XLINE_DASH ) );
397 mpPathObj->SetMergedItem( XLineColorItem(aEmpty, ::Color(COL_GRAY)) );
398 mpPathObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) );
400 ::basegfx::B2DPolygon aStartArrow;
401 aStartArrow.append(::basegfx::B2DPoint(20.0, 0.0));
402 aStartArrow.append(::basegfx::B2DPoint(0.0, 0.0));
403 aStartArrow.append(::basegfx::B2DPoint(10.0, 30.0));
404 aStartArrow.setClosed(true);
405 mpPathObj->SetMergedItem(XLineStartItem(aEmpty,::basegfx::B2DPolyPolygon(aStartArrow)));
406 mpPathObj->SetMergedItem(XLineStartWidthItem(400));
407 mpPathObj->SetMergedItem(XLineStartCenterItem(TRUE));
409 updatePathAttributes();
411 mpPathObj->SetMergedItem(XLineTransparenceItem(50));
413 mpMark = new SdrMark( mpPathObj, mrView.GetSdrPageView() );
415 mpPathObj->AddListener( *this );
417 Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY );
418 if( xNotifier.is() )
420 Reference< XChangesListener > xListener( this );
421 xNotifier->addChangesListener( this );
425 // --------------------------------------------------------------------
427 MotionPathTag::~MotionPathTag()
429 DBG_ASSERT( mpPathObj == 0, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" );
430 Dispose();
433 // --------------------------------------------------------------------
435 void MotionPathTag::updatePathAttributes()
437 String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") );
439 ::basegfx::B2DPolygon aCandidate;
440 if( mxPolyPoly.count() )
442 aCandidate = mxPolyPoly.getB2DPolygon(0);
443 ::basegfx::tools::checkClosed( aCandidate );
446 if( !aCandidate.isClosed() )
448 ::basegfx::B2DPolygon aEndArrow;
449 aEndArrow.append(::basegfx::B2DPoint(10.0, 0.0));
450 aEndArrow.append(::basegfx::B2DPoint(0.0, 30.0));
451 aEndArrow.append(::basegfx::B2DPoint(20.0, 30.0));
452 aEndArrow.setClosed(true);
453 mpPathObj->SetMergedItem(XLineEndItem(aEmpty,::basegfx::B2DPolyPolygon(aEndArrow)));
454 mpPathObj->SetMergedItem(XLineEndWidthItem(400));
455 mpPathObj->SetMergedItem(XLineEndCenterItem(TRUE));
457 else
459 mpPathObj->SetMergedItem(XLineEndItem());
463 // --------------------------------------------------------------------
465 void MotionPathTag::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
467 if( mpPathObj && !mbInUpdatePath && dynamic_cast< const SdrHint* >( &rHint ) && (mpEffect.get() != 0) )
469 if( mxPolyPoly != mpPathObj->GetPathPoly() )
471 mbInUpdatePath = true;
472 mxPolyPoly = mpPathObj->GetPathPoly();
473 rtl::Reference< MotionPathTag > xTag( this );
474 mrPane.updatePathFromMotionPathTag( xTag );
475 msLastPath = mpEffect->getPath();
476 updatePathAttributes();
477 mbInUpdatePath = false;
482 // --------------------------------------------------------------------
484 void MotionPathTag::MovePath( int nDX, int nDY )
486 if( mpPathObj )
488 mpPathObj->Move( Size( nDX, nDY ) );
489 mrView.updateHandles();
493 // --------------------------------------------------------------------
495 /** returns true if the MotionPathTag handled the event. */
496 bool MotionPathTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& rHdl )
498 if( !mpPathObj )
499 return false;
501 if( !isSelected() )
503 SmartTagReference xTag( this );
504 mrView.getSmartTags().select( xTag );
505 selectionChanged();
506 return true;
508 else
510 if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) )
512 mrView.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT, SFX_CALLMODE_ASYNCHRON);
513 return true;
515 else if( rMEvt.IsLeft() )
517 OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow();
518 Point aMDPos( pOut->PixelToLogic( rMEvt.GetPosPixel() ) );
520 if( !mrView.IsFrameDragSingles() && mrView.IsInsObjPointMode() && (rHdl.GetObjHdlNum() == SMART_TAG_HDL_NUM) )
522 // insert a point in edit mode
523 const bool bNewObj = rMEvt.IsMod1();
525 mrView.BrkAction();
527 Point aPt(aMDPos); // - pMarkedPV->GetOffset());
529 if(bNewObj)
530 aPt = mrView.GetSnapPos(aPt,mrView.GetSdrPageView());
532 sal_Bool bClosed0(mpPathObj->IsClosedObj());
534 sal_uInt32 nInsPointNum = mpPathObj->NbcInsPointOld(aPt, bNewObj, sal_True);
536 if(bClosed0 != mpPathObj->IsClosedObj())
538 // Obj was closed implicit
539 // object changed
540 mpPathObj->SetChanged();
541 mpPathObj->BroadcastObjectChange();
544 if(0xffffffff != nInsPointNum)
546 mrView.UnmarkAllPoints();
547 mrView.updateHandles();
549 bool bRet = mrView.BegDragObj(aMDPos, pOut, mrView.GetHdl(nInsPointNum+1), 0, new PathDragObjOwn( mrView ) );
551 if (bRet)
553 const_cast< SdrDragStat* >( &mrView.GetDragStat() )->SetMinMoved();
554 mrView.MovDragObj(aMDPos);
557 return true;
559 else
561 SmartHdl* pHdl = &rHdl;
562 if (!mrView.IsPointMarked(*pHdl) || rMEvt.IsShift())
564 if (!rMEvt.IsShift())
566 mrView.UnmarkAllPoints();
567 pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) );
569 else
571 if (mrView.IsPointMarked(*pHdl) )
573 mrView.UnmarkPoint(*pHdl);
574 pHdl = NULL;
576 else
578 pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) );
582 if (pHdl)
583 mrView.MarkPoint(*pHdl);
587 if( pHdl && !rMEvt.IsRight() )
589 mrView.BrkAction();
590 const USHORT nDrgLog = (USHORT)pOut->PixelToLogic(Size(DRGPIX,0)).Width();
592 rtl::Reference< MotionPathTag > xTag( this );
593 SdrDragMethod* pDragMethod;
595 // #i95646# add DragPoly as geometry to each local SdrDragMethod to be able
596 // to create the needed local SdrDragEntry for it in createSdrDragEntries()
597 const basegfx::B2DPolyPolygon aDragPoly(mpPathObj->GetPathPoly());
599 if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) )
601 pDragMethod = new PathDragMove( mrView, xTag, aDragPoly );
602 pHdl->SetPos( aMDPos );
604 else if( pHdl->GetKind() == HDL_POLY )
606 pDragMethod = new PathDragObjOwn( mrView, aDragPoly );
608 else
610 pDragMethod = new PathDragResize( mrView, xTag, aDragPoly );
613 mrView.BegDragObj(aMDPos, NULL, pHdl, nDrgLog, pDragMethod );
615 return true;
620 return false;
623 // --------------------------------------------------------------------
625 /** returns true if the SmartTag consumes this event. */
626 bool MotionPathTag::KeyInput( const KeyEvent& rKEvt )
628 if( !mpPathObj )
629 return false;
631 USHORT nCode = rKEvt.GetKeyCode().GetCode();
632 switch( nCode )
634 case KEY_DELETE:
635 return OnDelete();
637 case KEY_DOWN:
638 case KEY_UP:
639 case KEY_LEFT:
640 case KEY_RIGHT:
641 return OnMove( rKEvt );
643 case KEY_ESCAPE:
645 SmartTagReference xThis( this );
646 mrView.getSmartTags().deselect();
647 return true;
650 case KEY_TAB:
651 return OnTabHandles( rKEvt );
653 case KEY_SPACE:
654 return OnMarkHandle( rKEvt );
656 default:
657 break;
659 return false;
662 bool MotionPathTag::OnDelete()
664 mrPane.remove( mpEffect );
665 return true;
668 bool MotionPathTag::OnTabHandles( const KeyEvent& rKEvt )
670 if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
672 const SdrHdlList& rHdlList = mrView.GetHdlList();
673 sal_Bool bForward(!rKEvt.GetKeyCode().IsShift());
675 ((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);
677 // guarantee visibility of focused handle
678 SdrHdl* pHdl = rHdlList.GetFocusHdl();
680 if(pHdl)
682 Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
683 if( pWindow )
685 Point aHdlPosition(pHdl->GetPos());
686 Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
687 mrView.MakeVisible(aVisRect, *pWindow);
691 return true;
694 return false;
697 bool MotionPathTag::OnMarkHandle( const KeyEvent& rKEvt )
699 const SdrHdlList& rHdlList = mrView.GetHdlList();
700 SdrHdl* pHdl = rHdlList.GetFocusHdl();
702 if(pHdl && pHdl->GetKind() == HDL_POLY )
704 // rescue ID of point with focus
705 sal_uInt32 nPol(pHdl->GetPolyNum());
706 sal_uInt32 nPnt(pHdl->GetPointNum());
708 if(mrView.IsPointMarked(*pHdl))
710 if(rKEvt.GetKeyCode().IsShift())
712 mrView.UnmarkPoint(*pHdl);
715 else
717 if(!rKEvt.GetKeyCode().IsShift())
719 mrView.UnmarkAllPoints();
721 mrView.MarkPoint(*pHdl);
724 if(0L == rHdlList.GetFocusHdl())
726 // restore point with focus
727 SdrHdl* pNewOne = 0L;
729 for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++)
731 SdrHdl* pAct = rHdlList.GetHdl(a);
733 if(pAct && pAct->GetKind() == HDL_POLY && pAct->GetPolyNum() == nPol && pAct->GetPointNum() == nPnt)
734 pNewOne = pAct;
737 if(pNewOne)
738 ((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
742 return true;
745 bool MotionPathTag::OnMove( const KeyEvent& rKEvt )
747 long nX = 0;
748 long nY = 0;
750 switch( rKEvt.GetKeyCode().GetCode() )
752 case KEY_UP: nY = -1; break;
753 case KEY_DOWN: nY = 1; break;
754 case KEY_LEFT: nX = -1; break;
755 case KEY_RIGHT: nX = 1; break;
756 default: break;
759 if(rKEvt.GetKeyCode().IsMod2())
761 OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow();
762 Size aLogicSizeOnePixel = (pOut) ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100);
763 nX *= aLogicSizeOnePixel.Width();
764 nY *= aLogicSizeOnePixel.Height();
766 else
768 // old, fixed move distance
769 nX *= 100;
770 nY *= 100;
773 if( nX || nY )
775 // in point edit mode move the handle with the focus
776 const SdrHdlList& rHdlList = mrView.GetHdlList();
777 SdrHdl* pHdl = rHdlList.GetFocusHdl();
779 if(pHdl)
781 // now move the Handle (nX, nY)
782 Point aStartPoint(pHdl->GetPos());
783 Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
785 // start dragging
786 rtl::Reference< MotionPathTag > xTag( this );
787 SdrDragMethod* pDragMethod = 0;
788 if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) )
790 pDragMethod = new PathDragMove( mrView, xTag );
792 else if( pHdl->GetKind() == HDL_POLY )
794 pDragMethod = new PathDragObjOwn( mrView );
796 else if( pHdl->GetKind() != HDL_BWGT )
798 pDragMethod = new PathDragResize( mrView, xTag );
800 mrView.BegDragObj(aStartPoint, 0, pHdl, 0, pDragMethod);
802 if(mrView.IsDragObj())
804 FASTBOOL bWasNoSnap = mrView.GetDragStat().IsNoSnap();
805 BOOL bWasSnapEnabled = mrView.IsSnapEnabled();
807 // switch snapping off
808 if(!bWasNoSnap)
809 ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(TRUE);
810 if(bWasSnapEnabled)
811 mrView.SetSnapEnabled(FALSE);
813 mrView.MovAction(aEndPoint);
814 mrView.EndDragObj();
816 // restore snap
817 if(!bWasNoSnap)
818 ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(bWasNoSnap);
819 if(bWasSnapEnabled)
820 mrView.SetSnapEnabled(bWasSnapEnabled);
823 else
825 // move the path
826 MovePath( nX, nY );
830 return true;
833 // --------------------------------------------------------------------
835 ULONG MotionPathTag::GetMarkablePointCount() const
837 if( mpPathObj && isSelected() )
839 return mpPathObj->GetPointCount();
841 else
843 return 0;
847 // --------------------------------------------------------------------
849 ULONG MotionPathTag::GetMarkedPointCount() const
851 if( mpMark )
853 const SdrUShortCont* pPts=mpMark->GetMarkedPoints();
854 return pPts ? pPts->GetCount() : 0;
856 else
858 return 0;
862 // --------------------------------------------------------------------
864 BOOL MotionPathTag::MarkPoint(SdrHdl& rHdl, BOOL bUnmark )
866 BOOL bRet=FALSE;
867 if( mpPathObj && mrView.IsPointMarkable( rHdl ) && (rHdl.GetKind() != HDL_SMARTTAG) )
869 SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( &rHdl );
870 if( pSmartHdl && pSmartHdl->getTag().get() == this )
872 SdrUShortCont* pPts=mpMark->ForceMarkedPoints();
873 pPts->ForceSort();
874 if (mrView.MarkPointHelper(&rHdl,mpMark,bUnmark))
876 pPts->ForceSort();
877 mrView.MarkListHasChanged();
878 bRet=TRUE;
882 return bRet;
885 // --------------------------------------------------------------------
887 BOOL MotionPathTag::MarkPoints(const Rectangle* pRect, BOOL bUnmark )
889 BOOL bChgd=FALSE;
891 if( mpPathObj && isSelected() )
893 sal_Int32 nHdlNum = mrView.GetHdlList().GetHdlCount() - 1;
894 while( nHdlNum > 0 )
896 SmartHdl* pHdl = dynamic_cast< SmartHdl* >( mrView.GetHdl( sal::static_int_cast< ULONG >( nHdlNum-- ) ) );
898 if( pHdl && (pHdl->getTag().get() == this) && mrView.IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark)
900 Point aPos(pHdl->GetPos());
901 if( pRect==NULL || pRect->IsInside(aPos))
903 if( mrView.MarkPointHelper(pHdl,mpMark,bUnmark) )
904 bChgd=TRUE;
909 if(bChgd)
910 mrView.MarkListHasChanged();
913 return bChgd;
916 // --------------------------------------------------------------------
918 bool MotionPathTag::getContext( SdrViewContext& rContext )
920 if( mpPathObj && isSelected() && !mrView.IsFrameDragSingles() )
922 rContext = SDRCONTEXT_POINTEDIT;
923 return true;
925 else
927 return false;
931 // --------------------------------------------------------------------
933 void MotionPathTag::CheckPossibilities()
935 if( mpPathObj )
937 if( isSelected() )
939 mrView.SetMoveAllowed( true );
940 mrView.SetMoveProtected( false );
941 mrView.SetResizeFreeAllowed( true );
942 mrView.SetResizePropAllowed( true );
943 mrView.SetResizeProtected( false );
945 if( !mrView.IsFrameDragSingles() )
947 bool b1stSmooth(true);
948 bool b1stSegm(true);
949 bool bCurve(false);
950 bool bSmoothFuz(false);
951 bool bSegmFuz(false);
952 basegfx::B2VectorContinuity eSmooth = basegfx::CONTINUITY_NONE;
954 mrView.CheckPolyPossibilitiesHelper( mpMark, b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth );
960 // --------------------------------------------------------------------
962 void MotionPathTag::addCustomHandles( SdrHdlList& rHandlerList )
964 if( mpPathObj )
966 ::com::sun::star::awt::Point aPos( mxOrigin->getPosition() );
967 if( (aPos.X != maOriginPos.X) || (aPos.Y != maOriginPos.Y) )
969 ::basegfx::B2DHomMatrix aTransform;
970 aTransform.translate( aPos.X - maOriginPos.X, aPos.Y - maOriginPos.Y );
971 mxPolyPoly.transform( aTransform );
972 mpPathObj->SetPathPoly( mxPolyPoly );
973 maOriginPos = aPos;
976 SmartTagReference xThis( this );
977 SdPathHdl* pHdl = new SdPathHdl( xThis, mpPathObj );
978 pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM );
979 pHdl->SetPageView( mrView.GetSdrPageView() );
982 pHdl->SetObj(mpPathObj);
983 rHandlerList.AddHdl( pHdl );
985 if( isSelected() )
987 mrView.GetSdrPageView()->SetHasMarkedObj(TRUE);
989 if( !mrView.IsFrameDragSingles() )
991 SdrHdlList aTemp( rHandlerList.GetView() );
992 mpPathObj->AddToHdlList( aTemp );
993 const SdrUShortCont* pMrkPnts=mpMark->GetMarkedPoints();
995 sal_uInt32 nHandle;
996 for( nHandle = 0; nHandle < aTemp.GetHdlCount(); ++nHandle )
998 SdrHdl* pTempHdl = aTemp.GetHdl( nHandle );
1000 SmartHdl* pSmartHdl = new SmartHdl( xThis, mpPathObj, pTempHdl->GetPos(), pTempHdl->GetKind() );
1001 pSmartHdl->SetObjHdlNum( nHandle );
1002 pSmartHdl->SetPolyNum( pTempHdl->GetPolyNum() );
1003 pSmartHdl->SetPointNum( pTempHdl->GetPointNum() );
1004 pSmartHdl->SetPlusHdl( pTempHdl->IsPlusHdl() );
1005 pSmartHdl->SetSourceHdlNum( pTempHdl->GetSourceHdlNum() );
1006 pSmartHdl->SetPageView( mrView.GetSdrPageView() );
1008 rHandlerList.AddHdl( pSmartHdl );
1010 const bool bSelected= pMrkPnts && pMrkPnts->Exist(sal::static_int_cast< USHORT >(nHandle));
1011 pSmartHdl->SetSelected(bSelected);
1013 if( mrView.IsPlusHandlesAlwaysVisible() || bSelected )
1015 sal_uInt32 nPlusAnz=mpPathObj->GetPlusHdlCount(*pSmartHdl);
1016 for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
1018 SdrHdl* pPlusHdl = mpPathObj->GetPlusHdl(*pSmartHdl,nPlusNum);
1019 if (pPlusHdl!=NULL)
1021 pPlusHdl->SetObj(mpPathObj);
1022 pPlusHdl->SetPageView(mrView.GetSdrPageView());
1023 pPlusHdl->SetPlusHdl(TRUE);
1024 rHandlerList.AddHdl(pPlusHdl);
1030 else
1032 Rectangle aRect(mpPathObj->GetCurrentBoundRect());
1034 if(!aRect.IsEmpty())
1036 ULONG nCount = rHandlerList.GetHdlCount();
1038 BOOL bWdt0=aRect.Left()==aRect.Right();
1039 BOOL bHgt0=aRect.Top()==aRect.Bottom();
1040 if (bWdt0 && bHgt0)
1042 rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft(),HDL_UPLFT));
1044 else if (bWdt0 || bHgt0)
1046 rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft() ,HDL_UPLFT));
1047 rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight(),HDL_LWRGT));
1049 else
1051 if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft() ,HDL_UPLFT));
1052 if ( !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopCenter() ,HDL_UPPER));
1053 if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopRight() ,HDL_UPRGT));
1054 if (!bWdt0 ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.LeftCenter() ,HDL_LEFT ));
1055 if (!bWdt0 ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.RightCenter() ,HDL_RIGHT));
1056 if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomLeft() ,HDL_LWLFT));
1057 if ( !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomCenter(),HDL_LOWER));
1058 if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight() ,HDL_LWRGT));
1061 while( nCount < rHandlerList.GetHdlCount() )
1063 rHandlerList.GetHdl(nCount++)->SetPageView( mrView.GetSdrPageView() );
1071 // --------------------------------------------------------------------
1073 void MotionPathTag::disposing()
1075 Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY );
1076 if( xNotifier.is() )
1078 Reference< XChangesListener > xListener( this );
1079 xNotifier->removeChangesListener( this );
1082 if( mpPathObj )
1084 SdrPathObj* pPathObj = mpPathObj;
1085 mpPathObj = 0;
1086 mrView.updateHandles();
1087 delete pPathObj;
1090 if( mpMark )
1092 delete mpMark;
1093 mpMark = 0;
1096 SmartTag::disposing();
1099 // --------------------------------------------------------------------
1101 void MotionPathTag::deselect()
1103 SmartTag::deselect();
1105 if( mpMark )
1107 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1109 if( pPts )
1110 pPts->Clear();
1113 selectionChanged();
1116 void MotionPathTag::selectionChanged()
1118 if( mrView.GetViewShell() && mrView.GetViewShell()->GetViewFrame() )
1120 SfxBindings& rBindings = mrView.GetViewShell()->GetViewFrame()->GetBindings();
1121 rBindings.InvalidateAll(TRUE);
1124 // --------------------------------------------------------------------
1125 // IPolyPolygonEditorController
1126 // --------------------------------------------------------------------
1128 void MotionPathTag::DeleteMarkedPoints()
1130 if( mpPathObj && IsDeleteMarkedPointsPossible() )
1132 mrView.BrkAction();
1134 // Description
1135 // BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_DELETE);
1137 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1139 if( pPts )
1141 PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() );
1142 if( aEditor.DeletePoints( pPts->getContainer() ) )
1144 if( aEditor.GetPolyPolygon().count() )
1146 // AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath ));
1147 mpPathObj->SetPathPoly( aEditor.GetPolyPolygon() );
1149 else
1151 // AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pPath ) );
1152 // pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum());
1155 mrView.UnmarkAllPoints();
1156 mrView.MarkListHasChanged();
1157 mrView.updateHandles();
1161 // EndUndo();
1165 BOOL MotionPathTag::IsDeleteMarkedPointsPossible() const
1167 return mpPathObj && isSelected() && (GetMarkedPointCount() != 0);
1170 void MotionPathTag::RipUpAtMarkedPoints()
1172 // not supported for motion path
1175 bool MotionPathTag::IsRipUpAtMarkedPointsPossible() const
1177 // not supported for motion path
1178 return false;
1181 BOOL MotionPathTag::IsSetMarkedSegmentsKindPossible() const
1183 if( mpPathObj )
1184 return mrView.IsSetMarkedSegmentsKindPossible();
1185 else
1186 return FALSE;
1189 SdrPathSegmentKind MotionPathTag::GetMarkedSegmentsKind() const
1191 if( mpPathObj )
1192 return mrView.GetMarkedSegmentsKind();
1193 else
1194 return SDRPATHSEGMENT_LINE;
1197 void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind)
1199 if(mpPathObj && isSelected() && (GetMarkedPointCount() != 0))
1201 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1202 if(pPts)
1204 PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() );
1205 if(aEditor.SetSegmentsKind( eKind, pPts->getContainer()) )
1207 // AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
1208 mpPathObj->SetPathPoly(aEditor.GetPolyPolygon());
1209 mrView.MarkListHasChanged();
1210 mrView.updateHandles();
1216 BOOL MotionPathTag::IsSetMarkedPointsSmoothPossible() const
1218 if( mpPathObj )
1219 return mrView.IsSetMarkedPointsSmoothPossible();
1220 else
1221 return FALSE;
1224 SdrPathSmoothKind MotionPathTag::GetMarkedPointsSmooth() const
1226 if( mpPathObj )
1227 return mrView.GetMarkedPointsSmooth();
1228 else
1229 return SDRPATHSMOOTH_ANGULAR;
1232 void MotionPathTag::SetMarkedPointsSmooth(SdrPathSmoothKind eKind)
1234 basegfx::B2VectorContinuity eFlags;
1236 if(SDRPATHSMOOTH_ANGULAR == eKind)
1238 eFlags = basegfx::CONTINUITY_NONE;
1240 else if(SDRPATHSMOOTH_ASYMMETRIC == eKind)
1242 eFlags = basegfx::CONTINUITY_C1;
1244 else if(SDRPATHSMOOTH_SYMMETRIC == eKind)
1246 eFlags = basegfx::CONTINUITY_C2;
1248 else
1250 return;
1253 if(mpPathObj && mpMark && isSelected() && (GetMarkedPointCount() != 0))
1255 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1256 if(pPts)
1258 PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() );
1259 if(aEditor.SetPointsSmooth( eFlags, pPts->getContainer() ) )
1261 // AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
1262 mpPathObj->SetPathPoly(aEditor.GetPolyPolygon());
1263 mrView.MarkListHasChanged();
1264 mrView.updateHandles();
1270 void MotionPathTag::CloseMarkedObjects(BOOL /*bToggle*/, BOOL /*bOpen*/ )
1272 // not supported for motion path
1275 bool MotionPathTag::IsOpenCloseMarkedObjectsPossible() const
1277 // not supported for motion path
1278 return false;
1281 SdrObjClosedKind MotionPathTag::GetMarkedObjectsClosedState() const
1283 // not supported for motion path
1284 return SDROBJCLOSED_OPEN;
1287 // XChangesListener
1288 void SAL_CALL MotionPathTag::changesOccurred( const ChangesEvent& /*Event*/ ) throw (RuntimeException)
1290 if( mpPathObj && !mbInUpdatePath && (mpEffect->getPath() != msLastPath) )
1292 mbInUpdatePath =true;
1293 msLastPath = mpEffect->getPath();
1294 mpEffect->updateSdrPathObjFromPath( *mpPathObj );
1295 mbInUpdatePath = false;
1296 updatePathAttributes();
1297 mrView.updateHandles();
1301 void SAL_CALL MotionPathTag::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
1303 if( mpPathObj )
1304 Dispose();
1307 Any SAL_CALL MotionPathTag::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (RuntimeException)
1309 if( aType == XChangesListener::static_type() )
1310 return Any( Reference< XChangesListener >( this ) );
1311 if( aType == XEventListener::static_type() )
1312 return Any( Reference< XEventListener >( this ) );
1313 if( aType == XInterface::static_type() )
1314 return Any( Reference< XInterface >( this ) );
1316 return Any();
1319 void SAL_CALL MotionPathTag::acquire() throw ()
1321 SimpleReferenceComponent::acquire();
1324 void SAL_CALL MotionPathTag::release( ) throw ()
1326 SimpleReferenceComponent::release();
1329 } // end of namespace sd