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
