Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/drawfunc/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 <com/sun/star/embed/EmbedVerbs.hpp>
21
#include <editeng/flditem.hxx>
22
#include <svx/svddrgmt.hxx>
23
#include <svx/svdoole2.hxx>
24
#include <sfx2/dispatch.hxx>
25
#include <vcl/imapobj.hxx>
26
#include <svx/svdouno.hxx>
27
#include <svx/svdomedia.hxx>
28
#include <svx/svdpagv.hxx>
29
#include <svx/ImageMapInfo.hxx>
30
#include <svx/diagram/DiagramHelper_svx.hxx>
31
#include <editeng/outlobj.hxx>
32
#include <sfx2/app.hxx>
33
#include <sfx2/ipclient.hxx>
34
#include <sfx2/viewfrm.hxx>
35
#include <comphelper/lok.hxx>
36
37
#include <fusel.hxx>
38
#include <sc.hrc>
39
#include <fudraw.hxx>
40
#include <futext.hxx>
41
#include <drawview.hxx>
42
#include <tabvwsh.hxx>
43
#include <drwlayer.hxx>
44
#include <userdat.hxx>
45
#include <scmod.hxx>
46
#include <charthelper.hxx>
47
#include <docuno.hxx>
48
#include <docsh.hxx>
49
#include <stlpool.hxx>
50
51
//  maximal permitted mouse movement to start Drag&Drop
52
//! fusel,fuconstr,futext - combine them!
53
0
#define SC_MAXDRAGMOVE  3
54
// Min necessary mouse motion for normal dragging
55
0
#define SC_MINDRAGMOVE 2
56
57
using namespace com::sun::star;
58
59
FuSelection::FuSelection(ScTabViewShell& rViewSh, vcl::Window* pWin, ScDrawView* pViewP,
60
                         SdrModel& rDoc, const SfxRequest& rReq)
61
0
    : FuDraw(rViewSh, pWin, pViewP, rDoc, rReq)
62
0
{
63
0
}
64
65
FuSelection::~FuSelection()
66
0
{
67
0
}
68
69
bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
70
0
{
71
    // remember button state for creation of own MouseEvents
72
0
    SetMouseButtonCode(rMEvt.GetButtons());
73
0
    const bool bSelectionOnly = rMEvt.IsRight();
74
0
    if ( pView->IsAction() )
75
0
    {
76
0
        if ( bSelectionOnly )
77
0
            pView->BckAction();
78
0
        return true;
79
0
    }
80
81
0
    bIsInDragMode = false;      //  somewhere it has to be reset (#50033#)
82
83
0
    bool bReturn = FuDraw::MouseButtonDown(rMEvt);
84
0
    auto aLogicPosition = rMEvt.getLogicPosition();
85
0
    if (aLogicPosition)
86
0
        aMDPos = *aLogicPosition;
87
0
    else
88
0
        aMDPos = pWindow->PixelToLogic(rMEvt.GetPosPixel());
89
90
0
    if (comphelper::LibreOfficeKit::isActive())
91
0
    {
92
0
        ScViewData& rViewData = rViewShell.GetViewData();
93
0
        ScDocument& rDocument = rViewData.GetDocument();
94
0
        if (rDocument.IsNegativePage(rViewData.CurrentTabForData()))
95
0
            aMDPos.setX(-aMDPos.X());
96
0
    }
97
98
0
    if ( rMEvt.IsLeft() )
99
0
    {
100
0
        SdrHdl* pHdl = pView->PickHandle(aMDPos);
101
102
0
        if ( pHdl!=nullptr || pView->IsMarkedHit(aMDPos) )
103
0
        {
104
            // Determine if this is the tail of a SdrCaptionObj i.e.
105
            // we need to disable the drag option on the tail of a note
106
            // object. Also, disable the ability to use the circular
107
            // drag of a note object.
108
0
            bool bDrag = false;
109
0
            const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
110
0
            if( rMarkList.GetMarkCount() == 1 )
111
0
            {
112
0
                SdrObject* pMarkedObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
113
0
                if( ScDrawLayer::IsNoteCaption( pMarkedObj ) )
114
0
                {
115
                    // move using the valid caption handles for note text box.
116
0
                    if(pHdl && (pHdl->GetKind() != SdrHdlKind::Poly && pHdl->GetKind() != SdrHdlKind::Circle))
117
0
                        bDrag = true;
118
                    // move the complete note box.
119
0
                    else if(!pHdl)
120
0
                        bDrag = true;
121
0
                }
122
0
                else
123
0
                    bDrag = true;   // different object
124
0
            }
125
0
            else
126
0
                bDrag = true;       // several objects
127
128
0
            if ( bDrag )
129
0
            {
130
0
                aDragTimer.Start();
131
0
                if (pView->BegDragObj(aMDPos, nullptr, pHdl))
132
0
                    pView->GetDragMethod()->SetShiftPressed( rMEvt.IsShift() );
133
0
                bReturn = true;
134
0
            }
135
0
        }
136
0
        else
137
0
        {
138
0
            SdrPageView* pPV = nullptr;
139
0
            bool bAlt = rMEvt.IsMod2();
140
0
            SdrObject* pObj = !bAlt ? pView->PickObj(aMDPos, pView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO) : nullptr;
141
0
            if (pObj)
142
0
            {
143
0
                pView->BegMacroObj(aMDPos, pObj, pPV, pWindow);
144
0
                bReturn = true;
145
0
            }
146
0
            else
147
0
            {
148
0
                OUString sURL, sTarget;
149
0
                pObj = !bAlt ? pView->PickObj(aMDPos, pView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr;
150
0
                if (pObj)
151
0
                {
152
                   // Support for imported Excel docs
153
                   // Excel is of course not consistent and allows
154
                   // a hyperlink to be assigned for an object group
155
                   // and even though the hyperlink is exported in the Escher layer
156
                   // its never used, when dealing with a group object the link
157
                   // associated with the clicked object is used only
158
159
                   // additionally you can also select a macro in Excel for a grouped
160
                   // objects and this *usually* results in the macro being set
161
                   // for the elements in the group and no macro is exported
162
                   // for the group itself ( this however is not always true )
163
                   // if a macro and hlink are defined favour the hlink
164
                   // If a group object has no hyperlink use the hyperlink of the
165
                   // object clicked
166
167
0
                   if ( pObj->IsGroupObject() )
168
0
                   {
169
0
                       ScMacroInfo* pTmpInfo = ScDrawLayer::GetMacroInfo( pObj );
170
0
                       if ( !pTmpInfo || pTmpInfo->GetMacro().isEmpty() )
171
0
                       {
172
0
                           SdrObject* pHit = pView->PickObj(aMDPos, pView->getHitTolLog(), pPV, SdrSearchOptions::DEEP);
173
0
                           if (pHit)
174
0
                               pObj = pHit;
175
0
                       }
176
0
                   }
177
178
0
                   ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj, true );
179
                   // For interoperability favour links over macros if both are defined
180
0
                   if ( !pObj->getHyperlink().isEmpty() )
181
0
                   {
182
0
                       sURL = pObj->getHyperlink();
183
0
                   }
184
0
                   else if ( !pInfo->GetMacro().isEmpty() )
185
0
                   {
186
0
                       SfxObjectShell* pObjSh = SfxObjectShell::Current();
187
0
                       if ( pObjSh && SfxApplication::IsXScriptURL( pInfo->GetMacro() ) )
188
0
                       {
189
0
                           uno::Reference< beans::XPropertySet > xProps( pObj->getUnoShape(), uno::UNO_QUERY );
190
0
                           uno::Any aCaller;
191
0
                           if ( xProps.is() )
192
0
                           {
193
0
                               try
194
0
                               {
195
0
                                   aCaller = xProps->getPropertyValue(u"Name"_ustr);
196
0
                               }
197
0
                               catch( uno::Exception& ) {}
198
0
                           }
199
0
                           uno::Any aRet;
200
0
                           uno::Sequence< sal_Int16 > aOutArgsIndex;
201
0
                           uno::Sequence< uno::Any > aOutArgs;
202
0
                           uno::Sequence< uno::Any > aInArgs;
203
0
                           pObjSh->CallXScript( pInfo->GetMacro(),
204
0
                               aInArgs, aRet, aOutArgsIndex, aOutArgs, true, &aCaller );
205
0
                           rViewShell.FakeButtonUp( rViewShell.GetViewData().GetActivePart() );
206
0
                           return true;        // no CaptureMouse etc.
207
0
                       }
208
0
                   }
209
0
                }
210
211
                //  URL / ImageMap
212
213
0
                SdrViewEvent aVEvt;
214
0
                if ( !bAlt &&
215
0
                    pView->PickAnything( rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt ) != SdrHitKind::NONE &&
216
0
                    aVEvt.mpObj != nullptr )
217
0
                {
218
0
                    if ( SvxIMapInfo::GetIMapInfo( aVEvt.mpObj ) )       // ImageMap
219
0
                    {
220
0
                        const IMapObject* pIMapObj =
221
0
                                SvxIMapInfo::GetHitIMapObject( aVEvt.mpObj, aMDPos, pWindow->GetOutDev() );
222
0
                        if ( pIMapObj && !pIMapObj->GetURL().isEmpty() )
223
0
                        {
224
0
                            sURL = pIMapObj->GetURL();
225
0
                            sTarget = pIMapObj->GetTarget();
226
0
                        }
227
0
                    }
228
0
                    if ( aVEvt.meEvent == SdrEventKind::ExecuteUrl && aVEvt.mpURLField )   // URL
229
0
                    {
230
0
                        sURL = aVEvt.mpURLField->GetURL();
231
0
                        sTarget = aVEvt.mpURLField->GetTargetFrame();
232
0
                    }
233
0
                }
234
235
                // open hyperlink, if found at object or in object's text
236
                // Fragments pointing into the current document should be always opened.
237
0
                if ( !sURL.isEmpty() && (ScGlobal::ShouldOpenURL() || sURL.startsWith("#")) )
238
0
                {
239
0
                    ScGlobal::OpenURL( sURL, sTarget );
240
0
                    rViewShell.FakeButtonUp( rViewShell.GetViewData().GetActivePart() );
241
0
                    return true;        // no CaptureMouse etc.
242
0
                }
243
244
                //  Is another object being edited in this view?
245
                //  (Editing is ended in MarkListHasChanged - test before UnmarkAll)
246
0
                SfxInPlaceClient* pClient = rViewShell.GetIPClient();
247
0
                bool bWasOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
248
249
                //  Selection
250
251
                // do not allow multiselection with note caption
252
0
                bool bCaptionClicked = IsNoteCaptionClicked( aMDPos );
253
0
                if ( !rMEvt.IsShift() || bCaptionClicked || IsNoteCaptionMarked() )
254
0
                    pView->UnmarkAll();
255
256
                /*  Unlock internal layer, if a note caption is clicked. The
257
                    layer will be relocked in ScDrawView::MarkListHasChanged(). */
258
0
                if( bCaptionClicked )
259
0
                    pView->UnlockInternalLayer();
260
261
                // try to select the clicked object
262
0
                if ( pView->MarkObj( aMDPos, -2, false, rMEvt.IsMod1() ) )
263
0
                {
264
265
                    // move object
266
267
0
                    if (pView->IsMarkedHit(aMDPos))
268
0
                    {
269
                        //  Don't start drag timer if inplace editing of an OLE object
270
                        //  was just ended with this mouse click - the view will be moved
271
                        //  (different tool bars) and the object that was clicked on would
272
                        //  be moved unintentionally.
273
0
                        if ( !bWasOleActive )
274
0
                            aDragTimer.Start();
275
276
0
                        pHdl=pView->PickHandle(aMDPos);
277
0
                        pView->BegDragObj(aMDPos, nullptr, pHdl);
278
0
                        bReturn = true;
279
0
                    }
280
0
                    else                                    // object at the edge
281
0
                        if (rViewShell.IsDrawSelMode())
282
0
                            bReturn = true;
283
0
                }
284
0
                else
285
0
                {
286
0
                    if (rViewShell.IsDrawSelMode())
287
0
                    {
288
289
                        // select object
290
291
0
                        pView->BegMarkObj(aMDPos);
292
0
                        bReturn = true;
293
0
                    }
294
0
                }
295
0
            }
296
0
        }
297
298
0
    }
299
300
0
    if (!bIsInDragMode)
301
0
    {
302
        // VC calls CaptureMouse itself
303
0
        pWindow->CaptureMouse();
304
0
        ForcePointer(&rMEvt);
305
0
    }
306
307
0
    return bReturn;
308
0
}
309
310
bool FuSelection::MouseMove(const MouseEvent& rMEvt)
311
0
{
312
0
    bool bReturn = FuDraw::MouseMove(rMEvt);
313
314
0
    if (aDragTimer.IsActive() )
315
0
    {
316
0
        Point aOldPixel = pWindow->LogicToPixel( aMDPos );
317
0
        Point aNewPixel = rMEvt.GetPosPixel();
318
0
        if ( std::abs( aOldPixel.X() - aNewPixel.X() ) > SC_MAXDRAGMOVE ||
319
0
             std::abs( aOldPixel.Y() - aNewPixel.Y() ) > SC_MAXDRAGMOVE )
320
0
            aDragTimer.Stop();
321
0
    }
322
323
0
    if ( pView->IsAction() )
324
0
    {
325
0
        Point aPix(rMEvt.GetPosPixel());
326
0
        Point aPnt(pWindow->PixelToLogic(aPix));
327
328
0
        ForceScroll(aPix);
329
0
        pView->MovAction(aPnt);
330
0
        bReturn = true;
331
0
    }
332
333
0
    ForcePointer(&rMEvt);
334
335
0
    return bReturn;
336
0
}
337
338
bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt)
339
0
{
340
    // remember button state for creation of own MouseEvents
341
0
    SetMouseButtonCode(rMEvt.GetButtons());
342
343
0
    bool bReturn = FuDraw::MouseButtonUp(rMEvt);
344
0
    bool bOle = rViewShell.GetViewFrame().GetFrame().IsInPlace();
345
346
0
    SdrObject* pObj = nullptr;
347
0
    if (aDragTimer.IsActive() )
348
0
    {
349
0
        aDragTimer.Stop();
350
0
    }
351
352
0
    sal_uInt16 nDrgLog = sal_uInt16 ( pWindow->PixelToLogic(Size(SC_MINDRAGMOVE,0)).Width() );
353
0
    auto aLogicPosition = rMEvt.getLogicPosition();
354
0
    Point aPnt(aLogicPosition ? *aLogicPosition : pWindow->PixelToLogic(rMEvt.GetPosPixel()));
355
356
0
    bool bCopy = false;
357
0
    ScViewData& rViewData = rViewShell.GetViewData();
358
0
    ScDocument& rDocument = rViewData.GetDocument();
359
0
    SdrPageView* pPageView = ( pView ? pView->GetSdrPageView() : nullptr );
360
0
    SdrPage* pPage = ( pPageView ? pPageView->GetPage() : nullptr );
361
0
    ::std::vector< OUString > aExcludedChartNames;
362
0
    ScRangeListVector aProtectedChartRangesVector;
363
0
    bool bWasDragged = false;
364
365
0
    if (comphelper::LibreOfficeKit::isActive() && rDocument.IsNegativePage(rViewData.CurrentTabForData()))
366
0
        aPnt.setX(-aPnt.X());
367
368
0
    if (pView && rMEvt.IsLeft())
369
0
    {
370
0
        if ( pView->IsDragObj() )
371
0
        {
372
            // object was moved
373
0
            if ( rMEvt.IsMod1() )
374
0
            {
375
0
                if ( pPage )
376
0
                {
377
0
                    ScChartHelper::GetChartNames( aExcludedChartNames, pPage );
378
0
                }
379
0
                if ( pView )
380
0
                {
381
0
                    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
382
0
                    const size_t nMarkCount = rMarkList.GetMarkCount();
383
0
                    for ( size_t i = 0; i < nMarkCount; ++i )
384
0
                    {
385
0
                        SdrMark* pMark = rMarkList.GetMark( i );
386
0
                        pObj = ( pMark ? pMark->GetMarkedSdrObj() : nullptr );
387
0
                        if ( pObj )
388
0
                        {
389
0
                            ScChartHelper::AddRangesIfProtectedChart( aProtectedChartRangesVector, rDocument, pObj );
390
0
                        }
391
0
                    }
392
0
                }
393
0
                bCopy = true;
394
0
            }
395
396
0
            if (!rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() &&
397
0
                std::abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
398
0
                std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
399
0
            {
400
                /* If a user wants to click on an object in front of a marked
401
                   one, he releases the mouse button immediately */
402
0
                SdrPageView* pPV = nullptr;
403
0
                pObj = pView->PickObj(aMDPos, pView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::BEFOREMARK);
404
0
                if (pObj)
405
0
                {
406
0
                    pView->UnmarkAllObj();
407
0
                    pView->MarkObj(pObj,pPV);
408
0
                    return true;
409
0
                }
410
0
            }
411
0
            bWasDragged = pView->EndDragObj( rMEvt.IsMod1() );
412
0
            pView->ForceMarkedToAnotherPage();
413
414
0
            bReturn = true;
415
0
        }
416
0
        else if (pView->IsAction() )
417
0
        {
418
            // unlock internal layer to include note captions
419
0
            pView->UnlockInternalLayer();
420
0
            pView->EndAction();
421
0
            const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
422
0
            if ( rMarkList.GetMarkCount() != 0 )
423
0
            {
424
0
                bReturn = true;
425
426
                /*  if multi-selection contains a note caption object, remove
427
                    all other objects from selection. */
428
0
                const size_t nCount = rMarkList.GetMarkCount();
429
0
                if( nCount > 1 )
430
0
                {
431
0
                    bool bFound = false;
432
0
                    for( size_t nIdx = 0; !bFound && (nIdx < nCount); ++nIdx )
433
0
                    {
434
0
                        pObj = rMarkList.GetMark( nIdx )->GetMarkedSdrObj();
435
0
                        bFound = ScDrawLayer::IsNoteCaption( pObj );
436
0
                        if( bFound )
437
0
                        {
438
0
                            pView->UnMarkAll();
439
0
                            pView->MarkObj( pObj, pView->GetSdrPageView() );
440
0
                        }
441
0
                    }
442
0
                }
443
0
            }
444
0
        }
445
446
0
        if (ScModule::get()->GetIsWaterCan())
447
0
        {
448
0
            auto pStyleSheet = rViewData.GetDocument().GetStyleSheetPool()->GetActualStyleSheet();
449
0
            if (pStyleSheet && pStyleSheet->GetFamily() == SfxStyleFamily::Frame)
450
0
                pView->SetStyleSheet(static_cast<SfxStyleSheet*>(pStyleSheet), false);
451
0
        }
452
0
    }
453
454
    // maybe consider OLE object
455
0
    SfxInPlaceClient* pIPClient = rViewShell.GetIPClient();
456
457
0
    if (pIPClient)
458
0
    {
459
0
        ScModule* pScMod = ScModule::get();
460
0
        bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
461
462
0
        if ( pIPClient->IsObjectInPlaceActive() && !bUnoRefDialog )
463
0
            pIPClient->DeactivateObject();
464
0
    }
465
466
0
    sal_uInt16 nClicks = rMEvt.GetClicks();
467
0
    if (pView && nClicks == 2 && rMEvt.IsLeft())
468
0
    {
469
0
        const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
470
0
        if ( rMarkList.GetMarkCount() != 0 )
471
0
        {
472
0
            if (rMarkList.GetMarkCount() == 1)
473
0
            {
474
0
                SdrMark* pMark = rMarkList.GetMark(0);
475
0
                pObj = pMark->GetMarkedSdrObj();
476
477
0
                if (nullptr != pObj && pObj->isDiagram())
478
0
                {
479
0
                    SdrObject* pSubSelection(pObj->getDiagramSubSelection());
480
0
                    if (nullptr != pSubSelection && pSubSelection->isDiagramTextNode())
481
0
                        pObj = pSubSelection;
482
0
                }
483
484
                //  only activate, when the mouse also is over the selected object
485
486
0
                SdrViewEvent aVEvt;
487
0
                SdrHitKind eHit = pView->PickAnything( rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt );
488
0
                if (eHit != SdrHitKind::NONE && aVEvt.mpObj == pObj)
489
0
                {
490
0
                    assert(pObj);
491
492
0
                    SdrObjKind nSdrObjKind = pObj->GetObjIdentifier();
493
494
                    //  OLE: activate
495
496
0
                    if (nSdrObjKind == SdrObjKind::OLE2)
497
0
                    {
498
0
                        if (!bOle)
499
0
                        {
500
0
                            if (static_cast<SdrOle2Obj*>(pObj)->GetObjRef().is())
501
0
                            {
502
                                // release so if ActivateObject launches a warning dialog, then that dialog
503
                                // can get mouse events
504
0
                                if (pWindow->IsMouseCaptured())
505
0
                                    pWindow->ReleaseMouse();
506
0
                                rViewShell.ActivateObject(static_cast<SdrOle2Obj*>(pObj), css::embed::EmbedVerbs::MS_OLEVERB_PRIMARY);
507
0
                            }
508
0
                        }
509
0
                    }
510
511
                    //  Edit text
512
                    //  not in UNO controls
513
                    //  #i32352# not in media objects
514
515
0
                    else if ( DynCastSdrTextObj( pObj) != nullptr && dynamic_cast<const SdrUnoObj*>( pObj) == nullptr && dynamic_cast<const SdrMediaObj*>( pObj) ==  nullptr )
516
0
                    {
517
0
                        OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
518
0
                        bool bVertical = ( pOPO && pOPO->IsEffectivelyVertical() );
519
0
                        sal_uInt16 nTextSlotId = bVertical ? SID_DRAW_TEXT_VERTICAL : SID_DRAW_TEXT;
520
521
0
                        rViewShell.GetViewData().GetDispatcher().
522
0
                            Execute(nTextSlotId, SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
523
524
                        // Get the created FuText now and change into EditMode
525
0
                        FuPoor* pPoor = rViewShell.GetViewData().GetView()->GetDrawFuncPtr();
526
0
                        if ( pPoor && pPoor->GetSlotID() == nTextSlotId )    // has no RTTI
527
0
                        {
528
0
                            FuText* pText = static_cast<FuText*>(pPoor);
529
0
                            Point aMousePixel = rMEvt.GetPosPixel();
530
0
                            pText->SetInEditMode( pObj, &aMousePixel );
531
0
                        }
532
0
                        bReturn = true;
533
0
                    }
534
0
                }
535
0
            }
536
0
        }
537
0
        else if ( TestDetective( pView->GetSdrPageView(), aPnt ) )
538
0
            bReturn = true;
539
0
    }
540
541
0
    if (!bWasDragged && pView)
542
0
    {
543
0
        const SdrMarkList& rMarkList(pView->GetMarkedObjectList());
544
0
        if (rMarkList.GetMarkCount() == 1)
545
0
        {
546
0
            SdrObject* pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
547
548
0
            if(nullptr != pSingleObj && pSingleObj->isDiagram())
549
0
            {
550
0
                const std::shared_ptr< svx::diagram::DiagramHelper_svx >& rDiagramHelper(pSingleObj->getDiagramHelper());
551
0
                if (rDiagramHelper)
552
0
                {
553
0
                    SdrPageView* pPV;
554
0
                    SdrObject* pCandidate = pView->PickObj(aMDPos, pView->getHitTolLog(), pPV, SdrSearchOptions::DEEP);
555
0
                    if (pCandidate && !pCandidate->isDiagram())
556
0
                    {
557
0
                        rDiagramHelper->markDirectDiagramSubSelection(*pCandidate);
558
0
                        pView->UnmarkAllObj();
559
0
                        pView->MarkObj(pSingleObj,pPV);
560
0
                        return true;
561
0
                    }
562
0
                }
563
0
            }
564
0
        }
565
0
    }
566
567
0
    ForcePointer(&rMEvt);
568
569
0
    if (pWindow->IsMouseCaptured())
570
0
        pWindow->ReleaseMouse();
571
572
    //  command handler for context menu follows after MouseButtonUp,
573
    //  therefore here the hard IsLeft call
574
0
    if ( !bReturn && rMEvt.IsLeft() )
575
0
        if (rViewShell.IsDrawSelMode())
576
0
            rViewShell.GetViewData().GetDispatcher().
577
0
                Execute(SID_OBJECT_SELECT, SfxCallMode::SLOT | SfxCallMode::RECORD);
578
579
0
    if ( bCopy && pPage )
580
0
    {
581
0
        ScDocShell* pDocShell = rViewData.GetDocShell();
582
0
        ScModelObj* pModelObj = pDocShell ? pDocShell->GetModel() : nullptr;
583
0
        if ( pModelObj )
584
0
        {
585
0
            SCTAB nTab = rViewData.CurrentTabForData();
586
0
            ScChartHelper::CreateProtectedChartListenersAndNotify( rDocument, pPage, pModelObj, nTab,
587
0
                aProtectedChartRangesVector, aExcludedChartNames );
588
0
        }
589
0
    }
590
591
0
    return bReturn;
592
0
}
593
594
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */