/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
 
#include <config_wasm_strip.h>
 
#include <sfx2/objface.hxx>
#include <vcl/help.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <vcl/syswin.hxx>
#include <vcl/weld.hxx>
 
#include <svl/whiter.hxx>
#include <svl/slstitm.hxx>
#include <svl/eitem.hxx>
#include <sfx2/printer.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>
#include <sfx2/dispatch.hxx>
#include <editeng/paperinf.hxx>
#include <svx/svdview.hxx>
#include <svx/viewlayoutitem.hxx>
#include <svx/zoomslideritem.hxx>
#include <tools/svborder.hxx>
#include <osl/diagnose.h>
 
#include <globdoc.hxx>
#include <wdocsh.hxx>
#include <pvprtdat.hxx>
#include <swmodule.hxx>
#include <wrtsh.hxx>
#include <docsh.hxx>
#include <viewopt.hxx>
#include <doc.hxx>
#include <IDocumentDeviceAccess.hxx>
#include <pview.hxx>
#include <view.hxx>
#include <scroll.hxx>
#include <prtopt.hxx>
#include <usrpref.hxx>
#include "viewfunc.hxx"
 
#include <helpids.h>
#include <cmdid.h>
#include <strings.hrc>
 
#define ShellClass_SwPagePreview
#include <sfx2/msg.hxx>
#include <swslots.hxx>
#include <pagepreviewlayout.hxx>
 
#include <svx/svxdlg.hxx>
 
#include <memory>
#include <vcl/EnumContext.hxx>
#include <vcl/notebookbar/notebookbar.hxx>
 
using namespace ::com::sun::star;
SFX_IMPL_NAMED_VIEWFACTORY(SwPagePreview, "PrintPreview")
{
    SFX_VIEW_REGISTRATION(SwDocShell);
    SFX_VIEW_REGISTRATION(SwWebDocShell);
    SFX_VIEW_REGISTRATION(SwGlobalDocShell);
}
 
SFX_IMPL_INTERFACE(SwPagePreview, SfxViewShell)
 
void SwPagePreview::InitInterface_Impl()
{
    GetStaticInterface()->RegisterPopupMenu(u"preview"_ustr);
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT,
                                            SfxVisibilityFlags::Standard|SfxVisibilityFlags::Client|SfxVisibilityFlags::FullScreen|SfxVisibilityFlags::ReadonlyDoc,
                                            ToolbarId::PView_Toolbox);
}
 
 
#define SWVIEWFLAGS SfxViewShellFlags::HAS_PRINTOPTIONS
 
#define MIN_PREVIEW_ZOOM 25
#define MAX_PREVIEW_ZOOM 600
 
static sal_uInt16 lcl_GetNextZoomStep(sal_uInt16 nCurrentZoom, bool bZoomIn)
{
    static const sal_uInt16 aZoomArr[] =
    {
        25, 50, 75, 100, 150, 200, 400, 600
    };
    const int nZoomArrSize = static_cast<int>(SAL_N_ELEMENTS(aZoomArr));
    if (bZoomIn)
    {
        for(sal_uInt16 i : aZoomArr)
        {
            if(nCurrentZoom < i)
                return i;
        }
    }
    else
    {
        for(int i = nZoomArrSize - 1; i >= 0; --i)
        {
            if(nCurrentZoom > aZoomArr[i] || !i)
                return aZoomArr[i];
        }
    }
    return bZoomIn ? MAX_PREVIEW_ZOOM : MIN_PREVIEW_ZOOM;
};
 
static void lcl_InvalidateZoomSlots(SfxBindings& rBindings)
{
    static sal_uInt16 const aInval[] =
    {
        SID_ATTR_ZOOM, SID_ZOOM_OUT, SID_ZOOM_IN, SID_ATTR_ZOOMSLIDER, FN_PREVIEW_ZOOM, FN_STAT_ZOOM,
        0
    };
    rBindings.Invalidate( aInval );
}
 
namespace {
 
// At first the zoom dialog
class SwPreviewZoomDlg : public weld::GenericDialogController
{
    SwPagePreviewWin& m_rParent;
    std::unique_ptr<weld::SpinButton> m_xRowEdit;
    std::unique_ptr<weld::SpinButton> m_xColEdit;
 
public:
    SwPreviewZoomDlg(SwPagePreviewWin& rParent)
        : GenericDialogController(rParent.GetFrameWeld(), u"modules/swriter/ui/previewzoomdialog.ui"_ustr, u"PreviewZoomDialog"_ustr)
        , m_rParent(rParent)
        , m_xRowEdit(m_xBuilder->weld_spin_button(u"rows"_ustr))
        , m_xColEdit(m_xBuilder->weld_spin_button(u"cols"_ustr))
    {
        m_xRowEdit->set_value(rParent.GetRow());
        m_xColEdit->set_value(rParent.GetCol());
    }
 
    void execute()
    {
        if (run() == RET_OK)
        {
            m_rParent.CalcWish(m_xRowEdit->get_value(), m_xColEdit->get_value());
        }
    }
};
 
}
 
// all for SwPagePreviewWin
SwPagePreviewWin::SwPagePreviewWin( vcl::Window *pParent, SwPagePreview& rPView )
    : Window(pParent, WinBits(WB_CLIPCHILDREN))
    , mpViewShell(nullptr)
    , mrView(rPView)
    , mbCalcScaleForPreviewLayout(true)
    , maPaintedPreviewDocRect(tools::Rectangle(0,0,0,0))
    , mpPgPreviewLayout(nullptr)
{
    GetOutDev()->SetOutDevViewType( OutDevViewType::PrintPreview );
    SetHelpId(HID_PAGEPREVIEW);
    GetOutDev()->SetFillColor( GetBackground().GetColor() );
    GetOutDev()->SetLineColor( GetBackground().GetColor());
    SetMapMode( MapMode(MapUnit::MapTwip) );
 
    const SwMasterUsrPref *pUsrPref = SW_MOD()->GetUsrPref(false);
    mnRow = pUsrPref->GetPagePrevRow();     // 1 row
    mnCol = pUsrPref->GetPagePrevCol();     // 1 column
    mnSttPage = USHRT_MAX;
}
 
SwPagePreviewWin::~SwPagePreviewWin()
{
}
 
void  SwPagePreviewWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
    if (!mpViewShell || !mpViewShell->GetLayout())
        return;
 
    if (USHRT_MAX == mnSttPage)        // was never calculated ? (Init-Phase!)
    {
        // This is the size to which I always relate.
        if (!maPxWinSize.Height() || !maPxWinSize.Width())
            maPxWinSize = GetOutputSizePixel();
 
        tools::Rectangle aRect(rRenderContext.LogicToPixel(rRect));
        mpPgPreviewLayout->Prepare(1, Point(0,0), maPxWinSize,
                                   mnSttPage, maPaintedPreviewDocRect);
        SetSelectedPage(1);
        mpPgPreviewLayout->Paint(rRenderContext, rRenderContext.PixelToLogic(aRect));
        SetPagePreview(mnRow, mnCol);
    }
    else
    {
        MapMode aMM(rRenderContext.GetMapMode());
        aMM.SetScaleX(maScale);
        aMM.SetScaleY(maScale);
        rRenderContext.SetMapMode(aMM);
        mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(true);
        mpPgPreviewLayout->Paint(rRenderContext, rRect);
        mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(false);
    }
}
 
void SwPagePreviewWin::CalcWish( sal_Int16 nNewRow, sal_Int16 nNewCol )
{
    if( !mpViewShell || !mpViewShell->GetLayout() )
        return;
 
    const sal_Int16 nOldCol = mnCol;
    mnRow = nNewRow;
    mnCol = nNewCol;
    const sal_uInt16 nPages = mnRow * mnCol;
    const sal_uInt16 nLastSttPg = mrView.GetPageCount()+1 > nPages
                            ? mrView.GetPageCount()+1 - nPages : 0;
    if( mnSttPage > nLastSttPg )
        mnSttPage = nLastSttPg;
 
    mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
    mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
                              mnSttPage, maPaintedPreviewDocRect );
    SetSelectedPage( mnSttPage );
    SetPagePreview(mnRow, mnCol);
    maScale = GetMapMode().GetScaleX();
 
    // If changes have taken place at the columns, the special case "single column"
    // must be considered and corrected if necessary.
    if( (1 == nOldCol) != (1 == mnCol) )
        mrView.ScrollDocSzChg();
 
    // Order must be maintained!
    // additional invalidate page status.
    static sal_uInt16 aInval[] =
    {
        SID_ATTR_ZOOM, SID_ZOOM_OUT, SID_ZOOM_IN,
        FN_PREVIEW_ZOOM,
        FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
        FN_STAT_PAGE, FN_STAT_ZOOM,
        FN_SHOW_TWO_PAGES, FN_SHOW_MULTIPLE_PAGES,
        0
    };
    SfxBindings& rBindings = mrView.GetViewFrame().GetBindings();
    rBindings.Invalidate( aInval );
    rBindings.Update( FN_SHOW_TWO_PAGES );
    rBindings.Update( FN_SHOW_MULTIPLE_PAGES );
    // adjust scrollbars
    mrView.ScrollViewSzChg();
}
 
// mnSttPage is Absolute
bool SwPagePreviewWin::MovePage( int eMoveMode )
{
    // number of pages up
    const sal_uInt16 nPages = mnRow * mnCol;
    sal_uInt16 nNewSttPage = mnSttPage;
    const sal_uInt16 nPageCount = mrView.GetPageCount();
    const sal_uInt16 nDefSttPg = GetDefSttPage();
    bool bPaintPageAtFirstCol = true;
 
    switch( eMoveMode )
    {
    case MV_PAGE_UP:
    {
        const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage );
        const sal_uInt16 nNewAbsSttPage = nRelSttPage - nPages > 0 ?
                                          mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage - nPages ) :
                                          nDefSttPg;
        nNewSttPage = nNewAbsSttPage;
 
        const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() );
        const sal_uInt16 nNewRelSelPage = nRelSelPage - nPages > 0 ?
                                          nRelSelPage - nPages :
                                          1;
        SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewRelSelPage ) );
 
        break;
    }
    case MV_PAGE_DOWN:
    {
        const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage );
        const sal_uInt16 nNewAbsSttPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage + nPages );
        nNewSttPage = std::min(nNewAbsSttPage, nPageCount);
 
        const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() );
        const sal_uInt16 nNewAbsSelPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSelPage + nPages );
        SetSelectedPage( std::min(nNewAbsSelPage, nPageCount) );
 
        break;
    }
    case MV_DOC_STT:
        nNewSttPage = nDefSttPg;
        SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewSttPage ? nNewSttPage : 1 ) );
        break;
    case MV_DOC_END:
        // correct calculation of new start page.
        nNewSttPage = nPageCount;
        SetSelectedPage( nPageCount );
        break;
 
    case MV_SELPAGE:
        // <nNewSttPage> and <SelectedPage()> are already set.
        // not start at first column, only if the
        // complete preview layout columns doesn't fit into window.
        if ( !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() )
            bPaintPageAtFirstCol = false;
        break;
    case MV_SCROLL:
        // check, if paint page at first column
        // has to be avoided
        if ( !mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() ||
             !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() )
            bPaintPageAtFirstCol = false;
        break;
    case MV_NEWWINSIZE:
        // nothing special to do.
        break;
    case MV_CALC:
        // re-init page preview layout.
        mpPgPreviewLayout->ReInit();
 
        // correct calculation of new start page.
        if( nNewSttPage > nPageCount )
            nNewSttPage = nPageCount;
 
        // correct selected page number
        if( SelectedPage() > nPageCount )
            SetSelectedPage( nNewSttPage ? nNewSttPage : 1 );
    }
 
    mpPgPreviewLayout->Prepare( nNewSttPage, Point(0,0), maPxWinSize,
                              nNewSttPage,
                              maPaintedPreviewDocRect, bPaintPageAtFirstCol );
    if( nNewSttPage == mnSttPage &&
        eMoveMode != MV_SELPAGE )
        return false;
 
    SetPagePreview(mnRow, mnCol);
    mnSttPage = nNewSttPage;
 
    // additional invalidate page status.
    static sal_uInt16 aInval[] =
    {
        FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
        FN_STAT_PAGE, 0
    };
 
    SfxBindings& rBindings = mrView.GetViewFrame().GetBindings();
    rBindings.Invalidate( aInval );
 
    return true;
}
 
void SwPagePreviewWin::SetWinSize( const Size& rNewSize )
{
    // We always want the size as pixel units.
    maPxWinSize = LogicToPixel( rNewSize );
 
    if( USHRT_MAX == mnSttPage )
    {
        mnSttPage = GetDefSttPage();
        SetSelectedPage( GetDefSttPage() );
    }
 
    if ( mbCalcScaleForPreviewLayout )
    {
        mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
        maScale = GetMapMode().GetScaleX();
    }
    mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
                              mnSttPage, maPaintedPreviewDocRect );
    if ( mbCalcScaleForPreviewLayout )
    {
        SetSelectedPage( mnSttPage );
        mbCalcScaleForPreviewLayout = false;
    }
    SetPagePreview(mnRow, mnCol);
    maScale = GetMapMode().GetScaleX();
}
 
OUString SwPagePreviewWin::GetStatusStr( sal_uInt16 nPageCnt ) const
{
    // show physical and virtual page number of
    // selected page, if it's visible.
    const sal_uInt16 nPageNum = mpPgPreviewLayout->IsPageVisible( mpPgPreviewLayout->SelectedPage() )
        ? mpPgPreviewLayout->SelectedPage() : std::max<sal_uInt16>(mnSttPage, 1);
 
    OUString aStatusStr;
    const sal_uInt16 nVirtPageNum = mpPgPreviewLayout->GetVirtPageNumByPageNum( nPageNum );
    if( nVirtPageNum && nVirtPageNum != nPageNum )
    {
        aStatusStr = OUString::number(nVirtPageNum) + " " ;
    }
    return aStatusStr + OUString::number(nPageNum) + " / " + OUString::number(nPageCnt);
}
 
void  SwPagePreviewWin::KeyInput( const KeyEvent &rKEvt )
{
    const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
    bool bHandled = false;
    if(!rKeyCode.GetModifier())
    {
        sal_uInt16 nSlot = 0;
        switch(rKeyCode.GetCode())
        {
            case KEY_ADD : nSlot = SID_ZOOM_IN;         break;
            case KEY_ESCAPE: nSlot = FN_CLOSE_PAGEPREVIEW; break;
            case KEY_SUBTRACT : nSlot = SID_ZOOM_OUT;    break;
        }
        if(nSlot)
        {
            bHandled = true;
            mrView.GetViewFrame().GetDispatcher()->Execute(
                                nSlot, SfxCallMode::ASYNCHRON );
        }
    }
    if( !bHandled && !mrView.KeyInput( rKEvt ) )
        Window::KeyInput( rKEvt );
}
 
void SwPagePreviewWin::Command( const CommandEvent& rCEvt )
{
    bool bCallBase = true;
    switch( rCEvt.GetCommand() )
    {
        case CommandEventId::ContextMenu:
            SfxDispatcher::ExecutePopup();
            bCallBase = false;
        break;
 
        case CommandEventId::Wheel:
        case CommandEventId::StartAutoScroll:
        case CommandEventId::AutoScroll:
        {
            const CommandWheelData* pData = rCEvt.GetWheelData();
            if( pData )
            {
                const CommandWheelData aDataNew(pData->GetDelta(),pData->GetNotchDelta(),COMMAND_WHEEL_PAGESCROLL,
                    pData->GetMode(),pData->GetModifier(),pData->IsHorz(), pData->IsDeltaPixel());
                const CommandEvent aEvent( rCEvt.GetMousePosPixel(),rCEvt.GetCommand(),rCEvt.IsMouseEvent(),&aDataNew);
                bCallBase = !mrView.HandleWheelCommands( aEvent );
            }
            else
                bCallBase = !mrView.HandleWheelCommands( rCEvt );
       }
       break;
       default:
           ;
    }
 
    if( bCallBase )
        Window::Command( rCEvt );
}
 
void SwPagePreviewWin::MouseButtonDown( const MouseEvent& rMEvt )
{
    // consider single-click to set selected page
    if( MOUSE_LEFT != ( rMEvt.GetModifier() + rMEvt.GetButtons() ) )
        return;
 
    Point aPreviewPos( PixelToLogic( rMEvt.GetPosPixel() ) );
    Point aDocPos;
    bool bPosInEmptyPage;
    sal_uInt16 nNewSelectedPage;
    bool bIsDocPos =
        mpPgPreviewLayout->IsPreviewPosInDocPreviewPage( aPreviewPos,
                                aDocPos, bPosInEmptyPage, nNewSelectedPage );
    if ( bIsDocPos && rMEvt.GetClicks() == 2 )
    {
        // close page preview, set new cursor position and switch to
        // normal view.
        OUString sNewCursorPos = OUString::number( aDocPos.X() ) + ";" +
                               OUString::number( aDocPos.Y() ) + ";";
        mrView.SetNewCursorPos( sNewCursorPos );
 
        SfxViewFrame& rTmpFrame = mrView.GetViewFrame();
        rTmpFrame.GetBindings().Execute( SID_VIEWSHELL0, nullptr,
                                                SfxCallMode::ASYNCHRON );
    }
    else if ( bIsDocPos || bPosInEmptyPage )
    {
        // show clicked page as the selected one
        mpPgPreviewLayout->MarkNewSelectedPage( nNewSelectedPage );
        GetViewShell()->ShowPreviewSelection( nNewSelectedPage );
        // adjust position at vertical scrollbar.
        if ( mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() )
        {
            mrView.SetVScrollbarThumbPos( nNewSelectedPage );
        }
        // invalidate page status.
        static sal_uInt16 aInval[] =
        {
            FN_STAT_PAGE, 0
        };
        SfxBindings& rBindings = mrView.GetViewFrame().GetBindings();
        rBindings.Invalidate( aInval );
    }
}
 
// Set user prefs or view options
 
void SwPagePreviewWin::SetPagePreview( sal_Int16 nRow, sal_Int16 nCol )
{
    SwMasterUsrPref *pOpt = const_cast<SwMasterUsrPref *>(SW_MOD()->GetUsrPref(false));
 
    if (nRow != pOpt->GetPagePrevRow() || nCol != pOpt->GetPagePrevCol())
    {
        pOpt->SetPagePrevRow( nRow );
        pOpt->SetPagePrevCol( nCol );
        pOpt->SetModified();
 
        // Update scrollbar!
        mrView.ScrollViewSzChg();
    }
}
 
/** get selected page in document preview */
sal_uInt16 SwPagePreviewWin::SelectedPage() const
{
    return mpPgPreviewLayout->SelectedPage();
}
 
/** set selected page number in document preview */
void SwPagePreviewWin::SetSelectedPage( sal_uInt16 _nSelectedPageNum )
{
    mpPgPreviewLayout->SetSelectedPage( _nSelectedPageNum );
}
 
/** method to enable/disable book preview */
bool SwPagePreviewWin::SetBookPreviewMode( const bool _bBookPreview )
{
    return mpPgPreviewLayout->SetBookPreviewMode( _bBookPreview,
                                                mnSttPage,
                                                maPaintedPreviewDocRect );
}
 
void SwPagePreviewWin::DataChanged( const DataChangedEvent& rDCEvt )
{
    Window::DataChanged( rDCEvt );
 
    switch( rDCEvt.GetType() )
    {
    case DataChangedEventType::SETTINGS:
        // Rearrange the scrollbars or trigger resize, because the
        // size of the scrollbars may have be changed. Also the
        // size of the scrollbars has to be retrieved from the settings
        // out of the resize handler.
        if( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
            mrView.InvalidateBorder();              // Scrollbar widths
        // zoom has to be disabled if Accessibility support is switched on
        lcl_InvalidateZoomSlots(mrView.GetViewFrame().GetBindings());
        break;
 
    case DataChangedEventType::PRINTER:
    case DataChangedEventType::DISPLAY:
    case DataChangedEventType::FONTS:
    case DataChangedEventType::FONTSUBSTITUTION:
        mrView.GetDocShell()->UpdateFontList(); // Font change
        mpViewShell->InvalidateLayout(true);
        if ( mpViewShell->GetWin() )
            mpViewShell->GetWin()->Invalidate();
        break;
    default: break;
    }
}
 
void SwPagePreviewWin::ReInit()
{
    mpPgPreviewLayout->ReInit();
}
/** help method to execute SfxRequest FN_PAGEUP and FN_PAGEDOWN */
void SwPagePreview::ExecPgUpAndPgDown( const bool  _bPgUp,
                                        SfxRequest* _pReq )
{
    SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
    // check, if top/bottom of preview is *not* already visible.
    if( pPagePreviewLay->GetWinPagesScrollAmount( _bPgUp ? -1 : 1 ) != 0 )
    {
        if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() &&
             pPagePreviewLay->DoesPreviewLayoutColsFitIntoWindow() )
        {
            const int eMvMode = _bPgUp ?
                                SwPagePreviewWin::MV_PAGE_UP :
                                SwPagePreviewWin::MV_PAGE_DOWN;
            if ( ChgPage( eMvMode ) )
                m_pViewWin->Invalidate();
        }
        else
        {
            SwTwips nScrollAmount;
            sal_uInt16 nNewSelectedPageNum = 0;
            const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol();
            if( _bPgUp )
            {
                if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
                {
                    nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( -1 );
                    if ( (m_pViewWin->SelectedPage() - nVisPages) > 0 )
                        nNewSelectedPageNum = m_pViewWin->SelectedPage() - nVisPages;
                    else
                        nNewSelectedPageNum = 1;
                }
                else
                    nScrollAmount = - std::min( m_pViewWin->GetOutDev()->GetOutputSize().Height(),
                                           m_pViewWin->GetPaintedPreviewDocRect().Top() );
            }
            else
            {
                if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
                {
                    nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( 1 );
                    if ( (m_pViewWin->SelectedPage() + nVisPages) <= mnPageCount )
                        nNewSelectedPageNum = m_pViewWin->SelectedPage() + nVisPages;
                    else
                        nNewSelectedPageNum = mnPageCount;
                }
                else
                    nScrollAmount = std::min( m_pViewWin->GetOutDev()->GetOutputSize().Height(),
                                         ( pPagePreviewLay->GetPreviewDocSize().Height() -
                                           m_pViewWin->GetPaintedPreviewDocRect().Bottom() ) );
            }
            m_pViewWin->Scroll( 0, nScrollAmount );
            if ( nNewSelectedPageNum != 0 )
            {
                m_pViewWin->SetSelectedPage( nNewSelectedPageNum );
            }
            ScrollViewSzChg();
            // additional invalidate page status.
            static sal_uInt16 aInval[] =
            {
                FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
                FN_STAT_PAGE, 0
            };
            SfxBindings& rBindings = GetViewFrame().GetBindings();
            rBindings.Invalidate( aInval );
            m_pViewWin->Invalidate();
        }
    }
 
    if ( _pReq )
        _pReq->Done();
}
 
// Then all for the SwPagePreview
void  SwPagePreview::Execute( SfxRequest &rReq )
{
    int eMvMode = SwPagePreviewWin::MV_DOC_END;
    sal_Int16 nRow = 1;
    bool bRefresh = true;
 
    switch(rReq.GetSlot())
    {
        case SID_REFRESH_VIEW:
        case FN_STAT_PAGE:
        case FN_STAT_ZOOM:
            break;
 
        case FN_SHOW_MULTIPLE_PAGES:
        {
            const SfxItemSet *pArgs = rReq.GetArgs();
            if( pArgs && pArgs->Count() >= 2 )
            {
                sal_Int16 nCols = pArgs->Get(SID_ATTR_TABLE_COLUMN).GetValue();
                sal_Int16 nRows = pArgs->Get(SID_ATTR_TABLE_ROW).GetValue();
                m_pViewWin->CalcWish( nRows, nCols );
 
            }
            else
            {
                SwPreviewZoomDlg aDlg(*m_pViewWin);
                aDlg.execute();
            }
        }
        break;
        case FN_SHOW_BOOKVIEW:
        {
            const SfxItemSet* pArgs = rReq.GetArgs();
            const SfxPoolItem* pItem;
            bool bBookPreview = GetViewShell()->GetViewOptions()->IsPagePrevBookview();
            if( pArgs && SfxItemState::SET == pArgs->GetItemState( FN_SHOW_BOOKVIEW, false, &pItem ) )
            {
                bBookPreview = static_cast< const SfxBoolItem* >( pItem )->GetValue();
                const_cast<SwViewOption*>(GetViewShell()->GetViewOptions())->SetPagePrevBookview( bBookPreview );
                    // cast is not gentleman like, but it's common use in writer and in this case
            }
            if ( m_pViewWin->SetBookPreviewMode( bBookPreview ) )
            {
                // book preview mode changed. Thus, adjust scrollbars and
                // invalidate corresponding states.
                ScrollViewSzChg();
                static sal_uInt16 aInval[] =
                {
                    FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
                    FN_STAT_PAGE, FN_SHOW_BOOKVIEW, 0
                };
                SfxBindings& rBindings = GetViewFrame().GetBindings();
                rBindings.Invalidate( aInval );
                m_pViewWin->Invalidate();
            }
 
        }
        break;
        case FN_SHOW_TWO_PAGES:
            m_pViewWin->CalcWish( nRow, 2 );
            break;
 
        case FN_SHOW_SINGLE_PAGE:
            m_pViewWin->CalcWish( nRow, 1 );
            break;
 
        case FN_PREVIEW_ZOOM:
        case SID_ATTR_ZOOM:
        {
            const SfxItemSet *pArgs = rReq.GetArgs();
            ScopedVclPtr<AbstractSvxZoomDialog> pDlg;
            if(!pArgs)
            {
                SfxItemSetFixed<SID_ATTR_ZOOM, SID_ATTR_ZOOM> aCoreSet(GetPool());
                const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
                SvxZoomItem aZoom( pVOpt->GetZoomType(), pVOpt->GetZoom() );
                aZoom.SetValueSet(
                        SvxZoomEnableFlags::N50|
                        SvxZoomEnableFlags::N75|
                        SvxZoomEnableFlags::N100|
                        SvxZoomEnableFlags::N150|
                        SvxZoomEnableFlags::N200|
                        SvxZoomEnableFlags::WHOLEPAGE);
                aCoreSet.Put( aZoom );
 
                SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
                pDlg.disposeAndReset(pFact->CreateSvxZoomDialog(GetViewFrame().GetFrameWeld(), aCoreSet));
                pDlg->SetLimits( MINZOOM, MAXZOOM );
 
                if( pDlg->Execute() != RET_CANCEL )
                    pArgs = pDlg->GetOutputItemSet();
            }
            if( pArgs )
            {
                SvxZoomType eType = SvxZoomType::PERCENT;
                sal_uInt16 nZoomFactor = USHRT_MAX;
                if(const SvxZoomItem* pZoomItem = pArgs->GetItemIfSet(SID_ATTR_ZOOM))
                {
                    eType = pZoomItem->GetType();
                    nZoomFactor = pZoomItem->GetValue();
                }
                else if(const SfxUInt16Item* pPreviewItem = pArgs->GetItemIfSet(FN_PREVIEW_ZOOM))
                    nZoomFactor = pPreviewItem->GetValue();
                if(USHRT_MAX != nZoomFactor)
                    SetZoom(eType, nZoomFactor);
            }
        }
        break;
        case SID_ATTR_ZOOMSLIDER :
        {
            const SfxItemSet *pArgs = rReq.GetArgs();
            const SvxZoomSliderItem* pItem;
 
            if ( pArgs && (pItem = pArgs->GetItemIfSet(SID_ATTR_ZOOMSLIDER ) ) )
            {
                const sal_uInt16 nCurrentZoom = pItem->GetValue();
                SetZoom( SvxZoomType::PERCENT, nCurrentZoom );
            }
        }
        break;
        case SID_ZOOM_IN:
        case SID_ZOOM_OUT:
        {
            const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
            SetZoom(SvxZoomType::PERCENT,
                    lcl_GetNextZoomStep(pVOpt->GetZoom(), SID_ZOOM_IN == rReq.GetSlot()));
        }
        break;
        case FN_CHAR_LEFT:
        case FN_CHAR_RIGHT:
        case FN_LINE_UP:
        case FN_LINE_DOWN:
        {
            SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
            sal_uInt16 nNewSelectedPage;
            sal_uInt16 nNewStartPage;
            Point aNewStartPos;
            sal_Int16 nHoriMove = 0;
            sal_Int16 nVertMove = 0;
            switch(rReq.GetSlot())
            {
                case FN_CHAR_LEFT:  nHoriMove = -1; break;
                case FN_CHAR_RIGHT: nHoriMove = 1;  break;
                case FN_LINE_UP:    nVertMove = -1; break;
                case FN_LINE_DOWN:  nVertMove = 1;  break;
            }
            pPagePreviewLay->CalcStartValuesForSelectedPageMove( nHoriMove, nVertMove,
                                nNewSelectedPage, nNewStartPage, aNewStartPos );
            if ( m_pViewWin->SelectedPage() != nNewSelectedPage )
            {
                if ( pPagePreviewLay->IsPageVisible( nNewSelectedPage ) )
                {
                    pPagePreviewLay->MarkNewSelectedPage( nNewSelectedPage );
                    // adjust position at vertical scrollbar.
                    SetVScrollbarThumbPos( nNewSelectedPage );
                    bRefresh = false;
                }
                else
                {
                    m_pViewWin->SetSelectedPage( nNewSelectedPage );
                    m_pViewWin->SetSttPage( nNewStartPage );
                    bRefresh = ChgPage( SwPagePreviewWin::MV_SELPAGE );
                }
                GetViewShell()->ShowPreviewSelection( nNewSelectedPage );
                // invalidate page status.
                static sal_uInt16 aInval[] =
                {
                    FN_STAT_PAGE, 0
                };
                SfxBindings& rBindings = GetViewFrame().GetBindings();
                rBindings.Invalidate( aInval );
                rReq.Done();
            }
            else
            {
                bRefresh = false;
            }
            break;
        }
        case FN_PAGEUP:
        case FN_PAGEDOWN:
        {
            ExecPgUpAndPgDown( rReq.GetSlot() == FN_PAGEUP, &rReq );
            break;
        }
        case SID_JUMP_TO_SPECIFIC_PAGE:
        {
            const SfxItemSet *pArgs = rReq.GetArgs();
            if( pArgs && pArgs->Count())
            {
                sal_uInt16 nPageNum = static_cast<const SfxUInt16Item &>(pArgs->Get(SID_JUMP_TO_SPECIFIC_PAGE)).GetValue();
 
                if( nPageNum > 0 && nPageNum <= mnPageCount )
                {
                    m_pViewWin->SetSttPage( nPageNum);
                    m_pViewWin->SetSelectedPage( nPageNum );
                    ChgPage( SwPagePreviewWin::MV_SPECIFIC_PAGE, false );
                    ScrollViewSzChg();
                }
            }
        }
        break;
        case FN_START_OF_LINE:
        case FN_START_OF_DOCUMENT:
            eMvMode = SwPagePreviewWin::MV_DOC_STT;
            [[fallthrough]];
        case FN_END_OF_LINE:
        case FN_END_OF_DOCUMENT:
            m_pViewWin->SetSelectedPage(eMvMode == SwPagePreviewWin::MV_DOC_STT ? 1 : mnPageCount);
            {
                bool bRet = ChgPage( eMvMode );
                // return value for Basic
                rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), !bRet));
 
                bRefresh = bRet;
                rReq.Done();
            }
            break;
 
        case FN_PRINT_PAGEPREVIEW:
        {
            const SwPagePreviewPrtData* pPPVPD = m_pViewWin->GetViewShell()->GetDoc()->GetPreviewPrtData();
            // The thing with the orientation
            if(pPPVPD)
            {
                SfxPrinter* pPrinter = GetPrinter( true );
                if((pPrinter->GetOrientation() == Orientation::Landscape)
                        != pPPVPD->GetLandscape())
                    pPrinter->SetOrientation(pPPVPD->GetLandscape() ? Orientation::Landscape : Orientation::Portrait);
            }
            ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false );
            m_bNormalPrint = false;
            rReq.SetSlot( SID_PRINTDOC );
            SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
            rReq.SetSlot( FN_PRINT_PAGEPREVIEW );
            return;
        }
        case SID_PRINTDOCDIRECT:
        case SID_PRINTDOC:
            ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false );
            m_bNormalPrint = true;
            SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
            return;
        case FN_CLOSE_PAGEPREVIEW:
        case SID_PRINTPREVIEW:
            //  print preview is now always in the same frame as the tab view
            //  -> always switch this frame back to normal view
            //  (ScTabViewShell ctor reads stored view data)
            GetViewFrame().GetDispatcher()->Execute( SID_VIEWSHELL0, SfxCallMode::ASYNCHRON );
            break;
        case FN_INSERT_BREAK:
        {
            sal_uInt16 nSelPage = m_pViewWin->SelectedPage();
            //if a dummy page is selected (e.g. a non-existing right/left page)
            //the direct neighbor is used
            if(GetViewShell()->IsDummyPage( nSelPage ) && GetViewShell()->IsDummyPage( --nSelPage ))
                nSelPage +=2;
            m_nNewPage = nSelPage;
            SfxViewFrame& rTmpFrame = GetViewFrame();
            rTmpFrame.GetBindings().Execute( SID_VIEWSHELL0, nullptr,
                                                    SfxCallMode::ASYNCHRON );
        }
        break;
        default:
            OSL_ENSURE(false, "wrong dispatcher");
            return;
    }
 
    if( bRefresh )
        m_pViewWin->Invalidate();
}
 
void  SwPagePreview::GetState( SfxItemSet& rSet )
{
    SfxWhichIter aIter(rSet);
    sal_uInt16 nWhich = aIter.FirstWhich();
    OSL_ENSURE(nWhich, "empty set");
    SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
 
    while(nWhich)
    {
        switch(nWhich)
        {
        case SID_BROWSER_MODE:
        case FN_PRINT_LAYOUT:
            rSet.DisableItem(nWhich);
            break;
        case FN_START_OF_DOCUMENT:
        {
            if ( pPagePreviewLay->IsPageVisible( 1 ) )
                rSet.DisableItem(nWhich);
            break;
        }
        case FN_END_OF_DOCUMENT:
        {
            if ( pPagePreviewLay->IsPageVisible( mnPageCount ) )
                rSet.DisableItem(nWhich);
            break;
        }
        case FN_PAGEUP:
        {
            if( pPagePreviewLay->GetWinPagesScrollAmount( -1 ) == 0 )
                rSet.DisableItem(nWhich);
            break;
        }
        case FN_PAGEDOWN:
        {
            if( pPagePreviewLay->GetWinPagesScrollAmount( 1 ) == 0 )
                rSet.DisableItem(nWhich);
            break;
        }
 
        case FN_STAT_PAGE:
            {
                std::vector<OUString> aStringList
                {
                    m_sPageStr + m_pViewWin->GetStatusStr(mnPageCount),
                    OUString()
                };
                rSet.Put(SfxStringListItem(FN_STAT_PAGE, &aStringList));
            }
            break;
 
        case SID_ATTR_ZOOM:
        case FN_STAT_ZOOM:
            {
                    const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
                    SvxZoomItem aZoom(pVOpt->GetZoomType(), pVOpt->GetZoom());
                    aZoom.SetValueSet(
                            SvxZoomEnableFlags::N50|
                            SvxZoomEnableFlags::N75|
                            SvxZoomEnableFlags::N100|
                            SvxZoomEnableFlags::N150|
                            SvxZoomEnableFlags::N200);
                    rSet.Put( aZoom );
            }
        break;
        case SID_ATTR_ZOOMSLIDER :
            {
                    const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
                    const sal_uInt16 nCurrentZoom = pVOpt->GetZoom();
                    SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM );
                    aZoomSliderItem.AddSnappingPoint( 100 );
                    rSet.Put( aZoomSliderItem );
            }
        break;
        case FN_PREVIEW_ZOOM:
        {
                const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
                rSet.Put(SfxUInt16Item(nWhich, pVOpt->GetZoom()));
        }
        break;
        case SID_ZOOM_IN:
        case SID_ZOOM_OUT:
        {
            const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
            if((SID_ZOOM_IN == nWhich && pVOpt->GetZoom() >= MAX_PREVIEW_ZOOM) ||
                    (SID_ZOOM_OUT == nWhich && pVOpt->GetZoom() <= MIN_PREVIEW_ZOOM))
            {
                rSet.DisableItem(nWhich);
            }
        }
        break;
        case SID_ATTR_VIEWLAYOUT:
        {
            rSet.DisableItem( SID_ATTR_VIEWLAYOUT );
        }
        break;
        case FN_SHOW_MULTIPLE_PAGES:
        // should never be disabled
        break;
        case FN_SHOW_BOOKVIEW:
        {
            bool b = GetViewShell()->GetViewOptions()->IsPagePrevBookview();
            rSet.Put(SfxBoolItem(nWhich, b));
        }
        break;
 
        case FN_SHOW_TWO_PAGES:
            if( 2 == m_pViewWin->GetCol() && 1 == m_pViewWin->GetRow() )
                rSet.DisableItem( nWhich );
            break;
 
        case FN_PRINT_PAGEPREVIEW:
            // has the same status like the normal printing
            {
                const SfxPoolItem* pItem;
                SfxItemSetFixed<SID_PRINTDOC, SID_PRINTDOC> aSet( *rSet.GetPool() );
                GetSlotState( SID_PRINTDOC, SfxViewShell::GetInterface(), &aSet );
                if( SfxItemState::DISABLED == aSet.GetItemState( SID_PRINTDOC, false ))
                    rSet.DisableItem( nWhich );
                else if( SfxItemState::SET == aSet.GetItemState( SID_PRINTDOC,
                        false, &pItem ))
                {
                    const_cast<SfxPoolItem*>(pItem)->SetWhich( FN_PRINT_PAGEPREVIEW );
                    rSet.Put( *pItem );
                }
            }
            break;
 
        case SID_PRINTPREVIEW:
            rSet.Put( SfxBoolItem( nWhich, true ) );
            break;
 
        case SID_PRINTDOC:
        case SID_PRINTDOCDIRECT:
            GetSlotState( nWhich, SfxViewShell::GetInterface(), &rSet );
            break;
        }
        nWhich = aIter.NextWhich();
    }
}
 
void  SwPagePreview::StateUndo(SfxItemSet& rSet)
{
    SfxWhichIter aIter(rSet);
    sal_uInt16 nWhich = aIter.FirstWhich();
 
    while (nWhich)
    {
        rSet.DisableItem(nWhich);
        nWhich = aIter.NextWhich();
    }
}
 
void SwPagePreview::Init()
{
    if ( GetViewShell()->HasDrawView() )
        GetViewShell()->GetDrawView()->SetAnimationEnabled( false );
 
    m_bNormalPrint = true;
 
    // Check and process the DocSize. The shell could not be found via
    // the handler, because the shell is unknown to the SFX management
    // within the CTOR phase.
 
    const SwViewOption * pPrefs = SW_MOD()->GetUsrPref(false);
 
    mbHScrollbarEnabled = pPrefs->IsViewHScrollBar();
    mbVScrollbarEnabled = pPrefs->IsViewVScrollBar();
 
    // Update the fields
    // ATTENTION: Do cast the EditShell up, to use the SS.
    //            At the methods the current shell will be queried!
    SwEditShell* pESh = dynamic_cast<SwEditShell*>(GetViewShell());
    bool bIsModified = pESh != nullptr && pESh->IsModified();
 
    SwViewOption aOpt( *pPrefs );
    aOpt.SetPagePreview(true);
    aOpt.SetTab( false );
    aOpt.SetBlank( false );
    aOpt.SetHardBlank( false );
    aOpt.SetParagraph( false );
    aOpt.SetLineBreak( false );
    aOpt.SetPageBreak( false );
    aOpt.SetColumnBreak( false );
    aOpt.SetSoftHyph( false );
    aOpt.SetFieldName( false );
    aOpt.SetPostIts( false );
    aOpt.SetShowBookmarks( false );
    aOpt.SetShowHiddenChar( false );
    aOpt.SetShowHiddenField( false );
    aOpt.SetShowHiddenPara( false );
    aOpt.SetViewHRuler( false );
    aOpt.SetViewVRuler( false );
    aOpt.SetGraphic( true );
    aOpt.SetTable( true );
    aOpt.SetSnap( false );
    aOpt.SetGridVisible( false );
    aOpt.SetOnlineSpell( false );
    aOpt.SetHideWhitespaceMode( false );
 
    GetViewShell()->ApplyViewOptions( aOpt );
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
    GetViewShell()->ApplyAccessibilityOptions();
#endif
 
    // adjust view shell option to the same as for print
    SwPrintData const aPrintOptions = *SW_MOD()->GetPrtOptions(false);
    GetViewShell()->AdjustOptionsForPagePreview( aPrintOptions );
 
    GetViewShell()->CalcLayout();
    DocSzChgd( GetViewShell()->GetDocSize() );
 
    if( !bIsModified && pESh != nullptr )
        pESh->ResetModified();
}
 
SwPagePreview::SwPagePreview(SfxViewFrame& rViewFrame, SfxViewShell* pOldSh):
    SfxViewShell(rViewFrame, SWVIEWFLAGS),
    m_pViewWin( VclPtr<SwPagePreviewWin>::Create(&GetViewFrame().GetWindow(), *this ) ),
    m_nNewPage(USHRT_MAX),
    m_sPageStr(SwResId(STR_PAGE)),
    m_pHScrollbar(nullptr),
    m_pVScrollbar(nullptr),
    mnPageCount( 0 ),
    mbResetFormDesignMode( false ),
    mbFormDesignModeToReset( false )
{
    SetName(u"PageView"_ustr);
    SetWindow( m_pViewWin );
    CreateScrollbar( true );
    CreateScrollbar( false );
 
    SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Printpreview));
 
    SfxObjectShell* pObjShell = rViewFrame.GetObjectShell();
    if ( !pOldSh )
    {
        // Exists already a view on the document?
        SfxViewFrame *pF = SfxViewFrame::GetFirst( pObjShell );
        if (pF == &rViewFrame)
            pF = SfxViewFrame::GetNext( *pF, pObjShell );
        if ( pF )
            pOldSh = pF->GetViewShell();
    }
 
    SwViewShell *pVS, *pNew;
 
    if (SwPagePreview* pPagePreview = dynamic_cast<SwPagePreview*>(pOldSh))
        pVS = pPagePreview->GetViewShell();
    else
    {
        if (SwView* pView = dynamic_cast<SwView *>(pOldSh))
        {
            pVS = pView->GetWrtShellPtr();
            // save the current ViewData of the previous SwView
            pOldSh->WriteUserData( m_sSwViewData );
        }
        else
            pVS = GetDocShell()->GetWrtShell();
        if( pVS )
        {
            // Set the current page as the first.
            sal_uInt16 nPhysPg, nVirtPg;
            static_cast<SwCursorShell*>(pVS)->GetPageNum( nPhysPg, nVirtPg, true, false );
            if( 1 != m_pViewWin->GetCol() && 1 == nPhysPg )
                --nPhysPg;
            m_pViewWin->SetSttPage( nPhysPg );
        }
    }
 
    // for form shell remember design mode of draw view
    // of previous view shell
    if ( pVS && pVS->HasDrawView() )
    {
        mbResetFormDesignMode = true;
        mbFormDesignModeToReset = pVS->GetDrawView()->IsDesignMode();
    }
 
    if( pVS )
        pNew = new SwViewShell( *pVS, m_pViewWin, nullptr, VSHELLFLAG_ISPREVIEW );
    else
        pNew = new SwViewShell(
                *static_cast<SwDocShell*>(rViewFrame.GetObjectShell())->GetDoc(),
                m_pViewWin, nullptr, nullptr, VSHELLFLAG_ISPREVIEW );
 
    m_pViewWin->SetViewShell( pNew );
    pNew->SetSfxViewShell( this );
    Init();
}
 
SwPagePreview::~SwPagePreview()
{
    SetWindow( nullptr );
    SwViewShell* pVShell =  m_pViewWin->GetViewShell();
    pVShell->SetWin(nullptr);
    delete pVShell;
 
    m_pViewWin.disposeAndClear();
    m_pHScrollbar.disposeAndClear();
    m_pVScrollbar.disposeAndClear();
}
 
void SwPagePreview::Activate(bool bMDI)
{
    SfxViewShell::Activate(bMDI);
    SfxShell::Activate(bMDI);
}
 
SwDocShell* SwPagePreview::GetDocShell()
{
    return dynamic_cast<SwDocShell*>( GetViewFrame().GetObjectShell() );
}
 
void SwPagePreview::CreateScrollbar( bool bHori )
{
    vcl::Window *pMDI = &GetViewFrame().GetWindow();
    VclPtr<SwScrollbar>& ppScrollbar = bHori ? m_pHScrollbar : m_pVScrollbar;
 
    assert(!ppScrollbar); //check beforehand!
    ppScrollbar = VclPtr<SwScrollbar>::Create( pMDI, bHori );
 
    ScrollDocSzChg();
 
    if (bHori)
        ppScrollbar->SetScrollHdl( LINK( this, SwPagePreview, HoriScrollHdl ));
    else
        ppScrollbar->SetScrollHdl( LINK( this, SwPagePreview, VertScrollHdl ));
 
    InvalidateBorder();
    ppScrollbar->ExtendedShow();
}
 
bool SwPagePreview::ChgPage( int eMvMode, bool bUpdateScrollbar )
{
    tools::Rectangle aPixVisArea( m_pViewWin->LogicToPixel( m_aVisArea ) );
    bool bChg = m_pViewWin->MovePage( eMvMode ) ||
               eMvMode == SwPagePreviewWin::MV_CALC ||
               eMvMode == SwPagePreviewWin::MV_NEWWINSIZE;
    m_aVisArea = m_pViewWin->PixelToLogic( aPixVisArea );
 
    if( bChg )
    {
        // Update statusbar
        SfxBindings& rBindings = GetViewFrame().GetBindings();
 
        if( bUpdateScrollbar )
        {
            ScrollViewSzChg();
 
            static sal_uInt16 aInval[] =
            {
                FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT,
                FN_PAGEUP, FN_PAGEDOWN, 0
            };
            rBindings.Invalidate( aInval );
        }
        std::vector<OUString> aStringList
        {
            m_sPageStr + m_pViewWin->GetStatusStr(mnPageCount),
            OUString()
        };
        rBindings.SetState(SfxStringListItem(FN_STAT_PAGE, &aStringList));
    }
    return bChg;
}
 
// From here, everything was taken from the SwView.
void SwPagePreview::CalcAndSetBorderPixel( SvBorder &rToFill )
{
    const StyleSettings &rSet = m_pViewWin->GetSettings().GetStyleSettings();
    const tools::Long nTmp = rSet.GetScrollBarSize();
    if (m_pVScrollbar->IsScrollbarVisible(true))
        rToFill.Right()  = nTmp;
    if (m_pHScrollbar->IsScrollbarVisible(true))
        rToFill.Bottom() = nTmp;
    SetBorderPixel( rToFill );
}
 
void  SwPagePreview::InnerResizePixel( const Point &rOfst, const Size &rSize, bool )
{
    SvBorder aBorder;
    CalcAndSetBorderPixel( aBorder );
    tools::Rectangle aRect( rOfst, rSize );
    aRect += aBorder;
    ViewResizePixel( *m_pViewWin->GetOutDev(), aRect.TopLeft(), aRect.GetSize(),
                    m_pViewWin->GetOutputSizePixel(),
                    *m_pVScrollbar, *m_pHScrollbar );
 
    // Never set EditWin !
    // Never set VisArea !
}
 
void SwPagePreview::OuterResizePixel( const Point &rOfst, const Size &rSize )
{
    SvBorder aBorder;
    CalcAndSetBorderPixel( aBorder );
 
    // Never set EditWin !
 
    Size aTmpSize( m_pViewWin->GetOutputSizePixel() );
    Point aBottomRight( m_pViewWin->PixelToLogic( Point( aTmpSize.Width(), aTmpSize.Height() ) ) );
    SetVisArea( tools::Rectangle( Point(), aBottomRight ) );
 
    // Call of the DocSzChgd-Method of the scrollbars is necessary,
    // because from the maximum scroll range half the height of the
    // VisArea is always deducted.
    if ( m_pVScrollbar && !aTmpSize.IsEmpty() )
    {
        ScrollDocSzChg();
    }
 
    SvBorder aBorderNew;
    CalcAndSetBorderPixel( aBorderNew );
    ViewResizePixel( *m_pViewWin->GetOutDev(), rOfst, rSize, m_pViewWin->GetOutputSizePixel(),
                    *m_pVScrollbar, *m_pHScrollbar );
}
 
void SwPagePreview::SetVisArea( const tools::Rectangle &rRect )
{
    const Point aTopLeft(AlignToPixel(rRect.TopLeft()));
    const Point aBottomRight(AlignToPixel(rRect.BottomRight()));
    tools::Rectangle aLR(aTopLeft,aBottomRight);
 
    if(aLR == m_aVisArea)
        return;
        // No negative position, no negative size
 
    if(aLR.Top() < 0)
    {
        aLR.AdjustBottom(std::abs(aLR.Top()) );
        aLR.SetTop( 0 );
    }
 
    if(aLR.Left() < 0)
    {
        aLR.AdjustRight(std::abs(aLR.Left()) );
        aLR.SetLeft( 0 );
    }
    if(aLR.Right() < 0) aLR.SetRight( 0 );
    if(aLR.Bottom() < 0) aLR.SetBottom( 0 );
    if(aLR == m_aVisArea ||
        // Ignore empty rectangle
        ( 0 == aLR.Bottom() - aLR.Top() && 0 == aLR.Right() - aLR.Left() ) )
        return;
 
    if( aLR.Left() > aLR.Right() || aLR.Top() > aLR.Bottom() )
        return;
 
    // Before the data can be changed call an update if necessary.
    // Thereby ensured, that adjacent paints are correctly converted into
    // document coordinates.
    // As a precaution, we do this only when at the shell runs an action,
    // because then we do not really paint but the rectangles are just
    // bookmarked (in document coordinates).
    if( GetViewShell()->ActionPend() )
        m_pViewWin->PaintImmediately();
 
    // Set at View-Win the current size
    m_aVisArea = aLR;
    m_pViewWin->SetWinSize( aLR.GetSize() );
    ChgPage( SwPagePreviewWin::MV_NEWWINSIZE );
 
    m_pViewWin->Invalidate();
}
 
void SwPagePreview::PrintSettingsChanged()
{
    m_pViewWin->ReInit();
    ChgPage( SwPagePreviewWin::MV_DOC_STT );
}
 
IMPL_LINK(SwPagePreview, HoriScrollHdl, weld::Scrollbar&, rScrollbar, void)
{
    ScrollHdl(rScrollbar, true);
}
 
IMPL_LINK(SwPagePreview, VertScrollHdl, weld::Scrollbar&, rScrollbar, void)
{
    ScrollHdl(rScrollbar, false);
}
 
void SwPagePreview::ScrollHdl(weld::Scrollbar& rScrollbar, bool bHori)
{
    if(!GetViewShell())
        return;
 
    EndScrollHdl(rScrollbar, bHori);
 
    if( !bHori &&
        rScrollbar.get_scroll_type() == ScrollType::Drag &&
        Help::IsQuickHelpEnabled() &&
        GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow())
    {
        // Scroll how many pages??
        OUString sStateStr(m_sPageStr);
        tools::Long nThmbPos = rScrollbar.adjustment_get_value();
        if( 1 == m_pViewWin->GetCol() || !nThmbPos )
            ++nThmbPos;
        sStateStr += OUString::number( nThmbPos );
        Point aPos = m_pVScrollbar->GetParent()->OutputToScreenPixel(
                                        m_pVScrollbar->GetPosPixel());
        aPos.setY( m_pVScrollbar->OutputToScreenPixel(m_pVScrollbar->GetPointerPosPixel()).Y() );
        tools::Rectangle aRect;
        aRect.SetLeft( aPos.X() -8 );
        aRect.SetRight( aRect.Left() );
        aRect.SetTop( aPos.Y() );
        aRect.SetBottom( aRect.Top() );
 
        Help::ShowQuickHelp(m_pVScrollbar, aRect, sStateStr,
                QuickHelpFlags::Right|QuickHelpFlags::VCenter);
 
    }
}
 
void SwPagePreview::EndScrollHdl(weld::Scrollbar& rScrollbar, bool bHori)
{
    if(!GetViewShell())
        return;
 
    // boolean to avoid unnecessary invalidation of the window.
    bool bInvalidateWin = true;
 
    if (!bHori)       // scroll vertically
    {
        if ( Help::IsQuickHelpEnabled() )
            Help::ShowQuickHelp(m_pVScrollbar, tools::Rectangle(), OUString());
        SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
        if (pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
        {
            // Scroll how many pages ??
            const sal_uInt16 nThmbPos = pPagePreviewLay->ConvertRelativeToAbsolutePageNum(
                o3tl::narrowing<sal_uInt16>(rScrollbar.adjustment_get_value()) );
            // adjust to new preview functionality
            if( nThmbPos != m_pViewWin->SelectedPage() )
            {
                // consider case that page <nThmbPos>
                // is already visible
                if ( pPagePreviewLay->IsPageVisible( nThmbPos ) )
                {
                    pPagePreviewLay->MarkNewSelectedPage( nThmbPos );
                    // invalidation of window is unnecessary
                    bInvalidateWin = false;
                }
                else
                {
                    // consider whether layout columns
                    m_pViewWin->SetSttPage( nThmbPos );
                    m_pViewWin->SetSelectedPage( nThmbPos );
                    ChgPage( SwPagePreviewWin::MV_SCROLL, false );
                    // update scrollbars
                    ScrollViewSzChg();
                }
                // update accessibility
                GetViewShell()->ShowPreviewSelection( nThmbPos );
            }
            else
            {
                // invalidation of window is unnecessary
                bInvalidateWin = false;
            }
        }
        else
        {
            tools::Long nThmbPos = rScrollbar.adjustment_get_value();
            m_pViewWin->Scroll(0, nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Top());
        }
    }
    else
    {
        tools::Long nThmbPos = rScrollbar.adjustment_get_value();
        m_pViewWin->Scroll(nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Left(), 0);
    }
    // additional invalidate page status.
    static sal_uInt16 aInval[] =
    {
        FN_START_OF_DOCUMENT, FN_END_OF_DOCUMENT, FN_PAGEUP, FN_PAGEDOWN,
        FN_STAT_PAGE, 0
    };
    SfxBindings& rBindings = GetViewFrame().GetBindings();
    rBindings.Invalidate( aInval );
    // control invalidation of window
    if ( bInvalidateWin )
    {
        m_pViewWin->Invalidate();
    }
}
 
Point SwPagePreview::AlignToPixel(const Point &rPt) const
{
    return m_pViewWin->PixelToLogic( m_pViewWin->LogicToPixel( rPt ) );
}
 
void SwPagePreview::DocSzChgd( const Size &rSz )
{
    if( m_aDocSize == rSz )
        return;
 
    m_aDocSize = rSz;
 
    // #i96726#
    // Due to the multiple page layout it is needed to trigger recalculation
    // of the page preview layout, even if the count of pages is not changing.
    mnPageCount = GetViewShell()->GetNumPages();
 
    if( m_aVisArea.GetWidth() )
    {
        ChgPage( SwPagePreviewWin::MV_CALC );
        ScrollDocSzChg();
 
        m_pViewWin->Invalidate();
    }
}
 
void SwPagePreview::ScrollViewSzChg()
{
    if(!GetViewShell())
        return ;
 
    bool bShowVScrollbar = false, bShowHScrollbar = false;
 
    if(m_pVScrollbar)
    {
        if(GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow())
        {
            //vertical scrolling by row
            // adjust to new preview functionality
            const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol();
 
            m_pVScrollbar->SetVisibleSize( nVisPages );
            // set selected page as scroll bar position,
            // if it is visible.
            SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
            if ( pPagePreviewLay->IsPageVisible( m_pViewWin->SelectedPage() ) )
            {
                m_pVScrollbar->SetThumbPos(
                    pPagePreviewLay->ConvertAbsoluteToRelativePageNum(m_pViewWin->SelectedPage()) );
            }
            else
            {
                m_pVScrollbar->SetThumbPos(
                    pPagePreviewLay->ConvertAbsoluteToRelativePageNum(m_pViewWin->GetSttPage()) );
            }
            m_pVScrollbar->SetLineSize( m_pViewWin->GetCol() );
            m_pVScrollbar->SetPageSize( nVisPages );
            // calculate and set scrollbar range
            Range aScrollbarRange( 1, pPagePreviewLay->GetMaxPreviewPages() );
            // increase range by one, because left-top-corner is left blank.
            ++aScrollbarRange.Max();
            // increase range in order to access all pages
            aScrollbarRange.Max() += ( nVisPages - 1 );
            m_pVScrollbar->SetRange( aScrollbarRange );
 
            bShowVScrollbar = nVisPages < pPagePreviewLay->GetMaxPreviewPages();
        }
        else //vertical scrolling by pixel
        {
            const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect();
            const Size aPreviewSize =
                    GetViewShell()->PagePreviewLayout()->GetPreviewDocSize();
            m_pVScrollbar->SetRangeMax(aPreviewSize.Height()) ;
            tools::Long nVisHeight = rDocRect.GetHeight();
            m_pVScrollbar->SetVisibleSize( nVisHeight );
            m_pVScrollbar->SetThumbPos( rDocRect.Top() );
            m_pVScrollbar->SetLineSize( nVisHeight / 10 );
            m_pVScrollbar->SetPageSize( nVisHeight / 2 );
 
            bShowVScrollbar = true;
        }
 
        if (!mbVScrollbarEnabled)
            bShowVScrollbar = false;
 
        ShowVScrollbar(bShowVScrollbar);
    }
    if(m_pHScrollbar)
    {
        const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect();
        const Size aPreviewSize =
                GetViewShell()->PagePreviewLayout()->GetPreviewDocSize();
        Range aRange(0,0);
 
        if(rDocRect.GetWidth() < aPreviewSize.Width())
        {
            bShowHScrollbar = true;
 
            tools::Long nVisWidth = rDocRect.GetWidth();
            tools::Long nThumb = rDocRect.Left();
            aRange = Range(0, aPreviewSize.Width());
 
            m_pHScrollbar->SetRange( aRange );
            m_pHScrollbar->SetVisibleSize( nVisWidth );
            m_pHScrollbar->SetThumbPos( nThumb );
            m_pHScrollbar->SetLineSize( nVisWidth / 10 );
            m_pHScrollbar->SetPageSize( nVisWidth / 2 );
        }
 
        if (!mbHScrollbarEnabled)
            bShowHScrollbar = false;
 
        ShowHScrollbar(bShowHScrollbar);
    }
}
 
void SwPagePreview::ScrollDocSzChg()
{
    ScrollViewSzChg();
}
 
// All about printing
SfxPrinter*  SwPagePreview::GetPrinter( bool bCreate )
{
    return m_pViewWin->GetViewShell()->getIDocumentDeviceAccess().getPrinter( bCreate );
}
 
sal_uInt16  SwPagePreview::SetPrinter( SfxPrinter *pNew, SfxPrinterChangeFlags nDiffFlags )
{
    SwViewShell &rSh = *GetViewShell();
    SfxPrinter* pOld = rSh.getIDocumentDeviceAccess().getPrinter( false );
    if ( pOld && pOld->IsPrinting() )
        return SFX_PRINTERROR_BUSY;
 
    SwEditShell &rESh = static_cast<SwEditShell&>(rSh);  //Buh...
    if( ( SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP ) & nDiffFlags )
    {
        rSh.getIDocumentDeviceAccess().setPrinter( pNew, true, true );
        if( nDiffFlags & SfxPrinterChangeFlags::PRINTER )
            rESh.SetModified();
    }
    if ( ( nDiffFlags & SfxPrinterChangeFlags::OPTIONS ) == SfxPrinterChangeFlags::OPTIONS )
        ::SetPrinter( &rSh.getIDocumentDeviceAccess(), pNew, false );
 
    const bool bChgOri  = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION);
    const bool bChgSize = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE);
    if ( bChgOri || bChgSize )
    {
        rESh.StartAllAction();
        if ( bChgOri )
            rSh.ChgAllPageOrientation( pNew->GetOrientation() );
        if ( bChgSize )
        {
            Size aSz( SvxPaperInfo::GetPaperSize( pNew ) );
            rSh.ChgAllPageSize( aSz );
        }
        if( !m_bNormalPrint )
            m_pViewWin->CalcWish( m_pViewWin->GetRow(), m_pViewWin->GetCol() );
        rESh.SetModified();
        rESh.EndAllAction();
 
        static sal_uInt16 aInval[] =
        {
            SID_ATTR_LONG_ULSPACE, SID_ATTR_LONG_LRSPACE,
            SID_RULER_BORDERS, SID_RULER_PAGE_POS, 0
        };
#if OSL_DEBUG_LEVEL > 0
        {
            const sal_uInt16* pPtr = aInval + 1;
            do {
                OSL_ENSURE( *(pPtr - 1) < *pPtr, "wrong sorting!" );
            } while( *++pPtr );
        }
#endif
 
        GetViewFrame().GetBindings().Invalidate(aInval);
    }
 
    return 0;
}
 
bool SwPagePreview::HasPrintOptionsPage() const
{
    return true;
}
 
std::unique_ptr<SfxTabPage> SwPagePreview::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController,
                                                         const SfxItemSet &rOptions)
{
    return ::CreatePrintOptionsPage(pPage, pController, rOptions, !m_bNormalPrint);
}
 
void SwPagePreviewWin::SetViewShell( SwViewShell* pShell )
{
    mpViewShell = pShell;
    if ( mpViewShell && mpViewShell->IsPreview() )
    {
        mpPgPreviewLayout = mpViewShell->PagePreviewLayout();
    }
}
 
void SwPagePreviewWin::RepaintCoreRect( const SwRect& rRect )
{
    // #i24183#
    if ( mpPgPreviewLayout->PreviewLayoutValid() )
    {
        mpPgPreviewLayout->Repaint( tools::Rectangle( rRect.Pos(), rRect.SSize() ) );
    }
}
 
/** method to adjust preview to a new zoom factor
 
    #i19975# also consider zoom type - adding parameter <_eZoomType>
*/
void SwPagePreviewWin::AdjustPreviewToNewZoom( const sal_uInt16 _nZoomFactor,
                                               const SvxZoomType _eZoomType )
{
    // #i19975# consider zoom type
    if ( _eZoomType == SvxZoomType::WHOLEPAGE )
    {
        mnRow = 1;
        mnCol = 1;
        mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
        mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
                                  mnSttPage, maPaintedPreviewDocRect );
        SetSelectedPage( mnSttPage );
        SetPagePreview(mnRow, mnCol);
        maScale = GetMapMode().GetScaleX();
    }
    else if ( _nZoomFactor != 0 )
    {
        // calculate new scaling and set mapping mode appropriately.
        Fraction aNewScale( _nZoomFactor, 100 );
        MapMode aNewMapMode = GetMapMode();
        aNewMapMode.SetScaleX( aNewScale );
        aNewMapMode.SetScaleY( aNewScale );
        SetMapMode( aNewMapMode );
 
        // calculate new start position for preview paint
        Size aNewWinSize = PixelToLogic( maPxWinSize );
        Point aNewPaintStartPos =
                mpPgPreviewLayout->GetPreviewStartPosForNewScale( aNewScale, maScale, aNewWinSize );
 
        // remember new scaling and prepare preview paint
        // Note: paint of preview will be performed by a corresponding invalidate
        //          due to property changes.
        maScale = aNewScale;
        mpPgPreviewLayout->Prepare( 0, aNewPaintStartPos, maPxWinSize,
                                  mnSttPage, maPaintedPreviewDocRect );
    }
 
}
 
/**
 * pixel scrolling - horizontally always or vertically
 * when less than the desired number of rows fits into
 * the view
 */
void SwPagePreviewWin::Scroll(tools::Long nXMove, tools::Long nYMove, ScrollFlags /*nFlags*/)
{
    maPaintedPreviewDocRect.Move(nXMove, nYMove);
    mpPgPreviewLayout->Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
                              maPxWinSize, mnSttPage,
                              maPaintedPreviewDocRect );
 
}
 
bool SwPagePreview::HandleWheelCommands( const CommandEvent& rCEvt )
{
    bool bOk = false;
    const CommandWheelData* pWData = rCEvt.GetWheelData();
    if( pWData && CommandWheelMode::ZOOM == pWData->GetMode() )
    {
        sal_uInt16 nFactor = GetViewShell()->GetViewOptions()->GetZoom();
        const sal_uInt16 nOffset = 10;
        if( 0L > pWData->GetDelta() )
        {
            nFactor -= nOffset;
            if(nFactor < MIN_PREVIEW_ZOOM)
                nFactor = MIN_PREVIEW_ZOOM;
        }
        else
        {
            nFactor += nOffset;
            if(nFactor > MAX_PREVIEW_ZOOM)
                nFactor = MAX_PREVIEW_ZOOM;
        }
        SetZoom(SvxZoomType::PERCENT, nFactor);
        bOk = true;
    }
    else
        bOk = m_pViewWin->HandleScrollCommand( rCEvt, m_pHScrollbar, m_pVScrollbar );
    return bOk;
}
 
uno::Reference< css::accessibility::XAccessible >
    SwPagePreviewWin::CreateAccessible()
{
    SolarMutexGuard aGuard; // this should have happened already!!!
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
    OSL_ENSURE( GetViewShell() != nullptr, "We need a view shell" );
    css::uno::Reference< css::accessibility::XAccessible > xAcc = GetAccessible( false );
    if (xAcc.is())
    {
        return xAcc;
    }
    if (mpViewShell)
    {
        css::uno::Reference< css::accessibility::XAccessible > xAccPreview = mpViewShell->CreateAccessiblePreview();
        SetAccessible(xAccPreview);
    }
#endif
    return GetAccessible( false );
}
 
void SwPagePreview::ShowHScrollbar(bool bShow)
{
    m_pHScrollbar->Show(bShow);
    InvalidateBorder();
}
 
void SwPagePreview::ShowVScrollbar(bool bShow)
{
    m_pVScrollbar->Show(bShow);
    InvalidateBorder();
}
 
void SwPagePreview::EnableHScrollbar(bool bEnable)
{
    if (mbHScrollbarEnabled != bEnable)
    {
        mbHScrollbarEnabled = bEnable;
        ScrollViewSzChg();
    }
}
 
void SwPagePreview::EnableVScrollbar(bool bEnable)
{
    if (mbVScrollbarEnabled != bEnable)
    {
        mbVScrollbarEnabled = bEnable;
        ScrollViewSzChg();
    }
}
 
void SwPagePreview::SetZoom(SvxZoomType eType, sal_uInt16 nFactor)
{
    SwViewShell& rSh = *GetViewShell();
    SwViewOption aOpt(*rSh.GetViewOptions());
    // perform action only on changes of zoom or zoom type.
    if ( aOpt.GetZoom() != nFactor ||
         aOpt.GetZoomType() != eType )
    {
        aOpt.SetZoom(nFactor);
        aOpt.SetZoomType(eType);
        rSh.ApplyViewOptions( aOpt );
        lcl_InvalidateZoomSlots(GetViewFrame().GetBindings());
        // #i19975# also consider zoom type
        m_pViewWin->AdjustPreviewToNewZoom( nFactor, eType );
        ScrollViewSzChg();
    }
}
 
/** adjust position of vertical scrollbar */
void SwPagePreview::SetVScrollbarThumbPos( const sal_uInt16 _nNewThumbPos )
{
    if ( m_pVScrollbar )
    {
        m_pVScrollbar->SetThumbPos( _nNewThumbPos );
    }
}
 
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

V530 The return value of function 'Execute' is required to be utilized.

V530 The return value of function 'Execute' is required to be utilized.

V1054 Object slicing. Base class instance was initialized with derived class instance.