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