Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/func/fusel.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 <fusel.hxx>
21
#include <svx/svddrgmt.hxx>
22
#include <svx/svdpagv.hxx>
23
#include <svx/svdopage.hxx>
24
#include <svx/svdogrp.hxx>
25
#include <svx/scene3d.hxx>
26
#include <vcl/imapobj.hxx>
27
#include <unotools/securityoptions.hxx>
28
#include <svx/svxids.hrc>
29
#include <svx/xfillit0.hxx>
30
#include <svx/ImageMapInfo.hxx>
31
#include <sfx2/viewfrm.hxx>
32
#include <svl/stritem.hxx>
33
#include <svl/intitem.hxx>
34
#include <sfx2/dispatch.hxx>
35
#include <sfx2/docfile.hxx>
36
#include <editeng/flditem.hxx>
37
38
#include <svx/svdotable.hxx>
39
40
#include <app.hrc>
41
42
#include <sdmod.hxx>
43
#include <DrawDocShell.hxx>
44
#include <stlpool.hxx>
45
#include <fudraw.hxx>
46
#include <ViewShell.hxx>
47
#include <ViewShellBase.hxx>
48
#include <FrameView.hxx>
49
#include <View.hxx>
50
#include <Window.hxx>
51
#include <drawdoc.hxx>
52
#include <DrawViewShell.hxx>
53
#include <ToolBarManager.hxx>
54
#include <Client.hxx>
55
#include <annotationmanager.hxx>
56
57
#include <svx/svdundo.hxx>
58
59
#include <svx/sdrhittesthelper.hxx>
60
#include <svx/diagram/DiagramHelper_svx.hxx>
61
#include <svx/annotation/ObjectAnnotationData.hxx>
62
63
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
64
#include <comphelper/lok.hxx>
65
#include <svl/cryptosign.hxx>
66
67
using namespace ::com::sun::star;
68
69
namespace sd {
70
71
FuSelection::FuSelection (
72
    ViewShell& rViewSh,
73
    ::sd::Window* pWin,
74
    ::sd::View* pView,
75
    SdDrawDocument& rDoc,
76
    SfxRequest& rReq)
77
0
    : FuDraw(rViewSh, pWin, pView, rDoc, rReq),
78
0
      bTempRotation(false),
79
0
      bSelectionChanged(false),
80
0
      pHdl(nullptr),
81
0
      bSuppressChangesOfSelection(false),
82
0
      bMirrorSide0(false),
83
0
      nEditMode(SID_BEZIER_MOVE),
84
0
      pWaterCanCandidate(nullptr)
85
     //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point,
86
     //and SHIFT+ENTER key to decide the position and draw the new insert point
87
0
    ,bBeginInsertPoint(false),
88
0
      oldPoint(0,0)
89
0
  ,bMovedToCenterPoint(false)
90
0
{
91
0
}
92
93
rtl::Reference<FuPoor> FuSelection::Create( ViewShell& rViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument& rDoc, SfxRequest& rReq )
94
0
{
95
0
    rtl::Reference<FuPoor> xFunc( new FuSelection( rViewSh, pWin, pView, rDoc, rReq ) );
96
0
    xFunc->DoExecute(rReq);
97
0
    return xFunc;
98
0
}
99
100
void FuSelection::DoExecute( SfxRequest& rReq )
101
0
{
102
0
    FuDraw::DoExecute( rReq );
103
104
    // Select object bar
105
0
    SelectionHasChanged();
106
0
}
107
108
FuSelection::~FuSelection()
109
0
{
110
0
    mpView->UnmarkAllPoints();
111
0
    mpView->ResetCreationActive();
112
113
0
    if ( mpView->GetDragMode() != SdrDragMode::Move )
114
0
    {
115
0
        mpView->SetDragMode(SdrDragMode::Move);
116
0
    }
117
0
}
118
119
namespace {
120
0
    bool lcl_followHyperlinkAllowed(const MouseEvent& rMEvt) {
121
0
        if (!rMEvt.IsMod1() && SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink))
122
0
            return false;
123
0
        if (rMEvt.IsMod1() && !SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink))
124
0
            return false;
125
0
        return true;
126
0
    }
127
}
128
129
bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
130
0
{
131
0
    pHdl = nullptr;
132
0
    bool bReturn = FuDraw::MouseButtonDown(rMEvt);
133
0
    bool bWaterCan = SdModule::get()->GetWaterCan();
134
0
    const bool bReadOnly = mpDocSh->IsReadOnly();
135
    // When the right mouse button is pressed then only select objects
136
    // (and deselect others) as a preparation for showing the context
137
    // menu.
138
0
    const bool bSelectionOnly = rMEvt.IsRight();
139
140
0
    bMBDown = true;
141
0
    bSelectionChanged = false;
142
143
0
    if ( mpView->IsAction() )
144
0
    {
145
0
        if ( rMEvt.IsRight() )
146
0
            mpView->BckAction();
147
0
        return true;
148
0
    }
149
150
0
    sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() );
151
0
    sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
152
153
0
    if (comphelper::LibreOfficeKit::isActive())
154
0
    {
155
        // When tiled rendering, we always work in logic units, use the non-pixel constants.
156
0
        nDrgLog = DRGLOG;
157
0
        nHitLog = HITLOG;
158
0
    }
159
160
    // The following code is executed for right clicks as well as for left
161
    // clicks in order to modify the selection for the right button as a
162
    // preparation for the context menu.  The functions BegMarkObject() and
163
    // BegDragObject(), however, are not called for right clicks because a)
164
    // it makes no sense and b) to have IsAction() return sal_False when called
165
    // from Command() which is a prerequisite for the context menu.
166
0
    if ((rMEvt.IsLeft() || rMEvt.IsRight())
167
0
        && !mpView->IsAction()
168
0
        && (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints()))
169
0
    {
170
        /******************************************************************
171
        * NO BEZIER_EDITOR
172
        ******************************************************************/
173
0
        mpWindow->CaptureMouse();
174
0
        pHdl = mpView->PickHandle(aMDPos);
175
176
0
        Degree100 nAngle0  = GetAngle(aMDPos - mpView->GetRef1());
177
0
        nAngle0 -= 27000_deg100;
178
0
        nAngle0 = NormAngle36000(nAngle0);
179
0
        bMirrorSide0 = nAngle0 < 18000_deg100;
180
181
0
        if (!pHdl && mpView->Is3DRotationCreationActive())
182
0
        {
183
            /******************************************************************
184
            * If 3D-rotation bodies are about to be created,
185
            * end creation now.
186
            ******************************************************************/
187
0
            bSuppressChangesOfSelection = true;
188
0
            mpWindow->EnterWait();
189
0
            mpView->End3DCreation();
190
0
            bSuppressChangesOfSelection = false;
191
0
            mpView->ResetCreationActive();
192
0
            mpWindow->LeaveWait();
193
0
        }
194
195
0
        bool bTextEdit = false;
196
0
        SdrViewEvent aVEvt;
197
0
        SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
198
199
0
        if (eHit == SdrHitKind::TextEditObj && (mrViewShell.GetFrameView()->IsQuickEdit() || dynamic_cast< sdr::table::SdrTableObj* >(aVEvt.mpObj) != nullptr))
200
0
        {
201
0
            bTextEdit = true;
202
0
        }
203
204
        // When clicking into a URl field, also go to text edit mode (when not following the link)
205
0
        if (!bTextEdit && eHit == SdrHitKind::UrlField && !rMEvt.IsMod2() && !lcl_followHyperlinkAllowed(rMEvt))
206
0
            bTextEdit = true;
207
208
0
        bool bPreventModify = mpDocSh->IsReadOnly();
209
0
        SfxViewShell* pViewShell = mrViewShell.GetViewShell();
210
0
        if (bPreventModify && pViewShell && pViewShell->GetSignPDFCertificate().Is())
211
0
        {
212
            // If the just added signature line shape is selected, allow moving / resizing it.
213
0
            bPreventModify = false;
214
0
        }
215
216
0
        if(!bTextEdit
217
0
            && !bPreventModify
218
0
            && ((mpView->IsMarkedHit(aMDPos, nHitLog) && !rMEvt.IsShift() && !rMEvt.IsMod2()) || pHdl != nullptr)
219
0
            && (rMEvt.GetClicks() != 2)
220
0
            )
221
0
        {
222
0
            if (!pHdl && mpView->Is3DRotationCreationActive())
223
0
            {
224
                // Switch between 3D-rotation body -> selection
225
0
                mpView->ResetCreationActive();
226
0
            }
227
0
            else if (bWaterCan)
228
0
            {
229
                // Remember the selected object for proper handling in
230
                // MouseButtonUp().
231
0
                pWaterCanCandidate = pickObject (aMDPos);
232
0
            }
233
0
            else
234
0
            {
235
                // hit handle or marked object
236
0
                bFirstMouseMove = true;
237
0
                aDragTimer.Start();
238
0
            }
239
240
0
            if ( ! rMEvt.IsRight())
241
0
                if (mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog))
242
0
                    mpView->GetDragMethod()->SetShiftPressed( rMEvt.IsShift() );
243
0
            bReturn = true;
244
0
        }
245
0
        else
246
0
        {
247
0
            SdrPageView* pPV = nullptr;
248
0
            SdrObject* pObj = !rMEvt.IsMod2() ? mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO) : nullptr;
249
0
            if (pObj)
250
0
            {
251
0
                mpView->BegMacroObj(aMDPos, nHitLog, pObj, pPV, mpWindow);
252
0
                bReturn = true;
253
0
            }
254
0
            else if ( bTextEdit )
255
0
            {
256
0
                SdrObjKind nSdrObjKind = aVEvt.mpObj->GetObjIdentifier();
257
258
0
                if (aVEvt.mpObj->GetObjInventor() == SdrInventor::Default &&
259
0
                    (nSdrObjKind == SdrObjKind::Text ||
260
0
                     nSdrObjKind == SdrObjKind::TitleText ||
261
0
                     nSdrObjKind == SdrObjKind::OutlineText ||
262
0
                     !aVEvt.mpObj->IsEmptyPresObj()))
263
0
                {
264
                    // Seamless Editing: branch to text input
265
0
                    if (!rMEvt.IsShift())
266
0
                        mpView->UnmarkAll();
267
268
0
                    SfxUInt16Item aItem(SID_TEXTEDIT, 1);
269
0
                    mrViewShell.GetViewFrame()->GetDispatcher()->
270
0
                    ExecuteList(SID_TEXTEDIT,
271
0
                            SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
272
0
                            { &aItem });
273
0
                    return bReturn; // CAUTION, due to the synchronous slot the object is deleted now
274
0
                }
275
0
            }
276
0
            else if ( !rMEvt.IsMod2() && rMEvt.GetClicks() == 1 &&
277
0
                      aVEvt.meEvent == SdrEventKind::ExecuteUrl )
278
0
             {
279
0
                mpWindow->ReleaseMouse();
280
281
0
                if (!aVEvt.mpURLField)
282
0
                    return true;
283
284
                // If tiled rendering, let client handles URL execution and early returns.
285
0
                if (comphelper::LibreOfficeKit::isActive())
286
0
                {
287
0
                    SfxViewShell& rSfxViewShell = mrViewShell.GetViewShellBase();
288
0
                    rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_HYPERLINK_CLICKED, aVEvt.mpURLField->GetURL().toUtf8());
289
0
                    return true;
290
0
                }
291
292
0
                if (!lcl_followHyperlinkAllowed(rMEvt))
293
0
                    return true;
294
295
0
                SfxStringItem aStrItem(SID_FILE_NAME, aVEvt.mpURLField->GetURL());
296
0
                SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName());
297
0
                SfxBoolItem aBrowseItem( SID_BROWSE, true );
298
0
                SfxViewFrame* pFrame = mrViewShell.GetViewFrame();
299
0
                mpWindow->ReleaseMouse();
300
301
0
                if (rMEvt.IsMod1())
302
0
                {
303
                    // Open in new frame
304
0
                    pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
305
0
                        SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
306
0
                        { &aStrItem, &aBrowseItem, &aReferer });
307
0
                }
308
0
                else
309
0
                {
310
                    // Open in current frame
311
0
                    SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
312
0
                    pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
313
0
                        SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
314
0
                        { &aStrItem, &aFrameItem, &aBrowseItem, &aReferer });
315
0
                }
316
317
0
                bReturn = true;
318
0
            }
319
0
            else if(!rMEvt.IsMod2()
320
0
                && dynamic_cast< const DrawViewShell *>( &mrViewShell ) !=  nullptr
321
0
                )
322
0
            {
323
0
                pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER);
324
0
                if (pObj)
325
0
                {
326
                    // Handle ImageMap click when not just selecting
327
0
                    if (!bSelectionOnly)
328
0
                    {
329
0
                        if (lcl_followHyperlinkAllowed(rMEvt))
330
0
                            bReturn = HandleImageMapClick(pObj, aMDPos);
331
0
                    }
332
333
0
                    if (!bReturn
334
0
                        && (dynamic_cast<const SdrObjGroup*>(pObj) != nullptr
335
0
                            || DynCastE3dScene(pObj)))
336
0
                    {
337
0
                        if (rMEvt.GetClicks() == 1)
338
0
                        {
339
                            // Look into the group
340
0
                            pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV,
341
0
                                                   SdrSearchOptions::ALSOONMASTER
342
0
                                                       | SdrSearchOptions::DEEP);
343
0
                            if (pObj && lcl_followHyperlinkAllowed(rMEvt))
344
0
                                bReturn = HandleImageMapClick(pObj, aMDPos);
345
0
                        }
346
0
                        else if (!bReadOnly && rMEvt.GetClicks() == 2)
347
0
                        {
348
                            // New: double click on selected Group object
349
                            // enter group
350
0
                            if (!bSelectionOnly
351
0
                                && pObj->getSdrPageFromSdrObject() == pPV->GetPage())
352
0
                                bReturn = pPV->EnterGroup(pObj);
353
0
                        }
354
0
                    }
355
0
                    else if (pObj->GetObjIdentifier() == SdrObjKind::Page)
356
0
                    {
357
0
                        if (rMEvt.GetClicks() == 2)
358
0
                        {
359
0
                            if (DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(&mrViewShell))
360
0
                            {
361
0
                                SdrPageObj* pPageObj = static_cast<SdrPageObj*>(pObj);
362
0
                                sal_uInt16 nPageNum = (pPageObj->GetReferencedPage()->GetPageNum() - 1) / 2;
363
0
                                pDrawViewShell->SwitchPage(nPageNum);
364
0
                            }
365
0
                        }
366
0
                    }
367
0
                }
368
369
                // #i71727# replaced else here with two possibilities, once the original else (!pObj)
370
                // and also ignoring the found object when it's on a masterpage
371
0
                if(!pObj || (pObj->getSdrPageFromSdrObject() && pObj->getSdrPageFromSdrObject()->IsMasterPage()))
372
0
                {
373
0
                    if(mpView->IsGroupEntered() && 2 == rMEvt.GetClicks())
374
0
                    {
375
                        // New: double click on empty space/on obj on MasterPage, leave group
376
0
                        mpView->LeaveOneGroup();
377
0
                        bReturn = true;
378
0
                    }
379
0
                }
380
0
            }
381
382
0
            if (!bReturn)
383
0
            {
384
0
                if (bWaterCan)
385
0
                {
386
0
                    if ( ! (rMEvt.IsShift() || rMEvt.IsMod2()))
387
0
                    {
388
                        // Find the object under the current mouse position
389
                        // and store it for the MouseButtonUp() method to
390
                        // evaluate.
391
0
                        pWaterCanCandidate = pickObject (aMDPos);
392
0
                    }
393
0
                }
394
0
                else
395
0
                {
396
0
                    bReturn = true;
397
0
                    bool bDeactivateOLE = false;
398
399
0
                    if ( !rMEvt.IsShift() && !rMEvt.IsMod2() )
400
0
                    {
401
0
                        OSL_ASSERT (mrViewShell.GetViewShell()!=nullptr);
402
0
                        Client* pIPClient = static_cast<Client*>(
403
0
                            mrViewShell.GetViewShell()->GetIPClient());
404
405
0
                        if (pIPClient && pIPClient->IsObjectInPlaceActive())
406
0
                        {
407
                            // OLE-object gets deactivated in subsequent UnmarkAll()
408
0
                            bDeactivateOLE = true;
409
0
                        }
410
411
0
                        mpView->UnmarkAll();
412
0
                    }
413
414
0
                    bool bMarked = false;
415
416
0
                    if ( !rMEvt.IsMod1() && !bDeactivateOLE)
417
0
                    {
418
0
                        if ( rMEvt.IsMod2() )
419
0
                        {
420
0
                            bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift() );
421
0
                        }
422
0
                        else
423
0
                        {
424
0
                            bool bToggle = false;
425
426
0
                            const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
427
0
                            if (rMEvt.IsShift() && rMarkList.GetMarkCount() > 1)
428
0
                            {
429
                                // No Toggle on single selection
430
0
                                bToggle = true;
431
0
                            }
432
433
0
                            bMarked = mpView->MarkObj(aMDPos, nHitLog, bToggle);
434
0
                        }
435
0
                    }
436
437
0
                    if( !bDeactivateOLE )
438
0
                    {
439
0
                        if ( !bReadOnly &&
440
0
                             bMarked                                                   &&
441
0
                             (!rMEvt.IsShift() || mpView->IsMarkedHit(aMDPos, nHitLog)))
442
0
                        {
443
                            /**********************************************************
444
                             * Move object
445
                             **********************************************************/
446
0
                            aDragTimer.Start();
447
448
0
                            pHdl=mpView->PickHandle(aMDPos);
449
0
                            if ( ! rMEvt.IsRight())
450
0
                                mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
451
452
0
                            if (comphelper::LibreOfficeKit::isActive())
453
0
                            {
454
0
                                if (pObj->GetObjIdentifier() == SdrObjKind::Page)
455
0
                                {
456
0
                                    SdPage* pPage = mrViewShell.GetActualPage();
457
0
                                    if (pPage->IsCanvasPage())
458
0
                                    {
459
0
                                        ::tools::JsonWriter jsonWriter;
460
0
                                        jsonWriter.put("commandName", "ReshufflePagePopup");
461
0
                                        {
462
0
                                            auto jsonState = jsonWriter.startNode("state");
463
0
                                        }
464
465
0
                                        OString aPayload = jsonWriter.finishAndGetAsOString();
466
0
                                        if (pViewShell)
467
0
                                            pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
468
469
0
                                    }
470
0
                                }
471
0
                            }
472
0
                        }
473
0
                        else
474
0
                        {
475
                            /**********************************************************
476
                             * Select object
477
                             **********************************************************/
478
0
                            if ( ! rMEvt.IsRight())
479
0
                                mpView->BegMarkObj(aMDPos);
480
0
                        }
481
0
                    }
482
483
0
                    if( bMarked && bTempRotation && (nSlotId == SID_OBJECT_ROTATE) && !rMEvt.IsShift() && (rMEvt.GetClicks() != 2) )
484
0
                    {
485
0
                        nSlotId = SID_OBJECT_SELECT;
486
0
                        Activate();
487
0
                    }
488
0
                }
489
0
            }
490
0
        }
491
0
    }
492
0
    else if ( !bReadOnly
493
0
              && (rMEvt.IsLeft() || rMEvt.IsRight())
494
0
              && !mpView->IsAction())
495
0
    {
496
        /**********************************************************************
497
        * BEZIER-EDITOR
498
        **********************************************************************/
499
0
        mpWindow->CaptureMouse();
500
0
        SdrViewEvent aVEvt;
501
0
        SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
502
503
0
        if (eHit == SdrHitKind::Handle && aVEvt.mpHdl->GetKind() == SdrHdlKind::BezierWeight)
504
0
        {
505
            /******************************************************************
506
            * Drag Handle
507
            ******************************************************************/
508
0
            if ( ! rMEvt.IsRight())
509
0
                mpView->BegDragObj(aMDPos, nullptr, aVEvt.mpHdl, nDrgLog);
510
0
        }
511
0
        else if (eHit == SdrHitKind::MarkedObject && nEditMode == SID_BEZIER_INSERT)
512
0
        {
513
            /******************************************************************
514
            * Insert gluepoint
515
            ******************************************************************/
516
0
            mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1());
517
0
        }
518
0
        else if (eHit == SdrHitKind::MarkedObject && rMEvt.IsMod1())
519
0
        {
520
            /******************************************************************
521
            * Select gluepoint
522
            ******************************************************************/
523
0
            if (!rMEvt.IsShift())
524
0
                mpView->UnmarkAllPoints();
525
526
0
            if ( ! rMEvt.IsRight())
527
0
                mpView->BegMarkPoints(aMDPos);
528
0
        }
529
0
        else if (eHit == SdrHitKind::MarkedObject && !rMEvt.IsShift() && !rMEvt.IsMod2())
530
0
        {
531
            /******************************************************************
532
            * Move object
533
            ******************************************************************/
534
0
            if ( ! rMEvt.IsRight())
535
0
                mpView->BegDragObj(aMDPos, nullptr, nullptr, nDrgLog);
536
0
        }
537
0
        else if (eHit == SdrHitKind::Handle)
538
0
        {
539
            /******************************************************************
540
            * Select gluepoint
541
            ******************************************************************/
542
0
            if (!mpView->IsPointMarked(*aVEvt.mpHdl) || rMEvt.IsShift())
543
0
            {
544
0
                if (!rMEvt.IsShift())
545
0
                {
546
0
                    mpView->UnmarkAllPoints();
547
0
                    pHdl = mpView->PickHandle(aMDPos);
548
0
                }
549
0
                else
550
0
                {
551
0
                    if (mpView->IsPointMarked(*aVEvt.mpHdl))
552
0
                    {
553
0
                        mpView->UnmarkPoint(*aVEvt.mpHdl);
554
0
                        pHdl = nullptr;
555
0
                    }
556
0
                    else
557
0
                    {
558
0
                        pHdl = mpView->PickHandle(aMDPos);
559
0
                    }
560
0
                }
561
562
0
                if (pHdl)
563
0
                {
564
0
                    mpView->MarkPoint(*pHdl);
565
0
                    if ( ! rMEvt.IsRight())
566
0
                        mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
567
568
0
                }
569
0
            }
570
0
            else
571
0
            {
572
                // Point IS marked and NO shift is pressed. Start
573
                // dragging of selected point(s)
574
0
                pHdl = mpView->PickHandle(aMDPos);
575
0
                if(pHdl && ! rMEvt.IsRight())
576
0
                    mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
577
0
            }
578
0
        }
579
0
        else
580
0
        {
581
            /******************************************************************
582
            * Select or drag object
583
            ******************************************************************/
584
0
            if (!rMEvt.IsShift() && !rMEvt.IsMod2() && eHit == SdrHitKind::UnmarkedObject)
585
0
            {
586
0
               mpView->UnmarkAllObj();
587
0
            }
588
589
0
            bool bMarked = false;
590
591
0
            if (!rMEvt.IsMod1())
592
0
            {
593
0
                if (rMEvt.IsMod2())
594
0
                {
595
0
                    bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift());
596
0
                }
597
0
                else
598
0
                {
599
0
                    bMarked = mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift());
600
0
                }
601
0
            }
602
603
0
            const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
604
0
            if (bMarked &&
605
0
                (!rMEvt.IsShift() || eHit == SdrHitKind::MarkedObject))
606
0
            {
607
                // Move object
608
0
                if ( ! rMEvt.IsRight())
609
0
                    mpView->BegDragObj(aMDPos, nullptr, aVEvt.mpHdl, nDrgLog);
610
0
            }
611
0
            else if (rMarkList.GetMarkCount() != 0)
612
0
            {
613
                /**************************************************************
614
                * Select gluepoint
615
                **************************************************************/
616
0
                if (!rMEvt.IsShift())
617
0
                    mpView->UnmarkAllPoints();
618
619
0
                if ( ! rMEvt.IsRight())
620
0
                    mpView->BegMarkPoints(aMDPos);
621
0
            }
622
0
            else
623
0
            {
624
                /**************************************************************
625
                * Select object
626
                **************************************************************/
627
0
                if ( ! rMEvt.IsRight())
628
0
                    mpView->BegMarkObj(aMDPos);
629
0
            }
630
631
0
            ForcePointer(&rMEvt);
632
0
        }
633
0
    }
634
635
0
    if (!bIsInDragMode)
636
0
    {
637
0
        ForcePointer(&rMEvt);
638
0
    }
639
640
0
    return bReturn;
641
0
}
642
643
bool FuSelection::MouseMove(const MouseEvent& rMEvt)
644
0
{
645
0
    bool bReturn = FuDraw::MouseMove(rMEvt);
646
647
0
    if (aDragTimer.IsActive())
648
0
    {
649
0
        if(bFirstMouseMove)
650
0
        {
651
0
            bFirstMouseMove = false;
652
0
        }
653
0
        else
654
0
        {
655
0
            aDragTimer.Stop();
656
0
        }
657
0
    }
658
659
0
    if (mpView->IsAction())
660
0
    {
661
0
        Point aPix(rMEvt.GetPosPixel());
662
0
        Point aPnt(mpWindow->PixelToLogic(aPix));
663
664
0
        ForceScroll(aPix);
665
666
0
        if (mpView->IsInsObjPoint())
667
0
        {
668
0
            mpView->MovInsObjPoint(aPnt);
669
0
        }
670
0
        else
671
0
        {
672
0
            mpView->MovAction(aPnt);
673
0
        }
674
0
    }
675
676
0
    ForcePointer(&rMEvt);
677
678
0
    return bReturn;
679
0
}
680
681
bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt)
682
0
{
683
0
    bool bReturn = false;
684
    // When the right mouse button is pressed then only select objects
685
    // (and deselect others) as a preparation for showing the context
686
    // menu.
687
0
    const bool bSelectionOnly = rMEvt.IsRight();
688
689
0
    if (aDragTimer.IsActive() )
690
0
    {
691
0
        aDragTimer.Stop();
692
0
        bIsInDragMode = false;
693
0
    }
694
695
0
    if( !mpView )
696
0
        return false;
697
698
0
    Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
699
0
    sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
700
0
    sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() );
701
0
    svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast<svx::diagram::DiagramFrameHdl*>(pHdl));
702
703
0
    bool bWasDragged = false;
704
0
    if (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints())
705
0
    {
706
        /**********************************************************************
707
        * NO BEZIER_EDITOR
708
        **********************************************************************/
709
0
        if ( mpView->IsDragObj() )
710
0
        {
711
            /******************************************************************
712
            * Object was moved
713
            ******************************************************************/
714
0
            FrameView* pFrameView = mrViewShell.GetFrameView();
715
0
            bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
716
717
0
            if (bDragWithCopy)
718
0
            {
719
0
                bDragWithCopy = !mpView->IsPresObjSelected(false);
720
0
            }
721
722
0
            mpView->SetDragWithCopy(bDragWithCopy);
723
0
            bWasDragged = mpView->EndDragObj(mpView->IsDragWithCopy());
724
725
0
            mpView->ForceMarkedToAnotherPage();
726
727
0
            if (!rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() &&
728
0
                !bSelectionChanged                   &&
729
0
                std::abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
730
0
                std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
731
0
            {
732
                /*************************************************************
733
                * If a user wants to click on an object in front of a marked
734
                * one, he releases the mouse button immediately
735
                **************************************************************/
736
0
                SdrPageView* pPV;
737
0
                SdrObject* pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::BEFOREMARK);
738
739
0
                if (pObj && pPV->IsObjMarkable(pObj))
740
0
                {
741
0
                    mpView->UnmarkAllObj();
742
0
                    mpView->MarkObj(pObj,pPV);
743
0
                    return true;
744
0
                }
745
746
                // check for single object selected
747
0
                SdrObject* pSingleObj = nullptr;
748
749
0
                const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
750
0
                if (rMarkList.GetMarkCount()==1)
751
0
                {
752
0
                    pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
753
0
                }
754
755
                /**************************************************************
756
                * Toggle between selection and rotation
757
                **************************************************************/
758
0
                if (nSlotId == SID_OBJECT_SELECT
759
0
                    && !comphelper::LibreOfficeKit::isActive()
760
0
                    && mpView->IsRotateAllowed()
761
762
0
                    && (rMEvt.GetClicks() != 2)
763
0
                    && (mrViewShell.GetFrameView()->IsClickChangeRotation()
764
0
                        || (pSingleObj
765
0
                            && pSingleObj->GetObjInventor()==SdrInventor::E3d))
766
0
                    && ! bSelectionOnly)
767
768
0
                {
769
0
                    bTempRotation = true;
770
0
                    nSlotId = SID_OBJECT_ROTATE;
771
0
                    Activate();
772
0
                }
773
0
                else if (nSlotId == SID_OBJECT_ROTATE)
774
0
                {
775
0
                    nSlotId = SID_OBJECT_SELECT;
776
0
                    Activate();
777
0
                }
778
0
            }
779
0
            else if (nSlotId == SID_CONVERT_TO_3D_LATHE)
780
0
            {
781
0
                if (!pHdl)
782
0
                {
783
0
                    bSuppressChangesOfSelection = true;
784
0
                    mpView->Start3DCreation();
785
0
                    bSuppressChangesOfSelection = false;
786
0
                }
787
0
                else if (pHdl->GetKind() != SdrHdlKind::MirrorAxis &&
788
0
                         pHdl->GetKind() != SdrHdlKind::Ref1 &&
789
0
                         pHdl->GetKind() != SdrHdlKind::Ref2 && mpView->Is3DRotationCreationActive())
790
0
                {
791
                    /*********************************************************
792
                    * If 3D-rotation bodies are about to be created,
793
                    * end creation now
794
                    **********************************************************/
795
0
                    Degree100 nAngle1  = GetAngle(aPnt - mpView->GetRef1());
796
0
                    nAngle1 -= 27000_deg100;
797
0
                    nAngle1 = NormAngle36000(nAngle1);
798
0
                    bool bMirrorSide1 = nAngle1 < 18000_deg100;
799
800
0
                    if (bMirrorSide0 != bMirrorSide1)
801
0
                    {
802
0
                         bSuppressChangesOfSelection = true;
803
0
                         mpWindow->EnterWait();
804
0
                         mpView->End3DCreation();
805
0
                         bSuppressChangesOfSelection = false;
806
0
                         nSlotId = SID_OBJECT_SELECT;
807
0
                         mpWindow->LeaveWait();
808
0
                         Activate();
809
0
                    }
810
0
                }
811
0
            }
812
0
        }
813
0
        else if (rMEvt.IsMod1()
814
0
            && !rMEvt.IsMod2()
815
0
            && std::abs(aPnt.X() - aMDPos.X()) < nDrgLog
816
0
            && std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
817
0
        {
818
            // Enter group
819
0
            mpView->MarkObj(aPnt, nHitLog, rMEvt.IsShift(), rMEvt.IsMod1());
820
0
        }
821
822
0
        if (mpView->IsAction() )
823
0
        {
824
0
            mpView->EndAction();
825
0
        }
826
827
0
        if (SdModule::get()->GetWaterCan())
828
0
        {
829
0
            if( rMEvt.IsRight() )
830
0
            {
831
                // In watering-can mode, on press onto right mouse button, an undo is executed
832
0
                mrViewShell.GetViewFrame()->GetDispatcher()->Execute( SID_UNDO, SfxCallMode::ASYNCHRON );
833
0
            }
834
0
            else if (pWaterCanCandidate != nullptr)
835
0
            {
836
                // Is the candidate object still under the mouse?
837
0
                if (pickObject (aPnt) == pWaterCanCandidate)
838
0
                {
839
0
                    SdStyleSheetPool* pPool = static_cast<SdStyleSheetPool*>(
840
0
                        mpDocSh->GetStyleSheetPool());
841
0
                    if (pPool != nullptr)
842
0
                    {
843
0
                        SfxStyleSheet* pStyleSheet = static_cast<SfxStyleSheet*>(
844
0
                            pPool->GetActualStyleSheet());
845
0
                        if (pStyleSheet != nullptr && mpView->IsUndoEnabled() )
846
0
                        {
847
                            // Added UNDOs for the WaterCan mode. This was never done in
848
                            // the past, thus it was missing all the time.
849
0
                            std::unique_ptr<SdrUndoAction> pUndoAttr = mrDoc.GetSdrUndoFactory().CreateUndoAttrObject(*pWaterCanCandidate, true, true);
850
0
                            mpView->BegUndo(pUndoAttr->GetComment());
851
0
                            mpView->AddUndo(mrDoc.GetSdrUndoFactory().CreateUndoGeoObject(*pWaterCanCandidate));
852
0
                            mpView->AddUndo(std::move(pUndoAttr));
853
854
0
                            pWaterCanCandidate->SetStyleSheet (pStyleSheet, false);
855
856
0
                            mpView->EndUndo();
857
0
                        }
858
0
                    }
859
0
                }
860
0
            }
861
            // else when there has been no object under the mouse when the
862
            // button was pressed then nothing happens even when there is
863
            // one now.
864
0
        }
865
866
0
        sal_uInt16 nClicks = rMEvt.GetClicks();
867
868
0
        if (nClicks == 2 && rMEvt.IsLeft() && bMBDown &&
869
0
            !rMEvt.IsMod1() && !rMEvt.IsShift() )
870
0
        {
871
0
            DoubleClick(rMEvt);
872
0
        }
873
874
0
        bMBDown = false;
875
876
0
        ForcePointer(&rMEvt);
877
0
        pHdl = nullptr;
878
0
        mpWindow->ReleaseMouse();
879
0
        SdrObject* pSingleObj = nullptr;
880
0
        const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
881
0
        const size_t nMarkCount = rMarkList.GetMarkCount();
882
883
0
        if (nMarkCount==1)
884
0
        {
885
0
            pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
886
0
        }
887
888
0
        if (!bWasDragged && pSingleObj && pSingleObj->isAnnotationObject() && rMEvt.IsLeft())
889
0
        {
890
0
            auto& pAnnotationData = pSingleObj->getAnnotationData();
891
0
            if (pAnnotationData)
892
0
            {
893
0
                auto* pDrawViewShell = dynamic_cast<DrawViewShell*>(&mrViewShell);
894
0
                if (pDrawViewShell && pDrawViewShell->getAnnotationManagerPtr())
895
0
                    pDrawViewShell->getAnnotationManagerPtr()->SelectAnnotation(pAnnotationData->mxAnnotation, true);
896
0
            }
897
0
            return true;
898
0
        }
899
900
0
        if(!bWasDragged && nullptr != pSingleObj && pSingleObj->isDiagram())
901
0
        {
902
0
            if(nullptr != pDiagramFrameHdl)
903
0
            {
904
                // Check for click on svx::diagram::DiagramFrameHdl
905
                // - if we hit a SdrHdl
906
                // - if it was not moved
907
                // - if single object is selected and it is a Diagram
908
                // let the DiagramFrameHdl decide what to do
909
0
                svx::diagram::DiagramFrameHdl::clicked(aPnt);
910
0
                return true;
911
0
            }
912
0
            else
913
0
            {
914
0
                const std::shared_ptr< svx::diagram::DiagramHelper_svx >& rDiagramHelper(pSingleObj->getDiagramHelper());
915
0
                if (rDiagramHelper)
916
0
                {
917
0
                    SdrPageView* pPV;
918
0
                    SdrObject* pCandidate = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::DEEP);
919
0
                    if (pCandidate && !pCandidate->isDiagram())
920
0
                    {
921
0
                        rDiagramHelper->markDirectDiagramSubSelection(*pCandidate);
922
0
                        mpView->UnmarkAllObj();
923
0
                        mpView->MarkObj(pSingleObj,pPV);
924
0
                        return true;
925
0
                    }
926
0
                }
927
0
            }
928
0
        }
929
930
0
        if ( (nSlotId != SID_OBJECT_SELECT && nMarkCount==0)                    ||
931
0
             ( mpView->GetDragMode() == SdrDragMode::Crook &&
932
0
              !mpView->IsCrookAllowed( mpView->IsCrookNoContortion() ) ) ||
933
0
             ( mpView->GetDragMode() == SdrDragMode::Shear &&
934
0
              !mpView->IsShearAllowed() && !mpView->IsDistortAllowed() ) ||
935
0
             ( nSlotId==SID_CONVERT_TO_3D_LATHE && pSingleObj &&
936
0
              (pSingleObj->GetObjInventor() != SdrInventor::Default         ||
937
0
               pSingleObj->GetObjIdentifier() == SdrObjKind::Measure) ) )
938
0
        {
939
0
            bReturn = true;
940
0
            ForcePointer(&rMEvt);
941
0
            pHdl = nullptr;
942
0
            mpWindow->ReleaseMouse();
943
0
            FuDraw::MouseButtonUp(rMEvt);
944
0
            mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::SYNCHRON);
945
0
            return bReturn; // CAUTION, due to the synchronous slot, the object is deleted now.
946
0
        }
947
948
0
        FuDraw::MouseButtonUp(rMEvt);
949
0
    }
950
0
    else
951
0
    {
952
        /**********************************************************************
953
        * BEZIER_EDITOR
954
        **********************************************************************/
955
0
        if ( mpView->IsAction() )
956
0
        {
957
0
            if ( mpView->IsInsObjPoint() )
958
0
            {
959
0
                mpView->EndInsObjPoint(SdrCreateCmd::ForceEnd);
960
0
            }
961
0
            else if ( mpView->IsDragObj() )
962
0
            {
963
0
                FrameView* pFrameView = mrViewShell.GetFrameView();
964
0
                bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
965
966
0
                if (bDragWithCopy)
967
0
                {
968
0
                    bDragWithCopy = !mpView->IsPresObjSelected(false);
969
0
                }
970
971
0
                mpView->SetDragWithCopy(bDragWithCopy);
972
0
                mpView->EndDragObj( mpView->IsDragWithCopy() );
973
0
            }
974
0
            else
975
0
            {
976
0
                mpView->EndAction();
977
978
0
                sal_uInt16 nDrgLog2 = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() );
979
0
                Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
980
981
0
                if (std::abs(aMDPos.X() - aPos.X()) < nDrgLog2 &&
982
0
                    std::abs(aMDPos.Y() - aPos.Y()) < nDrgLog2 &&
983
0
                    !rMEvt.IsShift() && !rMEvt.IsMod2())
984
0
                {
985
0
                    SdrViewEvent aVEvt;
986
0
                    SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
987
988
0
                    if (eHit == SdrHitKind::NONE)
989
0
                    {
990
                        // Click on the same place - unselect
991
0
                        mpView->UnmarkAllObj();
992
0
                    }
993
0
                }
994
0
            }
995
0
        }
996
0
        else if (!rMEvt.IsShift() && rMEvt.IsMod1() && !rMEvt.IsMod2() &&
997
0
                 std::abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
998
0
                 std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
999
0
        {
1000
            // Enter group
1001
0
            mpView->MarkObj(aPnt, nHitLog, false, rMEvt.IsMod1());
1002
0
        }
1003
1004
0
        ForcePointer(&rMEvt);
1005
0
        pHdl = nullptr;
1006
0
        mpWindow->ReleaseMouse();
1007
1008
0
        FuDraw::MouseButtonUp(rMEvt);
1009
0
    }
1010
1011
0
    return bReturn;
1012
0
}
1013
1014
/**
1015
 * Process keyboard input
1016
 * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
1017
 */
1018
bool FuSelection::KeyInput(const KeyEvent& rKEvt)
1019
0
{
1020
0
    bool bReturn = false;
1021
1022
0
    switch (rKEvt.GetKeyCode().GetCode())
1023
0
    {
1024
0
        case KEY_ESCAPE:
1025
0
        {
1026
0
            bReturn = FuSelection::cancel();
1027
0
        }
1028
0
        break;
1029
        //add keyboard operation for insert points in drawing curve
1030
0
        case KEY_UP:
1031
0
        case KEY_DOWN:
1032
0
        case KEY_LEFT:
1033
0
        case KEY_RIGHT:
1034
0
        {
1035
0
            if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT)){
1036
0
                ::tools::Long nX = 0;
1037
0
                ::tools::Long nY = 0;
1038
0
                sal_uInt16  nCode = rKEvt.GetKeyCode().GetCode();
1039
0
                if (nCode == KEY_UP)
1040
0
                {
1041
                    // scroll up
1042
0
                    nX = 0;
1043
0
                    nY =-1;
1044
0
                }
1045
0
                else if (nCode == KEY_DOWN)
1046
0
                {
1047
                    // scroll down
1048
0
                    nX = 0;
1049
0
                    nY = 1;
1050
0
                }
1051
0
                else if (nCode == KEY_LEFT)
1052
0
                {
1053
                    // scroll left
1054
0
                    nX =-1;
1055
0
                    nY = 0;
1056
0
                }
1057
0
                else if (nCode == KEY_RIGHT)
1058
0
                {
1059
                    // scroll right
1060
0
                    nX = 1;
1061
0
                    nY = 0;
1062
0
                }
1063
1064
0
                Point centerPoint;
1065
0
                ::tools::Rectangle rect = mpView->GetMarkedObjRect();
1066
0
                centerPoint = mpWindow->LogicToPixel(rect.Center());
1067
0
                Point aPoint = bMovedToCenterPoint? oldPoint:centerPoint;
1068
0
                Point ePoint = aPoint + Point(nX,nY);
1069
0
                mpWindow->SetPointerPosPixel(ePoint);
1070
                //simulate mouse move action
1071
0
                MouseEvent eMevt(ePoint, 1, MouseEventModifiers::DRAGMOVE, MOUSE_LEFT, 0);
1072
0
                MouseMove(eMevt);
1073
0
                oldPoint = ePoint;
1074
0
                bMovedToCenterPoint = true;
1075
0
                bReturn = true;
1076
0
            }
1077
0
        }
1078
0
        break;
1079
0
        case KEY_RETURN:
1080
0
            if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT))
1081
0
            {
1082
0
                if(!bBeginInsertPoint)
1083
0
                {
1084
                    //simulate mouse button down action
1085
0
                    MouseEvent aMevt(oldPoint, 1,
1086
0
                                     MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::DRAGMOVE,
1087
0
                                     MOUSE_LEFT, KEY_SHIFT);
1088
0
                    MouseButtonDown(aMevt);
1089
0
                    mpWindow->CaptureMouse();
1090
0
                    bBeginInsertPoint = true;
1091
0
                }
1092
0
                else
1093
0
                {
1094
                    //simulate mouse button up action
1095
0
                    MouseEvent rMEvt(oldPoint, 1,
1096
0
                                     MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::ENTERWINDOW,
1097
0
                                     MOUSE_LEFT, KEY_SHIFT);
1098
0
                    MouseButtonUp(rMEvt);
1099
0
                    bBeginInsertPoint = false;
1100
0
                }
1101
0
                bReturn= true;
1102
0
            }
1103
0
            break;
1104
0
    }
1105
0
    if (!bReturn)
1106
0
    {
1107
0
        bReturn = FuDraw::KeyInput(rKEvt);
1108
1109
0
        const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1110
0
        if(rMarkList.GetMarkCount() == 0)
1111
0
        {
1112
0
            mpView->ResetCreationActive();
1113
1114
0
            mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
1115
0
        }
1116
0
    }
1117
1118
0
    return bReturn;
1119
1120
0
}
1121
1122
void FuSelection::Activate()
1123
0
{
1124
0
    SdrDragMode eMode;
1125
0
    mpView->ResetCreationActive();
1126
0
    mpView->SetEditMode(SdrViewEditMode::Edit);
1127
1128
0
    switch( nSlotId )
1129
0
    {
1130
0
        case SID_OBJECT_ROTATE:
1131
0
        {
1132
0
            eMode = SdrDragMode::Rotate;
1133
1134
0
            if ( mpView->GetDragMode() != eMode )
1135
0
                mpView->SetDragMode(eMode);
1136
0
        }
1137
0
        break;
1138
1139
0
        case SID_OBJECT_MIRROR:
1140
0
        {
1141
0
            eMode = SdrDragMode::Mirror;
1142
1143
0
            if ( mpView->GetDragMode() != eMode )
1144
0
                mpView->SetDragMode(eMode);
1145
0
        }
1146
0
        break;
1147
1148
0
        case SID_OBJECT_CROP:
1149
0
        {
1150
0
            eMode = SdrDragMode::Crop;
1151
1152
0
            if ( mpView->GetDragMode() != eMode )
1153
0
                mpView->SetDragMode(eMode);
1154
0
        }
1155
0
        break;
1156
1157
0
        case SID_OBJECT_TRANSPARENCE:
1158
0
        {
1159
0
            eMode = SdrDragMode::Transparence;
1160
1161
0
            if ( mpView->GetDragMode() != eMode )
1162
0
                mpView->SetDragMode(eMode);
1163
0
        }
1164
0
        break;
1165
1166
0
        case SID_OBJECT_GRADIENT:
1167
0
        {
1168
0
            eMode = SdrDragMode::Gradient;
1169
1170
0
            if ( mpView->GetDragMode() != eMode )
1171
0
                mpView->SetDragMode(eMode);
1172
0
        }
1173
0
        break;
1174
1175
0
        case SID_OBJECT_SHEAR:
1176
0
        {
1177
0
            eMode = SdrDragMode::Shear;
1178
1179
0
            if ( mpView->GetDragMode() != eMode )
1180
0
                mpView->SetDragMode(eMode);
1181
0
        }
1182
0
        break;
1183
1184
0
        case SID_OBJECT_CROOK_ROTATE:
1185
0
        {
1186
0
            eMode = SdrDragMode::Crook;
1187
1188
0
            if ( mpView->GetDragMode() != eMode )
1189
0
            {
1190
0
                mpView->SetDragMode(eMode);
1191
0
                mpView->SetCrookMode(SdrCrookMode::Rotate);
1192
0
            }
1193
0
        }
1194
0
        break;
1195
1196
0
        case SID_OBJECT_CROOK_SLANT:
1197
0
        {
1198
0
            eMode = SdrDragMode::Crook;
1199
1200
0
            if ( mpView->GetDragMode() != eMode )
1201
0
            {
1202
0
                mpView->SetDragMode(eMode);
1203
0
                mpView->SetCrookMode(SdrCrookMode::Slant);
1204
0
            }
1205
0
        }
1206
0
        break;
1207
1208
0
        case SID_OBJECT_CROOK_STRETCH:
1209
0
        {
1210
0
            eMode = SdrDragMode::Crook;
1211
1212
0
            if ( mpView->GetDragMode() != eMode )
1213
0
            {
1214
0
                mpView->SetDragMode(eMode);
1215
0
                mpView->SetCrookMode(SdrCrookMode::Stretch);
1216
0
            }
1217
0
        }
1218
0
        break;
1219
1220
0
        case SID_CONVERT_TO_3D_LATHE:
1221
0
        {
1222
0
            eMode = SdrDragMode::Mirror;
1223
0
            bSuppressChangesOfSelection = true;
1224
1225
0
            if ( mpView->GetDragMode() != eMode )
1226
0
                mpView->SetDragMode(eMode);
1227
1228
0
            if (!mpView->Is3DRotationCreationActive())
1229
0
                mpView->Start3DCreation();
1230
1231
0
            bSuppressChangesOfSelection = false;
1232
0
        }
1233
0
        break;
1234
1235
0
        default:
1236
0
        {
1237
0
            eMode = SdrDragMode::Move;
1238
1239
0
            if ( mpView->GetDragMode() != eMode )
1240
0
                mpView->SetDragMode(eMode);
1241
0
        }
1242
0
        break;
1243
0
    }
1244
1245
0
    if (nSlotId != SID_OBJECT_ROTATE)
1246
0
    {
1247
0
        bTempRotation = false;
1248
0
    }
1249
1250
0
    FuDraw::Activate();
1251
0
}
1252
1253
void FuSelection::SelectionHasChanged()
1254
0
{
1255
0
    bSelectionChanged = true;
1256
1257
0
    FuDraw::SelectionHasChanged();
1258
1259
0
    if (mpView->Is3DRotationCreationActive() && !bSuppressChangesOfSelection)
1260
0
    {
1261
        // Switch rotation body -> selection
1262
0
        mpView->ResetCreationActive();
1263
0
        nSlotId = SID_OBJECT_SELECT;
1264
0
        Activate();
1265
0
    }
1266
1267
    // Activate the right tool bar for the current context of the view.
1268
0
    mrViewShell.GetViewShellBase().GetToolBarManager()->SelectionHasChanged(mrViewShell, *mpView);
1269
0
}
1270
1271
/**
1272
 * Set current bezier edit mode
1273
 */
1274
void FuSelection::SetEditMode(sal_uInt16 nMode)
1275
0
{
1276
0
    nEditMode = nMode;
1277
1278
0
    if (nEditMode == SID_BEZIER_INSERT)
1279
0
    {
1280
0
        mpView->SetInsObjPointMode(true);
1281
0
    }
1282
0
    else
1283
0
    {
1284
0
        mpView->SetInsObjPointMode(false);
1285
0
    }
1286
1287
0
    ForcePointer();
1288
1289
0
    SfxBindings& rBindings = mrViewShell.GetViewFrame()->GetBindings();
1290
0
    rBindings.Invalidate(SID_BEZIER_MOVE);
1291
0
    rBindings.Invalidate(SID_BEZIER_INSERT);
1292
0
}
1293
1294
/**
1295
 * Execute ImageMap interaction
1296
 */
1297
bool FuSelection::HandleImageMapClick(const SdrObject* pObj, const Point& rPos)
1298
0
{
1299
0
    bool bClosed = pObj->IsClosedObj();
1300
0
    bool bFilled = false;
1301
1302
0
    if (bClosed)
1303
0
    {
1304
0
        SfxItemSet aSet(mrDoc.GetPool());
1305
1306
0
        aSet.Put(pObj->GetMergedItemSet());
1307
1308
0
        const XFillStyleItem& rFillStyle = aSet.Get(XATTR_FILLSTYLE);
1309
0
        bFilled = rFillStyle.GetValue() != drawing::FillStyle_NONE;
1310
0
    }
1311
1312
0
    const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
1313
0
    double fHitLog = mpWindow->PixelToLogic(Size(HITPIX, 0)).Width();
1314
0
    const ::tools::Long n2HitLog = fHitLog * 2;
1315
0
    Point aHitPosR(rPos);
1316
0
    Point aHitPosL(rPos);
1317
0
    Point aHitPosT(rPos);
1318
0
    Point aHitPosB(rPos);
1319
1320
0
    aHitPosR.AdjustX(n2HitLog);
1321
0
    aHitPosL.AdjustX(-n2HitLog);
1322
0
    aHitPosT.AdjustY(n2HitLog);
1323
0
    aHitPosB.AdjustY(-n2HitLog);
1324
1325
0
    if (!bClosed || !bFilled
1326
0
        || (SdrObjectPrimitiveHit(*pObj, aHitPosR, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer,
1327
0
                                  false)
1328
0
            && SdrObjectPrimitiveHit(*pObj, aHitPosL, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
1329
0
                                     pVisiLayer, false)
1330
0
            && SdrObjectPrimitiveHit(*pObj, aHitPosT, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
1331
0
                                     pVisiLayer, false)
1332
0
            && SdrObjectPrimitiveHit(*pObj, aHitPosB, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
1333
0
                                     pVisiLayer, false)))
1334
0
    {
1335
0
        if (SvxIMapInfo::GetIMapInfo(pObj))
1336
0
        {
1337
0
            const IMapObject* pIMapObj = SvxIMapInfo::GetHitIMapObject(pObj, rPos);
1338
1339
0
            if (pIMapObj && !pIMapObj->GetURL().isEmpty())
1340
0
            {
1341
                // Jump to Document
1342
0
                mpWindow->ReleaseMouse();
1343
0
                SfxStringItem aStrItem(SID_FILE_NAME, pIMapObj->GetURL());
1344
0
                SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName());
1345
0
                SfxViewFrame* pFrame = mrViewShell.GetViewFrame();
1346
0
                SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
1347
0
                SfxBoolItem aBrowseItem(SID_BROWSE, true);
1348
0
                mpWindow->ReleaseMouse();
1349
0
                pFrame->GetDispatcher()->ExecuteList(
1350
0
                    SID_OPENDOC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
1351
0
                    { &aStrItem, &aFrameItem, &aBrowseItem, &aReferer });
1352
1353
0
                return true;
1354
0
            }
1355
0
        }
1356
0
    }
1357
1358
0
    return false;
1359
0
}
1360
1361
/** is called when the current function should be aborted. <p>
1362
    This is used when a function gets a KEY_ESCAPE but can also
1363
    be called directly.
1364
1365
    @returns true if an active function was aborted
1366
*/
1367
bool FuSelection::cancel()
1368
0
{
1369
0
    if (mpView->Is3DRotationCreationActive())
1370
0
    {
1371
0
        mpView->ResetCreationActive();
1372
0
        mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
1373
0
        return true;
1374
0
    }
1375
0
    else
1376
0
    {
1377
0
        return false;
1378
0
    }
1379
0
}
1380
1381
SdrObject* FuSelection::pickObject (const Point& rTestPoint)
1382
0
{
1383
0
    SdrPageView* pPageView;
1384
0
    sal_uInt16 nHitLog = sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width());
1385
0
    return mpView->PickObj(rTestPoint, nHitLog, pPageView, SdrSearchOptions::PICKMARKABLE);
1386
0
}
1387
1388
void FuSelection::ForcePointer(const MouseEvent* pMEvt)
1389
0
{
1390
0
    if(bMovedToCenterPoint && !bBeginInsertPoint && pMEvt)
1391
0
    {
1392
0
        MouseEvent aMEvt(pMEvt->GetPosPixel(), pMEvt->GetClicks(),
1393
0
            pMEvt->GetMode(), pMEvt->GetButtons(), pMEvt->GetModifier() & ~KEY_SHIFT);
1394
0
        FuDraw::ForcePointer(&aMEvt);
1395
0
    }
1396
0
    else
1397
0
    {
1398
0
        FuDraw::ForcePointer(pMEvt);
1399
0
    }
1400
0
}
1401
1402
} // end of namespace sd
1403
1404
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */