/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: svdsnpv.cxx,v $ * $Revision: 1.14 $ * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" #include #include #include #include #include #include #include "svditer.hxx" #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////////////////////////// // #114409#-1 Migrate PageOrigin class ImplPageOriginOverlay { // The OverlayObjects ::sdr::overlay::OverlayObjectList maObjects; // The current position in logical coodinates basegfx::B2DPoint maPosition; public: ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos); ~ImplPageOriginOverlay(); void SetPosition(const basegfx::B2DPoint& rNewPosition); }; ImplPageOriginOverlay::ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos) : maPosition(rStartPos) { for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++) { SdrPaintWindow* pCandidate = rView.GetPaintWindow(a); ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager(); if(pTargetOverlay) { ::sdr::overlay::OverlayCrosshairStriped* aNew = new ::sdr::overlay::OverlayCrosshairStriped( maPosition); pTargetOverlay->add(*aNew); maObjects.append(*aNew); } } } ImplPageOriginOverlay::~ImplPageOriginOverlay() { // The OverlayObjects are cleared using the destructor of OverlayObjectList. // That destructor calls clear() at the list which removes all objects from the // OverlayManager and deletes them. } void ImplPageOriginOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition) { if(rNewPosition != maPosition) { // apply to OverlayObjects basegfx::B2DHomMatrix aMatrix; aMatrix.translate( rNewPosition.getX() - maPosition.getX(), rNewPosition.getY() - maPosition.getY()); maObjects.transform(aMatrix); // remember new position maPosition = rNewPosition; } } //////////////////////////////////////////////////////////////////////////////////////////////////// // #114409#-2 Migrate HelpLine class ImplHelpLineOverlay { // The OverlayObjects ::sdr::overlay::OverlayObjectList maObjects; // The current position in logical coodinates basegfx::B2DPoint maPosition; // HelpLine specific stuff SdrPageView* mpPageView; sal_uInt16 mnHelpLineNumber; SdrHelpLineKind meHelpLineKind; public: ImplHelpLineOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind); ~ImplHelpLineOverlay(); void SetPosition(const basegfx::B2DPoint& rNewPosition); // access to HelpLine specific stuff SdrPageView* GetPageView() const { return mpPageView; } sal_uInt16 GetHelpLineNumber() const { return mnHelpLineNumber; } SdrHelpLineKind GetHelpLineKind() const { return meHelpLineKind; } }; ImplHelpLineOverlay::ImplHelpLineOverlay( const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind) : maPosition(rStartPos), mpPageView(pPageView), mnHelpLineNumber(nHelpLineNumber), meHelpLineKind(eKind) { for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++) { SdrPaintWindow* pCandidate = rView.GetPaintWindow(a); ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager(); if(pTargetOverlay) { ::sdr::overlay::OverlayHelplineStriped* aNew = new ::sdr::overlay::OverlayHelplineStriped( maPosition, meHelpLineKind); pTargetOverlay->add(*aNew); maObjects.append(*aNew); } } } ImplHelpLineOverlay::~ImplHelpLineOverlay() { // The OverlayObjects are cleared using the destructor of OverlayObjectList. // That destructor calls clear() at the list which removes all objects from the // OverlayManager and deletes them. } void ImplHelpLineOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition) { if(rNewPosition != maPosition) { // apply to OverlayObjects basegfx::B2DHomMatrix aMatrix; aMatrix.translate( rNewPosition.getX() - maPosition.getX(), rNewPosition.getY() - maPosition.getY()); maObjects.transform(aMatrix); // remember new position maPosition = rNewPosition; } } //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // // @@@@ @@ @@ @@@@ @@@@@ @@ @@ @@ @@@@@ @@ @@ // @@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ // @@ @@@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@ // @@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@ @@@@ @@@@@@@ // @@ @@ @@@ @@ @@ @@ @@@ @@ @@ @@@@@@@ // @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@ // @@@@ @@ @@ @@ @@ @@ @ @@ @@@@@ @@ @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// void SdrSnapView::ClearVars() { nMagnSizPix=4; bSnapEnab=TRUE; bGridSnap=TRUE; bSnapTo1Pix=TRUE; bBordSnap=TRUE; bHlplSnap=TRUE; bOFrmSnap=TRUE; bOPntSnap=FALSE; bOConSnap=TRUE; bMoveMFrmSnap=TRUE; bMoveOFrmSnap=TRUE; bMoveOPntSnap=TRUE; bMoveOConSnap=TRUE; bMoveSnapOnlyTopLeft=FALSE; bOrtho=FALSE; bBigOrtho=TRUE; nSnapAngle=1500; bAngleSnapEnab=FALSE; bMoveOnlyDragging=FALSE; bSlantButShear=FALSE; bCrookNoContortion=FALSE; eCrookMode=SDRCROOK_ROTATE; bHlplFixed=FALSE; bEliminatePolyPoints=FALSE; nEliminatePolyPointLimitAngle=0; // #114409#-1 Migrate PageOrigin BrkSetPageOrg(); // #114409#-2 Migrate HelpLine BrkDragHelpLine(); } SdrSnapView::SdrSnapView(SdrModel* pModel1, OutputDevice* pOut): SdrPaintView(pModel1,pOut), // #114409#-1 Migrate PageOrigin mpPageOriginOverlay(0L), // #114409#-2 Migrate HelpLine mpHelpLineOverlay(0L) { ClearVars(); } // #114409#-1 Migrate PageOrigin SdrSnapView::~SdrSnapView() { // #114409#-1 Migrate PageOrigin BrkSetPageOrg(); // #114409#-2 Migrate HelpLine BrkDragHelpLine(); } //////////////////////////////////////////////////////////////////////////////////////////////////// BOOL SdrSnapView::IsAction() const { return IsSetPageOrg() || IsDragHelpLine() || SdrPaintView::IsAction(); } void SdrSnapView::MovAction(const Point& rPnt) { SdrPaintView::MovAction(rPnt); if (IsSetPageOrg()) { MovSetPageOrg(rPnt); } if (IsDragHelpLine()) { MovDragHelpLine(rPnt); } } void SdrSnapView::EndAction() { if (IsSetPageOrg()) { EndSetPageOrg(); } if (IsDragHelpLine()) { EndDragHelpLine(); } SdrPaintView::EndAction(); } void SdrSnapView::BckAction() { BrkSetPageOrg(); BrkDragHelpLine(); SdrPaintView::BckAction(); } void SdrSnapView::BrkAction() { BrkSetPageOrg(); BrkDragHelpLine(); SdrPaintView::BrkAction(); } void SdrSnapView::TakeActionRect(Rectangle& rRect) const { if (IsSetPageOrg() || IsDragHelpLine()) { rRect=Rectangle(aDragStat.GetNow(),aDragStat.GetNow()); } else { SdrPaintView::TakeActionRect(rRect); } } //////////////////////////////////////////////////////////////////////////////////////////////////// Point SdrSnapView::GetSnapPos(const Point& rPnt, const SdrPageView* pPV) const { Point aPt(rPnt); SnapPos(aPt,pPV); return aPt; } #define NOT_SNAPPED 0x7FFFFFFF USHORT SdrSnapView::SnapPos(Point& rPnt, const SdrPageView* pPV) const { if (!bSnapEnab) return SDRSNAP_NOTSNAPPED; BOOL bPVOfs=FALSE; long x=rPnt.X(); long y=rPnt.Y(); if (pPV==NULL) { bPVOfs=TRUE; pPV=GetSdrPageView(); if (pPV==NULL) return SDRSNAP_NOTSNAPPED; } long dx=NOT_SNAPPED; long dy=NOT_SNAPPED; long dx1,dy1; long mx=aMagnSiz.Width(); long my=aMagnSiz.Height(); if (bHlplVisible && bHlplSnap && !IsDragHelpLine()) { const SdrHelpLineList& rHLL=pPV->GetHelpLines(); USHORT nAnz=rHLL.GetCount(); for (USHORT i=nAnz; i>0;) { i--; const SdrHelpLine& rHL=rHLL[i]; const Point& rPos=rHL.GetPos(); switch (rHL.GetKind()) { case SDRHELPLINE_VERTICAL: { long a=x-rPos.X(); if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)GetPage(); long xs=pPage->GetWdt(); long ys=pPage->GetHgt(); long lft=pPage->GetLftBorder(); long rgt=pPage->GetRgtBorder(); long upp=pPage->GetUppBorder(); long lwr=pPage->GetLwrBorder(); long a; a=x- lft ; if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)GetPage(),/*IM_FLAT*/IM_DEEPNOGROUPS,TRUE); while (aIter.IsMore() && (nMaxPointSnapCount>0 || nMaxFrameSnapCount>0)) { SdrObject* pO=aIter.Next(); Rectangle aRect(pO->GetCurrentBoundRect()); aRect.Left ()-=mx; aRect.Right ()+=mx; aRect.Top ()-=my; aRect.Bottom()+=my; if (aRect.IsInside(rPnt)) { if (bOPntSnap && nMaxPointSnapCount>0) { sal_uInt32 nAnz(pO->GetSnapPointCount()); for (sal_uInt32 i(0L); i < nAnz && nMaxPointSnapCount > 0L; i++) { Point aP(pO->GetSnapPoint(i)); dx1=x-aP.X(); dy1=y-aP.Y(); if (Abs(dx1)<=mx && Abs(dy1)<=my && Abs(dx1)0) { Rectangle aLog(pO->GetSnapRect()); Rectangle aR1(aLog); aR1.Left ()-=mx; aR1.Right ()+=mx; aR1.Top ()-=my; aR1.Bottom()+=my; if (aR1.IsInside(rPnt)) { if (Abs(x-aLog.Left ())<=mx) { dx1=-(x-aLog.Left ()); if (Abs(dx1)GetPageOrigin().X() >= 0.0) fx += fSnapWidth / 2.0; else fx -= fSnapWidth / 2.0; x = (long)((fx - (double)pPV->GetPageOrigin().X()) / fSnapWidth); x = (long)((double)x * fSnapWidth + (double)pPV->GetPageOrigin().X()); dx = 0; } fSnapWidth = aSnapWdtY; if(dy == NOT_SNAPPED && fSnapWidth) { double fy = (double)y; // round statt trunc if(fy - (double)pPV->GetPageOrigin().Y() >= 0.0) fy += fSnapWidth / 2.0; else fy -= fSnapWidth / 2.0; y = (long)((fy - (double)pPV->GetPageOrigin().Y()) / fSnapWidth); y = (long)((double)y * fSnapWidth + (double)pPV->GetPageOrigin().Y()); dy = 0; } } BOOL bRet=SDRSNAP_NOTSNAPPED; if (dx==NOT_SNAPPED) dx=0; else bRet|=SDRSNAP_XSNAPPED; if (dy==NOT_SNAPPED) dy=0; else bRet|=SDRSNAP_YSNAPPED; rPnt.X()=x+dx; rPnt.Y()=y+dy; return bRet; } void SdrSnapView::CheckSnap(const Point& rPt, const SdrPageView* pPV, long& nBestXSnap, long& nBestYSnap, bool& bXSnapped, bool& bYSnapped) const { Point aPt(rPt); USHORT nRet=SnapPos(aPt,pPV); aPt-=rPt; if ((nRet & SDRSNAP_XSNAPPED) !=0) { if (bXSnapped) { if (Abs(aPt.X())SetPosition(aNewPos); } } sal_Bool SdrSnapView::EndSetPageOrg() { sal_Bool bRet(sal_False); if(IsSetPageOrg()) { SdrPageView* pPV = GetSdrPageView(); if(pPV) { Point aPnt(aDragStat.GetNow()); pPV->SetPageOrigin(aPnt); bRet = sal_True; } // cleanup BrkSetPageOrg(); } return bRet; } void SdrSnapView::BrkSetPageOrg() { if(IsSetPageOrg()) { DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)"); delete mpPageOriginOverlay; mpPageOriginOverlay = 0L; } } //////////////////////////////////////////////////////////////////////////////////////////////////// sal_Bool SdrSnapView::PickHelpLine(const Point& rPnt, short nTol, const OutputDevice& rOut, USHORT& rnHelpLineNum, SdrPageView*& rpPV) const { rpPV=NULL; nTol=ImpGetHitTolLogic(nTol,&rOut); SdrPageView* pPV = GetSdrPageView(); if(pPV) { Point aPnt(rPnt); USHORT nIndex=pPV->GetHelpLines().HitTest(aPnt,USHORT(nTol),rOut); if (nIndex!=SDRHELPLINE_NOTFOUND) { rpPV=pPV; rnHelpLineNum=nIndex; return sal_True; } } return sal_False; } // start HelpLine drag for new HelpLine sal_Bool SdrSnapView::BegDragHelpLine(USHORT nHelpLineNum, SdrPageView* pPV) { sal_Bool bRet(sal_False); if(!bHlplFixed) { BrkAction(); if(pPV && nHelpLineNum < pPV->GetHelpLines().GetCount()) { const SdrHelpLineList& rHelpLines = pPV->GetHelpLines(); const SdrHelpLine& rHelpLine = rHelpLines[nHelpLineNum]; Point aHelpLinePos = rHelpLine.GetPos(); // + pPV->GetOffset(); basegfx::B2DPoint aStartPos(aHelpLinePos.X(), aHelpLinePos.Y()); DBG_ASSERT(0L == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists a ImplHelpLineOverlay (!)"); mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, pPV, nHelpLineNum, rHelpLine.GetKind()); aDragStat.Reset(GetSnapPos(aHelpLinePos, pPV)); aDragStat.SetMinMove(ImpGetMinMovLogic(-3, 0L)); bRet = sal_True; } } return bRet; } // start HelpLine drag with existing HelpLine sal_Bool SdrSnapView::BegDragHelpLine(const Point& rPnt, SdrHelpLineKind eNewKind) { sal_Bool bRet(sal_False); BrkAction(); if(GetSdrPageView()) { DBG_ASSERT(0L == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists a ImplHelpLineOverlay (!)"); basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y()); mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, 0L, 0, eNewKind); aDragStat.Reset(GetSnapPos(rPnt, 0L)); bRet = sal_True; } return bRet; } Pointer SdrSnapView::GetDraggedHelpLinePointer() const { if(IsDragHelpLine()) { switch(mpHelpLineOverlay->GetHelpLineKind()) { case SDRHELPLINE_VERTICAL : return Pointer(POINTER_ESIZE); case SDRHELPLINE_HORIZONTAL: return Pointer(POINTER_SSIZE); default : return Pointer(POINTER_MOVE); } } return Pointer(POINTER_MOVE); } void SdrSnapView::MovDragHelpLine(const Point& rPnt) { if(IsDragHelpLine() && aDragStat.CheckMinMoved(rPnt)) { Point aPnt(GetSnapPos(rPnt, 0L)); if(aPnt != aDragStat.GetNow()) { aDragStat.NextMove(aPnt); DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::MovDragHelpLine: no ImplHelpLineOverlay (!)"); basegfx::B2DPoint aNewPos(aDragStat.GetNow().X(), aDragStat.GetNow().Y()); mpHelpLineOverlay->SetPosition(aNewPos); } } } sal_Bool SdrSnapView::EndDragHelpLine() { sal_Bool bRet(sal_False); if(IsDragHelpLine()) { if(aDragStat.IsMinMoved()) { SdrPageView* pPageView = mpHelpLineOverlay->GetPageView(); if(pPageView) { // moved existing one Point aPnt(aDragStat.GetNow()); const SdrHelpLineList& rHelpLines = pPageView->GetHelpLines(); SdrHelpLine aChangedHelpLine = rHelpLines[mpHelpLineOverlay->GetHelpLineNumber()]; aChangedHelpLine.SetPos(aPnt); pPageView->SetHelpLine(mpHelpLineOverlay->GetHelpLineNumber(), aChangedHelpLine); bRet = sal_True; } else { // create new one pPageView = GetSdrPageView(); if(pPageView) { Point aPnt(aDragStat.GetNow()); SdrHelpLine aNewHelpLine(mpHelpLineOverlay->GetHelpLineKind(), aPnt); pPageView->InsertHelpLine(aNewHelpLine); bRet = sal_True; } } } // cleanup BrkDragHelpLine(); } return bRet; } void SdrSnapView::BrkDragHelpLine() { if(IsDragHelpLine()) { DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::EndDragHelpLine: no ImplHelpLineOverlay (!)"); delete mpHelpLineOverlay; mpHelpLineOverlay = 0L; } } // eof