xref: /core/sw/source/uibase/uiview/viewport.cxx (revision 4407a035)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <vcl/commandevent.hxx>
21 #include <vcl/help.hxx>
22 #include <vcl/settings.hxx>
23 #include <vcl/syswin.hxx>
24 
25 #include <svx/ruler.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/viewfrm.hxx>
28 #include <view.hxx>
29 #include <wrtsh.hxx>
30 #include <viewopt.hxx>
31 #include <docsh.hxx>
32 #include <cmdid.h>
33 #include <edtwin.hxx>
34 #include <scroll.hxx>
35 
36 #include <PostItMgr.hxx>
37 
38 #include <basegfx/utils/zoomtools.hxx>
39 #include <comphelper/lok.hxx>
40 #include <vcl/weld.hxx>
41 #include <tools/svborder.hxx>
42 
43 #include "viewfunc.hxx"
44 
45 // The SetVisArea of the DocShell must not be called from InnerResizePixel.
46 // But our adjustments must take place.
47 static bool bProtectDocShellVisArea = false;
48 
49 static sal_uInt16 nPgNum = 0;
50 
51 bool SwView::IsDocumentBorder()
52 {
53     if (GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)
54         return true;
55 
56     if (!m_pWrtShell)
57         return false;
58 
59     return m_pWrtShell->GetViewOptions()->getBrowseMode() ||
60            SvxZoomType::PAGEWIDTH_NOBORDER == m_pWrtShell->GetViewOptions()->GetZoomType();
61 }
62 
63 static long GetLeftMargin( SwView const &rView )
64 {
65     SvxZoomType eType = rView.GetWrtShell().GetViewOptions()->GetZoomType();
66     long lRet = rView.GetWrtShell().GetAnyCurRect(CurRectType::PagePrt).Left();
67     return eType == SvxZoomType::PERCENT   ? lRet + DOCUMENTBORDER :
68            eType == SvxZoomType::PAGEWIDTH || eType == SvxZoomType::PAGEWIDTH_NOBORDER ? 0 :
69                                          lRet + DOCUMENTBORDER + nLeftOfst;
70 }
71 
72 static void lcl_GetPos(SwView const * pView,
73                 Point& rPos,
74                 SwScrollbar const * pScrollbar,
75                 bool bBorder)
76 {
77     SwWrtShell &rSh = pView->GetWrtShell();
78     const Size aDocSz( rSh.GetDocSize() );
79 
80     const long lBorder = bBorder ? DOCUMENTBORDER : DOCUMENTBORDER * 2;
81     const bool bHori = pScrollbar->IsHoriScroll();
82 
83     const long lPos = pScrollbar->GetThumbPos() + (bBorder ? DOCUMENTBORDER : 0);
84 
85     long lDelta = lPos - (bHori ? rSh.VisArea().Pos().X() : rSh.VisArea().Pos().Y());
86 
87     const long lSize = (bHori ? aDocSz.Width() : aDocSz.Height()) + lBorder;
88     // Should right or below are too much space,
89     // then they must be subtracted out of the VisArea!
90     long nTmp = pView->GetVisArea().Right()+lDelta;
91     if ( bHori && nTmp > lSize )
92         lDelta -= nTmp - lSize;
93     nTmp = pView->GetVisArea().Bottom()+lDelta;
94     if ( !bHori && nTmp > lSize )
95         lDelta -= nTmp - lSize;
96 
97     bHori ? rPos.AdjustX(lDelta) : rPos.AdjustY(lDelta);
98     if ( bBorder && (bHori ? rPos.X() : rPos.Y()) < DOCUMENTBORDER )
99         bHori ? rPos.setX(DOCUMENTBORDER) : rPos.setY(DOCUMENTBORDER);
100 }
101 
102 // Set zero ruler
103 
104 void SwView::InvalidateRulerPos()
105 {
106     static sal_uInt16 aInval[] =
107     {
108         SID_ATTR_PARA_LRSPACE, SID_RULER_BORDERS, SID_RULER_PAGE_POS,
109         SID_RULER_LR_MIN_MAX, SID_ATTR_LONG_ULSPACE, SID_ATTR_LONG_LRSPACE,
110         SID_RULER_BORDER_DISTANCE,
111         SID_ATTR_PARA_LRSPACE_VERTICAL, SID_RULER_BORDERS_VERTICAL,
112         SID_RULER_TEXT_RIGHT_TO_LEFT,
113         SID_RULER_ROWS, SID_RULER_ROWS_VERTICAL, FN_STAT_PAGE,
114         0
115     };
116 
117     GetViewFrame()->GetBindings().Invalidate(aInval);
118 
119     assert(m_pHRuler && "Why is the ruler not there?");
120     m_pHRuler->ForceUpdate();
121     m_pVRuler->ForceUpdate();
122 }
123 
124 // Limits the scrolling so far that only a quarter of the
125 // screen can be scrolled up before the end of the document.
126 
127 long SwView::SetHScrollMax( long lMax )
128 {
129     const long lBorder = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER * 2;
130     const long lSize = GetDocSz().Width() + lBorder - m_aVisArea.GetWidth();
131 
132     // At negative values the document is completely visible.
133     // In this case, no scrolling.
134     return std::max( std::min( lMax, lSize ), 0L );
135 }
136 
137 long SwView::SetVScrollMax( long lMax )
138 {
139     const long lBorder = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER * 2;
140     long lSize = GetDocSz().Height() + lBorder - m_aVisArea.GetHeight();
141     return std::max( std::min( lMax, lSize), 0L );        // see horizontal
142 }
143 
144 Point SwView::AlignToPixel(const Point &rPt) const
145 {
146     return GetEditWin().PixelToLogic( GetEditWin().LogicToPixel( rPt ) );
147 }
148 
149 // Document size has changed.
150 
151 void SwView::DocSzChgd(const Size &rSz)
152 {
153     m_aDocSz = rSz;
154 
155     if( !m_pWrtShell || m_aVisArea.IsEmpty() )      // no shell -> no change
156     {
157         bDocSzUpdated = false;
158         return;
159     }
160 
161     //If text has been deleted, it may be that the VisArea points behind the visible range.
162     tools::Rectangle aNewVisArea( m_aVisArea );
163     bool bModified = false;
164     SwTwips lGreenOffset = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER * 2;
165     SwTwips lTmp = m_aDocSz.Width() + lGreenOffset;
166 
167     if ( aNewVisArea.Right() >= lTmp  )
168     {
169         lTmp = aNewVisArea.Right() - lTmp;
170         aNewVisArea.AdjustRight( -lTmp );
171         aNewVisArea.AdjustLeft( -lTmp );
172         bModified = true;
173     }
174 
175     lTmp = m_aDocSz.Height() + lGreenOffset;
176     if ( aNewVisArea.Bottom() >= lTmp )
177     {
178         lTmp = aNewVisArea.Bottom() - lTmp;
179         aNewVisArea.AdjustBottom( -lTmp );
180         aNewVisArea.AdjustTop( -lTmp );
181         bModified = true;
182     }
183 
184     if ( bModified )
185         SetVisArea( aNewVisArea, false );
186 
187     if ( UpdateScrollbars() && !m_bInOuterResizePixel && !m_bInInnerResizePixel &&
188             !GetViewFrame()->GetFrame().IsInPlace())
189         OuterResizePixel( Point(),
190                           GetViewFrame()->GetWindow().GetOutputSizePixel() );
191 }
192 
193 // Set VisArea newly
194 
195 void SwView::SetVisArea( const tools::Rectangle &rRect, bool bUpdateScrollbar )
196 {
197     Size aOldSz( m_aVisArea.GetSize() );
198     if (comphelper::LibreOfficeKit::isActive() && m_pWrtShell)
199         // If m_pWrtShell's visible area is the whole document, do the same here.
200         aOldSz = m_pWrtShell->VisArea().SSize();
201 
202     if( rRect == m_aVisArea )
203         return;
204 
205     const SwTwips lMin = IsDocumentBorder() ? DOCUMENTBORDER : 0;
206 
207     // No negative position, no negative size
208     tools::Rectangle aLR = rRect;
209     if( aLR.Top() < lMin )
210     {
211         aLR.AdjustBottom(lMin - aLR.Top() );
212         aLR.SetTop( lMin );
213     }
214     if( aLR.Left() < lMin )
215     {
216         aLR.AdjustRight(lMin - aLR.Left() );
217         aLR.SetLeft( lMin );
218     }
219     if( aLR.Right() < 0 )
220         aLR.SetRight( 0 );
221     if( aLR.Bottom() < 0 )
222         aLR.SetBottom( 0 );
223 
224     if( aLR == m_aVisArea )
225         return;
226 
227     const Size aSize( aLR.GetSize() );
228     if( aSize.Width() < 0 || aSize.Height() < 0 )
229         return;
230 
231     // Before the data can be changed, call an update if necessary. This
232     // ensures that adjacent Paints in document coordinates are converted
233     // correctly.
234     // As a precaution, we do this only when an action is running in the
235     // shell, because then it is not really drawn but the rectangles will
236     // be only marked (in document coordinates).
237     if ( m_pWrtShell && m_pWrtShell->ActionPend() )
238         m_pWrtShell->GetWin()->Update();
239 
240     m_aVisArea = aLR;
241 
242     const bool bOuterResize = bUpdateScrollbar && UpdateScrollbars();
243 
244     if ( m_pWrtShell )
245     {
246         m_pWrtShell->VisPortChgd( m_aVisArea );
247         if ( aOldSz != m_pWrtShell->VisArea().SSize() &&
248              ( std::abs(aOldSz.Width() - m_pWrtShell->VisArea().Width()) > 2 ||
249                 std::abs(aOldSz.Height() - m_pWrtShell->VisArea().Height()) > 2 ) )
250             m_pWrtShell->InvalidateLayout( false );
251     }
252 
253     if ( !bProtectDocShellVisArea )
254     {
255         // If the size of VisArea is unchanged, we extend the size of the VisArea
256         // InternalObject on. By that the transport of errors shall be avoided.
257         tools::Rectangle aVis( m_aVisArea );
258         if ( aVis.GetSize() == aOldSz )
259             aVis.SetSize( GetDocShell()->SfxObjectShell::GetVisArea(ASPECT_CONTENT).GetSize() );
260                     // TODO/LATER: why casting?!
261                     //GetDocShell()->SfxInPlaceObject::GetVisArea().GetSize() );
262 
263         // With embedded always with modify...
264         // TODO/LATER: why casting?!
265         GetDocShell()->SfxObjectShell::SetVisArea( aVis );
266         /*
267         if ( GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
268             GetDocShell()->SfxInPlaceObject::SetVisArea( aVis );
269         else
270             GetDocShell()->SvEmbeddedObject::SetVisArea( aVis );*/
271     }
272 
273     SfxViewShell::VisAreaChanged();
274 
275     InvalidateRulerPos();
276 
277     if ( bOuterResize && !m_bInOuterResizePixel && !m_bInInnerResizePixel)
278             OuterResizePixel( Point(),
279                 GetViewFrame()->GetWindow().GetOutputSizePixel() );
280 }
281 
282 // Set Pos VisArea
283 
284 void SwView::SetVisArea( const Point &rPt, bool bUpdateScrollbar )
285 {
286     // Align once, so brushes will be inserted correctly.
287     // This goes wrong in the BrowseView, because the entire document may
288     // not be visible. Since the content in frames is fitting exactly,
289     // align is not possible (better idea?!?!)
290     // (fix: Bild.de, 200%) It does not work completely without alignment
291     // Let's see how far we get with half BrushSize.
292     Point aPt = GetEditWin().LogicToPixel( rPt );
293 #if HAVE_FEATURE_DESKTOP
294     const long nTmp = GetWrtShell().IsFrameView() ? 4 : 8;
295     aPt.AdjustX( -(aPt.X() % nTmp) );
296     aPt.AdjustY( -(aPt.Y() % nTmp) );
297 #endif
298     aPt = GetEditWin().PixelToLogic( aPt );
299 
300     if ( aPt == m_aVisArea.TopLeft() )
301         return;
302 
303     const long lXDiff = m_aVisArea.Left() - aPt.X();
304     const long lYDiff = m_aVisArea.Top()  - aPt.Y();
305     SetVisArea( tools::Rectangle( aPt,
306             Point( m_aVisArea.Right() - lXDiff, m_aVisArea.Bottom() - lYDiff ) ),
307             bUpdateScrollbar);
308 }
309 
310 void SwView::CheckVisArea()
311 {
312     m_pHScrollbar->SetAuto( m_pWrtShell->GetViewOptions()->getBrowseMode() &&
313                             !GetViewFrame()->GetFrame().IsInPlace() );
314     if ( IsDocumentBorder() )
315     {
316         if ( m_aVisArea.Left() != DOCUMENTBORDER ||
317              m_aVisArea.Top()  != DOCUMENTBORDER )
318         {
319             tools::Rectangle aNewVisArea( m_aVisArea );
320             aNewVisArea.Move( DOCUMENTBORDER - m_aVisArea.Left(),
321                               DOCUMENTBORDER - m_aVisArea.Top() );
322             SetVisArea( aNewVisArea );
323         }
324     }
325 }
326 
327 /// Calculate the visible range.
328 
329 //  OUT Point *pPt:             new position of the visible area
330 
331 //  IN  Rectangle &rRect:       Rectangle, which should be located
332 //                              within the new visible area.
333 //  sal_uInt16 nRange           optional accurate indication of the
334 //                              range by which to scroll if necessary.
335 
336 void SwView::CalcPt( Point *pPt, const tools::Rectangle &rRect,
337                      sal_uInt16 nRangeX, sal_uInt16 nRangeY)
338 {
339 
340     const SwTwips lMin = IsDocumentBorder() ? DOCUMENTBORDER : 0;
341 
342     long nYScroll = GetYScroll();
343     long nDesHeight = rRect.GetHeight();
344     long nCurHeight = m_aVisArea.GetHeight();
345     nYScroll = std::min(nYScroll, nCurHeight - nDesHeight); // If it is scarce, then scroll not too much.
346     if(nDesHeight > nCurHeight) // the height is not sufficient, then nYScroll is no longer of interest
347     {
348         pPt->setY( rRect.Top() );
349         pPt->setY( std::max( lMin, pPt->Y() ) );
350     }
351     else if ( rRect.Top() < m_aVisArea.Top() )                // Upward shift
352     {
353         pPt->setY( rRect.Top() - (nRangeY != USHRT_MAX ? nRangeY : nYScroll) );
354         pPt->setY( std::max( lMin, pPt->Y() ) );
355     }
356     else if( rRect.Bottom() > m_aVisArea.Bottom() )   // Downward shift
357     {
358         pPt->setY( rRect.Bottom() -
359                     (m_aVisArea.GetHeight()) + ( nRangeY != USHRT_MAX ?
360             nRangeY : nYScroll ) );
361         pPt->setY( SetVScrollMax( pPt->Y() ) );
362     }
363     long nXScroll = GetXScroll();
364     if ( rRect.Right() > m_aVisArea.Right() )         // Shift right
365     {
366         pPt->setX( rRect.Right()  -
367                     (m_aVisArea.GetWidth()) +
368                     (nRangeX != USHRT_MAX ? nRangeX : nXScroll) );
369         pPt->setX( SetHScrollMax( pPt->X() ) );
370     }
371     else if ( rRect.Left() < m_aVisArea.Left() )      // Shift left
372     {
373         pPt->setX( rRect.Left() - (nRangeX != USHRT_MAX ? nRangeX : nXScroll) );
374         pPt->setX( std::max( ::GetLeftMargin( *this ) + nLeftOfst, pPt->X() ) );
375         pPt->setX( std::min( rRect.Left() - nScrollX, pPt->X() ) );
376         pPt->setX( std::max( 0L, pPt->X() ) );
377     }
378 }
379 
380 // Scrolling
381 
382 bool SwView::IsScroll( const tools::Rectangle &rRect ) const
383 {
384     return m_bCenterCursor || m_bTopCursor || !m_aVisArea.IsInside(rRect);
385 }
386 
387 void SwView::Scroll( const tools::Rectangle &rRect, sal_uInt16 nRangeX, sal_uInt16 nRangeY )
388 {
389     if ( m_aVisArea.IsEmpty() )
390         return;
391 
392     tools::Rectangle aOldVisArea( m_aVisArea );
393     long nDiffY = 0;
394 
395     weld::Window* pCareDialog = SwViewShell::GetCareDialog(GetWrtShell());
396     if (pCareDialog)
397     {
398         int x, y, width, height;
399         tools::Rectangle aDlgRect;
400         if (pCareDialog->get_extents_relative_to(*GetEditWin().GetFrameWeld(), x, y, width, height))
401         {
402             Point aTopLeft(GetEditWin().GetSystemWindow()->OutputToAbsoluteScreenPixel(Point(x, y)));
403             aTopLeft = GetEditWin().AbsoluteScreenToOutputPixel(aTopLeft);
404             aDlgRect = GetEditWin().PixelToLogic(tools::Rectangle(aTopLeft, Size(width, height)));
405         }
406 
407         // Only if the dialogue is not the VisArea right or left:
408         if ( aDlgRect.Left() < m_aVisArea.Right() &&
409              aDlgRect.Right() > m_aVisArea.Left() )
410         {
411             // If we are not supposed to be centered, lying in the VisArea
412             // and are not covered by the dialogue ...
413             if ( !m_bCenterCursor && aOldVisArea.IsInside( rRect )
414                  && ( rRect.Left() > aDlgRect.Right()
415                       || rRect.Right() < aDlgRect.Left()
416                       || rRect.Top() > aDlgRect.Bottom()
417                       || rRect.Bottom() < aDlgRect.Top() ) )
418                 return;
419 
420             // Is above or below the dialogue more space?
421             long nTopDiff = aDlgRect.Top() - m_aVisArea.Top();
422             long nBottomDiff = m_aVisArea.Bottom() - aDlgRect.Bottom();
423             if ( nTopDiff < nBottomDiff )
424             {
425                 if ( nBottomDiff > 0 ) // Is there room below at all?
426                 {   // then we move the upper edge and we remember this
427                     nDiffY = aDlgRect.Bottom() - m_aVisArea.Top();
428                     m_aVisArea.AdjustTop(nDiffY );
429                 }
430             }
431             else
432             {
433                 if ( nTopDiff > 0 ) // Is there room below at all?
434                     m_aVisArea.SetBottom( aDlgRect.Top() ); // Modify the lower edge
435             }
436         }
437     }
438 
439     //s.o. !IsScroll()
440     if( !(m_bCenterCursor || m_bTopCursor) && m_aVisArea.IsInside( rRect ) )
441     {
442         m_aVisArea = aOldVisArea;
443         return;
444     }
445     // If the rectangle is larger than the visible area -->
446     // upper left corner
447     Size aSize( rRect.GetSize() );
448     const Size aVisSize( m_aVisArea.GetSize() );
449     if( !m_aVisArea.IsEmpty() && (
450         aSize.Width() + GetXScroll() > aVisSize.Width() ||
451         aSize.Height()+ GetYScroll() > aVisSize.Height() ))
452     {
453         Point aPt( m_aVisArea.TopLeft() );
454         aSize.setWidth( std::min( aSize.Width(), aVisSize.Width() ) );
455         aSize.setHeight( std::min( aSize.Height(),aVisSize.Height()) );
456 
457         CalcPt( &aPt, tools::Rectangle( rRect.TopLeft(), aSize ),
458                 static_cast< sal_uInt16 >((aVisSize.Width() - aSize.Width()) / 2),
459                 static_cast< sal_uInt16 >((aVisSize.Height()- aSize.Height())/ 2) );
460 
461         if( m_bTopCursor )
462         {
463             const long nBorder = IsDocumentBorder() ? DOCUMENTBORDER : 0;
464             aPt.setY( std::min( std::max( nBorder, rRect.Top() ),
465                                 m_aDocSz.Height() + nBorder -
466                                     m_aVisArea.GetHeight() ) );
467         }
468         aPt.AdjustY( -nDiffY );
469         m_aVisArea = aOldVisArea;
470         SetVisArea( aPt );
471         return;
472     }
473     if( !m_bCenterCursor )
474     {
475         Point aPt( m_aVisArea.TopLeft() );
476         CalcPt( &aPt, rRect, nRangeX, nRangeY );
477 
478         if( m_bTopCursor )
479         {
480             const long nBorder = IsDocumentBorder() ? DOCUMENTBORDER : 0;
481             aPt.setY( std::min( std::max( nBorder, rRect.Top() ),
482                                 m_aDocSz.Height() + nBorder -
483                                     m_aVisArea.GetHeight() ) );
484         }
485 
486         aPt.AdjustY( -nDiffY );
487         m_aVisArea = aOldVisArea;
488         SetVisArea( aPt );
489         return;
490     }
491 
492     //Center cursor
493     Point aPnt( m_aVisArea.TopLeft() );
494     // ... in Y-direction in any case
495     aPnt.AdjustY(( rRect.Top() + rRect.Bottom()
496                   - m_aVisArea.Top() - m_aVisArea.Bottom() ) / 2 - nDiffY );
497     // ... in X-direction, only if the rectangle protrudes over the right or left of the VisArea.
498     if ( rRect.Right() > m_aVisArea.Right() || rRect.Left() < m_aVisArea.Left() )
499     {
500         aPnt.AdjustX(( rRect.Left() + rRect.Right()
501                   - m_aVisArea.Left() - m_aVisArea.Right() ) / 2 );
502         aPnt.setX( SetHScrollMax( aPnt.X() ) );
503         const SwTwips lMin = IsDocumentBorder() ? DOCUMENTBORDER : 0;
504         aPnt.setX( std::max( (GetLeftMargin( *this ) - lMin) + nLeftOfst, aPnt.X() ) );
505     }
506     m_aVisArea = aOldVisArea;
507     if (pCareDialog)
508     {
509         // If we want to avoid only a dialogue, we do
510         // not want to go beyond the end of the document.
511         aPnt.setY( SetVScrollMax( aPnt.Y() ) );
512     }
513     SetVisArea( aPnt );
514 }
515 
516 /// Scroll page by page
517 //  Returns the value by which to be scrolled with PageUp / Down
518 
519 bool SwView::GetPageScrollUpOffset( SwTwips &rOff ) const
520 {
521     // in the LOK case, force the value set by the API
522     if (comphelper::LibreOfficeKit::isActive() && m_nLOKPageUpDownOffset > 0)
523     {
524         rOff = -m_nLOKPageUpDownOffset;
525         return true;
526     }
527 
528     if ( !m_aVisArea.Top() || !m_aVisArea.GetHeight() )
529         return false;
530     long nYScrl = GetYScroll() / 2;
531     rOff = -(m_aVisArea.GetHeight() - nYScrl);
532     // Do not scroll before the beginning of the document.
533     if( m_aVisArea.Top() - rOff < 0 )
534         rOff = rOff - m_aVisArea.Top();
535     else if( GetWrtShell().GetCharRect().Top() < (m_aVisArea.Top() + nYScrl))
536         rOff += nYScrl;
537 
538     return true;
539 }
540 
541 bool SwView::GetPageScrollDownOffset( SwTwips &rOff ) const
542 {
543     // in the LOK case, force the value set by the API
544     if (comphelper::LibreOfficeKit::isActive() && m_nLOKPageUpDownOffset > 0)
545     {
546         rOff = m_nLOKPageUpDownOffset;
547         return true;
548     }
549 
550     if ( !m_aVisArea.GetHeight() ||
551          (m_aVisArea.GetHeight() > m_aDocSz.Height()) )
552         return false;
553     long nYScrl = GetYScroll() / 2;
554     rOff = m_aVisArea.GetHeight() - nYScrl;
555     // Do not scroll past the end of the document.
556     if ( m_aVisArea.Top() + rOff > m_aDocSz.Height() )
557         rOff = m_aDocSz.Height() - m_aVisArea.Bottom();
558     else if( GetWrtShell().GetCharRect().Bottom() >
559                                             ( m_aVisArea.Bottom() - nYScrl ))
560         rOff -= nYScrl;
561 
562     return rOff > 0;
563 }
564 
565 // Scroll page by page
566 bool SwView::PageUp()
567 {
568     if (!m_aVisArea.GetHeight())
569         return false;
570 
571     Point aPos(m_aVisArea.TopLeft());
572     aPos.AdjustY( -(m_aVisArea.GetHeight() - (GetYScroll() / 2)) );
573     aPos.setY( std::max(0L, aPos.Y()) );
574     SetVisArea( aPos );
575     return true;
576 }
577 
578 bool SwView::PageDown()
579 {
580     if ( !m_aVisArea.GetHeight() )
581         return false;
582     Point aPos( m_aVisArea.TopLeft() );
583     aPos.AdjustY(m_aVisArea.GetHeight() - (GetYScroll() / 2) );
584     aPos.setY( SetVScrollMax( aPos.Y() ) );
585     SetVisArea( aPos );
586     return true;
587 }
588 
589 void SwView::PhyPageUp()
590 {
591     // Check for the currently visible page, do not format
592     sal_uInt16 nActPage = m_pWrtShell->GetNextPrevPageNum( false );
593 
594     if( USHRT_MAX != nActPage )
595     {
596         const Point aPt( m_aVisArea.Left(),
597                          m_pWrtShell->GetPagePos( nActPage ).Y() );
598         Point aAlPt( AlignToPixel( aPt ) );
599         // If there is a difference, has been truncated --> then add one pixel,
600         // so that no residue of the previous page is visible.
601         if( aPt.Y() != aAlPt.Y() )
602             aAlPt.AdjustY(3 * GetEditWin().PixelToLogic( Size( 0, 1 ) ).Height() );
603         SetVisArea( aAlPt );
604     }
605 }
606 
607 void SwView::PhyPageDown()
608 {
609     // Check for the currently visible page, do not format
610     sal_uInt16 nActPage = m_pWrtShell->GetNextPrevPageNum();
611     // If the last page of the document is visible, do nothing.
612     if( USHRT_MAX != nActPage )
613     {
614         const Point aPt( m_aVisArea.Left(),
615                          m_pWrtShell->GetPagePos( nActPage ).Y() );
616         Point aAlPt( AlignToPixel( aPt ) );
617         // If there is a difference, has been truncated --> then add one pixel,
618         // so that no residue of the previous page is visible.
619         if( aPt.Y() != aAlPt.Y() )
620             aAlPt.AdjustY(3 * GetEditWin().PixelToLogic( Size( 0, 1 ) ).Height() );
621         SetVisArea( aAlPt );
622     }
623 }
624 
625 bool SwView::PageUpCursor( bool bSelect )
626 {
627     if ( !bSelect )
628     {
629         const FrameTypeFlags eType = m_pWrtShell->GetFrameType(nullptr,true);
630         if ( eType & FrameTypeFlags::FOOTNOTE )
631         {
632             m_pWrtShell->MoveCursor();
633             m_pWrtShell->GotoFootnoteAnchor();
634             m_pWrtShell->Right(CRSR_SKIP_CHARS, false, 1, false );
635             return true;
636         }
637     }
638 
639     SwTwips lOff = 0;
640     if ( GetPageScrollUpOffset( lOff ) &&
641          (m_pWrtShell->IsCursorReadonly() ||
642           !m_pWrtShell->PageCursor( lOff, bSelect )) &&
643          PageUp() )
644     {
645         m_pWrtShell->ResetCursorStack();
646         return true;
647     }
648     return false;
649 }
650 
651 bool SwView::PageDownCursor(bool bSelect)
652 {
653     SwTwips lOff = 0;
654     if ( GetPageScrollDownOffset( lOff ) &&
655          (m_pWrtShell->IsCursorReadonly() ||
656           !m_pWrtShell->PageCursor( lOff, bSelect )) &&
657          PageDown() )
658     {
659         m_pWrtShell->ResetCursorStack();
660         return true;
661     }
662     return false;
663 }
664 
665 // Handler of the scrollbars
666 
667 IMPL_LINK( SwView, ScrollHdl, ScrollBar *, p, void )
668 {
669     SwScrollbar* pScrollbar = static_cast<SwScrollbar*>(p);
670     if ( GetWrtShell().ActionPend() )
671         return;
672 
673     if ( pScrollbar->GetType() == ScrollType::Drag )
674         m_pWrtShell->EnableSmooth( false );
675 
676     if(!m_pWrtShell->GetViewOptions()->getBrowseMode() &&
677         pScrollbar->GetType() == ScrollType::Drag)
678     {
679         // Here comment out again if it is not desired to scroll together:
680         // The end scrollhandler invalidate the FN_STAT_PAGE,
681         // so we don't must do it again.
682         EndScrollHdl(pScrollbar);
683 
684         if ( !m_bWheelScrollInProgress && Help::IsQuickHelpEnabled() &&
685              m_pWrtShell->GetViewOptions()->IsShowScrollBarTips())
686         {
687 
688             Point aPos( m_aVisArea.TopLeft() );
689             lcl_GetPos(this, aPos, pScrollbar, IsDocumentBorder());
690 
691             sal_uInt16 nPhNum = 1;
692             sal_uInt16 nVirtNum = 1;
693 
694             OUString sDisplay;
695             if(m_pWrtShell->GetPageNumber( aPos.Y(), false, nPhNum, nVirtNum, sDisplay ))
696             {
697                 // The end scrollhandler invalidate the FN_STAT_PAGE,
698                 // so we don't must do it again.
699         //      if(!GetViewFrame()->GetFrame().IsInPlace())
700         //            S F X_BINDINGS().Update(FN_STAT_PAGE);
701 
702                 //QuickHelp:
703                 if( m_pWrtShell->GetPageCnt() > 1 )
704                 {
705                     tools::Rectangle aRect;
706                     aRect.SetLeft( pScrollbar->GetParent()->OutputToScreenPixel(
707                                         pScrollbar->GetPosPixel() ).X() -8 );
708                     aRect.SetTop( pScrollbar->OutputToScreenPixel(
709                                     pScrollbar->GetPointerPosPixel() ).Y() );
710                     aRect.SetRight( aRect.Left() );
711                     aRect.SetBottom( aRect.Top() );
712 
713                     OUString sPageStr( GetPageStr( nPhNum, nVirtNum, sDisplay ));
714                     SwContentAtPos aCnt( IsAttrAtPos::Outline );
715                     bool bSuccess = m_pWrtShell->GetContentAtPos(aPos, aCnt);
716                     if (bSuccess && !aCnt.sStr.isEmpty())
717                     {
718                         sPageStr += "  - ";
719                         sal_Int32 nChunkLen = std::min<sal_Int32>(aCnt.sStr.getLength(), 80);
720                         OUString sChunk = aCnt.sStr.copy(0, nChunkLen);
721                         sPageStr = sChunk + sPageStr;
722                         sPageStr = sPageStr.replace('\t', ' ');
723                         sPageStr = sPageStr.replace(0x0a, ' ');
724                     }
725                     nPgNum = nPhNum;
726                 }
727             }
728         }
729     }
730     else
731         EndScrollHdl(pScrollbar);
732 
733     if ( pScrollbar->GetType() == ScrollType::Drag )
734         m_pWrtShell->EnableSmooth( true );
735 }
736 
737 // Handler of the scrollbars
738 
739 IMPL_LINK( SwView, EndScrollHdl, ScrollBar *, p, void )
740 {
741     SwScrollbar* pScrollbar = static_cast<SwScrollbar*>(p);
742     if ( !GetWrtShell().ActionPend() )
743     {
744         if(nPgNum)
745         {
746             nPgNum = 0;
747             Help::ShowQuickHelp(pScrollbar, tools::Rectangle(), OUString());
748         }
749         Point aPos( m_aVisArea.TopLeft() );
750         bool bBorder = IsDocumentBorder();
751         lcl_GetPos(this, aPos, pScrollbar, bBorder);
752         if ( bBorder && aPos == m_aVisArea.TopLeft() )
753             UpdateScrollbars();
754         else
755             SetVisArea( aPos, false );
756 
757         GetViewFrame()->GetBindings().Update(FN_STAT_PAGE);
758     }
759 }
760 
761 // Calculates the size of the m_aVisArea in dependency of the size of
762 // EditWin on the screen.
763 
764 void SwView::CalcVisArea( const Size &rOutPixel )
765 {
766     Point aTopLeft;
767     tools::Rectangle aRect( aTopLeft, rOutPixel );
768     aTopLeft = GetEditWin().PixelToLogic( aTopLeft );
769     Point aBottomRight( GetEditWin().PixelToLogic( aRect.BottomRight() ) );
770 
771     aRect.SetLeft( aTopLeft.X() );
772     aRect.SetTop( aTopLeft.Y() );
773     aRect.SetRight( aBottomRight.X() );
774     aRect.SetBottom( aBottomRight.Y() );
775 
776     // The shifts to the right and/or below can now be incorrect
777     // (e.g. change zoom level, change view size).
778     const long lBorder = IsDocumentBorder() ? DOCUMENTBORDER : DOCUMENTBORDER*2;
779     if ( aRect.Left() )
780     {
781         const long lWidth = GetWrtShell().GetDocSize().Width() + lBorder;
782         if ( aRect.Right() > lWidth )
783         {
784             long lDelta    = aRect.Right() - lWidth;
785             aRect.AdjustLeft( -lDelta );
786             aRect.AdjustRight( -lDelta );
787         }
788     }
789     if ( aRect.Top() )
790     {
791         const long lHeight = GetWrtShell().GetDocSize().Height() + lBorder;
792         if ( aRect.Bottom() > lHeight )
793         {
794             long lDelta     = aRect.Bottom() - lHeight;
795             aRect.AdjustTop( -lDelta );
796             aRect.AdjustBottom( -lDelta );
797         }
798     }
799     SetVisArea( aRect );
800     GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
801     GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER ); // for snapping points
802 }
803 
804 // Rearrange control elements
805 
806 void SwView::CalcAndSetBorderPixel( SvBorder &rToFill )
807 {
808     bool bRightVRuler = m_pWrtShell->GetViewOptions()->IsVRulerRight();
809     if ( m_pVRuler->IsVisible() )
810     {
811         long nWidth = m_pVRuler->GetSizePixel().Width();
812         if(bRightVRuler)
813             rToFill.Right() = nWidth;
814         else
815             rToFill.Left() = nWidth;
816     }
817 
818     OSL_ENSURE(m_pHRuler, "Why is the ruler not present?");
819     if ( m_pHRuler->IsVisible() )
820         rToFill.Top() = m_pHRuler->GetSizePixel().Height();
821 
822     const StyleSettings &rSet = GetEditWin().GetSettings().GetStyleSettings();
823     const long nTmp = rSet.GetScrollBarSize();
824     if( m_pVScrollbar->IsVisible(true) )
825     {
826         if(bRightVRuler)
827             rToFill.Left() = nTmp;
828         else
829             rToFill.Right()  = nTmp;
830     }
831     if ( m_pHScrollbar->IsVisible(true) )
832         rToFill.Bottom() = nTmp;
833 
834     SetBorderPixel( rToFill );
835 }
836 
837 void ViewResizePixel( const vcl::RenderContext &rRef,
838                     const Point &rOfst,
839                     const Size &rSize,
840                     const Size &rEditSz,
841                     SwScrollbar& rVScrollbar,
842                     SwScrollbar& rHScrollbar,
843                     vcl::Window& rScrollBarBox,
844                     SvxRuler* pVRuler,
845                     SvxRuler* pHRuler,
846                     bool bVRulerRight )
847 {
848 // ViewResizePixel is also used by Preview!!!
849 
850     const bool bHRuler = pHRuler && pHRuler->IsVisible();
851     const long nHLinSzHeight = bHRuler ?
852                         pHRuler->GetSizePixel().Height() : 0;
853     const bool bVRuler = pVRuler && pVRuler->IsVisible();
854     const long nVLinSzWidth = bVRuler ?
855                         pVRuler->GetSizePixel().Width() : 0;
856 
857     const long nScrollBarSize = rRef.GetSettings().GetStyleSettings().GetScrollBarSize();
858     const long nHBSzHeight = rHScrollbar.IsVisible(true) ? nScrollBarSize : 0;
859     const long nVBSzWidth = rVScrollbar.IsVisible(true) ? nScrollBarSize : 0;
860 
861     if(pVRuler)
862     {
863         WinBits nStyle = pVRuler->GetStyle()&~WB_RIGHT_ALIGNED;
864         Point aPos( rOfst.X(), rOfst.Y()+nHLinSzHeight );
865         if(bVRulerRight)
866         {
867             aPos.AdjustX(rSize.Width() - nVLinSzWidth );
868             nStyle |= WB_RIGHT_ALIGNED;
869         }
870         Size  aSize( nVLinSzWidth, rEditSz.Height() );
871         if(!aSize.Width())
872             aSize.setWidth( pVRuler->GetSizePixel().Width() );
873         pVRuler->SetStyle(nStyle);
874         pVRuler->SetPosSizePixel( aPos, aSize );
875         if(!pVRuler->IsVisible())
876             pVRuler->Resize();
877     }
878     // Ruler needs a resize, otherwise it will not work in the invisible condition
879     if(pHRuler)
880     {
881         Size aSize( rSize.Width(), nHLinSzHeight );
882         if ( nVBSzWidth && !bVRulerRight)
883             aSize.AdjustWidth( -nVBSzWidth );
884         if(!aSize.Height())
885             aSize.setHeight( pHRuler->GetSizePixel().Height() );
886         pHRuler->SetPosSizePixel( rOfst, aSize );
887         // VCL calls no resize on invisible windows
888         // but that is not a good idea for the ruler
889         if(!pHRuler->IsVisible())
890             pHRuler->Resize();
891     }
892 
893     // Arrange scrollbars and SizeBox
894     Point aScrollFillPos;
895     {
896         Point aPos( rOfst.X(),
897                     rOfst.Y()+rSize.Height()-nHBSzHeight );
898         if(bVRulerRight)
899         {
900             aPos.AdjustX(nVBSzWidth );
901         }
902 
903         Size  aSize( rSize.Width(), nHBSzHeight );
904         if ( nVBSzWidth )
905             aSize.AdjustWidth( -nVBSzWidth );
906         rHScrollbar.SetPosSizePixel( aPos, aSize );
907         aScrollFillPos.setY( aPos.Y() );
908     }
909     {
910         Point aPos( rOfst.X()+rSize.Width()-nVBSzWidth,
911                     rOfst.Y() );
912         Size  aSize( nVBSzWidth, rSize.Height() );
913         if(bVRulerRight)
914         {
915             aPos.setX( rOfst.X() );
916             if(bHRuler)
917             {
918                 aPos.AdjustY(nHLinSzHeight );
919                 aSize.AdjustHeight( -nHLinSzHeight );
920             }
921         }
922 
923         if ( nHBSzHeight )
924             aSize.AdjustHeight( -nHBSzHeight );
925         rVScrollbar.SetPosSizePixel( aPos, aSize );
926 
927         aPos.AdjustY(aSize.Height() );
928 
929         aScrollFillPos.setX( aPos.X() );
930     }
931 
932     rScrollBarBox.SetPosSizePixel(aScrollFillPos, Size(nVBSzWidth, nHBSzHeight));
933 }
934 
935 void SwView::ShowAtResize()
936 {
937     m_bShowAtResize = false;
938     if ( m_pWrtShell->GetViewOptions()->IsViewHRuler() )
939         m_pHRuler->Show();
940 }
941 
942 void SwView::InnerResizePixel( const Point &rOfst, const Size &rSize, bool )
943 {
944     Size aObjSize = GetObjectShell()->GetVisArea().GetSize();
945     if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
946     {
947         SvBorder aBorder( GetBorderPixel() );
948         Size aSize( rSize );
949         aSize.AdjustWidth( -(aBorder.Left() + aBorder.Right()) );
950         aSize.AdjustHeight( -(aBorder.Top() + aBorder.Bottom()) );
951         Size aObjSizePixel = GetWindow()->LogicToPixel(aObjSize, MapMode(MapUnit::MapTwip));
952         SfxViewShell::SetZoomFactor( Fraction( aSize.Width(), aObjSizePixel.Width() ),
953                         Fraction( aSize.Height(), aObjSizePixel.Height() ) );
954     }
955 
956     m_bInInnerResizePixel = true;
957     const bool bHScrollVisible = m_pHScrollbar->IsVisible(true);
958     const bool bVScrollVisible = m_pVScrollbar->IsVisible(true);
959     bool bRepeat = false;
960     do
961     {
962         Size aSz( rSize );
963         SvBorder aBorder;
964         CalcAndSetBorderPixel( aBorder );
965         if ( GetViewFrame()->GetFrame().IsInPlace() )
966         {
967             Size aViewSize( aSz );
968             Point aViewPos( rOfst );
969             aViewSize.AdjustHeight( -(aBorder.Top() + aBorder.Bottom()) );
970             aViewSize.AdjustWidth( -(aBorder.Left() + aBorder.Right()) );
971             aViewPos.AdjustX(aBorder.Left() );
972             aViewPos.AdjustY(aBorder.Top() );
973             GetEditWin().SetPosSizePixel( aViewPos, aViewSize );
974         }
975         else
976         {
977             aSz.AdjustHeight(aBorder.Top()  + aBorder.Bottom() );
978             aSz.AdjustWidth(aBorder.Left() + aBorder.Right() );
979         }
980 
981         Size aEditSz( GetEditWin().GetOutputSizePixel() );
982         ViewResizePixel( GetEditWin(), rOfst, aSz, aEditSz, *m_pVScrollbar,
983                             *m_pHScrollbar, *m_pScrollFill, m_pVRuler, m_pHRuler,
984                             m_pWrtShell->GetViewOptions()->IsVRulerRight());
985         if ( m_bShowAtResize )
986             ShowAtResize();
987 
988         if( m_pHRuler->IsVisible() || m_pVRuler->IsVisible() )
989         {
990             const Fraction& rFrac = GetEditWin().GetMapMode().GetScaleX();
991             long nZoom = 100;
992             if (rFrac.IsValid())
993                 nZoom = long(rFrac * 100);
994 
995             const Fraction aFrac( nZoom, 100 );
996             m_pVRuler->SetZoom( aFrac );
997             m_pHRuler->SetZoom( aFrac );
998             InvalidateRulerPos();   // Invalidate content.
999         }
1000         // Reset the cursor stack because the cursor positions for PageUp/Down
1001         // no longer fit the currently visible area.
1002         m_pWrtShell->ResetCursorStack();
1003 
1004         // EditWin never set!
1005 
1006         // Set VisArea, but do not call the SetVisArea of the Docshell there!
1007         bProtectDocShellVisArea = true;
1008         CalcVisArea( aEditSz );
1009         // Visibility changes of the automatic horizontal scrollbar
1010         // require to repeat the ViewResizePixel() call - but only once!
1011         if(bRepeat)
1012             bRepeat = false;
1013         else if(bHScrollVisible != m_pHScrollbar->IsVisible(true) ||
1014                 bVScrollVisible != m_pVScrollbar->IsVisible(true))
1015             bRepeat = true;
1016     }while( bRepeat );
1017     bProtectDocShellVisArea = false;
1018     m_bInInnerResizePixel = false;
1019 }
1020 
1021 void SwView::OuterResizePixel( const Point &rOfst, const Size &rSize )
1022 {
1023     // #i16909# return, if no size (caused by minimize window).
1024     if ( m_bInOuterResizePixel || ( !rSize.Width() && !rSize.Height() ) )
1025         return;
1026     m_bInOuterResizePixel = true;
1027 
1028     // Determine whether scroll bars may be displayed.
1029     bool bShowH = true,
1030          bShowV = true,
1031          bAuto  = true,
1032          bHAuto = true;
1033 
1034     const SwViewOption *pVOpt = m_pWrtShell->GetViewOptions();
1035     if ( !pVOpt->IsReadonly() || pVOpt->IsStarOneSetting() )
1036     {
1037         bShowH = pVOpt->IsViewHScrollBar();
1038         bShowV = pVOpt->IsViewVScrollBar();
1039     }
1040 
1041     if (!m_bHScrollbarEnabled)
1042     {
1043         bHAuto = bShowH = false;
1044     }
1045     if (!m_bVScrollbarEnabled)
1046     {
1047         bAuto = bShowV = false;
1048     }
1049 
1050     SwDocShell* pDocSh = GetDocShell();
1051     bool bIsPreview = pDocSh->IsPreview();
1052     if( bIsPreview )
1053     {
1054         bShowH = bShowV = bHAuto = bAuto = false;
1055     }
1056     if(m_pHScrollbar->IsVisible(false) != bShowH && !bHAuto)
1057         ShowHScrollbar(bShowH);
1058     m_pHScrollbar->SetAuto( bHAuto );
1059     if(m_pVScrollbar->IsVisible(false) != bShowV && !bAuto)
1060         ShowVScrollbar(bShowV);
1061     m_pVScrollbar->SetAuto(bAuto);
1062 
1063     SET_CURR_SHELL( m_pWrtShell.get() );
1064     bool bRepeat = false;
1065     long nCnt = 0;
1066 
1067     bool bUnLockView = !m_pWrtShell->IsViewLocked();
1068     m_pWrtShell->LockView( true );
1069     m_pWrtShell->LockPaint();
1070 
1071     do {
1072         ++nCnt;
1073         const bool bScroll1 = m_pVScrollbar->IsVisible(true);
1074         const bool bScroll2 = m_pHScrollbar->IsVisible(true);
1075         SvBorder aBorder;
1076         CalcAndSetBorderPixel( aBorder );
1077         const Size aEditSz( GetEditWin().GetOutputSizePixel() );
1078         ViewResizePixel( GetEditWin(), rOfst, rSize, aEditSz, *m_pVScrollbar,
1079                                 *m_pHScrollbar, *m_pScrollFill, m_pVRuler, m_pHRuler,
1080                                 m_pWrtShell->GetViewOptions()->IsVRulerRight() );
1081         if ( m_bShowAtResize )
1082             ShowAtResize();
1083 
1084         if( m_pHRuler->IsVisible() || m_pVRuler->IsVisible() )
1085             InvalidateRulerPos();   // Invalidate content.
1086 
1087         // Reset the cursor stack because the cursor positions for PageUp/Down
1088         // no longer fit the currently visible area.
1089         m_pWrtShell->ResetCursorStack();
1090 
1091         OSL_ENSURE( !GetEditWin().IsVisible() ||
1092                     (( aEditSz.Width() > 0 && aEditSz.Height() > 0 )
1093                         || !m_aVisArea.IsEmpty()), "Small world, isn't it?" );
1094 
1095         // Never set EditWin!
1096 
1097         // Of course the VisArea must also be set.
1098         // Now is the right time to re-calculate the zoom if it is not a simple factor.
1099         m_pWrtShell->StartAction();
1100         CalcVisArea( aEditSz );
1101 
1102         //Thus also in the outplace editing the page width will be adjusted immediately.
1103         //TODO/LATER: is that still necessary?!
1104         /*
1105         if ( pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
1106             pDocSh->SetVisArea(
1107                             pDocSh->SfxInPlaceObject::GetVisArea() );*/
1108         if ( m_pWrtShell->GetViewOptions()->GetZoomType() != SvxZoomType::PERCENT &&
1109              !m_pWrtShell->GetViewOptions()->getBrowseMode() )
1110             SetZoom_( aEditSz, m_pWrtShell->GetViewOptions()->GetZoomType(), 100, true );
1111         m_pWrtShell->EndAction();
1112 
1113         bRepeat = bScroll1 != m_pVScrollbar->IsVisible(true);
1114         if ( !bRepeat )
1115             bRepeat = bScroll2 != m_pHScrollbar->IsVisible(true);
1116 
1117         // Do no infinite loops.
1118         // If possible stop when the (auto-) scroll bars are visible.
1119         if ( bRepeat &&
1120              ( nCnt > 10 || ( nCnt > 3 && bHAuto && bAuto ) )
1121            )
1122         {
1123             bRepeat = false;
1124         }
1125 
1126     } while ( bRepeat );
1127 
1128     m_pWrtShell->UnlockPaint();
1129     if( bUnLockView )
1130         m_pWrtShell->LockView( false );
1131 
1132     m_bInOuterResizePixel = false;
1133 
1134     if ( m_pPostItMgr )
1135     {
1136         m_pPostItMgr->CalcRects();
1137         m_pPostItMgr->LayoutPostIts();
1138     }
1139 }
1140 
1141 void SwView::SetZoomFactor( const Fraction &rX, const Fraction &rY )
1142 {
1143     const Fraction &rFrac = rX < rY ? rX : rY;
1144     SetZoom( SvxZoomType::PERCENT, static_cast<short>(long(rFrac * Fraction( 100, 1 ))) );
1145 
1146     // To minimize rounding errors we also adjust the odd values
1147     // of the base class if necessary.
1148     SfxViewShell::SetZoomFactor( rX, rY );
1149 }
1150 
1151 bool SwView::UpdateScrollbars()
1152 {
1153     bool bRet = false;
1154     if ( !m_aVisArea.IsEmpty() )
1155     {
1156         const bool bBorder = IsDocumentBorder();
1157         tools::Rectangle aTmpRect( m_aVisArea );
1158         if ( bBorder )
1159         {
1160             Point aPt( DOCUMENTBORDER, DOCUMENTBORDER );
1161             aPt = AlignToPixel( aPt );
1162             aTmpRect.Move( -aPt.X(), -aPt.Y() );
1163         }
1164 
1165         Size aTmpSz( m_aDocSz );
1166         const long lOfst = bBorder ? 0 : DOCUMENTBORDER * 2;
1167         aTmpSz.AdjustWidth(lOfst ); aTmpSz.AdjustHeight(lOfst );
1168 
1169         {
1170             const bool bVScrollVisible = m_pVScrollbar->IsVisible(true);
1171             m_pVScrollbar->DocSzChgd( aTmpSz );
1172             m_pVScrollbar->ViewPortChgd( aTmpRect );
1173             if ( bVScrollVisible != m_pVScrollbar->IsVisible(true) )
1174                 bRet = true;
1175         }
1176         {
1177             const bool bHScrollVisible = m_pHScrollbar->IsVisible(true);
1178             m_pHScrollbar->DocSzChgd( aTmpSz );
1179             m_pHScrollbar->ViewPortChgd( aTmpRect );
1180             if ( bHScrollVisible != m_pHScrollbar->IsVisible(true) )
1181                 bRet = true;
1182             m_pScrollFill->Show(m_pHScrollbar->IsVisible(true) && m_pVScrollbar->IsVisible(true) );
1183         }
1184     }
1185     return bRet;
1186 }
1187 
1188 void SwView::Move()
1189 {
1190     if ( GetWrtShell().IsInSelect() )
1191         GetWrtShell().EndSelect();
1192     SfxViewShell::Move();
1193 }
1194 
1195 bool SwView::HandleWheelCommands( const CommandEvent& rCEvt )
1196 {
1197     bool bOk = false;
1198     const CommandWheelData* pWData = rCEvt.GetWheelData();
1199     if (pWData && CommandWheelMode::ZOOM == pWData->GetMode())
1200     {
1201         long nFact = m_pWrtShell->GetViewOptions()->GetZoom();
1202         if( 0L > pWData->GetDelta() )
1203             nFact = std::max( long(20), basegfx::zoomtools::zoomOut( nFact ));
1204         else
1205             nFact = std::min( long(600), basegfx::zoomtools::zoomIn( nFact ));
1206 
1207         SetZoom( SvxZoomType::PERCENT, nFact );
1208         bOk = true;
1209     }
1210     else
1211     {
1212         if (pWData && pWData->GetMode()==CommandWheelMode::SCROLL)
1213         {
1214             // This influences whether quick help is shown
1215             m_bWheelScrollInProgress=true;
1216         }
1217 
1218         if (pWData && (CommandWheelMode::SCROLL==pWData->GetMode()) &&
1219                 (COMMAND_WHEEL_PAGESCROLL == pWData->GetScrollLines()))
1220         {
1221             if (pWData->GetDelta()<0)
1222                 PhyPageDown();
1223             else
1224                 PhyPageUp();
1225             bOk = true;
1226         }
1227         else
1228             bOk = m_pEditWin->HandleScrollCommand(rCEvt, m_pHScrollbar, m_pVScrollbar);
1229 
1230         // Restore default state for case when scroll command comes from dragging scrollbar handle
1231         m_bWheelScrollInProgress=false;
1232     }
1233     return bOk;
1234 }
1235 
1236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1237