Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/source/uibase/uiview/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 44 kB image not shown  

Quelle  viewport.cxx   Sprache: C

 
/* -*- 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 <vcl/commandevent.hxx>
#include <vcl/help.hxx>
#include <vcl/settings.hxx>
#include <vcl/syswin.hxx>

#include <svx/ruler.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <view.hxx>
#include <wrtsh.hxx>
#include <viewopt.hxx>
#include <docsh.hxx>
#include <cmdid.h>
#include <edtwin.hxx>
#include <scroll.hxx>

#include <PostItMgr.hxx>

#include <basegfx/utils/zoomtools.hxx>
#include <comphelper/lok.hxx>
#include <vcl/weld.hxx>
#include <tools/svborder.hxx>
#include <osl/diagnose.h>

#include "viewfunc.hxx"

#include <FrameControlsManager.hxx>

// The SetVisArea of the DocShell must not be called from InnerResizePixel.
// But our adjustments must take place.
static bool bProtectDocShellVisArea = false;

static sal_uInt16 nPgNum = 0;

bool SwView::IsDocumentBorder()
{
    if (GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)
        return true;

    if (!m_pWrtShell)
        return false;

    return m_pWrtShell->GetViewOptions()->getBrowseMode() ||
           SvxZoomType::PAGEWIDTH_NOBORDER == m_pWrtShell->GetViewOptions()->GetZoomType();
}

static tools::Long GetLeftMargin( SwView const &rView )
{
    SvxZoomType eType = rView.GetWrtShell().GetViewOptions()->GetZoomType();
    tools::Long lRet = rView.GetWrtShell().GetAnyCurRect(CurRectType::PagePrt).Left();
    return eType == SvxZoomType::PERCENT   ? lRet + DOCUMENTBORDER :
           eType == SvxZoomType::PAGEWIDTH || eType == SvxZoomType::PAGEWIDTH_NOBORDER ? 0 :
                                         lRet + DOCUMENTBORDER + nLeftOfst;
}

static void lcl_GetPos(SwView const * pView,
                Point& rPos,
                const weld::Scrollbar& rScrollbar,
                bool bHori,
                bool bBorder)
{
    SwWrtShell &rSh = pView->GetWrtShell();
    const Size aDocSz( rSh.GetDocSize() );

    const tools::Long lBorder = bBorder ? DOCUMENTBORDER : DOCUMENTBORDER * 2;

    const tools::Long lPos = rScrollbar.adjustment_get_value() + (bBorder ? DOCUMENTBORDER : 0);

    tools::Long lDelta = lPos - (bHori ? rSh.VisArea().Pos().X() : rSh.VisArea().Pos().Y());

    const tools::Long lSize = (bHori ? aDocSz.Width() : aDocSz.Height()) + lBorder;
    // Should right or below are too much space,
    // then they must be subtracted out of the VisArea!
    tools::Long nTmp = pView->GetVisArea().Right()+lDelta;
    if ( bHori && nTmp > lSize )
        lDelta -= nTmp - lSize;
    nTmp = pView->GetVisArea().Bottom()+lDelta;
    if ( !bHori && nTmp > lSize )
        lDelta -= nTmp - lSize;

    bHori ? rPos.AdjustX(lDelta) : rPos.AdjustY(lDelta);
    if ( bBorder && (bHori ? rPos.X() : rPos.Y()) < DOCUMENTBORDER )
        bHori ? rPos.setX(DOCUMENTBORDER) : rPos.setY(DOCUMENTBORDER);
}

// Set zero ruler

void SwView::InvalidateRulerPos()
{
    static sal_uInt16 aInval[] =
    {
        SID_ATTR_PARA_LRSPACE, SID_RULER_BORDERS, SID_RULER_PAGE_POS,
        SID_RULER_LR_MIN_MAX, SID_ATTR_LONG_ULSPACE, SID_ATTR_LONG_LRSPACE,
        SID_RULER_BORDER_DISTANCE,
        SID_ATTR_PARA_LRSPACE_VERTICAL, SID_RULER_BORDERS_VERTICAL,
        SID_RULER_TEXT_RIGHT_TO_LEFT,
        SID_RULER_ROWS, SID_RULER_ROWS_VERTICAL, FN_STAT_PAGE,
        0
    };

    GetViewFrame().GetBindings().Invalidate(aInval);

    assert(m_pHRuler && "Why is the ruler not there?");
    m_pHRuler->ForceUpdate();
    m_pVRuler->ForceUpdate();
}

// Limits the scrolling so far that only a quarter of the
// screen can be scrolled up before the end of the document.

tools::Long SwView::SetHScrollMax( tools::Long lMax )
{
    const tools::Long lBorder = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER * 2;
    const tools::Long lSize = GetDocSz().Width() + lBorder - m_aVisArea.GetWidth();

    // At negative values the document is completely visible.
    // In this case, no scrolling.
    return std::clamp( lSize, tools::Long(0), lMax );
}

tools::Long SwView::SetVScrollMax( tools::Long lMax )
{
    const tools::Long lBorder = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER * 2;
    tools::Long lSize = GetDocSz().Height() + lBorder - m_aVisArea.GetHeight();
    return std::clamp( lSize, tools::Long(0), lMax );        // see horizontal
}

Point SwView::AlignToPixel(const Point &rPt) const
{
    return GetEditWin().PixelToLogic( GetEditWin().LogicToPixel( rPt ) );
}

// Document size has changed.

void SwView::DocSzChgd(const Size &rSz)
{
    m_aDocSz = rSz;

    if( !m_pWrtShell || m_aVisArea.IsEmpty() )      // no shell -> no change
    {
        bDocSzUpdated = false;
        return;
    }

    //If text has been deleted, it may be that the VisArea points behind the visible range.
    tools::Rectangle aNewVisArea( m_aVisArea );
    bool bModified = false;
    SwTwips lGreenOffset = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER * 2;
    SwTwips lTmp = m_aDocSz.Width() + lGreenOffset;

    if ( aNewVisArea.Right() >= lTmp  )
    {
        lTmp = aNewVisArea.Right() - lTmp;
        aNewVisArea.AdjustRight( -lTmp );
        aNewVisArea.AdjustLeft( -lTmp );
        bModified = true;
    }

    lTmp = m_aDocSz.Height() + lGreenOffset;
    if ( aNewVisArea.Bottom() >= lTmp )
    {
        lTmp = aNewVisArea.Bottom() - lTmp;
        aNewVisArea.AdjustBottom( -lTmp );
        aNewVisArea.AdjustTop( -lTmp );
        bModified = true;
    }

    if ( bModified )
        SetVisArea( aNewVisArea, false );

    if ( UpdateScrollbars() && !m_bInOuterResizePixel && !m_bInInnerResizePixel &&
            !GetViewFrame().GetFrame().IsInPlace())
        OuterResizePixel( Point(),
                          GetViewFrame().GetWindow().GetOutputSizePixel() );
}

// Set VisArea newly

void SwView::SetVisArea( const tools::Rectangle &rRect, bool bUpdateScrollbar )
{
    Size aOldSz( m_aVisArea.GetSize() );
    if (comphelper::LibreOfficeKit::isActive() && m_pWrtShell)
        // If m_pWrtShell's visible area is the whole document, do the same here.
        aOldSz = m_pWrtShell->VisArea().SSize();

    if( rRect == m_aVisArea )
        return;

    const SwTwips lMin = IsDocumentBorder() ? DOCUMENTBORDER : 0;

    // No negative position, no negative size
    tools::Rectangle aLR = rRect;
    if( aLR.Top() < lMin )
    {
        aLR.AdjustBottom(lMin - aLR.Top() );
        aLR.SetTop( lMin );
    }
    if( aLR.Left() < lMin )
    {
        aLR.AdjustRight(lMin - aLR.Left() );
        aLR.SetLeft( lMin );
    }
    if( aLR.Right() < 0 )
        aLR.SetRight( 0 );
    if( aLR.Bottom() < 0 )
        aLR.SetBottom( 0 );

    if( aLR == m_aVisArea )
        return;

    const Size aSize( aLR.GetSize() );
    if( aSize.IsEmpty() )
        return;

    // Before the data can be changed, call an update if necessary. This
    // ensures that adjacent Paints in document coordinates are converted
    // correctly.
    // As a precaution, we do this only when an action is running in the
    // shell, because then it is not really drawn but the rectangles will
    // be only marked (in document coordinates).
    if ( m_pWrtShell && m_pWrtShell->ActionPend() )
        m_pWrtShell->GetWin()->PaintImmediately();

    m_aVisArea = aLR;

    const bool bOuterResize = bUpdateScrollbar && UpdateScrollbars();

    if ( m_pWrtShell )
    {
        m_pWrtShell->VisPortChgd( SwRect(m_aVisArea) );
        if ( aOldSz != m_pWrtShell->VisArea().SSize() &&
             ( std::abs(aOldSz.Width() - m_pWrtShell->VisArea().Width()) > 2 ||
                std::abs(aOldSz.Height() - m_pWrtShell->VisArea().Height()) > 2 ) )
            m_pWrtShell->InvalidateLayout( false );
    }

    if ( !bProtectDocShellVisArea )
    {
        // If the size of VisArea is unchanged, we extend the size of the VisArea
        // InternalObject on. By that the transport of errors shall be avoided.
        tools::Rectangle aVis( m_aVisArea );
        if ( aVis.GetSize() == aOldSz )
            aVis.SetSize( GetDocShell()->SfxObjectShell::GetVisArea(ASPECT_CONTENT).GetSize() );
                    // TODO/LATER: why casting?!
                    //GetDocShell()->SfxInPlaceObject::GetVisArea().GetSize() );

        // With embedded always with modify...
        // TODO/LATER: why casting?!
        GetDocShell()->SfxObjectShell::SetVisArea( aVis );
        /*
        if ( GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
            GetDocShell()->SfxInPlaceObject::SetVisArea( aVis );
        else
            GetDocShell()->SvEmbeddedObject::SetVisArea( aVis );*/

    }

    SfxViewShell::VisAreaChanged();

    InvalidateRulerPos();

    if ( bOuterResize && !m_bInOuterResizePixel && !m_bInInnerResizePixel)
            OuterResizePixel( Point(),
                GetViewFrame().GetWindow().GetOutputSizePixel() );
}

// Set Pos VisArea

void SwView::SetVisArea( const Point &rPt, bool bUpdateScrollbar )
{
    // Align once, so brushes will be inserted correctly.
    // This goes wrong in the BrowseView, because the entire document may
    // not be visible. Since the content in frames is fitting exactly,
    // align is not possible (better idea?!?!)
    // (fix: Bild.de, 200%) It does not work completely without alignment
    // Let's see how far we get with half BrushSize.
    Point aPt = GetEditWin().LogicToPixel( rPt );
#if HAVE_FEATURE_DESKTOP
    const tools::Long nTmp = 8;
    aPt.AdjustX( -(aPt.X() % nTmp) );
    aPt.AdjustY( -(aPt.Y() % nTmp) );
#endif
    aPt = GetEditWin().PixelToLogic( aPt );

    if ( aPt == m_aVisArea.TopLeft() )
        return;

    if (GetWrtShell().GetViewOptions()->IsShowOutlineContentVisibilityButton())
        GetEditWin().GetFrameControlsManager().HideControls(FrameControlType::Outline);

    const tools::Long lXDiff = m_aVisArea.Left() - aPt.X();
    const tools::Long lYDiff = m_aVisArea.Top()  - aPt.Y();
    SetVisArea( tools::Rectangle( aPt,
            Point( m_aVisArea.Right() - lXDiff, m_aVisArea.Bottom() - lYDiff ) ),
            bUpdateScrollbar);
}

void SwView::CheckVisArea()
{
    if (m_pHScrollbar)
        m_pHScrollbar->SetAuto( m_pWrtShell->GetViewOptions()->getBrowseMode() &&
                                !GetViewFrame().GetFrame().IsInPlace() );
    if ( IsDocumentBorder() )
    {
        if ( m_aVisArea.Left() != DOCUMENTBORDER ||
             m_aVisArea.Top()  != DOCUMENTBORDER )
        {
            tools::Rectangle aNewVisArea( m_aVisArea );
            aNewVisArea.Move( DOCUMENTBORDER - m_aVisArea.Left(),
                              DOCUMENTBORDER - m_aVisArea.Top() );
            SetVisArea( aNewVisArea );
        }
    }
}

/// Calculate the visible range.

//  OUT Point *pPt:             new position of the visible area

//  IN  Rectangle &rRect:       Rectangle, which should be located
//                              within the new visible area.
//  sal_uInt16 nRange           optional accurate indication of the
//                              range by which to scroll if necessary.
//  eScrollSizeMode             mouse selection should only bring the selected part
//                              into the visible area, timer call needs increased size

void SwView::CalcPt( Point *pPt, const tools::Rectangle &rRect, sal_uInt16 nRangeX,
                    sal_uInt16 nRangeY, ScrollSizeMode eScrollSizeMode)
{

    const SwTwips lMin = IsDocumentBorder() ? DOCUMENTBORDER : 0;

    const tools::Long nDefaultYScroll = GetYScroll();
    tools::Long nYScroll;
    if (eScrollSizeMode != ScrollSizeMode::ScrollSizeDefault)
    {
        nYScroll = m_aVisArea.Top() > rRect.Top() ?
            m_aVisArea.Top() - rRect.Top() :
            rRect.Bottom() - m_aVisArea.Bottom();

        if (eScrollSizeMode == ScrollSizeMode::ScrollSizeTimer)
             nYScroll = std::min(nDefaultYScroll, nYScroll);
        else if (eScrollSizeMode == ScrollSizeMode::ScrollSizeTimer2)
             nYScroll = 2 * nDefaultYScroll;
    }
    else
        nYScroll = nDefaultYScroll;
    tools::Long nDesHeight = rRect.GetHeight();
    tools::Long nCurHeight = m_aVisArea.GetHeight();
    nYScroll = std::min(nYScroll, nCurHeight - nDesHeight); // If it is scarce, then scroll not too much.
    if(nDesHeight > nCurHeight) // the height is not sufficient, then nYScroll is no longer of interest
    {
        pPt->setY( rRect.Top() );
        pPt->setY( std::max( lMin, SwTwips(pPt->Y()) ) );
    }
    else if ( rRect.Top() < m_aVisArea.Top() )                // Upward shift
    {
        pPt->setY( rRect.Top() - (nRangeY != USHRT_MAX ? nRangeY : nYScroll) );
        pPt->setY( std::max( lMin, SwTwips(pPt->Y()) ) );
    }
    else if( rRect.Bottom() > m_aVisArea.Bottom() )   // Downward shift
    {
        pPt->setY( rRect.Bottom() -
                    (m_aVisArea.GetHeight()) + ( nRangeY != USHRT_MAX ?
            nRangeY : nYScroll ) );
        pPt->setY( SetVScrollMax( pPt->Y() ) );
    }
    tools::Long nXScroll = GetXScroll();
    if ( rRect.Right() > m_aVisArea.Right() )         // Shift right
    {
        pPt->setX( rRect.Right()  -
                    (m_aVisArea.GetWidth()) +
                    (nRangeX != USHRT_MAX ? nRangeX : nXScroll) );
        pPt->setX( SetHScrollMax( pPt->X() ) );
    }
    else if ( rRect.Left() < m_aVisArea.Left() )      // Shift left
    {
        pPt->setX( rRect.Left() - (nRangeX != USHRT_MAX ? nRangeX : nXScroll) );
        pPt->setX( std::max( ::GetLeftMargin( *this ) + nLeftOfst, pPt->X() ) );
        pPt->setX( std::min( rRect.Left() - nScrollX, pPt->X() ) );
        pPt->setX( std::max( tools::Long(0), pPt->X() ) );
    }
}

// Scrolling

bool SwView::IsScroll( const tools::Rectangle &rRect ) const
{
    return m_bCenterCursor || m_bTopCursor || !m_aVisArea.Contains(rRect);
}

void SwView::Scroll( const tools::Rectangle &rRect, sal_uInt16 nRangeX, sal_uInt16 nRangeY
    , ScrollSizeMode eScrollSizeMode )
{
    if ( m_aVisArea.IsEmpty() )
        return;

    tools::Rectangle aOldVisArea( m_aVisArea );
    tools::Long nDiffY = 0;

    weld::Window* pCareDialog = SwViewShell::GetCareDialog(GetWrtShell());
    if (pCareDialog)
    {
        int x, y, width, height;
        tools::Rectangle aDlgRect;
        if (pCareDialog->get_extents_relative_to(*GetEditWin().GetFrameWeld(), x, y, width, height))
        {
            AbsoluteScreenPixelPoint aTopLeftAbs(GetEditWin().GetSystemWindow()->OutputToAbsoluteScreenPixel(Point(x, y)));
            Point aTopLeft = GetEditWin().AbsoluteScreenToOutputPixel(aTopLeftAbs);
            aDlgRect = GetEditWin().PixelToLogic(tools::Rectangle(aTopLeft, Size(width, height)));
        }

        // Only if the dialogue is not the VisArea right or left:
        if ( aDlgRect.Left() < m_aVisArea.Right() &&
             aDlgRect.Right() > m_aVisArea.Left() )
        {
            // If we are not supposed to be centered, lying in the VisArea
            // and are not covered by the dialogue ...
            if ( !m_bCenterCursor && aOldVisArea.Contains( rRect )
                 && ( rRect.Left() > aDlgRect.Right()
                      || rRect.Right() < aDlgRect.Left()
                      || rRect.Top() > aDlgRect.Bottom()
                      || rRect.Bottom() < aDlgRect.Top() ) )
                return;

            // Is above or below the dialogue more space?
            tools::Long nTopDiff = aDlgRect.Top() - m_aVisArea.Top();
            tools::Long nBottomDiff = m_aVisArea.Bottom() - aDlgRect.Bottom();
            if ( nTopDiff < nBottomDiff )
            {
                if ( nBottomDiff > 0 ) // Is there room below at all?
                {   // then we move the upper edge and we remember this
                    nDiffY = aDlgRect.Bottom() - m_aVisArea.Top();
                    m_aVisArea.AdjustTop(nDiffY );
                }
            }
            else
            {
                if ( nTopDiff > 0 ) // Is there room below at all?
                    m_aVisArea.SetBottom( aDlgRect.Top() ); // Modify the lower edge
            }
        }
    }

    //s.o. !IsScroll()
    if( !(m_bCenterCursor || m_bTopCursor) && m_aVisArea.Contains( rRect ) )
    {
        m_aVisArea = aOldVisArea;
        return;
    }
    // If the rectangle is larger than the visible area -->
    // upper left corner
    Size aSize( rRect.GetSize() );
    const Size aVisSize( m_aVisArea.GetSize() );
    if( !m_aVisArea.IsEmpty() && (
        aSize.Width() + GetXScroll() > aVisSize.Width() ||
        aSize.Height()+ GetYScroll() > aVisSize.Height() ))
    {
        Point aPt( m_aVisArea.TopLeft() );
        aSize.setWidth( std::min( aSize.Width(), aVisSize.Width() ) );
        aSize.setHeight( std::min( aSize.Height(),aVisSize.Height()) );

        CalcPt( &aPt, tools::Rectangle( rRect.TopLeft(), aSize ),
                static_cast< sal_uInt16 >((aVisSize.Width() - aSize.Width()) / 2),
                static_cast< sal_uInt16 >((aVisSize.Height()- aSize.Height())/ 2),
                eScrollSizeMode );

        if( m_bTopCursor )
        {
            const tools::Long nBorder = IsDocumentBorder() ? DOCUMENTBORDER : 0;
            aPt.setY( std::min( std::max( nBorder, rRect.Top() ),
                                m_aDocSz.Height() + nBorder -
                                    m_aVisArea.GetHeight() ) );
        }
        aPt.AdjustY( -nDiffY );
        m_aVisArea = aOldVisArea;
        SetVisArea( aPt );
        return;
    }
    if( !m_bCenterCursor )
    {
        Point aPt( m_aVisArea.TopLeft() );
        CalcPt( &aPt, rRect, nRangeX, nRangeY, eScrollSizeMode );

        if( m_bTopCursor )
        {
            const tools::Long nBorder = IsDocumentBorder() ? DOCUMENTBORDER : 0;
            aPt.setY( std::min( std::max( nBorder, rRect.Top() ),
                                m_aDocSz.Height() + nBorder -
                                    m_aVisArea.GetHeight() ) );
        }

        aPt.AdjustY( -nDiffY );
        m_aVisArea = aOldVisArea;
        SetVisArea( aPt );
        return;
    }

    //Center cursor
    Point aPnt( m_aVisArea.TopLeft() );
    // ... in Y-direction in any case
    aPnt.AdjustY(( rRect.Top() + rRect.Bottom()
                  - m_aVisArea.Top() - m_aVisArea.Bottom() ) / 2 - nDiffY );
    // ... in X-direction, only if the rectangle protrudes over the right or left of the VisArea.
    if ( rRect.Right() > m_aVisArea.Right() || rRect.Left() < m_aVisArea.Left() )
    {
        aPnt.AdjustX(( rRect.Left() + rRect.Right()
                  - m_aVisArea.Left() - m_aVisArea.Right() ) / 2 );
        aPnt.setX( SetHScrollMax( aPnt.X() ) );
        const SwTwips lMin = IsDocumentBorder() ? DOCUMENTBORDER : 0;
        aPnt.setX( std::max( (GetLeftMargin( *this ) - lMin) + nLeftOfst, aPnt.X() ) );
    }
    m_aVisArea = aOldVisArea;
    if (pCareDialog)
    {
        // If we want to avoid only a dialogue, we do
        // not want to go beyond the end of the document.
        aPnt.setY( SetVScrollMax( aPnt.Y() ) );
    }
    SetVisArea( aPnt );
}

/// Scroll page by page
//  Returns the value by which to be scrolled with PageUp / Down

bool SwView::GetPageScrollUpOffset( SwTwips &rOff ) const
{
    // in the LOK case, force the value set by the API
    if (comphelper::LibreOfficeKit::isActive() && m_nLOKPageUpDownOffset > 0)
    {
        rOff = -m_nLOKPageUpDownOffset;
        return true;
    }

    if ( !m_aVisArea.Top() || !m_aVisArea.GetHeight() )
        return false;
    tools::Long nYScrl = GetYScroll() / 2;
    rOff = -(m_aVisArea.GetHeight() - nYScrl);
    // Do not scroll before the beginning of the document.
    if( m_aVisArea.Top() - rOff < 0 )
        rOff = rOff - m_aVisArea.Top();
    else if( GetWrtShell().GetCharRect().Top() < (m_aVisArea.Top() + nYScrl))
        rOff += nYScrl;

    return true;
}

bool SwView::GetPageScrollDownOffset( SwTwips &rOff ) const
{
    // in the LOK case, force the value set by the API
    if (comphelper::LibreOfficeKit::isActive() && m_nLOKPageUpDownOffset > 0)
    {
        rOff = m_nLOKPageUpDownOffset;
        return true;
    }

    if ( !m_aVisArea.GetHeight() ||
         (m_aVisArea.GetHeight() > m_aDocSz.Height()) )
        return false;
    tools::Long nYScrl = GetYScroll() / 2;
    rOff = m_aVisArea.GetHeight() - nYScrl;
    // Do not scroll past the end of the document.
    if ( m_aVisArea.Top() + rOff > m_aDocSz.Height() )
        rOff = m_aDocSz.Height() - m_aVisArea.Bottom();
    else if( GetWrtShell().GetCharRect().Bottom() >
                                            ( m_aVisArea.Bottom() - nYScrl ))
        rOff -= nYScrl;

    return rOff > 0;
}

// Scroll page by page
bool SwView::PageUp()
{
    if (!m_aVisArea.GetHeight())
        return false;

    Point aPos(m_aVisArea.TopLeft());
    aPos.AdjustY( -(m_aVisArea.GetHeight() - (GetYScroll() / 2)) );
    aPos.setY( std::max(tools::Long(0), aPos.Y()) );
    SetVisArea( aPos );
    return true;
}

bool SwView::PageDown()
{
    if ( !m_aVisArea.GetHeight() )
        return false;
    Point aPos( m_aVisArea.TopLeft() );
    aPos.AdjustY(m_aVisArea.GetHeight() - (GetYScroll() / 2) );
    aPos.setY( SetVScrollMax( aPos.Y() ) );
    SetVisArea( aPos );
    return true;
}

void SwView::PhyPageUp()
{
    // Check for the currently visible page, do not format
    sal_uInt16 nActPage = m_pWrtShell->GetNextPrevPageNum( false );

    if( USHRT_MAX != nActPage )
    {
        const Point aPt( m_aVisArea.Left(),
                         m_pWrtShell->GetPagePos( nActPage ).Y() );
        Point aAlPt( AlignToPixel( aPt ) );
        // If there is a difference, has been truncated --> then add one pixel,
        // so that no residue of the previous page is visible.
        if( aPt.Y() != aAlPt.Y() )
            aAlPt.AdjustY(3 * GetEditWin().PixelToLogic( Size( 0, 1 ) ).Height() );
        SetVisArea( aAlPt );
    }
}

void SwView::PhyPageDown()
{
    // Check for the currently visible page, do not format
    sal_uInt16 nActPage = m_pWrtShell->GetNextPrevPageNum();
    // If the last page of the document is visible, do nothing.
    if( USHRT_MAX != nActPage )
    {
        const Point aPt( m_aVisArea.Left(),
                         m_pWrtShell->GetPagePos( nActPage ).Y() );
        Point aAlPt( AlignToPixel( aPt ) );
        // If there is a difference, has been truncated --> then add one pixel,
        // so that no residue of the previous page is visible.
        if( aPt.Y() != aAlPt.Y() )
            aAlPt.AdjustY(3 * GetEditWin().PixelToLogic( Size( 0, 1 ) ).Height() );
        SetVisArea( aAlPt );
    }
}

bool SwView::PageUpCursor( bool bSelect )
{
    if ( !bSelect )
    {
        const FrameTypeFlags eType = m_pWrtShell->GetFrameType(nullptr,true);
        if ( eType & FrameTypeFlags::FOOTNOTE )
        {
            m_pWrtShell->MoveCursor();
            m_pWrtShell->GotoFootnoteAnchor();
            m_pWrtShell->Right(SwCursorSkipMode::Chars, false, 1, false );
            return true;
        }
    }

    SwTwips lOff = 0;
    if ( GetPageScrollUpOffset( lOff ) &&
         (m_pWrtShell->IsCursorReadonly() ||
          !m_pWrtShell->PageCursor( lOff, bSelect )) &&
         PageUp() )
    {
        m_pWrtShell->ResetCursorStack();
        return true;
    }
    return false;
}

bool SwView::PageDownCursor(bool bSelect)
{
    SwTwips lOff = 0;
    if ( GetPageScrollDownOffset( lOff ) &&
         (m_pWrtShell->IsCursorReadonly() ||
          !m_pWrtShell->PageCursor( lOff, bSelect )) &&
         PageDown() )
    {
        m_pWrtShell->ResetCursorStack();
        return true;
    }
    return false;
}

static void HideQuickHelp(vcl::Window* pParent) { Help::ShowQuickHelp(pParent, {}, {}); }

// Handler of the scrollbars
IMPL_LINK(SwView, VertScrollHdl, weld::Scrollbar&, rScrollbar, void)
{
    if ( GetWrtShell().ActionPend() )
        return;

    if (rScrollbar.get_scroll_type() == ScrollType::Drag)
        m_pWrtShell->EnableSmooth( false );

    bool bHidePending = nPgNum != 0;
    nPgNum = 0; // avoid flicker from hiding then showing help window again
    EndScrollHdl(rScrollbar, false);

    if (!m_pWrtShell->GetViewOptions()->getBrowseMode() &&
        rScrollbar.get_scroll_type() == ScrollType::Drag)
    {
        if ( !m_bWheelScrollInProgress && Help::IsQuickHelpEnabled() &&
             m_pWrtShell->GetViewOptions()->IsShowScrollBarTips())
        {

            Point aPos( m_aVisArea.TopLeft() );
            lcl_GetPos(this, aPos, rScrollbar, false, IsDocumentBorder());

            sal_uInt16 nPhNum = 1;
            sal_uInt16 nVirtNum = 1;

            OUString sDisplay;
            if(m_pWrtShell->GetPageNumber( aPos.Y(), false, nPhNum, nVirtNum, sDisplay ))
            {
                //QuickHelp:
                if( m_pWrtShell->GetPageCnt() > 1 )
                {
                    tools::Rectangle aRect;
                    aRect.SetLeft( m_pVScrollbar->GetParent()->OutputToScreenPixel(
                                        m_pVScrollbar->GetPosPixel() ).X() -8 );
                    aRect.SetTop( m_pVScrollbar->OutputToScreenPixel(
                                    m_pVScrollbar->GetPointerPosPixel() ).Y() );
                    aRect.SetRight( aRect.Left() );
                    aRect.SetBottom( aRect.Top() );

                    OUString sPageStr( GetPageStr( nPhNum, nVirtNum, sDisplay ));
                    SwContentAtPos aCnt(IsAttrAtPos::Outline | IsAttrAtPos::AllowContaining);
                    bool bSuccess = m_pWrtShell->GetContentAtPos(aPos, aCnt);
                    if (bSuccess && !aCnt.sStr.isEmpty())
                    {
                        sal_Int32 nChunkLen = std::min<sal_Int32>(aCnt.sStr.getLength(), 80);
                        std::u16string_view sChunk = aCnt.sStr.subView(0, nChunkLen);
                        sPageStr = sPageStr + " - " + sChunk;
                        sPageStr = sPageStr.replace('\t'' ').replace(0x0a, ' ');
                    }

                    Help::ShowQuickHelp(m_pVScrollbar, aRect, sPageStr,
                                    QuickHelpFlags::Right|QuickHelpFlags::VCenter);
                    bHidePending = false;
                    nPgNum = nPhNum;
                }
            }
        }
    }

    if (bHidePending)
        HideQuickHelp(m_pVScrollbar);

    if (rScrollbar.get_scroll_type() == ScrollType::Drag)
        m_pWrtShell->EnableSmooth( true );
}

// Handler of the scrollbars
void SwView::EndScrollHdl(const weld::Scrollbar& rScrollbar, bool bHorizontal)
{
    if ( GetWrtShell().ActionPend() )
        return;

    if(nPgNum)
    {
        nPgNum = 0;
        HideQuickHelp(bHorizontal ? m_pHScrollbar : m_pVScrollbar);
    }
    Point aPos( m_aVisArea.TopLeft() );
    bool bBorder = IsDocumentBorder();
    lcl_GetPos(this, aPos, rScrollbar, bHorizontal, bBorder);
    if ( bBorder && aPos == m_aVisArea.TopLeft() )
        UpdateScrollbars();
    else
        SetVisArea( aPos, false );

    GetViewFrame().GetBindings().Update(FN_STAT_PAGE);
}

IMPL_LINK(SwView, HoriScrollHdl, weld::Scrollbar&, rScrollBar, void)
{
    EndScrollHdl(rScrollBar, true);
}

// Calculates the size of the m_aVisArea in dependency of the size of
// EditWin on the screen.

void SwView::CalcVisArea( const Size &rOutPixel )
{
    Point aTopLeft;
    tools::Rectangle aRect( aTopLeft, rOutPixel );
    aRect = GetEditWin().PixelToLogic(aRect);

    // The shifts to the right and/or below can now be incorrect
    // (e.g. change zoom level, change view size).
    const tools::Long lBorder = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER*2;
    if ( aRect.Left() )
    {
        const tools::Long lWidth = GetWrtShell().GetDocSize().Width() + lBorder;
        if ( aRect.Right() > lWidth )
        {
            tools::Long lDelta    = aRect.Right() - lWidth;
            aRect.AdjustLeft( -lDelta );
            aRect.AdjustRight( -lDelta );
        }
    }
    if ( aRect.Top() )
    {
        const tools::Long lHeight = GetWrtShell().GetDocSize().Height() + lBorder;
        if ( aRect.Bottom() > lHeight )
        {
            tools::Long lDelta     = aRect.Bottom() - lHeight;
            aRect.AdjustTop( -lDelta );
            aRect.AdjustBottom( -lDelta );
        }
    }
    SetVisArea( aRect );
    GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOM );
    GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER ); // for snapping points
}

// Rearrange control elements

void SwView::CalcAndSetBorderPixel( SvBorder &rToFill )
{
    bool bRightVRuler = m_pWrtShell->GetViewOptions()->IsVRulerRight();
    if ( m_pVRuler->IsVisible() )
    {
        tools::Long nWidth = m_pVRuler->GetSizePixel().Width();
        if(bRightVRuler)
            rToFill.Right() = nWidth;
        else
            rToFill.Left() = nWidth;
    }

    OSL_ENSURE(m_pHRuler, "Why is the ruler not present?");
    if ( m_pHRuler->IsVisible() )
        rToFill.Top() = m_pHRuler->GetSizePixel().Height();

    const StyleSettings &rSet = GetEditWin().GetSettings().GetStyleSettings();
    const tools::Long nTmp = rSet.GetScrollBarSize();
    if( m_pVScrollbar->IsScrollbarVisible(true) )
    {
        if(bRightVRuler)
            rToFill.Left() = nTmp;
        else
            rToFill.Right()  = nTmp;
    }
    if ( m_pHScrollbar->IsScrollbarVisible(true) )
        rToFill.Bottom() = nTmp;

    SetBorderPixel( rToFill );
}

void ViewResizePixel( const vcl::RenderContext &rRef,
                    const Point &rOfst,
                    const Size &rSize,
                    const Size &rEditSz,
                    SwScrollbar& rVScrollbar,
                    SwScrollbar& rHScrollbar,
                    SvxRuler* pVRuler,
                    SvxRuler* pHRuler,
                    bool bVRulerRight )
{
// ViewResizePixel is also used by Preview!!!

    const bool bHRuler = pHRuler && pHRuler->IsVisible();
    const tools::Long nHLinSzHeight = bHRuler ?
                        pHRuler->GetSizePixel().Height() : 0;
    const bool bVRuler = pVRuler && pVRuler->IsVisible();
    const tools::Long nVLinSzWidth = bVRuler ?
                        pVRuler->GetSizePixel().Width() : 0;

    const tools::Long nScrollBarSize = rRef.GetSettings().GetStyleSettings().GetScrollBarSize();
    const tools::Long nHBSzHeight = rHScrollbar.IsScrollbarVisible(true) ? nScrollBarSize : 0;
    const tools::Long nVBSzWidth = rVScrollbar.IsScrollbarVisible(true) ? nScrollBarSize : 0;

    if(pVRuler)
    {
        WinBits nStyle = pVRuler->GetStyle()&~WB_RIGHT_ALIGNED;
        Point aPos( rOfst.X(), rOfst.Y()+nHLinSzHeight );
        if(bVRulerRight)
        {
            aPos.AdjustX(rSize.Width() - nVLinSzWidth );
            nStyle |= WB_RIGHT_ALIGNED;
        }
        Size  aSize( nVLinSzWidth, rEditSz.Height() );
        if(!aSize.Width())
            aSize.setWidth( pVRuler->GetSizePixel().Width() );
        pVRuler->SetStyle(nStyle);
        pVRuler->SetPosSizePixel( aPos, aSize );
        if(!pVRuler->IsVisible())
            pVRuler->Resize();
    }
    // Ruler needs a resize, otherwise it will not work in the invisible condition
    if(pHRuler)
    {
        Size aSize( rSize.Width(), nHLinSzHeight );
        if ( nVBSzWidth && !bVRulerRight)
            aSize.AdjustWidth( -nVBSzWidth );
        if(!aSize.Height())
            aSize.setHeight( pHRuler->GetSizePixel().Height() );
        pHRuler->SetPosSizePixel( rOfst, aSize );
        // VCL calls no resize on invisible windows
        // but that is not a good idea for the ruler
        if(!pHRuler->IsVisible())
            pHRuler->Resize();
    }

    // Arrange scrollbars and SizeBox
    Point aScrollFillPos;
    {
        Point aPos( rOfst.X(),
                    rOfst.Y()+rSize.Height()-nHBSzHeight );
        if(bVRulerRight)
        {
            aPos.AdjustX(nVBSzWidth );
        }

        Size  aSize( rSize.Width(), nHBSzHeight );
        if ( nVBSzWidth )
            aSize.AdjustWidth( -nVBSzWidth );
        rHScrollbar.SetPosSizePixel( aPos, aSize );
        aScrollFillPos.setY( aPos.Y() );
    }
    {
        Point aPos( rOfst.X()+rSize.Width()-nVBSzWidth,
                    rOfst.Y() );
        Size  aSize( nVBSzWidth, rSize.Height() );
        if(bVRulerRight)
        {
            aPos.setX( rOfst.X() );
            if(bHRuler)
            {
                aPos.AdjustY(nHLinSzHeight );
                aSize.AdjustHeight( -nHLinSzHeight );
            }
        }

        if ( nHBSzHeight )
            aSize.AdjustHeight( -nHBSzHeight );
        rVScrollbar.SetPosSizePixel( aPos, aSize );

        aPos.AdjustY(aSize.Height() );

        aScrollFillPos.setX( aPos.X() );
    }
}

void SwView::ShowAtResize()
{
    m_bShowAtResize = false;
    if ( m_pWrtShell->GetViewOptions()->IsViewHRuler() )
        m_pHRuler->Show();
}

void SwView::InnerResizePixel( const Point &rOfst, const Size &rSize, bool )
{
    Size aObjSize = GetObjectShell()->GetVisArea().GetSize();
    if ( !aObjSize.IsEmpty() )
    {
        SvBorder aBorder( GetBorderPixel() );
        Size aSize( rSize );
        aSize.AdjustWidth( -(aBorder.Left() + aBorder.Right()) );
        aSize.AdjustHeight( -(aBorder.Top() + aBorder.Bottom()) );
        Size aObjSizePixel = GetWindow()->LogicToPixel(aObjSize, MapMode(MapUnit::MapTwip));
        SfxViewShell::SetZoomFactor( Fraction( aSize.Width(), aObjSizePixel.Width() ),
                        Fraction( aSize.Height(), aObjSizePixel.Height() ) );
    }

    m_bInInnerResizePixel = true;
    const bool bHScrollVisible = m_pHScrollbar->IsScrollbarVisible(true);
    const bool bVScrollVisible = m_pVScrollbar->IsScrollbarVisible(true);
    bool bRepeat = false;
    do
    {
        Size aSz( rSize );
        SvBorder aBorder;
        CalcAndSetBorderPixel( aBorder );
        if ( GetViewFrame().GetFrame().IsInPlace() )
        {
            Size aViewSize( aSz );
            Point aViewPos( rOfst );
            aViewSize.AdjustHeight( -(aBorder.Top() + aBorder.Bottom()) );
            aViewSize.AdjustWidth( -(aBorder.Left() + aBorder.Right()) );
            aViewPos.AdjustX(aBorder.Left() );
            aViewPos.AdjustY(aBorder.Top() );
            GetEditWin().SetPosSizePixel( aViewPos, aViewSize );
        }
        else
        {
            aSz.AdjustHeight(aBorder.Top()  + aBorder.Bottom() );
            aSz.AdjustWidth(aBorder.Left() + aBorder.Right() );
        }

        Size aEditSz( GetEditWin().GetOutputSizePixel() );
        ViewResizePixel( *GetEditWin().GetOutDev(), rOfst, aSz, aEditSz, *m_pVScrollbar,
                            *m_pHScrollbar, m_pVRuler, m_pHRuler,
                            m_pWrtShell->GetViewOptions()->IsVRulerRight());
        if ( m_bShowAtResize )
            ShowAtResize();

        if( m_pHRuler->IsVisible() || m_pVRuler->IsVisible() )
        {
            const Fraction& rFrac = GetEditWin().GetMapMode().GetScaleX();
            tools::Long nZoom = 100;
            if (rFrac.IsValid())
                nZoom = tools::Long(rFrac * 100);

            const Fraction aFrac( nZoom, 100 );
            m_pVRuler->SetZoom( aFrac );
            m_pHRuler->SetZoom( aFrac );
            InvalidateRulerPos();   // Invalidate content.
        }
        // Reset the cursor stack because the cursor positions for PageUp/Down
        // no longer fit the currently visible area.
        m_pWrtShell->ResetCursorStack();

        // EditWin never set!

        // Set VisArea, but do not call the SetVisArea of the Docshell there!
        bProtectDocShellVisArea = true;
        CalcVisArea( aEditSz );
        // Visibility changes of the automatic horizontal scrollbar
        // require to repeat the ViewResizePixel() call - but only once!
        if(bRepeat)
            bRepeat = false;
        else if(bHScrollVisible != m_pHScrollbar->IsScrollbarVisible(true) ||
                bVScrollVisible != m_pVScrollbar->IsScrollbarVisible(true))
            bRepeat = true;
    }while( bRepeat );
    bProtectDocShellVisArea = false;
    m_bInInnerResizePixel = false;
}

void SwView::OuterResizePixel( const Point &rOfst, const Size &rSize )
{
    // #i16909# return, if no size (caused by minimize window).
    if ( m_bInOuterResizePixel || ( !rSize.Width() && !rSize.Height() ) )
        return;
    m_bInOuterResizePixel = true;

    // Determine whether scroll bars may be displayed.
    bool bShowH = true,
         bShowV = true,
         bAuto  = true,
         bHAuto = true;

    const SwViewOption *pVOpt = m_pWrtShell->GetViewOptions();
    if ( !pVOpt->IsReadonly() || pVOpt->IsStarOneSetting() )
    {
        bShowH = pVOpt->IsViewHScrollBar();
        bShowV = pVOpt->IsViewVScrollBar();
    }

    if (!m_bHScrollbarEnabled)
    {
        bHAuto = bShowH = false;
    }
    if (!m_bVScrollbarEnabled)
    {
        bAuto = bShowV = false;
    }

    SwDocShell* pDocSh = GetDocShell();
    bool bIsPreview = pDocSh->IsPreview();
    if( bIsPreview )
    {
        bShowH = bShowV = bHAuto = bAuto = false;
    }
    if(m_pHScrollbar->IsScrollbarVisible(false) != bShowH && !bHAuto)
        ShowHScrollbar(bShowH);
    m_pHScrollbar->SetAuto( bHAuto );
    if(m_pVScrollbar->IsScrollbarVisible(false) != bShowV && !bAuto)
        ShowVScrollbar(bShowV);
    m_pVScrollbar->SetAuto(bAuto);

    CurrShell aCurr( m_pWrtShell.get() );
    bool bRepeat = false;
    tools::Long nCnt = 0;

    bool bUnLockView = !m_pWrtShell->IsViewLocked();
    m_pWrtShell->LockView( true );
    m_pWrtShell->LockPaint(LockPaintReason::OuterResize);

    do {
        ++nCnt;
        const bool bScroll1 = m_pVScrollbar->IsScrollbarVisible(true);
        const bool bScroll2 = m_pHScrollbar->IsScrollbarVisible(true);
        SvBorder aBorder;
        CalcAndSetBorderPixel( aBorder );
        const Size aEditSz( GetEditWin().GetOutputSizePixel() );
        ViewResizePixel( *GetEditWin().GetOutDev(), rOfst, rSize, aEditSz, *m_pVScrollbar,
                                *m_pHScrollbar, m_pVRuler, m_pHRuler,
                                m_pWrtShell->GetViewOptions()->IsVRulerRight() );
        if ( m_bShowAtResize )
            ShowAtResize();

        if( m_pHRuler->IsVisible() || m_pVRuler->IsVisible() )
            InvalidateRulerPos();   // Invalidate content.

        // Reset the cursor stack because the cursor positions for PageUp/Down
        // no longer fit the currently visible area.
        m_pWrtShell->ResetCursorStack();

        OSL_ENSURE( !GetEditWin().IsVisible() ||
                    !aEditSz.IsEmpty() || !m_aVisArea.IsEmpty(), "Small world, isn't it?" );

        // Never set EditWin!

        // Of course the VisArea must also be set.
        // Now is the right time to re-calculate the zoom if it is not a simple factor.
        m_pWrtShell->StartAction();
        CalcVisArea( aEditSz );

        //Thus also in the outplace editing the page width will be adjusted immediately.
        //TODO/LATER: is that still necessary?!
        /*
        if ( pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
            pDocSh->SetVisArea(
                            pDocSh->SfxInPlaceObject::GetVisArea() );*/

        if ( m_pWrtShell->GetViewOptions()->GetZoomType() != SvxZoomType::PERCENT &&
             !m_pWrtShell->GetViewOptions()->getBrowseMode() )
            SetZoom_( aEditSz, m_pWrtShell->GetViewOptions()->GetZoomType(), 100, true );
        m_pWrtShell->EndAction();

        bRepeat = bScroll1 != m_pVScrollbar->IsScrollbarVisible(true);
        if ( !bRepeat )
            bRepeat = bScroll2 != m_pHScrollbar->IsScrollbarVisible(true);

        // Do no infinite loops.
        // If possible stop when the (auto-) scroll bars are visible.
        if ( bRepeat &&
             ( nCnt > 10 || ( nCnt > 3 && bHAuto && bAuto ) )
           )
        {
            bRepeat = false;
        }

    } while ( bRepeat );

    m_pWrtShell->UnlockPaint();
    if( bUnLockView )
        m_pWrtShell->LockView( false );

    m_bInOuterResizePixel = false;

    if ( m_pPostItMgr )
    {
        m_pPostItMgr->CalcRects();
        m_pPostItMgr->LayoutPostIts();
    }
}

void SwView::SetZoomFactor( const Fraction &rX, const Fraction &rY )
{
    const Fraction &rFrac = rX < rY ? rX : rY;
    SetZoom( SvxZoomType::PERCENT, static_cast<short>(tools::Long(rFrac * Fraction( 100, 1 ))) );

    // To minimize rounding errors we also adjust the odd values
    // of the base class if necessary.
    SfxViewShell::SetZoomFactor( rX, rY );
}

bool SwView::UpdateScrollbars()
{
    bool bRet = false;
    if ( !m_aVisArea.IsEmpty() )
    {
        const bool bBorder = IsDocumentBorder();
        tools::Rectangle aTmpRect( m_aVisArea );
        if ( bBorder )
        {
            Point aPt( DOCUMENTBORDER, DOCUMENTBORDER );
            aPt = AlignToPixel( aPt );
            aTmpRect.Move( -aPt.X(), -aPt.Y() );
        }

        Size aTmpSz( m_aDocSz );
        const tools::Long lOfst = bBorder ? 0 : DOCUMENTBORDER * 2;
        aTmpSz.AdjustWidth(lOfst ); aTmpSz.AdjustHeight(lOfst );

        if (m_pVScrollbar)
        {
            const bool bVScrollVisible = m_pVScrollbar->IsScrollbarVisible(true);
            m_pVScrollbar->DocSzChgd( aTmpSz );
            m_pVScrollbar->ViewPortChgd( aTmpRect );
            if ( bVScrollVisible != m_pVScrollbar->IsScrollbarVisible(true) )
                bRet = true;
        }
        if (m_pHScrollbar)
        {
            const bool bHScrollVisible = m_pHScrollbar->IsScrollbarVisible(true);
            m_pHScrollbar->DocSzChgd( aTmpSz );
            m_pHScrollbar->ViewPortChgd( aTmpRect );
            if ( bHScrollVisible != m_pHScrollbar->IsScrollbarVisible(true) )
                bRet = true;
        }
    }
    return bRet;
}

void SwView::Move()
{
    if ( GetWrtShell().IsInSelect() )
        GetWrtShell().EndSelect();
    SfxViewShell::Move();
}

bool SwView::HandleWheelCommands( const CommandEvent& rCEvt )
{
    bool bOk = false;
    const CommandWheelData* pWData = rCEvt.GetWheelData();
    if (pWData && CommandWheelMode::ZOOM == pWData->GetMode())
    {
        sal_uInt16 nFact = m_pWrtShell->GetViewOptions()->GetZoom();
        if( 0L > pWData->GetDelta() )
            nFact = std::max(MIN_ZOOM_PERCENT, basegfx::zoomtools::zoomOut( nFact ));
        else
            nFact = std::min(MAX_ZOOM_PERCENT, basegfx::zoomtools::zoomIn( nFact ));

        SetZoom( SvxZoomType::PERCENT, nFact );
        bOk = true;
    }
    else
    {
        if (pWData && pWData->GetMode()==CommandWheelMode::SCROLL)
        {
            // This influences whether quick help is shown
            m_bWheelScrollInProgress=true;
        }

        if (pWData && (CommandWheelMode::SCROLL==pWData->GetMode()) &&
                (COMMAND_WHEEL_PAGESCROLL == pWData->GetScrollLines()))
        {
            if (pWData->GetDelta()<0)
                PhyPageDown();
            else
                PhyPageUp();
            bOk = true;
        }
        else
            bOk = m_pEditWin->HandleScrollCommand(rCEvt, m_pHScrollbar, m_pVScrollbar);

        // Restore default state for case when scroll command comes from dragging scrollbar handle
        m_bWheelScrollInProgress=false;
    }
    return bOk;
}

bool SwView::HandleGestureZoomCommand(const CommandEvent& rCEvt)
{
    const CommandGestureZoomData* pData = rCEvt.GetGestureZoomData();

    if (pData->meEventType == GestureEventZoomType::Begin)
    {
        m_fLastZoomScale = pData->mfScaleDelta;
        return true;
    }

    if (pData->meEventType == GestureEventZoomType::Update)
    {
        double deltaBetweenEvents = (pData->mfScaleDelta - m_fLastZoomScale) / m_fLastZoomScale;
        m_fLastZoomScale = pData->mfScaleDelta;

        // Accumulate fractional zoom to avoid small zoom changes from being ignored
        m_fAccumulatedZoom += deltaBetweenEvents;
        int nZoomChangePercent = m_fAccumulatedZoom * 100;
        m_fAccumulatedZoom -= nZoomChangePercent / 100.0;

        sal_uInt16 nFact = m_pWrtShell->GetViewOptions()->GetZoom();
        nFact += nZoomChangePercent;
        nFact = std::clamp<sal_uInt16>(nFact, MIN_ZOOM_PERCENT, MAX_ZOOM_PERCENT);
        SetZoom(SvxZoomType::PERCENT, nFact);

        return true;
    }
    return true;
}

bool SwView::HandleGesturePanCommand(const CommandEvent& rCEvt)
{
    return m_pEditWin->HandleScrollCommand(rCEvt, m_pHScrollbar, m_pVScrollbar);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=90 H=91 G=90

¤ Dauer der Verarbeitung: 0.13 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.