diff options
Diffstat (limited to 'sd/source/ui/animations/motionpathtag.cxx')
-rw-r--r-- | sd/source/ui/animations/motionpathtag.cxx | 1327 |
1 files changed, 1327 insertions, 0 deletions
diff --git a/sd/source/ui/animations/motionpathtag.cxx b/sd/source/ui/animations/motionpathtag.cxx new file mode 100644 index 000000000000..30992f913705 --- /dev/null +++ b/sd/source/ui/animations/motionpathtag.cxx @@ -0,0 +1,1327 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + + +#include <com/sun/star/util/XChangesNotifier.hpp> + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> + +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <svx/sdr/overlay/overlaypolypolygon.hxx> +#include <svx/svdpagv.hxx> +#include <svx/sdrpagewindow.hxx> +#include <svx/sdrpaintwindow.hxx> +#include <svx/svdopath.hxx> +#include <svx/xlndsit.hxx> +#include <svx/xlnclit.hxx> +#include <svx/xlnstit.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xlnstwit.hxx> +#include <svx/xlnedwit.hxx> +#include <svx/xlnstcit.hxx> +#include <svx/xlnedcit.hxx> +#include <svx/xlntrit.hxx> +#include <svx/svxids.hrc> +#include <svx/polypolygoneditor.hxx> +#include <svx/svddrgmt.hxx> + +#include "CustomAnimationPane.hxx" +#include "View.hxx" +#include "motionpathtag.hxx" +#include "sdpage.hxx" +#include "ViewShell.hxx" +#include "app.hrc" +#include "Window.hxx" + +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> + +using ::rtl::OUString; +using ::sdr::PolyPolygonEditor; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::drawing; + +namespace sd +{ + +const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32; +static const int DRGPIX = 2; // Drag MinMove in Pixel + +// -------------------------------------------------------------------- + +class PathDragMove : public SdrDragMove +{ +private: + basegfx::B2DPolyPolygon maPathPolyPolygon; + +protected: + virtual void createSdrDragEntries(); + +public: + PathDragMove(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag, + const basegfx::B2DPolyPolygon& rPathPolyPolygon) + : SdrDragMove(rNewView), + maPathPolyPolygon(rPathPolyPolygon), + mxTag( xTag ) + {} + + PathDragMove(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag) + : SdrDragMove(rNewView), + maPathPolyPolygon(), + mxTag( xTag ) + {} + + virtual bool BeginSdrDrag(); + virtual bool EndSdrDrag(bool bCopy); + + rtl::Reference <MotionPathTag > mxTag; +}; + +void PathDragMove::createSdrDragEntries() +{ + // call parent + SdrDragMove::createSdrDragEntries(); + + if(maPathPolyPolygon.count()) + { + addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon)); + } +} + +bool PathDragMove::BeginSdrDrag() +{ + if( mxTag.is() ) + { + SdrPathObj* pPathObj = mxTag->getPathObj(); + if( pPathObj ) + { + DragStat().SetActionRect(pPathObj->GetCurrentBoundRect()); + } + } + Show(); + return TRUE; +} + +bool PathDragMove::EndSdrDrag(bool /*bCopy*/) +{ + Hide(); + if( mxTag.is() ) + mxTag->MovePath( DragStat().GetDX(), DragStat().GetDY() ); + return TRUE; +} +// -------------------------------------------------------------------- + +class PathDragResize : public SdrDragResize +{ +private: + basegfx::B2DPolyPolygon maPathPolyPolygon; + +protected: + virtual void createSdrDragEntries(); + +public: + PathDragResize(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag, + const basegfx::B2DPolyPolygon& rPathPolyPolygon) + : SdrDragResize(rNewView), + maPathPolyPolygon(rPathPolyPolygon), + mxTag( xTag ) + {} + + PathDragResize(SdrDragView& rNewView, + const rtl::Reference <MotionPathTag >& xTag) + : SdrDragResize(rNewView), + maPathPolyPolygon(), + mxTag( xTag ) + {} + + virtual bool EndSdrDrag(bool bCopy); + rtl::Reference <MotionPathTag > mxTag; +}; + +void PathDragResize::createSdrDragEntries() +{ + // call parent + SdrDragResize::createSdrDragEntries(); + + if(maPathPolyPolygon.count()) + { + addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon)); + } +} + +bool PathDragResize::EndSdrDrag(bool /*bCopy*/) +{ + Hide(); + if( mxTag.is() ) + { + SdrPathObj* pPathObj = mxTag->getPathObj(); + if( pPathObj ) + { + const Point aRef( DragStat().Ref1() ); + basegfx::B2DHomMatrix aTrans(basegfx::tools::createTranslateB2DHomMatrix(-aRef.X(), -aRef.Y())); + aTrans.scale(double(aXFact), double(aYFact)); + aTrans.translate(aRef.X(), aRef.Y()); + basegfx::B2DPolyPolygon aDragPoly(pPathObj->GetPathPoly()); + aDragPoly.transform(aTrans); + pPathObj->SetPathPoly( aDragPoly ); + } + } + return TRUE; +} + +// -------------------------------------------------------------------- + +class PathDragObjOwn : public SdrDragObjOwn +{ +private: + basegfx::B2DPolyPolygon maPathPolyPolygon; + +protected: + virtual void createSdrDragEntries(); + +public: + PathDragObjOwn(SdrDragView& rNewView, + const basegfx::B2DPolyPolygon& rPathPolyPolygon) + : SdrDragObjOwn(rNewView), + maPathPolyPolygon(rPathPolyPolygon) + {} + + PathDragObjOwn(SdrDragView& rNewView) + : SdrDragObjOwn(rNewView), + maPathPolyPolygon() + {} + + virtual bool EndSdrDrag(bool bCopy); +}; + +void PathDragObjOwn::createSdrDragEntries() +{ + // call parent + SdrDragObjOwn::createSdrDragEntries(); + + if(maPathPolyPolygon.count()) + { + addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon)); + } +} + +bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/) +{ + Hide(); + + SdrObject* pObj = GetDragObj(); + + if(pObj) + { + return pObj->applySpecialDrag(DragStat()); + } + else + { + return false; + } +} + +// -------------------------------------------------------------------- + +class SdPathHdl : public SmartHdl +{ +public: + SdPathHdl( const SmartTagReference& xTag, SdrPathObj* mpPathObj ); + virtual ~SdPathHdl(); + virtual void CreateB2dIAObject(); + virtual BOOL IsFocusHdl() const; + virtual Pointer GetSdrDragPointer() const; + virtual bool isMarkable() const; + +private: + SdrPathObj* mpPathObj; + rtl::Reference< MotionPathTag > mxTag; +}; + +// -------------------------------------------------------------------- + +SdPathHdl::SdPathHdl( const SmartTagReference& xTag, SdrPathObj* pPathObj ) +: SmartHdl( xTag, pPathObj->GetCurrentBoundRect().TopLeft() ) +, mpPathObj( pPathObj ) +, mxTag( dynamic_cast< MotionPathTag* >( xTag.get() ) ) +{ +} + +// -------------------------------------------------------------------- + +SdPathHdl::~SdPathHdl() +{ +} + +// -------------------------------------------------------------------- + +void SdPathHdl::CreateB2dIAObject() +{ + // first throw away old one + GetRidOfIAObject(); + + if(pHdlList) + { + SdrMarkView* pView = pHdlList->GetView(); + + if(pView && !pView->areMarkHandlesHidden()) + { + SdrPageView* pPageView = pView->GetSdrPageView(); + + if(pPageView) + { + for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) + { + const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); + + if(rPageWindow.GetPaintWindow().OutputToWindow()) + { + if(rPageWindow.GetOverlayManager() && mpPathObj) + { + const sdr::contact::ViewContact& rVC = mpPathObj->GetViewContact(); + const drawinglayer::primitive2d::Primitive2DSequence aSequence = rVC.getViewIndependentPrimitive2DSequence(); + sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence); + + rPageWindow.GetOverlayManager()->add(*pNew); + maOverlayGroup.append(*pNew); + } + } + } + } + } + } +} + +// -------------------------------------------------------------------- + +BOOL SdPathHdl::IsFocusHdl() const +{ + return FALSE; +} + +// -------------------------------------------------------------------- + +bool SdPathHdl::isMarkable() const +{ + return false; +} + +// -------------------------------------------------------------------- + +Pointer SdPathHdl::GetSdrDragPointer() const +{ + PointerStyle eStyle = POINTER_NOTALLOWED; + if( mxTag.is() ) + { + if( mxTag->isSelected() ) + { + if( !mxTag->getView().IsFrameDragSingles() && mxTag->getView().IsInsObjPointMode() ) + eStyle = POINTER_CROSS; + else + eStyle = POINTER_MOVE; + } + else + { + eStyle = POINTER_ARROW; + + } + } + return Pointer( eStyle ); +} + +// ==================================================================== + +MotionPathTag::MotionPathTag( CustomAnimationPane& rPane, ::sd::View& rView, const CustomAnimationEffectPtr& pEffect ) +: SmartTag( rView ) +, mrPane( rPane ) +, mpEffect( pEffect ) +, mxOrigin( pEffect->getTargetShape() ) +, msLastPath( pEffect->getPath() ) +, mbInUpdatePath( false ) +{ + mpPathObj = mpEffect->createSdrPathObjFromPath(); + mxPolyPoly = mpPathObj->GetPathPoly(); + maOriginPos = mxOrigin->getPosition(); + + SdrPage* pPage = mrView.GetSdrPageView()->GetPage(); + if( pPage ) + { + mpPathObj->SetPage( pPage ); + mpPathObj->SetObjList( pPage ); + } + + XDash aDash( XDASH_RECT, 1, 80, 1, 80, 80); + String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") ); + mpPathObj->SetMergedItem( XLineDashItem( aEmpty, aDash ) ); + mpPathObj->SetMergedItem( XLineStyleItem( XLINE_DASH ) ); + mpPathObj->SetMergedItem( XLineColorItem(aEmpty, ::Color(COL_GRAY)) ); + mpPathObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) ); + + ::basegfx::B2DPolygon aStartArrow; + aStartArrow.append(::basegfx::B2DPoint(20.0, 0.0)); + aStartArrow.append(::basegfx::B2DPoint(0.0, 0.0)); + aStartArrow.append(::basegfx::B2DPoint(10.0, 30.0)); + aStartArrow.setClosed(true); + mpPathObj->SetMergedItem(XLineStartItem(aEmpty,::basegfx::B2DPolyPolygon(aStartArrow))); + mpPathObj->SetMergedItem(XLineStartWidthItem(400)); + mpPathObj->SetMergedItem(XLineStartCenterItem(TRUE)); + + updatePathAttributes(); + + mpPathObj->SetMergedItem(XLineTransparenceItem(50)); + + mpMark = new SdrMark( mpPathObj, mrView.GetSdrPageView() ); + + mpPathObj->AddListener( *this ); + + Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY ); + if( xNotifier.is() ) + { + Reference< XChangesListener > xListener( this ); + xNotifier->addChangesListener( this ); + } +} + +// -------------------------------------------------------------------- + +MotionPathTag::~MotionPathTag() +{ + DBG_ASSERT( mpPathObj == 0, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" ); + Dispose(); +} + +// -------------------------------------------------------------------- + +void MotionPathTag::updatePathAttributes() +{ + String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") ); + + ::basegfx::B2DPolygon aCandidate; + if( mxPolyPoly.count() ) + { + aCandidate = mxPolyPoly.getB2DPolygon(0); + ::basegfx::tools::checkClosed( aCandidate ); + } + + if( !aCandidate.isClosed() ) + { + ::basegfx::B2DPolygon aEndArrow; + aEndArrow.append(::basegfx::B2DPoint(10.0, 0.0)); + aEndArrow.append(::basegfx::B2DPoint(0.0, 30.0)); + aEndArrow.append(::basegfx::B2DPoint(20.0, 30.0)); + aEndArrow.setClosed(true); + mpPathObj->SetMergedItem(XLineEndItem(aEmpty,::basegfx::B2DPolyPolygon(aEndArrow))); + mpPathObj->SetMergedItem(XLineEndWidthItem(400)); + mpPathObj->SetMergedItem(XLineEndCenterItem(TRUE)); + } + else + { + mpPathObj->SetMergedItem(XLineEndItem()); + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) +{ + if( mpPathObj && !mbInUpdatePath && dynamic_cast< const SdrHint* >( &rHint ) && (mpEffect.get() != 0) ) + { + if( mxPolyPoly != mpPathObj->GetPathPoly() ) + { + mbInUpdatePath = true; + mxPolyPoly = mpPathObj->GetPathPoly(); + rtl::Reference< MotionPathTag > xTag( this ); + mrPane.updatePathFromMotionPathTag( xTag ); + msLastPath = mpEffect->getPath(); + updatePathAttributes(); + mbInUpdatePath = false; + } + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::MovePath( int nDX, int nDY ) +{ + if( mpPathObj ) + { + mpPathObj->Move( Size( nDX, nDY ) ); + mrView.updateHandles(); + } +} + +// -------------------------------------------------------------------- + +/** returns true if the MotionPathTag handled the event. */ +bool MotionPathTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& rHdl ) +{ + if( !mpPathObj ) + return false; + + if( !isSelected() ) + { + SmartTagReference xTag( this ); + mrView.getSmartTags().select( xTag ); + selectionChanged(); + return true; + } + else + { + if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) ) + { + mrView.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT, SFX_CALLMODE_ASYNCHRON); + return true; + } + else if( rMEvt.IsLeft() ) + { + OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow(); + Point aMDPos( pOut->PixelToLogic( rMEvt.GetPosPixel() ) ); + + if( !mrView.IsFrameDragSingles() && mrView.IsInsObjPointMode() && (rHdl.GetObjHdlNum() == SMART_TAG_HDL_NUM) ) + { + // insert a point in edit mode + const bool bNewObj = rMEvt.IsMod1(); + + mrView.BrkAction(); + + Point aPt(aMDPos); // - pMarkedPV->GetOffset()); + + if(bNewObj) + aPt = mrView.GetSnapPos(aPt,mrView.GetSdrPageView()); + + sal_Bool bClosed0(mpPathObj->IsClosedObj()); + + sal_uInt32 nInsPointNum = mpPathObj->NbcInsPointOld(aPt, bNewObj, sal_True); + + if(bClosed0 != mpPathObj->IsClosedObj()) + { + // Obj was closed implicit + // object changed + mpPathObj->SetChanged(); + mpPathObj->BroadcastObjectChange(); + } + + if(0xffffffff != nInsPointNum) + { + mrView.UnmarkAllPoints(); + mrView.updateHandles(); + + bool bRet = mrView.BegDragObj(aMDPos, pOut, mrView.GetHdl(nInsPointNum+1), 0, new PathDragObjOwn( mrView ) ); + + if (bRet) + { + const_cast< SdrDragStat* >( &mrView.GetDragStat() )->SetMinMoved(); + mrView.MovDragObj(aMDPos); + } + } + return true; + } + else + { + SmartHdl* pHdl = &rHdl; + if (!mrView.IsPointMarked(*pHdl) || rMEvt.IsShift()) + { + if (!rMEvt.IsShift()) + { + mrView.UnmarkAllPoints(); + pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) ); + } + else + { + if (mrView.IsPointMarked(*pHdl) ) + { + mrView.UnmarkPoint(*pHdl); + pHdl = NULL; + } + else + { + pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) ); + } + } + + if (pHdl) + mrView.MarkPoint(*pHdl); + } + + + if( pHdl && !rMEvt.IsRight() ) + { + mrView.BrkAction(); + const USHORT nDrgLog = (USHORT)pOut->PixelToLogic(Size(DRGPIX,0)).Width(); + + rtl::Reference< MotionPathTag > xTag( this ); + SdrDragMethod* pDragMethod; + + // #i95646# add DragPoly as geometry to each local SdrDragMethod to be able + // to create the needed local SdrDragEntry for it in createSdrDragEntries() + const basegfx::B2DPolyPolygon aDragPoly(mpPathObj->GetPathPoly()); + + if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) ) + { + pDragMethod = new PathDragMove( mrView, xTag, aDragPoly ); + pHdl->SetPos( aMDPos ); + } + else if( pHdl->GetKind() == HDL_POLY ) + { + pDragMethod = new PathDragObjOwn( mrView, aDragPoly ); + } + else + { + pDragMethod = new PathDragResize( mrView, xTag, aDragPoly ); + } + + mrView.BegDragObj(aMDPos, NULL, pHdl, nDrgLog, pDragMethod ); + } + return true; + } + } + } + + return false; +} + +// -------------------------------------------------------------------- + +/** returns true if the SmartTag consumes this event. */ +bool MotionPathTag::KeyInput( const KeyEvent& rKEvt ) +{ + if( !mpPathObj ) + return false; + + USHORT nCode = rKEvt.GetKeyCode().GetCode(); + switch( nCode ) + { + case KEY_DELETE: + return OnDelete(); + + case KEY_DOWN: + case KEY_UP: + case KEY_LEFT: + case KEY_RIGHT: + return OnMove( rKEvt ); + + case KEY_ESCAPE: + { + SmartTagReference xThis( this ); + mrView.getSmartTags().deselect(); + return true; + } + + case KEY_TAB: + return OnTabHandles( rKEvt ); + + case KEY_SPACE: + return OnMarkHandle( rKEvt ); + + default: + break; + } + return false; +} + +bool MotionPathTag::OnDelete() +{ + mrPane.remove( mpEffect ); + return true; +} + +bool MotionPathTag::OnTabHandles( const KeyEvent& rKEvt ) +{ + if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2()) + { + const SdrHdlList& rHdlList = mrView.GetHdlList(); + sal_Bool bForward(!rKEvt.GetKeyCode().IsShift()); + + ((SdrHdlList&)rHdlList).TravelFocusHdl(bForward); + + // guarantee visibility of focused handle + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl) + { + Window* pWindow = mrView.GetViewShell()->GetActiveWindow(); + if( pWindow ) + { + Point aHdlPosition(pHdl->GetPos()); + Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200)); + mrView.MakeVisible(aVisRect, *pWindow); + } + } + + return true; + } + + return false; +} + +bool MotionPathTag::OnMarkHandle( const KeyEvent& rKEvt ) +{ + const SdrHdlList& rHdlList = mrView.GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl && pHdl->GetKind() == HDL_POLY ) + { + // rescue ID of point with focus + sal_uInt32 nPol(pHdl->GetPolyNum()); + sal_uInt32 nPnt(pHdl->GetPointNum()); + + if(mrView.IsPointMarked(*pHdl)) + { + if(rKEvt.GetKeyCode().IsShift()) + { + mrView.UnmarkPoint(*pHdl); + } + } + else + { + if(!rKEvt.GetKeyCode().IsShift()) + { + mrView.UnmarkAllPoints(); + } + mrView.MarkPoint(*pHdl); + } + + if(0L == rHdlList.GetFocusHdl()) + { + // restore point with focus + SdrHdl* pNewOne = 0L; + + for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++) + { + SdrHdl* pAct = rHdlList.GetHdl(a); + + if(pAct && pAct->GetKind() == HDL_POLY && pAct->GetPolyNum() == nPol && pAct->GetPointNum() == nPnt) + pNewOne = pAct; + } + + if(pNewOne) + ((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne); + } + } + + return true; +} + +bool MotionPathTag::OnMove( const KeyEvent& rKEvt ) +{ + long nX = 0; + long nY = 0; + + switch( rKEvt.GetKeyCode().GetCode() ) + { + case KEY_UP: nY = -1; break; + case KEY_DOWN: nY = 1; break; + case KEY_LEFT: nX = -1; break; + case KEY_RIGHT: nX = 1; break; + default: break; + } + + if(rKEvt.GetKeyCode().IsMod2()) + { + OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow(); + Size aLogicSizeOnePixel = (pOut) ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100); + nX *= aLogicSizeOnePixel.Width(); + nY *= aLogicSizeOnePixel.Height(); + } + else + { + // old, fixed move distance + nX *= 100; + nY *= 100; + } + + if( nX || nY ) + { + // in point edit mode move the handle with the focus + const SdrHdlList& rHdlList = mrView.GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl) + { + // now move the Handle (nX, nY) + Point aStartPoint(pHdl->GetPos()); + Point aEndPoint(pHdl->GetPos() + Point(nX, nY)); + + // start dragging + rtl::Reference< MotionPathTag > xTag( this ); + SdrDragMethod* pDragMethod = 0; + if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) ) + { + pDragMethod = new PathDragMove( mrView, xTag ); + } + else if( pHdl->GetKind() == HDL_POLY ) + { + pDragMethod = new PathDragObjOwn( mrView ); + } + else if( pHdl->GetKind() != HDL_BWGT ) + { + pDragMethod = new PathDragResize( mrView, xTag ); + } + mrView.BegDragObj(aStartPoint, 0, pHdl, 0, pDragMethod); + + if(mrView.IsDragObj()) + { + FASTBOOL bWasNoSnap = mrView.GetDragStat().IsNoSnap(); + BOOL bWasSnapEnabled = mrView.IsSnapEnabled(); + + // switch snapping off + if(!bWasNoSnap) + ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(TRUE); + if(bWasSnapEnabled) + mrView.SetSnapEnabled(FALSE); + + mrView.MovAction(aEndPoint); + mrView.EndDragObj(); + + // restore snap + if(!bWasNoSnap) + ((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(bWasNoSnap); + if(bWasSnapEnabled) + mrView.SetSnapEnabled(bWasSnapEnabled); + } + } + else + { + // move the path + MovePath( nX, nY ); + } + } + + return true; +} + +// -------------------------------------------------------------------- + +ULONG MotionPathTag::GetMarkablePointCount() const +{ + if( mpPathObj && isSelected() ) + { + return mpPathObj->GetPointCount(); + } + else + { + return 0; + } +} + +// -------------------------------------------------------------------- + +ULONG MotionPathTag::GetMarkedPointCount() const +{ + if( mpMark ) + { + const SdrUShortCont* pPts=mpMark->GetMarkedPoints(); + return pPts ? pPts->GetCount() : 0; + } + else + { + return 0; + } +} + +// -------------------------------------------------------------------- + +BOOL MotionPathTag::MarkPoint(SdrHdl& rHdl, BOOL bUnmark ) +{ + BOOL bRet=FALSE; + if( mpPathObj && mrView.IsPointMarkable( rHdl ) && (rHdl.GetKind() != HDL_SMARTTAG) ) + { + SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( &rHdl ); + if( pSmartHdl && pSmartHdl->getTag().get() == this ) + { + SdrUShortCont* pPts=mpMark->ForceMarkedPoints(); + pPts->ForceSort(); + if (mrView.MarkPointHelper(&rHdl,mpMark,bUnmark)) + { + pPts->ForceSort(); + mrView.MarkListHasChanged(); + bRet=TRUE; + } + } + } + return bRet; +} + +// -------------------------------------------------------------------- + +BOOL MotionPathTag::MarkPoints(const Rectangle* pRect, BOOL bUnmark ) +{ + BOOL bChgd=FALSE; + + if( mpPathObj && isSelected() ) + { + sal_Int32 nHdlNum = mrView.GetHdlList().GetHdlCount() - 1; + while( nHdlNum > 0 ) + { + SmartHdl* pHdl = dynamic_cast< SmartHdl* >( mrView.GetHdl( sal::static_int_cast< ULONG >( nHdlNum-- ) ) ); + + if( pHdl && (pHdl->getTag().get() == this) && mrView.IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark) + { + Point aPos(pHdl->GetPos()); + if( pRect==NULL || pRect->IsInside(aPos)) + { + if( mrView.MarkPointHelper(pHdl,mpMark,bUnmark) ) + bChgd=TRUE; + } + } + } + + if(bChgd) + mrView.MarkListHasChanged(); + } + + return bChgd; +} + +// -------------------------------------------------------------------- + +bool MotionPathTag::getContext( SdrViewContext& rContext ) +{ + if( mpPathObj && isSelected() && !mrView.IsFrameDragSingles() ) + { + rContext = SDRCONTEXT_POINTEDIT; + return true; + } + else + { + return false; + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::CheckPossibilities() +{ + if( mpPathObj ) + { + if( isSelected() ) + { + mrView.SetMoveAllowed( true ); + mrView.SetMoveProtected( false ); + mrView.SetResizeFreeAllowed( true ); + mrView.SetResizePropAllowed( true ); + mrView.SetResizeProtected( false ); + + if( !mrView.IsFrameDragSingles() ) + { + bool b1stSmooth(true); + bool b1stSegm(true); + bool bCurve(false); + bool bSmoothFuz(false); + bool bSegmFuz(false); + basegfx::B2VectorContinuity eSmooth = basegfx::CONTINUITY_NONE; + + mrView.CheckPolyPossibilitiesHelper( mpMark, b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth ); + } + } + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::addCustomHandles( SdrHdlList& rHandlerList ) +{ + if( mpPathObj ) + { + ::com::sun::star::awt::Point aPos( mxOrigin->getPosition() ); + if( (aPos.X != maOriginPos.X) || (aPos.Y != maOriginPos.Y) ) + { + const basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( + aPos.X - maOriginPos.X, aPos.Y - maOriginPos.Y)); + mxPolyPoly.transform( aTransform ); + mpPathObj->SetPathPoly( mxPolyPoly ); + maOriginPos = aPos; + } + + SmartTagReference xThis( this ); + SdPathHdl* pHdl = new SdPathHdl( xThis, mpPathObj ); + pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM ); + pHdl->SetPageView( mrView.GetSdrPageView() ); + + + pHdl->SetObj(mpPathObj); + rHandlerList.AddHdl( pHdl ); + + if( isSelected() ) + { + mrView.GetSdrPageView()->SetHasMarkedObj(TRUE); + + if( !mrView.IsFrameDragSingles() ) + { + SdrHdlList aTemp( rHandlerList.GetView() ); + mpPathObj->AddToHdlList( aTemp ); + const SdrUShortCont* pMrkPnts=mpMark->GetMarkedPoints(); + + sal_uInt32 nHandle; + for( nHandle = 0; nHandle < aTemp.GetHdlCount(); ++nHandle ) + { + SdrHdl* pTempHdl = aTemp.GetHdl( nHandle ); + + SmartHdl* pSmartHdl = new SmartHdl( xThis, mpPathObj, pTempHdl->GetPos(), pTempHdl->GetKind() ); + pSmartHdl->SetObjHdlNum( nHandle ); + pSmartHdl->SetPolyNum( pTempHdl->GetPolyNum() ); + pSmartHdl->SetPointNum( pTempHdl->GetPointNum() ); + pSmartHdl->SetPlusHdl( pTempHdl->IsPlusHdl() ); + pSmartHdl->SetSourceHdlNum( pTempHdl->GetSourceHdlNum() ); + pSmartHdl->SetPageView( mrView.GetSdrPageView() ); + + rHandlerList.AddHdl( pSmartHdl ); + + const bool bSelected= pMrkPnts && pMrkPnts->Exist(sal::static_int_cast< USHORT >(nHandle)); + pSmartHdl->SetSelected(bSelected); + + if( mrView.IsPlusHandlesAlwaysVisible() || bSelected ) + { + sal_uInt32 nPlusAnz=mpPathObj->GetPlusHdlCount(*pSmartHdl); + for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++) + { + SdrHdl* pPlusHdl = mpPathObj->GetPlusHdl(*pSmartHdl,nPlusNum); + if (pPlusHdl!=NULL) + { + pPlusHdl->SetObj(mpPathObj); + pPlusHdl->SetPageView(mrView.GetSdrPageView()); + pPlusHdl->SetPlusHdl(TRUE); + rHandlerList.AddHdl(pPlusHdl); + } + } + } + } + } + else + { + Rectangle aRect(mpPathObj->GetCurrentBoundRect()); + + if(!aRect.IsEmpty()) + { + ULONG nCount = rHandlerList.GetHdlCount(); + + BOOL bWdt0=aRect.Left()==aRect.Right(); + BOOL bHgt0=aRect.Top()==aRect.Bottom(); + if (bWdt0 && bHgt0) + { + rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft(),HDL_UPLFT)); + } + else if (bWdt0 || bHgt0) + { + rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft() ,HDL_UPLFT)); + rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight(),HDL_LWRGT)); + } + else + { + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft() ,HDL_UPLFT)); + if ( !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopCenter() ,HDL_UPPER)); + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopRight() ,HDL_UPRGT)); + if (!bWdt0 ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.LeftCenter() ,HDL_LEFT )); + if (!bWdt0 ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.RightCenter() ,HDL_RIGHT)); + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomLeft() ,HDL_LWLFT)); + if ( !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomCenter(),HDL_LOWER)); + if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight() ,HDL_LWRGT)); + } + + while( nCount < rHandlerList.GetHdlCount() ) + { + rHandlerList.GetHdl(nCount++)->SetPageView( mrView.GetSdrPageView() ); + } + } + } + } + } +} + +// -------------------------------------------------------------------- + +void MotionPathTag::disposing() +{ + Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY ); + if( xNotifier.is() ) + { + Reference< XChangesListener > xListener( this ); + xNotifier->removeChangesListener( this ); + } + + if( mpPathObj ) + { + SdrPathObj* pPathObj = mpPathObj; + mpPathObj = 0; + mrView.updateHandles(); + delete pPathObj; + } + + if( mpMark ) + { + delete mpMark; + mpMark = 0; + } + + SmartTag::disposing(); +} + +// -------------------------------------------------------------------- + +void MotionPathTag::deselect() +{ + SmartTag::deselect(); + + if( mpMark ) + { + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + + if( pPts ) + pPts->Clear(); + } + + selectionChanged(); +} + +void MotionPathTag::selectionChanged() +{ + if( mrView.GetViewShell() && mrView.GetViewShell()->GetViewFrame() ) + { + SfxBindings& rBindings = mrView.GetViewShell()->GetViewFrame()->GetBindings(); + rBindings.InvalidateAll(TRUE); + } +} +// -------------------------------------------------------------------- +// IPolyPolygonEditorController +// -------------------------------------------------------------------- + +void MotionPathTag::DeleteMarkedPoints() +{ + if( mpPathObj && IsDeleteMarkedPointsPossible() ) + { + mrView.BrkAction(); + + // Description +// BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_DELETE); + + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + + if( pPts ) + { + PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() ); + if( aEditor.DeletePoints( pPts->getContainer() ) ) + { + if( aEditor.GetPolyPolygon().count() ) + { +// AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath )); + mpPathObj->SetPathPoly( aEditor.GetPolyPolygon() ); + } + else + { +// AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pPath ) ); +// pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum()); + } + + mrView.UnmarkAllPoints(); + mrView.MarkListHasChanged(); + mrView.updateHandles(); + } + } + +// EndUndo(); + } +} + +BOOL MotionPathTag::IsDeleteMarkedPointsPossible() const +{ + return mpPathObj && isSelected() && (GetMarkedPointCount() != 0); +} + +void MotionPathTag::RipUpAtMarkedPoints() +{ + // not supported for motion path +} + +bool MotionPathTag::IsRipUpAtMarkedPointsPossible() const +{ + // not supported for motion path + return false; +} + +BOOL MotionPathTag::IsSetMarkedSegmentsKindPossible() const +{ + if( mpPathObj ) + return mrView.IsSetMarkedSegmentsKindPossible(); + else + return FALSE; +} + +SdrPathSegmentKind MotionPathTag::GetMarkedSegmentsKind() const +{ + if( mpPathObj ) + return mrView.GetMarkedSegmentsKind(); + else + return SDRPATHSEGMENT_LINE; +} + +void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind) +{ + if(mpPathObj && isSelected() && (GetMarkedPointCount() != 0)) + { + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + if(pPts) + { + PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() ); + if(aEditor.SetSegmentsKind( eKind, pPts->getContainer()) ) + { +// AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath)); + mpPathObj->SetPathPoly(aEditor.GetPolyPolygon()); + mrView.MarkListHasChanged(); + mrView.updateHandles(); + } + } + } +} + +BOOL MotionPathTag::IsSetMarkedPointsSmoothPossible() const +{ + if( mpPathObj ) + return mrView.IsSetMarkedPointsSmoothPossible(); + else + return FALSE; +} + +SdrPathSmoothKind MotionPathTag::GetMarkedPointsSmooth() const +{ + if( mpPathObj ) + return mrView.GetMarkedPointsSmooth(); + else + return SDRPATHSMOOTH_ANGULAR; +} + +void MotionPathTag::SetMarkedPointsSmooth(SdrPathSmoothKind eKind) +{ + basegfx::B2VectorContinuity eFlags; + + if(SDRPATHSMOOTH_ANGULAR == eKind) + { + eFlags = basegfx::CONTINUITY_NONE; + } + else if(SDRPATHSMOOTH_ASYMMETRIC == eKind) + { + eFlags = basegfx::CONTINUITY_C1; + } + else if(SDRPATHSMOOTH_SYMMETRIC == eKind) + { + eFlags = basegfx::CONTINUITY_C2; + } + else + { + return; + } + + if(mpPathObj && mpMark && isSelected() && (GetMarkedPointCount() != 0)) + { + SdrUShortCont* pPts = mpMark->GetMarkedPoints(); + if(pPts) + { + PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() ); + if(aEditor.SetPointsSmooth( eFlags, pPts->getContainer() ) ) + { +// AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath)); + mpPathObj->SetPathPoly(aEditor.GetPolyPolygon()); + mrView.MarkListHasChanged(); + mrView.updateHandles(); + } + } + } +} + +void MotionPathTag::CloseMarkedObjects(BOOL /*bToggle*/, BOOL /*bOpen*/ ) +{ + // not supported for motion path +} + +bool MotionPathTag::IsOpenCloseMarkedObjectsPossible() const +{ + // not supported for motion path + return false; +} + +SdrObjClosedKind MotionPathTag::GetMarkedObjectsClosedState() const +{ + // not supported for motion path + return SDROBJCLOSED_OPEN; +} + +// XChangesListener +void SAL_CALL MotionPathTag::changesOccurred( const ChangesEvent& /*Event*/ ) throw (RuntimeException) +{ + if( mpPathObj && !mbInUpdatePath && (mpEffect->getPath() != msLastPath) ) + { + mbInUpdatePath =true; + msLastPath = mpEffect->getPath(); + mpEffect->updateSdrPathObjFromPath( *mpPathObj ); + mbInUpdatePath = false; + updatePathAttributes(); + mrView.updateHandles(); + } +} + +void SAL_CALL MotionPathTag::disposing( const EventObject& /*Source*/ ) throw (RuntimeException) +{ + if( mpPathObj ) + Dispose(); +} + +Any SAL_CALL MotionPathTag::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (RuntimeException) +{ + if( aType == XChangesListener::static_type() ) + return Any( Reference< XChangesListener >( this ) ); + if( aType == XEventListener::static_type() ) + return Any( Reference< XEventListener >( this ) ); + if( aType == XInterface::static_type() ) + return Any( Reference< XInterface >( this ) ); + + return Any(); +} + +void SAL_CALL MotionPathTag::acquire() throw () +{ + SimpleReferenceComponent::acquire(); +} + +void SAL_CALL MotionPathTag::release( ) throw () +{ + SimpleReferenceComponent::release(); +} + +} // end of namespace sd + |