Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/view/drviewsa.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 <DrawViewShell.hxx>
21
#include <com/sun/star/scanner/ScannerManager.hpp>
22
#include <cppuhelper/implbase.hxx>
23
#include <comphelper/processfactory.hxx>
24
#include <editeng/sizeitem.hxx>
25
#include <svx/svdlayer.hxx>
26
#include <svx/svdograf.hxx>
27
#include <sfx2/zoomitem.hxx>
28
#include <sfx2/lokhelper.hxx>
29
#include <svx/svdpagv.hxx>
30
#include <svl/ptitem.hxx>
31
#include <svl/stritem.hxx>
32
#include <sfx2/request.hxx>
33
#include <sfx2/dispatch.hxx>
34
#include <svx/zoomslideritem.hxx>
35
#include <svl/eitem.hxx>
36
37
#include <sdcommands.h>
38
#include <svx/f3dchild.hxx>
39
#include <svx/clipfmtitem.hxx>
40
41
#include <sfx2/viewfrm.hxx>
42
#include <svtools/cliplistener.hxx>
43
#include <svx/float3d.hxx>
44
#include <svx/extedit.hxx>
45
#include <svx/sidebar/SelectionAnalyzer.hxx>
46
#include <svx/sidebar/SelectionChangeHandler.hxx>
47
#include <helpids.h>
48
49
#include <view/viewoverlaymanager.hxx>
50
#include <app.hrc>
51
#include <strings.hrc>
52
#include <sdmod.hxx>
53
#include <sdpage.hxx>
54
#include <FrameView.hxx>
55
#include <drawdoc.hxx>
56
#include <sdresid.hxx>
57
#include <DrawDocShell.hxx>
58
#include <Window.hxx>
59
#include <fupoor.hxx>
60
#include <fusel.hxx>
61
#include <funavig.hxx>
62
#include <drawview.hxx>
63
#include <SdUnoDrawView.hxx>
64
#include <ViewShellBase.hxx>
65
#include <slideshow.hxx>
66
#include <annotationmanager.hxx>
67
#include <DrawController.hxx>
68
#include <unomodel.hxx>
69
#include <comphelper/diagnose_ex.hxx>
70
#include <comphelper/lok.hxx>
71
#include <comphelper/servicehelper.hxx>
72
#include <LayerTabBar.hxx>
73
74
#include <memory>
75
76
using namespace ::com::sun::star;
77
using namespace ::com::sun::star::uno;
78
using vcl::EnumContext;
79
80
namespace sd {
81
82
bool DrawViewShell::mbPipette = false;
83
84
namespace {
85
86
class ScannerEventListener : public ::cppu::WeakImplHelper< lang::XEventListener >
87
{
88
private:
89
90
    DrawViewShell*      mpParent;
91
92
public:
93
94
0
                            explicit ScannerEventListener( DrawViewShell* pParent ) : mpParent( pParent )  {}
95
96
    // XEventListener
97
    virtual void SAL_CALL   disposing( const lang::EventObject& rEventObject ) override;
98
99
0
    void                    ParentDestroyed() { mpParent = nullptr; }
100
};
101
102
}
103
104
void SAL_CALL ScannerEventListener::disposing( const lang::EventObject& /*rEventObject*/ )
105
0
{
106
0
    if( mpParent )
107
0
        mpParent->ScannerEvent();
108
0
}
109
110
DrawViewShell::DrawViewShell( ViewShellBase& rViewShellBase, vcl::Window* pParentWindow, PageKind ePageKind, FrameView* pFrameViewArgument )
111
0
    : ViewShell (pParentWindow, rViewShellBase)
112
0
    , maTabControl(VclPtr<sd::TabControl>::Create(this, pParentWindow))
113
0
    , mbIsLayerModeActive(false)
114
0
    , mbIsInSwitchPage(false)
115
0
    , mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler(
116
0
          [this] () { return this->GetSidebarContextName(); },
117
0
          uno::Reference<frame::XController>(rViewShellBase.GetDrawController()),
118
0
          vcl::EnumContext::Context::Default))
119
0
    , mbMouseButtonDown(false)
120
0
    , mbMouseSelecting(false)
121
0
{
122
0
    if (pFrameViewArgument != nullptr)
123
0
        mpFrameView = pFrameViewArgument;
124
0
    else
125
0
        mpFrameView = new FrameView(GetDoc());
126
0
    Construct(GetDocSh(), ePageKind);
127
128
0
    mpSelectionChangeHandler->Connect();
129
130
0
    SetContextName(GetSidebarContextName());
131
132
0
    doShow();
133
134
0
    ConfigureAppBackgroundColor();
135
0
    SdModule* mod = SdModule::get();
136
0
    mod->GetColorConfig().AddListener(this);
137
138
0
    if (comphelper::LibreOfficeKit::isActive())
139
0
    {
140
        // get the full page size in pixels
141
0
        mpContentWindow->EnableMapMode();
142
0
        Size aSize(mpContentWindow->LogicToPixel(GetView()->GetSdrPageView()->GetPage()->GetSize()));
143
        // Disable map mode, so that it's possible to send mouse event
144
        // coordinates in logic units
145
0
        mpContentWindow->EnableMapMode(false);
146
147
        // arrange UI elements again with new view size
148
0
        GetParentWindow()->SetSizePixel(aSize);
149
0
        Resize();
150
151
0
        SdXImpressDocument* pModel = comphelper::getFromUnoTunnel<SdXImpressDocument>(rViewShellBase.GetCurrentDocument());
152
0
        SfxLokHelper::notifyViewRenderState(&rViewShellBase, pModel);
153
0
    }
154
0
}
155
156
DrawViewShell::~DrawViewShell()
157
0
{
158
0
    suppress_fun_call_w_exception(ImplDestroy());
159
0
}
160
161
void DrawViewShell::ImplDestroy()
162
0
{
163
0
    destroyXSlideShowInstance();
164
165
0
    SdModule::get()->GetColorConfig().RemoveListener(this);
166
167
0
    mpSelectionChangeHandler->Disconnect();
168
169
0
    mpAnnotationManager.reset();
170
0
    mpViewOverlayManager.reset();
171
172
0
    OSL_ASSERT (GetViewShell()!=nullptr);
173
174
0
    if( mxScannerListener.is() )
175
0
        static_cast< ScannerEventListener* >( mxScannerListener.get() )->ParentDestroyed();
176
177
    // Remove references to items within Svx3DWin
178
    // (maybe do a listening sometime in Svx3DWin)
179
0
    sal_uInt16 nId = Svx3DChildWindow::GetChildWindowId();
180
0
    SfxChildWindow* pWindow = GetViewFrame() ? GetViewFrame()->GetChildWindow(nId) : nullptr;
181
0
    if(pWindow)
182
0
    {
183
0
        Svx3DWin* p3DWin = static_cast< Svx3DWin* > (pWindow->GetWindow());
184
0
        if(p3DWin)
185
0
            p3DWin->DocumentReload();
186
0
    }
187
188
0
    EndListening (*GetDoc());
189
0
    EndListening (*GetDocSh());
190
191
0
    if( SlideShow::IsRunning(*this) )
192
0
        StopSlideShow();
193
194
0
    DisposeFunctions();
195
196
0
    sal_uInt16 aPageCnt = GetDoc()->GetSdPageCount(mePageKind);
197
198
0
    for (sal_uInt16 i = 0; i < aPageCnt; i++)
199
0
    {
200
0
        SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind);
201
202
0
        if (pPage == mpActualPage)
203
0
        {
204
0
            GetDoc()->SetSelected(pPage, true);
205
0
        }
206
0
        else
207
0
        {
208
0
            GetDoc()->SetSelected(pPage, false);
209
0
        }
210
0
    }
211
212
0
    if ( mxClipEvtLstnr.is() )
213
0
    {
214
0
        mxClipEvtLstnr->RemoveListener( GetActiveWindow() );
215
0
        mxClipEvtLstnr->ClearCallbackLink();        // prevent callback if another thread is waiting
216
0
        mxClipEvtLstnr.clear();
217
0
    }
218
219
0
    mpDrawView.reset();
220
    // Set mpView to NULL so that the destructor of the ViewShell base class
221
    // does not access it.
222
0
    mpView = nullptr;
223
224
0
    mpFrameView->Disconnect();
225
0
    maTabControl.disposeAndClear();
226
0
}
227
228
/**
229
 * common part of both constructors
230
 */
231
void DrawViewShell::Construct(DrawDocShell* pDocSh, PageKind eInitialPageKind)
232
0
{
233
0
    mpActualPage = nullptr;
234
0
    mbReadOnly = GetDocSh()->IsReadOnly();
235
0
    mxClipEvtLstnr.clear();
236
0
    mbPastePossible = false;
237
0
    mbIsLayerModeActive = false;
238
239
0
    mpFrameView->Connect();
240
241
0
    OSL_ASSERT (GetViewShell()!=nullptr);
242
243
0
    SetPool( &GetDoc()->GetPool() );
244
245
0
    GetDoc()->CreateFirstPages();
246
247
0
    mpDrawView.reset( new DrawView(pDocSh, GetActiveWindow()->GetOutDev(), this) );
248
0
    mpView = mpDrawView.get();             // Pointer of base class ViewShell
249
0
    mpDrawView->SetSwapAsynchron(); // Asynchronous load of graphics
250
251
    // We do not read the page kind from the frame view anymore so we have
252
    // to set it in order to resync frame view and this view.
253
0
    mpFrameView->SetPageKind(eInitialPageKind);
254
0
    mePageKind = eInitialPageKind;
255
0
    meEditMode = EditMode::Page;
256
0
    DocumentType eDocType = GetDoc()->GetDocumentType(); // RTTI does not work here
257
0
    switch (mePageKind)
258
0
    {
259
0
        case PageKind::Standard:
260
0
            meShellType = ST_IMPRESS;
261
0
            break;
262
263
0
        case PageKind::Notes:
264
0
            meShellType = ST_NOTES;
265
0
            break;
266
267
0
        case PageKind::Handout:
268
0
            meShellType = ST_HANDOUT;
269
0
            break;
270
0
    }
271
272
0
    Size aPageSize( GetDoc()->GetSdPage(0, mePageKind)->GetSize() );
273
0
    Point aPageOrg( aPageSize.Width(), aPageSize.Height() / 2);
274
0
    Size aSize(aPageSize.Width() * 3, aPageSize.Height() * 2);
275
0
    InitWindows(aPageOrg, aSize, Point(-1, -1));
276
277
0
    Point aVisAreaPos;
278
279
0
    if ( pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
280
0
    {
281
0
        aVisAreaPos = pDocSh->GetVisArea(ASPECT_CONTENT).TopLeft();
282
0
    }
283
284
0
    mpDrawView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aSize));
285
286
    // objects can not grow bigger than ViewSize
287
0
    GetDoc()->SetMaxObjSize(aSize);
288
289
    // Split-Handler for TabControls
290
0
    maTabControl->SetSplitHdl( LINK( this, DrawViewShell, TabSplitHdl ) );
291
292
    /* In order to set the correct EditMode of the FrameView, we select another
293
       one (small trick).  */
294
0
    if (mpFrameView->GetViewShEditMode(/*mePageKind*/) == EditMode::Page)
295
0
    {
296
0
        meEditMode = EditMode::MasterPage;
297
0
    }
298
0
    else
299
0
    {
300
0
        meEditMode = EditMode::Page;
301
0
    }
302
303
    // Use configuration of FrameView
304
0
    ReadFrameViewData(mpFrameView);
305
306
0
    if( eDocType == DocumentType::Draw )
307
0
    {
308
0
        GetActiveWindow()->SetHelpId( HID_SDGRAPHICVIEWSHELL );
309
0
    }
310
0
    else
311
0
    {
312
0
        if (mePageKind == PageKind::Notes)
313
0
        {
314
0
            GetActiveWindow()->SetHelpId( CMD_SID_NOTES_MODE );
315
316
            // AutoLayouts have to be created
317
0
            GetDoc()->StopWorkStartupDelay();
318
0
        }
319
0
        else if (mePageKind == PageKind::Handout)
320
0
        {
321
0
            GetActiveWindow()->SetHelpId( CMD_SID_HANDOUT_MASTER_MODE );
322
323
            // AutoLayouts have to be created
324
0
            GetDoc()->StopWorkStartupDelay();
325
0
        }
326
0
        else
327
0
        {
328
0
            GetActiveWindow()->SetHelpId( HID_SDDRAWVIEWSHELL );
329
0
        }
330
0
    }
331
332
    // start selection function
333
0
    SfxRequest aReq(SID_OBJECT_SELECT, SfxCallMode::SLOT, GetDoc()->GetItemPool());
334
0
    FuPermanent(aReq);
335
0
    mpDrawView->SetFrameDragSingles();
336
337
0
    if (pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)
338
0
    {
339
0
        mbZoomOnPage = false;
340
0
    }
341
0
    else
342
0
    {
343
0
        mbZoomOnPage = true;
344
0
    }
345
346
0
    mbIsRulerDrag = false;
347
348
0
    SetName (u"DrawViewShell"_ustr);
349
350
0
    mnLockCount = 0;
351
352
0
    const uno::Reference< uno::XComponentContext >& xContext( ::comphelper::getProcessComponentContext() );
353
354
0
    try
355
0
    {
356
0
        mxScannerManager = scanner::ScannerManager::create( xContext );
357
358
0
        mxScannerListener = new ScannerEventListener( this );
359
0
    }
360
0
    catch (DeploymentException const &)
361
0
    {
362
0
        SAL_INFO("sd", "Scanner manager not available");
363
0
    }
364
0
    catch (Exception const &)
365
0
    {
366
        // Eat the exception and log it
367
        // We can still continue if scanner manager is not available.
368
0
        DBG_UNHANDLED_EXCEPTION("sd");
369
0
    }
370
371
0
    mpAnnotationManager.reset( new AnnotationManager( GetViewShellBase() ) );
372
0
    mpViewOverlayManager.reset( new ViewOverlayManager( GetViewShellBase() ) );
373
0
}
374
375
void DrawViewShell::Init (bool bIsMainViewShell)
376
0
{
377
0
    ViewShell::Init(bIsMainViewShell);
378
379
0
    if (!IsListening(*GetDocSh()))
380
0
        StartListening (*GetDocSh());
381
0
}
382
383
void DrawViewShell::Shutdown()
384
0
{
385
0
    ViewShell::Shutdown();
386
387
0
    if(SlideShow::IsRunning( GetViewShellBase() )
388
0
        && !SlideShow::IsInteractiveSlideshow( GetViewShellBase() )) // IASS
389
0
    {
390
        // Turn off effects.
391
0
        GetDrawView()->SetAnimationMode(SdrAnimationMode::Disable);
392
0
    }
393
0
}
394
395
css::uno::Reference<css::drawing::XDrawSubController> DrawViewShell::CreateSubController()
396
0
{
397
0
    css::uno::Reference<css::drawing::XDrawSubController> xSubController;
398
399
0
    if (IsMainViewShell())
400
0
    {
401
        // Create uno sub controller for the main view shell.
402
0
        xSubController.set( new SdUnoDrawView( *this, *GetView()));
403
0
    }
404
405
0
    return xSubController;
406
0
}
407
408
bool DrawViewShell::RelocateToParentWindow (vcl::Window* pParentWindow)
409
0
{
410
    // DrawViewShells can not be relocated to a new parent window at the
411
    // moment, so return <FALSE/> except when the given parent window is the
412
    // parent window that is already in use.
413
0
    return pParentWindow==GetParentWindow();
414
0
}
415
416
/**
417
 * check if we have to draw a polyline
418
 */
419
420
/*
421
    Polylines are represented by macros as a sequence of:
422
        MoveTo (x, y)
423
        LineTo (x, y)   [or BezierTo (x, y)]
424
        LineTo (x, y)
425
            :
426
    There is no end command for polylines. Therefore, we have to test all
427
    commands in the requests for LineTo (BezierTo) and we have to gather
428
    the point-parameter. The first not-LineTo leads to the creation of the
429
    polyline from the gathered points.
430
*/
431
432
void DrawViewShell::CheckLineTo(SfxRequest& rReq)
433
0
{
434
#ifdef DBG_UTIL
435
    if(rReq.IsAPI())
436
    {
437
        if(SID_LINETO == rReq.GetSlot() || SID_BEZIERTO == rReq.GetSlot() || SID_MOVETO == rReq.GetSlot() )
438
        {
439
            OSL_FAIL("DrawViewShell::CheckLineTo: slots SID_LINETO, SID_BEZIERTO, SID_MOVETO no longer supported.");
440
        }
441
    }
442
#endif
443
444
0
    rReq.Ignore ();
445
0
}
446
447
/**
448
 * Change page parameter if SID_PAGESIZE or SID_PAGEMARGIN
449
 */
450
void DrawViewShell::SetupPage (Size const &rSize,
451
                                 ::tools::Long nLeft,
452
                                 ::tools::Long nRight,
453
                                 ::tools::Long nUpper,
454
                                 ::tools::Long nLower,
455
                                 bool bSize,
456
                                 bool bMargin,
457
                                 bool bScaleAll)
458
0
{
459
0
    sal_uInt16 nPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind);
460
0
    sal_uInt16 i;
461
462
0
    for (i = 0; i < nPageCnt; i++)
463
0
    {
464
        // first, handle all master pages
465
0
        SdPage *pPage = GetDoc()->GetMasterSdPage(i, mePageKind);
466
467
0
        if( pPage )
468
0
        {
469
0
            if( bSize )
470
0
            {
471
0
                ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
472
0
                pPage->ScaleObjects(rSize, aBorderRect, bScaleAll);
473
0
                pPage->SetSize(rSize);
474
475
0
            }
476
0
            if( bMargin )
477
0
            {
478
0
                pPage->SetLeftBorder(nLeft);
479
0
                pPage->SetRightBorder(nRight);
480
0
                pPage->SetUpperBorder(nUpper);
481
0
                pPage->SetLowerBorder(nLower);
482
0
            }
483
484
0
            if ( mePageKind == PageKind::Standard )
485
0
            {
486
0
                GetDoc()->GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
487
0
            }
488
489
0
            pPage->CreateTitleAndLayout();
490
0
        }
491
0
    }
492
493
0
    nPageCnt = GetDoc()->GetSdPageCount(mePageKind);
494
495
0
    for (i = 0; i < nPageCnt; i++)
496
0
    {
497
        // then, handle all pages
498
0
        SdPage *pPage = GetDoc()->GetSdPage(i, mePageKind);
499
500
0
        if( pPage )
501
0
        {
502
0
            if( bSize )
503
0
            {
504
0
                ::tools::Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
505
0
                pPage->ScaleObjects(rSize, aBorderRect, bScaleAll);
506
0
                pPage->SetSize(rSize);
507
0
            }
508
0
            if( bMargin )
509
0
            {
510
0
                pPage->SetLeftBorder(nLeft);
511
0
                pPage->SetRightBorder(nRight);
512
0
                pPage->SetUpperBorder(nUpper);
513
0
                pPage->SetLowerBorder(nLower);
514
0
            }
515
516
0
            if ( mePageKind == PageKind::Standard )
517
0
            {
518
0
                SdPage* pNotesPage = GetDoc()->GetSdPage(i, PageKind::Notes);
519
0
                pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
520
0
            }
521
522
0
            pPage->SetAutoLayout( pPage->GetAutoLayout() );
523
0
        }
524
0
    }
525
526
0
    if ( mePageKind == PageKind::Standard )
527
0
    {
528
0
        SdPage* pHandoutPage = GetDoc()->GetSdPage(0, PageKind::Handout);
529
0
        pHandoutPage->CreateTitleAndLayout(true);
530
0
    }
531
532
0
    ::tools::Long nWidth = mpActualPage->GetSize().Width();
533
0
    ::tools::Long nHeight = mpActualPage->GetSize().Height();
534
535
0
    Point aPageOrg(nWidth, nHeight / 2);
536
0
    Size aSize( nWidth * 3, nHeight * 2);
537
538
0
    InitWindows(aPageOrg, aSize, Point(-1, -1), true);
539
540
0
    Point aVisAreaPos;
541
542
0
    if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
543
0
    {
544
0
        aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
545
0
    }
546
547
0
    GetView()->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aSize));
548
549
0
    UpdateScrollBars();
550
551
0
    Point aNewOrigin(mpActualPage->GetLeftBorder(), mpActualPage->GetUpperBorder());
552
0
    GetView()->GetSdrPageView()->SetPageOrigin(aNewOrigin);
553
554
0
    GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
555
556
    // zoom onto (new) page size
557
0
    GetViewFrame()->GetDispatcher()->Execute(SID_SIZE_PAGE,
558
0
                        SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
559
0
}
560
561
void DrawViewShell::GetStatusBarState(SfxItemSet& rSet)
562
0
{
563
    /* Zoom-Item
564
       Here we should propagate the corresponding value (Optimal ?, page width
565
       or page) with the help of the ZoomItems !!!   */
566
0
    if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOM ) )
567
0
    {
568
0
        if (GetDocSh()->IsUIActive()
569
0
            || (SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow(GetViewShellBase())) // IASS
570
0
            || !GetActiveWindow())
571
0
        {
572
0
            rSet.DisableItem( SID_ATTR_ZOOM );
573
0
        }
574
0
        else
575
0
        {
576
0
            std::unique_ptr<SvxZoomItem> pZoomItem;
577
0
            sal_uInt16 nZoom = static_cast<sal_uInt16>(GetActiveWindow()->GetZoom());
578
579
0
            if( mbZoomOnPage )
580
0
                pZoomItem.reset(new SvxZoomItem( SvxZoomType::WHOLEPAGE, nZoom ));
581
0
            else
582
0
                pZoomItem.reset(new SvxZoomItem( SvxZoomType::PERCENT, nZoom ));
583
584
            // constrain area
585
0
            SvxZoomEnableFlags nZoomValues = SvxZoomEnableFlags::ALL;
586
0
            SdrPageView* pPageView = mpDrawView->GetSdrPageView();
587
588
0
            if( pPageView && pPageView->GetObjList()->GetObjCount() == 0 )
589
0
            {
590
0
                nZoomValues &= ~SvxZoomEnableFlags::OPTIMAL;
591
0
            }
592
593
0
            pZoomItem->SetValueSet( nZoomValues );
594
0
            rSet.Put( std::move(pZoomItem) );
595
0
        }
596
0
    }
597
0
    if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOMSLIDER ) )
598
0
    {
599
0
        rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetDoc() ) );
600
0
        if (GetDocSh()->IsUIActive()
601
0
            || (xSlideshow.is() && xSlideshow->isRunning() && !xSlideshow->IsInteractiveSlideshow()) // IASS
602
0
            || !GetActiveWindow() )
603
0
        {
604
0
            rSet.DisableItem( SID_ATTR_ZOOMSLIDER );
605
0
        }
606
0
        else
607
0
        {
608
0
            sd::Window * pActiveWindow = GetActiveWindow();
609
0
            SvxZoomSliderItem aZoomItem( static_cast<sal_uInt16>(pActiveWindow->GetZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMinZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMaxZoom()) ) ;
610
611
0
            SdrPageView* pPageView = mpDrawView->GetSdrPageView();
612
0
            if( pPageView )
613
0
            {
614
0
                Point aPagePos(0, 0);
615
0
                Size aPageSize = pPageView->GetPage()->GetSize();
616
617
0
                aPagePos.AdjustX(aPageSize.Width()  / 2 );
618
0
                aPageSize.setWidth( static_cast<::tools::Long>(aPageSize.Width() * 1.03) );
619
620
0
                aPagePos.AdjustY(aPageSize.Height() / 2 );
621
0
                aPageSize.setHeight( static_cast<::tools::Long>(aPageSize.Height() * 1.03) );
622
0
                aPagePos.AdjustY( -(aPageSize.Height() / 2) );
623
624
0
                aPagePos.AdjustX( -(aPageSize.Width()  / 2) );
625
626
0
                ::tools::Rectangle aFullPageZoomRect( aPagePos, aPageSize );
627
0
                aZoomItem.AddSnappingPoint( pActiveWindow->GetZoomForRect( aFullPageZoomRect ) );
628
0
            }
629
0
            aZoomItem.AddSnappingPoint(100);
630
0
            rSet.Put( aZoomItem );
631
0
        }
632
0
    }
633
634
0
    SdrPageView* pPageView = mpDrawView->GetSdrPageView();
635
0
    if (pPageView)
636
0
    {
637
0
        Point aPos = GetActiveWindow()->PixelToLogic(maMousePos);
638
0
        pPageView->LogicToPagePos(aPos);
639
0
        Fraction aUIScale(GetDoc()->GetUIScale());
640
0
        aPos.setX( ::tools::Long(aPos.X() / aUIScale) );
641
0
        aPos.setY( ::tools::Long(aPos.Y() / aUIScale) );
642
643
        // position- and size items
644
0
        if ( mpDrawView->IsAction() )
645
0
        {
646
0
            ::tools::Rectangle aRect;
647
0
            mpDrawView->TakeActionRect( aRect );
648
649
0
            if ( aRect.IsEmpty() )
650
0
                rSet.Put( SfxPointItem(SID_ATTR_POSITION, aPos) );
651
0
            else
652
0
            {
653
0
                pPageView->LogicToPagePos(aRect);
654
0
                aPos = aRect.TopLeft();
655
0
                aPos.setX( ::tools::Long(aPos.X() / aUIScale) );
656
0
                aPos.setY( ::tools::Long(aPos.Y() / aUIScale) );
657
0
                rSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos) );
658
0
                Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
659
0
                aSize.setHeight( ::tools::Long(aSize.Height() / aUIScale) );
660
0
                aSize.setWidth( ::tools::Long(aSize.Width()  / aUIScale) );
661
0
                rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize) );
662
0
            }
663
0
        }
664
0
        else
665
0
        {
666
0
            const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
667
0
            if ( rMarkList.GetMarkCount() != 0 )
668
0
            {
669
0
                ::tools::Rectangle aRect = mpDrawView->GetAllMarkedRect();
670
0
                pPageView->LogicToPagePos(aRect);
671
672
                // Show the position of the selected shape(s)
673
0
                Point aShapePosition (aRect.TopLeft());
674
0
                aShapePosition.setX( ::tools::Long(aShapePosition.X() / aUIScale) );
675
0
                aShapePosition.setY( ::tools::Long(aShapePosition.Y() / aUIScale) );
676
0
                rSet.Put (SfxPointItem(SID_ATTR_POSITION, aShapePosition));
677
678
0
                Size aSize( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() );
679
0
                aSize.setHeight( ::tools::Long(aSize.Height() / aUIScale) );
680
0
                aSize.setWidth( ::tools::Long(aSize.Width()  / aUIScale) );
681
0
                rSet.Put( SvxSizeItem( SID_ATTR_SIZE, aSize) );
682
0
            }
683
0
            else
684
0
            {
685
0
                rSet.Put( SfxPointItem(SID_ATTR_POSITION, aPos) );
686
0
                rSet.Put( SvxSizeItem( SID_ATTR_SIZE, Size( 0, 0 ) ) );
687
0
            }
688
0
        }
689
0
    }
690
691
    // Display of current page and layer.
692
0
    if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STATUS_PAGE ) )
693
0
    {
694
0
        sal_Int32 nPageCount = sal_Int32(GetDoc()->GetSdPageCount(mePageKind));
695
0
        sal_Int32 nActivePageCount = sal_Int32(GetDoc()->GetActiveSdPageCount());
696
        // Always show the slide/page number.
697
0
        OUString aOUString;
698
0
        if (GetDoc()->GetDocumentType() == DocumentType::Draw)
699
0
            aOUString = (nPageCount == nActivePageCount) ? SdResId(STR_SD_PAGE_COUNT_DRAW) : SdResId(STR_SD_PAGE_COUNT_CUSTOM_DRAW);
700
0
        else
701
0
            aOUString = (nPageCount == nActivePageCount) ? SdResId(STR_SD_PAGE_COUNT) : SdResId(STR_SD_PAGE_COUNT_CUSTOM);
702
703
0
        aOUString = aOUString.replaceFirst("%1", OUString::number(maTabControl->GetCurPagePos() + 1));
704
0
        aOUString = aOUString.replaceFirst("%2", OUString::number(nPageCount));
705
0
        if(nPageCount != nActivePageCount)
706
0
            aOUString = aOUString.replaceFirst("%3", OUString::number(nActivePageCount));
707
708
        // If in layer mode additionally show the layer that contains all
709
        // selected shapes of the page.  If the shapes are distributed on
710
        // more than one layer, no layer name is shown.
711
0
        if (IsLayerModeActive())
712
0
        {
713
0
            SdrLayerAdmin& rLayerAdmin = GetDoc()->GetLayerAdmin();
714
0
            SdrLayerID nLayer(0), nOldLayer(0);
715
0
            SdrObject* pObj = nullptr;
716
0
            const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
717
0
            const size_t nMarkCount = rMarkList.GetMarkCount();
718
0
            bool bOneLayer = true;
719
720
            // Use the first ten selected shapes as a (hopefully
721
            // representative) sample of all shapes of the current page.
722
            // Detect whether they belong to the same layer.
723
0
            for( size_t j = 0; j < nMarkCount && bOneLayer && j < 10; ++j )
724
0
            {
725
0
                pObj = rMarkList.GetMark( j )->GetMarkedSdrObj();
726
0
                if( pObj )
727
0
                {
728
0
                    nLayer = pObj->GetLayer();
729
730
0
                    if( j != 0 && nLayer != nOldLayer )
731
0
                        bOneLayer = false;
732
733
0
                    nOldLayer = nLayer;
734
0
                }
735
0
            }
736
737
            // Append the layer name to the current page number.
738
0
            if( bOneLayer && nMarkCount )
739
0
            {
740
0
                SdrLayer* pLayer = rLayerAdmin.GetLayerPerID( nLayer );
741
0
                if( pLayer )
742
0
                {
743
0
                    aOUString += " (" + LayerTabBar::convertToLocalizedName(pLayer->GetName()) + ")";
744
0
                }
745
0
            }
746
0
        }
747
748
0
        rSet.Put (SfxStringItem (SID_STATUS_PAGE, aOUString));
749
0
    }
750
    // Layout
751
0
    if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STATUS_LAYOUT ) )
752
0
    {
753
0
        OUString aString = mpActualPage->GetLayoutName();
754
0
        sal_Int32 nPos = aString.indexOf(SD_LT_SEPARATOR);
755
0
        if (nPos != -1)
756
0
            aString = aString.copy(0, nPos);
757
0
        rSet.Put( SfxStringItem( SID_STATUS_LAYOUT, aString ) );
758
0
    }
759
    // Scale
760
0
    if( SfxItemState::DEFAULT == rSet.GetItemState( SID_SCALE ) )
761
0
    {
762
0
        const Fraction& aUIScale = GetDoc()->GetUIScale();
763
0
        OUString aString = OUString::number(aUIScale.GetNumerator()) +
764
0
            ":" + OUString::number(aUIScale.GetDenominator());
765
0
        rSet.Put( SfxStringItem( SID_SCALE, aString ) );
766
0
    }
767
0
}
768
769
void DrawViewShell::Notify (SfxBroadcaster&, const SfxHint& rHint)
770
0
{
771
0
    if (rHint.GetId()!=SfxHintId::ModeChanged)
772
0
        return;
773
774
    // Change to selection when turning on read-only mode.
775
0
    if(GetDocSh()->IsReadOnly() && dynamic_cast< FuSelection* >( GetCurrentFunction().get() ) )
776
0
    {
777
0
        SfxRequest aReq(SID_OBJECT_SELECT, SfxCallMode::SLOT, GetDoc()->GetItemPool());
778
0
        FuPermanent(aReq);
779
0
    }
780
781
    // Turn on design mode when document is not read-only.
782
0
    if (GetDocSh()->IsReadOnly() != mbReadOnly )
783
0
    {
784
0
        mbReadOnly = GetDocSh()->IsReadOnly();
785
786
0
        SfxBoolItem aItem( SID_FM_DESIGN_MODE, !mbReadOnly );
787
0
        GetViewFrame()->GetDispatcher()->ExecuteList(SID_FM_DESIGN_MODE,
788
0
            SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
789
0
    }
790
791
0
}
792
793
void DrawViewShell::ExecuteAnnotation (SfxRequest const & rRequest)
794
0
{
795
0
    if (mpAnnotationManager)
796
0
        mpAnnotationManager->ExecuteAnnotation( rRequest );
797
0
}
798
799
void DrawViewShell::GetAnnotationState (SfxItemSet& rItemSet )
800
0
{
801
0
    if (mpAnnotationManager)
802
0
        mpAnnotationManager->GetAnnotationState( rItemSet );
803
0
}
804
805
OUString const & DrawViewShell::GetSidebarContextName() const
806
0
{
807
0
    svx::sidebar::SelectionAnalyzer::ViewType eViewType (svx::sidebar::SelectionAnalyzer::ViewType::Standard);
808
0
    switch (mePageKind)
809
0
    {
810
0
        case PageKind::Handout:
811
0
            eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Handout;
812
0
            break;
813
0
        case PageKind::Notes:
814
0
            eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Notes;
815
0
            break;
816
0
        case PageKind::Standard:
817
0
            if (meEditMode == EditMode::MasterPage)
818
0
                eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Master;
819
0
            else
820
0
                eViewType = svx::sidebar::SelectionAnalyzer::ViewType::Standard;
821
0
            break;
822
0
    }
823
0
    const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
824
0
    return EnumContext::GetContextName(
825
0
        svx::sidebar::SelectionAnalyzer::GetContextForSelection_SD(
826
0
            rMarkList,
827
0
            eViewType));
828
0
}
829
830
void DrawViewShell::ExecGoToNextPage (SfxRequest& rReq)
831
0
{
832
0
    SetCurrentFunction( FuNavigation::Create( *this, GetActiveWindow(), mpDrawView.get(), *GetDoc(), rReq) );
833
0
    Cancel();
834
0
}
835
836
void DrawViewShell::GetStateGoToNextPage (SfxItemSet& rSet)
837
0
{
838
0
    SdPage* pPage = GetActualPage();
839
0
    sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
840
0
    sal_uInt16 totalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
841
0
    if (nSdPage + 1 >= totalPages)
842
0
        rSet.DisableItem( SID_GO_TO_NEXT_PAGE );
843
0
}
844
845
void DrawViewShell::ExecGoToPreviousPage (SfxRequest& rReq)
846
0
{
847
0
    SetCurrentFunction( FuNavigation::Create( *this, GetActiveWindow(), mpDrawView.get(), *GetDoc(), rReq) );
848
0
    Cancel();
849
0
}
850
851
void DrawViewShell::GetStateGoToPreviousPage (SfxItemSet& rSet)
852
0
{
853
0
    SdPage* pPage = GetActualPage();
854
0
    sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
855
0
    if (nSdPage == 0)
856
0
        rSet.DisableItem( SID_GO_TO_PREVIOUS_PAGE );
857
0
}
858
859
860
void DrawViewShell::ExecGoToFirstPage (SfxRequest& rReq)
861
0
{
862
0
    SetCurrentFunction( FuNavigation::Create( *this, GetActiveWindow(), mpDrawView.get(), *GetDoc(), rReq) );
863
0
    Cancel();
864
0
}
865
866
void DrawViewShell::GetStateGoToFirstPage (SfxItemSet& rSet)
867
0
{
868
0
    SdPage* pPage = GetActualPage();
869
0
    sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
870
0
    if (nSdPage == 0)
871
0
        rSet.DisableItem( SID_GO_TO_FIRST_PAGE );
872
0
}
873
874
void DrawViewShell::ExecGoToLastPage (SfxRequest& rReq)
875
0
{
876
0
    SetCurrentFunction( FuNavigation::Create( *this, GetActiveWindow(), mpDrawView.get(), *GetDoc(), rReq) );
877
0
    Cancel();
878
0
}
879
880
void DrawViewShell::GetStateGoToLastPage (SfxItemSet& rSet)
881
0
{
882
0
    SdPage* pPage = GetActualPage();
883
0
    sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
884
0
    sal_uInt16 totalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
885
0
    if (nSdPage + 1 >= totalPages)
886
0
        rSet.DisableItem( SID_GO_TO_LAST_PAGE );
887
0
}
888
889
void DrawViewShell::ExecGoToPage (SfxRequest& rReq)
890
0
{
891
0
    SetCurrentFunction( FuNavigation::Create( *this, GetActiveWindow(), mpDrawView.get(), *GetDoc(), rReq) );
892
0
    Cancel();
893
0
}
894
895
void DrawViewShell::GetStateGoToPage (SfxItemSet& rSet)
896
0
{
897
0
    if (meEditMode == EditMode::MasterPage)
898
0
        rSet.DisableItem( SID_GO_TO_PAGE );
899
0
}
900
901
} // end of namespace sd
902
903
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */