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: motionpathtag.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_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"
64 #include "motionpathtag.hxx"
66 #include "ViewShell.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
;
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
91 basegfx::B2DPolyPolygon maPathPolyPolygon
;
94 virtual void createSdrDragEntries();
97 PathDragMove(SdrDragView
& rNewView
,
98 const rtl::Reference
<MotionPathTag
>& xTag
,
99 const basegfx::B2DPolyPolygon
& rPathPolyPolygon
)
100 : SdrDragMove(rNewView
),
101 maPathPolyPolygon(rPathPolyPolygon
),
105 PathDragMove(SdrDragView
& rNewView
,
106 const rtl::Reference
<MotionPathTag
>& xTag
)
107 : SdrDragMove(rNewView
),
112 virtual bool BeginSdrDrag();
113 virtual bool EndSdrDrag(bool bCopy
);
115 rtl::Reference
<MotionPathTag
> mxTag
;
118 void PathDragMove::createSdrDragEntries()
121 SdrDragMove::createSdrDragEntries();
123 if(maPathPolyPolygon
.count())
125 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon
));
129 bool PathDragMove::BeginSdrDrag()
133 SdrPathObj
* pPathObj
= mxTag
->getPathObj();
136 DragStat().SetActionRect(pPathObj
->GetCurrentBoundRect());
143 bool PathDragMove::EndSdrDrag(bool /*bCopy*/)
147 mxTag
->MovePath( DragStat().GetDX(), DragStat().GetDY() );
150 // --------------------------------------------------------------------
152 class PathDragResize
: public SdrDragResize
155 basegfx::B2DPolyPolygon maPathPolyPolygon
;
158 virtual void createSdrDragEntries();
161 PathDragResize(SdrDragView
& rNewView
,
162 const rtl::Reference
<MotionPathTag
>& xTag
,
163 const basegfx::B2DPolyPolygon
& rPathPolyPolygon
)
164 : SdrDragResize(rNewView
),
165 maPathPolyPolygon(rPathPolyPolygon
),
169 PathDragResize(SdrDragView
& rNewView
,
170 const rtl::Reference
<MotionPathTag
>& xTag
)
171 : SdrDragResize(rNewView
),
176 virtual bool EndSdrDrag(bool bCopy
);
177 rtl::Reference
<MotionPathTag
> mxTag
;
180 void PathDragResize::createSdrDragEntries()
183 SdrDragResize::createSdrDragEntries();
185 if(maPathPolyPolygon
.count())
187 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon
));
191 bool PathDragResize::EndSdrDrag(bool /*bCopy*/)
196 SdrPathObj
* pPathObj
= mxTag
->getPathObj();
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
);
212 // --------------------------------------------------------------------
214 class PathDragObjOwn
: public SdrDragObjOwn
217 basegfx::B2DPolyPolygon maPathPolyPolygon
;
220 virtual void createSdrDragEntries();
223 PathDragObjOwn(SdrDragView
& rNewView
,
224 const basegfx::B2DPolyPolygon
& rPathPolyPolygon
)
225 : SdrDragObjOwn(rNewView
),
226 maPathPolyPolygon(rPathPolyPolygon
)
229 PathDragObjOwn(SdrDragView
& rNewView
)
230 : SdrDragObjOwn(rNewView
),
234 virtual bool EndSdrDrag(bool bCopy
);
237 void PathDragObjOwn::createSdrDragEntries()
240 SdrDragObjOwn::createSdrDragEntries();
242 if(maPathPolyPolygon
.count())
244 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon
));
248 bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/)
252 SdrObject
* pObj
= GetDragObj();
256 return pObj
->applySpecialDrag(DragStat());
264 // --------------------------------------------------------------------
266 class SdPathHdl
: public SmartHdl
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;
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
305 SdrMarkView
* pView
= pHdlList
->GetView();
307 if(pView
&& !pView
->areMarkHandlesHidden())
309 SdrPageView
* pPageView
= pView
->GetSdrPageView();
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
342 // --------------------------------------------------------------------
344 bool SdPathHdl::isMarkable() const
349 // --------------------------------------------------------------------
351 Pointer
SdPathHdl::GetSdrDragPointer() const
353 PointerStyle eStyle
= POINTER_NOTALLOWED
;
356 if( mxTag
->isSelected() )
358 if( !mxTag
->getView().IsFrameDragSingles() && mxTag
->getView().IsInsObjPointMode() )
359 eStyle
= POINTER_CROSS
;
361 eStyle
= POINTER_MOVE
;
365 eStyle
= POINTER_ARROW
;
369 return Pointer( eStyle
);
372 // ====================================================================
374 MotionPathTag::MotionPathTag( CustomAnimationPane
& rPane
, ::sd::View
& rView
, const CustomAnimationEffectPtr
& pEffect
)
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();
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
);
420 Reference
< XChangesListener
> xListener( this );
421 xNotifier
->addChangesListener( this );
425 // --------------------------------------------------------------------
427 MotionPathTag::~MotionPathTag()
429 DBG_ASSERT( mpPathObj
== 0, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" );
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
));
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
)
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
)
503 SmartTagReference
xTag( this );
504 mrView
.getSmartTags().select( xTag
);
510 if( rMEvt
.IsLeft() && (rMEvt
.GetClicks() == 2) )
512 mrView
.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT
, SFX_CALLMODE_ASYNCHRON
);
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();
527 Point
aPt(aMDPos
); // - pMarkedPV->GetOffset());
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
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
) );
553 const_cast< SdrDragStat
* >( &mrView
.GetDragStat() )->SetMinMoved();
554 mrView
.MovDragObj(aMDPos
);
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
) );
571 if (mrView
.IsPointMarked(*pHdl
) )
573 mrView
.UnmarkPoint(*pHdl
);
578 pHdl
= dynamic_cast< SmartHdl
* >( mrView
.PickHandle(aMDPos
) );
583 mrView
.MarkPoint(*pHdl
);
587 if( pHdl
&& !rMEvt
.IsRight() )
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
);
610 pDragMethod
= new PathDragResize( mrView
, xTag
, aDragPoly
);
613 mrView
.BegDragObj(aMDPos
, NULL
, pHdl
, nDrgLog
, pDragMethod
);
623 // --------------------------------------------------------------------
625 /** returns true if the SmartTag consumes this event. */
626 bool MotionPathTag::KeyInput( const KeyEvent
& rKEvt
)
631 USHORT nCode
= rKEvt
.GetKeyCode().GetCode();
641 return OnMove( rKEvt
);
645 SmartTagReference
xThis( this );
646 mrView
.getSmartTags().deselect();
651 return OnTabHandles( rKEvt
);
654 return OnMarkHandle( rKEvt
);
662 bool MotionPathTag::OnDelete()
664 mrPane
.remove( mpEffect
);
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();
682 Window
* pWindow
= mrView
.GetViewShell()->GetActiveWindow();
685 Point
aHdlPosition(pHdl
->GetPos());
686 Rectangle
aVisRect(aHdlPosition
- Point(100, 100), Size(200, 200));
687 mrView
.MakeVisible(aVisRect
, *pWindow
);
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
);
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
)
738 ((SdrHdlList
&)rHdlList
).SetFocusHdl(pNewOne
);
745 bool MotionPathTag::OnMove( const KeyEvent
& rKEvt
)
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;
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();
768 // old, fixed move distance
775 // in point edit mode move the handle with the focus
776 const SdrHdlList
& rHdlList
= mrView
.GetHdlList();
777 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
781 // now move the Handle (nX, nY)
782 Point
aStartPoint(pHdl
->GetPos());
783 Point
aEndPoint(pHdl
->GetPos() + Point(nX
, nY
));
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
809 ((SdrDragStat
&)mrView
.GetDragStat()).SetNoSnap(TRUE
);
811 mrView
.SetSnapEnabled(FALSE
);
813 mrView
.MovAction(aEndPoint
);
818 ((SdrDragStat
&)mrView
.GetDragStat()).SetNoSnap(bWasNoSnap
);
820 mrView
.SetSnapEnabled(bWasSnapEnabled
);
833 // --------------------------------------------------------------------
835 ULONG
MotionPathTag::GetMarkablePointCount() const
837 if( mpPathObj
&& isSelected() )
839 return mpPathObj
->GetPointCount();
847 // --------------------------------------------------------------------
849 ULONG
MotionPathTag::GetMarkedPointCount() const
853 const SdrUShortCont
* pPts
=mpMark
->GetMarkedPoints();
854 return pPts
? pPts
->GetCount() : 0;
862 // --------------------------------------------------------------------
864 BOOL
MotionPathTag::MarkPoint(SdrHdl
& rHdl
, BOOL bUnmark
)
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();
874 if (mrView
.MarkPointHelper(&rHdl
,mpMark
,bUnmark
))
877 mrView
.MarkListHasChanged();
885 // --------------------------------------------------------------------
887 BOOL
MotionPathTag::MarkPoints(const Rectangle
* pRect
, BOOL bUnmark
)
891 if( mpPathObj
&& isSelected() )
893 sal_Int32 nHdlNum
= mrView
.GetHdlList().GetHdlCount() - 1;
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
) )
910 mrView
.MarkListHasChanged();
916 // --------------------------------------------------------------------
918 bool MotionPathTag::getContext( SdrViewContext
& rContext
)
920 if( mpPathObj
&& isSelected() && !mrView
.IsFrameDragSingles() )
922 rContext
= SDRCONTEXT_POINTEDIT
;
931 // --------------------------------------------------------------------
933 void MotionPathTag::CheckPossibilities()
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);
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
)
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
);
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
);
987 mrView
.GetSdrPageView()->SetHasMarkedObj(TRUE
);
989 if( !mrView
.IsFrameDragSingles() )
991 SdrHdlList
aTemp( rHandlerList
.GetView() );
992 mpPathObj
->AddToHdlList( aTemp
);
993 const SdrUShortCont
* pMrkPnts
=mpMark
->GetMarkedPoints();
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
);
1021 pPlusHdl
->SetObj(mpPathObj
);
1022 pPlusHdl
->SetPageView(mrView
.GetSdrPageView());
1023 pPlusHdl
->SetPlusHdl(TRUE
);
1024 rHandlerList
.AddHdl(pPlusHdl
);
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();
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
));
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 );
1084 SdrPathObj
* pPathObj
= mpPathObj
;
1086 mrView
.updateHandles();
1096 SmartTag::disposing();
1099 // --------------------------------------------------------------------
1101 void MotionPathTag::deselect()
1103 SmartTag::deselect();
1107 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
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() )
1135 // BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_DELETE);
1137 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
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() );
1151 // AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pPath ) );
1152 // pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum());
1155 mrView
.UnmarkAllPoints();
1156 mrView
.MarkListHasChanged();
1157 mrView
.updateHandles();
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
1181 BOOL
MotionPathTag::IsSetMarkedSegmentsKindPossible() const
1184 return mrView
.IsSetMarkedSegmentsKindPossible();
1189 SdrPathSegmentKind
MotionPathTag::GetMarkedSegmentsKind() const
1192 return mrView
.GetMarkedSegmentsKind();
1194 return SDRPATHSEGMENT_LINE
;
1197 void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind
)
1199 if(mpPathObj
&& isSelected() && (GetMarkedPointCount() != 0))
1201 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
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
1219 return mrView
.IsSetMarkedPointsSmoothPossible();
1224 SdrPathSmoothKind
MotionPathTag::GetMarkedPointsSmooth() const
1227 return mrView
.GetMarkedPointsSmooth();
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
;
1253 if(mpPathObj
&& mpMark
&& isSelected() && (GetMarkedPointCount() != 0))
1255 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
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
1281 SdrObjClosedKind
MotionPathTag::GetMarkedObjectsClosedState() const
1283 // not supported for motion path
1284 return SDROBJCLOSED_OPEN
;
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
)
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 ) );
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