Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/svx/source/svdraw/svdsnpv.cxx
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
21
#include <svx/svdsnpv.hxx>
22
23
#include <svx/svdobj.hxx>
24
#include <svx/svdpagv.hxx>
25
#include <svx/svdpage.hxx>
26
#include <svx/svditer.hxx>
27
#include <svx/sdr/overlay/overlayobjectlist.hxx>
28
#include <sdr/overlay/overlaycrosshair.hxx>
29
#include <sdr/overlay/overlayhelpline.hxx>
30
#include <svx/sdr/overlay/overlaymanager.hxx>
31
#include <svx/sdrpaintwindow.hxx>
32
#include <tools/debug.hxx>
33
#include <vcl/ptrstyle.hxx>
34
35
36
class ImplPageOriginOverlay
37
{
38
    // The OverlayObjects
39
    sdr::overlay::OverlayObjectList               maObjects;
40
41
    // The current position in logical coordinates
42
    basegfx::B2DPoint                               maPosition;
43
44
public:
45
    ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos);
46
47
    // The OverlayObjects are cleared using the destructor of OverlayObjectList.
48
    // That destructor calls clear() at the list which removes all objects from the
49
    // OverlayManager and deletes them.
50
51
    void SetPosition(const basegfx::B2DPoint& rNewPosition);
52
};
53
54
ImplPageOriginOverlay::ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos)
55
0
:   maPosition(rStartPos)
56
0
{
57
0
    for(sal_uInt32 a(0); a < rView.PaintWindowCount(); a++)
58
0
    {
59
0
        SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
60
0
        const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager();
61
62
0
        if (xTargetOverlay.is())
63
0
        {
64
0
            std::unique_ptr<sdr::overlay::OverlayCrosshairStriped> aNew(new sdr::overlay::OverlayCrosshairStriped(
65
0
                maPosition));
66
0
            xTargetOverlay->add(*aNew);
67
0
            maObjects.append(std::move(aNew));
68
0
        }
69
0
    }
70
0
}
71
72
void ImplPageOriginOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
73
0
{
74
0
    if(rNewPosition == maPosition)
75
0
        return;
76
77
    // apply to OverlayObjects
78
0
    for(sal_uInt32 a(0); a < maObjects.count(); a++)
79
0
    {
80
0
        sdr::overlay::OverlayCrosshairStriped* pCandidate =
81
0
            static_cast< sdr::overlay::OverlayCrosshairStriped* >(&maObjects.getOverlayObject(a));
82
83
0
        if(pCandidate)
84
0
        {
85
0
            pCandidate->setBasePosition(rNewPosition);
86
0
        }
87
0
    }
88
89
    // remember new position
90
0
    maPosition = rNewPosition;
91
0
}
92
93
94
class ImplHelpLineOverlay
95
{
96
    // The OverlayObjects
97
    sdr::overlay::OverlayObjectList               maObjects;
98
99
    // The current position in logical coordinates
100
    basegfx::B2DPoint                               maPosition;
101
102
    // HelpLine specific stuff
103
    SdrPageView*                                    mpPageView;
104
    sal_uInt16                                      mnHelpLineNumber;
105
    SdrHelpLineKind                                 meHelpLineKind;
106
107
public:
108
    ImplHelpLineOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
109
        SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind);
110
111
    // The OverlayObjects are cleared using the destructor of OverlayObjectList.
112
    // That destructor calls clear() at the list which removes all objects from the
113
    // OverlayManager and deletes them.
114
115
    void SetPosition(const basegfx::B2DPoint& rNewPosition);
116
117
    // access to HelpLine specific stuff
118
0
    SdrPageView* GetPageView() const { return mpPageView; }
119
0
    sal_uInt16 GetHelpLineNumber() const { return mnHelpLineNumber; }
120
0
    SdrHelpLineKind GetHelpLineKind() const { return meHelpLineKind; }
121
};
122
123
ImplHelpLineOverlay::ImplHelpLineOverlay(
124
    const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
125
    SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind)
126
0
:   maPosition(rStartPos),
127
0
    mpPageView(pPageView),
128
0
    mnHelpLineNumber(nHelpLineNumber),
129
0
    meHelpLineKind(eKind)
130
0
{
131
0
    for(sal_uInt32 a(0); a < rView.PaintWindowCount(); a++)
132
0
    {
133
0
        SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
134
0
        const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager();
135
136
0
        if (xTargetOverlay.is())
137
0
        {
138
0
            std::unique_ptr<sdr::overlay::OverlayHelplineStriped> aNew(new sdr::overlay::OverlayHelplineStriped(
139
0
                maPosition, meHelpLineKind));
140
0
            xTargetOverlay->add(*aNew);
141
0
            maObjects.append(std::move(aNew));
142
0
        }
143
0
    }
144
0
}
145
146
void ImplHelpLineOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
147
0
{
148
0
    if(rNewPosition == maPosition)
149
0
        return;
150
151
    // apply to OverlayObjects
152
0
    for(sal_uInt32 a(0); a < maObjects.count(); a++)
153
0
    {
154
0
        sdr::overlay::OverlayHelplineStriped* pCandidate =
155
0
            static_cast< sdr::overlay::OverlayHelplineStriped* >(&maObjects.getOverlayObject(a));
156
157
0
        if(pCandidate)
158
0
        {
159
0
            pCandidate->setBasePosition(rNewPosition);
160
0
        }
161
0
    }
162
163
    // remember new position
164
0
    maPosition = rNewPosition;
165
0
}
166
167
SdrSnapView::SdrSnapView(
168
    SdrModel& rSdrModel,
169
    OutputDevice* pOut)
170
391k
:   SdrPaintView(rSdrModel, pOut)
171
391k
    ,mpPageOriginOverlay(nullptr)
172
391k
    ,mpHelpLineOverlay(nullptr)
173
391k
    ,mnMagnSizPix(4)
174
391k
    ,mnSnapAngle(1500)
175
391k
    ,mnEliminatePolyPointLimitAngle(0)
176
391k
    ,meCrookMode(SdrCrookMode::Rotate)
177
391k
    ,mbSnapEnab(true)
178
391k
    ,mbGridSnap(true)
179
391k
    ,mbBordSnap(true)
180
391k
    ,mbHlplSnap(true)
181
391k
    ,mbOFrmSnap(true)
182
391k
    ,mbOPntSnap(false)
183
391k
    ,mbOConSnap(true)
184
391k
    ,mbMoveSnapOnlyTopLeft(false)
185
391k
    ,mbOrtho(false)
186
391k
    ,mbBigOrtho(true)
187
391k
    ,mbAngleSnapEnab(false)
188
391k
    ,mbMoveOnlyDragging(false)
189
391k
    ,mbSlantButShear(false)
190
391k
    ,mbCrookNoContortion(false)
191
391k
    ,mbEliminatePolyPoints(false)
192
391k
{
193
391k
}
194
195
SdrSnapView::~SdrSnapView()
196
391k
{
197
391k
    BrkSetPageOrg();
198
391k
    BrkDragHelpLine();
199
391k
}
200
201
202
bool SdrSnapView::IsAction() const
203
0
{
204
0
    return IsSetPageOrg() || IsDragHelpLine() || SdrPaintView::IsAction();
205
0
}
206
207
void SdrSnapView::MovAction(const Point& rPnt)
208
0
{
209
0
    SdrPaintView::MovAction(rPnt);
210
0
    if (IsSetPageOrg()) {
211
0
        MovSetPageOrg(rPnt);
212
0
    }
213
0
    if (IsDragHelpLine()) {
214
0
        MovDragHelpLine(rPnt);
215
0
    }
216
0
}
217
218
void SdrSnapView::EndAction()
219
0
{
220
0
    if (IsSetPageOrg()) {
221
0
        EndSetPageOrg();
222
0
    }
223
0
    if (IsDragHelpLine()) {
224
0
        EndDragHelpLine();
225
0
    }
226
0
    SdrPaintView::EndAction();
227
0
}
228
229
void SdrSnapView::BckAction()
230
0
{
231
0
    BrkSetPageOrg();
232
0
    BrkDragHelpLine();
233
0
    SdrPaintView::BckAction();
234
0
}
235
236
void SdrSnapView::BrkAction()
237
80.6k
{
238
80.6k
    BrkSetPageOrg();
239
80.6k
    BrkDragHelpLine();
240
80.6k
    SdrPaintView::BrkAction();
241
80.6k
}
242
243
void SdrSnapView::TakeActionRect(tools::Rectangle& rRect) const
244
0
{
245
0
    if (IsSetPageOrg() || IsDragHelpLine()) {
246
0
        rRect=tools::Rectangle(maDragStat.GetNow(),maDragStat.GetNow());
247
0
    } else {
248
0
        SdrPaintView::TakeActionRect(rRect);
249
0
    }
250
0
}
251
252
253
Point SdrSnapView::GetSnapPos(const Point& rPnt, const SdrPageView* pPV) const
254
0
{
255
0
    Point aPt(rPnt);
256
0
    SnapPos(aPt,pPV);
257
0
    return aPt;
258
0
}
259
260
0
#define NOT_SNAPPED 0x7FFFFFFF
261
SdrSnap SdrSnapView::SnapPos(Point& rPnt, const SdrPageView* pPV) const
262
0
{
263
0
    if (!mbSnapEnab) return SdrSnap::NOTSNAPPED;
264
0
    tools::Long x=rPnt.X();
265
0
    tools::Long y=rPnt.Y();
266
0
    if (pPV==nullptr) {
267
0
        pPV=GetSdrPageView();
268
0
        if (pPV==nullptr) return SdrSnap::NOTSNAPPED;
269
0
    }
270
271
0
    tools::Long dx=NOT_SNAPPED;
272
0
    tools::Long dy=NOT_SNAPPED;
273
0
    tools::Long dx1,dy1;
274
0
    tools::Long mx=maMagnSiz.Width();
275
0
    tools::Long my=maMagnSiz.Height();
276
0
    if (mbHlplVisible && mbHlplSnap && !IsDragHelpLine())
277
0
    {
278
0
        const SdrHelpLineList& rHLL=pPV->GetHelpLines();
279
0
        sal_uInt16 nCount=rHLL.GetCount();
280
0
        for (sal_uInt16 i=nCount; i>0;) {
281
0
            i--;
282
0
            const SdrHelpLine& rHL=rHLL[i];
283
0
            const Point& rPos=rHL.GetPos();
284
0
            switch (rHL.GetKind()) {
285
0
                case SdrHelpLineKind::Vertical: {
286
0
                    tools::Long a=x-rPos.X();
287
0
                    if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; }
288
0
                } break;
289
0
                case SdrHelpLineKind::Horizontal: {
290
0
                    tools::Long b=y-rPos.Y();
291
0
                    if (std::abs(b)<=my) { dy1=-b; if (std::abs(dy1)<std::abs(dy)) dy=dy1; }
292
0
                } break;
293
0
                case SdrHelpLineKind::Point: {
294
0
                    tools::Long a=x-rPos.X();
295
0
                    tools::Long b=y-rPos.Y();
296
0
                    if (std::abs(a)<=mx && std::abs(b)<=my) {
297
0
                        dx1=-a; dy1=-b;
298
0
                        if (std::abs(dx1)<std::abs(dx) && std::abs(dy1)<std::abs(dy)) { dx=dx1; dy=dy1; }
299
0
                    }
300
0
                } break;
301
0
            } // switch
302
0
        }
303
0
    }
304
0
    if (mbBordVisible && mbBordSnap) {
305
0
        SdrPage* pPage=pPV->GetPage();
306
0
        tools::Long xs=pPage->GetWidth();
307
0
        tools::Long ys=pPage->GetHeight();
308
0
        tools::Long lft=pPage->GetLeftBorder();
309
0
        tools::Long rgt=pPage->GetRightBorder();
310
0
        tools::Long upp=pPage->GetUpperBorder();
311
0
        tools::Long lwr=pPage->GetLowerBorder();
312
0
        tools::Long a;
313
0
        a=x- lft    ; if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // left margin
314
0
        a=x-(xs-rgt); if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // right margin
315
0
        a=x         ; if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // left edge of paper
316
0
        a=x- xs     ; if (std::abs(a)<=mx) { dx1=-a; if (std::abs(dx1)<std::abs(dx)) dx=dx1; } // right edge of paper
317
0
        a=y- upp    ; if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // left margin
318
0
        a=y-(ys-lwr); if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // right margin
319
0
        a=y         ; if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // left edge of paper
320
0
        a=y- ys     ; if (std::abs(a)<=my) { dy1=-a; if (std::abs(dy1)<std::abs(dy)) dy=dy1; } // right edge of paper
321
0
    }
322
0
    if (mbOFrmSnap || mbOPntSnap) {
323
0
        sal_uInt32 nMaxPointSnapCount=200;
324
0
        sal_uInt32 nMaxFrameSnapCount=200;
325
326
        // go back to SdrIterMode::DeepNoGroups runthrough for snap to object comparisons
327
0
        SdrObjListIter aIter(pPV->GetPage(),SdrIterMode::DeepNoGroups,true);
328
329
0
        while (aIter.IsMore() && (nMaxPointSnapCount>0 || nMaxFrameSnapCount>0)) {
330
0
            SdrObject* pO=aIter.Next();
331
0
            tools::Rectangle aRect(pO->GetCurrentBoundRect());
332
0
            aRect.AdjustLeft( -mx );
333
0
            aRect.AdjustRight(mx );
334
0
            aRect.AdjustTop( -my );
335
0
            aRect.AdjustBottom(my );
336
0
            if (aRect.Contains(rPnt)) {
337
0
                if (mbOPntSnap && nMaxPointSnapCount>0)
338
0
                {
339
0
                    sal_uInt32 nCount(pO->GetSnapPointCount());
340
0
                    for (sal_uInt32 i(0); i < nCount && nMaxPointSnapCount > 0; i++)
341
0
                    {
342
0
                        Point aP(pO->GetSnapPoint(i));
343
0
                        dx1=x-aP.X();
344
0
                        dy1=y-aP.Y();
345
0
                        if (std::abs(dx1)<=mx && std::abs(dy1)<=my && std::abs(dx1)<std::abs(dx) && std::abs(dy1)<std::abs(dy)) {
346
0
                            dx=-dx1;
347
0
                            dy=-dy1;
348
0
                        }
349
0
                        nMaxPointSnapCount--;
350
0
                    }
351
0
                }
352
0
                if (mbOFrmSnap && nMaxFrameSnapCount>0) {
353
0
                    tools::Rectangle aLog(pO->GetSnapRect());
354
0
                    tools::Rectangle aR1(aLog);
355
0
                    aR1.AdjustLeft( -mx );
356
0
                    aR1.AdjustRight(mx );
357
0
                    aR1.AdjustTop( -my );
358
0
                    aR1.AdjustBottom(my );
359
0
                    if (aR1.Contains(rPnt)) {
360
0
                        if (std::abs(x-aLog.Left  ())<=mx) { dx1=-(x-aLog.Left  ()); if (std::abs(dx1)<std::abs(dx)) dx=dx1; }
361
0
                        if (std::abs(x-aLog.Right ())<=mx) { dx1=-(x-aLog.Right ()); if (std::abs(dx1)<std::abs(dx)) dx=dx1; }
362
0
                        if (std::abs(y-aLog.Top   ())<=my) { dy1=-(y-aLog.Top   ()); if (std::abs(dy1)<std::abs(dy)) dy=dy1; }
363
0
                        if (std::abs(y-aLog.Bottom())<=my) { dy1=-(y-aLog.Bottom()); if (std::abs(dy1)<std::abs(dy)) dy=dy1; }
364
0
                    }
365
0
                    nMaxFrameSnapCount--;
366
0
                }
367
0
            }
368
0
        }
369
0
    }
370
0
    if(mbGridSnap)
371
0
    {
372
0
        double fSnapWidth(maSnapWdtX);
373
0
        if(dx == NOT_SNAPPED && fSnapWidth != 0.0)
374
0
        {
375
0
            double fx = static_cast<double>(x);
376
377
            // round instead of trunc
378
0
            if(fx - static_cast<double>(pPV->GetPageOrigin().X()) >= 0.0)
379
0
                fx += fSnapWidth / 2.0;
380
0
            else
381
0
                fx -= fSnapWidth / 2.0;
382
383
0
            x = static_cast<tools::Long>((fx - static_cast<double>(pPV->GetPageOrigin().X())) / fSnapWidth);
384
0
            x = static_cast<tools::Long>(static_cast<double>(x) * fSnapWidth + static_cast<double>(pPV->GetPageOrigin().X()));
385
0
            dx = 0;
386
0
        }
387
0
        fSnapWidth = double(maSnapWdtY);
388
0
        if(dy == NOT_SNAPPED && fSnapWidth)
389
0
        {
390
0
            double fy = static_cast<double>(y);
391
392
            // round instead of trunc
393
0
            if(fy - static_cast<double>(pPV->GetPageOrigin().Y()) >= 0.0)
394
0
                fy += fSnapWidth / 2.0;
395
0
            else
396
0
                fy -= fSnapWidth / 2.0;
397
398
0
            y = static_cast<tools::Long>((fy - static_cast<double>(pPV->GetPageOrigin().Y())) / fSnapWidth);
399
0
            y = static_cast<tools::Long>(static_cast<double>(y) * fSnapWidth + static_cast<double>(pPV->GetPageOrigin().Y()));
400
0
            dy = 0;
401
0
        }
402
0
    }
403
0
    SdrSnap bRet=SdrSnap::NOTSNAPPED;
404
0
    if (dx==NOT_SNAPPED) dx=0; else bRet|=SdrSnap::XSNAPPED;
405
0
    if (dy==NOT_SNAPPED) dy=0; else bRet|=SdrSnap::YSNAPPED;
406
0
    rPnt.setX(x+dx );
407
0
    rPnt.setY(y+dy );
408
0
    return bRet;
409
0
}
410
411
void SdrSnapView::CheckSnap(const Point& rPt, tools::Long& nBestXSnap, tools::Long& nBestYSnap, bool& bXSnapped, bool& bYSnapped) const
412
0
{
413
0
    Point aPt(rPt);
414
0
    SdrSnap nRet=SnapPos(aPt,nullptr);
415
0
    aPt-=rPt;
416
0
    if (nRet & SdrSnap::XSNAPPED) {
417
0
        if (bXSnapped) {
418
0
            if (std::abs(aPt.X())<std::abs(nBestXSnap)) {
419
0
                nBestXSnap=aPt.X();
420
0
            }
421
0
        } else {
422
0
            nBestXSnap=aPt.X();
423
0
            bXSnapped=true;
424
0
        }
425
0
    }
426
0
    if (nRet & SdrSnap::YSNAPPED) {
427
0
        if (bYSnapped) {
428
0
            if (std::abs(aPt.Y())<std::abs(nBestYSnap)) {
429
0
                nBestYSnap=aPt.Y();
430
0
            }
431
0
        } else {
432
0
            nBestYSnap=aPt.Y();
433
0
            bYSnapped=true;
434
0
        }
435
0
    }
436
0
}
437
438
439
void SdrSnapView::BegSetPageOrg(const Point& rPnt)
440
0
{
441
0
    BrkAction();
442
443
0
    DBG_ASSERT(nullptr == mpPageOriginOverlay, "SdrSnapView::BegSetPageOrg: There exists an ImplPageOriginOverlay (!)");
444
0
    basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
445
0
    mpPageOriginOverlay = new ImplPageOriginOverlay(*this, aStartPos);
446
0
    maDragStat.Reset(GetSnapPos(rPnt,nullptr));
447
0
}
448
449
void SdrSnapView::MovSetPageOrg(const Point& rPnt)
450
0
{
451
0
    if(IsSetPageOrg())
452
0
    {
453
0
        maDragStat.NextMove(GetSnapPos(rPnt,nullptr));
454
0
        DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
455
0
        basegfx::B2DPoint aNewPos(maDragStat.GetNow().X(), maDragStat.GetNow().Y());
456
0
        mpPageOriginOverlay->SetPosition(aNewPos);
457
0
    }
458
0
}
459
460
void SdrSnapView::EndSetPageOrg()
461
0
{
462
0
    if(!IsSetPageOrg())
463
0
        return;
464
465
0
    SdrPageView* pPV = GetSdrPageView();
466
467
0
    if(pPV)
468
0
    {
469
0
        Point aPnt(maDragStat.GetNow());
470
0
        pPV->SetPageOrigin(aPnt);
471
0
    }
472
473
    // cleanup
474
0
    BrkSetPageOrg();
475
0
}
476
477
void SdrSnapView::BrkSetPageOrg()
478
472k
{
479
472k
    if(IsSetPageOrg())
480
0
    {
481
0
        DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
482
0
        delete mpPageOriginOverlay;
483
0
        mpPageOriginOverlay = nullptr;
484
0
    }
485
472k
}
486
487
488
bool SdrSnapView::PickHelpLine(const Point& rPnt, short nTol, const OutputDevice& rOut, sal_uInt16& rnHelpLineNum, SdrPageView*& rpPV) const
489
0
{
490
0
    rpPV=nullptr;
491
0
    nTol=ImpGetHitTolLogic(nTol,&rOut);
492
0
    SdrPageView* pPV = GetSdrPageView();
493
494
0
    if(pPV)
495
0
    {
496
0
        Point aPnt(rPnt);
497
0
        sal_uInt16 nIndex=pPV->GetHelpLines().HitTest(aPnt,sal_uInt16(nTol),rOut);
498
0
        if (nIndex!=SDRHELPLINE_NOTFOUND) {
499
0
            rpPV=pPV;
500
0
            rnHelpLineNum=nIndex;
501
0
            return true;
502
0
        }
503
0
    }
504
0
    return false;
505
0
}
506
507
// start HelpLine drag for new HelpLine
508
bool SdrSnapView::BegDragHelpLine(sal_uInt16 nHelpLineNum, SdrPageView* pPV)
509
0
{
510
0
    bool bRet(false);
511
512
0
    BrkAction();
513
514
0
    if(pPV && nHelpLineNum < pPV->GetHelpLines().GetCount())
515
0
    {
516
0
        const SdrHelpLineList& rHelpLines = pPV->GetHelpLines();
517
0
        const SdrHelpLine& rHelpLine = rHelpLines[nHelpLineNum];
518
0
        Point aHelpLinePos = rHelpLine.GetPos();
519
0
        basegfx::B2DPoint aStartPos(aHelpLinePos.X(), aHelpLinePos.Y());
520
521
0
        DBG_ASSERT(nullptr == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists an ImplHelpLineOverlay (!)");
522
0
        mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, pPV, nHelpLineNum, rHelpLine.GetKind());
523
524
0
        maDragStat.Reset(GetSnapPos(aHelpLinePos, pPV));
525
0
        maDragStat.SetMinMove(ImpGetMinMovLogic(-3, nullptr));
526
527
0
        bRet = true;
528
0
    }
529
530
0
    return bRet;
531
0
}
532
533
// start HelpLine drag with existing HelpLine
534
void SdrSnapView::BegDragHelpLine(const Point& rPnt, SdrHelpLineKind eNewKind)
535
0
{
536
0
    BrkAction();
537
538
0
    if(GetSdrPageView())
539
0
    {
540
0
        DBG_ASSERT(nullptr == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists an ImplHelpLineOverlay (!)");
541
0
        basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
542
0
        mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, nullptr, 0, eNewKind);
543
0
        maDragStat.Reset(GetSnapPos(rPnt, nullptr));
544
0
    }
545
0
}
546
547
PointerStyle SdrSnapView::GetDraggedHelpLinePointer() const
548
0
{
549
0
    if(IsDragHelpLine())
550
0
    {
551
0
        switch(mpHelpLineOverlay->GetHelpLineKind())
552
0
        {
553
0
            case SdrHelpLineKind::Vertical  : return PointerStyle::ESize;
554
0
            case SdrHelpLineKind::Horizontal: return PointerStyle::SSize;
555
0
            default                    : return PointerStyle::Move;
556
0
        }
557
0
    }
558
559
0
    return PointerStyle::Move;
560
0
}
561
562
void SdrSnapView::MovDragHelpLine(const Point& rPnt)
563
0
{
564
0
    if(IsDragHelpLine() && maDragStat.CheckMinMoved(rPnt))
565
0
    {
566
0
        Point aPnt(GetSnapPos(rPnt, nullptr));
567
568
0
        if(aPnt != maDragStat.GetNow())
569
0
        {
570
0
            maDragStat.NextMove(aPnt);
571
0
            DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::MovDragHelpLine: no ImplHelpLineOverlay (!)");
572
0
            basegfx::B2DPoint aNewPos(maDragStat.GetNow().X(), maDragStat.GetNow().Y());
573
0
            mpHelpLineOverlay->SetPosition(aNewPos);
574
0
        }
575
0
    }
576
0
}
577
578
bool SdrSnapView::EndDragHelpLine()
579
0
{
580
0
    bool bRet(false);
581
582
0
    if(IsDragHelpLine())
583
0
    {
584
0
        if(maDragStat.IsMinMoved())
585
0
        {
586
0
            SdrPageView* pPageView = mpHelpLineOverlay->GetPageView();
587
588
0
            if(pPageView)
589
0
            {
590
                // moved existing one
591
0
                Point aPnt(maDragStat.GetNow());
592
0
                const SdrHelpLineList& rHelpLines = pPageView->GetHelpLines();
593
0
                SdrHelpLine aChangedHelpLine = rHelpLines[mpHelpLineOverlay->GetHelpLineNumber()];
594
0
                aChangedHelpLine.SetPos(aPnt);
595
0
                pPageView->SetHelpLine(mpHelpLineOverlay->GetHelpLineNumber(), aChangedHelpLine);
596
597
0
                bRet = true;
598
0
            }
599
0
            else
600
0
            {
601
                // create new one
602
0
                pPageView = GetSdrPageView();
603
604
0
                if(pPageView)
605
0
                {
606
0
                    Point aPnt(maDragStat.GetNow());
607
0
                    SdrHelpLine aNewHelpLine(mpHelpLineOverlay->GetHelpLineKind(), aPnt);
608
0
                    pPageView->InsertHelpLine(aNewHelpLine);
609
610
0
                    bRet = true;
611
0
                }
612
0
            }
613
0
        }
614
615
        // cleanup
616
0
        BrkDragHelpLine();
617
0
    }
618
619
0
    return bRet;
620
0
}
621
622
void SdrSnapView::BrkDragHelpLine()
623
472k
{
624
472k
    if(IsDragHelpLine())
625
0
    {
626
0
        DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::EndDragHelpLine: no ImplHelpLineOverlay (!)");
627
0
        delete mpHelpLineOverlay;
628
0
        mpHelpLineOverlay = nullptr;
629
0
    }
630
472k
}
631
632
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */