1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/util/XChangesNotifier.hpp>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
23 #include <basegfx/polygon/b2dpolygontools.hxx>
24 #include <basegfx/matrix/b2dhommatrixtools.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <sfx2/dispatch.hxx>
29 #include <svx/sdr/overlay/overlaymanager.hxx>
30 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
31 #include <svx/svdpagv.hxx>
32 #include <svx/sdrpagewindow.hxx>
33 #include <svx/sdrpaintwindow.hxx>
34 #include <svx/svdopath.hxx>
35 #include <svx/xlndsit.hxx>
36 #include <svx/xlnclit.hxx>
37 #include <svx/xlnstit.hxx>
38 #include <svx/xlnedit.hxx>
39 #include <svx/xlnstwit.hxx>
40 #include <svx/xlnedwit.hxx>
41 #include <svx/xlnstcit.hxx>
42 #include <svx/xlnedcit.hxx>
43 #include <svx/xlntrit.hxx>
44 #include <svx/svxids.hrc>
45 #include <svx/polypolygoneditor.hxx>
46 #include <svx/svddrgmt.hxx>
48 #include "CustomAnimationPane.hxx"
50 #include "motionpathtag.hxx"
52 #include "ViewShell.hxx"
56 #include <svx/sdr/contact/viewcontact.hxx>
57 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
59 using sdr::PolyPolygonEditor
;
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::lang
;
63 using namespace ::com::sun::star::util
;
64 using namespace ::com::sun::star::drawing
;
69 const sal_uInt32 SMART_TAG_HDL_NUM
= SAL_MAX_UINT32
;
70 static const int DRGPIX
= 2; // Drag MinMove in Pixel
72 class PathDragMove
: public SdrDragMove
75 basegfx::B2DPolyPolygon maPathPolyPolygon
;
78 virtual void createSdrDragEntries() SAL_OVERRIDE
;
81 PathDragMove(SdrDragView
& rNewView
,
82 const rtl::Reference
<MotionPathTag
>& xTag
,
83 const basegfx::B2DPolyPolygon
& rPathPolyPolygon
)
84 : SdrDragMove(rNewView
),
85 maPathPolyPolygon(rPathPolyPolygon
),
89 PathDragMove(SdrDragView
& rNewView
,
90 const rtl::Reference
<MotionPathTag
>& xTag
)
91 : SdrDragMove(rNewView
),
96 virtual bool BeginSdrDrag() SAL_OVERRIDE
;
97 virtual bool EndSdrDrag(bool bCopy
) SAL_OVERRIDE
;
99 rtl::Reference
<MotionPathTag
> mxTag
;
102 void PathDragMove::createSdrDragEntries()
105 SdrDragMove::createSdrDragEntries();
107 if(maPathPolyPolygon
.count())
109 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon
));
113 bool PathDragMove::BeginSdrDrag()
117 SdrPathObj
* pPathObj
= mxTag
->getPathObj();
120 DragStat().SetActionRect(pPathObj
->GetCurrentBoundRect());
127 bool PathDragMove::EndSdrDrag(bool /*bCopy*/)
131 mxTag
->MovePath( DragStat().GetDX(), DragStat().GetDY() );
135 class PathDragResize
: public SdrDragResize
138 basegfx::B2DPolyPolygon maPathPolyPolygon
;
141 virtual void createSdrDragEntries() SAL_OVERRIDE
;
144 PathDragResize(SdrDragView
& rNewView
,
145 const rtl::Reference
<MotionPathTag
>& xTag
,
146 const basegfx::B2DPolyPolygon
& rPathPolyPolygon
)
147 : SdrDragResize(rNewView
),
148 maPathPolyPolygon(rPathPolyPolygon
),
152 PathDragResize(SdrDragView
& rNewView
,
153 const rtl::Reference
<MotionPathTag
>& xTag
)
154 : SdrDragResize(rNewView
),
159 virtual bool EndSdrDrag(bool bCopy
) SAL_OVERRIDE
;
160 rtl::Reference
<MotionPathTag
> mxTag
;
163 void PathDragResize::createSdrDragEntries()
166 SdrDragResize::createSdrDragEntries();
168 if(maPathPolyPolygon
.count())
170 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon
));
174 bool PathDragResize::EndSdrDrag(bool /*bCopy*/)
179 SdrPathObj
* pPathObj
= mxTag
->getPathObj();
182 const Point
aRef( DragStat().Ref1() );
183 basegfx::B2DHomMatrix
aTrans(basegfx::tools::createTranslateB2DHomMatrix(-aRef
.X(), -aRef
.Y()));
184 aTrans
.scale(double(aXFact
), double(aYFact
));
185 aTrans
.translate(aRef
.X(), aRef
.Y());
186 basegfx::B2DPolyPolygon
aDragPoly(pPathObj
->GetPathPoly());
187 aDragPoly
.transform(aTrans
);
188 pPathObj
->SetPathPoly( aDragPoly
);
194 class PathDragObjOwn
: public SdrDragObjOwn
197 basegfx::B2DPolyPolygon maPathPolyPolygon
;
200 virtual void createSdrDragEntries() SAL_OVERRIDE
;
203 PathDragObjOwn(SdrDragView
& rNewView
,
204 const basegfx::B2DPolyPolygon
& rPathPolyPolygon
)
205 : SdrDragObjOwn(rNewView
),
206 maPathPolyPolygon(rPathPolyPolygon
)
209 PathDragObjOwn(SdrDragView
& rNewView
)
210 : SdrDragObjOwn(rNewView
),
214 virtual bool EndSdrDrag(bool bCopy
) SAL_OVERRIDE
;
217 void PathDragObjOwn::createSdrDragEntries()
220 SdrDragObjOwn::createSdrDragEntries();
222 if(maPathPolyPolygon
.count())
224 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon
));
228 bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/)
232 SdrObject
* pObj
= GetDragObj();
236 return pObj
->applySpecialDrag(DragStat());
244 class SdPathHdl
: public SmartHdl
247 SdPathHdl( const SmartTagReference
& xTag
, SdrPathObj
* mpPathObj
);
248 virtual ~SdPathHdl();
249 virtual void CreateB2dIAObject() SAL_OVERRIDE
;
250 virtual bool IsFocusHdl() const SAL_OVERRIDE
;
251 virtual bool isMarkable() const SAL_OVERRIDE
;
254 SdrPathObj
* mpPathObj
;
255 rtl::Reference
< MotionPathTag
> mxTag
;
258 SdPathHdl::SdPathHdl( const SmartTagReference
& xTag
, SdrPathObj
* pPathObj
)
259 : SmartHdl( xTag
, pPathObj
->GetCurrentBoundRect().TopLeft() )
260 , mpPathObj( pPathObj
)
261 , mxTag( dynamic_cast< MotionPathTag
* >( xTag
.get() ) )
265 SdPathHdl::~SdPathHdl()
269 void SdPathHdl::CreateB2dIAObject()
271 // first throw away old one
276 SdrMarkView
* pView
= pHdlList
->GetView();
278 if(pView
&& !pView
->areMarkHandlesHidden())
280 SdrPageView
* pPageView
= pView
->GetSdrPageView();
284 for(sal_uInt32
b(0L); b
< pPageView
->PageWindowCount(); b
++)
286 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(b
);
288 if(rPageWindow
.GetPaintWindow().OutputToWindow())
290 rtl::Reference
< sdr::overlay::OverlayManager
> xManager
= rPageWindow
.GetOverlayManager();
291 if (xManager
.is() && mpPathObj
)
293 const sdr::contact::ViewContact
& rVC
= mpPathObj
->GetViewContact();
294 const drawinglayer::primitive2d::Primitive2DSequence aSequence
= rVC
.getViewIndependentPrimitive2DSequence();
295 sdr::overlay::OverlayObject
* pNew
= new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence
);
297 xManager
->add(*pNew
);
298 maOverlayGroup
.append(*pNew
);
307 bool SdPathHdl::IsFocusHdl() const
312 bool SdPathHdl::isMarkable() const
317 MotionPathTag::MotionPathTag( CustomAnimationPane
& rPane
, ::sd::View
& rView
, const CustomAnimationEffectPtr
& pEffect
)
320 , mpEffect( pEffect
)
321 , mxOrigin( pEffect
->getTargetShape() )
322 , msLastPath( pEffect
->getPath() )
323 , mbInUpdatePath( false )
325 mpPathObj
= mpEffect
->createSdrPathObjFromPath();
326 mxPolyPoly
= mpPathObj
->GetPathPoly();
328 maOriginPos
= mxOrigin
->getPosition();
330 SdrPage
* pPage
= mrView
.GetSdrPageView()->GetPage();
333 mpPathObj
->SetPage( pPage
);
334 mpPathObj
->SetObjList( pPage
);
337 XDash
aDash( css::drawing::DashStyle_RECT
, 1, 80, 1, 80, 80);
338 OUString
aEmpty( "?" );
339 mpPathObj
->SetMergedItem( XLineDashItem( aEmpty
, aDash
) );
340 mpPathObj
->SetMergedItem( XLineStyleItem( drawing::LineStyle_DASH
) );
341 mpPathObj
->SetMergedItem( XLineColorItem(aEmpty
, ::Color(COL_GRAY
)) );
342 mpPathObj
->SetMergedItem( XFillStyleItem( drawing::FillStyle_NONE
) );
344 ::basegfx::B2DPolygon aStartArrow
;
345 aStartArrow
.append(::basegfx::B2DPoint(20.0, 0.0));
346 aStartArrow
.append(::basegfx::B2DPoint(0.0, 0.0));
347 aStartArrow
.append(::basegfx::B2DPoint(10.0, 30.0));
348 aStartArrow
.setClosed(true);
349 mpPathObj
->SetMergedItem(XLineStartItem(aEmpty
,::basegfx::B2DPolyPolygon(aStartArrow
)));
350 mpPathObj
->SetMergedItem(XLineStartWidthItem(400));
351 mpPathObj
->SetMergedItem(XLineStartCenterItem(true));
353 updatePathAttributes();
355 mpPathObj
->SetMergedItem(XLineTransparenceItem(50));
357 mpMark
= new SdrMark( mpPathObj
, mrView
.GetSdrPageView() );
359 mpPathObj
->AddListener( *this );
361 Reference
< XChangesNotifier
> xNotifier( mpEffect
->getNode(), UNO_QUERY
);
364 Reference
< XChangesListener
> xListener( this );
365 xNotifier
->addChangesListener( this );
369 MotionPathTag::~MotionPathTag()
371 DBG_ASSERT( mpPathObj
== 0, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" );
375 void MotionPathTag::updatePathAttributes()
377 OUString
aEmpty( "?" );
379 ::basegfx::B2DPolygon aCandidate
;
380 if( mxPolyPoly
.count() )
382 aCandidate
= mxPolyPoly
.getB2DPolygon(0);
383 ::basegfx::tools::checkClosed( aCandidate
);
386 if( !aCandidate
.isClosed() )
388 ::basegfx::B2DPolygon aEndArrow
;
389 aEndArrow
.append(::basegfx::B2DPoint(10.0, 0.0));
390 aEndArrow
.append(::basegfx::B2DPoint(0.0, 30.0));
391 aEndArrow
.append(::basegfx::B2DPoint(20.0, 30.0));
392 aEndArrow
.setClosed(true);
393 mpPathObj
->SetMergedItem(XLineEndItem(aEmpty
,::basegfx::B2DPolyPolygon(aEndArrow
)));
394 mpPathObj
->SetMergedItem(XLineEndWidthItem(400));
395 mpPathObj
->SetMergedItem(XLineEndCenterItem(true));
399 mpPathObj
->SetMergedItem(XLineEndItem());
403 void MotionPathTag::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
405 if( mpPathObj
&& !mbInUpdatePath
&& dynamic_cast< const SdrHint
* >( &rHint
) && (mpEffect
.get() != 0) )
407 if( mxPolyPoly
!= mpPathObj
->GetPathPoly() )
409 mbInUpdatePath
= true;
410 mxPolyPoly
= mpPathObj
->GetPathPoly();
411 rtl::Reference
< MotionPathTag
> xTag( this );
412 mrPane
.updatePathFromMotionPathTag( xTag
);
413 msLastPath
= mpEffect
->getPath();
414 updatePathAttributes();
415 mbInUpdatePath
= false;
420 void MotionPathTag::MovePath( int nDX
, int nDY
)
424 mpPathObj
->Move( Size( nDX
, nDY
) );
425 mrView
.updateHandles();
429 /** returns true if the MotionPathTag handled the event. */
430 bool MotionPathTag::MouseButtonDown( const MouseEvent
& rMEvt
, SmartHdl
& rHdl
)
437 SmartTagReference
xTag( this );
438 mrView
.getSmartTags().select( xTag
);
444 if( rMEvt
.IsLeft() && (rMEvt
.GetClicks() == 2) )
446 mrView
.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT
, SfxCallMode::ASYNCHRON
);
449 else if( rMEvt
.IsLeft() )
451 OutputDevice
* pOut
= mrView
.GetViewShell()->GetActiveWindow();
452 Point
aMDPos( pOut
->PixelToLogic( rMEvt
.GetPosPixel() ) );
454 if( !mrView
.IsFrameDragSingles() && mrView
.IsInsObjPointMode() && (rHdl
.GetObjHdlNum() == SMART_TAG_HDL_NUM
) )
456 // insert a point in edit mode
457 const bool bNewObj
= rMEvt
.IsMod1();
461 Point
aPt(aMDPos
); // - pMarkedPV->GetOffset());
464 aPt
= mrView
.GetSnapPos(aPt
,mrView
.GetSdrPageView());
466 bool bClosed0(mpPathObj
->IsClosedObj());
468 sal_uInt32 nInsPointNum
= mpPathObj
->NbcInsPointOld(aPt
, bNewObj
, true);
470 if(bClosed0
!= mpPathObj
->IsClosedObj())
472 // Obj was closed implicit
474 mpPathObj
->SetChanged();
475 mpPathObj
->BroadcastObjectChange();
478 if(0xffffffff != nInsPointNum
)
480 mrView
.UnmarkAllPoints();
481 mrView
.updateHandles();
483 bool bRet
= mrView
.BegDragObj(aMDPos
, pOut
, mrView
.GetHdl(nInsPointNum
+1), 0, new PathDragObjOwn( mrView
) );
487 const_cast< SdrDragStat
* >( &mrView
.GetDragStat() )->SetMinMoved();
488 mrView
.MovDragObj(aMDPos
);
495 SmartHdl
* pHdl
= &rHdl
;
496 if (!mrView
.IsPointMarked(*pHdl
) || rMEvt
.IsShift())
498 if (!rMEvt
.IsShift())
500 mrView
.UnmarkAllPoints();
501 pHdl
= dynamic_cast< SmartHdl
* >( mrView
.PickHandle(aMDPos
) );
505 if (mrView
.IsPointMarked(*pHdl
) )
507 mrView
.UnmarkPoint(*pHdl
);
512 pHdl
= dynamic_cast< SmartHdl
* >( mrView
.PickHandle(aMDPos
) );
517 mrView
.MarkPoint(*pHdl
);
520 if( pHdl
&& !rMEvt
.IsRight() )
523 const sal_uInt16 nDrgLog
= (sal_uInt16
)pOut
->PixelToLogic(Size(DRGPIX
,0)).Width();
525 rtl::Reference
< MotionPathTag
> xTag( this );
526 SdrDragMethod
* pDragMethod
;
528 // #i95646# add DragPoly as geometry to each local SdrDragMethod to be able
529 // to create the needed local SdrDragEntry for it in createSdrDragEntries()
530 const basegfx::B2DPolyPolygon
aDragPoly(mpPathObj
->GetPathPoly());
532 if( (pHdl
->GetKind() == HDL_MOVE
) || (pHdl
->GetKind() == HDL_SMARTTAG
) )
534 pDragMethod
= new PathDragMove( mrView
, xTag
, aDragPoly
);
535 pHdl
->SetPos( aMDPos
);
537 else if( pHdl
->GetKind() == HDL_POLY
)
539 pDragMethod
= new PathDragObjOwn( mrView
, aDragPoly
);
543 pDragMethod
= new PathDragResize( mrView
, xTag
, aDragPoly
);
546 mrView
.BegDragObj(aMDPos
, NULL
, pHdl
, nDrgLog
, pDragMethod
);
556 /** returns true if the SmartTag consumes this event. */
557 bool MotionPathTag::KeyInput( const KeyEvent
& rKEvt
)
562 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
572 return OnMove( rKEvt
);
576 SmartTagReference
xThis( this );
577 mrView
.getSmartTags().deselect();
582 return OnTabHandles( rKEvt
);
585 return OnMarkHandle( rKEvt
);
593 bool MotionPathTag::OnDelete()
595 mrPane
.remove( mpEffect
);
599 bool MotionPathTag::OnTabHandles( const KeyEvent
& rKEvt
)
601 if(rKEvt
.GetKeyCode().IsMod1() || rKEvt
.GetKeyCode().IsMod2())
603 const SdrHdlList
& rHdlList
= mrView
.GetHdlList();
604 bool bForward(!rKEvt
.GetKeyCode().IsShift());
606 ((SdrHdlList
&)rHdlList
).TravelFocusHdl(bForward
);
608 // guarantee visibility of focused handle
609 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
613 Window
* pWindow
= mrView
.GetViewShell()->GetActiveWindow();
616 Point
aHdlPosition(pHdl
->GetPos());
617 Rectangle
aVisRect(aHdlPosition
- Point(100, 100), Size(200, 200));
618 mrView
.MakeVisible(aVisRect
, *pWindow
);
628 bool MotionPathTag::OnMarkHandle( const KeyEvent
& rKEvt
)
630 const SdrHdlList
& rHdlList
= mrView
.GetHdlList();
631 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
633 if(pHdl
&& pHdl
->GetKind() == HDL_POLY
)
635 // rescue ID of point with focus
636 sal_uInt32
nPol(pHdl
->GetPolyNum());
637 sal_uInt32
nPnt(pHdl
->GetPointNum());
639 if(mrView
.IsPointMarked(*pHdl
))
641 if(rKEvt
.GetKeyCode().IsShift())
643 mrView
.UnmarkPoint(*pHdl
);
648 if(!rKEvt
.GetKeyCode().IsShift())
650 mrView
.UnmarkAllPoints();
652 mrView
.MarkPoint(*pHdl
);
655 if(0L == rHdlList
.GetFocusHdl())
657 // restore point with focus
658 SdrHdl
* pNewOne
= 0L;
660 for(size_t a
= 0; !pNewOne
&& a
< rHdlList
.GetHdlCount(); ++a
)
662 SdrHdl
* pAct
= rHdlList
.GetHdl(a
);
664 if(pAct
&& pAct
->GetKind() == HDL_POLY
&& pAct
->GetPolyNum() == nPol
&& pAct
->GetPointNum() == nPnt
)
669 ((SdrHdlList
&)rHdlList
).SetFocusHdl(pNewOne
);
676 bool MotionPathTag::OnMove( const KeyEvent
& rKEvt
)
681 switch( rKEvt
.GetKeyCode().GetCode() )
683 case KEY_UP
: nY
= -1; break;
684 case KEY_DOWN
: nY
= 1; break;
685 case KEY_LEFT
: nX
= -1; break;
686 case KEY_RIGHT
: nX
= 1; break;
690 if(rKEvt
.GetKeyCode().IsMod2())
692 OutputDevice
* pOut
= mrView
.GetViewShell()->GetActiveWindow();
693 Size aLogicSizeOnePixel
= (pOut
) ? pOut
->PixelToLogic(Size(1,1)) : Size(100, 100);
694 nX
*= aLogicSizeOnePixel
.Width();
695 nY
*= aLogicSizeOnePixel
.Height();
699 // old, fixed move distance
706 // in point edit mode move the handle with the focus
707 const SdrHdlList
& rHdlList
= mrView
.GetHdlList();
708 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
712 // now move the Handle (nX, nY)
713 Point
aStartPoint(pHdl
->GetPos());
714 Point
aEndPoint(pHdl
->GetPos() + Point(nX
, nY
));
717 rtl::Reference
< MotionPathTag
> xTag( this );
718 SdrDragMethod
* pDragMethod
= 0;
719 if( (pHdl
->GetKind() == HDL_MOVE
) || (pHdl
->GetKind() == HDL_SMARTTAG
) )
721 pDragMethod
= new PathDragMove( mrView
, xTag
);
723 else if( pHdl
->GetKind() == HDL_POLY
)
725 pDragMethod
= new PathDragObjOwn( mrView
);
727 else if( pHdl
->GetKind() != HDL_BWGT
)
729 pDragMethod
= new PathDragResize( mrView
, xTag
);
731 mrView
.BegDragObj(aStartPoint
, 0, pHdl
, 0, pDragMethod
);
733 if(mrView
.IsDragObj())
735 bool bWasNoSnap
= mrView
.GetDragStat().IsNoSnap();
736 bool bWasSnapEnabled
= mrView
.IsSnapEnabled();
738 // switch snapping off
740 ((SdrDragStat
&)mrView
.GetDragStat()).SetNoSnap(true);
742 mrView
.SetSnapEnabled(false);
744 mrView
.MovAction(aEndPoint
);
749 ((SdrDragStat
&)mrView
.GetDragStat()).SetNoSnap(bWasNoSnap
);
751 mrView
.SetSnapEnabled(bWasSnapEnabled
);
764 sal_uLong
MotionPathTag::GetMarkablePointCount() const
766 if( mpPathObj
&& isSelected() )
768 return mpPathObj
->GetPointCount();
776 sal_uLong
MotionPathTag::GetMarkedPointCount() const
780 const SdrUShortCont
* pPts
=mpMark
->GetMarkedPoints();
781 return pPts
? pPts
->size() : 0;
789 bool MotionPathTag::MarkPoint(SdrHdl
& rHdl
, bool bUnmark
)
792 if( mpPathObj
&& mrView
.IsPointMarkable( rHdl
) && (rHdl
.GetKind() != HDL_SMARTTAG
) )
794 SmartHdl
* pSmartHdl
= dynamic_cast< SmartHdl
* >( &rHdl
);
795 if( pSmartHdl
&& pSmartHdl
->getTag().get() == this )
797 mpMark
->ForceMarkedPoints();
798 if (mrView
.MarkPointHelper(&rHdl
,mpMark
,bUnmark
))
800 mrView
.MarkListHasChanged();
808 bool MotionPathTag::MarkPoints(const Rectangle
* pRect
, bool bUnmark
)
812 if( mpPathObj
&& isSelected() )
814 size_t nHdlNum
= mrView
.GetHdlList().GetHdlCount();
818 while( --nHdlNum
> 0 )
820 SmartHdl
* pHdl
= dynamic_cast< SmartHdl
* >( mrView
.GetHdl( nHdlNum
) );
822 if( pHdl
&& (pHdl
->getTag().get() == this) && mrView
.IsPointMarkable(*pHdl
) && pHdl
->IsSelected() == bUnmark
)
824 Point
aPos(pHdl
->GetPos());
825 if( pRect
==NULL
|| pRect
->IsInside(aPos
))
827 if( mrView
.MarkPointHelper(pHdl
,mpMark
,bUnmark
) )
834 mrView
.MarkListHasChanged();
840 bool MotionPathTag::getContext( SdrViewContext
& rContext
)
842 if( mpPathObj
&& isSelected() && !mrView
.IsFrameDragSingles() )
844 rContext
= SDRCONTEXT_POINTEDIT
;
853 void MotionPathTag::CheckPossibilities()
859 mrView
.SetMoveAllowed( true );
860 mrView
.SetMoveProtected( false );
861 mrView
.SetResizeFreeAllowed( true );
862 mrView
.SetResizePropAllowed( true );
863 mrView
.SetResizeProtected( false );
865 if( !mrView
.IsFrameDragSingles() )
867 bool b1stSmooth(true);
870 bool bSmoothFuz(false);
871 bool bSegmFuz(false);
872 basegfx::B2VectorContinuity eSmooth
= basegfx::CONTINUITY_NONE
;
874 mrView
.CheckPolyPossibilitiesHelper( mpMark
, b1stSmooth
, b1stSegm
, bCurve
, bSmoothFuz
, bSegmFuz
, eSmooth
);
880 void MotionPathTag::addCustomHandles( SdrHdlList
& rHandlerList
)
884 ::com::sun::star::awt::Point aPos
;
886 aPos
= mxOrigin
->getPosition();
887 if( (aPos
.X
!= maOriginPos
.X
) || (aPos
.Y
!= maOriginPos
.Y
) )
889 const basegfx::B2DHomMatrix
aTransform(basegfx::tools::createTranslateB2DHomMatrix(
890 aPos
.X
- maOriginPos
.X
, aPos
.Y
- maOriginPos
.Y
));
891 mxPolyPoly
.transform( aTransform
);
892 mpPathObj
->SetPathPoly( mxPolyPoly
);
896 SmartTagReference
xThis( this );
897 SdPathHdl
* pHdl
= new SdPathHdl( xThis
, mpPathObj
);
898 pHdl
->SetObjHdlNum( SMART_TAG_HDL_NUM
);
899 pHdl
->SetPageView( mrView
.GetSdrPageView() );
901 pHdl
->SetObj(mpPathObj
);
902 rHandlerList
.AddHdl( pHdl
);
906 mrView
.GetSdrPageView()->SetHasMarkedObj(true);
908 if( !mrView
.IsFrameDragSingles() )
910 SdrHdlList
aTemp( rHandlerList
.GetView() );
911 mpPathObj
->AddToHdlList( aTemp
);
912 const SdrUShortCont
* pMrkPnts
=mpMark
->GetMarkedPoints();
914 for( size_t nHandle
= 0; nHandle
< aTemp
.GetHdlCount(); ++nHandle
)
916 SdrHdl
* pTempHdl
= aTemp
.GetHdl( nHandle
);
918 SmartHdl
* pSmartHdl
= new SmartHdl( xThis
, mpPathObj
, pTempHdl
->GetPos(), pTempHdl
->GetKind() );
919 pSmartHdl
->SetObjHdlNum( static_cast<sal_uInt32
>(nHandle
) );
920 pSmartHdl
->SetPolyNum( pTempHdl
->GetPolyNum() );
921 pSmartHdl
->SetPointNum( pTempHdl
->GetPointNum() );
922 pSmartHdl
->SetPlusHdl( pTempHdl
->IsPlusHdl() );
923 pSmartHdl
->SetSourceHdlNum( pTempHdl
->GetSourceHdlNum() );
924 pSmartHdl
->SetPageView( mrView
.GetSdrPageView() );
926 rHandlerList
.AddHdl( pSmartHdl
);
928 const bool bSelected
= pMrkPnts
&& pMrkPnts
->find( sal_uInt16(nHandle
) ) != pMrkPnts
->end();
929 pSmartHdl
->SetSelected(bSelected
);
931 if( mrView
.IsPlusHandlesAlwaysVisible() || bSelected
)
933 sal_uInt32 nPlusAnz
=mpPathObj
->GetPlusHdlCount(*pSmartHdl
);
934 for (sal_uInt32 nPlusNum
=0; nPlusNum
<nPlusAnz
; nPlusNum
++)
936 SdrHdl
* pPlusHdl
= mpPathObj
->GetPlusHdl(*pSmartHdl
,nPlusNum
);
939 pPlusHdl
->SetObj(mpPathObj
);
940 pPlusHdl
->SetPageView(mrView
.GetSdrPageView());
941 pPlusHdl
->SetPlusHdl(true);
942 rHandlerList
.AddHdl(pPlusHdl
);
950 Rectangle
aRect(mpPathObj
->GetCurrentBoundRect());
954 size_t nCount
= rHandlerList
.GetHdlCount();
956 bool bWdt0
=aRect
.Left()==aRect
.Right();
957 bool bHgt0
=aRect
.Top()==aRect
.Bottom();
960 rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.TopLeft(),HDL_UPLFT
));
962 else if (bWdt0
|| bHgt0
)
964 rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.TopLeft() ,HDL_UPLFT
));
965 rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.BottomRight(),HDL_LWRGT
));
969 if (!bWdt0
&& !bHgt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.TopLeft() ,HDL_UPLFT
));
970 if ( !bHgt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.TopCenter() ,HDL_UPPER
));
971 if (!bWdt0
&& !bHgt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.TopRight() ,HDL_UPRGT
));
972 if (!bWdt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.LeftCenter() ,HDL_LEFT
));
973 if (!bWdt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.RightCenter() ,HDL_RIGHT
));
974 if (!bWdt0
&& !bHgt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.BottomLeft() ,HDL_LWLFT
));
975 if ( !bHgt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.BottomCenter(),HDL_LOWER
));
976 if (!bWdt0
&& !bHgt0
) rHandlerList
.AddHdl(new SmartHdl( xThis
, mpPathObj
, aRect
.BottomRight() ,HDL_LWRGT
));
979 while( nCount
< rHandlerList
.GetHdlCount() )
981 rHandlerList
.GetHdl(nCount
++)->SetPageView( mrView
.GetSdrPageView() );
989 void MotionPathTag::disposing()
991 Reference
< XChangesNotifier
> xNotifier( mpEffect
->getNode(), UNO_QUERY
);
994 Reference
< XChangesListener
> xListener( this );
995 xNotifier
->removeChangesListener( this );
1000 SdrPathObj
* pPathObj
= mpPathObj
;
1002 mrView
.updateHandles();
1012 SmartTag::disposing();
1015 void MotionPathTag::deselect()
1017 SmartTag::deselect();
1021 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
1030 void MotionPathTag::selectionChanged()
1032 if( mrView
.GetViewShell() && mrView
.GetViewShell()->GetViewFrame() )
1034 SfxBindings
& rBindings
= mrView
.GetViewShell()->GetViewFrame()->GetBindings();
1035 rBindings
.InvalidateAll(true);
1039 // IPolyPolygonEditorController
1041 void MotionPathTag::DeleteMarkedPoints()
1043 if( mpPathObj
&& IsDeleteMarkedPointsPossible() )
1047 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
1051 PolyPolygonEditor
aEditor( mpPathObj
->GetPathPoly(), mpPathObj
->IsClosed() );
1052 if( aEditor
.DeletePoints( *pPts
) )
1054 if( aEditor
.GetPolyPolygon().count() )
1056 mpPathObj
->SetPathPoly( aEditor
.GetPolyPolygon() );
1059 mrView
.UnmarkAllPoints();
1060 mrView
.MarkListHasChanged();
1061 mrView
.updateHandles();
1067 bool MotionPathTag::IsDeleteMarkedPointsPossible() const
1069 return mpPathObj
&& isSelected() && (GetMarkedPointCount() != 0);
1072 void MotionPathTag::RipUpAtMarkedPoints()
1074 // not supported for motion path
1077 bool MotionPathTag::IsRipUpAtMarkedPointsPossible() const
1079 // not supported for motion path
1083 bool MotionPathTag::IsSetMarkedSegmentsKindPossible() const
1086 return mrView
.IsSetMarkedSegmentsKindPossible();
1091 SdrPathSegmentKind
MotionPathTag::GetMarkedSegmentsKind() const
1094 return mrView
.GetMarkedSegmentsKind();
1096 return SDRPATHSEGMENT_LINE
;
1099 void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind
)
1101 if(mpPathObj
&& isSelected() && (GetMarkedPointCount() != 0))
1103 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
1106 PolyPolygonEditor
aEditor( mpPathObj
->GetPathPoly(), mpPathObj
->IsClosed() );
1107 if(aEditor
.SetSegmentsKind( eKind
, *pPts
) )
1109 mpPathObj
->SetPathPoly(aEditor
.GetPolyPolygon());
1110 mrView
.MarkListHasChanged();
1111 mrView
.updateHandles();
1117 bool MotionPathTag::IsSetMarkedPointsSmoothPossible() const
1120 return mrView
.IsSetMarkedPointsSmoothPossible();
1125 SdrPathSmoothKind
MotionPathTag::GetMarkedPointsSmooth() const
1128 return mrView
.GetMarkedPointsSmooth();
1130 return SDRPATHSMOOTH_ANGULAR
;
1133 void MotionPathTag::SetMarkedPointsSmooth(SdrPathSmoothKind eKind
)
1135 basegfx::B2VectorContinuity eFlags
;
1137 if(SDRPATHSMOOTH_ANGULAR
== eKind
)
1139 eFlags
= basegfx::CONTINUITY_NONE
;
1141 else if(SDRPATHSMOOTH_ASYMMETRIC
== eKind
)
1143 eFlags
= basegfx::CONTINUITY_C1
;
1145 else if(SDRPATHSMOOTH_SYMMETRIC
== eKind
)
1147 eFlags
= basegfx::CONTINUITY_C2
;
1154 if(mpPathObj
&& mpMark
&& isSelected() && (GetMarkedPointCount() != 0))
1156 SdrUShortCont
* pPts
= mpMark
->GetMarkedPoints();
1159 PolyPolygonEditor
aEditor( mpPathObj
->GetPathPoly(), mpPathObj
->IsClosed() );
1160 if(aEditor
.SetPointsSmooth( eFlags
, *pPts
) )
1162 mpPathObj
->SetPathPoly(aEditor
.GetPolyPolygon());
1163 mrView
.MarkListHasChanged();
1164 mrView
.updateHandles();
1170 void MotionPathTag::CloseMarkedObjects(bool /*bToggle*/, bool /*bOpen*/ )
1172 // not supported for motion path
1175 bool MotionPathTag::IsOpenCloseMarkedObjectsPossible() const
1177 // not supported for motion path
1181 SdrObjClosedKind
MotionPathTag::GetMarkedObjectsClosedState() const
1183 // not supported for motion path
1184 return SDROBJCLOSED_OPEN
;
1188 void SAL_CALL
MotionPathTag::changesOccurred( const ChangesEvent
& /*Event*/ ) throw (RuntimeException
, std::exception
)
1190 if( mpPathObj
&& !mbInUpdatePath
&& (mpEffect
->getPath() != msLastPath
) )
1192 mbInUpdatePath
=true;
1193 msLastPath
= mpEffect
->getPath();
1194 mpEffect
->updateSdrPathObjFromPath( *mpPathObj
);
1195 mbInUpdatePath
= false;
1196 updatePathAttributes();
1197 mrView
.updateHandles();
1201 void SAL_CALL
MotionPathTag::disposing( const EventObject
& /*Source*/ ) throw (RuntimeException
, std::exception
)
1207 Any SAL_CALL
MotionPathTag::queryInterface( const ::com::sun::star::uno::Type
& aType
) throw (RuntimeException
, std::exception
)
1209 if( aType
== cppu::UnoType
<XChangesListener
>::get() )
1210 return Any( Reference
< XChangesListener
>( this ) );
1211 if( aType
== cppu::UnoType
<XEventListener
>::get() )
1212 return Any( Reference
< XEventListener
>( this ) );
1213 if( aType
== cppu::UnoType
<XInterface
>::get() )
1214 return Any( Reference
< XInterface
>( this ) );
1219 void SAL_CALL
MotionPathTag::acquire() throw ()
1221 SimpleReferenceComponent::acquire();
1224 void SAL_CALL
MotionPathTag::release( ) throw ()
1226 SimpleReferenceComponent::release();
1229 } // end of namespace sd
1231 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */