Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/view/drviews1.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 <ViewShellImplementation.hxx>
22
23
#include <DrawController.hxx>
24
#include <com/sun/star/embed/XEmbeddedObject.hpp>
25
26
#include <comphelper/scopeguard.hxx>
27
#include <rtl/ref.hxx>
28
29
#include <svx/svxids.hrc>
30
#include <svx/svdpagv.hxx>
31
#include <sfx2/viewfrm.hxx>
32
#include <sfx2/bindings.hxx>
33
#include <svx/svdoole2.hxx>
34
#include <sfx2/dispatch.hxx>
35
#include <sfx2/module.hxx>
36
#include <sfx2/notebookbar/SfxNotebookBar.hxx>
37
#include <sfx2/lokhelper.hxx>
38
#include <sfx2/zoomitem.hxx>
39
#include <svx/svdopage.hxx>
40
#include <svx/fmshell.hxx>
41
#include <tools/debug.hxx>
42
#include <comphelper/diagnose_ex.hxx>
43
#include <vcl/graphicfilter.hxx>
44
45
#include <view/viewoverlaymanager.hxx>
46
47
#include <app.hrc>
48
49
#include <fupoor.hxx>
50
#include <unokywds.hxx>
51
#include <sdpage.hxx>
52
#include <FrameView.hxx>
53
#include <Window.hxx>
54
#include <drawview.hxx>
55
#include <drawdoc.hxx>
56
#include <DrawDocShell.hxx>
57
#include <Ruler.hxx>
58
#include <Client.hxx>
59
#include <slideshow.hxx>
60
#include <AnimationChildWindow.hxx>
61
#include <ToolBarManager.hxx>
62
#include <FormShellManager.hxx>
63
#include <ViewShellBase.hxx>
64
#include <LayerTabBar.hxx>
65
#include <ViewShellManager.hxx>
66
#include <ViewShellHint.hxx>
67
#include <SlideSorter.hxx>
68
#include <SlideSorterViewShell.hxx>
69
#include <controller/SlideSorterController.hxx>
70
#include <controller/SlsPageSelector.hxx>
71
72
#include <comphelper/lok.hxx>
73
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
74
#include <vcl/uitest/logger.hxx>
75
#include <vcl/uitest/eventdescription.hxx>
76
#include <titledockwin.hxx>
77
#include <strings.hrc>
78
#include <sdresid.hxx>
79
#include <unomodel.hxx>
80
81
using namespace com::sun::star;
82
83
namespace sd {
84
85
void DrawViewShell::Activate(bool bIsMDIActivate)
86
0
{
87
0
    ViewShell::Activate(bIsMDIActivate);
88
89
    // tdf#150773: do not grab focus on loading
90
0
    if (mbFirstTimeActivation)
91
0
        mbFirstTimeActivation = false;
92
0
    else
93
0
    {
94
95
        // When the mode is switched to normal the main view shell grabs focus.
96
        // This is done for getting cut/copy/paste commands on slides in the left
97
        // pane (slide sorter view shell) to work properly.
98
0
        SfxShell* pTopViewShell = GetViewShellBase().GetViewShellManager()->GetTopViewShell();
99
0
        if (pTopViewShell == this)
100
0
        {
101
0
            GetActiveWindow()->GrabFocus();
102
0
        }
103
0
    }
104
0
}
105
106
void DrawViewShell::UIActivating( SfxInPlaceClient* pCli )
107
0
{
108
0
    ViewShell::UIActivating(pCli);
109
110
    // Disable own controls
111
0
    maTabControl->Disable();
112
0
    if (GetLayerTabControl() != nullptr)
113
0
        GetLayerTabControl()->Disable();
114
0
}
115
116
void DrawViewShell::UIDeactivated( SfxInPlaceClient* pCli )
117
0
{
118
    // Enable own controls
119
0
    maTabControl->Enable();
120
0
    if (GetLayerTabControl() != nullptr)
121
0
        GetLayerTabControl()->Enable();
122
123
0
    ViewShell::UIDeactivated(pCli);
124
0
}
125
126
void DrawViewShell::Deactivate(bool bIsMDIActivate)
127
0
{
128
    // Temporarily disable context broadcasting while the Deactivate()
129
    // call is forwarded to our base class.
130
0
    const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));
131
132
0
    ViewShell::Deactivate(bIsMDIActivate);
133
134
0
    SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled);
135
0
}
136
137
namespace
138
{
139
    class LockUI
140
    {
141
    private:
142
        void Lock(bool bLock);
143
        SfxViewFrame *mpFrame;
144
    public:
145
0
        explicit LockUI(SfxViewFrame *pFrame) : mpFrame(pFrame) { Lock(true); }
146
0
        ~LockUI() { Lock(false); }
147
148
    };
149
150
    void LockUI::Lock(bool bLock)
151
0
    {
152
0
        if (!mpFrame)
153
0
            return;
154
0
        mpFrame->Enable( !bLock );
155
0
    }
156
}
157
158
/**
159
 * Called, if state of selection of view is changed
160
 */
161
162
void DrawViewShell::SelectionHasChanged()
163
0
{
164
0
    Invalidate();
165
166
    //Update3DWindow(); // 3D-Controller
167
0
    SfxBoolItem aItem( SID_3D_STATE, true );
168
0
    GetViewFrame()->GetDispatcher()->ExecuteList(
169
0
        SID_3D_STATE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
170
171
0
    SdrOle2Obj* pOleObj = nullptr;
172
173
0
    const SdrMarkList& rMarkList(mpDrawView->GetMarkedObjectList());
174
0
    if ( rMarkList.GetMarkCount() != 0 )
175
0
    {
176
0
        if (rMarkList.GetMarkCount() == 1)
177
0
        {
178
0
            SdrMark* pMark = rMarkList.GetMark(0);
179
0
            SdrObject* pObj = pMark->GetMarkedSdrObj();
180
181
0
            SdrInventor nInv        = pObj->GetObjInventor();
182
0
            SdrObjKind  nSdrObjKind = pObj->GetObjIdentifier();
183
184
0
            if (nInv == SdrInventor::Default && nSdrObjKind == SdrObjKind::OLE2)
185
0
            {
186
0
                pOleObj = static_cast<SdrOle2Obj*>(pObj);
187
0
                UpdateIMapDlg( pObj );
188
0
            }
189
0
            else if (nSdrObjKind == SdrObjKind::Graphic)
190
0
                UpdateIMapDlg( pObj );
191
0
        }
192
0
    }
193
194
0
    ViewShellBase& rBase = GetViewShellBase();
195
0
    rBase.SetVerbs( uno::Sequence< embed::VerbDescriptor >() );
196
197
0
    try
198
0
    {
199
0
        if (pOleObj)
200
0
        {
201
0
            if (const auto& xObj = pOleObj->GetObjRef())
202
0
                rBase.SetVerbs(xObj->getSupportedVerbs());
203
0
        }
204
0
        else if (auto* pIPClient = rBase.GetIPClient();
205
0
                 pIPClient && pIPClient->IsObjectInPlaceActive())
206
0
        {
207
            // as appropriate take ole-objects into account and deactivate
208
209
            // this means we recently deselected an inplace active ole object so
210
            // we need to deselect it now
211
212
            //#i47279# disable frame until after object has completed unload
213
0
            LockUI aUILock(GetViewFrame());
214
0
            pIPClient->DeactivateObject();
215
            //HMHmpDrView->ShowMarkHdl();
216
0
        }
217
0
    }
218
0
    catch( css::uno::Exception& )
219
0
    {
220
0
        TOOLS_WARN_EXCEPTION( "sd", "sd::DrawViewShell::SelectionHasChanged()" );
221
0
    }
222
223
0
    if( HasCurrentFunction() )
224
0
    {
225
0
        GetCurrentFunction()->SelectionHasChanged();
226
0
    }
227
0
    else
228
0
    {
229
0
        GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*this,*mpDrawView);
230
0
    }
231
232
    // Invalidate for every subshell
233
0
    GetViewShellBase().GetViewShellManager()->InvalidateAllSubShells(this);
234
235
0
    mpDrawView->UpdateSelectionClipboard();
236
237
0
    GetViewShellBase().GetDrawController()->FireSelectionChangeListener();
238
0
}
239
240
namespace {
241
242
void collectUIInformation(const OUString& aZoom)
243
0
{
244
0
    EventDescription aDescription;
245
0
    aDescription.aID = "impress_win";
246
0
    aDescription.aParameters = {{"ZOOM", aZoom}};
247
0
    aDescription.aAction = "SET";
248
0
    aDescription.aKeyWord = "ImpressWindowUIObject";
249
0
    aDescription.aParent = "MainWindow";
250
251
0
    UITestLogger::getInstance().logEvent(aDescription);
252
0
}
253
254
}
255
256
/**
257
 * set zoom factor
258
 */
259
void DrawViewShell::SetZoom( ::tools::Long nZoom )
260
0
{
261
    // Make sure that the zoom factor will not be recalculated on
262
    // following window resizings.
263
0
    mbZoomOnPage = false;
264
0
    ViewShell::SetZoom( nZoom );
265
0
    GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
266
0
    GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
267
0
    mpViewOverlayManager->onZoomChanged();
268
0
    collectUIInformation(OUString::number(nZoom));
269
0
    RememberPageZoom(nZoom);
270
0
}
271
272
/**
273
 * Set zoom rectangle for active window
274
 */
275
276
void DrawViewShell::SetZoomRect( const ::tools::Rectangle& rZoomRect )
277
0
{
278
0
    ViewShell::SetZoomRect( rZoomRect );
279
0
    GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
280
0
    GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
281
0
    mpViewOverlayManager->onZoomChanged();
282
0
}
283
284
/**
285
 * PrepareClose, as appropriate end text input, so other viewshells
286
 * discover a refreshed text object.
287
 */
288
289
bool DrawViewShell::PrepareClose( bool bUI )
290
0
{
291
0
    if ( !ViewShell::PrepareClose(bUI) )
292
0
        return false;
293
294
0
    if( HasCurrentFunction() )
295
0
    {
296
0
        sal_uInt16 nID = GetCurrentFunction()->GetSlotID();
297
0
        if (nID == SID_TEXTEDIT || nID == SID_ATTR_CHAR)
298
0
        {
299
0
            mpDrawView->SdrEndTextEdit();
300
0
        }
301
0
    }
302
303
0
    return true;
304
0
}
305
306
307
/**
308
 * Set status (enabled/disabled) of menu SfxSlots
309
 */
310
311
void DrawViewShell::ChangeEditMode(EditMode eEMode, bool bIsLayerModeActive)
312
0
{
313
0
    if (meEditMode == eEMode && mbIsLayerModeActive == bIsLayerModeActive)
314
0
        return;
315
316
0
    ViewShellManager::UpdateLock aLock (GetViewShellBase().GetViewShellManager());
317
318
0
    sal_uInt16 nActualPageId = maTabControl->GetPageId(0);
319
320
0
    if (mePageKind == PageKind::Handout)
321
0
    {
322
        // at handouts only allow MasterPage
323
0
        eEMode = EditMode::MasterPage;
324
0
    }
325
326
0
    GetViewShellBase().GetDrawController()->FireChangeEditMode (eEMode == EditMode::MasterPage);
327
0
    GetViewShellBase().GetDrawController()->FireChangeLayerMode (bIsLayerModeActive);
328
329
0
    if ( mpDrawView->IsTextEdit() )
330
0
    {
331
        // This exits the text edit mode when going in and out of window focus, which is not needed
332
        // Let's keep this call as comment for now as it probably just needs a better conditional.
333
        // mpDrawView->SdrEndTextEdit();
334
0
    }
335
336
0
    LayerTabBar* pLayerBar = GetLayerTabControl();
337
0
    if (pLayerBar != nullptr)
338
0
        pLayerBar->EndEditMode();
339
0
    maTabControl->EndEditMode();
340
341
0
    GetViewShellBase().GetDrawController()->BroadcastContextChange();
342
343
0
    meEditMode = eEMode;
344
345
0
    if(pLayerBar)
346
0
    {
347
        // #i87182# only switch activation mode of LayerTabBar when there is one,
348
        // else it will not get initialized with the current set of Layers as needed
349
0
        mbIsLayerModeActive = bIsLayerModeActive;
350
0
    }
351
352
    // Determine whether to show the master view toolbar.  The master
353
    // page mode has to be active and the shell must not be a handout
354
    // view.
355
0
    bool bShowMasterViewToolbar (meEditMode == EditMode::MasterPage
356
0
         && GetShellType() != ViewShell::ST_HANDOUT);
357
0
    bool bShowPresentationToolbar (meEditMode != EditMode::MasterPage
358
0
         && GetShellType() != ViewShell::ST_HANDOUT
359
0
         && GetShellType() != ViewShell::ST_DRAW);
360
361
    // If the master view toolbar is not shown we hide it before
362
    // switching the edit mode.
363
0
    if (::sd::ViewShell::mpImpl->mbIsInitialized
364
0
        && IsMainViewShell())
365
0
    {
366
0
        if ( !bShowMasterViewToolbar )
367
0
            GetViewShellBase().GetToolBarManager()->ResetToolBars(ToolBarManager::ToolBarGroup::MasterMode);
368
0
        if ( !bShowPresentationToolbar )
369
0
            GetViewShellBase().GetToolBarManager()->ResetToolBars(ToolBarManager::ToolBarGroup::CommonTask);
370
0
    }
371
372
0
    ConfigureAppBackgroundColor();
373
374
    // tdf#87638 - change slide pane title according to the edit mode
375
0
    auto setLeftPaneTitleIfPaneExists
376
0
        = [pViewShell = GetViewFrame()](sal_uInt16 nId, TranslateId aId)
377
0
    {
378
0
        if (auto* pChildWindow = pViewShell->GetChildWindow(nId))
379
0
            if (auto* pTitledDockingWindow
380
0
                = static_cast<TitledDockingWindow*>(pChildWindow->GetWindow()))
381
0
                pTitledDockingWindow->SetTitle(SdResId(aId));
382
0
    };
383
384
0
    if (meEditMode == EditMode::Page)
385
0
    {
386
        /******************************************************************
387
        * PAGEMODE
388
        ******************************************************************/
389
390
0
        maTabControl->Clear();
391
392
        // tdf#87638 - change slide pane title according to the edit mode
393
0
        setLeftPaneTitleIfPaneExists(SID_LEFT_PANE_DRAW, STR_LEFT_PANE_DRAW_TITLE);
394
0
        setLeftPaneTitleIfPaneExists(SID_LEFT_PANE_IMPRESS, STR_LEFT_PANE_IMPRESS_TITLE);
395
396
0
        SdPage* pPage;
397
0
        sal_uInt16 nPageCnt = GetDoc()->GetSdPageCount(mePageKind);
398
399
0
        for (sal_uInt16 i = 0; i < nPageCnt; i++)
400
0
        {
401
0
            pPage = GetDoc()->GetSdPage(i, mePageKind);
402
0
            OUString aPageName = pPage->GetName();
403
0
            maTabControl->InsertPage(pPage->getPageId(), aPageName);
404
405
0
            if ( !comphelper::LibreOfficeKit::isActive() && pPage->IsSelected() )
406
0
            {
407
0
                nActualPageId = pPage->getPageId();
408
0
            }
409
0
        }
410
411
0
        maTabControl->SetCurPageId(nActualPageId);
412
413
0
        SwitchPage(maTabControl->GetPagePos(nActualPageId));
414
415
        //tdf#102343 re-enable common undo on switch back from master mode
416
0
        mpDrawView->GetModel().SetDisableTextEditUsesCommonUndoManager(false);
417
0
    }
418
0
    else
419
0
    {
420
        /******************************************************************
421
        * MASTERPAGE
422
        ******************************************************************/
423
0
        GetViewFrame()->SetChildWindow(
424
0
            AnimationChildWindow::GetChildWindowId(), false );
425
426
        // tdf#87638 - change slide pane title according to the edit mode
427
0
        setLeftPaneTitleIfPaneExists(SID_LEFT_PANE_DRAW, STR_LEFT_PANE_DRAW_TITLE_MASTER);
428
0
        setLeftPaneTitleIfPaneExists(SID_LEFT_PANE_IMPRESS, STR_LEFT_PANE_IMPRESS_TITLE_MASTER);
429
430
0
        if (!mpActualPage)
431
0
        {
432
            // as long as there is no mpActualPage, take first
433
0
            mpActualPage = GetDoc()->GetSdPage(0, mePageKind);
434
0
        }
435
436
0
        maTabControl->Clear();
437
0
        sal_uInt16 nActualMasterPageId = maTabControl->GetPageId(0);
438
0
        sal_uInt16 nMasterPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind);
439
440
0
        for (sal_uInt16 i = 0; i < nMasterPageCnt; i++)
441
0
        {
442
0
            SdPage* pMaster = GetDoc()->GetMasterSdPage(i, mePageKind);
443
0
            OUString aLayoutName = pMaster->GetLayoutName();
444
0
            sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR);
445
0
            if (nPos != -1)
446
0
                aLayoutName = aLayoutName.copy(0, nPos);
447
448
0
            maTabControl->InsertPage(pMaster->getPageId(), aLayoutName);
449
450
0
            if (&(mpActualPage->TRG_GetMasterPage()) == pMaster)
451
0
            {
452
0
                nActualMasterPageId = pMaster->getPageId();
453
0
            }
454
0
        }
455
456
0
        maTabControl->SetCurPageId(nActualMasterPageId);
457
0
        SwitchPage(maTabControl->GetPagePos(nActualMasterPageId));
458
459
        //tdf#102343 changing attributes of textboxes in master typically
460
        //changes the stylesheet they are linked to, so if the common
461
        //undo manager is in use, those stylesheet changes are thrown
462
        //away at present
463
0
        mpDrawView->GetModel().SetDisableTextEditUsesCommonUndoManager(true);
464
0
    }
465
466
    // If the master view toolbar is to be shown we turn it on after the
467
    // edit mode has been changed.
468
0
    if (::sd::ViewShell::mpImpl->mbIsInitialized && !sfx2::SfxNotebookBar::IsActive()
469
0
        && IsMainViewShell())
470
0
    {
471
0
        if (bShowMasterViewToolbar)
472
0
            GetViewShellBase().GetToolBarManager()->SetToolBar(
473
0
                ToolBarManager::ToolBarGroup::MasterMode,
474
0
                ToolBarManager::msMasterViewToolBar);
475
0
        if (bShowPresentationToolbar)
476
0
            GetViewShellBase().GetToolBarManager()->SetToolBar(
477
0
                ToolBarManager::ToolBarGroup::CommonTask,
478
0
                ToolBarManager::msCommonTaskToolBar);
479
0
    }
480
481
0
    if ( ! mbIsLayerModeActive)
482
0
    {
483
0
        maTabControl->Show();
484
        // Set the tab control only for draw pages.  For master page
485
        // this has been done already above.
486
0
        if (meEditMode == EditMode::Page)
487
0
            maTabControl->SetCurPageId (nActualPageId);
488
0
    }
489
490
0
    ResetActualLayer();
491
492
0
    Invalidate( SID_PAGEMODE );
493
0
    Invalidate( SID_LAYERMODE );
494
0
    Invalidate( SID_MASTERPAGE );
495
0
    Invalidate( SID_DELETE_MASTER_PAGE );
496
0
    Invalidate( SID_DELETE_PAGE );
497
0
    Invalidate( SID_SLIDE_MASTER_MODE );
498
0
    Invalidate( SID_NOTES_MASTER_MODE );
499
0
    Invalidate( SID_HANDOUT_MASTER_MODE );
500
0
    InvalidateWindows();
501
502
0
    if (sfx2::SfxNotebookBar::IsActive())
503
0
        UIFeatureChanged();
504
505
0
    SetContextName(GetSidebarContextName());
506
507
0
}
508
509
/**
510
 * Generate horizontal ruler
511
 */
512
513
VclPtr<SvxRuler> DrawViewShell::CreateHRuler (::sd::Window* pWin)
514
0
{
515
0
    VclPtr<Ruler> pRuler;
516
0
    WinBits  aWBits;
517
0
    SvxRulerSupportFlags nFlags = SvxRulerSupportFlags::OBJECT;
518
519
0
    aWBits  = WB_HSCROLL | WB_3DLOOK | WB_BORDER | WB_EXTRAFIELD;
520
0
    nFlags |= SvxRulerSupportFlags::SET_NULLOFFSET |
521
0
              SvxRulerSupportFlags::TABS |
522
0
              SvxRulerSupportFlags::PARAGRAPH_MARGINS; // new
523
524
0
    pRuler = VclPtr<Ruler>::Create(*this, GetParentWindow(), pWin, nFlags,
525
0
        GetViewFrame()->GetBindings(), aWBits);
526
527
    // Metric ...
528
0
    sal_uInt16 nMetric = static_cast<sal_uInt16>(GetDoc()->GetUIUnit());
529
530
0
    if( nMetric == 0xffff )
531
0
        nMetric = static_cast<sal_uInt16>(GetViewShellBase().GetViewFrame().GetDispatcher()->GetModule()->GetFieldUnit());
532
533
0
    pRuler->SetUnit( FieldUnit( nMetric ) );
534
535
    // ... and also set DefTab at the ruler
536
0
    pRuler->SetDefTabDist( GetDoc()->GetDefaultTabulator() ); // new
537
538
0
    Fraction aUIScale(pWin->GetMapMode().GetScaleX());
539
0
    aUIScale *= GetDoc()->GetUIScale();
540
0
    pRuler->SetZoom(aUIScale);
541
542
0
    return pRuler;
543
0
}
544
545
/**
546
 * Generate vertical ruler
547
 */
548
549
VclPtr<SvxRuler> DrawViewShell::CreateVRuler(::sd::Window* pWin)
550
0
{
551
0
    VclPtr<SvxRuler> pRuler;
552
0
    WinBits  aWBits = WB_VSCROLL | WB_3DLOOK | WB_BORDER;
553
0
    SvxRulerSupportFlags nFlags = SvxRulerSupportFlags::OBJECT;
554
555
0
    pRuler = VclPtr<Ruler>::Create(*this, GetParentWindow(), pWin, nFlags,
556
0
        GetViewFrame()->GetBindings(), aWBits);
557
558
    // Metric same as HRuler, use document setting
559
0
    sal_uInt16 nMetric = static_cast<sal_uInt16>(GetDoc()->GetUIUnit());
560
561
0
    if( nMetric == 0xffff )
562
0
        nMetric = static_cast<sal_uInt16>(GetViewShellBase().GetViewFrame().GetDispatcher()->GetModule()->GetFieldUnit());
563
564
0
    pRuler->SetUnit( FieldUnit( nMetric ) );
565
566
0
    Fraction aUIScale(pWin->GetMapMode().GetScaleY());
567
0
    aUIScale *= GetDoc()->GetUIScale();
568
0
    pRuler->SetZoom(aUIScale);
569
570
0
    return pRuler;
571
0
}
572
573
/**
574
 * Refresh horizontal ruler
575
 */
576
577
void DrawViewShell::UpdateHRuler()
578
0
{
579
0
    Invalidate( SID_ATTR_LONG_LRSPACE );
580
0
    Invalidate( SID_RULER_PAGE_POS );
581
0
    Invalidate( SID_RULER_OBJECT );
582
0
    Invalidate( SID_RULER_TEXT_RIGHT_TO_LEFT );
583
584
0
    if (mpHorizontalRuler)
585
0
        mpHorizontalRuler->ForceUpdate();
586
0
}
587
588
/**
589
 * Refresh vertical ruler
590
 */
591
592
void DrawViewShell::UpdateVRuler()
593
0
{
594
0
    Invalidate( SID_ATTR_LONG_LRSPACE );
595
0
    Invalidate( SID_RULER_PAGE_POS );
596
0
    Invalidate( SID_RULER_OBJECT );
597
598
0
    if (mpVerticalRuler)
599
0
        mpVerticalRuler->ForceUpdate();
600
0
}
601
602
/**
603
 * Refresh TabControl on splitter change
604
 */
605
606
IMPL_LINK( DrawViewShell, TabSplitHdl, TabBar *, pTab, void )
607
0
{
608
0
    const ::tools::Long nMax = maViewSize.Width() - maScrBarWH.Width()
609
0
        - maTabControl->GetPosPixel().X() ;
610
611
0
    Size aTabSize = maTabControl->GetSizePixel();
612
0
    aTabSize.setWidth( std::min(pTab->GetSplitSize(), static_cast<::tools::Long>(nMax-1)) );
613
614
0
    maTabControl->SetSizePixel(aTabSize);
615
616
0
    if(GetLayerTabControl()) // #i87182#
617
0
    {
618
0
        GetLayerTabControl()->SetSizePixel(aTabSize);
619
0
    }
620
621
0
    Point aPos = maTabControl->GetPosPixel();
622
0
    aPos.AdjustX(aTabSize.Width() );
623
624
0
    Size aScrSize(nMax - aTabSize.Width(), maScrBarWH.Height());
625
0
    mpHorizontalScrollBar->SetPosSizePixel(aPos, aScrSize);
626
0
}
627
628
/// inherited from sd::ViewShell
629
SdPage* DrawViewShell::getCurrentPage() const
630
0
{
631
0
    const sal_uInt16 nPageCount = (meEditMode == EditMode::Page)?
632
0
                                    GetDoc()->GetSdPageCount(mePageKind):
633
0
                                    GetDoc()->GetMasterSdPageCount(mePageKind);
634
635
0
    sal_uInt16 nCurrentPage = maTabControl->GetCurPagePos();
636
0
    DBG_ASSERT((nCurrentPage<nPageCount), "sd::DrawViewShell::getCurrentPage(), illegal page index!");
637
0
    if (nCurrentPage >= nPageCount)
638
0
        nCurrentPage = 0; // play safe here
639
640
0
    if (meEditMode == EditMode::Page)
641
0
    {
642
0
        return GetDoc()->GetSdPage(nCurrentPage, mePageKind);
643
0
    }
644
0
    else // EditMode::MasterPage
645
0
    {
646
0
        return GetDoc()->GetMasterSdPage(nCurrentPage, mePageKind);
647
0
    }
648
0
}
649
650
/**
651
 * Select new refreshed page, in case of a page order change (eg. by undo)
652
 */
653
654
void DrawViewShell::ResetActualPage()
655
0
{
656
0
    if (!GetDoc())
657
0
        return;
658
659
0
    sal_uInt16 nCurrentPageId = maTabControl->GetCurPageId();
660
0
    sal_uInt16 nNewPageId;
661
0
    sal_uInt16 nCurrentPageNum = maTabControl->GetPagePos(nCurrentPageId);
662
0
    sal_uInt16 nPageCount   = (meEditMode == EditMode::Page)?GetDoc()->GetSdPageCount(mePageKind):GetDoc()->GetMasterSdPageCount(mePageKind);
663
664
0
    if (nCurrentPageNum >= nPageCount)
665
0
        nCurrentPageNum = nPageCount - 1;
666
667
0
    if (meEditMode == EditMode::Page)
668
0
    {
669
670
        // Update for TabControl
671
0
        maTabControl->Clear();
672
673
0
        SdPage* pPage = nullptr;
674
675
0
        for (sal_uInt16 i = 0; i < nPageCount; i++)
676
0
        {
677
0
            pPage = GetDoc()->GetSdPage(i, mePageKind);
678
0
            OUString aPageName = pPage->GetName();
679
0
            maTabControl->InsertPage(pPage->getPageId(), aPageName);
680
681
0
            if (nCurrentPageId == pPage->getPageId())
682
0
            {
683
0
                nCurrentPageNum = i;
684
0
                GetDoc()->SetSelected(pPage, true);
685
0
            }
686
0
            else
687
0
                GetDoc()->SetSelected(pPage, false);
688
0
        }
689
690
0
        nNewPageId = maTabControl->GetPageId(nCurrentPageNum);
691
0
        maTabControl->SetCurPageId(nNewPageId);
692
0
    }
693
0
    else // EditMode::MasterPage
694
0
    {
695
0
        maTabControl->Clear();
696
697
0
        sal_uInt16 nMasterPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind);
698
0
        for (sal_uInt16 i = 0; i < nMasterPageCnt; i++)
699
0
        {
700
0
            SdPage* pMaster = GetDoc()->GetMasterSdPage(i, mePageKind);
701
0
            OUString aLayoutName = pMaster->GetLayoutName();
702
0
            sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR);
703
0
            if (nPos != -1)
704
0
                aLayoutName = aLayoutName.copy(0, nPos);
705
0
            maTabControl->InsertPage(pMaster->getPageId(), aLayoutName);
706
707
0
            if (pMaster->getPageId() == nCurrentPageId)
708
0
                nCurrentPageNum = i;
709
0
        }
710
711
0
        nNewPageId = maTabControl->GetPageId(nCurrentPageNum);
712
0
        maTabControl->SetCurPageId(nNewPageId);
713
0
        SwitchPage(nCurrentPageNum);
714
0
    }
715
716
0
    bool bAllowChangeFocus = nNewPageId != nCurrentPageId;
717
0
    SfxBoolItem aI(SID_SWITCHPAGE, bAllowChangeFocus);
718
0
    GetViewFrame()->GetDispatcher()->ExecuteList(SID_SWITCHPAGE,
719
0
                SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
720
0
                { &aI });
721
0
}
722
723
/**
724
 * Apply "Verb" on OLE-object.
725
 */
726
ErrCode DrawViewShell::DoVerb(sal_Int32 nVerb)
727
0
{
728
0
    const SdrMarkList& rMarkList(mpDrawView->GetMarkedObjectList());
729
0
    if ( rMarkList.GetMarkCount() != 0 )
730
0
    {
731
0
        if (rMarkList.GetMarkCount() == 1)
732
0
        {
733
0
            SdrMark* pMark = rMarkList.GetMark(0);
734
0
            SdrObject* pObj = pMark->GetMarkedSdrObj();
735
736
0
            SdrInventor nInv        = pObj->GetObjInventor();
737
0
            SdrObjKind  nSdrObjKind = pObj->GetObjIdentifier();
738
739
0
            if (nInv == SdrInventor::Default && nSdrObjKind == SdrObjKind::OLE2)
740
0
            {
741
0
                ActivateObject( static_cast<SdrOle2Obj*>(pObj), nVerb);
742
0
            }
743
0
        }
744
0
    }
745
746
0
    return ERRCODE_NONE;
747
0
}
748
749
/**
750
 * Activate OLE-object
751
 */
752
bool DrawViewShell::ActivateObject(SdrOle2Obj* pObj, sal_Int32 nVerb)
753
0
{
754
0
    bool bActivated = false;
755
756
0
    if ( !GetDocSh()->IsUIActive() )
757
0
    {
758
0
        ToolBarManager::UpdateLock aLock (GetViewShellBase().GetToolBarManager());
759
760
0
        bActivated = ViewShell::ActivateObject(pObj, nVerb);
761
0
    }
762
763
0
    return bActivated;
764
0
}
765
766
/**
767
 * Mark the desired page as selected (1), deselected (0), toggle (2).
768
 * nPage refers to the page in question.
769
 */
770
bool DrawViewShell::SelectPage(sal_uInt16 nPage, sal_uInt16 nSelect)
771
0
{
772
0
    SdPage* pPage = GetDoc()->GetSdPage(nPage, PageKind::Standard);
773
0
    if (!pPage)
774
0
        return false;
775
776
    //page selector marks pages as selected in view
777
0
    sd::slidesorter::SlideSorterViewShell* pSlideSorterVS
778
0
        = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase());
779
780
0
    if (nSelect == 1 || (/*Toggle*/ nSelect > 1 && !pPage->IsSelected()))
781
0
    {
782
0
        GetDoc()->SetSelected(pPage, true); // Select.
783
0
        if (pSlideSorterVS)
784
0
            pSlideSorterVS->GetSlideSorter().GetController().GetPageSelector().SelectPage(nPage);
785
0
    }
786
0
    else
787
0
    {
788
0
        GetDoc()->SetSelected(pPage, false); // Deselect.
789
0
        if (pSlideSorterVS)
790
0
            pSlideSorterVS->GetSlideSorter().GetController().GetPageSelector().DeselectPage(nPage);
791
0
    }
792
793
0
    return true;
794
0
}
795
796
bool DrawViewShell::IsSelected(sal_uInt16 nPage)
797
0
{
798
0
    slidesorter::SlideSorterViewShell* pVShell
799
0
        = slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase());
800
0
    if (pVShell != nullptr)
801
0
        return pVShell->GetSlideSorter().GetController().GetPageSelector().IsPageSelected(nPage);
802
803
0
    return false;
804
0
}
805
806
namespace
807
{
808
void notifyLinkAnnotations(SfxViewShell* pViewShell, SdPage* pPage)
809
0
{
810
0
    if (!pViewShell || !pPage)
811
0
        return;
812
0
    ::tools::JsonWriter jsonWriter;
813
0
    jsonWriter.put("commandName", "PageLinks");
814
0
    {
815
0
        auto jsonState = jsonWriter.startNode("state");
816
0
        {
817
0
            auto jsonLinks = jsonWriter.startArray("links");
818
0
            for (const auto& link : pPage->getLinkAnnotations())
819
0
            {
820
0
                auto jsonLink = jsonWriter.startStruct();
821
0
                std::stringstream ss;
822
0
                ss << link.first;
823
0
                jsonWriter.put("rectangle", ss.str());
824
0
                jsonWriter.put("uri", link.second);
825
0
            }
826
0
        }
827
0
    }
828
0
    OString aPayload = jsonWriter.finishAndGetAsOString();
829
0
    pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
830
0
}
831
}
832
833
/**
834
 * Switch to desired page.
835
 * nSelectPage refers to the current EditMode
836
 * bAllowChangeFocus set to false when slide is inserted before current page
837
 *                   and we need to only update the current page number,
838
 *                   do not disturb editing in that case
839
 * bUpdateScrollbars set to false when the scrollbars are going to be updated by
840
 *                   some other mechanism. (e.g. if the page switch happened as
841
 *                   a result of a scroll)
842
 */
843
bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage, bool bAllowChangeFocus,
844
                               bool bUpdateScrollbars)
845
0
{
846
    /** Under some circumstances there are nested calls to SwitchPage() and
847
        may crash the application (activation of form controls when the
848
        shell of the edit view is not on top of the shell stack, see issue
849
        83888 for details.)  Therefore the nested calls are ignored (they
850
        would jump to the wrong page anyway.)
851
    */
852
853
0
    if (mbIsInSwitchPage)
854
0
        return false;
855
0
    mbIsInSwitchPage = true;
856
0
    comphelper::ScopeGuard aGuard(
857
0
            [this] () { this->mbIsInSwitchPage = false; } );
858
859
0
    if (GetActiveWindow()->IsInPaint())
860
0
    {
861
        // Switching the current page while a Paint is being executed is
862
        // dangerous.  So, post it for later execution and return.
863
0
        maAsynchronousSwitchPageCall.Post(
864
0
            [this, nSelectedPage] () { this->SwitchPage(nSelectedPage); } );
865
0
        return false;
866
0
    }
867
868
0
    bool bOK = false;
869
870
    // With the current implementation of FuSlideShow there is a problem
871
    // when it displays the show in a window: when the show is stopped it
872
    // returns at one point in time SDRPAGE_NOTFOUND as current page index.
873
    // Because FuSlideShow is currently being rewritten this bug is fixed
874
    // here.
875
    // This is not as bad a hack as it may look because making SwitchPage()
876
    // more robust with respect to invalid page numbers is a good thing
877
    // anyway.
878
0
    if (nSelectedPage == SDRPAGE_NOTFOUND)
879
0
    {
880
0
        nSelectedPage = 0;
881
0
    }
882
0
    else
883
0
    {
884
        // Make sure that the given page index points to an existing page.  Move
885
        // the index into the valid range if necessary.
886
0
        sal_uInt16 nPageCount = (meEditMode == EditMode::Page)
887
0
            ? GetDoc()->GetSdPageCount(mePageKind)
888
0
            : GetDoc()->GetMasterSdPageCount(mePageKind);
889
0
        if (nSelectedPage >= nPageCount)
890
0
            nSelectedPage = nPageCount-1;
891
0
    }
892
893
0
    if (IsSwitchPageAllowed())
894
0
    {
895
0
        ModifyGuard aGuard2( GetDoc() );
896
897
0
        bOK = true;
898
899
0
        if (mpActualPage)
900
0
        {
901
0
            SdPage* pNewPage = nullptr;
902
903
0
            if (meEditMode == EditMode::MasterPage)
904
0
            {
905
0
                if( GetDoc()->GetMasterSdPageCount(mePageKind) > nSelectedPage )
906
0
                    pNewPage = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind);
907
908
0
                if( pNewPage )
909
0
                {
910
0
                    SdrPageView* pPV = mpDrawView->GetSdrPageView();
911
0
                    OUString sPageText(pNewPage->GetLayoutName());
912
0
                    sal_Int32 nPos = sPageText.indexOf(SD_LT_SEPARATOR);
913
0
                    if (nPos != -1)
914
0
                        sPageText = sPageText.copy(0, nPos);
915
0
                    if (pPV
916
0
                        && pNewPage == dynamic_cast< SdPage* >( pPV->GetPage() )
917
0
                        && sPageText == maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)))
918
0
                    {
919
                        // this slide is already visible
920
0
                        return true;
921
0
                    }
922
0
                }
923
0
            }
924
0
            else
925
0
            {
926
0
                OSL_ASSERT(mpFrameView!=nullptr);
927
0
                mpFrameView->SetSelectedPage(nSelectedPage);
928
929
0
                if (GetDoc()->GetSdPageCount(mePageKind) > nSelectedPage)
930
0
                    pNewPage = GetDoc()->GetSdPage(nSelectedPage, mePageKind);
931
932
0
                if (mpActualPage == pNewPage)
933
0
                {
934
0
                    SdrPageView* pPV = mpDrawView->GetSdrPageView();
935
936
0
                    SdPage* pCurrentPage = pPV ? dynamic_cast<SdPage*>(pPV->GetPage()) : nullptr;
937
0
                    if (pCurrentPage
938
0
                        && pNewPage == pCurrentPage
939
0
                        && maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) == pNewPage->GetName())
940
0
                    {
941
                        // this slide is already visible
942
0
                        if (comphelper::LibreOfficeKit::isActive())
943
0
                            notifyLinkAnnotations(GetViewShell(), mpActualPage);
944
0
                        return true;
945
0
                    }
946
0
                }
947
0
            }
948
0
        }
949
950
0
        if (bAllowChangeFocus && !SfxLokHelper::isSettingView())
951
0
            mpDrawView->SdrEndTextEdit();
952
953
0
        mpActualPage = nullptr;
954
955
0
        if (meEditMode == EditMode::Page)
956
0
        {
957
0
            mpActualPage = GetDoc()->GetSdPage(nSelectedPage, mePageKind);
958
0
        }
959
0
        else
960
0
        {
961
0
            SdPage* pMaster = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind);
962
963
            // does the selected page fit to the masterpage?
964
0
            sal_uInt16 nPageCount = GetDoc()->GetSdPageCount(mePageKind);
965
0
            for (sal_uInt16 i = 0; i < nPageCount; i++)
966
0
            {
967
0
                SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind);
968
0
                if(pPage && pPage->IsSelected() && pMaster == &(pPage->TRG_GetMasterPage()))
969
0
                {
970
0
                    mpActualPage = pPage;
971
0
                    break;
972
0
                }
973
0
            }
974
975
0
            if (!mpActualPage)
976
0
            {
977
                // take the first page, that fits to the masterpage
978
0
                for (sal_uInt16 i = 0; i < nPageCount; i++)
979
0
                {
980
0
                    SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind);
981
0
                    if(pPage && pMaster == &(pPage->TRG_GetMasterPage()))
982
0
                    {
983
0
                        mpActualPage = pPage;
984
0
                        break;
985
0
                    }
986
0
                }
987
0
            }
988
0
        }
989
990
0
        for (sal_uInt16 i = 0; i < GetDoc()->GetSdPageCount(mePageKind); i++)
991
0
        {
992
            // deselect all pages
993
0
            GetDoc()->SetSelected( GetDoc()->GetSdPage(i, mePageKind), false);
994
0
        }
995
996
0
        if (!mpActualPage)
997
0
        {
998
            // as far as there is no mpActualPage, take the first
999
0
            mpActualPage = GetDoc()->GetSdPage(0, mePageKind);
1000
0
        }
1001
1002
        // also select this page (mpActualPage always points at a drawing page,
1003
        // never at a masterpage)
1004
0
        GetDoc()->SetSelected(mpActualPage, true);
1005
1006
0
        if (comphelper::LibreOfficeKit::isActive())
1007
0
        {
1008
            // notify LibreOfficeKit about changed page
1009
0
            OString aPayload = OString::number(nSelectedPage);
1010
0
            if (SfxViewShell* pViewShell = GetViewShell())
1011
0
            {
1012
0
                pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload);
1013
0
                notifyLinkAnnotations(pViewShell, mpActualPage);
1014
0
            }
1015
0
        }
1016
1017
0
        rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetDoc() ) );
1018
0
        if( !xSlideshow.is() || !xSlideshow->isRunning() || ( xSlideshow->getAnimationMode() != ANIMATIONMODE_SHOW ) )
1019
0
        {
1020
            // tighten VisArea, to possibly deactivate objects
1021
            // !!! only if we are not in presentation mode (#96279) !!!
1022
0
            OSL_ASSERT (GetViewShell()!=nullptr);
1023
0
            GetViewShell()->DisconnectAllClients();
1024
0
            VisAreaChanged(::tools::Rectangle(Point(), Size(1, 1)));
1025
0
        }
1026
1027
        // Try to prefetch all graphics for the active page. This will be done
1028
        // in threads to be more efficient than loading them on-demand one by one.
1029
0
        std::vector<Graphic*> graphics;
1030
0
        mpActualPage->getGraphicsForPrefetch(graphics);
1031
0
        if(graphics.size() > 1) // threading does not help with loading just one
1032
0
            GraphicFilter::GetGraphicFilter().MakeGraphicsAvailableThreaded(graphics);
1033
1034
0
        if (meEditMode == EditMode::Page)
1035
0
        {
1036
            /**********************************************************************
1037
            * PAGEMODE
1038
            **********************************************************************/
1039
1040
0
            SdrPageView* pPV = mpDrawView->GetSdrPageView();
1041
0
            SdPage* pCurrentPage = pPV ? dynamic_cast<SdPage*>(pPV->GetPage()) : nullptr;
1042
1043
0
            bool bChangeZoom = false;
1044
1045
0
            if (pCurrentPage)
1046
0
            {
1047
0
                Size aCurrentPageSize = pCurrentPage->GetSize();
1048
0
                const ::tools::Long nCurrentWidth = aCurrentPageSize.Width();
1049
0
                const ::tools::Long nCurrentHeight = aCurrentPageSize.Height();
1050
1051
0
                SdPage* pSelectedPage = GetDoc()->GetSdPage(nSelectedPage, mePageKind);
1052
0
                Size aNewPageSize = pSelectedPage->GetSize();
1053
0
                const ::tools::Long nNewWidth = aNewPageSize.Width();
1054
0
                const ::tools::Long nNewHeight = aNewPageSize.Height();
1055
1056
0
                bChangeZoom = pCurrentPage->IsCanvasPage() || pSelectedPage->IsCanvasPage();
1057
1058
0
                if ((nCurrentWidth != nNewWidth || nCurrentHeight != nNewHeight) && bAllowChangeFocus)
1059
0
                {
1060
0
                    Point aPageOrg(nNewWidth, nNewHeight / 2);
1061
0
                    Size aViewSize(nNewWidth * 3, nNewHeight * 2);
1062
0
                    Point aVisAreaPos;
1063
1064
0
                    GetDoc()->SetMaxObjSize(aViewSize);
1065
1066
0
                    InitWindows(aPageOrg, aViewSize, Point(-1, -1), true);
1067
1068
0
                    if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
1069
0
                    {
1070
0
                        aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
1071
0
                    }
1072
0
                    if (mpDrawView)
1073
0
                    {
1074
0
                        mpDrawView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aViewSize));
1075
0
                    }
1076
                    // pSelectedPage->SetBackgroundFullSize(true);
1077
1078
0
                    UpdateScrollBars();
1079
1080
0
                    if (comphelper::LibreOfficeKit::isActive())
1081
0
                    {
1082
0
                        OString aPayload = ".uno:CurrentPageResize"_ostr;
1083
0
                        SfxViewShell* pViewShell = GetViewShell();
1084
0
                        pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
1085
0
                    }
1086
0
                }
1087
0
            }
1088
0
            GetDoc()->SetSelected(mpActualPage, true);
1089
1090
0
            SdrPageView* pPageView = mpDrawView->GetSdrPageView();
1091
1092
0
            if (pPageView)
1093
0
            {
1094
0
                mpFrameView->SetVisibleLayers( pPageView->GetVisibleLayers() );
1095
0
                mpFrameView->SetPrintableLayers( pPageView->GetPrintableLayers() );
1096
0
                mpFrameView->SetLockedLayers( pPageView->GetLockedLayers() );
1097
1098
0
                if (mePageKind == PageKind::Notes)
1099
0
                {
1100
0
                    mpFrameView->SetNotesHelpLines( pPageView->GetHelpLines() );
1101
0
                }
1102
0
                else if (mePageKind == PageKind::Handout)
1103
0
                {
1104
0
                    mpFrameView->SetHandoutHelpLines( pPageView->GetHelpLines() );
1105
0
                }
1106
0
                else
1107
0
                {
1108
0
                    mpFrameView->SetStandardHelpLines( pPageView->GetHelpLines() );
1109
0
                }
1110
0
            }
1111
1112
0
            mpDrawView->HideSdrPage();
1113
0
            maTabControl->SetCurPageId(maTabControl->GetPageId(nSelectedPage));
1114
0
            mpDrawView->ShowSdrPage(mpActualPage);
1115
0
            GetViewShellBase().GetDrawController()->FireSwitchCurrentPage(mpActualPage);
1116
1117
0
            if (comphelper::LibreOfficeKit::isActive())
1118
0
            {
1119
0
                if (bChangeZoom && bAllowChangeFocus)
1120
0
                {
1121
0
                    sal_uInt16 nZoom = GetPageZoom();
1122
0
                    if (nZoom != 0)
1123
0
                    {
1124
0
                        OString aPayload = ".uno:PageZoomChange="_ostr + OString::number(nZoom);
1125
0
                        if (SfxViewShell* pViewShell = GetViewShell())
1126
0
                            pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
1127
0
                    }
1128
0
                }
1129
0
                if (GetDoc()->HasCanvasPage() && getCurrentPage()->IsCanvasPage() && bAllowChangeFocus)
1130
0
                {
1131
0
                    bool bShowCenter = maCanvasPageVisArea.IsEmpty();
1132
0
                    ::tools::JsonWriter aJsonWriter;
1133
0
                    if (bShowCenter)
1134
0
                        aJsonWriter.put("commandName", "CanvasPageCenter");
1135
0
                    else
1136
0
                        aJsonWriter.put("commandName", "CanvasPageVisArea");
1137
0
                    {
1138
0
                        auto jsonState = aJsonWriter.startNode("state");
1139
0
                        aJsonWriter.put("x", maCanvasPageVisArea.Left());
1140
0
                        aJsonWriter.put("y", maCanvasPageVisArea.Top());
1141
0
                        aJsonWriter.put("width", maCanvasPageVisArea.GetWidth());
1142
0
                        aJsonWriter.put("height", maCanvasPageVisArea.GetHeight());
1143
0
                    }
1144
0
                    OString aPayload = aJsonWriter.finishAndGetAsOString();
1145
0
                    if (SfxViewShell* pViewShell = GetViewShell())
1146
0
                    {
1147
0
                        pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
1148
0
                    }
1149
0
                }
1150
0
            }
1151
0
            else
1152
0
            {
1153
0
                if (bChangeZoom && bAllowChangeFocus)
1154
0
                {
1155
0
                    const sal_uInt16 nZoom = GetPageZoom();
1156
0
                    if (nZoom)
1157
0
                    {
1158
0
                        const SvxZoomItem aZoomItem(SvxZoomType::PERCENT, nZoom, SID_ATTR_ZOOM);
1159
0
                        GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::SLOT, {&aZoomItem});
1160
0
                    }
1161
0
                }
1162
0
            }
1163
1164
0
            SdrPageView* pNewPageView = mpDrawView->GetSdrPageView();
1165
1166
0
            if (pNewPageView)
1167
0
            {
1168
0
                pNewPageView->SetVisibleLayers( mpFrameView->GetVisibleLayers() );
1169
0
                pNewPageView->SetPrintableLayers( mpFrameView->GetPrintableLayers() );
1170
0
                pNewPageView->SetLockedLayers( mpFrameView->GetLockedLayers() );
1171
1172
0
                if (mePageKind == PageKind::Notes)
1173
0
                {
1174
0
                    pNewPageView->SetHelpLines( mpFrameView->GetNotesHelpLines() );
1175
0
                }
1176
0
                else if (mePageKind == PageKind::Handout)
1177
0
                {
1178
0
                    pNewPageView->SetHelpLines( mpFrameView->GetHandoutHelpLines() );
1179
0
                }
1180
0
                else
1181
0
                {
1182
0
                    pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() );
1183
0
                }
1184
0
            }
1185
1186
0
            OUString aPageName = mpActualPage->GetName();
1187
1188
0
            if (maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) != aPageName)
1189
0
            {
1190
0
                maTabControl->SetPageText(maTabControl->GetPageId(nSelectedPage), aPageName);
1191
0
            }
1192
0
        }
1193
0
        else
1194
0
        {
1195
            /**********************************************************************
1196
            * MASTERPAGE
1197
            **********************************************************************/
1198
0
            SdrPageView* pPageView = mpDrawView->GetSdrPageView();
1199
1200
0
            if (pPageView)
1201
0
            {
1202
0
                mpFrameView->SetVisibleLayers( pPageView->GetVisibleLayers() );
1203
0
                mpFrameView->SetPrintableLayers( pPageView->GetPrintableLayers() );
1204
0
                mpFrameView->SetLockedLayers( pPageView->GetLockedLayers() );
1205
1206
0
                if (mePageKind == PageKind::Notes)
1207
0
                {
1208
0
                    mpFrameView->SetNotesHelpLines( pPageView->GetHelpLines() );
1209
0
                }
1210
0
                else if (mePageKind == PageKind::Handout)
1211
0
                {
1212
0
                    mpFrameView->SetHandoutHelpLines( pPageView->GetHelpLines() );
1213
0
                }
1214
0
                else
1215
0
                {
1216
0
                    mpFrameView->SetStandardHelpLines( pPageView->GetHelpLines() );
1217
0
                }
1218
0
            }
1219
1220
0
            mpDrawView->HideSdrPage();
1221
0
            maTabControl->SetCurPageId(maTabControl->GetPageId(nSelectedPage));
1222
1223
0
            SdPage* pMaster = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind);
1224
1225
0
            if( !pMaster )              // if this page should not exist
1226
0
                pMaster = GetDoc()->GetMasterSdPage(0, mePageKind);
1227
1228
0
            sal_uInt16 nNum = pMaster->GetPageNum();
1229
0
            mpDrawView->ShowSdrPage(mpDrawView->GetModel().GetMasterPage(nNum));
1230
1231
0
            GetViewShellBase().GetDrawController()->FireSwitchCurrentPage(pMaster);
1232
1233
0
            SdrPageView* pNewPageView = mpDrawView->GetSdrPageView();
1234
1235
0
            if (pNewPageView)
1236
0
            {
1237
0
                pNewPageView->SetVisibleLayers( mpFrameView->GetVisibleLayers() );
1238
0
                pNewPageView->SetPrintableLayers( mpFrameView->GetPrintableLayers() );
1239
0
                pNewPageView->SetLockedLayers( mpFrameView->GetLockedLayers() );
1240
1241
0
                if (mePageKind == PageKind::Notes)
1242
0
                {
1243
0
                    pNewPageView->SetHelpLines( mpFrameView->GetNotesHelpLines() );
1244
0
                }
1245
0
                else if (mePageKind == PageKind::Handout)
1246
0
                {
1247
0
                    pNewPageView->SetHelpLines( mpFrameView->GetHandoutHelpLines() );
1248
0
                }
1249
0
                else
1250
0
                {
1251
0
                    pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() );
1252
0
                }
1253
0
            }
1254
1255
0
            OUString aLayoutName(pMaster->GetLayoutName());
1256
0
            sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR);
1257
0
            if (nPos != -1)
1258
0
                aLayoutName = aLayoutName.copy(0, nPos);
1259
1260
0
            if (maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) != aLayoutName)
1261
0
            {
1262
0
                maTabControl->SetPageText(maTabControl->GetPageId(nSelectedPage), aLayoutName);
1263
0
            }
1264
1265
0
            if( mePageKind == PageKind::Handout )
1266
0
            {
1267
                // set pages for all available handout presentation objects
1268
0
                sd::ShapeList& rShapeList = pMaster->GetPresentationShapeList();
1269
0
                SdrObject* pObj = nullptr;
1270
0
                rShapeList.seekShape(0);
1271
1272
0
                while( (pObj = rShapeList.getNextShape()) )
1273
0
                {
1274
0
                    if( pMaster->GetPresObjKind(pObj) == PresObjKind::Handout )
1275
0
                    {
1276
                        // #i105146# We want no content to be displayed for PageKind::Handout,
1277
                        // so just never set a page as content
1278
0
                        static_cast<SdrPageObj*>(pObj)->SetReferencedPage(nullptr);
1279
0
                    }
1280
0
                }
1281
0
            }
1282
0
        }
1283
1284
0
        Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
1285
0
        ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
1286
0
        VisAreaChanged(aVisAreaWin);
1287
0
        mpDrawView->VisAreaChanged(GetActiveWindow()->GetOutDev());
1288
1289
        // so navigator (and effect window) notice that
1290
0
        SfxBindings& rBindings = GetViewFrame()->GetBindings();
1291
0
        rBindings.Invalidate(SID_NAVIGATOR_STATE, true);
1292
0
        rBindings.Invalidate(SID_NAVIGATOR_PAGENAME, true);
1293
0
        rBindings.Invalidate(SID_STATUS_PAGE, true);
1294
0
        rBindings.Invalidate(SID_DELETE_MASTER_PAGE, true);
1295
0
        rBindings.Invalidate(SID_DELETE_PAGE, true);
1296
0
        rBindings.Invalidate(SID_ASSIGN_LAYOUT, true);
1297
0
        rBindings.Invalidate(SID_INSERTPAGE, true);
1298
0
        UpdatePreview( mpActualPage );
1299
1300
0
        mpDrawView->AdjustMarkHdl();
1301
1302
0
        if(bUpdateScrollbars)
1303
0
            UpdateScrollBars();
1304
0
    }
1305
1306
0
    return bOK;
1307
0
}
1308
1309
/**
1310
 * Check if page change is allowed
1311
 */
1312
1313
bool DrawViewShell::IsSwitchPageAllowed() const
1314
0
{
1315
0
    bool bOK = true;
1316
1317
0
    FmFormShell* pFormShell = GetViewShellBase().GetFormShellManager()->GetFormShell();
1318
0
    if (pFormShell != nullptr && !pFormShell->PrepareClose(false))
1319
0
        bOK = false;
1320
1321
0
    return bOK;
1322
0
}
1323
1324
/**
1325
 * Select new refreshed page, in case of a page order change (eg. by undo)
1326
 */
1327
1328
void DrawViewShell::ResetActualLayer()
1329
0
{
1330
0
    LayerTabBar* pLayerBar = GetLayerTabControl();
1331
0
    if (pLayerBar == nullptr)
1332
0
        return;
1333
1334
    // remember old tab count and current tab id
1335
    // this is needed when one layer is renamed to
1336
    // restore current tab
1337
0
    sal_uInt16 nOldLayerCnt = pLayerBar->GetPageCount(); // actually it is tab count
1338
0
    sal_uInt16 nOldLayerPos = pLayerBar->GetCurPageId(); // actually it is a tab nId
1339
1340
    /**
1341
     * Update for LayerTab
1342
     */
1343
0
    pLayerBar->Clear();
1344
1345
0
    OUString aName; // a real layer name
1346
0
    OUString aActiveLayer = mpDrawView->GetActiveLayer();
1347
0
    sal_uInt16 nActiveLayerPos = SDRLAYERPOS_NOTFOUND;
1348
0
    SdrLayerAdmin& rLayerAdmin = GetDoc()->GetLayerAdmin();
1349
0
    sal_uInt16 nLayerCnt = rLayerAdmin.GetLayerCount();
1350
1351
0
    for ( sal_uInt16 nLayerPos = 0; nLayerPos < nLayerCnt; nLayerPos++ )
1352
0
    {
1353
0
        aName = rLayerAdmin.GetLayer(nLayerPos)->GetName();
1354
1355
0
        if ( aName == aActiveLayer )
1356
0
        {
1357
0
            nActiveLayerPos = nLayerPos;
1358
0
        }
1359
1360
0
        if ( aName != sUNO_LayerName_background ) // layer "background" has never a tab
1361
0
        {
1362
0
            if (meEditMode == EditMode::MasterPage)
1363
0
            {
1364
                // don't show page layer onto the masterpage
1365
0
                if (aName != sUNO_LayerName_layout   &&
1366
0
                    aName != sUNO_LayerName_controls &&
1367
0
                    aName != sUNO_LayerName_measurelines)
1368
0
                {
1369
0
                    TabBarPageBits nBits = TabBarPageBits::NONE;
1370
0
                    SdrPageView* pPV = mpDrawView->GetSdrPageView();
1371
0
                    if (pPV)
1372
0
                    {
1373
0
                        if (!pPV->IsLayerVisible(aName))
1374
0
                        {
1375
0
                            nBits |= TabBarPageBits::Blue;
1376
0
                        }
1377
0
                        if (pPV->IsLayerLocked(aName))
1378
0
                        {
1379
0
                            nBits |= TabBarPageBits::Italic;
1380
0
                        }
1381
0
                        if (!pPV->IsLayerPrintable(aName))
1382
0
                        {
1383
0
                            nBits |= TabBarPageBits::Underline;
1384
0
                        }
1385
0
                    }
1386
1387
0
                    pLayerBar->InsertPage(nLayerPos+1, aName, nBits); // why +1? It is a nId, not a position. Position is APPEND.
1388
0
                }
1389
0
            }
1390
0
            else
1391
0
            {
1392
                // don't show masterpage layer onto the page
1393
0
                if (aName != sUNO_LayerName_background_objects)
1394
0
                {
1395
0
                    TabBarPageBits nBits = TabBarPageBits::NONE;
1396
0
                    if (!mpDrawView->GetSdrPageView()->IsLayerVisible(aName))
1397
0
                    {
1398
0
                        nBits = TabBarPageBits::Blue;
1399
0
                    }
1400
0
                    if (mpDrawView->GetSdrPageView()->IsLayerLocked(aName))
1401
0
                    {
1402
0
                        nBits |= TabBarPageBits::Italic;
1403
0
                    }
1404
0
                    if (!mpDrawView->GetSdrPageView()->IsLayerPrintable(aName))
1405
0
                    {
1406
0
                        nBits |= TabBarPageBits::Underline;
1407
0
                    }
1408
1409
0
                    pLayerBar->InsertPage(nLayerPos+1, aName, nBits);// why +1?
1410
0
                }
1411
0
            }
1412
0
        }
1413
0
    }
1414
1415
0
    if ( nActiveLayerPos == SDRLAYERPOS_NOTFOUND )
1416
0
    {
1417
0
        if( nOldLayerCnt == pLayerBar->GetPageCount() )
1418
0
        {
1419
0
            nActiveLayerPos = nOldLayerPos - 1;
1420
0
        }
1421
0
        else
1422
0
        {
1423
0
            nActiveLayerPos = ( meEditMode == EditMode::MasterPage ) ? 2 : 0;
1424
0
        }
1425
1426
0
        mpDrawView->SetActiveLayer( pLayerBar->GetLayerName(nActiveLayerPos + 1) );// why +1?
1427
0
    }
1428
1429
0
    pLayerBar->SetCurPageId(nActiveLayerPos + 1);
1430
0
    GetViewFrame()->GetBindings().Invalidate( SID_TOGGLELAYERVISIBILITY );
1431
0
    GetViewFrame()->GetBindings().Invalidate( SID_MODIFYLAYER );
1432
0
    GetViewFrame()->GetBindings().Invalidate( SID_DELETE_LAYER );
1433
0
}
1434
1435
/**
1436
 * AcceptDrop
1437
 */
1438
1439
sal_Int8 DrawViewShell::AcceptDrop (
1440
    const AcceptDropEvent& rEvt,
1441
    DropTargetHelper& rTargetHelper,
1442
    ::sd::Window* /*pTargetWindow*/,
1443
    sal_uInt16 /*nPage*/,
1444
    SdrLayerID nLayer )
1445
0
{
1446
0
    if( SlideShow::IsRunning( GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow( GetViewShellBase() ) ) // IASS
1447
0
        return DND_ACTION_NONE;
1448
1449
0
    return mpDrawView->AcceptDrop( rEvt, rTargetHelper, nLayer );
1450
0
}
1451
1452
/**
1453
 * ExecuteDrop
1454
 */
1455
1456
sal_Int8 DrawViewShell::ExecuteDrop (
1457
    const ExecuteDropEvent& rEvt,
1458
    DropTargetHelper& /*rTargetHelper*/,
1459
    ::sd::Window* pTargetWindow,
1460
    sal_uInt16 nPage,
1461
    SdrLayerID nLayer)
1462
0
{
1463
0
    if( nPage != SDRPAGE_NOTFOUND )
1464
0
        nPage = GetDoc()->GetSdPage( nPage, mePageKind )->GetPageNum();
1465
1466
0
    if( SlideShow::IsRunning( GetViewShellBase() ) && !SlideShow::IsInteractiveSlideshow( GetViewShellBase() )) // IASS
1467
0
        return DND_ACTION_NONE;
1468
1469
0
    Broadcast(ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START));
1470
0
    sal_Int8 nResult (mpDrawView->ExecuteDrop( rEvt, pTargetWindow, nPage, nLayer ));
1471
0
    Broadcast(ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END));
1472
1473
0
    return nResult;
1474
0
}
1475
1476
} // end of namespace sd
1477
1478
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */