Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/func/fuediglu.cxx
Line
Count
Source
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
#include <fuediglu.hxx>
21
#include <svl/eitem.hxx>
22
#include <svx/svdglue.hxx>
23
#include <sfx2/request.hxx>
24
25
#include <app.hrc>
26
27
#include <Window.hxx>
28
#include <View.hxx>
29
#include <ViewShell.hxx>
30
#include <ViewShellBase.hxx>
31
#include <ToolBarManager.hxx>
32
33
namespace sd {
34
35
36
FuEditGluePoints::FuEditGluePoints (
37
    ViewShell& rViewSh,
38
    ::sd::Window* pWin,
39
    ::sd::View* pView,
40
    SdDrawDocument& rDoc,
41
    SfxRequest& rReq)
42
0
    : FuDraw(rViewSh, pWin, pView, rDoc, rReq)
43
     //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point,
44
     //and SHIFT+ENTER key to decide the position and draw the new insert point
45
0
     ,bBeginInsertPoint(false),
46
0
    oldPoint(0,0)
47
0
{
48
0
}
49
50
rtl::Reference<FuPoor> FuEditGluePoints::Create( ViewShell& rViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument& rDoc, SfxRequest& rReq, bool bPermanent )
51
0
{
52
0
    FuEditGluePoints* pFunc;
53
0
    rtl::Reference<FuPoor> xFunc( pFunc = new FuEditGluePoints( rViewSh, pWin, pView, rDoc, rReq ) );
54
0
    xFunc->DoExecute(rReq);
55
0
    pFunc->SetPermanent( bPermanent );
56
0
    return xFunc;
57
0
}
58
59
void FuEditGluePoints::DoExecute( SfxRequest& rReq )
60
0
{
61
0
    FuDraw::DoExecute( rReq );
62
0
    mpView->SetInsGluePointMode(false);
63
0
    mrViewShell.GetViewShellBase().GetToolBarManager()->AddToolBar(
64
0
        ToolBarManager::ToolBarGroup::Function,
65
0
        ToolBarManager::msGluePointsToolBar);
66
0
}
67
68
FuEditGluePoints::~FuEditGluePoints()
69
0
{
70
0
    mpView->BrkAction();
71
0
    mpView->UnmarkAllGluePoints();
72
0
    mpView->SetInsGluePointMode(false);
73
0
}
74
75
bool FuEditGluePoints::MouseButtonDown(const MouseEvent& rMEvt)
76
0
{
77
0
    mpView->SetActualWin( mpWindow->GetOutDev() );
78
79
0
    bool bReturn = FuDraw::MouseButtonDown(rMEvt);
80
81
0
    if (mpView->IsAction())
82
0
    {
83
0
        if (rMEvt.IsRight())
84
0
            mpView->BckAction();
85
86
0
        return true;
87
0
    }
88
89
0
    if (rMEvt.IsLeft())
90
0
    {
91
0
        bReturn = true;
92
0
        sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
93
0
        sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() );
94
0
        mpWindow->CaptureMouse();
95
96
0
        SdrViewEvent aVEvt;
97
0
        SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
98
99
0
        if (eHit == SdrHitKind::Handle)
100
0
        {
101
            // drag handle
102
0
            SdrHdl* pHdl = aVEvt.mpHdl;
103
104
0
            if (mpView->IsGluePointMarked(aVEvt.mpObj, aVEvt.mnGlueId) && rMEvt.IsShift())
105
0
            {
106
0
                mpView->UnmarkGluePoint(aVEvt.mpObj, aVEvt.mnGlueId);
107
0
                pHdl = nullptr;
108
0
            }
109
110
0
            if (pHdl)
111
0
            {
112
                // drag handle
113
0
                mpView->BegDragObj(aMDPos, nullptr, aVEvt.mpHdl, nDrgLog);
114
0
            }
115
0
        }
116
0
        else if (eHit == SdrHitKind::MarkedObject && mpView->IsInsGluePointMode())
117
0
        {
118
            // insert gluepoints
119
0
            mpView->BegInsGluePoint(aMDPos);
120
0
        }
121
0
        else if (eHit == SdrHitKind::MarkedObject && rMEvt.IsMod1())
122
0
        {
123
            // select gluepoints
124
0
            if (!rMEvt.IsShift())
125
0
                mpView->UnmarkAllGluePoints();
126
127
0
            mpView->BegMarkGluePoints(aMDPos);
128
0
        }
129
0
        else if (eHit == SdrHitKind::MarkedObject && !rMEvt.IsShift() && !rMEvt.IsMod2())
130
0
        {
131
            // move object
132
0
            mpView->BegDragObj(aMDPos, nullptr, nullptr, nDrgLog);
133
0
        }
134
0
        else if (eHit == SdrHitKind::Gluepoint)
135
0
        {
136
            // select gluepoints
137
0
            if (!rMEvt.IsShift())
138
0
                mpView->UnmarkAllGluePoints();
139
140
0
            mpView->MarkGluePoint(aVEvt.mpObj, aVEvt.mnGlueId, false);
141
0
            SdrHdl* pHdl = mpView->GetGluePointHdl(aVEvt.mpObj, aVEvt.mnGlueId);
142
143
0
            if (pHdl)
144
0
            {
145
0
                mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
146
0
            }
147
0
        }
148
0
        else
149
0
        {
150
            // select or drag object
151
0
            if (!rMEvt.IsShift() && !rMEvt.IsMod2() && eHit == SdrHitKind::UnmarkedObject)
152
0
            {
153
0
               mpView->UnmarkAllObj();
154
0
            }
155
156
0
            bool bMarked = false;
157
158
0
            if (!rMEvt.IsMod1())
159
0
            {
160
0
                if (rMEvt.IsMod2())
161
0
                {
162
0
                    bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift());
163
0
                }
164
0
                else
165
0
                {
166
0
                    bMarked = mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift());
167
0
                }
168
0
            }
169
170
0
            const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
171
0
            if (bMarked &&
172
0
                (!rMEvt.IsShift() || eHit == SdrHitKind::MarkedObject))
173
0
            {
174
                // move object
175
0
                mpView->BegDragObj(aMDPos, nullptr, aVEvt.mpHdl, nDrgLog);
176
0
            }
177
0
            else if (rMarkList.GetMarkCount() != 0)
178
0
            {
179
                // select gluepoint
180
0
                if (!rMEvt.IsShift())
181
0
                    mpView->UnmarkAllGluePoints();
182
183
0
                mpView->BegMarkGluePoints(aMDPos);
184
0
            }
185
0
            else
186
0
            {
187
                // select object
188
0
                mpView->BegMarkObj(aMDPos);
189
0
            }
190
0
        }
191
192
0
        ForcePointer(&rMEvt);
193
0
    }
194
195
0
    return bReturn;
196
0
}
197
198
bool FuEditGluePoints::MouseMove(const MouseEvent& rMEvt)
199
0
{
200
0
    mpView->SetActualWin( mpWindow->GetOutDev() );
201
202
0
    FuDraw::MouseMove(rMEvt);
203
204
0
    if (mpView->IsAction())
205
0
    {
206
0
        Point aPix(rMEvt.GetPosPixel());
207
0
        Point aPnt( mpWindow->PixelToLogic(aPix) );
208
0
        ForceScroll(aPix);
209
0
        mpView->MovAction(aPnt);
210
0
    }
211
212
0
    ForcePointer(&rMEvt);
213
214
0
    return true;
215
0
}
216
217
bool FuEditGluePoints::MouseButtonUp(const MouseEvent& rMEvt)
218
0
{
219
0
    mpView->SetActualWin( mpWindow->GetOutDev() );
220
221
0
    bool bReturn = false;
222
223
0
    if (mpView->IsAction())
224
0
    {
225
0
        bReturn = true;
226
0
        mpView->EndAction();
227
0
    }
228
229
0
    FuDraw::MouseButtonUp(rMEvt);
230
231
0
    sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() );
232
0
    Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
233
234
0
    if (std::abs(aMDPos.X() - aPos.X()) < nDrgLog &&
235
0
        std::abs(aMDPos.Y() - aPos.Y()) < nDrgLog &&
236
0
        !rMEvt.IsShift() && !rMEvt.IsMod2())
237
0
    {
238
0
        SdrViewEvent aVEvt;
239
0
        SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
240
241
0
        if (eHit == SdrHitKind::NONE)
242
0
        {
243
            // click on position: deselect
244
0
            mpView->UnmarkAllObj();
245
0
        }
246
0
    }
247
248
0
    mpWindow->ReleaseMouse();
249
250
0
    return bReturn;
251
0
}
252
253
/**
254
 * Process keyboard input
255
 * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
256
 */
257
bool FuEditGluePoints::KeyInput(const KeyEvent& rKEvt)
258
0
{
259
0
    mpView->SetActualWin( mpWindow->GetOutDev() );
260
261
    //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point,
262
    //and SHIFT+ENTER key to decide the position and draw the new insert point
263
264
0
    bool bReturn = false;
265
266
0
    switch (rKEvt.GetKeyCode().GetCode())
267
0
    {
268
0
        case KEY_UP:
269
0
        case KEY_DOWN:
270
0
        case KEY_LEFT:
271
0
        case KEY_RIGHT:
272
0
        {
273
0
            if(rKEvt.GetKeyCode().IsShift()&& mpView->IsInsGluePointMode() ){
274
0
                ::tools::Long nX = 0;
275
0
                ::tools::Long nY = 0;
276
0
                sal_uInt16  nCode = rKEvt.GetKeyCode().GetCode();
277
0
                if (nCode == KEY_UP)
278
0
                {
279
                    // scroll up
280
0
                    nX = 0;
281
0
                    nY =-1;
282
0
                }
283
0
                else if (nCode == KEY_DOWN)
284
0
                {
285
                    // scroll down
286
0
                    nX = 0;
287
0
                    nY = 1;
288
0
                }
289
0
                else if (nCode == KEY_LEFT)
290
0
                {
291
                    // scroll left
292
0
                    nX =-1;
293
0
                    nY = 0;
294
0
                }
295
0
                else if (nCode == KEY_RIGHT)
296
0
                {
297
                    // scroll right
298
0
                    nX = 1;
299
0
                    nY = 0;
300
0
                }
301
0
                Point centerPoint;
302
0
                ::tools::Rectangle rect = mpView->GetMarkedObjRect();
303
0
                centerPoint = mpWindow->LogicToPixel(rect.Center());
304
0
                Point aPoint = bBeginInsertPoint? oldPoint:centerPoint;
305
0
                Point ePoint = aPoint + Point(nX,nY);
306
0
                mpWindow->SetPointerPosPixel(ePoint);
307
                //simulate mouse move action
308
0
                MouseEvent eMevt(ePoint, 1, MouseEventModifiers::DRAGMOVE, MOUSE_LEFT, 0);
309
0
                MouseMove(eMevt);
310
0
                oldPoint = ePoint;
311
0
                bBeginInsertPoint = true;
312
0
                bReturn = true;
313
0
            }
314
0
        }
315
0
        break;
316
0
        case KEY_RETURN:
317
0
            if(rKEvt.GetKeyCode().IsShift() && mpView->IsInsGluePointMode() )
318
0
            {
319
0
                if(bBeginInsertPoint)
320
0
                {
321
0
                    mpWindow->SetPointerPosPixel(oldPoint);
322
                    //simulate mouse button down action
323
0
                    MouseEvent aMevt(oldPoint, 1,
324
0
                                     MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::DRAGMOVE,
325
0
                                     MOUSE_LEFT, KEY_SHIFT);
326
                    // MT IA2: Not used?
327
                    // sal_uInt16 ubuttons = aMevt.GetButtons();
328
                    // sal_uInt16 uMod      = aMevt.GetModifier();
329
0
                    MouseButtonDown(aMevt);
330
0
                    mpWindow->CaptureMouse();
331
                    //simulate mouse button up action
332
0
                    MouseEvent rMEvt(oldPoint+Point(0,0), 1,
333
0
                                     MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::ENTERWINDOW,
334
0
                                     MOUSE_LEFT, KEY_SHIFT);
335
0
                    MouseButtonUp(rMEvt);
336
0
                    bReturn= true;
337
0
                }
338
0
            }
339
0
            break;
340
0
    }
341
342
0
    if(!bReturn)
343
0
        bReturn = FuDraw::KeyInput(rKEvt);
344
345
0
    return bReturn;
346
0
}
347
348
//Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point, and
349
//SHIFT+ENTER key to decide the position and draw the new insert point
350
void FuEditGluePoints::ForcePointer(const MouseEvent* pMEvt)
351
0
{
352
0
    if(bBeginInsertPoint && pMEvt)
353
0
    {
354
0
        MouseEvent aMEvt(pMEvt->GetPosPixel(), pMEvt->GetClicks(),
355
0
            pMEvt->GetMode(), pMEvt->GetButtons(), pMEvt->GetModifier() & ~KEY_SHIFT);
356
0
        FuDraw::ForcePointer(&aMEvt);
357
0
    }
358
0
    else
359
0
    {
360
0
        FuDraw::ForcePointer(pMEvt);
361
0
    }
362
0
}
363
364
bool FuEditGluePoints::Command(const CommandEvent& rCEvt)
365
0
{
366
0
    mpView->SetActualWin( mpWindow->GetOutDev() );
367
0
    return FuPoor::Command( rCEvt );
368
0
}
369
370
void FuEditGluePoints::Activate()
371
0
{
372
0
    mpView->SetGluePointEditMode();
373
0
    FuDraw::Activate();
374
0
}
375
376
void FuEditGluePoints::Deactivate()
377
0
{
378
0
    mpView->SetGluePointEditMode( false );
379
0
    FuDraw::Deactivate();
380
0
}
381
382
void FuEditGluePoints::ReceiveRequest(SfxRequest& rReq)
383
0
{
384
0
    switch (rReq.GetSlot())
385
0
    {
386
0
        case SID_GLUE_INSERT_POINT:
387
0
        {
388
0
            mpView->SetInsGluePointMode(!mpView->IsInsGluePointMode());
389
0
        }
390
0
        break;
391
392
0
        case SID_GLUE_ESCDIR_LEFT:
393
0
        {
394
0
            mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::LEFT,
395
0
                    !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::LEFT ) );
396
0
        }
397
0
        break;
398
399
0
        case SID_GLUE_ESCDIR_RIGHT:
400
0
        {
401
0
            mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::RIGHT,
402
0
                    !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::RIGHT ) );
403
0
        }
404
0
        break;
405
406
0
        case SID_GLUE_ESCDIR_TOP:
407
0
        {
408
0
            mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::TOP,
409
0
                    !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::TOP ) );
410
0
        }
411
0
        break;
412
413
0
        case SID_GLUE_ESCDIR_BOTTOM:
414
0
        {
415
0
            mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::BOTTOM,
416
0
                    !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::BOTTOM ) );
417
0
        }
418
0
        break;
419
420
0
        case SID_GLUE_PERCENT:
421
0
        {
422
0
            const SfxItemSet* pSet = rReq.GetArgs();
423
0
            const SfxPoolItem& rItem = pSet->Get(SID_GLUE_PERCENT);
424
0
            bool bPercent = static_cast<const SfxBoolItem&>(rItem).GetValue();
425
0
            mpView->SetMarkedGluePointsPercent(bPercent);
426
0
        }
427
0
        break;
428
429
0
        case SID_GLUE_HORZALIGN_CENTER:
430
0
        {
431
0
            mpView->SetMarkedGluePointsAlign(false, SdrAlign::HORZ_CENTER);
432
0
        }
433
0
        break;
434
435
0
        case SID_GLUE_HORZALIGN_LEFT:
436
0
        {
437
0
            mpView->SetMarkedGluePointsAlign(false, SdrAlign::HORZ_LEFT);
438
0
        }
439
0
        break;
440
441
0
        case SID_GLUE_HORZALIGN_RIGHT:
442
0
        {
443
0
            mpView->SetMarkedGluePointsAlign(false, SdrAlign::HORZ_RIGHT);
444
0
        }
445
0
        break;
446
447
0
        case SID_GLUE_VERTALIGN_CENTER:
448
0
        {
449
0
            mpView->SetMarkedGluePointsAlign(true, SdrAlign::VERT_CENTER);
450
0
        }
451
0
        break;
452
453
0
        case SID_GLUE_VERTALIGN_TOP:
454
0
        {
455
0
            mpView->SetMarkedGluePointsAlign(true, SdrAlign::VERT_TOP);
456
0
        }
457
0
        break;
458
459
0
        case SID_GLUE_VERTALIGN_BOTTOM:
460
0
        {
461
0
            mpView->SetMarkedGluePointsAlign(true, SdrAlign::VERT_BOTTOM);
462
0
        }
463
0
        break;
464
0
    }
465
466
    // at the end, call base class
467
0
    FuPoor::ReceiveRequest(rReq);
468
0
}
469
470
} // end of namespace sd
471
472
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */