Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/sw/source/uibase/uiview/pview.cxx
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <config_wasm_strip.h>
21
22
#include <sfx2/objface.hxx>
23
#include <vcl/help.hxx>
24
#include <vcl/commandevent.hxx>
25
#include <vcl/settings.hxx>
26
#include <vcl/svapp.hxx>
27
#include <vcl/syswin.hxx>
28
#include <vcl/weld.hxx>
29
30
#include <svl/whiter.hxx>
31
#include <svl/slstitm.hxx>
32
#include <svl/eitem.hxx>
33
#include <sfx2/printer.hxx>
34
#include <sfx2/bindings.hxx>
35
#include <sfx2/request.hxx>
36
#include <sfx2/dispatch.hxx>
37
#include <editeng/paperinf.hxx>
38
#include <svx/svdview.hxx>
39
#include <svx/viewlayoutitem.hxx>
40
#include <svx/zoomslideritem.hxx>
41
#include <tools/svborder.hxx>
42
#include <osl/diagnose.h>
43
44
#include <globdoc.hxx>
45
#include <wdocsh.hxx>
46
#include <pvprtdat.hxx>
47
#include <swmodule.hxx>
48
#include <wrtsh.hxx>
49
#include <docsh.hxx>
50
#include <viewopt.hxx>
51
#include <doc.hxx>
52
#include <IDocumentDeviceAccess.hxx>
53
#include <pview.hxx>
54
#include <view.hxx>
55
#include <scroll.hxx>
56
#include <prtopt.hxx>
57
#include <usrpref.hxx>
58
#include "viewfunc.hxx"
59
60
#include <helpids.h>
61
#include <cmdid.h>
62
#include <strings.hrc>
63
64
#define ShellClass_SwPagePreview
65
#include <sfx2/msg.hxx>
66
#include <swslots.hxx>
67
#include <pagepreviewlayout.hxx>
68
69
#include <svx/svxdlg.hxx>
70
71
#include <memory>
72
#include <vcl/EnumContext.hxx>
73
#include <vcl/notebookbar/notebookbar.hxx>
74
75
using namespace ::com::sun::star;
76
SFX_IMPL_NAMED_VIEWFACTORY(SwPagePreview, "PrintPreview")
77
0
{
78
0
    SFX_VIEW_REGISTRATION(SwDocShell);
79
0
    SFX_VIEW_REGISTRATION(SwWebDocShell);
80
0
    SFX_VIEW_REGISTRATION(SwGlobalDocShell);
81
0
}
82
83
SFX_IMPL_INTERFACE(SwPagePreview, SfxViewShell)
84
85
void SwPagePreview::InitInterface_Impl()
86
9
{
87
9
    GetStaticInterface()->RegisterPopupMenu(u"preview"_ustr);
88
9
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT,
89
9
                                            SfxVisibilityFlags::Standard|SfxVisibilityFlags::Client|SfxVisibilityFlags::FullScreen|SfxVisibilityFlags::ReadonlyDoc,
90
9
                                            ToolbarId::PView_Toolbox);
91
9
}
92
93
94
0
#define SWVIEWFLAGS SfxViewShellFlags::HAS_PRINTOPTIONS
95
96
0
#define MIN_PREVIEW_ZOOM 25
97
0
#define MAX_PREVIEW_ZOOM 600
98
99
static sal_uInt16 lcl_GetNextZoomStep(sal_uInt16 nCurrentZoom, bool bZoomIn)
100
0
{
101
0
    static const sal_uInt16 aZoomArr[] =
102
0
    {
103
0
        25, 50, 75, 100, 150, 200, 400, 600
104
0
    };
105
0
    const int nZoomArrSize = static_cast<int>(SAL_N_ELEMENTS(aZoomArr));
106
0
    if (bZoomIn)
107
0
    {
108
0
        for(sal_uInt16 i : aZoomArr)
109
0
        {
110
0
            if(nCurrentZoom < i)
111
0
                return i;
112
0
        }
113
0
    }
114
0
    else
115
0
    {
116
0
        for(int i = nZoomArrSize - 1; i >= 0; --i)
117
0
        {
118
0
            if(nCurrentZoom > aZoomArr[i] || !i)
119
0
                return aZoomArr[i];
120
0
        }
121
0
    }
122
0
    return bZoomIn ? MAX_PREVIEW_ZOOM : MIN_PREVIEW_ZOOM;
123
0
};
124
125
static void lcl_InvalidateZoomSlots(SfxBindings& rBindings)
126
0
{
127
0
    static sal_uInt16 const aInval[] =
128
0
    {
129
0
        SID_ATTR_ZOOM, SID_ZOOM_OUT, SID_ZOOM_IN, SID_ATTR_ZOOMSLIDER, FN_PREVIEW_ZOOM, FN_STAT_ZOOM,
130
0
        0
131
0
    };
132
0
    rBindings.Invalidate( aInval );
133
0
}
134
135
namespace {
136
137
// At first the zoom dialog
138
class SwPreviewZoomDlg : public weld::GenericDialogController
139
{
140
    SwPagePreviewWin& m_rParent;
141
    std::unique_ptr<weld::SpinButton> m_xRowEdit;
142
    std::unique_ptr<weld::SpinButton> m_xColEdit;
143
144
public:
145
    SwPreviewZoomDlg(SwPagePreviewWin& rParent)
146
0
        : GenericDialogController(rParent.GetFrameWeld(), u"modules/swriter/ui/previewzoomdialog.ui"_ustr, u"PreviewZoomDialog"_ustr)
147
0
        , m_rParent(rParent)
148
0
        , m_xRowEdit(m_xBuilder->weld_spin_button(u"rows"_ustr))
149
0
        , m_xColEdit(m_xBuilder->weld_spin_button(u"cols"_ustr))
150
0
    {
151
0
        m_xRowEdit->set_value(rParent.GetRow());
152
0
        m_xColEdit->set_value(rParent.GetCol());
153
0
    }
154
155
    void execute()
156
0
    {
157
0
        if (run() == RET_OK)
158
0
        {
159
0
            m_rParent.CalcWish(m_xRowEdit->get_value(), m_xColEdit->get_value());
160
0
        }
161
0
    }
162
};
163
164
}
165
166
// all for SwPagePreviewWin
167
SwPagePreviewWin::SwPagePreviewWin( vcl::Window *pParent, SwPagePreview& rPView )
168
0
    : Window(pParent, WinBits(WB_CLIPCHILDREN))
169
0
    , mpViewShell(nullptr)
170
0
    , mrView(rPView)
171
0
    , mbCalcScaleForPreviewLayout(true)
172
0
    , maPaintedPreviewDocRect(tools::Rectangle(0,0,0,0))
173
0
    , mpPgPreviewLayout(nullptr)
174
0
{
175
0
    GetOutDev()->SetOutDevViewType( OutDevViewType::PrintPreview );
176
0
    SetHelpId(HID_PAGEPREVIEW);
177
0
    GetOutDev()->SetFillColor( GetBackground().GetColor() );
178
0
    GetOutDev()->SetLineColor( GetBackground().GetColor());
179
0
    SetMapMode( MapMode(MapUnit::MapTwip) );
180
181
0
    const SwMasterUsrPref* pUsrPref = SwModule::get()->GetUsrPref(false);
182
0
    mnRow = pUsrPref->GetPagePrevRow();     // 1 row
183
0
    mnCol = pUsrPref->GetPagePrevCol();     // 1 column
184
0
    mnSttPage = USHRT_MAX;
185
0
}
Unexecuted instantiation: SwPagePreviewWin::SwPagePreviewWin(vcl::Window*, SwPagePreview&)
Unexecuted instantiation: SwPagePreviewWin::SwPagePreviewWin(vcl::Window*, SwPagePreview&)
186
187
SwPagePreviewWin::~SwPagePreviewWin()
188
0
{
189
0
}
190
191
void  SwPagePreviewWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
192
0
{
193
0
    if (!mpViewShell || !mpViewShell->GetLayout())
194
0
        return;
195
196
0
    if (USHRT_MAX == mnSttPage)        // was never calculated ? (Init-Phase!)
197
0
    {
198
        // This is the size to which I always relate.
199
0
        if (!maPxWinSize.Height() || !maPxWinSize.Width())
200
0
            maPxWinSize = GetOutputSizePixel();
201
202
0
        tools::Rectangle aRect(rRenderContext.LogicToPixel(rRect));
203
0
        mpPgPreviewLayout->Prepare(1, Point(0,0), maPxWinSize,
204
0
                                   mnSttPage, maPaintedPreviewDocRect);
205
0
        SetSelectedPage(1);
206
0
        mpPgPreviewLayout->Paint(rRenderContext, rRenderContext.PixelToLogic(aRect));
207
0
        SetPagePreview(mnRow, mnCol);
208
0
    }
209
0
    else
210
0
    {
211
0
        MapMode aMM(rRenderContext.GetMapMode());
212
0
        aMM.SetScaleX(maScale);
213
0
        aMM.SetScaleY(maScale);
214
0
        rRenderContext.SetMapMode(aMM);
215
0
        mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(true);
216
0
        mpPgPreviewLayout->Paint(rRenderContext, rRect);
217
0
        mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(false);
218
0
    }
219
0
}
220
221
void SwPagePreviewWin::CalcWish( sal_Int16 nNewRow, sal_Int16 nNewCol )
222
0
{
223
0
    if( !mpViewShell || !mpViewShell->GetLayout() )
224
0
        return;
225
226
0
    const sal_Int16 nOldCol = mnCol;
227
0
    mnRow = nNewRow;
228
0
    mnCol = nNewCol;
229
0
    const sal_uInt16 nPages = mnRow * mnCol;
230
0
    const sal_uInt16 nLastSttPg = mrView.GetPageCount()+1 > nPages
231
0
                            ? mrView.GetPageCount()+1 - nPages : 0;
232
0
    if( mnSttPage > nLastSttPg )
233
0
        mnSttPage = nLastSttPg;
234
235
0
    mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
236
0
    mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
237
0
                              mnSttPage, maPaintedPreviewDocRect );
238
0
    SetSelectedPage( mnSttPage );
239
0
    SetPagePreview(mnRow, mnCol);
240
0
    maScale = GetMapMode().GetScaleX();
241
242
    // If changes have taken place at the columns, the special case "single column"
243
    // must be considered and corrected if necessary.
244
0
    if( (1 == nOldCol) != (1 == mnCol) )
245
0
        mrView.ScrollDocSzChg();
246
247
    // Order must be maintained!
248
    // additional invalidate page status.
249
0
    static sal_uInt16 aInval[] =
250
0
    {
251
0
        SID_ATTR_ZOOM, SID_ZOOM_OUT, SID_ZOOM_IN,
252
0
        FN_PREVIEW_ZOOM,
253
0
        FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
254
0
        FN_STAT_PAGE, FN_STAT_ZOOM,
255
0
        FN_SHOW_TWO_PAGES, FN_SHOW_MULTIPLE_PAGES,
256
0
        0
257
0
    };
258
0
    SfxBindings& rBindings = mrView.GetViewFrame().GetBindings();
259
0
    rBindings.Invalidate( aInval );
260
0
    rBindings.Update( FN_SHOW_TWO_PAGES );
261
0
    rBindings.Update( FN_SHOW_MULTIPLE_PAGES );
262
    // adjust scrollbars
263
0
    mrView.ScrollViewSzChg();
264
0
}
265
266
// mnSttPage is Absolute
267
bool SwPagePreviewWin::MovePage( int eMoveMode )
268
0
{
269
    // number of pages up
270
0
    const sal_uInt16 nPages = mnRow * mnCol;
271
0
    sal_uInt16 nNewSttPage = mnSttPage;
272
0
    const sal_uInt16 nPageCount = mrView.GetPageCount();
273
0
    const sal_uInt16 nDefSttPg = GetDefSttPage();
274
0
    bool bPaintPageAtFirstCol = true;
275
276
0
    switch( eMoveMode )
277
0
    {
278
0
    case MV_PAGE_UP:
279
0
    {
280
0
        const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage );
281
0
        const sal_uInt16 nNewAbsSttPage = nRelSttPage - nPages > 0 ?
282
0
                                          mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage - nPages ) :
283
0
                                          nDefSttPg;
284
0
        nNewSttPage = nNewAbsSttPage;
285
286
0
        const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() );
287
0
        const sal_uInt16 nNewRelSelPage = nRelSelPage - nPages > 0 ?
288
0
                                          nRelSelPage - nPages :
289
0
                                          1;
290
0
        SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewRelSelPage ) );
291
292
0
        break;
293
0
    }
294
0
    case MV_PAGE_DOWN:
295
0
    {
296
0
        const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage );
297
0
        const sal_uInt16 nNewAbsSttPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage + nPages );
298
0
        nNewSttPage = std::min(nNewAbsSttPage, nPageCount);
299
300
0
        const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() );
301
0
        const sal_uInt16 nNewAbsSelPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSelPage + nPages );
302
0
        SetSelectedPage( std::min(nNewAbsSelPage, nPageCount) );
303
304
0
        break;
305
0
    }
306
0
    case MV_DOC_STT:
307
0
        nNewSttPage = nDefSttPg;
308
0
        SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewSttPage ? nNewSttPage : 1 ) );
309
0
        break;
310
0
    case MV_DOC_END:
311
        // correct calculation of new start page.
312
0
        nNewSttPage = nPageCount;
313
0
        SetSelectedPage( nPageCount );
314
0
        break;
315
316
0
    case MV_SELPAGE:
317
        // <nNewSttPage> and <SelectedPage()> are already set.
318
        // not start at first column, only if the
319
        // complete preview layout columns doesn't fit into window.
320
0
        if ( !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() )
321
0
            bPaintPageAtFirstCol = false;
322
0
        break;
323
0
    case MV_SCROLL:
324
        // check, if paint page at first column
325
        // has to be avoided
326
0
        if ( !mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() ||
327
0
             !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() )
328
0
            bPaintPageAtFirstCol = false;
329
0
        break;
330
0
    case MV_NEWWINSIZE:
331
        // nothing special to do.
332
0
        break;
333
0
    case MV_CALC:
334
        // re-init page preview layout.
335
0
        mpPgPreviewLayout->ReInit();
336
337
        // correct calculation of new start page.
338
0
        if( nNewSttPage > nPageCount )
339
0
            nNewSttPage = nPageCount;
340
341
        // correct selected page number
342
0
        if( SelectedPage() > nPageCount )
343
0
            SetSelectedPage( nNewSttPage ? nNewSttPage : 1 );
344
0
    }
345
346
0
    mpPgPreviewLayout->Prepare( nNewSttPage, Point(0,0), maPxWinSize,
347
0
                              nNewSttPage,
348
0
                              maPaintedPreviewDocRect, bPaintPageAtFirstCol );
349
0
    if( nNewSttPage == mnSttPage &&
350
0
        eMoveMode != MV_SELPAGE )
351
0
        return false;
352
353
0
    SetPagePreview(mnRow, mnCol);
354
0
    mnSttPage = nNewSttPage;
355
356
    // additional invalidate page status.
357
0
    static sal_uInt16 aInval[] =
358
0
    {
359
0
        FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
360
0
        FN_STAT_PAGE, 0
361
0
    };
362
363
0
    SfxBindings& rBindings = mrView.GetViewFrame().GetBindings();
364
0
    rBindings.Invalidate( aInval );
365
366
0
    return true;
367
0
}
368
369
void SwPagePreviewWin::SetWinSize( const Size& rNewSize )
370
0
{
371
    // We always want the size as pixel units.
372
0
    maPxWinSize = LogicToPixel( rNewSize );
373
374
0
    if( USHRT_MAX == mnSttPage )
375
0
    {
376
0
        mnSttPage = GetDefSttPage();
377
0
        SetSelectedPage( GetDefSttPage() );
378
0
    }
379
380
0
    if ( mbCalcScaleForPreviewLayout )
381
0
    {
382
0
        mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
383
0
        maScale = GetMapMode().GetScaleX();
384
0
    }
385
0
    mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
386
0
                              mnSttPage, maPaintedPreviewDocRect );
387
0
    if ( mbCalcScaleForPreviewLayout )
388
0
    {
389
0
        SetSelectedPage( mnSttPage );
390
0
        mbCalcScaleForPreviewLayout = false;
391
0
    }
392
0
    SetPagePreview(mnRow, mnCol);
393
0
    maScale = GetMapMode().GetScaleX();
394
0
}
395
396
OUString SwPagePreviewWin::GetStatusStr( sal_uInt16 nPageCnt ) const
397
0
{
398
    // show physical and virtual page number of
399
    // selected page, if it's visible.
400
0
    const sal_uInt16 nPageNum = mpPgPreviewLayout->IsPageVisible( mpPgPreviewLayout->SelectedPage() )
401
0
        ? mpPgPreviewLayout->SelectedPage() : std::max<sal_uInt16>(mnSttPage, 1);
402
403
0
    OUString aStatusStr;
404
0
    const sal_uInt16 nVirtPageNum = mpPgPreviewLayout->GetVirtPageNumByPageNum( nPageNum );
405
0
    if( nVirtPageNum && nVirtPageNum != nPageNum )
406
0
    {
407
0
        aStatusStr = OUString::number(nVirtPageNum) + " " ;
408
0
    }
409
0
    return aStatusStr + OUString::number(nPageNum) + " / " + OUString::number(nPageCnt);
410
0
}
411
412
void  SwPagePreviewWin::KeyInput( const KeyEvent &rKEvt )
413
0
{
414
0
    const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
415
0
    bool bHandled = false;
416
0
    if(!rKeyCode.GetModifier())
417
0
    {
418
0
        sal_uInt16 nSlot = 0;
419
0
        switch(rKeyCode.GetCode())
420
0
        {
421
0
            case KEY_ADD : nSlot = SID_ZOOM_IN;         break;
422
0
            case KEY_ESCAPE: nSlot = FN_CLOSE_PAGEPREVIEW; break;
423
0
            case KEY_SUBTRACT : nSlot = SID_ZOOM_OUT;    break;
424
0
        }
425
0
        if(nSlot)
426
0
        {
427
0
            bHandled = true;
428
0
            mrView.GetViewFrame().GetDispatcher()->Execute(
429
0
                                nSlot, SfxCallMode::ASYNCHRON );
430
0
        }
431
0
    }
432
0
    if( !bHandled && !mrView.KeyInput( rKEvt ) )
433
0
        Window::KeyInput( rKEvt );
434
0
}
435
436
void SwPagePreviewWin::Command( const CommandEvent& rCEvt )
437
0
{
438
0
    bool bCallBase = true;
439
0
    switch( rCEvt.GetCommand() )
440
0
    {
441
0
        case CommandEventId::ContextMenu:
442
0
            SfxDispatcher::ExecutePopup();
443
0
            bCallBase = false;
444
0
        break;
445
446
0
        case CommandEventId::Wheel:
447
0
        case CommandEventId::StartAutoScroll:
448
0
        case CommandEventId::AutoScroll:
449
0
        {
450
0
            const CommandWheelData* pData = rCEvt.GetWheelData();
451
0
            if( pData )
452
0
            {
453
0
                const CommandWheelData aDataNew(pData->GetDelta(),pData->GetNotchDelta(),COMMAND_WHEEL_PAGESCROLL,
454
0
                    pData->GetMode(),pData->GetModifier(),pData->IsHorz(), pData->IsDeltaPixel());
455
0
                const CommandEvent aEvent( rCEvt.GetMousePosPixel(),rCEvt.GetCommand(),rCEvt.IsMouseEvent(),&aDataNew);
456
0
                bCallBase = !mrView.HandleWheelCommands( aEvent );
457
0
            }
458
0
            else
459
0
                bCallBase = !mrView.HandleWheelCommands( rCEvt );
460
0
       }
461
0
       break;
462
0
       default:
463
0
           ;
464
0
    }
465
466
0
    if( bCallBase )
467
0
        Window::Command( rCEvt );
468
0
}
469
470
void SwPagePreviewWin::MouseButtonDown( const MouseEvent& rMEvt )
471
0
{
472
    // consider single-click to set selected page
473
0
    if( MOUSE_LEFT != ( rMEvt.GetModifier() + rMEvt.GetButtons() ) )
474
0
        return;
475
476
0
    Point aPreviewPos( PixelToLogic( rMEvt.GetPosPixel() ) );
477
0
    Point aDocPos;
478
0
    bool bPosInEmptyPage;
479
0
    sal_uInt16 nNewSelectedPage;
480
0
    bool bIsDocPos =
481
0
        mpPgPreviewLayout->IsPreviewPosInDocPreviewPage( aPreviewPos,
482
0
                                aDocPos, bPosInEmptyPage, nNewSelectedPage );
483
0
    if ( bIsDocPos && rMEvt.GetClicks() == 2 )
484
0
    {
485
        // close page preview, set new cursor position and switch to
486
        // normal view.
487
0
        OUString sNewCursorPos = OUString::number( aDocPos.X() ) + ";" +
488
0
                               OUString::number( aDocPos.Y() ) + ";";
489
0
        mrView.SetNewCursorPos( sNewCursorPos );
490
491
0
        SfxViewFrame& rTmpFrame = mrView.GetViewFrame();
492
0
        rTmpFrame.GetBindings().Execute( SID_VIEWSHELL0, nullptr,
493
0
                                                SfxCallMode::ASYNCHRON );
494
0
    }
495
0
    else if ( bIsDocPos || bPosInEmptyPage )
496
0
    {
497
        // show clicked page as the selected one
498
0
        mpPgPreviewLayout->MarkNewSelectedPage( nNewSelectedPage );
499
0
        GetViewShell()->ShowPreviewSelection( nNewSelectedPage );
500
        // adjust position at vertical scrollbar.
501
0
        if ( mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() )
502
0
        {
503
0
            mrView.SetVScrollbarThumbPos( nNewSelectedPage );
504
0
        }
505
        // invalidate page status.
506
0
        static sal_uInt16 aInval[] =
507
0
        {
508
0
            FN_STAT_PAGE, 0
509
0
        };
510
0
        SfxBindings& rBindings = mrView.GetViewFrame().GetBindings();
511
0
        rBindings.Invalidate( aInval );
512
0
    }
513
0
}
514
515
// Set user prefs or view options
516
517
void SwPagePreviewWin::SetPagePreview( sal_Int16 nRow, sal_Int16 nCol )
518
0
{
519
0
    SwMasterUsrPref* pOpt = const_cast<SwMasterUsrPref*>(SwModule::get()->GetUsrPref(false));
520
521
0
    if (nRow != pOpt->GetPagePrevRow() || nCol != pOpt->GetPagePrevCol())
522
0
    {
523
0
        pOpt->SetPagePrevRow( nRow );
524
0
        pOpt->SetPagePrevCol( nCol );
525
0
        pOpt->SetModified();
526
527
        // Update scrollbar!
528
0
        mrView.ScrollViewSzChg();
529
0
    }
530
0
}
531
532
/** get selected page in document preview */
533
sal_uInt16 SwPagePreviewWin::SelectedPage() const
534
0
{
535
0
    return mpPgPreviewLayout->SelectedPage();
536
0
}
537
538
/** set selected page number in document preview */
539
void SwPagePreviewWin::SetSelectedPage( sal_uInt16 _nSelectedPageNum )
540
0
{
541
0
    mpPgPreviewLayout->SetSelectedPage( _nSelectedPageNum );
542
0
}
543
544
/** method to enable/disable book preview */
545
bool SwPagePreviewWin::SetBookPreviewMode( const bool _bBookPreview )
546
0
{
547
0
    return mpPgPreviewLayout->SetBookPreviewMode( _bBookPreview,
548
0
                                                mnSttPage,
549
0
                                                maPaintedPreviewDocRect );
550
0
}
551
552
void SwPagePreviewWin::DataChanged( const DataChangedEvent& rDCEvt )
553
0
{
554
0
    Window::DataChanged( rDCEvt );
555
556
0
    switch( rDCEvt.GetType() )
557
0
    {
558
0
    case DataChangedEventType::SETTINGS:
559
        // Rearrange the scrollbars or trigger resize, because the
560
        // size of the scrollbars may have be changed. Also the
561
        // size of the scrollbars has to be retrieved from the settings
562
        // out of the resize handler.
563
0
        if( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
564
0
            mrView.InvalidateBorder();              // Scrollbar widths
565
        // zoom has to be disabled if Accessibility support is switched on
566
0
        lcl_InvalidateZoomSlots(mrView.GetViewFrame().GetBindings());
567
0
        break;
568
569
0
    case DataChangedEventType::PRINTER:
570
0
    case DataChangedEventType::DISPLAY:
571
0
    case DataChangedEventType::FONTS:
572
0
    case DataChangedEventType::FONTSUBSTITUTION:
573
0
        mrView.GetDocShell()->UpdateFontList(); // Font change
574
0
        mpViewShell->InvalidateLayout(true);
575
0
        if ( mpViewShell->GetWin() )
576
0
            mpViewShell->GetWin()->Invalidate();
577
0
        break;
578
0
    default: break;
579
0
    }
580
0
}
581
582
void SwPagePreviewWin::ReInit()
583
0
{
584
0
    mpPgPreviewLayout->ReInit();
585
0
}
586
/** help method to execute SfxRequest FN_PAGEUP and FN_PAGEDOWN */
587
void SwPagePreview::ExecPgUpAndPgDown( const bool  _bPgUp,
588
                                        SfxRequest* _pReq )
589
0
{
590
0
    SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
591
    // check, if top/bottom of preview is *not* already visible.
592
0
    if( pPagePreviewLay->GetWinPagesScrollAmount( _bPgUp ? -1 : 1 ) != 0 )
593
0
    {
594
0
        if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() &&
595
0
             pPagePreviewLay->DoesPreviewLayoutColsFitIntoWindow() )
596
0
        {
597
0
            const int eMvMode = _bPgUp ?
598
0
                                SwPagePreviewWin::MV_PAGE_UP :
599
0
                                SwPagePreviewWin::MV_PAGE_DOWN;
600
0
            if ( ChgPage( eMvMode ) )
601
0
                m_pViewWin->Invalidate();
602
0
        }
603
0
        else
604
0
        {
605
0
            SwTwips nScrollAmount;
606
0
            sal_uInt16 nNewSelectedPageNum = 0;
607
0
            const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol();
608
0
            if( _bPgUp )
609
0
            {
610
0
                if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
611
0
                {
612
0
                    nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( -1 );
613
0
                    if ( (m_pViewWin->SelectedPage() - nVisPages) > 0 )
614
0
                        nNewSelectedPageNum = m_pViewWin->SelectedPage() - nVisPages;
615
0
                    else
616
0
                        nNewSelectedPageNum = 1;
617
0
                }
618
0
                else
619
0
                    nScrollAmount = - std::min( m_pViewWin->GetOutDev()->GetOutputSize().Height(),
620
0
                                           m_pViewWin->GetPaintedPreviewDocRect().Top() );
621
0
            }
622
0
            else
623
0
            {
624
0
                if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
625
0
                {
626
0
                    nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( 1 );
627
0
                    if ( (m_pViewWin->SelectedPage() + nVisPages) <= mnPageCount )
628
0
                        nNewSelectedPageNum = m_pViewWin->SelectedPage() + nVisPages;
629
0
                    else
630
0
                        nNewSelectedPageNum = mnPageCount;
631
0
                }
632
0
                else
633
0
                    nScrollAmount = std::min( m_pViewWin->GetOutDev()->GetOutputSize().Height(),
634
0
                                         ( pPagePreviewLay->GetPreviewDocSize().Height() -
635
0
                                           m_pViewWin->GetPaintedPreviewDocRect().Bottom() ) );
636
0
            }
637
0
            m_pViewWin->Scroll( 0, nScrollAmount );
638
0
            if ( nNewSelectedPageNum != 0 )
639
0
            {
640
0
                m_pViewWin->SetSelectedPage( nNewSelectedPageNum );
641
0
            }
642
0
            ScrollViewSzChg();
643
            // additional invalidate page status.
644
0
            static sal_uInt16 aInval[] =
645
0
            {
646
0
                FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
647
0
                FN_STAT_PAGE, 0
648
0
            };
649
0
            SfxBindings& rBindings = GetViewFrame().GetBindings();
650
0
            rBindings.Invalidate( aInval );
651
0
            m_pViewWin->Invalidate();
652
0
        }
653
0
    }
654
655
0
    if ( _pReq )
656
0
        _pReq->Done();
657
0
}
658
659
// Then all for the SwPagePreview
660
void  SwPagePreview::Execute( SfxRequest &rReq )
661
0
{
662
0
    int eMvMode = SwPagePreviewWin::MV_DOC_END;
663
0
    sal_Int16 nRow = 1;
664
0
    bool bRefresh = true;
665
666
0
    switch(rReq.GetSlot())
667
0
    {
668
0
        case SID_REFRESH_VIEW:
669
0
        case FN_STAT_PAGE:
670
0
        case FN_STAT_ZOOM:
671
0
            break;
672
673
0
        case FN_SHOW_MULTIPLE_PAGES:
674
0
        {
675
0
            const SfxItemSet *pArgs = rReq.GetArgs();
676
0
            if( pArgs && pArgs->Count() >= 2 )
677
0
            {
678
0
                sal_Int16 nCols = pArgs->Get(SID_ATTR_TABLE_COLUMN).GetValue();
679
0
                sal_Int16 nRows = pArgs->Get(SID_ATTR_TABLE_ROW).GetValue();
680
0
                m_pViewWin->CalcWish( nRows, nCols );
681
682
0
            }
683
0
            else
684
0
            {
685
0
                SwPreviewZoomDlg aDlg(*m_pViewWin);
686
0
                aDlg.execute();
687
0
            }
688
0
        }
689
0
        break;
690
0
        case FN_SHOW_BOOKVIEW:
691
0
        {
692
0
            const SfxItemSet* pArgs = rReq.GetArgs();
693
0
            const SfxPoolItem* pItem;
694
0
            bool bBookPreview = GetViewShell()->GetViewOptions()->IsPagePrevBookview();
695
0
            if( pArgs && SfxItemState::SET == pArgs->GetItemState( FN_SHOW_BOOKVIEW, false, &pItem ) )
696
0
            {
697
0
                bBookPreview = static_cast< const SfxBoolItem* >( pItem )->GetValue();
698
0
                const_cast<SwViewOption*>(GetViewShell()->GetViewOptions())->SetPagePrevBookview( bBookPreview );
699
                    // cast is not gentleman like, but it's common use in writer and in this case
700
0
            }
701
0
            if ( m_pViewWin->SetBookPreviewMode( bBookPreview ) )
702
0
            {
703
                // book preview mode changed. Thus, adjust scrollbars and
704
                // invalidate corresponding states.
705
0
                ScrollViewSzChg();
706
0
                static sal_uInt16 aInval[] =
707
0
                {
708
0
                    FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
709
0
                    FN_STAT_PAGE, FN_SHOW_BOOKVIEW, 0
710
0
                };
711
0
                SfxBindings& rBindings = GetViewFrame().GetBindings();
712
0
                rBindings.Invalidate( aInval );
713
0
                m_pViewWin->Invalidate();
714
0
            }
715
716
0
        }
717
0
        break;
718
0
        case FN_SHOW_TWO_PAGES:
719
0
            m_pViewWin->CalcWish( nRow, 2 );
720
0
            break;
721
722
0
        case FN_SHOW_SINGLE_PAGE:
723
0
            m_pViewWin->CalcWish( nRow, 1 );
724
0
            break;
725
726
0
        case FN_PREVIEW_ZOOM:
727
0
        case SID_ATTR_ZOOM:
728
0
        {
729
0
            const SfxItemSet *pArgs = rReq.GetArgs();
730
0
            ScopedVclPtr<AbstractSvxZoomDialog> pDlg;
731
0
            if(!pArgs)
732
0
            {
733
0
                SfxItemSetFixed<SID_ATTR_ZOOM, SID_ATTR_ZOOM> aCoreSet(GetPool());
734
0
                const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
735
0
                SvxZoomItem aZoom( pVOpt->GetZoomType(), pVOpt->GetZoom() );
736
0
                aZoom.SetValueSet(
737
0
                        SvxZoomEnableFlags::N50|
738
0
                        SvxZoomEnableFlags::N75|
739
0
                        SvxZoomEnableFlags::N100|
740
0
                        SvxZoomEnableFlags::N150|
741
0
                        SvxZoomEnableFlags::N200|
742
0
                        SvxZoomEnableFlags::WHOLEPAGE);
743
0
                aCoreSet.Put( aZoom );
744
745
0
                SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
746
0
                pDlg.disposeAndReset(pFact->CreateSvxZoomDialog(GetViewFrame().GetFrameWeld(), aCoreSet));
747
0
                pDlg->SetLimits( MINZOOM, MAXZOOM );
748
749
0
                if( pDlg->Execute() != RET_CANCEL )
750
0
                    pArgs = pDlg->GetOutputItemSet();
751
0
            }
752
0
            if( pArgs )
753
0
            {
754
0
                SvxZoomType eType = SvxZoomType::PERCENT;
755
0
                sal_uInt16 nZoomFactor = USHRT_MAX;
756
0
                if(const SvxZoomItem* pZoomItem = pArgs->GetItemIfSet(SID_ATTR_ZOOM))
757
0
                {
758
0
                    eType = pZoomItem->GetType();
759
0
                    nZoomFactor = pZoomItem->GetValue();
760
0
                }
761
0
                else if(const SfxUInt16Item* pPreviewItem = pArgs->GetItemIfSet(FN_PREVIEW_ZOOM))
762
0
                    nZoomFactor = pPreviewItem->GetValue();
763
0
                if(USHRT_MAX != nZoomFactor)
764
0
                    SetZoom(eType, nZoomFactor);
765
0
            }
766
0
        }
767
0
        break;
768
0
        case SID_ATTR_ZOOMSLIDER :
769
0
        {
770
0
            const SfxItemSet *pArgs = rReq.GetArgs();
771
0
            const SvxZoomSliderItem* pItem;
772
773
0
            if ( pArgs && (pItem = pArgs->GetItemIfSet(SID_ATTR_ZOOMSLIDER ) ) )
774
0
            {
775
0
                const sal_uInt16 nCurrentZoom = pItem->GetValue();
776
0
                SetZoom( SvxZoomType::PERCENT, nCurrentZoom );
777
0
            }
778
0
        }
779
0
        break;
780
0
        case SID_ZOOM_IN:
781
0
        case SID_ZOOM_OUT:
782
0
        {
783
0
            const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
784
0
            SetZoom(SvxZoomType::PERCENT,
785
0
                    lcl_GetNextZoomStep(pVOpt->GetZoom(), SID_ZOOM_IN == rReq.GetSlot()));
786
0
        }
787
0
        break;
788
0
        case FN_CHAR_LEFT:
789
0
        case FN_CHAR_RIGHT:
790
0
        case FN_LINE_UP:
791
0
        case FN_LINE_DOWN:
792
0
        {
793
0
            SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
794
0
            sal_uInt16 nNewSelectedPage;
795
0
            sal_uInt16 nNewStartPage;
796
0
            Point aNewStartPos;
797
0
            sal_Int16 nHoriMove = 0;
798
0
            sal_Int16 nVertMove = 0;
799
0
            switch(rReq.GetSlot())
800
0
            {
801
0
                case FN_CHAR_LEFT:  nHoriMove = -1; break;
802
0
                case FN_CHAR_RIGHT: nHoriMove = 1;  break;
803
0
                case FN_LINE_UP:    nVertMove = -1; break;
804
0
                case FN_LINE_DOWN:  nVertMove = 1;  break;
805
0
            }
806
0
            pPagePreviewLay->CalcStartValuesForSelectedPageMove( nHoriMove, nVertMove,
807
0
                                nNewSelectedPage, nNewStartPage, aNewStartPos );
808
0
            if ( m_pViewWin->SelectedPage() != nNewSelectedPage )
809
0
            {
810
0
                if ( pPagePreviewLay->IsPageVisible( nNewSelectedPage ) )
811
0
                {
812
0
                    pPagePreviewLay->MarkNewSelectedPage( nNewSelectedPage );
813
                    // adjust position at vertical scrollbar.
814
0
                    SetVScrollbarThumbPos( nNewSelectedPage );
815
0
                    bRefresh = false;
816
0
                }
817
0
                else
818
0
                {
819
0
                    m_pViewWin->SetSelectedPage( nNewSelectedPage );
820
0
                    m_pViewWin->SetSttPage( nNewStartPage );
821
0
                    bRefresh = ChgPage( SwPagePreviewWin::MV_SELPAGE );
822
0
                }
823
0
                GetViewShell()->ShowPreviewSelection( nNewSelectedPage );
824
                // invalidate page status.
825
0
                static sal_uInt16 aInval[] =
826
0
                {
827
0
                    FN_STAT_PAGE, 0
828
0
                };
829
0
                SfxBindings& rBindings = GetViewFrame().GetBindings();
830
0
                rBindings.Invalidate( aInval );
831
0
                rReq.Done();
832
0
            }
833
0
            else
834
0
            {
835
0
                bRefresh = false;
836
0
            }
837
0
            break;
838
0
        }
839
0
        case FN_PAGEUP:
840
0
        case FN_PAGEDOWN:
841
0
        {
842
0
            ExecPgUpAndPgDown( rReq.GetSlot() == FN_PAGEUP, &rReq );
843
0
            break;
844
0
        }
845
0
        case SID_JUMP_TO_SPECIFIC_PAGE:
846
0
        {
847
0
            const SfxItemSet *pArgs = rReq.GetArgs();
848
0
            if( pArgs && pArgs->Count())
849
0
            {
850
0
                sal_uInt16 nPageNum = static_cast<const SfxUInt16Item &>(pArgs->Get(SID_JUMP_TO_SPECIFIC_PAGE)).GetValue();
851
852
0
                if( nPageNum > 0 && nPageNum <= mnPageCount )
853
0
                {
854
0
                    m_pViewWin->SetSttPage( nPageNum);
855
0
                    m_pViewWin->SetSelectedPage( nPageNum );
856
0
                    ChgPage( SwPagePreviewWin::MV_SPECIFIC_PAGE, false );
857
0
                    ScrollViewSzChg();
858
0
                }
859
0
            }
860
0
        }
861
0
        break;
862
0
        case FN_START_OF_LINE:
863
0
        case FN_START_OF_DOCUMENT:
864
0
            eMvMode = SwPagePreviewWin::MV_DOC_STT;
865
0
            [[fallthrough]];
866
0
        case FN_END_OF_LINE:
867
0
        case FN_END_OF_DOCUMENT:
868
0
            m_pViewWin->SetSelectedPage(eMvMode == SwPagePreviewWin::MV_DOC_STT ? 1 : mnPageCount);
869
0
            {
870
0
                bool bRet = ChgPage( eMvMode );
871
                // return value for Basic
872
0
                rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), !bRet));
873
874
0
                bRefresh = bRet;
875
0
                rReq.Done();
876
0
            }
877
0
            break;
878
879
0
        case FN_PRINT_PAGEPREVIEW:
880
0
        {
881
0
            const SwPagePreviewPrtData* pPPVPD = m_pViewWin->GetViewShell()->GetDoc()->GetPreviewPrtData();
882
            // The thing with the orientation
883
0
            if(pPPVPD)
884
0
            {
885
0
                SfxPrinter* pPrinter = GetPrinter( true );
886
0
                if((pPrinter->GetOrientation() == Orientation::Landscape)
887
0
                        != pPPVPD->GetLandscape())
888
0
                    pPrinter->SetOrientation(pPPVPD->GetLandscape() ? Orientation::Landscape : Orientation::Portrait);
889
0
            }
890
0
            ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false );
891
0
            m_bNormalPrint = false;
892
0
            rReq.SetSlot( SID_PRINTDOC );
893
0
            SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
894
0
            rReq.SetSlot( FN_PRINT_PAGEPREVIEW );
895
0
            return;
896
0
        }
897
0
        case SID_PRINTDOCDIRECT:
898
0
        case SID_PRINTDOC:
899
0
            ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false );
900
0
            m_bNormalPrint = true;
901
0
            SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
902
0
            return;
903
0
        case FN_CLOSE_PAGEPREVIEW:
904
0
        case SID_PRINTPREVIEW:
905
            //  print preview is now always in the same frame as the tab view
906
            //  -> always switch this frame back to normal view
907
            //  (ScTabViewShell ctor reads stored view data)
908
0
            GetViewFrame().GetDispatcher()->Execute( SID_VIEWSHELL0, SfxCallMode::ASYNCHRON );
909
0
            break;
910
0
        case FN_INSERT_BREAK:
911
0
        {
912
0
            sal_uInt16 nSelPage = m_pViewWin->SelectedPage();
913
            //if a dummy page is selected (e.g. a non-existing right/left page)
914
            //the direct neighbor is used
915
0
            if(GetViewShell()->IsDummyPage( nSelPage ) && GetViewShell()->IsDummyPage( --nSelPage ))
916
0
                nSelPage +=2;
917
0
            m_nNewPage = nSelPage;
918
0
            SfxViewFrame& rTmpFrame = GetViewFrame();
919
0
            rTmpFrame.GetBindings().Execute( SID_VIEWSHELL0, nullptr,
920
0
                                                    SfxCallMode::ASYNCHRON );
921
0
        }
922
0
        break;
923
0
        default:
924
0
            OSL_ENSURE(false, "wrong dispatcher");
925
0
            return;
926
0
    }
927
928
0
    if( bRefresh )
929
0
        m_pViewWin->Invalidate();
930
0
}
931
932
void  SwPagePreview::GetState( SfxItemSet& rSet )
933
0
{
934
0
    SfxWhichIter aIter(rSet);
935
0
    sal_uInt16 nWhich = aIter.FirstWhich();
936
0
    OSL_ENSURE(nWhich, "empty set");
937
0
    SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
938
939
0
    while(nWhich)
940
0
    {
941
0
        switch(nWhich)
942
0
        {
943
0
        case SID_BROWSER_MODE:
944
0
        case FN_PRINT_LAYOUT:
945
0
        case FN_SINGLE_PAGE_PER_ROW:
946
0
        case FN_MULTIPLE_PAGES_PER_ROW:
947
0
        case FN_BOOKVIEW:
948
0
            rSet.DisableItem(nWhich);
949
0
            break;
950
0
        case FN_START_OF_DOCUMENT:
951
0
        {
952
0
            if ( pPagePreviewLay->IsPageVisible( 1 ) )
953
0
                rSet.DisableItem(nWhich);
954
0
            break;
955
0
        }
956
0
        case FN_END_OF_DOCUMENT:
957
0
        {
958
0
            if ( pPagePreviewLay->IsPageVisible( mnPageCount ) )
959
0
                rSet.DisableItem(nWhich);
960
0
            break;
961
0
        }
962
0
        case FN_PAGEUP:
963
0
        {
964
0
            if( pPagePreviewLay->GetWinPagesScrollAmount( -1 ) == 0 )
965
0
                rSet.DisableItem(nWhich);
966
0
            break;
967
0
        }
968
0
        case FN_PAGEDOWN:
969
0
        {
970
0
            if( pPagePreviewLay->GetWinPagesScrollAmount( 1 ) == 0 )
971
0
                rSet.DisableItem(nWhich);
972
0
            break;
973
0
        }
974
975
0
        case FN_STAT_PAGE:
976
0
            {
977
0
                std::vector<OUString> aStringList
978
0
                {
979
0
                    m_sPageStr + m_pViewWin->GetStatusStr(mnPageCount),
980
0
                    OUString()
981
0
                };
982
0
                rSet.Put(SfxStringListItem(FN_STAT_PAGE, &aStringList));
983
0
            }
984
0
            break;
985
986
0
        case SID_ATTR_ZOOM:
987
0
        case FN_STAT_ZOOM:
988
0
            {
989
0
                    const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
990
0
                    SvxZoomItem aZoom(pVOpt->GetZoomType(), pVOpt->GetZoom());
991
0
                    aZoom.SetValueSet(
992
0
                            SvxZoomEnableFlags::N50|
993
0
                            SvxZoomEnableFlags::N75|
994
0
                            SvxZoomEnableFlags::N100|
995
0
                            SvxZoomEnableFlags::N150|
996
0
                            SvxZoomEnableFlags::N200);
997
0
                    rSet.Put( aZoom );
998
0
            }
999
0
        break;
1000
0
        case SID_ATTR_ZOOMSLIDER :
1001
0
            {
1002
0
                    const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
1003
0
                    const sal_uInt16 nCurrentZoom = pVOpt->GetZoom();
1004
0
                    SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM );
1005
0
                    aZoomSliderItem.AddSnappingPoint( 100 );
1006
0
                    rSet.Put( aZoomSliderItem );
1007
0
            }
1008
0
        break;
1009
0
        case FN_PREVIEW_ZOOM:
1010
0
        {
1011
0
                const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
1012
0
                rSet.Put(SfxUInt16Item(nWhich, pVOpt->GetZoom()));
1013
0
        }
1014
0
        break;
1015
0
        case SID_ZOOM_IN:
1016
0
        case SID_ZOOM_OUT:
1017
0
        {
1018
0
            const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
1019
0
            if((SID_ZOOM_IN == nWhich && pVOpt->GetZoom() >= MAX_PREVIEW_ZOOM) ||
1020
0
                    (SID_ZOOM_OUT == nWhich && pVOpt->GetZoom() <= MIN_PREVIEW_ZOOM))
1021
0
            {
1022
0
                rSet.DisableItem(nWhich);
1023
0
            }
1024
0
        }
1025
0
        break;
1026
0
        case SID_ATTR_VIEWLAYOUT:
1027
0
        {
1028
0
            rSet.DisableItem( SID_ATTR_VIEWLAYOUT );
1029
0
        }
1030
0
        break;
1031
0
        case FN_SHOW_MULTIPLE_PAGES:
1032
        // should never be disabled
1033
0
        break;
1034
0
        case FN_SHOW_BOOKVIEW:
1035
0
        {
1036
0
            bool b = GetViewShell()->GetViewOptions()->IsPagePrevBookview();
1037
0
            rSet.Put(SfxBoolItem(nWhich, b));
1038
0
        }
1039
0
        break;
1040
1041
0
        case FN_SHOW_TWO_PAGES:
1042
0
            if( 2 == m_pViewWin->GetCol() && 1 == m_pViewWin->GetRow() )
1043
0
                rSet.DisableItem( nWhich );
1044
0
            break;
1045
1046
0
        case FN_PRINT_PAGEPREVIEW:
1047
            // has the same status like the normal printing
1048
0
            {
1049
0
                const SfxPoolItem* pItem;
1050
0
                SfxItemSetFixed<SID_PRINTDOC, SID_PRINTDOC> aSet( *rSet.GetPool() );
1051
0
                GetSlotState( SID_PRINTDOC, SfxViewShell::GetInterface(), &aSet );
1052
0
                if( SfxItemState::DISABLED == aSet.GetItemState( SID_PRINTDOC, false ))
1053
0
                    rSet.DisableItem( nWhich );
1054
0
                else if( SfxItemState::SET == aSet.GetItemState( SID_PRINTDOC,
1055
0
                        false, &pItem ))
1056
0
                {
1057
0
                    const_cast<SfxPoolItem*>(pItem)->SetWhich( FN_PRINT_PAGEPREVIEW );
1058
0
                    rSet.Put( *pItem );
1059
0
                }
1060
0
            }
1061
0
            break;
1062
1063
0
        case SID_PRINTPREVIEW:
1064
0
            rSet.Put( SfxBoolItem( nWhich, true ) );
1065
0
            break;
1066
1067
0
        case SID_PRINTDOC:
1068
0
        case SID_PRINTDOCDIRECT:
1069
0
            GetSlotState( nWhich, SfxViewShell::GetInterface(), &rSet );
1070
0
            break;
1071
0
        }
1072
0
        nWhich = aIter.NextWhich();
1073
0
    }
1074
0
}
1075
1076
void  SwPagePreview::StateUndo(SfxItemSet& rSet)
1077
0
{
1078
0
    SfxWhichIter aIter(rSet);
1079
0
    sal_uInt16 nWhich = aIter.FirstWhich();
1080
1081
0
    while (nWhich)
1082
0
    {
1083
0
        rSet.DisableItem(nWhich);
1084
0
        nWhich = aIter.NextWhich();
1085
0
    }
1086
0
}
1087
1088
void SwPagePreview::Init()
1089
0
{
1090
0
    if ( GetViewShell()->HasDrawView() )
1091
0
        GetViewShell()->GetDrawView()->SetAnimationEnabled( false );
1092
1093
0
    m_bNormalPrint = true;
1094
1095
    // Check and process the DocSize. The shell could not be found via
1096
    // the handler, because the shell is unknown to the SFX management
1097
    // within the CTOR phase.
1098
1099
0
    SwModule* mod = SwModule::get();
1100
0
    const SwViewOption* pPrefs = mod->GetUsrPref(false);
1101
1102
0
    mbHScrollbarEnabled = pPrefs->IsViewHScrollBar();
1103
0
    mbVScrollbarEnabled = pPrefs->IsViewVScrollBar();
1104
1105
    // Update the fields
1106
    // ATTENTION: Do cast the EditShell up, to use the SS.
1107
    //            At the methods the current shell will be queried!
1108
0
    SwEditShell* pESh = dynamic_cast<SwEditShell*>(GetViewShell());
1109
0
    bool bIsModified = pESh != nullptr && pESh->IsModified();
1110
1111
0
    SwViewOption aOpt( *pPrefs );
1112
    // tdf#101142 print preview should use a white background
1113
0
    SwViewColors aColors( aOpt.GetColorConfig() );
1114
0
    aColors.m_aDocColor = COL_WHITE;
1115
0
    aOpt.SetColorConfig( aColors );
1116
0
    aOpt.SetPagePreview(true);
1117
0
    aOpt.SetTab( false );
1118
0
    aOpt.SetBlank( false );
1119
0
    aOpt.SetHardBlank( false );
1120
0
    aOpt.SetParagraph( false );
1121
0
    aOpt.SetLineBreak( false );
1122
0
    aOpt.SetPageBreak( false );
1123
0
    aOpt.SetColumnBreak( false );
1124
0
    aOpt.SetSoftHyph( false );
1125
0
    aOpt.SetFieldName( false );
1126
0
    aOpt.SetPostIts( false );
1127
0
    aOpt.SetShowBookmarks( false );
1128
0
    aOpt.SetShowHiddenChar( false );
1129
0
    aOpt.SetShowHiddenField( false );
1130
0
    aOpt.SetShowHiddenPara( false );
1131
0
    aOpt.SetViewHRuler( false );
1132
0
    aOpt.SetViewVRuler( false );
1133
0
    aOpt.SetGraphic( true );
1134
0
    aOpt.SetTable( true );
1135
0
    aOpt.SetSnap( false );
1136
0
    aOpt.SetGridVisible( false );
1137
0
    aOpt.SetOnlineSpell( false );
1138
0
    aOpt.SetHideWhitespaceMode( false );
1139
1140
0
    GetViewShell()->ApplyViewOptions( aOpt );
1141
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
1142
0
    GetViewShell()->ApplyAccessibilityOptions();
1143
0
#endif
1144
1145
    // adjust view shell option to the same as for print
1146
0
    SwPrintData const aPrintOptions = *mod->GetPrtOptions(false);
1147
0
    GetViewShell()->AdjustOptionsForPagePreview( aPrintOptions );
1148
1149
0
    GetViewShell()->CalcLayout();
1150
0
    DocSzChgd( GetViewShell()->GetDocSize() );
1151
1152
0
    if( !bIsModified && pESh != nullptr )
1153
0
        pESh->ResetModified();
1154
0
}
1155
1156
SwPagePreview::SwPagePreview(SfxViewFrame& rViewFrame, SfxViewShell* pOldSh):
1157
0
    SfxViewShell(rViewFrame, SWVIEWFLAGS),
1158
0
    m_pViewWin( VclPtr<SwPagePreviewWin>::Create(&GetViewFrame().GetWindow(), *this ) ),
1159
    m_nNewPage(USHRT_MAX),
1160
0
    m_sPageStr(SwResId(STR_PAGE)),
1161
0
    m_pHScrollbar(nullptr),
1162
0
    m_pVScrollbar(nullptr),
1163
0
    mnPageCount( 0 ),
1164
0
    mbResetFormDesignMode( false ),
1165
0
    mbFormDesignModeToReset( false )
1166
0
{
1167
0
    SetName(u"PageView"_ustr);
1168
0
    SetWindow( m_pViewWin );
1169
0
    CreateScrollbar( true );
1170
0
    CreateScrollbar( false );
1171
1172
0
    SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Printpreview));
1173
1174
0
    SfxObjectShell* pObjShell = rViewFrame.GetObjectShell();
1175
0
    if ( !pOldSh )
1176
0
    {
1177
        // Exists already a view on the document?
1178
0
        SfxViewFrame *pF = SfxViewFrame::GetFirst( pObjShell );
1179
0
        if (pF == &rViewFrame)
1180
0
            pF = SfxViewFrame::GetNext( *pF, pObjShell );
1181
0
        if ( pF )
1182
0
            pOldSh = pF->GetViewShell();
1183
0
    }
1184
1185
0
    SwViewShell *pVS, *pNew;
1186
1187
0
    if (SwPagePreview* pPagePreview = dynamic_cast<SwPagePreview*>(pOldSh))
1188
0
        pVS = pPagePreview->GetViewShell();
1189
0
    else
1190
0
    {
1191
0
        if (SwView* pView = dynamic_cast<SwView *>(pOldSh))
1192
0
        {
1193
0
            pVS = pView->GetWrtShellPtr();
1194
            // save the current ViewData of the previous SwView
1195
0
            pOldSh->WriteUserData( m_sSwViewData );
1196
0
        }
1197
0
        else
1198
0
            pVS = GetDocShell()->GetWrtShell();
1199
0
        if( pVS )
1200
0
        {
1201
            // Set the current page as the first.
1202
0
            sal_uInt16 nPhysPg, nVirtPg;
1203
0
            static_cast<SwCursorShell*>(pVS)->GetPageNum( nPhysPg, nVirtPg, true, false );
1204
0
            if( 1 != m_pViewWin->GetCol() && 1 == nPhysPg )
1205
0
                --nPhysPg;
1206
0
            m_pViewWin->SetSttPage( nPhysPg );
1207
0
        }
1208
0
    }
1209
1210
    // for form shell remember design mode of draw view
1211
    // of previous view shell
1212
0
    if ( pVS && pVS->HasDrawView() )
1213
0
    {
1214
0
        mbResetFormDesignMode = true;
1215
0
        mbFormDesignModeToReset = pVS->GetDrawView()->IsDesignMode();
1216
0
    }
1217
1218
0
    if( pVS )
1219
0
        pNew = new SwViewShell( *pVS, m_pViewWin, nullptr, VSHELLFLAG_ISPREVIEW );
1220
0
    else
1221
0
        pNew = new SwViewShell(
1222
0
                *static_cast<SwDocShell*>(rViewFrame.GetObjectShell())->GetDoc(),
1223
0
                m_pViewWin, nullptr, nullptr, VSHELLFLAG_ISPREVIEW );
1224
1225
0
    m_pViewWin->SetViewShell( pNew );
1226
0
    pNew->SetSfxViewShell( this );
1227
0
    Init();
1228
0
}
1229
1230
SwPagePreview::~SwPagePreview()
1231
0
{
1232
0
    SetWindow( nullptr );
1233
0
    SwViewShell* pVShell =  m_pViewWin->GetViewShell();
1234
0
    pVShell->SetWin(nullptr);
1235
0
    delete pVShell;
1236
1237
0
    m_pViewWin.disposeAndClear();
1238
0
    m_pHScrollbar.disposeAndClear();
1239
0
    m_pVScrollbar.disposeAndClear();
1240
0
}
1241
1242
void SwPagePreview::Activate(bool bMDI)
1243
0
{
1244
0
    SfxViewShell::Activate(bMDI);
1245
0
    SfxShell::Activate(bMDI);
1246
0
}
1247
1248
SwDocShell* SwPagePreview::GetDocShell()
1249
0
{
1250
0
    return dynamic_cast<SwDocShell*>( GetViewFrame().GetObjectShell() );
1251
0
}
1252
1253
void SwPagePreview::CreateScrollbar( bool bHori )
1254
0
{
1255
0
    vcl::Window *pMDI = &GetViewFrame().GetWindow();
1256
0
    VclPtr<SwScrollbar>& ppScrollbar = bHori ? m_pHScrollbar : m_pVScrollbar;
1257
1258
0
    assert(!ppScrollbar); //check beforehand!
1259
0
    ppScrollbar = VclPtr<SwScrollbar>::Create( pMDI, bHori );
1260
1261
0
    ScrollDocSzChg();
1262
1263
0
    if (bHori)
1264
0
        ppScrollbar->SetScrollHdl( LINK( this, SwPagePreview, HoriScrollHdl ));
1265
0
    else
1266
0
        ppScrollbar->SetScrollHdl( LINK( this, SwPagePreview, VertScrollHdl ));
1267
1268
0
    InvalidateBorder();
1269
0
    ppScrollbar->ExtendedShow();
1270
0
}
1271
1272
bool SwPagePreview::ChgPage( int eMvMode, bool bUpdateScrollbar )
1273
0
{
1274
0
    tools::Rectangle aPixVisArea( m_pViewWin->LogicToPixel( m_aVisArea ) );
1275
0
    bool bChg = m_pViewWin->MovePage( eMvMode ) ||
1276
0
               eMvMode == SwPagePreviewWin::MV_CALC ||
1277
0
               eMvMode == SwPagePreviewWin::MV_NEWWINSIZE;
1278
0
    m_aVisArea = m_pViewWin->PixelToLogic( aPixVisArea );
1279
1280
0
    if( bChg )
1281
0
    {
1282
        // Update statusbar
1283
0
        SfxBindings& rBindings = GetViewFrame().GetBindings();
1284
1285
0
        if( bUpdateScrollbar )
1286
0
        {
1287
0
            ScrollViewSzChg();
1288
1289
0
            static sal_uInt16 aInval[] =
1290
0
            {
1291
0
                FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT,
1292
0
                FN_PAGEUP, FN_PAGEDOWN, 0
1293
0
            };
1294
0
            rBindings.Invalidate( aInval );
1295
0
        }
1296
0
        std::vector<OUString> aStringList
1297
0
        {
1298
0
            m_sPageStr + m_pViewWin->GetStatusStr(mnPageCount),
1299
0
            OUString()
1300
0
        };
1301
0
        rBindings.SetState(SfxStringListItem(FN_STAT_PAGE, &aStringList));
1302
0
    }
1303
0
    return bChg;
1304
0
}
1305
1306
// From here, everything was taken from the SwView.
1307
void SwPagePreview::CalcAndSetBorderPixel( SvBorder &rToFill )
1308
0
{
1309
0
    const StyleSettings &rSet = m_pViewWin->GetSettings().GetStyleSettings();
1310
0
    const tools::Long nTmp = rSet.GetScrollBarSize();
1311
0
    if (m_pVScrollbar->IsScrollbarVisible(true))
1312
0
        rToFill.Right()  = nTmp;
1313
0
    if (m_pHScrollbar->IsScrollbarVisible(true))
1314
0
        rToFill.Bottom() = nTmp;
1315
0
    SetBorderPixel( rToFill );
1316
0
}
1317
1318
void  SwPagePreview::InnerResizePixel( const Point &rOfst, const Size &rSize, bool )
1319
0
{
1320
0
    SvBorder aBorder;
1321
0
    CalcAndSetBorderPixel( aBorder );
1322
0
    tools::Rectangle aRect( rOfst, rSize );
1323
0
    aRect += aBorder;
1324
0
    ViewResizePixel( *m_pViewWin->GetOutDev(), aRect.TopLeft(), aRect.GetSize(),
1325
0
                    m_pViewWin->GetOutputSizePixel(),
1326
0
                    *m_pVScrollbar, *m_pHScrollbar );
1327
1328
    // Never set EditWin !
1329
    // Never set VisArea !
1330
0
}
1331
1332
void SwPagePreview::OuterResizePixel( const Point &rOfst, const Size &rSize )
1333
0
{
1334
0
    SvBorder aBorder;
1335
0
    CalcAndSetBorderPixel( aBorder );
1336
1337
    // Never set EditWin !
1338
1339
0
    Size aTmpSize( m_pViewWin->GetOutputSizePixel() );
1340
0
    Point aBottomRight( m_pViewWin->PixelToLogic( Point( aTmpSize.Width(), aTmpSize.Height() ) ) );
1341
0
    SetVisArea( tools::Rectangle( Point(), aBottomRight ) );
1342
1343
    // Call of the DocSzChgd-Method of the scrollbars is necessary,
1344
    // because from the maximum scroll range half the height of the
1345
    // VisArea is always deducted.
1346
0
    if ( m_pVScrollbar && !aTmpSize.IsEmpty() )
1347
0
    {
1348
0
        ScrollDocSzChg();
1349
0
    }
1350
1351
0
    SvBorder aBorderNew;
1352
0
    CalcAndSetBorderPixel( aBorderNew );
1353
0
    ViewResizePixel( *m_pViewWin->GetOutDev(), rOfst, rSize, m_pViewWin->GetOutputSizePixel(),
1354
0
                    *m_pVScrollbar, *m_pHScrollbar );
1355
0
}
1356
1357
void SwPagePreview::SetVisArea( const tools::Rectangle &rRect )
1358
0
{
1359
0
    const Point aTopLeft(AlignToPixel(rRect.TopLeft()));
1360
0
    const Point aBottomRight(AlignToPixel(rRect.BottomRight()));
1361
0
    tools::Rectangle aLR(aTopLeft,aBottomRight);
1362
1363
0
    if(aLR == m_aVisArea)
1364
0
        return;
1365
        // No negative position, no negative size
1366
1367
0
    if(aLR.Top() < 0)
1368
0
    {
1369
0
        aLR.AdjustBottom(std::abs(aLR.Top()) );
1370
0
        aLR.SetTop( 0 );
1371
0
    }
1372
1373
0
    if(aLR.Left() < 0)
1374
0
    {
1375
0
        aLR.AdjustRight(std::abs(aLR.Left()) );
1376
0
        aLR.SetLeft( 0 );
1377
0
    }
1378
0
    if(aLR.Right() < 0) aLR.SetRight( 0 );
1379
0
    if(aLR.Bottom() < 0) aLR.SetBottom( 0 );
1380
0
    if(aLR == m_aVisArea ||
1381
        // Ignore empty rectangle
1382
0
        ( 0 == aLR.Bottom() - aLR.Top() && 0 == aLR.Right() - aLR.Left() ) )
1383
0
        return;
1384
1385
0
    if( aLR.Left() > aLR.Right() || aLR.Top() > aLR.Bottom() )
1386
0
        return;
1387
1388
    // Before the data can be changed call an update if necessary.
1389
    // Thereby ensured, that adjacent paints are correctly converted into
1390
    // document coordinates.
1391
    // As a precaution, we do this only when at the shell runs an action,
1392
    // because then we do not really paint but the rectangles are just
1393
    // bookmarked (in document coordinates).
1394
0
    if( GetViewShell()->ActionPend() )
1395
0
        m_pViewWin->PaintImmediately();
1396
1397
    // Set at View-Win the current size
1398
0
    m_aVisArea = aLR;
1399
0
    m_pViewWin->SetWinSize( aLR.GetSize() );
1400
0
    ChgPage( SwPagePreviewWin::MV_NEWWINSIZE );
1401
1402
0
    m_pViewWin->Invalidate();
1403
0
}
1404
1405
void SwPagePreview::PrintSettingsChanged()
1406
0
{
1407
0
    m_pViewWin->ReInit();
1408
0
    ChgPage( SwPagePreviewWin::MV_DOC_STT );
1409
0
}
1410
1411
IMPL_LINK(SwPagePreview, HoriScrollHdl, weld::Scrollbar&, rScrollbar, void)
1412
0
{
1413
0
    ScrollHdl(rScrollbar, true);
1414
0
}
1415
1416
IMPL_LINK(SwPagePreview, VertScrollHdl, weld::Scrollbar&, rScrollbar, void)
1417
0
{
1418
0
    ScrollHdl(rScrollbar, false);
1419
0
}
1420
1421
void SwPagePreview::ScrollHdl(const weld::Scrollbar& rScrollbar, bool bHori)
1422
0
{
1423
0
    if(!GetViewShell())
1424
0
        return;
1425
1426
0
    EndScrollHdl(rScrollbar, bHori);
1427
1428
0
    if( !bHori &&
1429
0
        rScrollbar.get_scroll_type() == ScrollType::Drag &&
1430
0
        Help::IsQuickHelpEnabled() &&
1431
0
        GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow())
1432
0
    {
1433
        // Scroll how many pages??
1434
0
        OUString sStateStr(m_sPageStr);
1435
0
        tools::Long nThmbPos = rScrollbar.adjustment_get_value();
1436
0
        if( 1 == m_pViewWin->GetCol() || !nThmbPos )
1437
0
            ++nThmbPos;
1438
0
        sStateStr += OUString::number( nThmbPos );
1439
0
        Point aPos = m_pVScrollbar->GetParent()->OutputToScreenPixel(
1440
0
                                        m_pVScrollbar->GetPosPixel());
1441
0
        aPos.setY( m_pVScrollbar->OutputToScreenPixel(m_pVScrollbar->GetPointerPosPixel()).Y() );
1442
0
        tools::Rectangle aRect;
1443
0
        aRect.SetLeft( aPos.X() -8 );
1444
0
        aRect.SetRight( aRect.Left() );
1445
0
        aRect.SetTop( aPos.Y() );
1446
0
        aRect.SetBottom( aRect.Top() );
1447
1448
0
        Help::ShowQuickHelp(m_pVScrollbar, aRect, sStateStr,
1449
0
                QuickHelpFlags::Right|QuickHelpFlags::VCenter);
1450
1451
0
    }
1452
0
}
1453
1454
void SwPagePreview::EndScrollHdl(const weld::Scrollbar& rScrollbar, bool bHori)
1455
0
{
1456
0
    if(!GetViewShell())
1457
0
        return;
1458
1459
    // boolean to avoid unnecessary invalidation of the window.
1460
0
    bool bInvalidateWin = true;
1461
1462
0
    if (!bHori)       // scroll vertically
1463
0
    {
1464
0
        if ( Help::IsQuickHelpEnabled() )
1465
0
            Help::ShowQuickHelp(m_pVScrollbar, tools::Rectangle(), OUString());
1466
0
        SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
1467
0
        if (pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
1468
0
        {
1469
            // Scroll how many pages ??
1470
0
            const sal_uInt16 nThmbPos = pPagePreviewLay->ConvertRelativeToAbsolutePageNum(
1471
0
                o3tl::narrowing<sal_uInt16>(rScrollbar.adjustment_get_value()) );
1472
            // adjust to new preview functionality
1473
0
            if( nThmbPos != m_pViewWin->SelectedPage() )
1474
0
            {
1475
                // consider case that page <nThmbPos>
1476
                // is already visible
1477
0
                if ( pPagePreviewLay->IsPageVisible( nThmbPos ) )
1478
0
                {
1479
0
                    pPagePreviewLay->MarkNewSelectedPage( nThmbPos );
1480
                    // invalidation of window is unnecessary
1481
0
                    bInvalidateWin = false;
1482
0
                }
1483
0
                else
1484
0
                {
1485
                    // consider whether layout columns
1486
0
                    m_pViewWin->SetSttPage( nThmbPos );
1487
0
                    m_pViewWin->SetSelectedPage( nThmbPos );
1488
0
                    ChgPage( SwPagePreviewWin::MV_SCROLL, false );
1489
                    // update scrollbars
1490
0
                    ScrollViewSzChg();
1491
0
                }
1492
                // update accessibility
1493
0
                GetViewShell()->ShowPreviewSelection( nThmbPos );
1494
0
            }
1495
0
            else
1496
0
            {
1497
                // invalidation of window is unnecessary
1498
0
                bInvalidateWin = false;
1499
0
            }
1500
0
        }
1501
0
        else
1502
0
        {
1503
0
            tools::Long nThmbPos = rScrollbar.adjustment_get_value();
1504
0
            m_pViewWin->Scroll(0, nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Top());
1505
0
        }
1506
0
    }
1507
0
    else
1508
0
    {
1509
0
        tools::Long nThmbPos = rScrollbar.adjustment_get_value();
1510
0
        m_pViewWin->Scroll(nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Left(), 0);
1511
0
    }
1512
    // additional invalidate page status.
1513
0
    static sal_uInt16 aInval[] =
1514
0
    {
1515
0
        FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
1516
0
        FN_STAT_PAGE, 0
1517
0
    };
1518
0
    SfxBindings& rBindings = GetViewFrame().GetBindings();
1519
0
    rBindings.Invalidate( aInval );
1520
    // control invalidation of window
1521
0
    if ( bInvalidateWin )
1522
0
    {
1523
0
        m_pViewWin->Invalidate();
1524
0
    }
1525
0
}
1526
1527
Point SwPagePreview::AlignToPixel(const Point &rPt) const
1528
0
{
1529
0
    return m_pViewWin->PixelToLogic( m_pViewWin->LogicToPixel( rPt ) );
1530
0
}
1531
1532
void SwPagePreview::DocSzChgd( const Size &rSz )
1533
0
{
1534
0
    if( m_aDocSize == rSz )
1535
0
        return;
1536
1537
0
    m_aDocSize = rSz;
1538
1539
    // #i96726#
1540
    // Due to the multiple page layout it is needed to trigger recalculation
1541
    // of the page preview layout, even if the count of pages is not changing.
1542
0
    mnPageCount = GetViewShell()->GetNumPages();
1543
1544
0
    if( m_aVisArea.GetWidth() )
1545
0
    {
1546
0
        ChgPage( SwPagePreviewWin::MV_CALC );
1547
0
        ScrollDocSzChg();
1548
1549
0
        m_pViewWin->Invalidate();
1550
0
    }
1551
0
}
1552
1553
void SwPagePreview::ScrollViewSzChg()
1554
0
{
1555
0
    if(!GetViewShell())
1556
0
        return ;
1557
1558
0
    bool bShowVScrollbar = false, bShowHScrollbar = false;
1559
1560
0
    if(m_pVScrollbar)
1561
0
    {
1562
0
        if(GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow())
1563
0
        {
1564
            //vertical scrolling by row
1565
            // adjust to new preview functionality
1566
0
            const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol();
1567
1568
0
            m_pVScrollbar->SetVisibleSize( nVisPages );
1569
            // set selected page as scroll bar position,
1570
            // if it is visible.
1571
0
            SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
1572
0
            if ( pPagePreviewLay->IsPageVisible( m_pViewWin->SelectedPage() ) )
1573
0
            {
1574
0
                m_pVScrollbar->SetThumbPos(
1575
0
                    pPagePreviewLay->ConvertAbsoluteToRelativePageNum(m_pViewWin->SelectedPage()) );
1576
0
            }
1577
0
            else
1578
0
            {
1579
0
                m_pVScrollbar->SetThumbPos(
1580
0
                    pPagePreviewLay->ConvertAbsoluteToRelativePageNum(m_pViewWin->GetSttPage()) );
1581
0
            }
1582
0
            m_pVScrollbar->SetLineSize( m_pViewWin->GetCol() );
1583
0
            m_pVScrollbar->SetPageSize( nVisPages );
1584
            // calculate and set scrollbar range
1585
0
            Range aScrollbarRange( 1, pPagePreviewLay->GetMaxPreviewPages() );
1586
            // increase range by one, because left-top-corner is left blank.
1587
0
            ++aScrollbarRange.Max();
1588
            // increase range in order to access all pages
1589
0
            aScrollbarRange.Max() += ( nVisPages - 1 );
1590
0
            m_pVScrollbar->SetRange( aScrollbarRange );
1591
1592
0
            bShowVScrollbar = nVisPages < pPagePreviewLay->GetMaxPreviewPages();
1593
0
        }
1594
0
        else //vertical scrolling by pixel
1595
0
        {
1596
0
            const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect();
1597
0
            const Size aPreviewSize =
1598
0
                    GetViewShell()->PagePreviewLayout()->GetPreviewDocSize();
1599
0
            m_pVScrollbar->SetRangeMax(aPreviewSize.Height()) ;
1600
0
            tools::Long nVisHeight = rDocRect.GetHeight();
1601
0
            m_pVScrollbar->SetVisibleSize( nVisHeight );
1602
0
            m_pVScrollbar->SetThumbPos( rDocRect.Top() );
1603
0
            m_pVScrollbar->SetLineSize( nVisHeight / 10 );
1604
0
            m_pVScrollbar->SetPageSize( nVisHeight / 2 );
1605
1606
0
            bShowVScrollbar = true;
1607
0
        }
1608
1609
0
        if (!mbVScrollbarEnabled)
1610
0
            bShowVScrollbar = false;
1611
1612
0
        ShowVScrollbar(bShowVScrollbar);
1613
0
    }
1614
0
    if(m_pHScrollbar)
1615
0
    {
1616
0
        const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect();
1617
0
        const Size aPreviewSize =
1618
0
                GetViewShell()->PagePreviewLayout()->GetPreviewDocSize();
1619
0
        Range aRange(0,0);
1620
1621
0
        if(rDocRect.GetWidth() < aPreviewSize.Width())
1622
0
        {
1623
0
            bShowHScrollbar = true;
1624
1625
0
            tools::Long nVisWidth = rDocRect.GetWidth();
1626
0
            tools::Long nThumb = rDocRect.Left();
1627
0
            aRange = Range(0, aPreviewSize.Width());
1628
1629
0
            m_pHScrollbar->SetRange( aRange );
1630
0
            m_pHScrollbar->SetVisibleSize( nVisWidth );
1631
0
            m_pHScrollbar->SetThumbPos( nThumb );
1632
0
            m_pHScrollbar->SetLineSize( nVisWidth / 10 );
1633
0
            m_pHScrollbar->SetPageSize( nVisWidth / 2 );
1634
0
        }
1635
1636
0
        if (!mbHScrollbarEnabled)
1637
0
            bShowHScrollbar = false;
1638
1639
0
        ShowHScrollbar(bShowHScrollbar);
1640
0
    }
1641
0
}
1642
1643
void SwPagePreview::ScrollDocSzChg()
1644
0
{
1645
0
    ScrollViewSzChg();
1646
0
}
1647
1648
// All about printing
1649
SfxPrinter*  SwPagePreview::GetPrinter( bool bCreate )
1650
0
{
1651
0
    return m_pViewWin->GetViewShell()->getIDocumentDeviceAccess().getPrinter( bCreate );
1652
0
}
1653
1654
sal_uInt16  SwPagePreview::SetPrinter( SfxPrinter *pNew, SfxPrinterChangeFlags nDiffFlags )
1655
0
{
1656
0
    SwViewShell &rSh = *GetViewShell();
1657
0
    SfxPrinter* pOld = rSh.getIDocumentDeviceAccess().getPrinter( false );
1658
0
    if ( pOld && pOld->IsPrinting() )
1659
0
        return SFX_PRINTERROR_BUSY;
1660
1661
0
    SwEditShell &rESh = static_cast<SwEditShell&>(rSh);  //Buh...
1662
0
    if( ( SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP ) & nDiffFlags )
1663
0
    {
1664
0
        rSh.getIDocumentDeviceAccess().setPrinter( pNew, true, true );
1665
0
        if( nDiffFlags & SfxPrinterChangeFlags::PRINTER )
1666
0
            rESh.SetModified();
1667
0
    }
1668
0
    if ( ( nDiffFlags & SfxPrinterChangeFlags::OPTIONS ) == SfxPrinterChangeFlags::OPTIONS )
1669
0
        ::SetPrinter( &rSh.getIDocumentDeviceAccess(), pNew, false );
1670
1671
0
    const bool bChgOri  = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION);
1672
0
    const bool bChgSize = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE);
1673
0
    if ( bChgOri || bChgSize )
1674
0
    {
1675
0
        rESh.StartAllAction();
1676
0
        if ( bChgOri )
1677
0
            rSh.ChgAllPageOrientation( pNew->GetOrientation() );
1678
0
        if ( bChgSize )
1679
0
        {
1680
0
            Size aSz( SvxPaperInfo::GetPaperSize( pNew ) );
1681
0
            rSh.ChgAllPageSize( aSz );
1682
0
        }
1683
0
        if( !m_bNormalPrint )
1684
0
            m_pViewWin->CalcWish( m_pViewWin->GetRow(), m_pViewWin->GetCol() );
1685
0
        rESh.SetModified();
1686
0
        rESh.EndAllAction();
1687
1688
0
        static sal_uInt16 aInval[] =
1689
0
        {
1690
0
            SID_ATTR_LONG_ULSPACE, SID_ATTR_LONG_LRSPACE,
1691
0
            SID_RULER_BORDERS, SID_RULER_PAGE_POS, 0
1692
0
        };
1693
#if OSL_DEBUG_LEVEL > 0
1694
        {
1695
            const sal_uInt16* pPtr = aInval + 1;
1696
            do {
1697
                OSL_ENSURE( *(pPtr - 1) < *pPtr, "wrong sorting!" );
1698
            } while( *++pPtr );
1699
        }
1700
#endif
1701
1702
0
        GetViewFrame().GetBindings().Invalidate(aInval);
1703
0
    }
1704
1705
0
    return 0;
1706
0
}
1707
1708
bool SwPagePreview::HasPrintOptionsPage() const
1709
0
{
1710
0
    return true;
1711
0
}
1712
1713
std::unique_ptr<SfxTabPage> SwPagePreview::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController,
1714
                                                         const SfxItemSet &rOptions)
1715
0
{
1716
0
    return ::CreatePrintOptionsPage(pPage, pController, rOptions, !m_bNormalPrint);
1717
0
}
1718
1719
void SwPagePreviewWin::SetViewShell( SwViewShell* pShell )
1720
0
{
1721
0
    mpViewShell = pShell;
1722
0
    if ( mpViewShell && mpViewShell->IsPreview() )
1723
0
    {
1724
0
        mpPgPreviewLayout = mpViewShell->PagePreviewLayout();
1725
0
    }
1726
0
}
1727
1728
void SwPagePreviewWin::RepaintCoreRect( const SwRect& rRect )
1729
0
{
1730
    // #i24183#
1731
0
    if ( mpPgPreviewLayout->PreviewLayoutValid() )
1732
0
    {
1733
0
        mpPgPreviewLayout->Repaint( tools::Rectangle( rRect.Pos(), rRect.SSize() ) );
1734
0
    }
1735
0
}
1736
1737
/** method to adjust preview to a new zoom factor
1738
1739
    #i19975# also consider zoom type - adding parameter <_eZoomType>
1740
*/
1741
void SwPagePreviewWin::AdjustPreviewToNewZoom( const sal_uInt16 _nZoomFactor,
1742
                                               const SvxZoomType _eZoomType )
1743
0
{
1744
    // #i19975# consider zoom type
1745
0
    if ( _eZoomType == SvxZoomType::WHOLEPAGE )
1746
0
    {
1747
0
        mnRow = 1;
1748
0
        mnCol = 1;
1749
0
        mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
1750
0
        mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
1751
0
                                  mnSttPage, maPaintedPreviewDocRect );
1752
0
        SetSelectedPage( mnSttPage );
1753
0
        SetPagePreview(mnRow, mnCol);
1754
0
        maScale = GetMapMode().GetScaleX();
1755
0
    }
1756
0
    else if ( _nZoomFactor != 0 )
1757
0
    {
1758
        // calculate new scaling and set mapping mode appropriately.
1759
0
        Fraction aNewScale( _nZoomFactor, 100 );
1760
0
        MapMode aNewMapMode = GetMapMode();
1761
0
        aNewMapMode.SetScaleX( aNewScale );
1762
0
        aNewMapMode.SetScaleY( aNewScale );
1763
0
        SetMapMode( aNewMapMode );
1764
1765
        // calculate new start position for preview paint
1766
0
        Size aNewWinSize = PixelToLogic( maPxWinSize );
1767
0
        Point aNewPaintStartPos =
1768
0
                mpPgPreviewLayout->GetPreviewStartPosForNewScale( aNewScale, maScale, aNewWinSize );
1769
1770
        // remember new scaling and prepare preview paint
1771
        // Note: paint of preview will be performed by a corresponding invalidate
1772
        //          due to property changes.
1773
0
        maScale = aNewScale;
1774
0
        mpPgPreviewLayout->Prepare( 0, aNewPaintStartPos, maPxWinSize,
1775
0
                                  mnSttPage, maPaintedPreviewDocRect );
1776
0
    }
1777
1778
0
}
1779
1780
/**
1781
 * pixel scrolling - horizontally always or vertically
1782
 * when less than the desired number of rows fits into
1783
 * the view
1784
 */
1785
void SwPagePreviewWin::Scroll(tools::Long nXMove, tools::Long nYMove, ScrollFlags /*nFlags*/)
1786
0
{
1787
0
    maPaintedPreviewDocRect.Move(nXMove, nYMove);
1788
0
    mpPgPreviewLayout->Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
1789
0
                              maPxWinSize, mnSttPage,
1790
0
                              maPaintedPreviewDocRect );
1791
1792
0
}
1793
1794
bool SwPagePreview::HandleWheelCommands( const CommandEvent& rCEvt )
1795
0
{
1796
0
    bool bOk = false;
1797
0
    const CommandWheelData* pWData = rCEvt.GetWheelData();
1798
0
    if( pWData && CommandWheelMode::ZOOM == pWData->GetMode() )
1799
0
    {
1800
0
        sal_uInt16 nFactor = GetViewShell()->GetViewOptions()->GetZoom();
1801
0
        const sal_uInt16 nOffset = 10;
1802
0
        if( 0L > pWData->GetDelta() )
1803
0
        {
1804
0
            nFactor -= nOffset;
1805
0
            if(nFactor < MIN_PREVIEW_ZOOM)
1806
0
                nFactor = MIN_PREVIEW_ZOOM;
1807
0
        }
1808
0
        else
1809
0
        {
1810
0
            nFactor += nOffset;
1811
0
            if(nFactor > MAX_PREVIEW_ZOOM)
1812
0
                nFactor = MAX_PREVIEW_ZOOM;
1813
0
        }
1814
0
        SetZoom(SvxZoomType::PERCENT, nFactor);
1815
0
        bOk = true;
1816
0
    }
1817
0
    else
1818
0
        bOk = m_pViewWin->HandleScrollCommand( rCEvt, m_pHScrollbar, m_pVScrollbar );
1819
0
    return bOk;
1820
0
}
1821
1822
uno::Reference< css::accessibility::XAccessible >
1823
    SwPagePreviewWin::CreateAccessible()
1824
0
{
1825
0
    SolarMutexGuard aGuard; // this should have happened already!!!
1826
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
1827
0
    OSL_ENSURE( GetViewShell() != nullptr, "We need a view shell" );
1828
0
    if (mpViewShell)
1829
0
        return mpViewShell->CreateAccessiblePreview();
1830
0
#endif
1831
0
    return {};
1832
0
}
1833
1834
void SwPagePreview::ShowHScrollbar(bool bShow)
1835
0
{
1836
0
    m_pHScrollbar->Show(bShow);
1837
0
    InvalidateBorder();
1838
0
}
1839
1840
void SwPagePreview::ShowVScrollbar(bool bShow)
1841
0
{
1842
0
    m_pVScrollbar->Show(bShow);
1843
0
    InvalidateBorder();
1844
0
}
1845
1846
void SwPagePreview::EnableHScrollbar(bool bEnable)
1847
0
{
1848
0
    if (mbHScrollbarEnabled != bEnable)
1849
0
    {
1850
0
        mbHScrollbarEnabled = bEnable;
1851
0
        ScrollViewSzChg();
1852
0
    }
1853
0
}
1854
1855
void SwPagePreview::EnableVScrollbar(bool bEnable)
1856
0
{
1857
0
    if (mbVScrollbarEnabled != bEnable)
1858
0
    {
1859
0
        mbVScrollbarEnabled = bEnable;
1860
0
        ScrollViewSzChg();
1861
0
    }
1862
0
}
1863
1864
void SwPagePreview::SetZoom(SvxZoomType eType, sal_uInt16 nFactor)
1865
0
{
1866
0
    SwViewShell& rSh = *GetViewShell();
1867
0
    SwViewOption aOpt(*rSh.GetViewOptions());
1868
    // perform action only on changes of zoom or zoom type.
1869
0
    if ( aOpt.GetZoom() != nFactor ||
1870
0
         aOpt.GetZoomType() != eType )
1871
0
    {
1872
0
        aOpt.SetZoom(nFactor);
1873
0
        aOpt.SetZoomType(eType);
1874
0
        rSh.ApplyViewOptions( aOpt );
1875
0
        lcl_InvalidateZoomSlots(GetViewFrame().GetBindings());
1876
        // #i19975# also consider zoom type
1877
0
        m_pViewWin->AdjustPreviewToNewZoom( nFactor, eType );
1878
0
        ScrollViewSzChg();
1879
0
    }
1880
0
}
1881
1882
/** adjust position of vertical scrollbar */
1883
void SwPagePreview::SetVScrollbarThumbPos( const sal_uInt16 _nNewThumbPos )
1884
0
{
1885
0
    if ( m_pVScrollbar )
1886
0
    {
1887
0
        m_pVScrollbar->SetThumbPos( _nNewThumbPos );
1888
0
    }
1889
0
}
1890
1891
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */