Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/view/viewshe2.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <com/sun/star/embed/EmbedVerbs.hpp>
21
#include <com/sun/star/embed/XEmbeddedObject.hpp>
22
23
#include <ViewShell.hxx>
24
#include <ViewShellHint.hxx>
25
26
#include <ViewShellImplementation.hxx>
27
#include <FactoryIds.hxx>
28
29
#include <svx/svxids.hrc>
30
#include <svx/svdpagv.hxx>
31
#include <sfx2/dispatch.hxx>
32
#include <svx/ruler.hxx>
33
#include <editeng/outliner.hxx>
34
#include <svtools/ehdl.hxx>
35
#include <svx/svdoole2.hxx>
36
#include <svtools/sfxecode.hxx>
37
#include <unotools/moduleoptions.hxx>
38
#include <comphelper/classids.hxx>
39
#include <osl/diagnose.h>
40
41
#include <strings.hrc>
42
#include <app.hrc>
43
#include <unokywds.hxx>
44
45
#include <sdundogr.hxx>
46
#include <FrameView.hxx>
47
#include <sdresid.hxx>
48
#include <drawdoc.hxx>
49
#include <View.hxx>
50
#include <fupoor.hxx>
51
#include <Client.hxx>
52
#include <DrawDocShell.hxx>
53
#include <sdpage.hxx>
54
#include <DrawViewShell.hxx>
55
#include <ViewShellBase.hxx>
56
57
#include <Window.hxx>
58
59
#include <framework/windowstatehelper.hxx>
60
#include <sfx2/viewfrm.hxx>
61
#include <svtools/soerr.hxx>
62
#include <svx/charthelper.hxx>
63
#include <comphelper/lok.hxx>
64
65
using namespace com::sun::star;
66
67
namespace
68
{
69
inline double getViewToScrollScalarForPanAcrossPages(sal_uInt16 nTotalPages, double fVisibleHeight,
70
                                                     ::tools::Long nScrollRangeMax)
71
0
{
72
    // fTotalScrollableRange is (1 - fVisibleHeight) for all of the
73
    // pages except the last one. Because switch to the next page
74
    // happens when the view reaches bottom.
75
0
    double fTotalScrollableRange = (nTotalPages - 1) * (1 - fVisibleHeight) + 1.0;
76
0
    return nScrollRangeMax / fTotalScrollableRange;
77
0
}
78
}
79
80
namespace sd {
81
82
/**
83
 * adjust Thumbpos and VisibleSize
84
 */
85
void ViewShell::UpdateScrollBars()
86
0
{
87
0
    if (mpHorizontalScrollBar)
88
0
    {
89
0
        ::tools::Long nW = static_cast<::tools::Long>(std::min(1.0, mpContentWindow->GetVisibleWidth()) * 32000);
90
0
        ::tools::Long nX = static_cast<::tools::Long>(mpContentWindow->GetVisibleX() * 32000);
91
0
        mpHorizontalScrollBar->SetVisibleSize(nW);
92
0
        mpHorizontalScrollBar->SetThumbPos(nX);
93
0
        nW = 32000 - nW;
94
0
        ::tools::Long nLine = static_cast<::tools::Long>(mpContentWindow->GetScrlLineWidth() * nW);
95
0
        ::tools::Long nPage = static_cast<::tools::Long>(mpContentWindow->GetScrlPageWidth() * nW);
96
0
        mpHorizontalScrollBar->SetLineSize(nLine);
97
0
        mpHorizontalScrollBar->SetPageSize(nPage);
98
0
    }
99
100
0
    if (mpVerticalScrollBar)
101
0
    {
102
0
        if (CanPanAcrossPages())
103
0
        {
104
0
            SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
105
0
            sal_uInt16 nCurPage = (pPage->GetPageNum() - 1) / 2;
106
0
            sal_uInt16 nTotalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
107
108
            // nRangeMax is max int, and not ::tools::Long since the underlying
109
            // implementation weld::Scrollbar uses int
110
0
            ::tools::Long nRangeMax = std::numeric_limits<int>::max();
111
0
            double fVisibleHeight = std::min(mpContentWindow->GetVisibleHeight(), 1.0);
112
0
            double fMappingFactor
113
0
                = getViewToScrollScalarForPanAcrossPages(nTotalPages, fVisibleHeight, nRangeMax);
114
0
            double fVisibleY = std::max(0.0, mpContentWindow->GetVisibleY());
115
0
            double fCurrentThumbPos = nCurPage * (1 - fVisibleHeight) + fVisibleY;
116
0
            double fScrollLineHeight
117
0
                = mpContentWindow->GetScrlLineHeight() * (1.0 - fVisibleHeight);
118
0
            double fScrollPageHeight
119
0
                = mpContentWindow->GetScrlPageHeight() * (1.0 - fVisibleHeight);
120
121
0
            mpVerticalScrollBar->SetRange(Range(0, nRangeMax));
122
0
            mpVerticalScrollBar->SetVisibleSize(fVisibleHeight * fMappingFactor);
123
0
            mpVerticalScrollBar->SetThumbPos(fCurrentThumbPos * fMappingFactor);
124
0
            mpVerticalScrollBar->SetLineSize(fScrollLineHeight * fMappingFactor);
125
0
            mpVerticalScrollBar->SetPageSize(fScrollPageHeight * fMappingFactor);
126
0
        }
127
0
        else if (IsPageFlipMode()) // ie in zoom mode where no panning
128
0
        {
129
0
            SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
130
0
            sal_uInt16 nCurPage = (pPage->GetPageNum() - 1) / 2;
131
0
            sal_uInt16 nTotalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
132
0
            mpVerticalScrollBar->SetRange(Range(0,256*nTotalPages));
133
0
            mpVerticalScrollBar->SetVisibleSize(256);
134
0
            mpVerticalScrollBar->SetThumbPos(256*nCurPage);
135
0
            mpVerticalScrollBar->SetLineSize(256);
136
0
            mpVerticalScrollBar->SetPageSize(256);
137
0
        }
138
0
        else // single page pan mode
139
0
        {
140
0
            ::tools::Long nH = static_cast<::tools::Long>(std::min(1.0, mpContentWindow->GetVisibleHeight()) * 32000);
141
0
            ::tools::Long nY = static_cast<::tools::Long>(mpContentWindow->GetVisibleY() * 32000);
142
143
0
            mpVerticalScrollBar->SetRange(Range(0,32000));
144
0
            mpVerticalScrollBar->SetVisibleSize(nH);
145
0
            mpVerticalScrollBar->SetThumbPos(nY);
146
0
            nH = 32000 - nH;
147
0
            ::tools::Long nLine = static_cast<::tools::Long>(mpContentWindow->GetScrlLineHeight() * nH);
148
0
            ::tools::Long nPage = static_cast<::tools::Long>(mpContentWindow->GetScrlPageHeight() * nH);
149
0
            mpVerticalScrollBar->SetLineSize(nLine);
150
0
            mpVerticalScrollBar->SetPageSize(nPage);
151
0
        }
152
0
    }
153
154
0
    if (mbHasRulers)
155
0
    {
156
0
        UpdateHRuler();
157
0
        UpdateVRuler();
158
0
    }
159
160
0
}
161
/**
162
 * Handling for horizontal Scrollbars
163
 */
164
IMPL_LINK_NOARG(ViewShell, HScrollHdl, weld::Scrollbar&, void)
165
0
{
166
0
    VirtHScrollHdl(mpHorizontalScrollBar);
167
0
}
168
169
/**
170
 * virtual scroll handler for horizontal Scrollbars
171
 */
172
void ViewShell::VirtHScrollHdl(ScrollAdaptor* pHScroll)
173
0
{
174
0
    double fX = static_cast<double>(pHScroll->GetThumbPos()) / pHScroll->GetRange().Len();
175
176
    // scroll all windows of the column
177
0
    ::sd::View* pView = GetView();
178
0
    OutlinerView* pOLV = nullptr;
179
180
0
    if (pView)
181
0
        pOLV = pView->GetTextEditOutlinerView();
182
183
0
    if (pOLV)
184
0
        pOLV->HideCursor();
185
186
0
    mpContentWindow->SetVisibleXY(fX, -1);
187
188
0
    ::tools::Rectangle aVisArea = GetDocSh()->GetVisArea(ASPECT_CONTENT);
189
0
    Point aVisAreaPos = GetActiveWindow()->PixelToLogic( Point(0,0) );
190
0
    aVisArea.SetPos(aVisAreaPos);
191
0
    GetDocSh()->SetVisArea(aVisArea);
192
193
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
194
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
195
0
    VisAreaChanged(aVisAreaWin);
196
197
0
    if (pView)
198
0
    {
199
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
200
0
    }
201
202
0
    if (pOLV)
203
0
        pOLV->ShowCursor();
204
205
0
    if (mbHasRulers)
206
0
        UpdateHRuler();
207
0
}
208
209
/**
210
 * handling for vertical Scrollbars
211
 */
212
IMPL_LINK_NOARG(ViewShell, VScrollHdl, weld::Scrollbar&, void)
213
0
{
214
0
    VirtVScrollHdl(mpVerticalScrollBar);
215
0
}
216
217
/**
218
 * handling for vertical Scrollbars
219
 */
220
void ViewShell::VirtVScrollHdl(ScrollAdaptor* pVScroll)
221
0
{
222
0
    auto doScrollView = [&](double fY)
223
0
    {
224
0
        ::sd::View* pView = GetView();
225
0
        OutlinerView* pOLV = nullptr;
226
227
0
        if (pView)
228
0
            pOLV = pView->GetTextEditOutlinerView();
229
230
0
        if (pOLV)
231
0
            pOLV->HideCursor();
232
233
0
        mpContentWindow->SetVisibleXY(-1, fY);
234
235
0
        ::tools::Rectangle aVisArea = GetDocSh()->GetVisArea(ASPECT_CONTENT);
236
0
        Point aVisAreaPos = GetActiveWindow()->PixelToLogic( Point(0,0) );
237
0
        aVisArea.SetPos(aVisAreaPos);
238
0
        GetDocSh()->SetVisArea(aVisArea);
239
240
0
        Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
241
0
        ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
242
0
        VisAreaChanged(aVisAreaWin);
243
244
0
        if (pView)
245
0
        {
246
0
            pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
247
0
        }
248
249
0
        if (pOLV)
250
0
            pOLV->ShowCursor();
251
252
0
        if (mbHasRulers)
253
0
            UpdateVRuler();
254
0
    };
255
256
0
    if (CanPanAcrossPages())
257
0
    {
258
0
        SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
259
0
        auto nCurPage = (pPage->GetPageNum() - 1) >> 1;
260
0
        sal_uInt16 nTotalPages = GetDoc()->GetSdPageCount(pPage->GetPageKind());
261
262
0
        double fVisibleHeight = mpContentWindow->GetVisibleHeight();
263
0
        double fMappingFactor = getViewToScrollScalarForPanAcrossPages(nTotalPages, fVisibleHeight,
264
0
                                                                       pVScroll->GetRange().Max());
265
266
0
        double fScrollableDistancePerPage = 1 - std::min(fVisibleHeight, 1.0);
267
268
0
        sal_uInt16 nNewPage
269
0
            = std::min((pVScroll->GetThumbPos() / fMappingFactor) / fScrollableDistancePerPage,
270
0
                       static_cast<double>(nTotalPages - 1));
271
272
0
        if (nCurPage != nNewPage)
273
0
            static_cast<DrawViewShell*>(this)->SwitchPage(nNewPage, true, false);
274
275
0
        double fNewPageStart = nNewPage * fScrollableDistancePerPage;
276
0
        double fY = (pVScroll->GetThumbPos() / fMappingFactor) - fNewPageStart;
277
278
0
        doScrollView(fY);
279
0
    }
280
0
    else if (IsPageFlipMode())
281
0
    {
282
0
        SdPage* pPage = static_cast<DrawViewShell*>(this)->GetActualPage();
283
0
        auto nCurPage = (pPage->GetPageNum() - 1) >> 1;
284
0
        sal_uInt16 nNewPage = static_cast<sal_uInt16>(pVScroll->GetThumbPos())/256;
285
0
        if( nCurPage != nNewPage )
286
0
            static_cast<DrawViewShell*>(this)->SwitchPage(nNewPage);
287
0
    }
288
0
    else // single page panning mode
289
0
    {
290
0
        double fY = static_cast<double>(pVScroll->GetThumbPos()) / pVScroll->GetRange().Len();
291
0
        doScrollView(fY);
292
0
    }
293
0
}
294
295
VclPtr<SvxRuler> ViewShell::CreateHRuler(::sd::Window* )
296
0
{
297
0
    return nullptr;
298
0
}
299
300
VclPtr<SvxRuler> ViewShell::CreateVRuler(::sd::Window* )
301
0
{
302
0
    return nullptr;
303
0
}
304
305
void ViewShell::UpdateHRuler()
306
0
{
307
0
}
308
309
void ViewShell::UpdateVRuler()
310
0
{
311
0
}
312
313
/**
314
 * Scroll a specific number of lines. Is used in the automatic scrolling
315
 * (character/drag).
316
 */
317
void ViewShell::ScrollLines(::tools::Long nLinesX, ::tools::Long nLinesY)
318
0
{
319
0
    if ( nLinesX )
320
0
    {
321
0
        nLinesX *= mpHorizontalScrollBar->GetLineSize();
322
0
    }
323
0
    if ( nLinesY )
324
0
    {
325
0
        nLinesY *= mpVerticalScrollBar->GetLineSize();
326
0
    }
327
328
0
    Scroll(nLinesX, nLinesY);
329
0
}
330
331
void ViewShell::Scroll(::tools::Long nScrollX, ::tools::Long nScrollY)
332
0
{
333
0
    if (nScrollX)
334
0
    {
335
0
        ::tools::Long nNewThumb = mpHorizontalScrollBar->GetThumbPos() + nScrollX;
336
0
        mpHorizontalScrollBar->SetThumbPos(nNewThumb);
337
0
    }
338
0
    if (nScrollY)
339
0
    {
340
0
        ::tools::Long nNewThumb = mpVerticalScrollBar->GetThumbPos() + nScrollY;
341
0
        mpVerticalScrollBar->SetThumbPos(nNewThumb);
342
0
    }
343
0
    double  fX = static_cast<double>(mpHorizontalScrollBar->GetThumbPos()) /
344
0
                            mpHorizontalScrollBar->GetRange().Len();
345
0
    double  fY = static_cast<double>(mpVerticalScrollBar->GetThumbPos()) /
346
0
                            mpVerticalScrollBar->GetRange().Len();
347
348
0
    GetActiveWindow()->SetVisibleXY(fX, fY);
349
350
0
    ::tools::Rectangle aVisArea = GetDocSh()->GetVisArea(ASPECT_CONTENT);
351
0
    Point aVisAreaPos = GetActiveWindow()->PixelToLogic( Point(0,0) );
352
0
    aVisArea.SetPos(aVisAreaPos);
353
0
    GetDocSh()->SetVisArea(aVisArea);
354
355
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
356
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
357
0
    VisAreaChanged(aVisAreaWin);
358
359
0
    ::sd::View* pView = GetView();
360
0
    if (pView)
361
0
    {
362
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
363
0
    }
364
365
0
    if (mbHasRulers)
366
0
    {
367
0
        UpdateHRuler();
368
0
        UpdateVRuler();
369
0
    }
370
0
}
371
372
/**
373
 * Set zoom factor for all split windows.
374
 */
375
void ViewShell::SetZoom(::tools::Long nZoom)
376
0
{
377
0
    Fraction aUIScale(nZoom, 100);
378
0
    aUIScale *= GetDoc()->GetUIScale();
379
380
0
    if (mpHorizontalRuler)
381
0
        mpHorizontalRuler->SetZoom(aUIScale);
382
383
0
    if (mpVerticalRuler)
384
0
        mpVerticalRuler->SetZoom(aUIScale);
385
386
0
    if (mpContentWindow)
387
0
    {
388
0
        mpContentWindow->SetZoomIntegral(nZoom);
389
390
        // #i74769# Here is a 2nd way (besides Window::Scroll) to set the visible prt
391
        // of the window. It needs - like Scroll(ScrollFlags::Children) does - also to move
392
        // the child windows. I am trying InvalidateFlags::Children here which makes things better,
393
        // but does not solve the problem completely. Need to ask PL.
394
0
        mpContentWindow->Invalidate(InvalidateFlags::Children);
395
0
    }
396
397
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
398
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
399
0
    VisAreaChanged(aVisAreaWin);
400
401
0
    ::sd::View* pView = GetView();
402
0
    if (pView)
403
0
    {
404
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
405
0
    }
406
407
0
    UpdateScrollBars();
408
0
}
409
410
::tools::Long ViewShell::GetZoom() const
411
0
{
412
0
    if (mpContentWindow)
413
0
    {
414
0
        return mpContentWindow->GetZoom();
415
0
    }
416
417
0
    return 0;
418
0
}
419
420
/**
421
 * Set zoom rectangle for active window. Sets all split windows to the same zoom
422
 * factor.
423
 */
424
void ViewShell::SetZoomRect(const ::tools::Rectangle& rZoomRect)
425
0
{
426
0
    ::tools::Long nZoom = GetActiveWindow()->SetZoomRect(rZoomRect);
427
0
    Fraction aUIScale(nZoom, 100);
428
0
    aUIScale *= GetDoc()->GetUIScale();
429
430
0
    Point aPos = GetActiveWindow()->GetWinViewPos();
431
432
0
    if (mpHorizontalRuler)
433
0
        mpHorizontalRuler->SetZoom(aUIScale);
434
435
0
    if (mpVerticalRuler)
436
0
        mpVerticalRuler->SetZoom(aUIScale);
437
438
0
    if (mpContentWindow)
439
0
    {
440
0
        Point aNewPos = mpContentWindow->GetWinViewPos();
441
0
        aNewPos.setX( aPos.X() );
442
0
        aNewPos.setY( aPos.Y() );
443
0
        mpContentWindow->SetZoomIntegral(nZoom);
444
0
        mpContentWindow->SetWinViewPos(aNewPos);
445
0
        mpContentWindow->UpdateMapOrigin();
446
447
        // When tiled rendering, UpdateMapOrigin() doesn't touch the map mode.
448
0
        if (!comphelper::LibreOfficeKit::isActive())
449
            // #i74769# see above
450
0
            mpContentWindow->Invalidate(InvalidateFlags::Children);
451
0
    }
452
453
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
454
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
455
0
    VisAreaChanged(aVisAreaWin);
456
457
0
    ::sd::View* pView = GetView();
458
0
    if (pView)
459
0
    {
460
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
461
0
    }
462
463
0
    UpdateScrollBars();
464
0
}
465
466
/**
467
 * Initialize imaging parameters for all split windows.
468
 */
469
void ViewShell::InitWindows(const Point& rViewOrigin, const Size& rViewSize,
470
                              const Point& rWinPos, bool bUpdate)
471
0
{
472
0
    if (mpContentWindow)
473
0
    {
474
0
        mpContentWindow->SetViewOrigin(rViewOrigin);
475
0
        mpContentWindow->SetViewSize(rViewSize);
476
0
        mpContentWindow->SetWinViewPos(rWinPos);
477
478
0
        if ( bUpdate )
479
0
        {
480
0
            mpContentWindow->UpdateMapOrigin();
481
0
            mpContentWindow->Invalidate();
482
0
        }
483
0
    }
484
485
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
486
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
487
0
    VisAreaChanged(aVisAreaWin);
488
489
0
    ::sd::View* pView = GetView();
490
0
    if (pView)
491
0
    {
492
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
493
0
    }
494
0
}
495
496
/**
497
 * Invalidate all split windows below the ?provided rectangle.
498
 */
499
void ViewShell::InvalidateWindows()
500
0
{
501
0
    if (mpContentWindow)
502
0
        mpContentWindow->Invalidate();
503
0
}
504
505
/**
506
 * Draw a selection rectangle with the ?provided pen on all split windows.
507
 */
508
void ViewShell::DrawMarkRect(const ::tools::Rectangle& rRect) const
509
0
{
510
0
    if (mpContentWindow)
511
0
    {
512
0
        mpContentWindow->InvertTracking(rRect, ShowTrackFlags::Object | ShowTrackFlags::TrackWindow);
513
0
    }
514
0
}
515
516
void ViewShell::SetPageSizeAndBorder(PageKind ePageKind, const Size& rNewSize,
517
                                       ::tools::Long nLeft, ::tools::Long nRight,
518
                                       ::tools::Long nUpper, ::tools::Long nLower, bool bScaleAll,
519
                                       Orientation eOrientation, sal_uInt16 nPaperBin,
520
                                       bool bBackgroundFullSize)
521
0
{
522
0
    const sal_uInt16 nMasterPageCnt(GetDoc()->GetMasterSdPageCount(ePageKind));
523
0
    const sal_uInt16 nPageCnt(GetDoc()->GetSdPageCount(ePageKind));
524
525
0
    if(0 == nPageCnt && 0 == nMasterPageCnt)
526
0
    {
527
0
        return;
528
0
    }
529
530
0
    std::unique_ptr<SdUndoGroup> pUndoGroup;
531
0
    SfxViewShell* pViewShell(GetViewShell());
532
0
    if (pViewShell)
533
0
    {
534
0
        pUndoGroup.reset(new SdUndoGroup(*GetDoc()));
535
0
        pUndoGroup->SetComment(SdResId(STR_UNDO_CHANGE_PAGEFORMAT));
536
0
    }
537
0
    Broadcast (ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_START));
538
539
    // use Model-based method at SdDrawDocument
540
0
    GetDoc()->AdaptPageSizeForAllPages(
541
0
        rNewSize,
542
0
        ePageKind,
543
0
        pUndoGroup.get(),
544
0
        nLeft,
545
0
        nRight,
546
0
        nUpper,
547
0
        nLower,
548
0
        bScaleAll,
549
0
        eOrientation,
550
0
        nPaperBin,
551
0
        bBackgroundFullSize);
552
553
    // adjust handout page to new format of the standard page
554
0
    if(0 != nPageCnt && ((ePageKind == PageKind::Standard) || (ePageKind == PageKind::Handout)))
555
0
    {
556
0
        GetDoc()->GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
557
0
    }
558
559
    // handed over undo group to undo manager
560
0
    if (pViewShell)
561
0
    {
562
0
        pViewShell->GetViewFrame().GetObjectShell()->GetUndoManager()->AddUndoAction(std::move(pUndoGroup));
563
0
    }
564
565
    // calculate View-Sizes
566
0
    SdPage* pPage(0 != nPageCnt
567
0
        ? GetDoc()->GetSdPage(0, ePageKind)
568
0
        : GetDoc()->GetMasterSdPage(0, ePageKind));
569
0
    const ::tools::Long nWidth(pPage->GetSize().Width());
570
0
    const ::tools::Long nHeight(pPage->GetSize().Height());
571
0
    const Point aPageOrg(nWidth, nHeight / 2);
572
0
    const Size aViewSize(nWidth * 3, nHeight * 2);
573
0
    Point aVisAreaPos;
574
0
    ::sd::View* pView(GetView());
575
0
    const Point aNewOrigin(pPage->GetLeftBorder(), pPage->GetUpperBorder());
576
577
0
    InitWindows(aPageOrg, aViewSize, Point(-1, -1), true);
578
579
0
    if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
580
0
    {
581
0
        aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
582
0
    }
583
584
0
    if (pView)
585
0
    {
586
0
        pView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aViewSize));
587
0
    }
588
589
0
    UpdateScrollBars();
590
591
0
    if (pView)
592
0
    {
593
0
        pView->GetSdrPageView()->SetPageOrigin(aNewOrigin);
594
0
    }
595
596
0
    if(nullptr != pViewShell)
597
0
    {
598
0
        pViewShell->GetViewFrame().GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
599
        // zoom onto (new) page size
600
0
        pViewShell->GetViewFrame().GetDispatcher()->Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
601
0
    }
602
603
0
    Broadcast(ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_END));
604
0
}
605
606
/**
607
 * Set zoom factor for InPlace
608
 */
609
void ViewShell::SetZoomFactor(const Fraction& rZoomX, const Fraction&)
610
0
{
611
0
    ::tools::Long nZoom = static_cast<::tools::Long>(static_cast<double>(rZoomX) * 100);
612
0
    SetZoom(nZoom);
613
0
}
614
615
void ViewShell::SetActiveWindow (::sd::Window* pWin)
616
0
{
617
0
    SfxViewShell* pViewShell = GetViewShell();
618
0
    assert(pViewShell!=nullptr);
619
620
0
    if (pViewShell->GetWindow() != pWin)
621
0
    {
622
        // #i31551# was wrong, it may have been a problem with the repaint at that time.
623
        // For transparent form controls, it is necessary to have that flag set, all apps
624
        // do set it. Enabling again.
625
0
        if (pWin)
626
0
        {
627
0
            pWin->EnableChildTransparentMode();
628
0
        }
629
0
    }
630
631
0
    if (mpActiveWindow.get() != pWin)
632
0
        mpActiveWindow = pWin;
633
634
    // The rest of this function is not guarded anymore against calling this
635
    // method with an already active window because the functions may still
636
    // point to the old window when the new one has already been assigned to
637
    // pWindow elsewhere.
638
0
    ::sd::View* pView = GetView();
639
0
    if (pView)
640
0
    {
641
0
        pView->SetActualWin(pWin->GetOutDev());
642
0
    }
643
0
    if(HasCurrentFunction())
644
0
    {
645
0
        GetCurrentFunction()->SetWindow(pWin);
646
0
    }
647
0
}
648
649
bool ViewShell::RequestHelp(const HelpEvent& rHEvt)
650
0
{
651
0
    bool bReturn = false;
652
653
0
    if (bool(rHEvt.GetMode()))
654
0
    {
655
0
        if(HasCurrentFunction())
656
0
        {
657
0
            bReturn = GetCurrentFunction()->RequestHelp(rHEvt);
658
0
        }
659
0
    }
660
661
0
    return bReturn;
662
0
}
663
664
void ViewShell::SetFrameView (FrameView* pNewFrameView)
665
0
{
666
0
    mpFrameView = pNewFrameView;
667
0
    ReadFrameViewData (mpFrameView);
668
0
}
669
670
/*************************************************************************
671
|*
672
|* Read FrameViews data and set actual views data
673
|*
674
\************************************************************************/
675
676
void ViewShell::ReadFrameViewData(FrameView*)
677
0
{
678
0
}
679
680
/*************************************************************************
681
|*
682
|* Write actual views data to FrameView
683
|*
684
\************************************************************************/
685
686
void ViewShell::WriteFrameViewData()
687
0
{
688
0
}
689
690
bool ViewShell::ActivateObject(SdrOle2Obj* pObj, sal_Int32 nVerb)
691
0
{
692
0
    ErrCode aErrCode = ERRCODE_NONE;
693
694
0
    SfxErrorContext aEC(ERRCTX_SO_DOVERB, GetFrameWeld(), RID_SO_ERRCTX);
695
0
    bool bAbort = false;
696
0
    GetDocSh()->SetWaitCursor( true );
697
0
    SfxViewShell* pViewShell = GetViewShell();
698
0
    assert(pViewShell!=nullptr);
699
0
    bool bChangeDefaultsForChart = false;
700
701
0
    uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef();
702
0
    if ( !xObj.is() )
703
0
    {
704
        // provide OLE object to empty OLE object
705
0
        OUString aName = pObj->GetProgName();
706
0
        OUString aObjName;
707
0
        SvGlobalName aClass;
708
709
0
        if( aName == "StarChart"  || aName == "StarOrg" )
710
0
        {
711
0
            if( SvtModuleOptions().IsChartInstalled() )
712
0
            {
713
0
                aClass = SvGlobalName( SO3_SCH_CLASSID );
714
0
                bChangeDefaultsForChart = true;
715
0
            }
716
0
        }
717
0
        else if( aName == "StarCalc" )
718
0
        {
719
0
            if( SvtModuleOptions().IsCalcInstalled() )
720
0
                aClass = SvGlobalName( SO3_SC_CLASSID );
721
0
        }
722
0
        else if( aName == "StarMath" )
723
0
        {
724
0
            if( SvtModuleOptions().IsMathInstalled() )
725
0
                aClass = SvGlobalName( SO3_SM_CLASSID );
726
0
        }
727
728
0
        if ( aClass != SvGlobalName() )
729
0
            xObj = GetDocSh()->GetEmbeddedObjectContainer().CreateEmbeddedObject( aClass.GetByteSequence(), aObjName );
730
731
0
        if( !xObj.is() )
732
0
        {
733
0
            aName.clear();
734
735
            // call dialog "insert OLE object"
736
0
            GetDocSh()->SetWaitCursor( false );
737
0
            pViewShell->GetViewFrame().GetDispatcher()->Execute(
738
0
                SID_INSERT_OBJECT,
739
0
                SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
740
0
            xObj = pObj->GetObjRef();
741
0
            GetDocSh()->SetWaitCursor( true );
742
743
0
            if (!xObj.is())
744
0
            {
745
0
                bAbort = true;
746
0
            }
747
0
        }
748
749
0
        if ( xObj.is() )
750
0
        {
751
            // OLE object is no longer empty
752
0
            pObj->SetEmptyPresObj(false);
753
0
            pObj->SetOutlinerParaObject(std::nullopt);
754
0
            pObj->ClearGraphic();
755
756
            // the empty OLE object gets a new IPObj
757
0
            if (!aName.isEmpty())
758
0
            {
759
0
                pObj->SetObjRef(xObj);
760
0
                pObj->SetName(aObjName);
761
0
                pObj->SetPersistName(aObjName);
762
0
            }
763
0
            else
764
0
            {
765
                // insertion was done by the dialog
766
0
                pObj->SetObjRef(xObj);
767
0
            }
768
769
0
            ::tools::Rectangle aRect = pObj->GetLogicRect();
770
771
0
            if ( pObj->GetAspect() != embed::Aspects::MSOLE_ICON )
772
0
            {
773
0
                awt::Size aSz;
774
0
                aSz.Width = aRect.GetWidth();
775
0
                aSz.Height = aRect.GetHeight();
776
0
                xObj->setVisualAreaSize( pObj->GetAspect(), aSz );
777
0
            }
778
779
0
            GetViewShellBase().SetVerbs( xObj->getSupportedVerbs() );
780
781
0
            nVerb = embed::EmbedVerbs::MS_OLEVERB_SHOW;
782
0
        }
783
0
        else
784
0
        {
785
0
            aErrCode = ERRCODE_SFX_OLEGENERAL;
786
0
        }
787
0
    }
788
789
0
    if( aErrCode == ERRCODE_NONE )
790
0
    {
791
0
        ::sd::View* pView = GetView();
792
793
0
        if (pView->IsTextEdit())
794
0
        {
795
0
            pView->SdrEndTextEdit();
796
0
        }
797
798
0
        SfxInPlaceClient* pSdClient =
799
0
            pViewShell->FindIPClient(pObj->GetObjRef(), GetActiveWindow());
800
801
0
        if ( !pSdClient )
802
0
        {
803
0
            pSdClient = new Client(pObj, *this, GetActiveWindow());
804
0
        }
805
806
0
        ::tools::Rectangle aRect = pObj->GetLogicRect();
807
808
0
        {
809
            // #i118485# center on BoundRect for activation,
810
            // OLE may be sheared/rotated now
811
0
            const ::tools::Rectangle& rBoundRect = pObj->GetCurrentBoundRect();
812
0
            const Point aDelta(rBoundRect.Center() - aRect.Center());
813
0
            aRect.Move(aDelta.X(), aDelta.Y());
814
0
        }
815
816
0
        Size aDrawSize = aRect.GetSize();
817
818
0
        MapMode aMapMode( GetDoc()->GetScaleUnit() );
819
0
        Size aObjAreaSize = pObj->GetOrigObjSize( &aMapMode );
820
0
        if( pObj->IsChart() ) //charts never should be stretched see #i84323# for example
821
0
            aObjAreaSize = aDrawSize;
822
823
0
        Fraction aScaleWidth (aDrawSize.Width(),  aObjAreaSize.Width() );
824
0
        Fraction aScaleHeight(aDrawSize.Height(), aObjAreaSize.Height() );
825
0
        aScaleWidth.ReduceInaccurate(10);       // compatible to the SdrOle2Obj
826
0
        aScaleHeight.ReduceInaccurate(10);
827
0
        pSdClient->SetSizeScale(aScaleWidth, aScaleHeight);
828
829
        // visible section is only changed in-place!
830
0
        aRect.SetSize(aObjAreaSize);
831
        // the object area size must be set after scaling, since it triggers the resizing
832
0
        pSdClient->SetObjArea(aRect);
833
834
0
        if( bChangeDefaultsForChart && xObj.is())
835
0
        {
836
0
            ChartHelper::AdaptDefaultsForChart( xObj );
837
0
        }
838
839
0
        pSdClient->DoVerb(nVerb);   // if necessary, ErrCode is outputted by Sfx
840
0
        pViewShell->GetViewFrame().GetBindings().Invalidate(
841
0
            SID_NAVIGATOR_STATE, true);
842
0
    }
843
844
0
    GetDocSh()->SetWaitCursor( false );
845
846
0
    if (aErrCode != ERRCODE_NONE && !bAbort)
847
0
    {
848
0
        ErrorHandler::HandleError(ErrCodeMsg(aErrCode));
849
0
    }
850
851
0
    return aErrCode == ERRCODE_NONE;
852
0
}
853
854
/**
855
 * @returns enclosing rectangle of all (split-) windows.
856
 */
857
const ::tools::Rectangle& ViewShell::GetAllWindowRect()
858
0
{
859
0
    maAllWindowRectangle.SetPos(
860
0
        mpContentWindow->OutputToScreenPixel(Point(0,0)));
861
0
    return maAllWindowRectangle;
862
0
}
863
864
void ViewShell::ReadUserData()
865
0
{
866
    // zoom onto VisArea from FrameView
867
0
    GetViewShell()->GetViewFrame().GetDispatcher()->Execute(SID_SIZE_VISAREA,
868
0
        SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
869
0
}
870
871
void ViewShell::WriteUserData()
872
0
{
873
    // writing of our data is always done in WriteFrameViewData()
874
0
    WriteFrameViewData();
875
0
}
876
877
/**
878
 * Switch ruler on/off
879
 */
880
void ViewShell::SetRuler(bool bRuler)
881
0
{
882
0
    mbHasRulers = ( bRuler && !GetDocSh()->IsPreview() ); // no rulers on preview mode
883
884
0
    if (mpHorizontalRuler)
885
0
    {
886
0
        if (mbHasRulers)
887
0
        {
888
0
            mpHorizontalRuler->Show();
889
0
        }
890
0
        else
891
0
        {
892
0
            mpHorizontalRuler->Hide();
893
0
        }
894
0
    }
895
896
0
    if (mpVerticalRuler)
897
0
    {
898
0
        if (mbHasRulers)
899
0
        {
900
0
            mpVerticalRuler->Show();
901
0
        }
902
0
        else
903
0
        {
904
0
            mpVerticalRuler->Hide();
905
0
        }
906
0
    }
907
908
0
    OSL_ASSERT(GetViewShell()!=nullptr);
909
0
    if (IsMainViewShell())
910
0
        GetViewShell()->InvalidateBorder();
911
0
}
912
913
void ViewShell::SetScrollBarsVisible(bool bVisible)
914
0
{
915
0
    if (mpVerticalScrollBar)
916
0
        mpVerticalScrollBar->Show( bVisible );
917
918
0
    if (mpHorizontalScrollBar)
919
0
        mpHorizontalScrollBar->Show( bVisible );
920
0
}
921
922
sal_Int8 ViewShell::AcceptDrop (
923
    const AcceptDropEvent& rEvt,
924
    DropTargetHelper& rTargetHelper,
925
    ::sd::Window* /*pTargetWindow*/,
926
    sal_uInt16 /*nPage*/,
927
    SdrLayerID nLayer)
928
0
{
929
0
    ::sd::View* pView = GetView();
930
0
    return( pView ? pView->AcceptDrop( rEvt, rTargetHelper, nLayer ) : DND_ACTION_NONE );
931
0
}
932
933
sal_Int8 ViewShell::ExecuteDrop (
934
    const ExecuteDropEvent& rEvt,
935
    DropTargetHelper& /*rTargetHelper*/,
936
    ::sd::Window* pTargetWindow,
937
    sal_uInt16 nPage,
938
    SdrLayerID nLayer)
939
0
{
940
0
    ::sd::View* pView = GetView();
941
0
    return pView ? pView->ExecuteDrop( rEvt, pTargetWindow, nPage, nLayer ) : DND_ACTION_NONE;
942
0
}
943
944
void ViewShell::WriteUserDataSequence ( css::uno::Sequence < css::beans::PropertyValue >& rSequence )
945
0
{
946
0
    const sal_Int32 nIndex = rSequence.getLength();
947
0
    rSequence.realloc( nIndex + 2 );
948
0
    auto pSequence = rSequence.getArray();
949
950
0
    OSL_ASSERT (GetViewShell()!=nullptr);
951
    // Get the view id from the view shell in the center pane.  This will
952
    // usually be the called view shell, but to be on the safe side we call
953
    // the main view shell explicitly.
954
0
    SfxInterfaceId nViewID (IMPRESS_FACTORY_ID);
955
0
    if (auto pViewShell = GetViewShellBase().GetMainViewShell().get())
956
0
        nViewID = pViewShell->mpImpl->GetViewId();
957
0
    pSequence[nIndex].Name = sUNO_View_ViewId;
958
0
    pSequence[nIndex].Value <<= "view" + OUString::number( static_cast<sal_uInt16>(nViewID));
959
960
0
    pSequence[nIndex].Name = u"WindowState"_ustr;
961
0
    pSequence[nIndex].Value <<= ::framework::WindowStateHelper::GetFromWindow(GetViewShellBase().GetWindow());
962
963
0
    mpFrameView->WriteUserDataSequence( rSequence );
964
0
}
965
966
void ViewShell::ReadUserDataSequence ( const css::uno::Sequence < css::beans::PropertyValue >& rSequence )
967
0
{
968
0
    mpFrameView->ReadUserDataSequence( rSequence );
969
0
}
970
971
void ViewShell::VisAreaChanged(const ::tools::Rectangle& /*rRect*/)
972
0
{
973
0
    OSL_ASSERT (GetViewShell()!=nullptr);
974
0
    GetViewShell()->VisAreaChanged();
975
0
}
976
977
void ViewShell::SetWinViewPos(const Point& rWinPos)
978
0
{
979
0
    if (mpContentWindow)
980
0
    {
981
0
        mpContentWindow->SetWinViewPos(rWinPos);
982
983
0
        mpContentWindow->UpdateMapOrigin();
984
0
        mpContentWindow->Invalidate();
985
0
    }
986
987
0
    if (mbHasRulers)
988
0
    {
989
0
        UpdateHRuler();
990
0
        UpdateVRuler();
991
0
    }
992
993
0
    UpdateScrollBars();
994
995
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
996
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
997
0
    VisAreaChanged(aVisAreaWin);
998
999
0
    ::sd::View* pView = GetView();
1000
0
    if (pView)
1001
0
    {
1002
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
1003
0
    }
1004
0
}
1005
1006
Point const & ViewShell::GetWinViewPos() const
1007
0
{
1008
0
    return mpContentWindow->GetWinViewPos();
1009
0
}
1010
1011
Point const & ViewShell::GetViewOrigin() const
1012
0
{
1013
0
    return mpContentWindow->GetViewOrigin();
1014
0
}
1015
1016
} // end of namespace sd
1017
1018
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */