tdf#158198 sw: prevent xBookmark.getAnchor().setString("") from deleting
[LibreOffice.git] / svx / source / svdraw / svddrgv.cxx
blob645cb8fd2befa014c15ef31cb0180f7cc2330fec
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 .
21 #include <osl/diagnose.h>
22 #include <tools/debug.hxx>
23 #include <svx/svddrgv.hxx>
24 #include <svx/svdview.hxx>
25 #include <svx/svdundo.hxx>
26 #include <svx/svdocapt.hxx>
27 #include <svx/svdpagv.hxx>
28 #include <svx/svdopath.hxx>
29 #include <svx/svdoedge.hxx>
30 #include <svx/strings.hrc>
31 #include <svx/dialmgr.hxx>
32 #include "svddrgm1.hxx"
33 #include <svx/svdoashp.hxx>
34 #include <svx/sdrpaintwindow.hxx>
35 #include <basegfx/matrix/b2dhommatrix.hxx>
36 #include <svx/sdr/overlay/overlaymanager.hxx>
37 #include <svx/sdrpagewindow.hxx>
38 #include <unotools/configmgr.hxx>
39 #include <comphelper/lok.hxx>
40 #include <officecfg/Office/Common.hxx>
41 #include <sfx2/objsh.hxx>
42 #include <sfx2/viewsh.hxx>
43 #include <svl/cryptosign.hxx>
45 using namespace sdr;
47 SdrDragView::SdrDragView(SdrModel& rSdrModel, OutputDevice* pOut)
48 : SdrExchangeView(rSdrModel, pOut)
49 , mpDragHdl(nullptr)
50 , meDragHdl(SdrHdlKind::Move)
51 , mnDragThresholdPixels(6)
52 , mbFramDrag(false)
53 , mbMarkedHitMovesAlways(false)
54 , mbDragLimit(false)
55 , mbDragHdl(false)
56 , mbDragStripes(false)
57 , mbSolidDragging(comphelper::IsFuzzing() || officecfg::Office::Common::Drawinglayer::SolidDragCreate::get())
58 , mbResizeAtCenter(false)
59 , mbCrookAtCenter(false)
60 , mbDragWithCopy(false)
61 , mbInsGluePoint(false)
62 , mbInsObjPointMode(false)
63 , mbInsGluePointMode(false)
64 , mbNoDragXorPolys(false)
66 meDragMode = SdrDragMode::Move;
69 SdrDragView::~SdrDragView()
73 bool SdrDragView::IsAction() const
75 return (mpCurrentSdrDragMethod || SdrExchangeView::IsAction());
78 void SdrDragView::MovAction(const Point& rPnt)
80 SdrExchangeView::MovAction(rPnt);
81 if (mpCurrentSdrDragMethod)
83 MovDragObj(rPnt);
87 void SdrDragView::EndAction()
89 if (mpCurrentSdrDragMethod)
91 EndDragObj();
93 SdrExchangeView::EndAction();
96 void SdrDragView::BckAction()
98 SdrExchangeView::BckAction();
99 BrkDragObj();
102 void SdrDragView::BrkAction()
104 SdrExchangeView::BrkAction();
105 BrkDragObj();
108 void SdrDragView::TakeActionRect(tools::Rectangle& rRect) const
110 if (mpCurrentSdrDragMethod)
112 rRect=maDragStat.GetActionRect();
113 if (rRect.IsEmpty())
115 SdrPageView* pPV = GetSdrPageView();
117 if(pPV&& pPV->HasMarkedObjPageView())
119 // #i95646# is this used..?
120 const basegfx::B2DRange aBoundRange(mpCurrentSdrDragMethod->getCurrentRange());
121 if (aBoundRange.isEmpty())
123 rRect.SetEmpty();
125 else
127 rRect = tools::Rectangle(
128 basegfx::fround<tools::Long>(aBoundRange.getMinX()), basegfx::fround<tools::Long>(aBoundRange.getMinY()),
129 basegfx::fround<tools::Long>(aBoundRange.getMaxX()), basegfx::fround<tools::Long>(aBoundRange.getMaxY()));
133 if (rRect.IsEmpty())
135 rRect=tools::Rectangle(maDragStat.GetNow(),maDragStat.GetNow());
138 else
140 SdrExchangeView::TakeActionRect(rRect);
144 bool SdrDragView::TakeDragObjAnchorPos(Point& rPos, bool bTR ) const
146 tools::Rectangle aR;
147 TakeActionRect(aR);
148 rPos = bTR ? aR.TopRight() : aR.TopLeft();
149 const SdrMarkList& rMarkList = GetMarkedObjectList();
150 if (rMarkList.GetMarkCount()==1 && IsDragObj() && // only on single selection
151 !IsDraggingPoints() && !IsDraggingGluePoints() && // not when moving points
152 dynamic_cast<const SdrDragMovHdl*>( mpCurrentSdrDragMethod.get() ) == nullptr) // not when moving handles
154 SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj();
155 if (auto pCaptionObj = dynamic_cast<SdrCaptionObj*>(pObj))
157 Point aPt(pCaptionObj->GetTailPos());
158 bool bTail=meDragHdl==SdrHdlKind::Poly; // drag tail
159 bool bOwn=dynamic_cast<const SdrDragObjOwn*>( mpCurrentSdrDragMethod.get() ) != nullptr; // specific to object
160 if (!bTail)
161 { // for bTail, TakeActionRect already does the right thing
162 if (bOwn)
163 { // bOwn may be MoveTextFrame, ResizeTextFrame, but may not (any more) be DragTail
164 rPos=aPt;
166 else
168 // drag the whole Object (Move, Resize, ...)
169 const basegfx::B2DPoint aTransformed(mpCurrentSdrDragMethod->getCurrentTransformation() * basegfx::B2DPoint(aPt.X(), aPt.Y()));
170 rPos.setX( basegfx::fround<tools::Long>(aTransformed.getX()) );
171 rPos.setY( basegfx::fround<tools::Long>(aTransformed.getY()) );
175 return true;
177 return false;
181 bool SdrDragView::TakeDragLimit(SdrDragMode /*eMode*/, tools::Rectangle& /*rRect*/) const
183 return false;
186 bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl, short nMinMov, SdrDragMethod* _pForcedMeth)
188 BrkAction();
190 // so we don't leak the object on early return
191 std::unique_ptr<SdrDragMethod> pForcedMeth(_pForcedMeth);
193 bool bRet=false;
195 SetDragWithCopy(false);
196 //TODO: aAni.Reset();
197 mpCurrentSdrDragMethod=nullptr;
198 SdrDragMode eTmpMode=meDragMode;
199 if (eTmpMode==SdrDragMode::Move && pHdl!=nullptr && pHdl->GetKind()!=SdrHdlKind::Move) {
200 eTmpMode=SdrDragMode::Resize;
202 mbDragLimit=TakeDragLimit(eTmpMode,maDragLimit);
203 mbFramDrag=ImpIsFrameHandles();
204 if (!mbFramDrag &&
205 (mpMarkedObj==nullptr || !mpMarkedObj->hasSpecialDrag()) &&
206 (pHdl==nullptr || pHdl->GetObj()==nullptr)) {
207 mbFramDrag=true;
210 Point aPnt(rPnt);
211 basegfx::B2DVector aGridOffset(0.0, 0.0);
212 const SdrMarkList& rMarkList = GetMarkedObjectList();
214 // Coordinate maybe affected by GridOffset, so we may need to
215 // adapt to Model-coordinates here
216 if((comphelper::LibreOfficeKit::isActive() && mpMarkedObj
217 && getPossibleGridOffsetForSdrObject(aGridOffset, rMarkList.GetMark(0)->GetMarkedSdrObj(), GetSdrPageView()))
218 || (getPossibleGridOffsetForPosition(
219 aGridOffset,
220 basegfx::B2DPoint(aPnt.X(), aPnt.Y()),
221 GetSdrPageView())))
223 aPnt.AdjustX(basegfx::fround<tools::Long>(-aGridOffset.getX()));
224 aPnt.AdjustY(basegfx::fround<tools::Long>(-aGridOffset.getY()));
227 if(pHdl == nullptr
228 || pHdl->GetKind() == SdrHdlKind::Move
229 || pHdl->GetKind() == SdrHdlKind::MirrorAxis
230 || pHdl->GetKind() == SdrHdlKind::Transparence
231 || pHdl->GetKind() == SdrHdlKind::Gradient)
233 maDragStat.Reset(aPnt);
235 else
237 maDragStat.Reset(pHdl->GetPos());
240 maDragStat.SetView(static_cast<SdrView*>(this));
241 maDragStat.SetPageView(mpMarkedPV); // <<-- DragPV has to go here!!!
242 maDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut));
243 maDragStat.SetHdl(pHdl);
244 maDragStat.NextPoint();
245 mpDragWin=pOut;
246 mpDragHdl=pHdl;
247 meDragHdl= pHdl==nullptr ? SdrHdlKind::Move : pHdl->GetKind();
248 mbDragHdl=meDragHdl==SdrHdlKind::Ref1 || meDragHdl==SdrHdlKind::Ref2 || meDragHdl==SdrHdlKind::MirrorAxis;
250 // Expand test for SdrHdlKind::Anchor_TR
251 bool bNotDraggable = (SdrHdlKind::Anchor == meDragHdl || SdrHdlKind::Anchor_TR == meDragHdl);
253 if(pHdl && (pHdl->GetKind() == SdrHdlKind::SmartTag) && pForcedMeth )
255 // just use the forced method for smart tags
257 else if(mbDragHdl)
259 mpCurrentSdrDragMethod.reset(new SdrDragMovHdl(*this));
261 else if(!bNotDraggable)
263 switch (meDragMode)
265 case SdrDragMode::Rotate: case SdrDragMode::Shear:
267 switch (meDragHdl)
269 case SdrHdlKind::Left: case SdrHdlKind::Right:
270 case SdrHdlKind::Upper: case SdrHdlKind::Lower:
272 // are 3D objects selected?
273 bool b3DObjSelected = false;
274 for(size_t a=0; !b3DObjSelected && a<rMarkList.GetMarkCount(); ++a)
276 SdrObject* pObj = rMarkList.GetMark(a)->GetMarkedSdrObj();
277 if(DynCastE3dObject(pObj))
278 b3DObjSelected = true;
280 // If yes, allow shear even when !IsShearAllowed,
281 // because 3D objects are limited rotations
282 if (!b3DObjSelected && !IsShearAllowed())
283 return false;
284 mpCurrentSdrDragMethod.reset(new SdrDragShear(*this,meDragMode==SdrDragMode::Rotate));
285 } break;
286 case SdrHdlKind::UpperLeft: case SdrHdlKind::UpperRight:
287 case SdrHdlKind::LowerLeft: case SdrHdlKind::LowerRight:
289 if (meDragMode==SdrDragMode::Shear)
291 if (!IsDistortAllowed(true) && !IsDistortAllowed()) return false;
292 mpCurrentSdrDragMethod.reset(new SdrDragDistort(*this));
294 else
296 if (!IsRotateAllowed(true)) return false;
297 mpCurrentSdrDragMethod.reset(new SdrDragRotate(*this));
299 } break;
300 default:
302 if (IsMarkedHitMovesAlways() && meDragHdl==SdrHdlKind::Move)
303 { // SdrHdlKind::Move is true, even if Obj is hit directly
304 if (!IsMoveAllowed()) return false;
305 mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
307 else
309 if (!IsRotateAllowed(true)) return false;
310 mpCurrentSdrDragMethod.reset(new SdrDragRotate(*this));
314 } break;
315 case SdrDragMode::Mirror:
317 if (meDragHdl==SdrHdlKind::Move && IsMarkedHitMovesAlways())
319 if (!IsMoveAllowed()) return false;
320 mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
322 else
324 if (!IsMirrorAllowed(true,true)) return false;
325 mpCurrentSdrDragMethod.reset(new SdrDragMirror(*this));
327 } break;
329 case SdrDragMode::Crop:
331 if (meDragHdl==SdrHdlKind::Move && IsMarkedHitMovesAlways())
333 if (!IsMoveAllowed())
334 return false;
335 mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
337 else
339 if (!IsCropAllowed())
340 return false;
341 mpCurrentSdrDragMethod.reset(new SdrDragCrop(*this));
344 break;
346 case SdrDragMode::Transparence:
348 if(meDragHdl == SdrHdlKind::Move && IsMarkedHitMovesAlways())
350 if(!IsMoveAllowed())
351 return false;
352 mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
354 else
356 if(!IsTransparenceAllowed())
357 return false;
359 mpCurrentSdrDragMethod.reset(new SdrDragGradient(*this, false));
361 break;
363 case SdrDragMode::Gradient:
365 if(meDragHdl == SdrHdlKind::Move && IsMarkedHitMovesAlways())
367 if(!IsMoveAllowed())
368 return false;
369 mpCurrentSdrDragMethod.reset(new SdrDragMove(*this));
371 else
373 if(!IsGradientAllowed())
374 return false;
376 mpCurrentSdrDragMethod.reset(new SdrDragGradient(*this));
378 break;
381 case SdrDragMode::Crook :
383 if (meDragHdl==SdrHdlKind::Move && IsMarkedHitMovesAlways())
385 if (!IsMoveAllowed()) return false;
386 mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
388 else
390 if (!IsCrookAllowed(true) && !IsCrookAllowed()) return false;
391 mpCurrentSdrDragMethod.reset( new SdrDragCrook(*this) );
393 } break;
395 default:
397 // SdrDragMode::Move
398 if((meDragHdl == SdrHdlKind::Move) && !IsMoveAllowed())
400 return false;
402 else if(meDragHdl == SdrHdlKind::Glue)
404 mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
406 else
408 if(mbFramDrag)
410 if(meDragHdl == SdrHdlKind::Move)
412 mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
414 else
416 bool bResizeAllowed = IsResizeAllowed(true);
417 SfxViewShell* pViewShell = GetSfxViewShell();
418 if (!bResizeAllowed && pViewShell && pViewShell->GetSignPDFCertificate().Is())
420 // If the just added signature line shape is selected, allow resizing it.
421 bResizeAllowed = true;
423 if(!bResizeAllowed)
425 return false;
428 bool bSingleTextObjMark = false; // SJ: #i100490#
429 if ( rMarkList.GetMarkCount() == 1 )
431 mpMarkedObj=rMarkList.GetMark(0)->GetMarkedSdrObj();
432 if ( mpMarkedObj &&
433 DynCastSdrTextObj( mpMarkedObj) != nullptr &&
434 static_cast<SdrTextObj*>(mpMarkedObj)->IsTextFrame() )
435 bSingleTextObjMark = true;
437 if ( bSingleTextObjMark )
438 mpCurrentSdrDragMethod.reset( new SdrDragObjOwn(*this) );
439 else
440 mpCurrentSdrDragMethod.reset( new SdrDragResize(*this) );
443 else
445 if(SdrHdlKind::Move == meDragHdl)
447 const bool bCustomShapeSelected(1 == rMarkList.GetMarkCount() && dynamic_cast<const SdrObjCustomShape*>(rMarkList.GetMark(0)->GetMarkedSdrObj()) != nullptr);
449 if(bCustomShapeSelected)
451 mpCurrentSdrDragMethod.reset( new SdrDragMove( *this ) );
454 else if(SdrHdlKind::Poly == meDragHdl)
456 const bool bConnectorSelected(1 == rMarkList.GetMarkCount() && dynamic_cast<const SdrEdgeObj*>(rMarkList.GetMark(0)->GetMarkedSdrObj()) != nullptr);
458 if(bConnectorSelected)
460 // #i97784#
461 // fallback to old behaviour for connectors (see
462 // text in task description for more details)
464 else if(!IsMoveAllowed() || !IsResizeAllowed())
466 // #i77187#
467 // do not allow move of polygon points if object is move or size protected
468 return false;
472 if(!mpCurrentSdrDragMethod)
474 // fallback to DragSpecial if no interaction defined
475 mpCurrentSdrDragMethod.reset( new SdrDragObjOwn(*this) );
482 if (pForcedMeth)
484 mpCurrentSdrDragMethod = std::move(pForcedMeth);
486 maDragStat.SetDragMethod(mpCurrentSdrDragMethod.get());
487 if (mpCurrentSdrDragMethod)
489 bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
490 if (!bRet)
492 if (pHdl==nullptr && dynamic_cast< const SdrDragObjOwn* >(mpCurrentSdrDragMethod.get()) != nullptr)
494 // Obj may not Move SpecialDrag, so try with MoveFrameDrag
495 mpCurrentSdrDragMethod.reset();
497 if (!IsMoveAllowed())
498 return false;
500 mbFramDrag=true;
501 mpCurrentSdrDragMethod.reset( new SdrDragMove(*this) );
502 maDragStat.SetDragMethod(mpCurrentSdrDragMethod.get());
503 bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
506 if (!bRet)
508 mpCurrentSdrDragMethod.reset();
509 maDragStat.SetDragMethod(mpCurrentSdrDragMethod.get());
514 return bRet;
517 void SdrDragView::MovDragObj(const Point& rPnt)
519 if (!mpCurrentSdrDragMethod)
520 return;
522 Point aPnt(rPnt);
523 basegfx::B2DVector aGridOffset(0.0, 0.0);
525 // Coordinate maybe affected by GridOffset, so we may need to
526 // adapt to Model-coordinates here
527 const SdrMarkList& rMarkList = GetMarkedObjectList();
528 if((comphelper::LibreOfficeKit::isActive() && mpMarkedObj
529 && getPossibleGridOffsetForSdrObject(aGridOffset, rMarkList.GetMark(0)->GetMarkedSdrObj(), GetSdrPageView()))
530 || (getPossibleGridOffsetForPosition(
531 aGridOffset,
532 basegfx::B2DPoint(aPnt.X(), aPnt.Y()),
533 GetSdrPageView())))
535 aPnt.AdjustX(basegfx::fround<tools::Long>(-aGridOffset.getX()));
536 aPnt.AdjustY(basegfx::fround<tools::Long>(-aGridOffset.getY()));
539 ImpLimitToWorkArea(aPnt);
540 mpCurrentSdrDragMethod->MoveSdrDrag(aPnt); // this call already makes a Hide()/Show combination
543 bool SdrDragView::EndDragObj(bool bCopy)
545 bool bRet(false);
547 // #i73341# If inserting GluePoint, do not insist on last points being different
548 if(mpCurrentSdrDragMethod && maDragStat.IsMinMoved() && (IsInsertGluePoint() || maDragStat.GetNow() != maDragStat.GetPrev()))
550 sal_Int32 nSavedHdlCount=0;
552 if (mbEliminatePolyPoints)
554 nSavedHdlCount=GetMarkablePointCount();
557 const bool bUndo = IsUndoEnabled();
558 if (IsInsertGluePoint() && bUndo)
560 BegUndo(maInsPointUndoStr);
561 AddUndo(std::move(mpInsPointUndo));
564 bRet = mpCurrentSdrDragMethod->EndSdrDrag(bCopy);
566 if( IsInsertGluePoint() && bUndo)
567 EndUndo();
569 mpCurrentSdrDragMethod.reset();
571 if (mbEliminatePolyPoints)
573 if (nSavedHdlCount!=GetMarkablePointCount())
575 UnmarkAllPoints();
579 if (mbInsPolyPoint)
581 SetMarkHandles(nullptr);
582 mbInsPolyPoint=false;
583 if( bUndo )
585 BegUndo(maInsPointUndoStr);
586 AddUndo(std::move(mpInsPointUndo));
587 EndUndo();
591 meDragHdl=SdrHdlKind::Move;
592 mpDragHdl=nullptr;
594 if (!mbSomeObjChgdFlag)
596 // Obj did not broadcast (e. g. Writer FlyFrames)
597 if(!mbDragHdl)
599 AdjustMarkHdl();
603 else
605 BrkDragObj();
608 mbInsPolyPoint=false;
609 SetInsertGluePoint(false);
611 return bRet;
614 void SdrDragView::BrkDragObj()
616 if (!mpCurrentSdrDragMethod)
617 return;
619 mpCurrentSdrDragMethod->CancelSdrDrag();
621 mpCurrentSdrDragMethod.reset();
623 if (mbInsPolyPoint)
625 mpInsPointUndo->Undo(); // delete inserted point again
626 mpInsPointUndo.reset();
627 SetMarkHandles(nullptr);
628 mbInsPolyPoint=false;
630 else if (IsInsertGluePoint())
632 mpInsPointUndo->Undo(); // delete inserted gluepoint again
633 mpInsPointUndo.reset();
634 SetInsertGluePoint(false);
637 meDragHdl=SdrHdlKind::Move;
638 mpDragHdl=nullptr;
641 bool SdrDragView::IsInsObjPointPossible() const
643 return mpMarkedObj!=nullptr && mpMarkedObj->IsPolyObj();
646 bool SdrDragView::ImpBegInsObjPoint(bool bIdxZwang, const Point& rPnt, bool bNewObj, OutputDevice* pOut)
648 bool bRet(false);
650 if(auto pMarkedPath = dynamic_cast<SdrPathObj*>( mpMarkedObj))
652 BrkAction();
653 mpInsPointUndo = GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*mpMarkedObj);
654 DBG_ASSERT( mpInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
656 OUString aStr(SvxResId(STR_DragInsertPoint));
658 maInsPointUndoStr = aStr.replaceFirst("%1", mpMarkedObj->TakeObjNameSingul() );
660 Point aPt(rPnt);
662 if(bNewObj)
663 aPt = GetSnapPos(aPt,mpMarkedPV);
665 bool bClosed0 = pMarkedPath->IsClosedObj();
667 const sal_uInt32 nInsPointNum { bIdxZwang
668 ? pMarkedPath->NbcInsPoint(aPt, bNewObj)
669 : pMarkedPath->NbcInsPointOld(aPt, bNewObj)
672 if(bClosed0 != pMarkedPath->IsClosedObj())
674 // Obj was closed implicitly
675 // object changed
676 pMarkedPath->SetChanged();
677 pMarkedPath->BroadcastObjectChange();
680 if (nInsPointNum != SAL_MAX_UINT32)
682 mbInsPolyPoint = true;
683 UnmarkAllPoints();
684 AdjustMarkHdl();
686 bRet = BegDragObj(rPnt, pOut, maHdlList.GetHdl(nInsPointNum), 0);
688 if (bRet)
690 maDragStat.SetMinMoved();
691 MovDragObj(rPnt);
694 else
696 mpInsPointUndo.reset();
700 return bRet;
703 bool SdrDragView::EndInsObjPoint(SdrCreateCmd eCmd)
705 if(IsInsObjPoint())
707 Point aPnt(maDragStat.GetNow());
708 bool bOk=EndDragObj();
709 if (bOk && eCmd!=SdrCreateCmd::ForceEnd)
711 // Ret=True means: Action is over.
712 bOk = ! ImpBegInsObjPoint(true, aPnt, eCmd == SdrCreateCmd::NextObject, mpDragWin);
715 return bOk;
716 } else return false;
719 bool SdrDragView::IsInsGluePointPossible() const
721 bool bRet=false;
722 const SdrMarkList& rMarkList = GetMarkedObjectList();
723 if (IsInsGluePointMode() && rMarkList.GetMarkCount() != 0)
725 if (rMarkList.GetMarkCount()==1)
727 // return sal_False, if only 1 object which is a connector.
728 const SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj();
729 if (dynamic_cast<const SdrEdgeObj *>(pObj) == nullptr)
731 bRet=true;
734 else
736 bRet=true;
739 return bRet;
742 bool SdrDragView::BegInsGluePoint(const Point& rPnt)
744 bool bRet=false;
745 SdrObject* pObj;
746 SdrPageView* pPV;
747 if (PickMarkedObj(rPnt,pObj,pPV,SdrSearchOptions::PASS2BOUND))
749 BrkAction();
750 UnmarkAllGluePoints();
751 mpInsPointUndo = GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
752 DBG_ASSERT( mpInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
753 OUString aStr(SvxResId(STR_DragInsertGluePoint));
755 maInsPointUndoStr = aStr.replaceFirst("%1", pObj->TakeObjNameSingul() );
757 SdrGluePointList* pGPL=pObj->ForceGluePointList();
758 if (pGPL!=nullptr)
760 sal_uInt16 nGlueIdx=pGPL->Insert(SdrGluePoint());
761 SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
762 sal_uInt16 nGlueId=rGP.GetId();
763 rGP.SetAbsolutePos(rPnt,*pObj);
765 SdrHdl* pHdl=nullptr;
766 if (MarkGluePoint(pObj,nGlueId,false))
768 pHdl=GetGluePointHdl(pObj,nGlueId);
770 if (pHdl!=nullptr && pHdl->GetKind()==SdrHdlKind::Glue && pHdl->GetObj()==pObj && pHdl->GetObjHdlNum()==nGlueId)
772 SetInsertGluePoint(true);
773 bRet=BegDragObj(rPnt,nullptr,pHdl,0);
774 if (bRet)
776 maDragStat.SetMinMoved();
777 MovDragObj(rPnt);
779 else
781 SetInsertGluePoint(false);
782 mpInsPointUndo.reset();
785 else
787 OSL_FAIL("BegInsGluePoint(): GluePoint handle not found.");
790 else
792 // no gluepoints possible for this object (e. g. Edge)
793 SetInsertGluePoint(false);
794 mpInsPointUndo.reset();
798 return bRet;
801 void SdrDragView::ShowDragObj(bool IsSizeValid)
803 if(!mpCurrentSdrDragMethod || maDragStat.IsShown())
804 return;
806 // Changed for the GridOffset stuff: No longer iterate over
807 // SdrPaintWindow(s), but now over SdrPageWindow(s), so doing the
808 // same as the SdrHdl visualizations (see ::CreateB2dIAObject) do.
809 // This is needed to get access to an ObjectContact which is needed
810 // to evtl. process that GridOffset in CreateOverlayGeometry
811 SdrPageView* pPageView(GetSdrPageView());
813 if(nullptr != pPageView)
815 for(sal_uInt32 a(0); a < pPageView->PageWindowCount(); a++)
817 const SdrPageWindow& rPageWindow(*pPageView->GetPageWindow(a));
818 const SdrPaintWindow& rPaintWindow(rPageWindow.GetPaintWindow());
820 if(rPaintWindow.OutputToWindow())
822 const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager(
823 rPaintWindow.GetOverlayManager());
825 if(xOverlayManager.is())
827 mpCurrentSdrDragMethod->CreateOverlayGeometry(
828 *xOverlayManager,
829 rPageWindow.GetObjectContact(), IsSizeValid);
831 // #i101679# Force changed overlay to be shown
832 xOverlayManager->flush();
838 maDragStat.SetShown(true);
841 void SdrDragView::HideDragObj()
843 if(mpCurrentSdrDragMethod && maDragStat.IsShown())
845 mpCurrentSdrDragMethod->destroyOverlayGeometry();
846 maDragStat.SetShown(false);
851 void SdrDragView::SetNoDragXorPolys(bool bOn)
853 if (IsNoDragXorPolys()==bOn)
854 return;
856 const bool bDragging(mpCurrentSdrDragMethod);
857 const bool bShown(bDragging && maDragStat.IsShown());
859 if(bShown)
861 HideDragObj();
864 mbNoDragXorPolys = bOn;
866 if(bDragging)
868 // force recreation of drag content
869 mpCurrentSdrDragMethod->resetSdrDragEntries();
872 if(bShown)
874 ShowDragObj();
878 void SdrDragView::SetDragStripes(bool bOn)
880 if (mpCurrentSdrDragMethod && maDragStat.IsShown())
882 HideDragObj();
883 mbDragStripes=bOn;
884 ShowDragObj();
886 else
888 mbDragStripes=bOn;
892 bool SdrDragView::IsOrthoDesired() const
894 if( dynamic_cast< const SdrDragObjOwn* >( mpCurrentSdrDragMethod.get() )
895 || dynamic_cast< const SdrDragResize* >(mpCurrentSdrDragMethod.get() ))
897 return m_bOrthoDesiredOnMarked;
900 return false;
903 void SdrDragView::SetMarkHandles(SfxViewShell* pOtherShell)
905 if( mpDragHdl )
906 mpDragHdl = nullptr;
908 SdrExchangeView::SetMarkHandles(pOtherShell);
911 void SdrDragView::SetSolidDragging(bool bOn)
913 if(mbSolidDragging != bOn)
915 mbSolidDragging = bOn;
919 bool SdrDragView::IsSolidDragging() const
921 // allow each user to disable by having a local setting, but using AND for
922 // checking allowance
923 return mbSolidDragging && officecfg::Office::Common::Drawinglayer::SolidDragCreate::get();
926 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */