/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <svx/svddrgv.hxx>
#include <svx/svdview.hxx>
#include <svx/xattr.hxx>
#include <svx/xpoly.hxx>
#include <svx/svdetc.hxx>
#include <svx/svdtrans.hxx>
#include <svx/svdundo.hxx>
#include <svx/svdocapt.hxx>
#include <svx/svdpagv.hxx>
#include <svx/svdopath.hxx>
#include <svx/svdoedge.hxx>
#include <svx/strings.hrc>
#include <svx/dialmgr.hxx>
#include "svddrgm1.hxx"
#include <svx/obj3d.hxx>
#include <svx/svdoashp.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <svx/polypolygoneditor.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
using namespace sdr;
// DragView
void SdrDragView::ImpClearVars()
{
mbFramDrag=false;
meDragMode=SdrDragMode::Move;
mbDragLimit=false;
mbMarkedHitMovesAlways=false;
meDragHdl=SdrHdlKind::Move;
mpDragHdl=nullptr;
mbDragHdl=false;
mpCurrentSdrDragMethod=nullptr;
mbDragStripes=false;
mbDragWithCopy=false;
mpInsPointUndo=nullptr;
mbInsGluePoint=false;
mbInsObjPointMode=false;
mbInsGluePointMode=false;
mbNoDragXorPolys=false;
mbResizeAtCenter=false;
mbCrookAtCenter=false;
// init using default
mbSolidDragging = getOptionsDrawinglayer().IsSolidDragCreate();
}
SdrDragView::SdrDragView(
SdrModel& rSdrModel,
OutputDevice* pOut)
: SdrExchangeView(rSdrModel, pOut)
{
ImpClearVars();
}
SdrDragView::~SdrDragView()
{
}
bool SdrDragView::IsAction() const
{
return (mpCurrentSdrDragMethod || SdrExchangeView::IsAction());
}
void SdrDragView::MovAction(const Point& rPnt)
{
SdrExchangeView::MovAction(rPnt);
if (mpCurrentSdrDragMethod)
{
MovDragObj(rPnt);
}
}
void SdrDragView::EndAction()
{
if (mpCurrentSdrDragMethod)
{
EndDragObj();
}
SdrExchangeView::EndAction();
}
void SdrDragView::BckAction()
{
SdrExchangeView::BckAction();
BrkDragObj();
}
void SdrDragView::BrkAction()
{
SdrExchangeView::BrkAction();
BrkDragObj();
}
void SdrDragView::TakeActionRect(tools::Rectangle& rRect) const
{
if (mpCurrentSdrDragMethod)
{
rRect=maDragStat.GetActionRect();
if (rRect.IsEmpty())
{
SdrPageView* pPV = GetSdrPageView();
if(pPV&& pPV->HasMarkedObjPageView())
{
// #i95646# is this used..?
const basegfx::B2DRange aBoundRange(mpCurrentSdrDragMethod->getCurrentRange());
if (aBoundRange.isEmpty())
{
rRect.SetEmpty();
}
else
{
rRect = tools::Rectangle(
basegfx::fround(aBoundRange.getMinX()), basegfx::fround(aBoundRange.getMinY()),
basegfx::fround(aBoundRange.getMaxX()), basegfx::fround(aBoundRange.getMaxY()));
}
}
}
if (rRect.IsEmpty())
{
rRect=tools::Rectangle(maDragStat.GetNow(),maDragStat.GetNow());
}
}
else
{
SdrExchangeView::TakeActionRect(rRect);
}
}
bool SdrDragView::TakeDragObjAnchorPos(Point& rPos, bool bTR ) const
{
tools::Rectangle aR;
TakeActionRect(aR);
rPos = bTR ? aR.TopRight() : aR.TopLeft();
if (GetMarkedObjectCount()==1 && IsDragObj() && // only on single selection
!IsDraggingPoints() && !IsDraggingGluePoints() && // not when moving points
dynamic_cast<const SdrDragMovHdl*>( mpCurrentSdrDragMethod.get() ) == nullptr) // not when moving handles
{
SdrObject* pObj=GetMarkedObjectByIndex(0);
if (dynamic_cast<const SdrCaptionObj*>( pObj) != nullptr)
{
Point aPt(static_cast<SdrCaptionObj*>(pObj)->GetTailPos());
bool bTail=meDragHdl==SdrHdlKind::Poly; // drag tail
bool bOwn=dynamic_cast<const SdrDragObjOwn*>( mpCurrentSdrDragMethod.get() ) != nullptr; // specific to object
if (!bTail)
{ // for bTail, TakeActionRect already does the right thing
if (bOwn)
{ // bOwn may be MoveTextFrame, ResizeTextFrame, but may not (any more) be DragTail
rPos=aPt;
}
else
{
// drag the whole Object (Move, Resize, ...)
const basegfx::B2DPoint aTransformed(mpCurrentSdrDragMethod->getCurrentTransformation() * basegfx::B2DPoint(aPt.X(), aPt.Y()));
rPos.setX( basegfx::fround(aTransformed.getX()) );
rPos.setY( basegfx::fround(aTransformed.getY()) );
}
}
}
return true;
}
return false;
}
bool SdrDragView::TakeDragLimit(SdrDragMode /*eMode*/, tools::Rectangle& /*rRect*/) const
{
return false;
}
bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl, short nMinMov, SdrDragMethod* _pForcedMeth)
{
BrkAction();
// so we don't leak the object on early return
std::unique_ptr<SdrDragMethod> pForcedMeth(_pForcedMeth);
bool bRet=false;
{
SetDragWithCopy(false);
//TODO: aAni.Reset();
mpCurrentSdrDragMethod=nullptr;
mbDragLimit=false;
SdrDragMode eTmpMode=meDragMode;
if (eTmpMode==SdrDragMode::Move && pHdl!=nullptr && pHdl->GetKind()!=SdrHdlKind::Move) {
eTmpMode=SdrDragMode::Resize;
}
mbDragLimit=TakeDragLimit(eTmpMode,maDragLimit);
mbFramDrag=ImpIsFrameHandles();
if (!mbFramDrag &&
(mpMarkedObj==nullptr || !mpMarkedObj->hasSpecialDrag()) &&
(pHdl==nullptr || pHdl->GetObj()==nullptr)) {
mbFramDrag=true;
}
Point aPnt(rPnt);
if(pHdl == nullptr
|| pHdl->GetKind() == SdrHdlKind::Move
|| pHdl->GetKind() == SdrHdlKind::MirrorAxis
|| pHdl->GetKind() == SdrHdlKind::Transparence
|| pHdl->GetKind() == SdrHdlKind::Gradient)
{
maDragStat.Reset(aPnt);
}
else
{
maDragStat.Reset(pHdl->GetPos());
}
maDragStat.SetView(static_cast<SdrView*>(this));
maDragStat.SetPageView(mpMarkedPV); // <<-- DragPV has to go here!!!
maDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut));
maDragStat.SetHdl(pHdl);
maDragStat.NextPoint();
mpDragWin=pOut;
mpDragHdl=pHdl;
meDragHdl= pHdl==nullptr ? SdrHdlKind::Move : pHdl->GetKind();
mbDragHdl=meDragHdl==SdrHdlKind::Ref1 || meDragHdl==SdrHdlKind::Ref2 || meDragHdl==SdrHdlKind::MirrorAxis;
// Expand test for SdrHdlKind::Anchor_TR
bool bNotDraggable = (SdrHdlKind::Anchor == meDragHdl || SdrHdlKind::Anchor_TR == meDragHdl);
if(pHdl && (pHdl->GetKind() == SdrHdlKind::SmartTag) && pForcedMeth )
{
// just use the forced method for smart tags
}
else if(mbDragHdl)
{
mpCurrentSdrDragMethod.reset(new SdrDragMovHdl(*this));
}
else if(!bNotDraggable)
{
switch (meDragMode)
{
case SdrDragMode::Rotate: case SdrDragMode::Shear:
{
switch (meDragHdl)
{
case SdrHdlKind::Left: case SdrHdlKind::Right:
case SdrHdlKind::Upper: case SdrHdlKind::Lower:
{
// are 3D objects selected?
bool b3DObjSelected = false;
for(size_t a=0; !b3DObjSelected && a<GetMarkedObjectCount(); ++a)
{
SdrObject* pObj = GetMarkedObjectByIndex(a);
if(dynamic_cast< const E3dObject* >(pObj))
b3DObjSelected = true;
}
// If yes, allow shear even when !IsShearAllowed,
// because 3D objects are limited rotations
if (!b3DObjSelected && !IsShearAllowed())
return false;
mpCurrentSdrDragMethod.reset(new SdrDragShear(*this,meDragMode==SdrDragMode::Rotate));
} break;
case SdrHdlKind::UpperLeft: case SdrHdlKind::UpperRight:
case SdrHdlKind::LowerLeft: case SdrHdlKind::LowerRight:
{
if (meDragMode==SdrDragMode::Shear)
{
if (!IsDistortAllowed(true) && !IsDistortAllowed()) return false;
mpCurrentSdrDragMethod.reset(new SdrDragDistort(*this));
}
else
{
if (!IsRotateAllowed(true)) return false;
mpCurrentSdrDragMethod.reset(new SdrDragRotate(*this));
}
} break;
default:
{
if (IsMarkedHitMovesAlways() && meDragHdl==SdrHdlKind::Move)
{ // SdrHdlKind::Move is true, even if Obj is hit directly
if (!IsMoveAllowed()) return false;
mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
}
else
{
if (!IsRotateAllowed(true)) return false;
mpCurrentSdrDragMethod.reset(new SdrDragRotate(*this));
}
}
}
} break;
case SdrDragMode::Mirror:
{
if (meDragHdl==SdrHdlKind::Move && IsMarkedHitMovesAlways())
{
if (!IsMoveAllowed()) return false;
mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
}
else
{
if (!IsMirrorAllowed(true,true)) return false;
mpCurrentSdrDragMethod.reset(new SdrDragMirror(*this));
}
} break;
case SdrDragMode::Crop:
{
if (meDragHdl==SdrHdlKind::Move && IsMarkedHitMovesAlways())
{
if (!IsMoveAllowed())
return false;
mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
}
else
{
if (!IsCropAllowed())
return false;
mpCurrentSdrDragMethod.reset(new SdrDragCrop(*this));
}
}
break;
case SdrDragMode::Transparence:
{
if(meDragHdl == SdrHdlKind::Move && IsMarkedHitMovesAlways())
{
if(!IsMoveAllowed())
return false;
mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
}
else
{
if(!IsTransparenceAllowed())
return false;
mpCurrentSdrDragMethod.reset(new SdrDragGradient(*this, false));
}
break;
}
case SdrDragMode::Gradient:
{
if(meDragHdl == SdrHdlKind::Move && IsMarkedHitMovesAlways())
{
if(!IsMoveAllowed())
return false;
mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
}
else
{
if(!IsGradientAllowed())
return false;
mpCurrentSdrDragMethod.reset(new SdrDragGradient(*this));
}
break;
}
case SdrDragMode::Crook :
{
if (meDragHdl==SdrHdlKind::Move && IsMarkedHitMovesAlways())
{
if (!IsMoveAllowed()) return false;
mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
}
else
{
if (!IsCrookAllowed(true) && !IsCrookAllowed()) return false;
mpCurrentSdrDragMethod.reset( new SdrDragCrook(*this) );
}
} break;
default:
{
// SdrDragMode::Move
if((meDragHdl == SdrHdlKind::Move) && !IsMoveAllowed())
{
return false;
}
else if(meDragHdl == SdrHdlKind::Glue)
{
mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
}
else
{
if(mbFramDrag)
{
if(meDragHdl == SdrHdlKind::Move)
{
mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
}
else
{
if(!IsResizeAllowed(true))
{
return false;
}
bool bSingleTextObjMark = false; // SJ: #i100490#
if ( GetMarkedObjectCount() == 1 )
{
mpMarkedObj=GetMarkedObjectByIndex(0);
if ( mpMarkedObj &&
dynamic_cast<const SdrTextObj*>( mpMarkedObj) != nullptr &&
static_cast<SdrTextObj*>(mpMarkedObj)->IsTextFrame() )
bSingleTextObjMark = true;
}
if ( bSingleTextObjMark )
mpCurrentSdrDragMethod.reset( new SdrDragObjOwn(*this) );
else
mpCurrentSdrDragMethod.reset( new SdrDragResize(*this) );
}
}
else
{
if(SdrHdlKind::Move == meDragHdl)
{
const bool bCustomShapeSelected(1 == GetMarkedObjectCount() && dynamic_cast<const SdrObjCustomShape*>(GetMarkedObjectByIndex(0)) != nullptr);
if(bCustomShapeSelected)
{
mpCurrentSdrDragMethod.reset( new SdrDragMove( *this ) );
}
}
else if(SdrHdlKind::Poly == meDragHdl)
{
const bool bConnectorSelected(1 == GetMarkedObjectCount() && dynamic_cast<const SdrEdgeObj*>(GetMarkedObjectByIndex(0)) != nullptr);
if(bConnectorSelected)
{
// #i97784#
// fallback to old behaviour for connectors (see
// text in task description for more details)
}
else if(!IsMoveAllowed() || !IsResizeAllowed())
{
// #i77187#
// do not allow move of polygon points if object is move or size protected
return false;
}
}
if(!mpCurrentSdrDragMethod)
{
// fallback to DragSpecial if no interaction defined
mpCurrentSdrDragMethod.reset( new SdrDragObjOwn(*this) );
}
}
}
}
}
}
if (pForcedMeth)
{
mpCurrentSdrDragMethod = std::move(pForcedMeth);
}
maDragStat.SetDragMethod(mpCurrentSdrDragMethod.get());
if (mpCurrentSdrDragMethod)
{
bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
if (!bRet)
{
if (pHdl==nullptr && dynamic_cast< const SdrDragObjOwn* >(mpCurrentSdrDragMethod.get()) != nullptr)
{
// Obj may not Move SpecialDrag, so try with MoveFrameDrag
mpCurrentSdrDragMethod.reset();
if (!IsMoveAllowed())
return false;
mbFramDrag=true;
mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
maDragStat.SetDragMethod(mpCurrentSdrDragMethod.get());
bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
}
}
if (!bRet)
{
mpCurrentSdrDragMethod.reset();
maDragStat.SetDragMethod(mpCurrentSdrDragMethod.get());
}
}
}
return bRet;
}
void SdrDragView::MovDragObj(const Point& rPnt)
{
if (mpCurrentSdrDragMethod)
{
Point aPnt(rPnt);
ImpLimitToWorkArea(aPnt);
mpCurrentSdrDragMethod->MoveSdrDrag(aPnt); // this call already makes a Hide()/Show combination
}
}
bool SdrDragView::EndDragObj(bool bCopy)
{
bool bRet(false);
// #i73341# If inserting GluePoint, do not insist on last points being different
if(mpCurrentSdrDragMethod && maDragStat.IsMinMoved() && (IsInsertGluePoint() || maDragStat.GetNow() != maDragStat.GetPrev()))
{
sal_Int32 nSavedHdlCount=0;
if (bEliminatePolyPoints)
{
nSavedHdlCount=GetMarkablePointCount();
}
const bool bUndo = IsUndoEnabled();
if (IsInsertGluePoint() && bUndo)
{
BegUndo(maInsPointUndoStr);
AddUndo(mpInsPointUndo);
}
bRet = mpCurrentSdrDragMethod->EndSdrDrag(bCopy);
if( IsInsertGluePoint() && bUndo)
EndUndo();
mpCurrentSdrDragMethod.reset();
if (bEliminatePolyPoints)
{
if (nSavedHdlCount!=GetMarkablePointCount())
{
UnmarkAllPoints();
}
}
if (mbInsPolyPoint)
{
SetMarkHandles(nullptr);
mbInsPolyPoint=false;
if( bUndo )
{
BegUndo(maInsPointUndoStr);
AddUndo(mpInsPointUndo);
EndUndo();
}
}
meDragHdl=SdrHdlKind::Move;
mpDragHdl=nullptr;
if (!mbSomeObjChgdFlag)
{
// Obj did not broadcast (e. g. Writer FlyFrames)
if(!mbDragHdl)
{
AdjustMarkHdl();
}
}
}
else
{
BrkDragObj();
}
mbInsPolyPoint=false;
SetInsertGluePoint(false);
return bRet;
}
void SdrDragView::BrkDragObj()
{
if (mpCurrentSdrDragMethod)
{
mpCurrentSdrDragMethod->CancelSdrDrag();
mpCurrentSdrDragMethod.reset();
if (mbInsPolyPoint)
{
mpInsPointUndo->Undo(); // delete inserted point again
delete mpInsPointUndo;
mpInsPointUndo=nullptr;
SetMarkHandles(nullptr);
mbInsPolyPoint=false;
}
if (IsInsertGluePoint())
{
mpInsPointUndo->Undo(); // delete inserted glue point again
delete mpInsPointUndo;
mpInsPointUndo=nullptr;
SetInsertGluePoint(false);
}
meDragHdl=SdrHdlKind::Move;
mpDragHdl=nullptr;
}
}
bool SdrDragView::IsInsObjPointPossible() const
{
return mpMarkedObj!=nullptr && mpMarkedObj->IsPolyObj();
}
bool SdrDragView::ImpBegInsObjPoint(bool bIdxZwang, const Point& rPnt, bool bNewObj, OutputDevice* pOut)
{
bool bRet(false);
if(auto pMarkedPath = dynamic_cast<SdrPathObj*>( mpMarkedObj))
{
BrkAction();
mpInsPointUndo = dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mpMarkedObj) );
DBG_ASSERT( mpInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
OUString aStr(SvxResId(STR_DragInsertPoint));
maInsPointUndoStr = aStr.replaceFirst("%1", mpMarkedObj->TakeObjNameSingul() );
Point aPt(rPnt);
if(bNewObj)
aPt = GetSnapPos(aPt,mpMarkedPV);
bool bClosed0 = pMarkedPath->IsClosedObj();
const sal_uInt32 nInsPointNum { bIdxZwang
? pMarkedPath->NbcInsPoint(aPt, bNewObj)
: pMarkedPath->NbcInsPointOld(aPt, bNewObj)
};
if(bClosed0 != pMarkedPath->IsClosedObj())
{
// Obj was closed implicitly
// object changed
pMarkedPath->SetChanged();
pMarkedPath->BroadcastObjectChange();
}
if (nInsPointNum != SAL_MAX_UINT32)
{
mbInsPolyPoint = true;
UnmarkAllPoints();
AdjustMarkHdl();
bRet = BegDragObj(rPnt, pOut, maHdlList.GetHdl(nInsPointNum), 0);
if (bRet)
{
maDragStat.SetMinMoved();
MovDragObj(rPnt);
}
}
else
{
delete mpInsPointUndo;
mpInsPointUndo = nullptr;
}
}
return bRet;
}
bool SdrDragView::EndInsObjPoint(SdrCreateCmd eCmd)
{
if(IsInsObjPoint())
{
Point aPnt(maDragStat.GetNow());
bool bOk=EndDragObj();
if (bOk && eCmd!=SdrCreateCmd::ForceEnd)
{
// Ret=True means: Action is over.
bOk = ! ImpBegInsObjPoint(true, aPnt, eCmd == SdrCreateCmd::NextObject, mpDragWin);
}
return bOk;
} else return false;
}
bool SdrDragView::IsInsGluePointPossible() const
{
bool bRet=false;
if (IsInsGluePointMode() && AreObjectsMarked())
{
if (GetMarkedObjectCount()==1)
{
// return sal_False, if only 1 object which is a connector.
const SdrObject* pObj=GetMarkedObjectByIndex(0);
if (dynamic_cast<const SdrEdgeObj *>(pObj) == nullptr)
{
bRet=true;
}
}
else
{
bRet=true;
}
}
return bRet;
}
bool SdrDragView::BegInsGluePoint(const Point& rPnt)
{
bool bRet=false;
SdrObject* pObj;
SdrPageView* pPV;
if (PickMarkedObj(rPnt,pObj,pPV,SdrSearchOptions::PASS2BOUND))
{
BrkAction();
UnmarkAllGluePoints();
mpInsPointUndo= dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj) );
DBG_ASSERT( mpInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
OUString aStr(SvxResId(STR_DragInsertGluePoint));
maInsPointUndoStr = aStr.replaceFirst("%1", pObj->TakeObjNameSingul() );
SdrGluePointList* pGPL=pObj->ForceGluePointList();
if (pGPL!=nullptr)
{
sal_uInt16 nGlueIdx=pGPL->Insert(SdrGluePoint());
SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
sal_uInt16 nGlueId=rGP.GetId();
rGP.SetAbsolutePos(rPnt,*pObj);
SdrHdl* pHdl=nullptr;
if (MarkGluePoint(pObj,nGlueId,false))
{
pHdl=GetGluePointHdl(pObj,nGlueId);
}
if (pHdl!=nullptr && pHdl->GetKind()==SdrHdlKind::Glue && pHdl->GetObj()==pObj && pHdl->GetObjHdlNum()==nGlueId)
{
SetInsertGluePoint(true);
bRet=BegDragObj(rPnt,nullptr,pHdl,0);
if (bRet)
{
maDragStat.SetMinMoved();
MovDragObj(rPnt);
}
else
{
SetInsertGluePoint(false);
delete mpInsPointUndo;
mpInsPointUndo=nullptr;
}
}
else
{
OSL_FAIL("BegInsGluePoint(): GluePoint handle not found.");
}
}
else
{
// no glue points possible for this object (e. g. Edge)
SetInsertGluePoint(false);
delete mpInsPointUndo;
mpInsPointUndo=nullptr;
}
}
return bRet;
}
void SdrDragView::ShowDragObj()
{
if(mpCurrentSdrDragMethod && !maDragStat.IsShown())
{
for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
{
SdrPaintWindow* pCandidate = GetPaintWindow(a);
rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = pCandidate->GetOverlayManager();
if (xOverlayManager.is())
{
mpCurrentSdrDragMethod->CreateOverlayGeometry(*xOverlayManager);
// #i101679# Force changed overlay to be shown
xOverlayManager->flush();
}
}
maDragStat.SetShown(true);
}
}
void SdrDragView::HideDragObj()
{
if(mpCurrentSdrDragMethod && maDragStat.IsShown())
{
mpCurrentSdrDragMethod->destroyOverlayGeometry();
maDragStat.SetShown(false);
}
}
void SdrDragView::SetNoDragXorPolys(bool bOn)
{
if (IsNoDragXorPolys()!=bOn)
{
const bool bDragging(mpCurrentSdrDragMethod);
const bool bShown(bDragging && maDragStat.IsShown());
if(bShown)
{
HideDragObj();
}
mbNoDragXorPolys = bOn;
if(bDragging)
{
// force recreation of drag content
mpCurrentSdrDragMethod->resetSdrDragEntries();
}
if(bShown)
{
ShowDragObj();
}
}
}
void SdrDragView::SetDragStripes(bool bOn)
{
if (mpCurrentSdrDragMethod && maDragStat.IsShown())
{
HideDragObj();
mbDragStripes=bOn;
ShowDragObj();
}
else
{
mbDragStripes=bOn;
}
}
bool SdrDragView::IsOrthoDesired() const
{
if( dynamic_cast< const SdrDragObjOwn* >( mpCurrentSdrDragMethod.get() )
|| dynamic_cast< const SdrDragResize* >(mpCurrentSdrDragMethod.get() ))
{
return bOrthoDesiredOnMarked;
}
return false;
}
void SdrDragView::SetMarkHandles(SfxViewShell* pOtherShell)
{
if( mpDragHdl )
mpDragHdl = nullptr;
SdrExchangeView::SetMarkHandles(pOtherShell);
}
void SdrDragView::SetSolidDragging(bool bOn)
{
if(mbSolidDragging != bOn)
{
mbSolidDragging = bOn;
}
}
bool SdrDragView::IsSolidDragging() const
{
// allow each user to disable by having a local setting, but using AND for
// checking allowance
return mbSolidDragging && getOptionsDrawinglayer().IsSolidDragCreate();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V519 The 'mbDragLimit' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 210, 215.