Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/svx/source/dialog/graphctl.cxx
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <config_wasm_strip.h>
21
22
#include <svl/itempool.hxx>
23
#include <vcl/settings.hxx>
24
#include <vcl/ptrstyle.hxx>
25
#include <vcl/svapp.hxx>
26
27
#include <svx/graphctl.hxx>
28
#include <svx/sdr/overlay/overlaymanager.hxx>
29
#include <GraphCtlAccessibleContext.hxx>
30
#include <svx/svxids.hrc>
31
#include <svx/svdpage.hxx>
32
#include <svx/sdrpaintwindow.hxx>
33
34
void GraphCtrlUserCall::Changed( const SdrObject& rObj, SdrUserCallType eType, const tools::Rectangle& /*rOldBoundRect*/ )
35
0
{
36
0
    switch( eType )
37
0
    {
38
0
        case SdrUserCallType::MoveOnly:
39
0
        case SdrUserCallType::Resize:
40
0
            rWin.SdrObjChanged( rObj );
41
0
        break;
42
43
0
        case SdrUserCallType::Inserted:
44
0
            rWin.SdrObjCreated( rObj );
45
0
        break;
46
47
0
        default:
48
0
        break;
49
0
    }
50
0
    rWin.QueueIdleUpdate();
51
0
}
52
53
GraphCtrl::GraphCtrl(weld::Dialog* pDialog)
54
0
    : aUpdateIdle("svx GraphCtrl Update")
55
0
    , aMap100(MapUnit::Map100thMM)
56
0
    , eObjKind(SdrObjKind::NONE)
57
0
    , nPolyEdit(0)
58
0
    , bEditMode(false)
59
0
    , mbSdrMode(false)
60
0
    , mbInIdleUpdate(false)
61
0
    , mpDialog(pDialog)
62
0
{
63
0
    pUserCall.reset(new GraphCtrlUserCall( *this ));
64
0
    aUpdateIdle.SetPriority( TaskPriority::LOWEST );
65
0
    aUpdateIdle.SetInvokeHandler( LINK( this, GraphCtrl, UpdateHdl ) );
66
0
    aUpdateIdle.Start();
67
0
}
68
69
void GraphCtrl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
70
0
{
71
0
    weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
72
0
    EnableRTL(false);
73
0
}
74
75
GraphCtrl::~GraphCtrl()
76
0
{
77
0
    aUpdateIdle.Stop();
78
79
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
80
0
    if( mpAccContext.is() )
81
0
    {
82
0
        mpAccContext->disposing();
83
0
        mpAccContext.clear();
84
0
    }
85
0
#endif
86
87
0
    pView.reset();
88
0
    pModel.reset();
89
0
    pUserCall.reset();
90
0
}
91
92
void GraphCtrl::SetSdrMode(bool bSdrMode)
93
0
{
94
0
    mbSdrMode = bSdrMode;
95
96
0
    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
97
0
    OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
98
0
    rDevice.SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
99
0
    xVD->SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
100
0
    rDevice.SetMapMode( aMap100 );
101
0
    xVD->SetMapMode( aMap100 );
102
103
0
    pView.reset();
104
0
    pModel.reset();
105
106
0
    if ( mbSdrMode )
107
0
        InitSdrModel();
108
109
0
    QueueIdleUpdate();
110
0
}
111
112
void GraphCtrl::InitSdrModel()
113
0
{
114
0
    SolarMutexGuard aGuard;
115
116
0
    rtl::Reference<SdrPage> pPage;
117
118
    // destroy old junk
119
0
    pView.reset();
120
0
    pModel.reset();
121
122
    // Creating a Model
123
0
    pModel.reset(new SdrModel(nullptr, nullptr, true));
124
0
    pModel->SetScaleUnit(aMap100.GetMapUnit());
125
0
    pModel->SetDefaultFontHeight( 500 );
126
127
0
    pPage = new SdrPage( *pModel );
128
129
0
    pPage->SetSize( aGraphSize );
130
0
    pPage->SetBorder( 0, 0, 0, 0 );
131
0
    pModel->InsertPage( pPage.get() );
132
0
    pModel->SetChanged( false );
133
134
    // Creating a View
135
0
    pView.reset(new GraphCtrlView(*pModel, this));
136
0
    pView->SetWorkArea( tools::Rectangle( Point(), aGraphSize ) );
137
0
    pView->EnableExtendedMouseEventDispatcher( true );
138
0
    pView->ShowSdrPage(pView->GetModel().GetPage(0));
139
0
    pView->SetFrameDragSingles();
140
0
    pView->SetMarkedPointsSmooth( SdrPathSmoothKind::Symmetric );
141
0
    pView->SetEditMode();
142
143
    // #i72889# set needed flags
144
0
    pView->SetPageDecorationAllowed(false);
145
0
    pView->SetMasterPageVisualizationAllowed(false);
146
0
    pView->SetBufferedOutputAllowed(true);
147
0
    pView->SetBufferedOverlayAllowed(true);
148
149
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
150
    // Tell the accessibility object about the changes.
151
0
    if (mpAccContext.is())
152
0
        mpAccContext->setModelAndView (pModel.get(), pView.get());
153
0
#endif
154
0
}
155
156
void GraphCtrl::SetGraphic( const Graphic& rGraphic, bool bNewModel )
157
0
{
158
0
    aGraphic = rGraphic;
159
0
    xVD->SetOutputSizePixel(Size(0, 0)); //force redraw
160
161
0
    if ( aGraphic.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel )
162
0
        aGraphSize = Application::GetDefaultDevice()->PixelToLogic( aGraphic.GetPrefSize(), aMap100 );
163
0
    else
164
0
        aGraphSize = OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), aMap100 );
165
166
0
    if ( mbSdrMode && bNewModel )
167
0
        InitSdrModel();
168
169
0
    aGraphSizeLink.Call( this );
170
171
0
    Resize();
172
173
0
    Invalidate();
174
0
    QueueIdleUpdate();
175
0
}
176
177
void GraphCtrl::GraphicToVD()
178
0
{
179
0
    OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
180
0
    xVD->SetOutputSizePixel(GetOutputSizePixel());
181
0
    xVD->SetBackground(rDevice.GetBackground());
182
0
    xVD->Erase();
183
0
    const bool bGraphicValid(GraphicType::NONE != aGraphic.GetType());
184
0
    if (bGraphicValid)
185
0
        aGraphic.Draw(*xVD, Point(), aGraphSize);
186
0
}
187
188
void GraphCtrl::Resize()
189
0
{
190
0
    weld::CustomWidgetController::Resize();
191
192
0
    if (aGraphSize.Width() && aGraphSize.Height())
193
0
    {
194
0
        MapMode         aDisplayMap( aMap100 );
195
0
        Point           aNewPos;
196
0
        Size            aNewSize;
197
0
        OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
198
0
        const Size      aWinSize = rDevice.PixelToLogic( GetOutputSizePixel(), aDisplayMap );
199
0
        const tools::Long      nWidth = aWinSize.Width();
200
0
        const tools::Long      nHeight = aWinSize.Height();
201
0
        double          fGrfWH = static_cast<double>(aGraphSize.Width()) / aGraphSize.Height();
202
0
        double          fWinWH = static_cast<double>(nWidth) / nHeight;
203
204
        // Adapt Bitmap to Thumb size
205
0
        if ( fGrfWH < fWinWH)
206
0
        {
207
0
            aNewSize.setWidth( static_cast<tools::Long>( static_cast<double>(nHeight) * fGrfWH ) );
208
0
            aNewSize.setHeight( nHeight );
209
0
        }
210
0
        else
211
0
        {
212
0
            aNewSize.setWidth( nWidth );
213
0
            aNewSize.setHeight( static_cast<tools::Long>( static_cast<double>(nWidth) / fGrfWH ) );
214
0
        }
215
216
0
        aNewPos.setX( ( nWidth - aNewSize.Width() )  >> 1 );
217
0
        aNewPos.setY( ( nHeight - aNewSize.Height() ) >> 1 );
218
219
        // Implementing MapMode for Engine
220
0
        aDisplayMap.SetScaleX( Fraction( aNewSize.Width(), aGraphSize.Width() ) );
221
0
        aDisplayMap.SetScaleY( Fraction( aNewSize.Height(), aGraphSize.Height() ) );
222
223
0
        aDisplayMap.SetOrigin( OutputDevice::LogicToLogic( aNewPos, aMap100, aDisplayMap ) );
224
0
        rDevice.SetMapMode( aDisplayMap );
225
0
        xVD->SetMapMode( aDisplayMap );
226
0
    }
227
228
0
    Invalidate();
229
0
}
230
231
void GraphCtrl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
232
0
{
233
    // #i72889# used split repaint to be able to paint an own background
234
    // even to the buffered view
235
0
    const bool bGraphicValid(GraphicType::NONE != aGraphic.GetType());
236
237
0
    if (GetOutputSizePixel() != xVD->GetOutputSizePixel())
238
0
        GraphicToVD();
239
240
0
    if (mbSdrMode)
241
0
    {
242
0
        SdrPaintWindow* pPaintWindow = pView->BeginCompleteRedraw(&rRenderContext);
243
0
        pPaintWindow->SetOutputToWindow(true);
244
245
0
        if (bGraphicValid)
246
0
        {
247
0
            vcl::RenderContext& rTarget = pPaintWindow->GetTargetOutputDevice();
248
249
0
            OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
250
0
            rTarget.SetBackground(rDevice.GetBackground());
251
0
            rTarget.Erase();
252
253
0
            rTarget.DrawOutDev(Point(), xVD->GetOutputSize(), Point(), xVD->GetOutputSize(), *xVD);
254
0
        }
255
256
0
        const vcl::Region aRepaintRegion(rRect);
257
0
        pView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion);
258
0
        pView->EndCompleteRedraw(*pPaintWindow, true);
259
0
    }
260
0
    else
261
0
    {
262
        // #i73381# in non-SdrMode, paint to local directly
263
0
        rRenderContext.DrawOutDev(rRect.TopLeft(), rRect.GetSize(),
264
0
                                  rRect.TopLeft(), rRect.GetSize(),
265
0
                                  *xVD);
266
0
    }
267
0
}
268
269
void GraphCtrl::SdrObjChanged( const SdrObject&  )
270
0
{
271
0
    QueueIdleUpdate();
272
0
}
273
274
void GraphCtrl::SdrObjCreated( const SdrObject& )
275
0
{
276
0
    QueueIdleUpdate();
277
0
}
278
279
void GraphCtrl::MarkListHasChanged()
280
0
{
281
0
    QueueIdleUpdate();
282
0
}
283
284
bool GraphCtrl::KeyInput( const KeyEvent& rKEvt )
285
0
{
286
0
    vcl::KeyCode aCode( rKEvt.GetKeyCode() );
287
0
    bool    bProc = false;
288
289
0
    OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
290
291
0
    switch ( aCode.GetCode() )
292
0
    {
293
0
        case KEY_DELETE:
294
0
        case KEY_BACKSPACE:
295
0
        {
296
0
            if ( mbSdrMode )
297
0
            {
298
0
                pView->DeleteMarked();
299
0
                bProc = true;
300
0
            }
301
0
        }
302
0
        break;
303
304
0
        case KEY_ESCAPE:
305
0
        {
306
0
            if ( mbSdrMode )
307
0
            {
308
0
                const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
309
0
                if ( pView->IsAction() )
310
0
                {
311
0
                    pView->BrkAction();
312
0
                    bProc = true;
313
0
                }
314
0
                else if ( rMarkList.GetMarkCount() != 0 )
315
0
                {
316
0
                    pView->UnmarkAllObj();
317
0
                    bProc = true;
318
0
                }
319
0
            }
320
0
        }
321
0
        break;
322
323
0
        case KEY_F11:
324
0
        case KEY_TAB:
325
0
        {
326
0
            if( mbSdrMode )
327
0
            {
328
0
                if( !aCode.IsMod1() && !aCode.IsMod2() )
329
0
                {
330
0
                    bool bForward = !aCode.IsShift();
331
                    // select next object
332
0
                    if ( ! pView->MarkNextObj( bForward ))
333
0
                    {
334
                        // At first or last object.  Cycle to the other end
335
                        // of the list.
336
0
                        pView->UnmarkAllObj();
337
0
                        pView->MarkNextObj (bForward);
338
0
                    }
339
0
                    bProc = true;
340
0
                }
341
0
                else if(aCode.IsMod1())
342
0
                {
343
                    // select next handle
344
0
                    const SdrHdlList& rHdlList = pView->GetHdlList();
345
0
                    bool bForward(!aCode.IsShift());
346
347
0
                    const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
348
349
0
                    bProc = true;
350
0
                }
351
0
            }
352
0
        }
353
0
        break;
354
355
0
        case KEY_END:
356
0
        {
357
358
0
            if ( aCode.IsMod1() )
359
0
            {
360
                // mark last object
361
0
                pView->UnmarkAllObj();
362
0
                pView->MarkNextObj();
363
364
0
                bProc = true;
365
0
            }
366
0
        }
367
0
        break;
368
369
0
        case KEY_HOME:
370
0
        {
371
0
            if ( aCode.IsMod1() )
372
0
            {
373
0
                pView->UnmarkAllObj();
374
0
                pView->MarkNextObj(true);
375
376
0
                bProc = true;
377
0
            }
378
0
        }
379
0
        break;
380
381
0
        case KEY_UP:
382
0
        case KEY_DOWN:
383
0
        case KEY_LEFT:
384
0
        case KEY_RIGHT:
385
0
        {
386
0
            tools::Long nX = 0;
387
0
            tools::Long nY = 0;
388
389
0
            if (aCode.GetCode() == KEY_UP)
390
0
            {
391
                // Scroll up
392
0
                nX = 0;
393
0
                nY =-1;
394
0
            }
395
0
            else if (aCode.GetCode() == KEY_DOWN)
396
0
            {
397
                // Scroll down
398
0
                nX = 0;
399
0
                nY = 1;
400
0
            }
401
0
            else if (aCode.GetCode() == KEY_LEFT)
402
0
            {
403
                // Scroll left
404
0
                nX =-1;
405
0
                nY = 0;
406
0
            }
407
0
            else if (aCode.GetCode() == KEY_RIGHT)
408
0
            {
409
                // Scroll right
410
0
                nX = 1;
411
0
                nY = 0;
412
0
            }
413
414
0
            const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
415
0
            if (rMarkList.GetMarkCount() != 0 && !aCode.IsMod1() )
416
0
            {
417
0
                if(aCode.IsMod2())
418
0
                {
419
                    // move in 1 pixel distance
420
0
                    Size aLogicSizeOnePixel = rDevice.PixelToLogic(Size(1,1));
421
0
                    nX *= aLogicSizeOnePixel.Width();
422
0
                    nY *= aLogicSizeOnePixel.Height();
423
0
                }
424
0
                else
425
0
                {
426
                    // old, fixed move distance
427
0
                    nX *= 100;
428
0
                    nY *= 100;
429
0
                }
430
431
                // II
432
0
                const SdrHdlList& rHdlList = pView->GetHdlList();
433
0
                SdrHdl* pHdl = rHdlList.GetFocusHdl();
434
435
0
                if(nullptr == pHdl)
436
0
                {
437
                    // restrict movement to WorkArea
438
0
                    const tools::Rectangle& rWorkArea = pView->GetWorkArea();
439
440
0
                    if(!rWorkArea.IsEmpty())
441
0
                    {
442
0
                        tools::Rectangle aMarkRect(pView->GetMarkedObjRect());
443
0
                        aMarkRect.Move(nX, nY);
444
445
0
                        if(!aMarkRect.Contains(rWorkArea))
446
0
                        {
447
0
                            if(aMarkRect.Left() < rWorkArea.Left())
448
0
                            {
449
0
                                nX += rWorkArea.Left() - aMarkRect.Left();
450
0
                            }
451
452
0
                            if(aMarkRect.Right() > rWorkArea.Right())
453
0
                            {
454
0
                                nX -= aMarkRect.Right() - rWorkArea.Right();
455
0
                            }
456
457
0
                            if(aMarkRect.Top() < rWorkArea.Top())
458
0
                            {
459
0
                                nY += rWorkArea.Top() - aMarkRect.Top();
460
0
                            }
461
462
0
                            if(aMarkRect.Bottom() > rWorkArea.Bottom())
463
0
                            {
464
0
                                nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
465
0
                            }
466
0
                        }
467
0
                    }
468
469
                    // no handle selected
470
0
                    if(0 != nX || 0 != nY)
471
0
                    {
472
0
                        pView->MoveAllMarked(Size(nX, nY));
473
0
                    }
474
0
                }
475
0
                else
476
0
                {
477
                    // move handle with index nHandleIndex
478
0
                    if (nX || nY)
479
0
                    {
480
                        // now move the Handle (nX, nY)
481
0
                        Point aStartPoint(pHdl->GetPos());
482
0
                        Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
483
0
                        const SdrDragStat& rDragStat = pView->GetDragStat();
484
485
                        // start dragging
486
0
                        pView->BegDragObj(aStartPoint, nullptr, pHdl, 0);
487
488
0
                        if(pView->IsDragObj())
489
0
                        {
490
0
                            bool bWasNoSnap = rDragStat.IsNoSnap();
491
0
                            bool bWasSnapEnabled = pView->IsSnapEnabled();
492
493
                            // switch snapping off
494
0
                            if(!bWasNoSnap)
495
0
                                const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
496
0
                            if(bWasSnapEnabled)
497
0
                                pView->SetSnapEnabled(false);
498
499
0
                            pView->MovAction(aEndPoint);
500
0
                            pView->EndDragObj();
501
502
                            // restore snap
503
0
                            if(!bWasNoSnap)
504
0
                                const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
505
0
                            if(bWasSnapEnabled)
506
0
                                pView->SetSnapEnabled(bWasSnapEnabled);
507
0
                        }
508
0
                    }
509
0
                }
510
511
0
                bProc = true;
512
0
            }
513
0
        }
514
0
        break;
515
516
0
        case KEY_SPACE:
517
0
        {
518
0
            const SdrHdlList& rHdlList = pView->GetHdlList();
519
0
            SdrHdl* pHdl = rHdlList.GetFocusHdl();
520
521
0
            if(pHdl)
522
0
            {
523
0
                if(pHdl->GetKind() == SdrHdlKind::Poly)
524
0
                {
525
                    // rescue ID of point with focus
526
0
                    sal_uInt32 nPol(pHdl->GetPolyNum());
527
0
                    sal_uInt32 nPnt(pHdl->GetPointNum());
528
529
0
                    if(pView->IsPointMarked(*pHdl))
530
0
                    {
531
0
                        if(rKEvt.GetKeyCode().IsShift())
532
0
                        {
533
0
                            pView->UnmarkPoint(*pHdl);
534
0
                        }
535
0
                    }
536
0
                    else
537
0
                    {
538
0
                        if(!rKEvt.GetKeyCode().IsShift())
539
0
                        {
540
0
                            pView->UnmarkAllPoints();
541
0
                        }
542
543
0
                        pView->MarkPoint(*pHdl);
544
0
                    }
545
546
0
                    if(nullptr == rHdlList.GetFocusHdl())
547
0
                    {
548
                        // restore point with focus
549
0
                        SdrHdl* pNewOne = nullptr;
550
551
0
                        for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a)
552
0
                        {
553
0
                            SdrHdl* pAct = rHdlList.GetHdl(a);
554
555
0
                            if(pAct
556
0
                                && pAct->GetKind() == SdrHdlKind::Poly
557
0
                                && pAct->GetPolyNum() == nPol
558
0
                                && pAct->GetPointNum() == nPnt)
559
0
                            {
560
0
                                pNewOne = pAct;
561
0
                            }
562
0
                        }
563
564
0
                        if(pNewOne)
565
0
                        {
566
0
                            const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne);
567
0
                        }
568
0
                    }
569
570
0
                    bProc = true;
571
0
                }
572
0
            }
573
0
        }
574
0
        break;
575
576
0
        default:
577
0
        break;
578
0
    }
579
580
0
    if (bProc)
581
0
        ReleaseMouse();
582
583
0
    QueueIdleUpdate();
584
585
0
    return bProc;
586
0
}
587
588
bool GraphCtrl::MouseButtonDown( const MouseEvent& rMEvt )
589
0
{
590
0
    if ( mbSdrMode && ( rMEvt.GetClicks() < 2 ) )
591
0
    {
592
0
        OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
593
594
0
        const Point aLogPt( rDevice.PixelToLogic( rMEvt.GetPosPixel() ) );
595
596
0
        if ( !tools::Rectangle( Point(), aGraphSize ).Contains( aLogPt ) && !pView->IsEditMode() )
597
0
            weld::CustomWidgetController::MouseButtonDown( rMEvt );
598
0
        else
599
0
        {
600
            // Get Focus for key inputs
601
0
            GrabFocus();
602
603
0
            if ( nPolyEdit )
604
0
            {
605
0
                SdrViewEvent    aVEvt;
606
0
                SdrHitKind      eHit = pView->PickAnything( rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt );
607
608
0
                if ( nPolyEdit == SID_BEZIER_INSERT && eHit == SdrHitKind::MarkedObject )
609
0
                    pView->BegInsObjPoint( aLogPt, rMEvt.IsMod1());
610
0
                else
611
0
                    pView->MouseButtonDown( rMEvt, &rDevice );
612
0
            }
613
0
            else
614
0
                pView->MouseButtonDown( rMEvt, &rDevice );
615
0
        }
616
617
0
        SdrObject* pCreateObj = pView->GetCreateObj();
618
619
        // We want to realize the insert
620
0
        if ( pCreateObj && !pCreateObj->GetUserCall() )
621
0
            pCreateObj->SetUserCall( pUserCall.get() );
622
623
0
        SetPointer( pView->GetPreferredPointer( aLogPt, &rDevice ) );
624
0
    }
625
0
    else
626
0
        weld::CustomWidgetController::MouseButtonDown( rMEvt );
627
628
0
    QueueIdleUpdate();
629
630
0
    return false;
631
0
}
632
633
bool GraphCtrl::MouseMove(const MouseEvent& rMEvt)
634
0
{
635
0
    OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
636
0
    const Point aLogPos( rDevice.PixelToLogic( rMEvt.GetPosPixel() ) );
637
638
0
    if ( mbSdrMode )
639
0
    {
640
0
        pView->MouseMove( rMEvt, &rDevice );
641
642
0
        if( ( SID_BEZIER_INSERT == nPolyEdit ) &&
643
0
            !pView->PickHandle( aLogPos ) &&
644
0
            !pView->IsInsObjPoint() )
645
0
        {
646
0
            SetPointer( PointerStyle::Cross );
647
0
        }
648
0
        else
649
0
            SetPointer( pView->GetPreferredPointer( aLogPos, &rDevice ) );
650
0
    }
651
0
    else
652
0
        weld::CustomWidgetController::MouseButtonUp( rMEvt );
653
654
0
    if ( aMousePosLink.IsSet() )
655
0
    {
656
0
        if ( tools::Rectangle( Point(), aGraphSize ).Contains( aLogPos ) )
657
0
            aMousePos = aLogPos;
658
0
        else
659
0
            aMousePos = Point();
660
661
0
        aMousePosLink.Call( this );
662
0
    }
663
664
0
    QueueIdleUpdate();
665
666
0
    return false;
667
0
}
668
669
bool GraphCtrl::MouseButtonUp(const MouseEvent& rMEvt)
670
0
{
671
0
    if ( mbSdrMode )
672
0
    {
673
0
        OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
674
675
0
        if ( pView->IsInsObjPoint() )
676
0
            pView->EndInsObjPoint( SdrCreateCmd::ForceEnd );
677
0
        else
678
0
            pView->MouseButtonUp( rMEvt, &rDevice );
679
680
0
        ReleaseMouse();
681
0
        SetPointer( pView->GetPreferredPointer( rDevice.PixelToLogic( rMEvt.GetPosPixel() ), &rDevice ) );
682
0
    }
683
0
    else
684
0
        weld::CustomWidgetController::MouseButtonUp( rMEvt );
685
686
0
    QueueIdleUpdate();
687
688
0
    return false;
689
0
}
690
691
SdrObject* GraphCtrl::GetSelectedSdrObject() const
692
0
{
693
0
    SdrObject* pSdrObj = nullptr;
694
695
0
    if ( mbSdrMode )
696
0
    {
697
0
        const SdrMarkList&  rMarkList = pView->GetMarkedObjectList();
698
699
0
        if ( rMarkList.GetMarkCount() == 1 )
700
0
            pSdrObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
701
0
    }
702
703
0
    return pSdrObj;
704
0
}
705
706
void GraphCtrl::SetEditMode( const bool _bEditMode )
707
0
{
708
0
    if ( mbSdrMode )
709
0
    {
710
0
        bEditMode = _bEditMode;
711
0
        pView->SetEditMode( bEditMode );
712
0
        eObjKind = SdrObjKind::NONE;
713
0
        pView->SetCurrentObj(eObjKind);
714
0
    }
715
0
    else
716
0
        bEditMode = false;
717
718
0
    QueueIdleUpdate();
719
0
}
720
721
void GraphCtrl::SetPolyEditMode( const sal_uInt16 _nPolyEdit )
722
0
{
723
0
    if ( mbSdrMode && ( _nPolyEdit != nPolyEdit ) )
724
0
    {
725
0
        nPolyEdit = _nPolyEdit;
726
0
        pView->SetFrameDragSingles( nPolyEdit == 0 );
727
0
    }
728
0
    else
729
0
        nPolyEdit = 0;
730
731
0
    QueueIdleUpdate();
732
0
}
733
734
void GraphCtrl::SetObjKind( const SdrObjKind _eObjKind )
735
0
{
736
0
    if ( mbSdrMode )
737
0
    {
738
0
        bEditMode = false;
739
0
        pView->SetEditMode( bEditMode );
740
0
        eObjKind = _eObjKind;
741
0
        pView->SetCurrentObj(eObjKind);
742
0
    }
743
0
    else
744
0
        eObjKind = SdrObjKind::NONE;
745
746
0
    QueueIdleUpdate();
747
0
}
748
749
IMPL_LINK_NOARG(GraphCtrl, UpdateHdl, Timer *, void)
750
0
{
751
0
    mbInIdleUpdate = true;
752
0
    aUpdateLink.Call( this );
753
0
    mbInIdleUpdate = false;
754
0
}
755
756
void GraphCtrl::QueueIdleUpdate()
757
0
{
758
0
    if (!mbInIdleUpdate)
759
0
        aUpdateIdle.Start();
760
0
}
761
762
namespace
763
{
764
    class WeldOverlayManager final : public sdr::overlay::OverlayManager
765
    {
766
        weld::CustomWidgetController& m_rGraphCtrl;
767
768
    public:
769
        WeldOverlayManager(weld::CustomWidgetController& rGraphCtrl, OutputDevice& rDevice)
770
0
            : OverlayManager(rDevice)
771
0
            , m_rGraphCtrl(rGraphCtrl)
772
0
        {
773
0
        }
774
775
        // invalidate the given range at local OutputDevice
776
        virtual void invalidateRange(const basegfx::B2DRange& rRange) override
777
0
        {
778
0
            tools::Rectangle aInvalidateRectangle(RangeToInvalidateRectangle(rRange));
779
0
            m_rGraphCtrl.Invalidate(aInvalidateRectangle);
780
0
        }
781
    };
782
}
783
784
rtl::Reference<sdr::overlay::OverlayManager> GraphCtrlView::CreateOverlayManager(OutputDevice& rDevice) const
785
0
{
786
0
    assert(&rDevice == &rGraphCtrl.GetDrawingArea()->get_ref_device());
787
0
    if (rDevice.GetOutDevType() == OUTDEV_VIRDEV)
788
0
    {
789
0
        rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager(new WeldOverlayManager(rGraphCtrl, rDevice));
790
0
        InitOverlayManager(xOverlayManager);
791
0
        return xOverlayManager;
792
0
    }
793
0
    return SdrView::CreateOverlayManager(rDevice);
794
0
}
795
796
void GraphCtrlView::InvalidateOneWin(OutputDevice& rDevice)
797
0
{
798
0
    assert(&rDevice == &rGraphCtrl.GetDrawingArea()->get_ref_device());
799
0
    if (rDevice.GetOutDevType() == OUTDEV_VIRDEV)
800
0
    {
801
0
        rGraphCtrl.Invalidate();
802
0
        return;
803
0
    }
804
0
    SdrView::InvalidateOneWin(rDevice);
805
0
}
806
807
void GraphCtrlView::InvalidateOneWin(OutputDevice& rDevice, const tools::Rectangle& rArea)
808
0
{
809
0
    assert(&rDevice == &rGraphCtrl.GetDrawingArea()->get_ref_device());
810
0
    if (rDevice.GetOutDevType() == OUTDEV_VIRDEV)
811
0
    {
812
0
        rGraphCtrl.Invalidate(rArea);
813
0
        return;
814
0
    }
815
0
    SdrView::InvalidateOneWin(rDevice, rArea);
816
0
}
817
818
GraphCtrlView::~GraphCtrlView()
819
0
{
820
    // turn SetOutputToWindow back off again before
821
    // turning back into our baseclass during dtoring
822
0
    const sal_uInt32 nWindowCount(PaintWindowCount());
823
0
    for (sal_uInt32 nWinNum(0); nWinNum < nWindowCount; nWinNum++)
824
0
    {
825
0
        SdrPaintWindow* pPaintWindow = GetPaintWindow(nWinNum);
826
0
        pPaintWindow->SetOutputToWindow(false);
827
0
    }
828
0
}
829
830
Point GraphCtrl::GetPositionInDialog() const
831
0
{
832
0
    int x, y, width, height;
833
0
    if (GetDrawingArea()->get_extents_relative_to(*mpDialog, x, y, width, height))
834
0
        return Point(x, y);
835
0
    return Point();
836
0
}
837
838
rtl::Reference<comphelper::OAccessible> GraphCtrl::CreateAccessible()
839
0
{
840
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
841
0
    if(mpAccContext == nullptr )
842
0
    {
843
0
        mpAccContext = new SvxGraphCtrlAccessibleContext(*this);
844
0
    }
845
0
#endif
846
0
    return mpAccContext;
847
0
}
848
849
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */