Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / svdraw / svdsnpv.cxx
blobbcef8b3c3ea54bc5c8a949ee87d65829cddc27af
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 <svx/svdsnpv.hxx>
22 #include <math.h>
24 #include <svx/svdobj.hxx>
25 #include <svx/svdpagv.hxx>
26 #include <svx/svdpage.hxx>
27 #include <svx/svditer.hxx>
28 #include <svx/sdr/overlay/overlayobjectlist.hxx>
29 #include <sdr/overlay/overlaycrosshair.hxx>
30 #include <sdr/overlay/overlayhelpline.hxx>
31 #include <svx/sdr/overlay/overlaymanager.hxx>
32 #include <svx/sdrpaintwindow.hxx>
33 #include <tools/debug.hxx>
34 #include <vcl/ptrstyle.hxx>
37 class ImplPageOriginOverlay
39 // The OverlayObjects
40 sdr::overlay::OverlayObjectList maObjects;
42 // The current position in logical coordinates
43 basegfx::B2DPoint maPosition;
45 public:
46 ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos);
48 // The OverlayObjects are cleared using the destructor of OverlayObjectList.
49 // That destructor calls clear() at the list which removes all objects from the
50 // OverlayManager and deletes them.
52 void SetPosition(const basegfx::B2DPoint& rNewPosition);
55 ImplPageOriginOverlay::ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos)
56 : maPosition(rStartPos)
58 for(sal_uInt32 a(0); a < rView.PaintWindowCount(); a++)
60 SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
61 const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager();
63 if (xTargetOverlay.is())
65 std::unique_ptr<sdr::overlay::OverlayCrosshairStriped> aNew(new sdr::overlay::OverlayCrosshairStriped(
66 maPosition));
67 xTargetOverlay->add(*aNew);
68 maObjects.append(std::move(aNew));
73 void ImplPageOriginOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
75 if(rNewPosition == maPosition)
76 return;
78 // apply to OverlayObjects
79 for(sal_uInt32 a(0); a < maObjects.count(); a++)
81 sdr::overlay::OverlayCrosshairStriped* pCandidate =
82 static_cast< sdr::overlay::OverlayCrosshairStriped* >(&maObjects.getOverlayObject(a));
84 if(pCandidate)
86 pCandidate->setBasePosition(rNewPosition);
90 // remember new position
91 maPosition = rNewPosition;
95 class ImplHelpLineOverlay
97 // The OverlayObjects
98 sdr::overlay::OverlayObjectList maObjects;
100 // The current position in logical coordinates
101 basegfx::B2DPoint maPosition;
103 // HelpLine specific stuff
104 SdrPageView* mpPageView;
105 sal_uInt16 mnHelpLineNumber;
106 SdrHelpLineKind meHelpLineKind;
108 public:
109 ImplHelpLineOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
110 SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind);
112 // The OverlayObjects are cleared using the destructor of OverlayObjectList.
113 // That destructor calls clear() at the list which removes all objects from the
114 // OverlayManager and deletes them.
116 void SetPosition(const basegfx::B2DPoint& rNewPosition);
118 // access to HelpLine specific stuff
119 SdrPageView* GetPageView() const { return mpPageView; }
120 sal_uInt16 GetHelpLineNumber() const { return mnHelpLineNumber; }
121 SdrHelpLineKind GetHelpLineKind() const { return meHelpLineKind; }
124 ImplHelpLineOverlay::ImplHelpLineOverlay(
125 const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
126 SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind)
127 : maPosition(rStartPos),
128 mpPageView(pPageView),
129 mnHelpLineNumber(nHelpLineNumber),
130 meHelpLineKind(eKind)
132 for(sal_uInt32 a(0); a < rView.PaintWindowCount(); a++)
134 SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
135 const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager();
137 if (xTargetOverlay.is())
139 std::unique_ptr<sdr::overlay::OverlayHelplineStriped> aNew(new sdr::overlay::OverlayHelplineStriped(
140 maPosition, meHelpLineKind));
141 xTargetOverlay->add(*aNew);
142 maObjects.append(std::move(aNew));
147 void ImplHelpLineOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
149 if(rNewPosition == maPosition)
150 return;
152 // apply to OverlayObjects
153 for(sal_uInt32 a(0); a < maObjects.count(); a++)
155 sdr::overlay::OverlayHelplineStriped* pCandidate =
156 static_cast< sdr::overlay::OverlayHelplineStriped* >(&maObjects.getOverlayObject(a));
158 if(pCandidate)
160 pCandidate->setBasePosition(rNewPosition);
164 // remember new position
165 maPosition = rNewPosition;
168 SdrSnapView::SdrSnapView(
169 SdrModel& rSdrModel,
170 OutputDevice* pOut)
171 : SdrPaintView(rSdrModel, pOut)
172 ,mpPageOriginOverlay(nullptr)
173 ,mpHelpLineOverlay(nullptr)
174 ,nMagnSizPix(4)
175 ,nSnapAngle(1500)
176 ,nEliminatePolyPointLimitAngle(0)
177 ,eCrookMode(SdrCrookMode::Rotate)
178 ,bSnapEnab(true)
179 ,bGridSnap(true)
180 ,bBordSnap(true)
181 ,bHlplSnap(true)
182 ,bOFrmSnap(true)
183 ,bOPntSnap(false)
184 ,bOConSnap(true)
185 ,bMoveSnapOnlyTopLeft(false)
186 ,bOrtho(false)
187 ,bBigOrtho(true)
188 ,bAngleSnapEnab(false)
189 ,bMoveOnlyDragging(false)
190 ,bSlantButShear(false)
191 ,bCrookNoContortion(false)
192 ,bEliminatePolyPoints(false)
196 SdrSnapView::~SdrSnapView()
198 BrkSetPageOrg();
199 BrkDragHelpLine();
203 bool SdrSnapView::IsAction() const
205 return IsSetPageOrg() || IsDragHelpLine() || SdrPaintView::IsAction();
208 void SdrSnapView::MovAction(const Point& rPnt)
210 SdrPaintView::MovAction(rPnt);
211 if (IsSetPageOrg()) {
212 MovSetPageOrg(rPnt);
214 if (IsDragHelpLine()) {
215 MovDragHelpLine(rPnt);
219 void SdrSnapView::EndAction()
221 if (IsSetPageOrg()) {
222 EndSetPageOrg();
224 if (IsDragHelpLine()) {
225 EndDragHelpLine();
227 SdrPaintView::EndAction();
230 void SdrSnapView::BckAction()
232 BrkSetPageOrg();
233 BrkDragHelpLine();
234 SdrPaintView::BckAction();
237 void SdrSnapView::BrkAction()
239 BrkSetPageOrg();
240 BrkDragHelpLine();
241 SdrPaintView::BrkAction();
244 void SdrSnapView::TakeActionRect(tools::Rectangle& rRect) const
246 if (IsSetPageOrg() || IsDragHelpLine()) {
247 rRect=tools::Rectangle(maDragStat.GetNow(),maDragStat.GetNow());
248 } else {
249 SdrPaintView::TakeActionRect(rRect);
254 Point SdrSnapView::GetSnapPos(const Point& rPnt, const SdrPageView* pPV) const
256 Point aPt(rPnt);
257 SnapPos(aPt,pPV);
258 return aPt;
261 #define NOT_SNAPPED 0x7FFFFFFF
262 SdrSnap SdrSnapView::SnapPos(Point& rPnt, const SdrPageView* pPV) const
264 if (!bSnapEnab) return SdrSnap::NOTSNAPPED;
265 tools::Long x=rPnt.X();
266 tools::Long y=rPnt.Y();
267 if (pPV==nullptr) {
268 pPV=GetSdrPageView();
269 if (pPV==nullptr) return SdrSnap::NOTSNAPPED;
272 tools::Long dx=NOT_SNAPPED;
273 tools::Long dy=NOT_SNAPPED;
274 tools::Long dx1,dy1;
275 tools::Long mx=aMagnSiz.Width();
276 tools::Long my=aMagnSiz.Height();
277 if (mbHlplVisible && bHlplSnap && !IsDragHelpLine())
279 const SdrHelpLineList& rHLL=pPV->GetHelpLines();
280 sal_uInt16 nCount=rHLL.GetCount();
281 for (sal_uInt16 i=nCount; i>0;) {
282 i--;
283 const SdrHelpLine& rHL=rHLL[i];
284 const Point& rPos=rHL.GetPos();
285 switch (rHL.GetKind()) {
286 case SdrHelpLineKind::Vertical: {
287 tools::Long a=x-rPos.X();
288 if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; }
289 } break;
290 case SdrHelpLineKind::Horizontal: {
291 tools::Long b=y-rPos.Y();
292 if (std::abs(b)<=my) { dy1=-b; if (std::abs(dy1)<std::abs(dy)) dy=dy1; }
293 } break;
294 case SdrHelpLineKind::Point: {
295 tools::Long a=x-rPos.X();
296 tools::Long b=y-rPos.Y();
297 if (std::abs(a)<=mx && std::abs(b)<=my) {
298 dx1=-a; dy1=-b;
299 if (std::abs(dx1)<std::abs(dx) && std::abs(dy1)<std::abs(dy)) { dx=dx1; dy=dy1; }
301 } break;
302 } // switch
305 if (mbBordVisible && bBordSnap) {
306 SdrPage* pPage=pPV->GetPage();
307 tools::Long xs=pPage->GetWidth();
308 tools::Long ys=pPage->GetHeight();
309 tools::Long lft=pPage->GetLeftBorder();
310 tools::Long rgt=pPage->GetRightBorder();
311 tools::Long upp=pPage->GetUpperBorder();
312 tools::Long lwr=pPage->GetLowerBorder();
313 tools::Long a;
314 a=x- lft ; if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // left margin
315 a=x-(xs-rgt); if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // right margin
316 a=x ; if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // left edge of paper
317 a=x- xs ; if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // right edge of paper
318 a=y- upp ; if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // left margin
319 a=y-(ys-lwr); if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // right margin
320 a=y ; if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // left edge of paper
321 a=y- ys ; if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // right edge of paper
323 if (bOFrmSnap || bOPntSnap) {
324 sal_uInt32 nMaxPointSnapCount=200;
325 sal_uInt32 nMaxFrameSnapCount=200;
327 // go back to SdrIterMode::DeepNoGroups runthrough for snap to object comparisons
328 SdrObjListIter aIter(pPV->GetPage(),SdrIterMode::DeepNoGroups,true);
330 while (aIter.IsMore() && (nMaxPointSnapCount>0 || nMaxFrameSnapCount>0)) {
331 SdrObject* pO=aIter.Next();
332 tools::Rectangle aRect(pO->GetCurrentBoundRect());
333 aRect.AdjustLeft( -mx );
334 aRect.AdjustRight(mx );
335 aRect.AdjustTop( -my );
336 aRect.AdjustBottom(my );
337 if (aRect.Contains(rPnt)) {
338 if (bOPntSnap && nMaxPointSnapCount>0)
340 sal_uInt32 nCount(pO->GetSnapPointCount());
341 for (sal_uInt32 i(0); i < nCount && nMaxPointSnapCount > 0; i++)
343 Point aP(pO->GetSnapPoint(i));
344 dx1=x-aP.X();
345 dy1=y-aP.Y();
346 if (std::abs(dx1)<=mx && std::abs(dy1)<=my && std::abs(dx1)<std::abs(dx) && std::abs(dy1)<std::abs(dy)) {
347 dx=-dx1;
348 dy=-dy1;
350 nMaxPointSnapCount--;
353 if (bOFrmSnap && nMaxFrameSnapCount>0) {
354 tools::Rectangle aLog(pO->GetSnapRect());
355 tools::Rectangle aR1(aLog);
356 aR1.AdjustLeft( -mx );
357 aR1.AdjustRight(mx );
358 aR1.AdjustTop( -my );
359 aR1.AdjustBottom(my );
360 if (aR1.Contains(rPnt)) {
361 if (std::abs(x-aLog.Left ())<=mx) { dx1=-(x-aLog.Left ()); if (std::abs(dx1)<std::abs(dx)) dx=dx1; }
362 if (std::abs(x-aLog.Right ())<=mx) { dx1=-(x-aLog.Right ()); if (std::abs(dx1)<std::abs(dx)) dx=dx1; }
363 if (std::abs(y-aLog.Top ())<=my) { dy1=-(y-aLog.Top ()); if (std::abs(dy1)<std::abs(dy)) dy=dy1; }
364 if (std::abs(y-aLog.Bottom())<=my) { dy1=-(y-aLog.Bottom()); if (std::abs(dy1)<std::abs(dy)) dy=dy1; }
366 nMaxFrameSnapCount--;
371 if(bGridSnap)
373 double fSnapWidth(aSnapWdtX);
374 if(dx == NOT_SNAPPED && fSnapWidth != 0.0)
376 double fx = static_cast<double>(x);
378 // round instead of trunc
379 if(fx - static_cast<double>(pPV->GetPageOrigin().X()) >= 0.0)
380 fx += fSnapWidth / 2.0;
381 else
382 fx -= fSnapWidth / 2.0;
384 x = static_cast<tools::Long>((fx - static_cast<double>(pPV->GetPageOrigin().X())) / fSnapWidth);
385 x = static_cast<tools::Long>(static_cast<double>(x) * fSnapWidth + static_cast<double>(pPV->GetPageOrigin().X()));
386 dx = 0;
388 fSnapWidth = double(aSnapWdtY);
389 if(dy == NOT_SNAPPED && fSnapWidth)
391 double fy = static_cast<double>(y);
393 // round instead of trunc
394 if(fy - static_cast<double>(pPV->GetPageOrigin().Y()) >= 0.0)
395 fy += fSnapWidth / 2.0;
396 else
397 fy -= fSnapWidth / 2.0;
399 y = static_cast<tools::Long>((fy - static_cast<double>(pPV->GetPageOrigin().Y())) / fSnapWidth);
400 y = static_cast<tools::Long>(static_cast<double>(y) * fSnapWidth + static_cast<double>(pPV->GetPageOrigin().Y()));
401 dy = 0;
404 SdrSnap bRet=SdrSnap::NOTSNAPPED;
405 if (dx==NOT_SNAPPED) dx=0; else bRet|=SdrSnap::XSNAPPED;
406 if (dy==NOT_SNAPPED) dy=0; else bRet|=SdrSnap::YSNAPPED;
407 rPnt.setX(x+dx );
408 rPnt.setY(y+dy );
409 return bRet;
412 void SdrSnapView::CheckSnap(const Point& rPt, tools::Long& nBestXSnap, tools::Long& nBestYSnap, bool& bXSnapped, bool& bYSnapped) const
414 Point aPt(rPt);
415 SdrSnap nRet=SnapPos(aPt,nullptr);
416 aPt-=rPt;
417 if (nRet & SdrSnap::XSNAPPED) {
418 if (bXSnapped) {
419 if (std::abs(aPt.X())<std::abs(nBestXSnap)) {
420 nBestXSnap=aPt.X();
422 } else {
423 nBestXSnap=aPt.X();
424 bXSnapped=true;
427 if (nRet & SdrSnap::YSNAPPED) {
428 if (bYSnapped) {
429 if (std::abs(aPt.Y())<std::abs(nBestYSnap)) {
430 nBestYSnap=aPt.Y();
432 } else {
433 nBestYSnap=aPt.Y();
434 bYSnapped=true;
440 void SdrSnapView::BegSetPageOrg(const Point& rPnt)
442 BrkAction();
444 DBG_ASSERT(nullptr == mpPageOriginOverlay, "SdrSnapView::BegSetPageOrg: There exists an ImplPageOriginOverlay (!)");
445 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
446 mpPageOriginOverlay = new ImplPageOriginOverlay(*this, aStartPos);
447 maDragStat.Reset(GetSnapPos(rPnt,nullptr));
450 void SdrSnapView::MovSetPageOrg(const Point& rPnt)
452 if(IsSetPageOrg())
454 maDragStat.NextMove(GetSnapPos(rPnt,nullptr));
455 DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
456 basegfx::B2DPoint aNewPos(maDragStat.GetNow().X(), maDragStat.GetNow().Y());
457 mpPageOriginOverlay->SetPosition(aNewPos);
461 void SdrSnapView::EndSetPageOrg()
463 if(!IsSetPageOrg())
464 return;
466 SdrPageView* pPV = GetSdrPageView();
468 if(pPV)
470 Point aPnt(maDragStat.GetNow());
471 pPV->SetPageOrigin(aPnt);
474 // cleanup
475 BrkSetPageOrg();
478 void SdrSnapView::BrkSetPageOrg()
480 if(IsSetPageOrg())
482 DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
483 delete mpPageOriginOverlay;
484 mpPageOriginOverlay = nullptr;
489 bool SdrSnapView::PickHelpLine(const Point& rPnt, short nTol, const OutputDevice& rOut, sal_uInt16& rnHelpLineNum, SdrPageView*& rpPV) const
491 rpPV=nullptr;
492 nTol=ImpGetHitTolLogic(nTol,&rOut);
493 SdrPageView* pPV = GetSdrPageView();
495 if(pPV)
497 Point aPnt(rPnt);
498 sal_uInt16 nIndex=pPV->GetHelpLines().HitTest(aPnt,sal_uInt16(nTol),rOut);
499 if (nIndex!=SDRHELPLINE_NOTFOUND) {
500 rpPV=pPV;
501 rnHelpLineNum=nIndex;
502 return true;
505 return false;
508 // start HelpLine drag for new HelpLine
509 bool SdrSnapView::BegDragHelpLine(sal_uInt16 nHelpLineNum, SdrPageView* pPV)
511 bool bRet(false);
513 BrkAction();
515 if(pPV && nHelpLineNum < pPV->GetHelpLines().GetCount())
517 const SdrHelpLineList& rHelpLines = pPV->GetHelpLines();
518 const SdrHelpLine& rHelpLine = rHelpLines[nHelpLineNum];
519 Point aHelpLinePos = rHelpLine.GetPos();
520 basegfx::B2DPoint aStartPos(aHelpLinePos.X(), aHelpLinePos.Y());
522 DBG_ASSERT(nullptr == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists an ImplHelpLineOverlay (!)");
523 mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, pPV, nHelpLineNum, rHelpLine.GetKind());
525 maDragStat.Reset(GetSnapPos(aHelpLinePos, pPV));
526 maDragStat.SetMinMove(ImpGetMinMovLogic(-3, nullptr));
528 bRet = true;
531 return bRet;
534 // start HelpLine drag with existing HelpLine
535 void SdrSnapView::BegDragHelpLine(const Point& rPnt, SdrHelpLineKind eNewKind)
537 BrkAction();
539 if(GetSdrPageView())
541 DBG_ASSERT(nullptr == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists an ImplHelpLineOverlay (!)");
542 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
543 mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, nullptr, 0, eNewKind);
544 maDragStat.Reset(GetSnapPos(rPnt, nullptr));
548 PointerStyle SdrSnapView::GetDraggedHelpLinePointer() const
550 if(IsDragHelpLine())
552 switch(mpHelpLineOverlay->GetHelpLineKind())
554 case SdrHelpLineKind::Vertical : return PointerStyle::ESize;
555 case SdrHelpLineKind::Horizontal: return PointerStyle::SSize;
556 default : return PointerStyle::Move;
560 return PointerStyle::Move;
563 void SdrSnapView::MovDragHelpLine(const Point& rPnt)
565 if(IsDragHelpLine() && maDragStat.CheckMinMoved(rPnt))
567 Point aPnt(GetSnapPos(rPnt, nullptr));
569 if(aPnt != maDragStat.GetNow())
571 maDragStat.NextMove(aPnt);
572 DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::MovDragHelpLine: no ImplHelpLineOverlay (!)");
573 basegfx::B2DPoint aNewPos(maDragStat.GetNow().X(), maDragStat.GetNow().Y());
574 mpHelpLineOverlay->SetPosition(aNewPos);
579 bool SdrSnapView::EndDragHelpLine()
581 bool bRet(false);
583 if(IsDragHelpLine())
585 if(maDragStat.IsMinMoved())
587 SdrPageView* pPageView = mpHelpLineOverlay->GetPageView();
589 if(pPageView)
591 // moved existing one
592 Point aPnt(maDragStat.GetNow());
593 const SdrHelpLineList& rHelpLines = pPageView->GetHelpLines();
594 SdrHelpLine aChangedHelpLine = rHelpLines[mpHelpLineOverlay->GetHelpLineNumber()];
595 aChangedHelpLine.SetPos(aPnt);
596 pPageView->SetHelpLine(mpHelpLineOverlay->GetHelpLineNumber(), aChangedHelpLine);
598 bRet = true;
600 else
602 // create new one
603 pPageView = GetSdrPageView();
605 if(pPageView)
607 Point aPnt(maDragStat.GetNow());
608 SdrHelpLine aNewHelpLine(mpHelpLineOverlay->GetHelpLineKind(), aPnt);
609 pPageView->InsertHelpLine(aNewHelpLine);
611 bRet = true;
616 // cleanup
617 BrkDragHelpLine();
620 return bRet;
623 void SdrSnapView::BrkDragHelpLine()
625 if(IsDragHelpLine())
627 DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::EndDragHelpLine: no ImplHelpLineOverlay (!)");
628 delete mpHelpLineOverlay;
629 mpHelpLineOverlay = nullptr;
633 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */