/* -*- 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 .
*/
// The SetVisArea of the DocShell must not be called from InnerResizePixel. // But our adjustments must take place. staticbool bProtectDocShellVisArea = false;
static sal_uInt16 nPgNum = 0;
bool SwView::IsDocumentBorder()
{ if (GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED) returntrue;
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;
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;
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();
// 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();
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 );*/
}
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);
// 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
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()) );
//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; returntrue;
}
if ( !m_aVisArea.Top() || !m_aVisArea.GetHeight() ) returnfalse;
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(); elseif( GetWrtShell().GetCharRect().Top() < (m_aVisArea.Top() + nYScrl))
rOff += nYScrl;
returntrue;
}
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; returntrue;
}
if ( !m_aVisArea.GetHeight() ||
(m_aVisArea.GetHeight() > m_aDocSz.Height()) ) returnfalse;
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(); elseif( GetWrtShell().GetCharRect().Bottom() >
( m_aVisArea.Bottom() - nYScrl ))
rOff -= nYScrl;
return rOff > 0;
}
// Scroll page by page bool SwView::PageUp()
{ if (!m_aVisArea.GetHeight()) returnfalse;
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 );
}
}
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 );
}
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; elseif(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;
// 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();
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;
}
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.