bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / animations / motionpathtag.cxx
blobe15ac0db2701c24bfda72d5016890e7ec96b2198
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
49 #include "View.hxx"
50 #include "motionpathtag.hxx"
51 #include "sdpage.hxx"
52 #include "ViewShell.hxx"
53 #include "app.hrc"
54 #include "Window.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;
66 namespace sd
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
74 private:
75 basegfx::B2DPolyPolygon maPathPolyPolygon;
77 protected:
78 virtual void createSdrDragEntries() SAL_OVERRIDE;
80 public:
81 PathDragMove(SdrDragView& rNewView,
82 const rtl::Reference <MotionPathTag >& xTag,
83 const basegfx::B2DPolyPolygon& rPathPolyPolygon)
84 : SdrDragMove(rNewView),
85 maPathPolyPolygon(rPathPolyPolygon),
86 mxTag( xTag )
89 PathDragMove(SdrDragView& rNewView,
90 const rtl::Reference <MotionPathTag >& xTag)
91 : SdrDragMove(rNewView),
92 maPathPolyPolygon(),
93 mxTag( xTag )
96 virtual bool BeginSdrDrag() SAL_OVERRIDE;
97 virtual bool EndSdrDrag(bool bCopy) SAL_OVERRIDE;
99 rtl::Reference <MotionPathTag > mxTag;
102 void PathDragMove::createSdrDragEntries()
104 // call parent
105 SdrDragMove::createSdrDragEntries();
107 if(maPathPolyPolygon.count())
109 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
113 bool PathDragMove::BeginSdrDrag()
115 if( mxTag.is() )
117 SdrPathObj* pPathObj = mxTag->getPathObj();
118 if( pPathObj )
120 DragStat().SetActionRect(pPathObj->GetCurrentBoundRect());
123 Show();
124 return true;
127 bool PathDragMove::EndSdrDrag(bool /*bCopy*/)
129 Hide();
130 if( mxTag.is() )
131 mxTag->MovePath( DragStat().GetDX(), DragStat().GetDY() );
132 return true;
135 class PathDragResize : public SdrDragResize
137 private:
138 basegfx::B2DPolyPolygon maPathPolyPolygon;
140 protected:
141 virtual void createSdrDragEntries() SAL_OVERRIDE;
143 public:
144 PathDragResize(SdrDragView& rNewView,
145 const rtl::Reference <MotionPathTag >& xTag,
146 const basegfx::B2DPolyPolygon& rPathPolyPolygon)
147 : SdrDragResize(rNewView),
148 maPathPolyPolygon(rPathPolyPolygon),
149 mxTag( xTag )
152 PathDragResize(SdrDragView& rNewView,
153 const rtl::Reference <MotionPathTag >& xTag)
154 : SdrDragResize(rNewView),
155 maPathPolyPolygon(),
156 mxTag( xTag )
159 virtual bool EndSdrDrag(bool bCopy) SAL_OVERRIDE;
160 rtl::Reference <MotionPathTag > mxTag;
163 void PathDragResize::createSdrDragEntries()
165 // call parent
166 SdrDragResize::createSdrDragEntries();
168 if(maPathPolyPolygon.count())
170 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
174 bool PathDragResize::EndSdrDrag(bool /*bCopy*/)
176 Hide();
177 if( mxTag.is() )
179 SdrPathObj* pPathObj = mxTag->getPathObj();
180 if( pPathObj )
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 );
191 return true;
194 class PathDragObjOwn : public SdrDragObjOwn
196 private:
197 basegfx::B2DPolyPolygon maPathPolyPolygon;
199 protected:
200 virtual void createSdrDragEntries() SAL_OVERRIDE;
202 public:
203 PathDragObjOwn(SdrDragView& rNewView,
204 const basegfx::B2DPolyPolygon& rPathPolyPolygon)
205 : SdrDragObjOwn(rNewView),
206 maPathPolyPolygon(rPathPolyPolygon)
209 PathDragObjOwn(SdrDragView& rNewView)
210 : SdrDragObjOwn(rNewView),
211 maPathPolyPolygon()
214 virtual bool EndSdrDrag(bool bCopy) SAL_OVERRIDE;
217 void PathDragObjOwn::createSdrDragEntries()
219 // call parent
220 SdrDragObjOwn::createSdrDragEntries();
222 if(maPathPolyPolygon.count())
224 addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
228 bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/)
230 Hide();
232 SdrObject* pObj = GetDragObj();
234 if(pObj)
236 return pObj->applySpecialDrag(DragStat());
238 else
240 return false;
244 class SdPathHdl : public SmartHdl
246 public:
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;
253 private:
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
272 GetRidOfIAObject();
274 if(pHdlList)
276 SdrMarkView* pView = pHdlList->GetView();
278 if(pView && !pView->areMarkHandlesHidden())
280 SdrPageView* pPageView = pView->GetSdrPageView();
282 if(pPageView)
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
309 return false;
312 bool SdPathHdl::isMarkable() const
314 return false;
317 MotionPathTag::MotionPathTag( CustomAnimationPane& rPane, ::sd::View& rView, const CustomAnimationEffectPtr& pEffect )
318 : SmartTag( rView )
319 , mrPane( rPane )
320 , mpEffect( pEffect )
321 , mxOrigin( pEffect->getTargetShape() )
322 , msLastPath( pEffect->getPath() )
323 , mbInUpdatePath( false )
325 mpPathObj = mpEffect->createSdrPathObjFromPath();
326 mxPolyPoly = mpPathObj->GetPathPoly();
327 if (mxOrigin.is())
328 maOriginPos = mxOrigin->getPosition();
330 SdrPage* pPage = mrView.GetSdrPageView()->GetPage();
331 if( pPage )
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 );
362 if( xNotifier.is() )
364 Reference< XChangesListener > xListener( this );
365 xNotifier->addChangesListener( this );
369 MotionPathTag::~MotionPathTag()
371 DBG_ASSERT( mpPathObj == 0, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" );
372 Dispose();
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));
397 else
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 )
422 if( mpPathObj )
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 )
432 if( !mpPathObj )
433 return false;
435 if( !isSelected() )
437 SmartTagReference xTag( this );
438 mrView.getSmartTags().select( xTag );
439 selectionChanged();
440 return true;
442 else
444 if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) )
446 mrView.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT, SfxCallMode::ASYNCHRON);
447 return true;
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();
459 mrView.BrkAction();
461 Point aPt(aMDPos); // - pMarkedPV->GetOffset());
463 if(bNewObj)
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
473 // object changed
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 ) );
485 if (bRet)
487 const_cast< SdrDragStat* >( &mrView.GetDragStat() )->SetMinMoved();
488 mrView.MovDragObj(aMDPos);
491 return true;
493 else
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) );
503 else
505 if (mrView.IsPointMarked(*pHdl) )
507 mrView.UnmarkPoint(*pHdl);
508 pHdl = NULL;
510 else
512 pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) );
516 if (pHdl)
517 mrView.MarkPoint(*pHdl);
520 if( pHdl && !rMEvt.IsRight() )
522 mrView.BrkAction();
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 );
541 else
543 pDragMethod = new PathDragResize( mrView, xTag, aDragPoly );
546 mrView.BegDragObj(aMDPos, NULL, pHdl, nDrgLog, pDragMethod );
548 return true;
553 return false;
556 /** returns true if the SmartTag consumes this event. */
557 bool MotionPathTag::KeyInput( const KeyEvent& rKEvt )
559 if( !mpPathObj )
560 return false;
562 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
563 switch( nCode )
565 case KEY_DELETE:
566 return OnDelete();
568 case KEY_DOWN:
569 case KEY_UP:
570 case KEY_LEFT:
571 case KEY_RIGHT:
572 return OnMove( rKEvt );
574 case KEY_ESCAPE:
576 SmartTagReference xThis( this );
577 mrView.getSmartTags().deselect();
578 return true;
581 case KEY_TAB:
582 return OnTabHandles( rKEvt );
584 case KEY_SPACE:
585 return OnMarkHandle( rKEvt );
587 default:
588 break;
590 return false;
593 bool MotionPathTag::OnDelete()
595 mrPane.remove( mpEffect );
596 return true;
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();
611 if(pHdl)
613 Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
614 if( pWindow )
616 Point aHdlPosition(pHdl->GetPos());
617 Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
618 mrView.MakeVisible(aVisRect, *pWindow);
622 return true;
625 return false;
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);
646 else
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)
665 pNewOne = pAct;
668 if(pNewOne)
669 ((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
673 return true;
676 bool MotionPathTag::OnMove( const KeyEvent& rKEvt )
678 long nX = 0;
679 long nY = 0;
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;
687 default: 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();
697 else
699 // old, fixed move distance
700 nX *= 100;
701 nY *= 100;
704 if( nX || nY )
706 // in point edit mode move the handle with the focus
707 const SdrHdlList& rHdlList = mrView.GetHdlList();
708 SdrHdl* pHdl = rHdlList.GetFocusHdl();
710 if(pHdl)
712 // now move the Handle (nX, nY)
713 Point aStartPoint(pHdl->GetPos());
714 Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
716 // start dragging
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
739 if(!bWasNoSnap)
740 ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(true);
741 if(bWasSnapEnabled)
742 mrView.SetSnapEnabled(false);
744 mrView.MovAction(aEndPoint);
745 mrView.EndDragObj();
747 // restore snap
748 if(!bWasNoSnap)
749 ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(bWasNoSnap);
750 if(bWasSnapEnabled)
751 mrView.SetSnapEnabled(bWasSnapEnabled);
754 else
756 // move the path
757 MovePath( nX, nY );
761 return true;
764 sal_uLong MotionPathTag::GetMarkablePointCount() const
766 if( mpPathObj && isSelected() )
768 return mpPathObj->GetPointCount();
770 else
772 return 0;
776 sal_uLong MotionPathTag::GetMarkedPointCount() const
778 if( mpMark )
780 const SdrUShortCont* pPts=mpMark->GetMarkedPoints();
781 return pPts ? pPts->size() : 0;
783 else
785 return 0;
789 bool MotionPathTag::MarkPoint(SdrHdl& rHdl, bool bUnmark )
791 bool bRet=false;
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();
801 bRet=true;
805 return bRet;
808 bool MotionPathTag::MarkPoints(const Rectangle* pRect, bool bUnmark )
810 bool bChgd=false;
812 if( mpPathObj && isSelected() )
814 size_t nHdlNum = mrView.GetHdlList().GetHdlCount();
815 if ( nHdlNum <= 1 )
816 return false;
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) )
828 bChgd=true;
833 if(bChgd)
834 mrView.MarkListHasChanged();
837 return bChgd;
840 bool MotionPathTag::getContext( SdrViewContext& rContext )
842 if( mpPathObj && isSelected() && !mrView.IsFrameDragSingles() )
844 rContext = SDRCONTEXT_POINTEDIT;
845 return true;
847 else
849 return false;
853 void MotionPathTag::CheckPossibilities()
855 if( mpPathObj )
857 if( isSelected() )
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);
868 bool b1stSegm(true);
869 bool bCurve(false);
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 )
882 if( mpPathObj )
884 ::com::sun::star::awt::Point aPos;
885 if (mxOrigin.is())
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 );
893 maOriginPos = aPos;
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 );
904 if( isSelected() )
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);
937 if (pPlusHdl!=NULL)
939 pPlusHdl->SetObj(mpPathObj);
940 pPlusHdl->SetPageView(mrView.GetSdrPageView());
941 pPlusHdl->SetPlusHdl(true);
942 rHandlerList.AddHdl(pPlusHdl);
948 else
950 Rectangle aRect(mpPathObj->GetCurrentBoundRect());
952 if(!aRect.IsEmpty())
954 size_t nCount = rHandlerList.GetHdlCount();
956 bool bWdt0=aRect.Left()==aRect.Right();
957 bool bHgt0=aRect.Top()==aRect.Bottom();
958 if (bWdt0 && bHgt0)
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));
967 else
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 );
992 if( xNotifier.is() )
994 Reference< XChangesListener > xListener( this );
995 xNotifier->removeChangesListener( this );
998 if( mpPathObj )
1000 SdrPathObj* pPathObj = mpPathObj;
1001 mpPathObj = 0;
1002 mrView.updateHandles();
1003 delete pPathObj;
1006 if( mpMark )
1008 delete mpMark;
1009 mpMark = 0;
1012 SmartTag::disposing();
1015 void MotionPathTag::deselect()
1017 SmartTag::deselect();
1019 if( mpMark )
1021 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1023 if( pPts )
1024 pPts->clear();
1027 selectionChanged();
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() )
1045 mrView.BrkAction();
1047 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1049 if( pPts )
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
1080 return false;
1083 bool MotionPathTag::IsSetMarkedSegmentsKindPossible() const
1085 if( mpPathObj )
1086 return mrView.IsSetMarkedSegmentsKindPossible();
1087 else
1088 return false;
1091 SdrPathSegmentKind MotionPathTag::GetMarkedSegmentsKind() const
1093 if( mpPathObj )
1094 return mrView.GetMarkedSegmentsKind();
1095 else
1096 return SDRPATHSEGMENT_LINE;
1099 void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind)
1101 if(mpPathObj && isSelected() && (GetMarkedPointCount() != 0))
1103 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1104 if(pPts)
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
1119 if( mpPathObj )
1120 return mrView.IsSetMarkedPointsSmoothPossible();
1121 else
1122 return false;
1125 SdrPathSmoothKind MotionPathTag::GetMarkedPointsSmooth() const
1127 if( mpPathObj )
1128 return mrView.GetMarkedPointsSmooth();
1129 else
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;
1149 else
1151 return;
1154 if(mpPathObj && mpMark && isSelected() && (GetMarkedPointCount() != 0))
1156 SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1157 if(pPts)
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
1178 return false;
1181 SdrObjClosedKind MotionPathTag::GetMarkedObjectsClosedState() const
1183 // not supported for motion path
1184 return SDROBJCLOSED_OPEN;
1187 // XChangesListener
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)
1203 if( mpPathObj )
1204 Dispose();
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 ) );
1216 return Any();
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: */