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/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
    RememberPageZoom(nZoom);
409
0
}
410
411
::tools::Long ViewShell::GetZoom() const
412
0
{
413
0
    if (mpContentWindow)
414
0
    {
415
0
        return mpContentWindow->GetZoom();
416
0
    }
417
418
0
    return 0;
419
0
}
420
421
/**
422
 * Set zoom rectangle for active window. Sets all split windows to the same zoom
423
 * factor.
424
 */
425
void ViewShell::SetZoomRect(const ::tools::Rectangle& rZoomRect)
426
0
{
427
0
    ::tools::Long nZoom = GetActiveWindow()->SetZoomRect(rZoomRect);
428
0
    Fraction aUIScale(nZoom, 100);
429
0
    aUIScale *= GetDoc()->GetUIScale();
430
431
0
    Point aPos = GetActiveWindow()->GetWinViewPos();
432
433
0
    if (mpHorizontalRuler)
434
0
        mpHorizontalRuler->SetZoom(aUIScale);
435
436
0
    if (mpVerticalRuler)
437
0
        mpVerticalRuler->SetZoom(aUIScale);
438
439
0
    if (mpContentWindow)
440
0
    {
441
0
        Point aNewPos = mpContentWindow->GetWinViewPos();
442
0
        aNewPos.setX( aPos.X() );
443
0
        aNewPos.setY( aPos.Y() );
444
0
        mpContentWindow->SetZoomIntegral(nZoom);
445
0
        mpContentWindow->SetWinViewPos(aNewPos);
446
0
        mpContentWindow->UpdateMapOrigin();
447
448
        // When tiled rendering, UpdateMapOrigin() doesn't touch the map mode.
449
0
        if (!comphelper::LibreOfficeKit::isActive())
450
            // #i74769# see above
451
0
            mpContentWindow->Invalidate(InvalidateFlags::Children);
452
0
    }
453
454
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
455
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
456
0
    VisAreaChanged(aVisAreaWin);
457
458
0
    ::sd::View* pView = GetView();
459
0
    if (pView)
460
0
    {
461
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
462
0
    }
463
464
0
    UpdateScrollBars();
465
0
}
466
467
/**
468
 * Initialize imaging parameters for all split windows.
469
 */
470
void ViewShell::InitWindows(const Point& rViewOrigin, const Size& rViewSize,
471
                              const Point& rWinPos, bool bUpdate)
472
0
{
473
0
    if (mpContentWindow)
474
0
    {
475
0
        mpContentWindow->SetViewOrigin(rViewOrigin);
476
0
        mpContentWindow->SetViewSize(rViewSize);
477
0
        mpContentWindow->SetWinViewPos(rWinPos);
478
479
0
        if ( bUpdate )
480
0
        {
481
0
            mpContentWindow->UpdateMapOrigin();
482
0
            mpContentWindow->Invalidate();
483
0
        }
484
0
    }
485
486
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
487
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
488
0
    VisAreaChanged(aVisAreaWin);
489
490
0
    ::sd::View* pView = GetView();
491
0
    if (pView)
492
0
    {
493
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
494
0
    }
495
0
}
496
497
/**
498
 * Invalidate all split windows below the ?provided rectangle.
499
 */
500
void ViewShell::InvalidateWindows()
501
0
{
502
0
    if (mpContentWindow)
503
0
        mpContentWindow->Invalidate();
504
0
}
505
506
/**
507
 * Draw a selection rectangle with the ?provided pen on all split windows.
508
 */
509
void ViewShell::DrawMarkRect(const ::tools::Rectangle& rRect) const
510
0
{
511
0
    if (mpContentWindow)
512
0
    {
513
0
        mpContentWindow->InvertTracking(rRect, ShowTrackFlags::Object | ShowTrackFlags::TrackWindow);
514
0
    }
515
0
}
516
517
void ViewShell::SetPageSizeAndBorder(PageKind ePageKind, const Size& rNewSize,
518
                                       ::tools::Long nLeft, ::tools::Long nRight,
519
                                       ::tools::Long nUpper, ::tools::Long nLower, bool bScaleAll,
520
                                       Orientation eOrientation, sal_uInt16 nPaperBin,
521
                                       bool bBackgroundFullSize)
522
0
{
523
0
    const sal_uInt16 nMasterPageCnt(GetDoc()->GetMasterSdPageCount(ePageKind));
524
0
    const sal_uInt16 nPageCnt(GetDoc()->GetSdPageCount(ePageKind));
525
526
0
    if(0 == nPageCnt && 0 == nMasterPageCnt)
527
0
    {
528
0
        return;
529
0
    }
530
531
0
    std::unique_ptr<SdUndoGroup> pUndoGroup;
532
0
    SfxViewShell* pViewShell(GetViewShell());
533
0
    if (pViewShell)
534
0
    {
535
0
        pUndoGroup.reset(new SdUndoGroup(*GetDoc()));
536
0
        pUndoGroup->SetComment(SdResId(STR_UNDO_CHANGE_PAGEFORMAT));
537
0
    }
538
0
    Broadcast (ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_START));
539
540
0
    SdDrawDocument* pDrawDoc = GetDoc();
541
542
0
    if (pDrawDoc->ShouldResizeAllPages())
543
        // use Model-based method at SdDrawDocument
544
0
        pDrawDoc->AdaptPageSizeForAllPages(
545
0
            rNewSize,
546
0
            ePageKind,
547
0
            pUndoGroup.get(),
548
0
            nLeft,
549
0
            nRight,
550
0
            nUpper,
551
0
            nLower,
552
0
            bScaleAll,
553
0
            eOrientation,
554
0
            nPaperBin,
555
0
            bBackgroundFullSize);
556
557
0
    else
558
0
    {
559
0
        SdPage* pCurrentPage = getCurrentPage();
560
0
        pDrawDoc->ResizeCurrentPage(
561
0
            pCurrentPage,
562
0
            rNewSize,
563
0
            ePageKind,
564
0
            pUndoGroup.get(),
565
0
            nLeft,
566
0
            nRight,
567
0
            nUpper,
568
0
            nLower,
569
0
            bScaleAll,
570
0
            eOrientation,
571
0
            nPaperBin,
572
0
            bBackgroundFullSize
573
0
        );
574
0
    }
575
576
    // adjust handout page to new format of the standard page
577
0
    if(0 != nPageCnt && ((ePageKind == PageKind::Standard) || (ePageKind == PageKind::Handout)))
578
0
    {
579
0
        GetDoc()->GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
580
0
    }
581
582
    // handed over undo group to undo manager
583
0
    if (pViewShell)
584
0
    {
585
0
        pViewShell->GetViewFrame().GetObjectShell()->GetUndoManager()->AddUndoAction(std::move(pUndoGroup));
586
0
    }
587
588
    // calculate View-Sizes
589
0
    SdPage* pPage(0 != nPageCnt
590
0
        ? GetDoc()->GetSdPage(0, ePageKind)
591
0
        : GetDoc()->GetMasterSdPage(0, ePageKind));
592
0
    const ::tools::Long nWidth(pPage->GetSize().Width());
593
0
    const ::tools::Long nHeight(pPage->GetSize().Height());
594
0
    const Point aPageOrg(nWidth, nHeight / 2);
595
0
    const Size aViewSize(nWidth * 3, nHeight * 2);
596
0
    Point aVisAreaPos;
597
0
    ::sd::View* pView(GetView());
598
0
    const Point aNewOrigin(pPage->GetLeftBorder(), pPage->GetUpperBorder());
599
600
0
    InitWindows(aPageOrg, aViewSize, Point(-1, -1), true);
601
602
0
    if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
603
0
    {
604
0
        aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
605
0
    }
606
607
0
    if (pView)
608
0
    {
609
0
        pView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aViewSize));
610
0
    }
611
612
0
    UpdateScrollBars();
613
614
0
    if (pView)
615
0
    {
616
0
        pView->GetSdrPageView()->SetPageOrigin(aNewOrigin);
617
0
    }
618
619
0
    if(nullptr != pViewShell)
620
0
    {
621
0
        pViewShell->GetViewFrame().GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
622
        // zoom onto (new) page size
623
0
        pViewShell->GetViewFrame().GetDispatcher()->Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
624
0
    }
625
626
0
    Broadcast(ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_END));
627
0
}
628
629
/**
630
 * Set zoom factor for InPlace
631
 */
632
void ViewShell::SetZoomFactor(const Fraction& rZoomX, const Fraction&)
633
0
{
634
0
    ::tools::Long nZoom = static_cast<::tools::Long>(static_cast<double>(rZoomX) * 100);
635
0
    SetZoom(nZoom);
636
0
}
637
638
sal_uInt16 ViewShell::GetPageZoom() const
639
0
{
640
0
    if (getCurrentPage()->IsCanvasPage())
641
0
        return mnCanvasPageZoom;
642
0
    return mnNonCanvasPageZoom;
643
0
}
644
645
void ViewShell::RememberPageZoom(const sal_uInt16 nZoom)
646
0
{
647
0
    SdPage* pPage = getCurrentPage();
648
0
    if (pPage && pPage->IsCanvasPage())
649
0
        mnCanvasPageZoom = nZoom;
650
0
    else
651
0
        mnNonCanvasPageZoom = nZoom;
652
0
}
653
654
void ViewShell::SetActiveWindow (::sd::Window* pWin)
655
0
{
656
0
    SfxViewShell* pViewShell = GetViewShell();
657
0
    assert(pViewShell!=nullptr);
658
659
0
    if (pViewShell->GetWindow() != pWin)
660
0
    {
661
        // #i31551# was wrong, it may have been a problem with the repaint at that time.
662
        // For transparent form controls, it is necessary to have that flag set, all apps
663
        // do set it. Enabling again.
664
0
        if (pWin)
665
0
        {
666
0
            pWin->EnableChildTransparentMode();
667
0
        }
668
0
    }
669
670
0
    if (mpActiveWindow.get() != pWin)
671
0
        mpActiveWindow = pWin;
672
673
    // The rest of this function is not guarded anymore against calling this
674
    // method with an already active window because the functions may still
675
    // point to the old window when the new one has already been assigned to
676
    // pWindow elsewhere.
677
0
    ::sd::View* pView = GetView();
678
0
    if (pView)
679
0
    {
680
0
        pView->SetActualWin(pWin->GetOutDev());
681
0
    }
682
0
    if(HasCurrentFunction())
683
0
    {
684
0
        GetCurrentFunction()->SetWindow(pWin);
685
0
    }
686
0
}
687
688
bool ViewShell::RequestHelp(const HelpEvent& rHEvt)
689
0
{
690
0
    bool bReturn = false;
691
692
0
    if (bool(rHEvt.GetMode()))
693
0
    {
694
0
        if(HasCurrentFunction())
695
0
        {
696
0
            bReturn = GetCurrentFunction()->RequestHelp(rHEvt);
697
0
        }
698
0
    }
699
700
0
    return bReturn;
701
0
}
702
703
void ViewShell::SetFrameView (FrameView* pNewFrameView)
704
0
{
705
0
    mpFrameView = pNewFrameView;
706
0
    ReadFrameViewData (mpFrameView);
707
0
}
708
709
/*************************************************************************
710
|*
711
|* Read FrameViews data and set actual views data
712
|*
713
\************************************************************************/
714
715
void ViewShell::ReadFrameViewData(FrameView*)
716
0
{
717
0
}
718
719
/*************************************************************************
720
|*
721
|* Write actual views data to FrameView
722
|*
723
\************************************************************************/
724
725
void ViewShell::WriteFrameViewData()
726
0
{
727
0
}
728
729
bool ViewShell::ActivateObject(SdrOle2Obj* pObj, sal_Int32 nVerb)
730
0
{
731
0
    ErrCode aErrCode = ERRCODE_NONE;
732
733
0
    SfxErrorContext aEC(ERRCTX_SO_DOVERB, GetFrameWeld(), RID_SO_ERRCTX);
734
0
    bool bAbort = false;
735
0
    GetDocSh()->SetWaitCursor( true );
736
0
    SfxViewShell* pViewShell = GetViewShell();
737
0
    assert(pViewShell!=nullptr);
738
0
    bool bChangeDefaultsForChart = false;
739
740
0
    uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef();
741
0
    if ( !xObj.is() )
742
0
    {
743
        // provide OLE object to empty OLE object
744
0
        OUString aName = pObj->GetProgName();
745
0
        OUString aObjName;
746
0
        SvGlobalName aClass;
747
748
0
        if( aName == "StarChart"  || aName == "StarOrg" )
749
0
        {
750
0
            if( SvtModuleOptions().IsChartInstalled() )
751
0
            {
752
0
                aClass = SvGlobalName( SO3_SCH_CLASSID );
753
0
                bChangeDefaultsForChart = true;
754
0
            }
755
0
        }
756
0
        else if( aName == "StarCalc" )
757
0
        {
758
0
            if( SvtModuleOptions().IsCalcInstalled() )
759
0
                aClass = SvGlobalName( SO3_SC_CLASSID );
760
0
        }
761
0
        else if( aName == "StarMath" )
762
0
        {
763
0
            if( SvtModuleOptions().IsMathInstalled() )
764
0
                aClass = SvGlobalName( SO3_SM_CLASSID );
765
0
        }
766
767
0
        if ( aClass != SvGlobalName() )
768
0
            xObj = GetDocSh()->GetEmbeddedObjectContainer().CreateEmbeddedObject( aClass.GetByteSequence(), aObjName );
769
770
0
        if( !xObj.is() )
771
0
        {
772
0
            aName.clear();
773
774
            // call dialog "insert OLE object"
775
0
            GetDocSh()->SetWaitCursor( false );
776
0
            pViewShell->GetViewFrame().GetDispatcher()->Execute(
777
0
                SID_INSERT_OBJECT,
778
0
                SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
779
0
            xObj = pObj->GetObjRef();
780
0
            GetDocSh()->SetWaitCursor( true );
781
782
0
            if (!xObj.is())
783
0
            {
784
0
                bAbort = true;
785
0
            }
786
0
        }
787
788
0
        if ( xObj.is() )
789
0
        {
790
            // OLE object is no longer empty
791
0
            pObj->SetEmptyPresObj(false);
792
0
            pObj->SetOutlinerParaObject(std::nullopt);
793
0
            pObj->ClearGraphic();
794
795
            // the empty OLE object gets a new IPObj
796
0
            if (!aName.isEmpty())
797
0
            {
798
0
                pObj->SetObjRef(xObj);
799
0
                pObj->SetName(aObjName);
800
0
                pObj->SetPersistName(aObjName);
801
0
            }
802
0
            else
803
0
            {
804
                // insertion was done by the dialog
805
0
                pObj->SetObjRef(xObj);
806
0
            }
807
808
0
            ::tools::Rectangle aRect = pObj->GetLogicRect();
809
810
0
            if ( pObj->GetAspect() != embed::Aspects::MSOLE_ICON )
811
0
            {
812
0
                awt::Size aSz;
813
0
                aSz.Width = aRect.GetWidth();
814
0
                aSz.Height = aRect.GetHeight();
815
0
                xObj->setVisualAreaSize( pObj->GetAspect(), aSz );
816
0
            }
817
818
0
            GetViewShellBase().SetVerbs( xObj->getSupportedVerbs() );
819
820
0
            nVerb = embed::EmbedVerbs::MS_OLEVERB_SHOW;
821
0
        }
822
0
        else
823
0
        {
824
0
            aErrCode = ERRCODE_SFX_OLEGENERAL;
825
0
        }
826
0
    }
827
828
0
    if( aErrCode == ERRCODE_NONE )
829
0
    {
830
0
        ::sd::View* pView = GetView();
831
832
0
        if (pView->IsTextEdit())
833
0
        {
834
0
            pView->SdrEndTextEdit();
835
0
        }
836
837
0
        SfxInPlaceClient* pSdClient =
838
0
            pViewShell->FindIPClient(pObj->GetObjRef(), GetActiveWindow());
839
840
0
        if ( !pSdClient )
841
0
        {
842
0
            pSdClient = new Client(pObj, *this, GetActiveWindow());
843
0
        }
844
845
0
        ::tools::Rectangle aRect = pObj->GetLogicRect();
846
847
0
        {
848
            // #i118485# center on BoundRect for activation,
849
            // OLE may be sheared/rotated now
850
0
            const ::tools::Rectangle& rBoundRect = pObj->GetCurrentBoundRect();
851
0
            const Point aDelta(rBoundRect.Center() - aRect.Center());
852
0
            aRect.Move(aDelta.X(), aDelta.Y());
853
0
        }
854
855
0
        Size aDrawSize = aRect.GetSize();
856
857
0
        MapMode aMapMode( GetDoc()->GetScaleUnit() );
858
0
        Size aObjAreaSize = pObj->GetOrigObjSize( &aMapMode );
859
0
        if( pObj->IsChart() ) //charts never should be stretched see #i84323# for example
860
0
            aObjAreaSize = aDrawSize;
861
862
0
        Fraction aScaleWidth (aDrawSize.Width(),  aObjAreaSize.Width() );
863
0
        Fraction aScaleHeight(aDrawSize.Height(), aObjAreaSize.Height() );
864
0
        aScaleWidth.ReduceInaccurate(10);       // compatible to the SdrOle2Obj
865
0
        aScaleHeight.ReduceInaccurate(10);
866
0
        pSdClient->SetSizeScale(aScaleWidth, aScaleHeight);
867
868
        // visible section is only changed in-place!
869
0
        aRect.SetSize(aObjAreaSize);
870
        // the object area size must be set after scaling, since it triggers the resizing
871
0
        pSdClient->SetObjArea(aRect);
872
873
0
        if( bChangeDefaultsForChart && xObj.is())
874
0
        {
875
0
            ChartHelper::AdaptDefaultsForChart( xObj );
876
0
        }
877
878
0
        pSdClient->DoVerb(nVerb);   // if necessary, ErrCode is outputted by Sfx
879
0
        pViewShell->GetViewFrame().GetBindings().Invalidate(
880
0
            SID_NAVIGATOR_STATE, true);
881
0
    }
882
883
0
    GetDocSh()->SetWaitCursor( false );
884
885
0
    if (aErrCode != ERRCODE_NONE && !bAbort)
886
0
    {
887
0
        ErrorHandler::HandleError(ErrCodeMsg(aErrCode));
888
0
    }
889
890
0
    return aErrCode == ERRCODE_NONE;
891
0
}
892
893
/**
894
 * @returns enclosing rectangle of all (split-) windows.
895
 */
896
const ::tools::Rectangle& ViewShell::GetAllWindowRect()
897
0
{
898
0
    maAllWindowRectangle.SetPos(
899
0
        mpContentWindow->OutputToScreenPixel(Point(0,0)));
900
0
    return maAllWindowRectangle;
901
0
}
902
903
void ViewShell::ReadUserData()
904
0
{
905
    // zoom onto VisArea from FrameView
906
0
    GetViewShell()->GetViewFrame().GetDispatcher()->Execute(SID_SIZE_VISAREA,
907
0
        SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
908
0
}
909
910
void ViewShell::WriteUserData()
911
0
{
912
    // writing of our data is always done in WriteFrameViewData()
913
0
    WriteFrameViewData();
914
0
}
915
916
/**
917
 * Switch ruler on/off
918
 */
919
void ViewShell::SetRuler(bool bRuler)
920
0
{
921
0
    mbHasRulers = ( bRuler && !GetDocSh()->IsPreview() ); // no rulers on preview mode
922
923
0
    if (mpHorizontalRuler)
924
0
    {
925
0
        if (mbHasRulers)
926
0
        {
927
0
            mpHorizontalRuler->Show();
928
0
        }
929
0
        else
930
0
        {
931
0
            mpHorizontalRuler->Hide();
932
0
        }
933
0
    }
934
935
0
    if (mpVerticalRuler)
936
0
    {
937
0
        if (mbHasRulers)
938
0
        {
939
0
            mpVerticalRuler->Show();
940
0
        }
941
0
        else
942
0
        {
943
0
            mpVerticalRuler->Hide();
944
0
        }
945
0
    }
946
947
0
    OSL_ASSERT(GetViewShell()!=nullptr);
948
0
    if (IsMainViewShell())
949
0
        GetViewShell()->InvalidateBorder();
950
0
}
951
952
void ViewShell::SetScrollBarsVisible(bool bVisible)
953
0
{
954
0
    if (mpVerticalScrollBar)
955
0
        mpVerticalScrollBar->Show( bVisible );
956
957
0
    if (mpHorizontalScrollBar)
958
0
        mpHorizontalScrollBar->Show( bVisible );
959
0
}
960
961
sal_Int8 ViewShell::AcceptDrop (
962
    const AcceptDropEvent& rEvt,
963
    DropTargetHelper& rTargetHelper,
964
    ::sd::Window* /*pTargetWindow*/,
965
    sal_uInt16 /*nPage*/,
966
    SdrLayerID nLayer)
967
0
{
968
0
    ::sd::View* pView = GetView();
969
0
    return( pView ? pView->AcceptDrop( rEvt, rTargetHelper, nLayer ) : DND_ACTION_NONE );
970
0
}
971
972
sal_Int8 ViewShell::ExecuteDrop (
973
    const ExecuteDropEvent& rEvt,
974
    DropTargetHelper& /*rTargetHelper*/,
975
    ::sd::Window* pTargetWindow,
976
    sal_uInt16 nPage,
977
    SdrLayerID nLayer)
978
0
{
979
0
    ::sd::View* pView = GetView();
980
0
    return pView ? pView->ExecuteDrop( rEvt, pTargetWindow, nPage, nLayer ) : DND_ACTION_NONE;
981
0
}
982
983
void ViewShell::WriteUserDataSequence ( css::uno::Sequence < css::beans::PropertyValue >& rSequence )
984
0
{
985
0
    const sal_Int32 nIndex = rSequence.getLength();
986
0
    rSequence.realloc( nIndex + 2 );
987
0
    auto pSequence = rSequence.getArray();
988
989
0
    OSL_ASSERT (GetViewShell()!=nullptr);
990
    // Get the view id from the view shell in the center pane.  This will
991
    // usually be the called view shell, but to be on the safe side we call
992
    // the main view shell explicitly.
993
0
    SfxInterfaceId nViewID (IMPRESS_FACTORY_ID);
994
0
    if (auto pViewShell = GetViewShellBase().GetMainViewShell().get())
995
0
        nViewID = pViewShell->mpImpl->GetViewId();
996
0
    pSequence[nIndex].Name = sUNO_View_ViewId;
997
0
    pSequence[nIndex].Value <<= "view" + OUString::number( static_cast<sal_uInt16>(nViewID));
998
999
0
    pSequence[nIndex].Name = u"WindowState"_ustr;
1000
0
    pSequence[nIndex].Value <<= ::framework::WindowStateHelper::GetFromWindow(GetViewShellBase().GetWindow());
1001
1002
0
    mpFrameView->WriteUserDataSequence( rSequence );
1003
0
}
1004
1005
void ViewShell::ReadUserDataSequence ( const css::uno::Sequence < css::beans::PropertyValue >& rSequence )
1006
0
{
1007
0
    mpFrameView->ReadUserDataSequence( rSequence );
1008
0
}
1009
1010
void ViewShell::VisAreaChanged(const ::tools::Rectangle& /*rRect*/)
1011
0
{
1012
0
    OSL_ASSERT (GetViewShell()!=nullptr);
1013
0
    GetViewShell()->VisAreaChanged();
1014
0
}
1015
1016
void ViewShell::SetWinViewPos(const Point& rWinPos)
1017
0
{
1018
0
    if (mpContentWindow)
1019
0
    {
1020
0
        mpContentWindow->SetWinViewPos(rWinPos);
1021
1022
0
        mpContentWindow->UpdateMapOrigin();
1023
0
        mpContentWindow->Invalidate();
1024
0
    }
1025
1026
0
    if (mbHasRulers)
1027
0
    {
1028
0
        UpdateHRuler();
1029
0
        UpdateVRuler();
1030
0
    }
1031
1032
0
    UpdateScrollBars();
1033
1034
0
    Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
1035
0
    ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) );
1036
0
    VisAreaChanged(aVisAreaWin);
1037
1038
0
    ::sd::View* pView = GetView();
1039
0
    if (pView)
1040
0
    {
1041
0
        pView->VisAreaChanged(GetActiveWindow()->GetOutDev());
1042
0
    }
1043
0
}
1044
1045
Point const & ViewShell::GetWinViewPos() const
1046
0
{
1047
0
    return mpContentWindow->GetWinViewPos();
1048
0
}
1049
1050
Point const & ViewShell::GetViewOrigin() const
1051
0
{
1052
0
    return mpContentWindow->GetViewOrigin();
1053
0
}
1054
1055
} // end of namespace sd
1056
1057
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */