1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 #include <pagepreviewlayout.hxx> 31 #ifndef _PREVWPAGE_HXX 32 #include <prevwpage.hxx> 33 #endif 34 35 #include <algorithm> 36 #include <vcl/window.hxx> 37 #include <rootfrm.hxx> 38 #include <pagefrm.hxx> 39 #include <viewsh.hxx> 40 #include <viewimp.hxx> 41 #include <viewopt.hxx> 42 #include <swregion.hxx> 43 #ifndef _COMCORE_HRC 44 #include <comcore.hrc> 45 #endif 46 // OD 19.02.2003 #107369# - method <SwAlignRect(..)> 47 #include <frmtool.hxx> 48 // OD 24.09.2003 #i19975# 49 #include <svx/zoomitem.hxx> 50 #include <printdata.hxx> 51 52 #include <IDocumentDeviceAccess.hxx> 53 54 // OD 20.02.2003 #107369# - method to update statics for paint 55 // Note: method defined in '/sw/source/core/layout/paintfrm.cxx' 56 extern void SwCalcPixStatics( OutputDevice *pOut ); 57 58 // ============================================================================= 59 // methods to initialize page preview layout 60 // ============================================================================= 61 SwPagePreviewLayout::SwPagePreviewLayout( ViewShell& _rParentViewShell, 62 const SwRootFrm& _rLayoutRootFrm ) 63 : mnXFree ( 4*142 ), 64 mnYFree ( 4*142 ), 65 mrParentViewShell( _rParentViewShell ), 66 mrLayoutRootFrm ( _rLayoutRootFrm ) 67 { 68 _Clear(); 69 70 // OD 2004-03-05 #i18143# 71 mbBookPreview = false; 72 mbBookPreviewModeToggled = false; 73 74 mbPrintEmptyPages = mrParentViewShell.getIDocumentDeviceAccess()->getPrintData().IsPrintEmptyPages(); 75 } 76 77 void SwPagePreviewLayout::_Clear() 78 { 79 mbLayoutInfoValid = mbLayoutSizesValid = mbPaintInfoValid = false; 80 81 maWinSize.Width() = 0; 82 maWinSize.Height() = 0; 83 mnCols = mnRows = 0; 84 85 _ClearPrevwLayoutSizes(); 86 87 mbDoesLayoutRowsFitIntoWindow = false; 88 mbDoesLayoutColsFitIntoWindow = false; 89 90 mnPaintPhyStartPageNum = 0; 91 mnPaintStartCol = mnPaintStartRow = 0; 92 mbNoPageVisible = false; 93 maPaintStartPageOffset.X() = 0; 94 maPaintStartPageOffset.Y() = 0; 95 maPaintPreviewDocOffset.X() = 0; 96 maPaintPreviewDocOffset.Y() = 0; 97 maAdditionalPaintOffset.X() = 0; 98 maAdditionalPaintOffset.Y() = 0; 99 maPaintedPrevwDocRect.Left() = 0; 100 maPaintedPrevwDocRect.Top() = 0; 101 maPaintedPrevwDocRect.Right() = 0; 102 maPaintedPrevwDocRect.Bottom() = 0; 103 mnSelectedPageNum = 0; 104 _ClearPrevwPageData(); 105 106 // OD 07.11.2003 #i22014# 107 mbInPaint = false; 108 mbNewLayoutDuringPaint = false; 109 } 110 111 void SwPagePreviewLayout::_ClearPrevwLayoutSizes() 112 { 113 mnPages = 0; 114 115 maMaxPageSize.Width() = 0; 116 maMaxPageSize.Height() = 0; 117 maPreviewDocRect.Left() = maPreviewDocRect.Top() = 0; 118 maPreviewDocRect.Right() = maPreviewDocRect.Bottom() = 0; 119 mnColWidth = mnRowHeight = 0; 120 mnPrevwLayoutWidth = mnPrevwLayoutHeight = 0; 121 } 122 123 void SwPagePreviewLayout::_ClearPrevwPageData() 124 { 125 for ( std::vector<PrevwPage*>::iterator aPageDelIter = maPrevwPages.begin(); 126 aPageDelIter != maPrevwPages.end(); 127 ++aPageDelIter ) 128 { 129 delete (*aPageDelIter); 130 } 131 maPrevwPages.clear(); 132 } 133 134 /** calculate page preview layout sizes 135 136 OD 18.12.2002 #103492# 137 138 @author OD 139 */ 140 void SwPagePreviewLayout::_CalcPrevwLayoutSizes() 141 { 142 // calculate maximal page size; calculate also number of pages 143 144 const SwPageFrm* pPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 145 while ( pPage ) 146 { 147 if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() ) 148 { 149 pPage = static_cast<const SwPageFrm*>(pPage->GetNext()); 150 continue; 151 } 152 153 ++mnPages; 154 pPage->Calc(); 155 const Size& rPageSize = pPage->Frm().SSize(); 156 if ( rPageSize.Width() > maMaxPageSize.Width() ) 157 maMaxPageSize.Width() = rPageSize.Width(); 158 if ( rPageSize.Height() > maMaxPageSize.Height() ) 159 maMaxPageSize.Height() = rPageSize.Height(); 160 pPage = static_cast<const SwPageFrm*>(pPage->GetNext()); 161 } 162 // calculate and set column width and row height 163 mnColWidth = maMaxPageSize.Width() + mnXFree; 164 mnRowHeight = maMaxPageSize.Height() + mnYFree; 165 166 // calculate and set preview layout width and height 167 mnPrevwLayoutWidth = mnCols * mnColWidth + mnXFree; 168 mnPrevwLayoutHeight = mnRows * mnRowHeight + mnYFree; 169 170 // calculate document rectangle in preview layout 171 { 172 Size aDocSize; 173 // document width 174 aDocSize.Width() = mnPrevwLayoutWidth; 175 176 // document height 177 // determine number of rows needed for <nPages> in preview layout 178 // OD 19.02.2003 #107369# - use method <GetRowOfPage(..)>. 179 sal_uInt16 nDocRows = GetRowOfPage( mnPages ); 180 aDocSize.Height() = nDocRows * maMaxPageSize.Height() + 181 (nDocRows+1) * mnYFree; 182 maPreviewDocRect.SetPos( Point( 0, 0 ) ); 183 maPreviewDocRect.SetSize( aDocSize ); 184 } 185 } 186 187 /** init page preview layout 188 189 OD 11.12.2002 #103492# 190 initialize the page preview settings for a given layout. 191 side effects: 192 (1) If parameter <_bCalcScale> is true, mapping mode with calculated 193 scaling is set at the output device and the zoom at the view options of 194 the given view shell is set with the calculated scaling. 195 196 @author OD 197 */ 198 bool SwPagePreviewLayout::Init( const sal_uInt16 _nCols, 199 const sal_uInt16 _nRows, 200 const Size& _rPxWinSize, 201 const bool _bCalcScale 202 ) 203 { 204 // check environment and parameters 205 { 206 bool bColsRowsValid = (_nCols != 0) && (_nRows != 0); 207 ASSERT( bColsRowsValid, "preview layout parameters not correct - preview layout can *not* be initialized" ); 208 if ( !bColsRowsValid ) 209 return false; 210 211 bool bPxWinSizeValid = (_rPxWinSize.Width() >= 0) && 212 (_rPxWinSize.Height() >= 0); 213 ASSERT( bPxWinSizeValid, "no window size - preview layout can *not* be initialized" ); 214 if ( !bPxWinSizeValid ) 215 return false; 216 } 217 218 // environment and parameters ok 219 220 // clear existing preview settings 221 _Clear(); 222 223 // set layout information columns and rows 224 mnCols = _nCols; 225 mnRows = _nRows; 226 227 _CalcPrevwLayoutSizes(); 228 229 // validate layout information 230 mbLayoutInfoValid = true; 231 232 if ( _bCalcScale ) 233 { 234 // calculate scaling 235 MapMode aMapMode( MAP_TWIP ); 236 Size aWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize, aMapMode ); 237 Fraction aXScale( aWinSize.Width(), mnPrevwLayoutWidth ); 238 Fraction aYScale( aWinSize.Height(), mnPrevwLayoutHeight ); 239 if( aXScale < aYScale ) 240 aYScale = aXScale; 241 { 242 // adjust scaling for Drawing layer. 243 aYScale *= Fraction( 1000, 1 ); 244 long nNewNuminator = aYScale.operator long(); 245 if( nNewNuminator < 1 ) 246 nNewNuminator = 1; 247 aYScale = Fraction( nNewNuminator, 1000 ); 248 // propagate scaling as zoom percentage to view options for font cache 249 _ApplyNewZoomAtViewShell( static_cast<sal_uInt8>(nNewNuminator/10) ); 250 } 251 aMapMode.SetScaleY( aYScale ); 252 aMapMode.SetScaleX( aYScale ); 253 // set created mapping mode with calculated scaling at output device. 254 mrParentViewShell.GetOut()->SetMapMode( aMapMode ); 255 // OD 20.02.2003 #107369# - update statics for paint. 256 ::SwCalcPixStatics( mrParentViewShell.GetOut() ); 257 } 258 259 // set window size in twips 260 maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize ); 261 // validate layout sizes 262 mbLayoutSizesValid = true; 263 264 return true; 265 } 266 267 /** apply new zoom at given view shell 268 269 OD 11.12.2002 #103492# - implementation of <_ApplyNewZoomAtViewShell> 270 271 @author OD 272 */ 273 void SwPagePreviewLayout::_ApplyNewZoomAtViewShell( sal_uInt8 _aNewZoom ) 274 { 275 SwViewOption aNewViewOptions = *(mrParentViewShell.GetViewOptions()); 276 if ( aNewViewOptions.GetZoom() != _aNewZoom ) 277 { 278 aNewViewOptions.SetZoom( _aNewZoom ); 279 // OD 24.09.2003 #i19975# - consider zoom type. 280 enum SvxZoomType eZoomType = SVX_ZOOM_PERCENT; 281 aNewViewOptions.SetZoomType( eZoomType ); 282 mrParentViewShell.ApplyViewOptions( aNewViewOptions ); 283 } 284 } 285 286 /** method to adjust page preview layout to document changes 287 288 OD 18.12.2002 #103492# 289 290 @author OD 291 */ 292 bool SwPagePreviewLayout::ReInit() 293 { 294 // check environment and parameters 295 { 296 bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid; 297 ASSERT( bLayoutSettingsValid, 298 "no valid preview layout info/sizes - no re-init of page preview layout"); 299 if ( !bLayoutSettingsValid ) 300 return false; 301 } 302 303 _ClearPrevwLayoutSizes(); 304 _CalcPrevwLayoutSizes(); 305 306 return true; 307 } 308 309 // ============================================================================= 310 // methods to prepare paint of page preview 311 // ============================================================================= 312 /** prepare paint of page preview 313 314 OD 12.12.2002 #103492# 315 OD 21.03.2003 #108282# - delete parameter _onStartPageVirtNum 316 317 @author OD, _nProposedStartPageNum, _onStartPageNum are absolute 318 */ 319 bool SwPagePreviewLayout::Prepare( const sal_uInt16 _nProposedStartPageNum, 320 const Point _aProposedStartPos, 321 const Size& _rPxWinSize, 322 sal_uInt16& _onStartPageNum, 323 Rectangle& _orDocPreviewPaintRect, 324 const bool _bStartWithPageAtFirstCol 325 ) 326 { 327 sal_uInt16 nProposedStartPageNum = ConvertAbsoluteToRelativePageNum( _nProposedStartPageNum ); 328 // check environment and parameters 329 { 330 bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid; 331 ASSERT( bLayoutSettingsValid, 332 "no valid preview layout info/sizes - no prepare of preview paint"); 333 if ( !bLayoutSettingsValid ) 334 return false; 335 336 bool bStartPageRangeValid = nProposedStartPageNum <= mnPages; 337 ASSERT( bStartPageRangeValid, 338 "proposed start page not existing - no prepare of preview paint"); 339 if ( !bStartPageRangeValid ) 340 return false; 341 342 bool bStartPosRangeValid = 343 _aProposedStartPos.X() >= 0 && _aProposedStartPos.Y() >= 0 && 344 _aProposedStartPos.X() <= maPreviewDocRect.Right() && 345 _aProposedStartPos.Y() <= maPreviewDocRect.Bottom(); 346 ASSERT( bStartPosRangeValid, 347 "proposed start position out of range - no prepare of preview paint"); 348 if ( !bStartPosRangeValid ) 349 return false; 350 351 bool bWinSizeValid = _rPxWinSize.Width() != 0 && _rPxWinSize.Height() != 0; 352 ASSERT ( bWinSizeValid, "no window size - no prepare of preview paint"); 353 if ( !bWinSizeValid ) 354 return false; 355 356 bool bStartInfoValid = _nProposedStartPageNum > 0 || 357 _aProposedStartPos != Point(0,0); 358 if ( !bStartInfoValid ) 359 nProposedStartPageNum = 1; 360 } 361 362 // environment and parameter ok 363 364 // update window size at preview setting data 365 maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize ); 366 367 mbNoPageVisible = false; 368 if ( nProposedStartPageNum > 0 ) 369 { 370 // determine column and row of proposed start page in virtual preview layout 371 sal_uInt16 nColOfProposed = GetColOfPage( nProposedStartPageNum ); 372 sal_uInt16 nRowOfProposed = GetRowOfPage( nProposedStartPageNum ); 373 // determine start page 374 if ( _bStartWithPageAtFirstCol ) 375 { 376 // OD 19.02.2003 #107369# - leaving left-top-corner blank is 377 // controlled by <mbBookPreview>. 378 if ( mbBookPreview && 379 ( nProposedStartPageNum == 1 || nRowOfProposed == 1 ) 380 ) 381 mnPaintPhyStartPageNum = 1; 382 else 383 mnPaintPhyStartPageNum = nProposedStartPageNum - (nColOfProposed-1); 384 } 385 else 386 mnPaintPhyStartPageNum = nProposedStartPageNum; 387 388 mnPaintPhyStartPageNum = ConvertRelativeToAbsolutePageNum( mnPaintPhyStartPageNum ); 389 390 // set starting column 391 if ( _bStartWithPageAtFirstCol ) 392 mnPaintStartCol = 1; 393 else 394 mnPaintStartCol = nColOfProposed; 395 // set starting row 396 mnPaintStartRow = nRowOfProposed; 397 // page offset == (-1,-1), indicating no offset and paint of free space. 398 maPaintStartPageOffset.X() = -1; 399 maPaintStartPageOffset.Y() = -1; 400 // virtual preview document offset. 401 if ( _bStartWithPageAtFirstCol ) 402 maPaintPreviewDocOffset.X() = 0; 403 else 404 maPaintPreviewDocOffset.X() = (nColOfProposed-1) * mnColWidth; 405 maPaintPreviewDocOffset.Y() = (nRowOfProposed-1) * mnRowHeight; 406 } 407 else 408 { 409 // determine column and row of proposed start position. 410 // Note: paint starts at point (0,0) 411 sal_uInt16 nColOfProposed = 412 static_cast<sal_uInt16>(_aProposedStartPos.X() / mnColWidth) + 1; 413 sal_uInt16 nRowOfProposed = 414 static_cast<sal_uInt16>(_aProposedStartPos.Y() / mnRowHeight) + 1; 415 // determine start page == page at proposed start position 416 // OD 19.02.2003 #107369# - leaving left-top-corner blank is 417 // controlled by <mbBookPreview>. 418 if ( mbBookPreview && 419 ( nRowOfProposed == 1 && nColOfProposed == 1 ) 420 ) 421 mnPaintPhyStartPageNum = 1; 422 else 423 { 424 // OD 19.02.2003 #107369# - leaving left-top-corner blank is 425 // controlled by <mbBookPreview>. 426 mnPaintPhyStartPageNum = (nRowOfProposed-1) * mnCols + nColOfProposed; 427 if ( mbBookPreview ) 428 --mnPaintPhyStartPageNum; 429 if ( mnPaintPhyStartPageNum > mnPages ) 430 { 431 // no page will be visible, because shown part of document 432 // preview is the last row to the right of the last page 433 mnPaintPhyStartPageNum = mnPages; 434 mbNoPageVisible = true; 435 } 436 } 437 // set starting column and starting row 438 mnPaintStartCol = nColOfProposed; 439 mnPaintStartRow = nRowOfProposed; 440 // page offset 441 maPaintStartPageOffset.X() = 442 (_aProposedStartPos.X() % mnColWidth) - mnXFree; 443 maPaintStartPageOffset.Y() = 444 (_aProposedStartPos.Y() % mnRowHeight) - mnYFree; 445 // virtual preview document offset. 446 maPaintPreviewDocOffset = _aProposedStartPos; 447 } 448 449 // determine additional paint offset, if preview layout fits into window. 450 _CalcAdditionalPaintOffset(); 451 452 // determine rectangle to be painted from document preview 453 _CalcDocPrevwPaintRect(); 454 _orDocPreviewPaintRect = maPaintedPrevwDocRect; 455 456 // OD 20.01.2003 #103492# - shift visible preview document area to the left, 457 // if on the right is an area left blank. 458 if ( !mbDoesLayoutColsFitIntoWindow && 459 maPaintedPrevwDocRect.GetWidth() < maWinSize.Width() ) 460 { 461 maPaintedPrevwDocRect.Move( 462 -(maWinSize.Width() - maPaintedPrevwDocRect.GetWidth()), 0 ); 463 Prepare( 0, maPaintedPrevwDocRect.TopLeft(), 464 _rPxWinSize, _onStartPageNum, 465 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol ); 466 } 467 468 // OD 20.01.2003 #103492# - shift visible preview document area to the top, 469 // if on the botton is an area left blank. 470 if ( mbBookPreviewModeToggled && 471 maPaintedPrevwDocRect.Bottom() == maPreviewDocRect.Bottom() && 472 maPaintedPrevwDocRect.GetHeight() < maWinSize.Height() ) 473 { 474 if ( mbDoesLayoutRowsFitIntoWindow ) 475 { 476 if ( maPaintedPrevwDocRect.GetHeight() < mnPrevwLayoutHeight) 477 { 478 maPaintedPrevwDocRect.Move( 479 0, -(mnPrevwLayoutHeight - maPaintedPrevwDocRect.GetHeight()) ); 480 Prepare( 0, maPaintedPrevwDocRect.TopLeft(), 481 _rPxWinSize, _onStartPageNum, 482 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol ); 483 } 484 } 485 else 486 { 487 maPaintedPrevwDocRect.Move( 488 0, -(maWinSize.Height() - maPaintedPrevwDocRect.GetHeight()) ); 489 Prepare( 0, maPaintedPrevwDocRect.TopLeft(), 490 _rPxWinSize, _onStartPageNum, 491 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol ); 492 } 493 } 494 495 // determine preview pages - visible pages with needed data for paint and 496 // accessible pages with needed data. 497 _CalcPreviewPages(); 498 499 // OD 07.11.2003 #i22014# - indicate new layout, if print preview is in paint 500 if ( mbInPaint ) 501 { 502 mbNewLayoutDuringPaint = true; 503 } 504 505 // validate paint data 506 mbPaintInfoValid = true; 507 508 // return start page 509 _onStartPageNum = mnPaintPhyStartPageNum; 510 511 return true; 512 } 513 514 /** calculate additional paint offset 515 516 OD 12.12.2002 #103492# 517 518 @author OD 519 */ 520 void SwPagePreviewLayout::_CalcAdditionalPaintOffset() 521 { 522 if ( mnPrevwLayoutWidth <= maWinSize.Width() && 523 maPaintStartPageOffset.X() <= 0 ) 524 { 525 mbDoesLayoutColsFitIntoWindow = true; 526 maAdditionalPaintOffset.X() = (maWinSize.Width() - mnPrevwLayoutWidth) / 2; 527 } 528 else 529 { 530 mbDoesLayoutColsFitIntoWindow = false; 531 maAdditionalPaintOffset.X() = 0; 532 } 533 534 if ( mnPrevwLayoutHeight <= maWinSize.Height() && 535 maPaintStartPageOffset.Y() <= 0 ) 536 { 537 mbDoesLayoutRowsFitIntoWindow = true; 538 maAdditionalPaintOffset.Y() = (maWinSize.Height() - mnPrevwLayoutHeight) / 2; 539 } 540 else 541 { 542 mbDoesLayoutRowsFitIntoWindow = false; 543 maAdditionalPaintOffset.Y() = 0; 544 } 545 } 546 547 /** calculate painted preview document rectangle 548 549 OD 12.12.2002 #103492# 550 551 @author OD 552 */ 553 void SwPagePreviewLayout::_CalcDocPrevwPaintRect() 554 { 555 Point aTopLeftPos = maPaintPreviewDocOffset; 556 maPaintedPrevwDocRect.SetPos( aTopLeftPos ); 557 558 Size aSize; 559 if ( mbDoesLayoutColsFitIntoWindow ) 560 //aSize.Width() = mnPrevwLayoutWidth; 561 aSize.Width() = Min( mnPrevwLayoutWidth, 562 maPreviewDocRect.GetWidth() - aTopLeftPos.X() ); 563 else 564 aSize.Width() = Min( maPreviewDocRect.GetWidth() - aTopLeftPos.X(), 565 maWinSize.Width() - maAdditionalPaintOffset.X() ); 566 if ( mbDoesLayoutRowsFitIntoWindow ) 567 //aSize.Height() = mnPrevwLayoutHeight; 568 aSize.Height() = Min( mnPrevwLayoutHeight, 569 maPreviewDocRect.GetHeight() - aTopLeftPos.Y() ); 570 else 571 aSize.Height() = Min( maPreviewDocRect.GetHeight() - aTopLeftPos.Y(), 572 maWinSize.Height() - maAdditionalPaintOffset.Y() ); 573 maPaintedPrevwDocRect.SetSize( aSize ); 574 } 575 576 /** calculate preview pages 577 578 OD 12.12.2002 #103492# 579 580 @author OD 581 */ 582 void SwPagePreviewLayout::_CalcPreviewPages() 583 { 584 _ClearPrevwPageData(); 585 586 if ( mbNoPageVisible ) 587 return; 588 589 // determine start page frame 590 const SwPageFrm* pStartPage = mrLayoutRootFrm.GetPageByPageNum( mnPaintPhyStartPageNum ); 591 592 // calculate initial paint offset 593 Point aInitialPaintOffset; 594 if ( maPaintStartPageOffset != Point( -1, -1 ) ) 595 aInitialPaintOffset = Point(0,0) - maPaintStartPageOffset; 596 else 597 aInitialPaintOffset = Point( mnXFree, mnYFree ); 598 aInitialPaintOffset += maAdditionalPaintOffset; 599 600 // prepare loop data 601 const SwPageFrm* pPage = pStartPage; 602 sal_uInt16 nCurrCol = mnPaintStartCol; 603 sal_uInt16 nConsideredRows = 0; 604 Point aCurrPaintOffset = aInitialPaintOffset; 605 // loop on pages to determine preview background retangles 606 while ( pPage && 607 (!mbDoesLayoutRowsFitIntoWindow || nConsideredRows < mnRows) && 608 aCurrPaintOffset.Y() < maWinSize.Height() 609 ) 610 { 611 if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() ) 612 { 613 pPage = static_cast<const SwPageFrm*>(pPage->GetNext()); 614 continue; 615 } 616 617 pPage->Calc(); 618 619 // consider only pages, which have to be painted. 620 if ( nCurrCol < mnPaintStartCol ) 621 { 622 // calculate data of unvisible page needed for accessibility 623 PrevwPage* pPrevwPage = new PrevwPage; 624 Point aCurrAccOffset = aCurrPaintOffset - 625 Point( (mnPaintStartCol-nCurrCol) * mnColWidth, 0 ); 626 _CalcPreviewDataForPage( *(pPage), aCurrAccOffset, pPrevwPage ); 627 pPrevwPage->bVisible = false; 628 maPrevwPages.push_back( pPrevwPage ); 629 // continue with next page and next column 630 pPage = static_cast<const SwPageFrm*>(pPage->GetNext()); 631 ++nCurrCol; 632 continue; 633 } 634 if ( aCurrPaintOffset.X() < maWinSize.Width() ) 635 { 636 // OD 19.02.2003 #107369# - leaving left-top-corner blank is 637 // controlled by <mbBookPreview>. 638 if ( mbBookPreview && pPage->GetPhyPageNum() == 1 && mnCols != 1 && nCurrCol == 1 639 ) 640 { 641 // first page in 2nd column 642 // --> continue with increased paint offset and next column 643 aCurrPaintOffset.X() += mnColWidth; 644 ++nCurrCol; 645 continue; 646 } 647 648 // calculate data of visible page 649 PrevwPage* pPrevwPage = new PrevwPage; 650 _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPrevwPage ); 651 pPrevwPage->bVisible = true; 652 maPrevwPages.push_back( pPrevwPage ); 653 } 654 else 655 { 656 // calculate data of unvisible page needed for accessibility 657 PrevwPage* pPrevwPage = new PrevwPage; 658 _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPrevwPage ); 659 pPrevwPage->bVisible = false; 660 maPrevwPages.push_back( pPrevwPage ); 661 } 662 663 // prepare data for next loop 664 pPage = static_cast<const SwPageFrm*>(pPage->GetNext()); 665 666 aCurrPaintOffset.X() += mnColWidth; 667 ++nCurrCol; 668 if ( nCurrCol > mnCols ) 669 { 670 ++nConsideredRows; 671 aCurrPaintOffset.X() = aInitialPaintOffset.X(); 672 nCurrCol = 1; 673 aCurrPaintOffset.Y() += mnRowHeight; 674 } 675 } 676 } 677 678 /** determines preview data for a given page and a given preview offset 679 680 OD 13.12.2002 #103492# 681 682 @author OD 683 */ 684 bool SwPagePreviewLayout::_CalcPreviewDataForPage( const SwPageFrm& _rPage, 685 const Point& _rPrevwOffset, 686 PrevwPage* _opPrevwPage ) 687 { 688 // page frame 689 _opPrevwPage->pPage = &_rPage; 690 // size of page frame 691 if ( _rPage.IsEmptyPage() ) 692 { 693 if ( _rPage.GetPhyPageNum() % 2 == 0 ) 694 _opPrevwPage->aPageSize = _rPage.GetPrev()->Frm().SSize(); 695 else 696 _opPrevwPage->aPageSize = _rPage.GetNext()->Frm().SSize(); 697 } 698 else 699 _opPrevwPage->aPageSize = _rPage.Frm().SSize(); 700 // position of page in preview window 701 Point aPrevwWinOffset( _rPrevwOffset ); 702 if ( _opPrevwPage->aPageSize.Width() < maMaxPageSize.Width() ) 703 aPrevwWinOffset.X() += ( maMaxPageSize.Width() - _opPrevwPage->aPageSize.Width() ) / 2; 704 if ( _opPrevwPage->aPageSize.Height() < maMaxPageSize.Height() ) 705 aPrevwWinOffset.Y() += ( maMaxPageSize.Height() - _opPrevwPage->aPageSize.Height() ) / 2; 706 _opPrevwPage->aPrevwWinPos = aPrevwWinOffset; 707 // logic position of page and mapping offset for paint 708 if ( _rPage.IsEmptyPage() ) 709 { 710 _opPrevwPage->aLogicPos = _opPrevwPage->aPrevwWinPos; 711 _opPrevwPage->aMapOffset = Point( 0, 0 ); 712 } 713 else 714 { 715 _opPrevwPage->aLogicPos = _rPage.Frm().Pos(); 716 _opPrevwPage->aMapOffset = _opPrevwPage->aPrevwWinPos - _opPrevwPage->aLogicPos; 717 } 718 719 return true; 720 } 721 722 /** enable/disable book preview 723 724 OD 2004-03-04 #i18143# 725 726 @author OD 727 */ 728 bool SwPagePreviewLayout::SetBookPreviewMode( const bool _bEnableBookPreview, 729 sal_uInt16& _onStartPageNum, 730 Rectangle& _orDocPreviewPaintRect ) 731 { 732 bool bRet = false; 733 734 if ( mbBookPreview != _bEnableBookPreview) 735 { 736 mbBookPreview = _bEnableBookPreview; 737 // re-initialize page preview layout 738 ReInit(); 739 // re-prepare page preview layout 740 { 741 mbBookPreviewModeToggled = true; 742 Point aProposedStartPos( maPaintPreviewDocOffset ); 743 // if proposed start position is below virtual preview document 744 // bottom, adjust it to the virtual preview document bottom 745 if ( aProposedStartPos.Y() > maPreviewDocRect.Bottom() ) 746 { 747 aProposedStartPos.Y() = maPreviewDocRect.Bottom(); 748 } 749 Prepare( 0, aProposedStartPos, 750 mrParentViewShell.GetOut()->LogicToPixel( maWinSize ), 751 _onStartPageNum, _orDocPreviewPaintRect ); 752 mbBookPreviewModeToggled = false; 753 } 754 755 bRet = true; 756 } 757 758 return bRet; 759 } 760 761 // ============================================================================= 762 // methods to determine new data for changing the current shown part of the 763 // document preview. 764 // ============================================================================= 765 /** calculate start position for new scale 766 767 OD 12.12.2002 #103492# 768 769 @author OD 770 */ 771 Point SwPagePreviewLayout::GetPreviewStartPosForNewScale( 772 const Fraction& _aNewScale, 773 const Fraction& _aOldScale, 774 const Size& _aNewWinSize ) const 775 { 776 Point aNewPaintStartPos = maPaintedPrevwDocRect.TopLeft(); 777 if ( _aNewScale < _aOldScale ) 778 { 779 // increase paint width by moving start point to left. 780 if ( mnPrevwLayoutWidth < _aNewWinSize.Width() ) 781 aNewPaintStartPos.X() = 0; 782 else if ( maPaintedPrevwDocRect.GetWidth() < _aNewWinSize.Width() ) 783 { 784 aNewPaintStartPos.X() -= 785 (_aNewWinSize.Width() - maPaintedPrevwDocRect.GetWidth()) / 2; 786 if ( aNewPaintStartPos.X() < 0) 787 aNewPaintStartPos.X() = 0; 788 } 789 790 if ( !mbDoesLayoutRowsFitIntoWindow ) 791 { 792 // increase paint height by moving start point to top. 793 if ( mnPrevwLayoutHeight < _aNewWinSize.Height() ) 794 { 795 aNewPaintStartPos.Y() = 796 ( (mnPaintStartRow - 1) * mnRowHeight ); 797 } 798 else if ( maPaintedPrevwDocRect.GetHeight() < _aNewWinSize.Height() ) 799 { 800 aNewPaintStartPos.Y() -= 801 (_aNewWinSize.Height() - maPaintedPrevwDocRect.GetHeight()) / 2; 802 if ( aNewPaintStartPos.Y() < 0) 803 aNewPaintStartPos.Y() = 0; 804 } 805 } 806 } 807 else 808 { 809 // decrease paint width by moving start point to right 810 if ( maPaintedPrevwDocRect.GetWidth() > _aNewWinSize.Width() ) 811 aNewPaintStartPos.X() += 812 (maPaintedPrevwDocRect.GetWidth() - _aNewWinSize.Width()) / 2; 813 // decrease paint height by moving start point to bottom 814 if ( maPaintedPrevwDocRect.GetHeight() > _aNewWinSize.Height() ) 815 { 816 aNewPaintStartPos.Y() += 817 (maPaintedPrevwDocRect.GetHeight() - _aNewWinSize.Height()) / 2; 818 // check, if new y-position is outside document preview 819 if ( aNewPaintStartPos.Y() > maPreviewDocRect.Bottom() ) 820 aNewPaintStartPos.Y() = 821 Max( 0L, maPreviewDocRect.Bottom() - mnPrevwLayoutHeight ); 822 } 823 } 824 825 return aNewPaintStartPos; 826 } 827 828 /** determines, if page with given page number is visible in preview 829 830 OD 12.12.2002 #103492# 831 832 @author OD, _nPageNum is absolut! 833 */ 834 bool SwPagePreviewLayout::IsPageVisible( const sal_uInt16 _nPageNum ) const 835 { 836 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 837 return pPrevwPage && pPrevwPage->bVisible; 838 } 839 840 /** calculate data to bring new selected page into view. 841 842 OD 12.12.2002 #103492# 843 844 @author OD, IN/OUT parameters are absolute page numbers!!! 845 */ 846 bool SwPagePreviewLayout::CalcStartValuesForSelectedPageMove( 847 const sal_Int16 _nHoriMove, 848 const sal_Int16 _nVertMove, 849 sal_uInt16& _orNewSelectedPage, 850 sal_uInt16& _orNewStartPage, 851 Point& _orNewStartPos ) const 852 { 853 // determine position of current selected page 854 sal_uInt16 nTmpRelSelPageNum = ConvertAbsoluteToRelativePageNum( mnSelectedPageNum ); 855 sal_uInt16 nNewRelSelectedPageNum = nTmpRelSelPageNum; 856 857 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 858 // by <mbBookPreview>. 859 if ( mbBookPreview ) 860 { 861 // Note: consider that left-top-corner is left blank --> +1 862 ++nTmpRelSelPageNum; 863 } 864 sal_uInt16 nTmpCol = nTmpRelSelPageNum % mnCols; 865 sal_uInt16 nCurrRow = nTmpRelSelPageNum / mnCols; 866 if ( nTmpCol > 0 ) 867 ++nCurrRow; 868 869 // determine new selected page number 870 { 871 if ( _nHoriMove != 0 ) 872 { 873 if ( (nNewRelSelectedPageNum + _nHoriMove) < 1 ) 874 nNewRelSelectedPageNum = 1; 875 else if ( (nNewRelSelectedPageNum + _nHoriMove) > mnPages ) 876 nNewRelSelectedPageNum = mnPages; 877 else 878 nNewRelSelectedPageNum = nNewRelSelectedPageNum + _nHoriMove; 879 } 880 if ( _nVertMove != 0 ) 881 { 882 if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) < 1 ) 883 nNewRelSelectedPageNum = 1; 884 else if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) > mnPages ) 885 nNewRelSelectedPageNum = mnPages; 886 else 887 nNewRelSelectedPageNum += ( _nVertMove * mnCols ); 888 } 889 } 890 891 sal_uInt16 nNewStartPage = mnPaintPhyStartPageNum; 892 Point aNewStartPos = Point(0,0); 893 894 sal_uInt16 nNewAbsSelectedPageNum = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum ); 895 if ( !IsPageVisible( nNewAbsSelectedPageNum ) ) 896 { 897 if ( _nHoriMove != 0 && _nVertMove != 0 ) 898 { 899 ASSERT( false, "missing implementation for moving preview selected page horizontal AND vertical"); 900 return false; 901 } 902 903 // new selected page has to be brought into view considering current 904 // visible preview. 905 sal_Int16 nTotalRows = GetRowOfPage( mnPages ); 906 if ( (_nHoriMove > 0 || _nVertMove > 0) && 907 mbDoesLayoutRowsFitIntoWindow && 908 mbDoesLayoutColsFitIntoWindow && // OD 20.02.2003 #107369# - add condition 909 nCurrRow > nTotalRows - mnRows ) 910 { 911 // new proposed start page = left-top-corner of last possible 912 // preview page. 913 nNewStartPage = (nTotalRows - mnRows) * mnCols + 1; 914 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 915 // by <mbBookPreview>. 916 if ( mbBookPreview ) 917 { 918 // Note: decrease new proposed start page number by one, 919 // because of blank left-top-corner 920 --nNewStartPage; 921 } 922 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewStartPage ); 923 } 924 else 925 { 926 // new proposed start page = new selected page. 927 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum ); 928 } 929 } 930 931 _orNewSelectedPage = nNewAbsSelectedPageNum; 932 _orNewStartPage = nNewStartPage; 933 _orNewStartPos = aNewStartPos; 934 935 return true; 936 } 937 938 /** checks, if given position is inside a shown document page 939 940 OD 17.12.2002 #103492# 941 942 @author OD 943 */ 944 struct PrevwPosInsidePagePred 945 { 946 const Point mnPrevwPos; 947 PrevwPosInsidePagePred( const Point _nPrevwPos ) : mnPrevwPos( _nPrevwPos ) {}; 948 bool operator() ( const PrevwPage* _pPrevwPage ) 949 { 950 if ( _pPrevwPage->bVisible ) 951 { 952 Rectangle aPrevwPageRect( _pPrevwPage->aPrevwWinPos, _pPrevwPage->aPageSize ); 953 return aPrevwPageRect.IsInside( mnPrevwPos ) ? true : false; 954 } 955 else 956 return false; 957 } 958 }; 959 960 bool SwPagePreviewLayout::IsPrevwPosInDocPrevwPage( const Point _aPrevwPos, 961 Point& _orDocPos, 962 bool& _obPosInEmptyPage, 963 sal_uInt16& _onPageNum ) const 964 { 965 bool bIsPosInsideDoc; 966 967 // initialize variable parameter values. 968 _orDocPos.X() = 0; 969 _orDocPos.Y() = 0; 970 _obPosInEmptyPage = false; 971 _onPageNum = 0; 972 973 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter = 974 std::find_if( maPrevwPages.begin(), maPrevwPages.end(), 975 PrevwPosInsidePagePred( _aPrevwPos ) ); 976 977 if ( aFoundPrevwPageIter == maPrevwPages.end() ) 978 // given preview position outside a document page. 979 bIsPosInsideDoc = false; 980 else 981 { 982 _onPageNum = (*aFoundPrevwPageIter)->pPage->GetPhyPageNum(); 983 if ( (*aFoundPrevwPageIter)->pPage->IsEmptyPage() ) 984 { 985 // given preview position inside an empty page 986 bIsPosInsideDoc = false; 987 _obPosInEmptyPage = true; 988 } 989 else 990 { 991 // given preview position inside a normal page 992 bIsPosInsideDoc = true; 993 _orDocPos = _aPrevwPos - 994 (*aFoundPrevwPageIter)->aPrevwWinPos + 995 (*aFoundPrevwPageIter)->aLogicPos; 996 } 997 } 998 999 return bIsPosInsideDoc; 1000 } 1001 1002 /** determine window page scroll amount 1003 1004 OD 17.12.2002 #103492# 1005 1006 @author OD 1007 */ 1008 SwTwips SwPagePreviewLayout::GetWinPagesScrollAmount( 1009 const sal_Int16 _nWinPagesToScroll ) const 1010 { 1011 SwTwips nScrollAmount; 1012 if ( mbDoesLayoutRowsFitIntoWindow ) 1013 { 1014 nScrollAmount = (mnPrevwLayoutHeight - mnYFree) * _nWinPagesToScroll; 1015 } 1016 else 1017 nScrollAmount = _nWinPagesToScroll * maPaintedPrevwDocRect.GetHeight(); 1018 1019 // OD 19.02.2003 #107369# - check, if preview layout size values are valid. 1020 // If not, the checks for an adjustment of the scroll amount aren't useful. 1021 if ( mbLayoutSizesValid ) 1022 { 1023 if ( (maPaintedPrevwDocRect.Top() + nScrollAmount) <= 0 ) 1024 nScrollAmount = -maPaintedPrevwDocRect.Top(); 1025 1026 // OD 14.02.2003 #107369# - correct scroll amount 1027 if ( nScrollAmount > 0 && 1028 maPaintedPrevwDocRect.Bottom() == maPreviewDocRect.Bottom() 1029 ) 1030 { 1031 nScrollAmount = 0; 1032 } 1033 else 1034 { 1035 while ( (maPaintedPrevwDocRect.Top() + nScrollAmount + mnYFree) >= maPreviewDocRect.GetHeight() ) 1036 { 1037 nScrollAmount -= mnRowHeight; 1038 } 1039 } 1040 } 1041 1042 return nScrollAmount; 1043 } 1044 1045 // ============================================================================= 1046 // methods to paint page preview layout 1047 // ============================================================================= 1048 /** paint prepared preview 1049 1050 OD 12.12.2002 #103492# 1051 1052 @author OD 1053 */ 1054 bool SwPagePreviewLayout::Paint( const Rectangle _aOutRect ) const 1055 { 1056 // check environment and parameters 1057 { 1058 if ( !mrParentViewShell.GetWin() && 1059 !mrParentViewShell.GetOut()->GetConnectMetaFile() ) 1060 return false; 1061 1062 ASSERT( mbPaintInfoValid, 1063 "invalid preview settings - no paint of preview" ); 1064 if ( !mbPaintInfoValid ) 1065 return false; 1066 } 1067 1068 // OD 17.11.2003 #i22014# - no paint, if <superfluous> flag is set at layout 1069 if ( mrLayoutRootFrm.IsSuperfluous() ) 1070 { 1071 return true; 1072 } 1073 1074 // environment and parameter ok 1075 1076 // OD 07.11.2003 #i22014# 1077 if ( mbInPaint ) 1078 { 1079 return false; 1080 } 1081 mbInPaint = true; 1082 1083 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1084 1085 // prepare paint 1086 if ( maPrevwPages.size() > 0 ) 1087 { 1088 mrParentViewShell.Imp()->bFirstPageInvalid = sal_False; 1089 mrParentViewShell.Imp()->pFirstVisPage = 1090 const_cast<SwPageFrm*>(maPrevwPages[0]->pPage); 1091 } 1092 1093 // paint preview background 1094 { 1095 SwRegionRects aPreviewBackgrdRegion( _aOutRect ); 1096 // calculate preview background rectangles 1097 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1098 aPageIter != maPrevwPages.end(); 1099 ++aPageIter ) 1100 { 1101 if ( (*aPageIter)->bVisible ) 1102 { 1103 aPreviewBackgrdRegion -= 1104 SwRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize ); 1105 } 1106 } 1107 // paint preview background rectangles 1108 mrParentViewShell._PaintDesktop( aPreviewBackgrdRegion ); 1109 } 1110 1111 // prepare data for paint of pages 1112 const Rectangle aPxOutRect( pOutputDev->LogicToPixel( _aOutRect ) ); 1113 1114 MapMode aMapMode( pOutputDev->GetMapMode() ); 1115 MapMode aSavedMapMode = aMapMode; 1116 1117 const Font& rEmptyPgFont = SwPageFrm::GetEmptyPageFont(); 1118 1119 Color aEmptyPgShadowBorderColor = SwViewOption::GetFontColor(); 1120 1121 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1122 aPageIter != maPrevwPages.end(); 1123 ++aPageIter ) 1124 { 1125 if ( !(*aPageIter)->bVisible ) 1126 continue; 1127 1128 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); 1129 aMapMode.SetOrigin( (*aPageIter)->aMapOffset ); 1130 pOutputDev->SetMapMode( aMapMode ); 1131 Rectangle aPxPaintRect = pOutputDev->LogicToPixel( aPageRect ); 1132 if ( aPxOutRect.IsOver( aPxPaintRect) ) 1133 { 1134 if ( (*aPageIter)->pPage->IsEmptyPage() ) 1135 { 1136 const Color aRetouche( mrParentViewShell.Imp()->GetRetoucheColor() ); 1137 if( pOutputDev->GetFillColor() != aRetouche ) 1138 pOutputDev->SetFillColor( aRetouche ); 1139 pOutputDev->SetLineColor(); // OD 20.02.2003 #107369# - no line color 1140 // OD 20.02.2003 #107369# - use aligned page rectangle 1141 { 1142 SwRect aTmpPageRect( aPageRect ); 1143 ::SwAlignRect( aTmpPageRect, &mrParentViewShell); 1144 aPageRect = aTmpPageRect.SVRect(); 1145 } 1146 pOutputDev->DrawRect( aPageRect ); 1147 1148 // paint empty page text 1149 Font aOldFont( pOutputDev->GetFont() ); 1150 pOutputDev->SetFont( rEmptyPgFont ); 1151 pOutputDev->DrawText( aPageRect, SW_RESSTR( STR_EMPTYPAGE ), 1152 TEXT_DRAW_VCENTER | 1153 TEXT_DRAW_CENTER | 1154 TEXT_DRAW_CLIP ); 1155 pOutputDev->SetFont( aOldFont ); 1156 // paint shadow and border for empty page 1157 // OD 19.02.2003 #107369# - use new method to paint page border and 1158 // shadow 1159 SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, true ); 1160 } 1161 else 1162 { 1163 mrParentViewShell.aVisArea = aPageRect; 1164 aPxPaintRect.Intersection( aPxOutRect ); 1165 Rectangle aPaintRect = pOutputDev->PixelToLogic( aPxPaintRect ); 1166 mrParentViewShell.Paint( aPaintRect ); 1167 // --> OD 2007-08-15 #i80691# 1168 // paint page border and shadow 1169 { 1170 SwRect aPageBorderRect; 1171 SwPageFrm::GetBorderAndShadowBoundRect( SwRect( aPageRect ), &mrParentViewShell, aPageBorderRect, true ); 1172 const Region aDLRegion(aPageBorderRect.SVRect()); 1173 mrParentViewShell.DLPrePaint2(aDLRegion); 1174 SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, true ); 1175 mrParentViewShell.DLPostPaint2(true); 1176 } 1177 // <-- 1178 } 1179 // OD 07.11.2003 #i22014# - stop painting, because new print 1180 // preview layout is created during paint. 1181 if ( mbNewLayoutDuringPaint ) 1182 { 1183 break; 1184 } 1185 1186 if ( (*aPageIter)->pPage->GetPhyPageNum() == mnSelectedPageNum ) 1187 { 1188 _PaintSelectMarkAtPage( (*aPageIter) ); 1189 } 1190 1191 } 1192 } 1193 1194 // OD 17.11.2003 #i22014# - no update of accessible preview, if a new 1195 // print preview layout is created during paint. 1196 if ( !mbNewLayoutDuringPaint ) 1197 { 1198 // update at accessiblilty interface 1199 mrParentViewShell.Imp()->UpdateAccessiblePreview( 1200 maPrevwPages, 1201 aMapMode.GetScaleX(), 1202 mrLayoutRootFrm.GetPageByPageNum( mnSelectedPageNum ), 1203 maWinSize ); 1204 } 1205 1206 pOutputDev->SetMapMode( aSavedMapMode ); 1207 mrParentViewShell.aVisArea.Clear(); 1208 1209 // OD 07.11.2003 #i22014# 1210 mbInPaint = false; 1211 mbNewLayoutDuringPaint = false; 1212 1213 return true; 1214 } 1215 1216 /** repaint pages on page preview 1217 1218 OD 18.12.2002 #103492# 1219 1220 @author OD 1221 */ 1222 void SwPagePreviewLayout::Repaint( const Rectangle _aInvalidCoreRect ) const 1223 { 1224 // check environment and parameters 1225 { 1226 if ( !mrParentViewShell.GetWin() && 1227 !mrParentViewShell.GetOut()->GetConnectMetaFile() ) 1228 return; 1229 1230 ASSERT( mbPaintInfoValid, 1231 "invalid preview settings - no paint of preview" ); 1232 if ( !mbPaintInfoValid ) 1233 return; 1234 } 1235 1236 // environment and parameter ok 1237 1238 // prepare paint 1239 if ( maPrevwPages.size() > 0 ) 1240 { 1241 mrParentViewShell.Imp()->bFirstPageInvalid = sal_False; 1242 mrParentViewShell.Imp()->pFirstVisPage = 1243 const_cast<SwPageFrm*>(maPrevwPages[0]->pPage); 1244 } 1245 1246 // invalidate visible pages, which overlap the invalid core rectangle 1247 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1248 aPageIter != maPrevwPages.end(); 1249 ++aPageIter ) 1250 { 1251 if ( !(*aPageIter)->bVisible ) 1252 continue; 1253 1254 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); 1255 if ( _aInvalidCoreRect.IsOver( aPageRect ) ) 1256 { 1257 aPageRect.Intersection( _aInvalidCoreRect ); 1258 Rectangle aInvalidPrevwRect = aPageRect; 1259 aInvalidPrevwRect.SetPos( aInvalidPrevwRect.TopLeft() - 1260 (*aPageIter)->aLogicPos + 1261 (*aPageIter)->aPrevwWinPos ); 1262 mrParentViewShell.GetWin()->Invalidate( aInvalidPrevwRect ); 1263 } 1264 } 1265 } 1266 1267 /** paint selection mark at page 1268 1269 OD 17.12.2002 #103492# 1270 1271 @author OD 1272 */ 1273 void SwPagePreviewLayout::_PaintSelectMarkAtPage( 1274 const PrevwPage* _aSelectedPrevwPage ) const 1275 { 1276 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1277 MapMode aMapMode( pOutputDev->GetMapMode() ); 1278 // save mapping mode of output device 1279 MapMode aSavedMapMode = aMapMode; 1280 // save fill and line color of output device 1281 Color aFill( pOutputDev->GetFillColor() ); 1282 Color aLine( pOutputDev->GetLineColor() ); 1283 1284 // determine selection mark color 1285 Color aSelPgLineColor(COL_LIGHTBLUE); 1286 const StyleSettings& rSettings = 1287 mrParentViewShell.GetWin()->GetSettings().GetStyleSettings(); 1288 if ( rSettings.GetHighContrastMode() ) 1289 aSelPgLineColor = rSettings.GetHighlightTextColor(); 1290 1291 // set needed mapping mode at output device 1292 aMapMode.SetOrigin( _aSelectedPrevwPage->aMapOffset ); 1293 pOutputDev->SetMapMode( aMapMode ); 1294 1295 // calculate page rectangle in pixel coordinates 1296 SwRect aPageRect( _aSelectedPrevwPage->aLogicPos, 1297 _aSelectedPrevwPage->aPageSize ); 1298 // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for 1299 // page border and shadow paint - see <SwPageFrm::PaintBorderAndShadow(..)> 1300 ::SwAlignRect( aPageRect, &mrParentViewShell); 1301 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1302 1303 // draw two rectangle 1304 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1305 Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(), 1306 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1307 aRect = pOutputDev->PixelToLogic( aRect ); 1308 pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color 1309 pOutputDev->SetLineColor( aSelPgLineColor ); 1310 pOutputDev->DrawRect( aRect ); 1311 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1312 aRect = Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1, 1313 aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 ); 1314 aRect = pOutputDev->PixelToLogic( aRect ); 1315 pOutputDev->DrawRect( aRect ); 1316 1317 // reset fill and line color of output device 1318 pOutputDev->SetFillColor( aFill ); 1319 pOutputDev->SetLineColor( aLine ); 1320 1321 // reset mapping mode of output device 1322 pOutputDev->SetMapMode( aSavedMapMode ); 1323 } 1324 1325 /** paint to mark new selected page 1326 1327 OD 17.12.2002 #103492# 1328 Perform paint for current selected page in order to unmark it. 1329 Set new selected page and perform paint to mark this page. 1330 1331 @author OD, _nSelectedPage, mnSelectedPage are absolut 1332 */ 1333 void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage ) 1334 { 1335 sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum; 1336 mnSelectedPageNum = _nSelectedPage; 1337 1338 // re-paint for current selected page in order to umark it. 1339 const PrevwPage* pOldSelectedPrevwPage = _GetPrevwPageByPageNum( nOldSelectedPageNum ); 1340 if ( pOldSelectedPrevwPage && pOldSelectedPrevwPage->bVisible ) 1341 { 1342 // OD 20.02.2003 #107369# - invalidate only areas of selection mark. 1343 SwRect aPageRect( pOldSelectedPrevwPage->aPrevwWinPos, 1344 pOldSelectedPrevwPage->aPageSize ); 1345 ::SwAlignRect( aPageRect, &mrParentViewShell); 1346 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1347 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1348 // invalidate top mark line 1349 Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(), 1350 aPxPageRect.Right(), aPxPageRect.Top()+1 ); 1351 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1352 // invalidate right mark line 1353 aInvalPxRect = Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(), 1354 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1355 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1356 // invalidate bottom mark line 1357 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1, 1358 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1359 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1360 // invalidate left mark line 1361 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Top(), 1362 aPxPageRect.Left()+1, aPxPageRect.Bottom() ); 1363 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1364 } 1365 1366 // re-paint for new selected page in order to mark it. 1367 const PrevwPage* pNewSelectedPrevwPage = _GetPrevwPageByPageNum( _nSelectedPage ); 1368 if ( pNewSelectedPrevwPage && pNewSelectedPrevwPage->bVisible ) 1369 _PaintSelectMarkAtPage( pNewSelectedPrevwPage ); 1370 } 1371 1372 1373 // ============================================================================= 1374 // helper methods 1375 // ============================================================================= 1376 /** get preview page by physical page number 1377 1378 OD 17.12.2002 #103492# 1379 1380 @author OD 1381 */ 1382 struct EqualsPageNumPred 1383 { 1384 const sal_uInt16 mnPageNum; 1385 EqualsPageNumPred( const sal_uInt16 _nPageNum ) : mnPageNum( _nPageNum ) {}; 1386 bool operator() ( const PrevwPage* _pPrevwPage ) 1387 { 1388 return _pPrevwPage->pPage->GetPhyPageNum() == mnPageNum; 1389 } 1390 }; 1391 1392 const PrevwPage* SwPagePreviewLayout::_GetPrevwPageByPageNum( const sal_uInt16 _nPageNum ) const 1393 { 1394 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter = 1395 std::find_if( maPrevwPages.begin(), maPrevwPages.end(), 1396 EqualsPageNumPred( _nPageNum ) ); 1397 1398 if ( aFoundPrevwPageIter == maPrevwPages.end() ) 1399 return 0; 1400 else 1401 return (*aFoundPrevwPageIter); 1402 } 1403 1404 /** determine row the page with the given number is in 1405 1406 OD 17.01.2003 #103492# 1407 1408 @author OD, _nPageNum is relative 1409 */ 1410 sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const 1411 { 1412 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1413 // by <mbBookPreview>. 1414 if ( mbBookPreview ) 1415 { 1416 // Note: increase given physical page number by one, because left-top-corner 1417 // in the preview layout is left blank. 1418 ++_nPageNum; 1419 } 1420 1421 sal_uInt16 nRow = (_nPageNum) / mnCols; 1422 if ( ( (_nPageNum) % mnCols ) > 0 ) 1423 ++nRow; 1424 1425 return nRow; 1426 } 1427 1428 /** determine column the page with the given number is in 1429 1430 OD 17.01.2003 #103492# 1431 1432 @author OD, _nPageNum is relative 1433 */ 1434 sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const 1435 { 1436 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1437 // by <mbBookPreview>. 1438 if ( mbBookPreview ) 1439 { 1440 // Note: increase given physical page number by one, because left-top-corner 1441 // in the preview layout is left blank. 1442 ++_nPageNum; 1443 } 1444 1445 sal_uInt16 nCol = (_nPageNum) % mnCols; 1446 if ( nCol == 0 ) 1447 nCol = mnCols; 1448 1449 return nCol; 1450 } 1451 1452 Size SwPagePreviewLayout::GetPrevwDocSize() const 1453 { 1454 ASSERT( PreviewLayoutValid(), "PagePreviewLayout not valid" ); 1455 return maPreviewDocRect.GetSize(); 1456 } 1457 1458 /** get size of a preview page by its physical page number 1459 1460 OD 15.01.2003 #103492# 1461 1462 @author OD 1463 */ 1464 Size SwPagePreviewLayout::GetPrevwPageSizeByPageNum( sal_uInt16 _nPageNum ) const 1465 { 1466 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1467 if ( pPrevwPage ) 1468 { 1469 return pPrevwPage->aPageSize; 1470 } 1471 else 1472 { 1473 return Size( 0, 0 ); 1474 } 1475 } 1476 1477 /** get virtual page number by its physical page number 1478 1479 OD 21.03.2003 #108282# 1480 1481 @author OD 1482 */ 1483 sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const 1484 { 1485 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1486 if ( pPrevwPage ) 1487 { 1488 return pPrevwPage->pPage->GetVirtPageNum(); 1489 } 1490 else 1491 { 1492 return 0; 1493 } 1494 } 1495 1496 /** Convert absolute to relative page numbers (see PrintEmptyPages) 1497 1498 @author FME 1499 */ 1500 sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const 1501 { 1502 if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum ) 1503 { 1504 return _nAbsPageNum; 1505 } 1506 1507 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1508 1509 sal_uInt16 nRet = 1; 1510 1511 while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum ) 1512 { 1513 if ( !pTmpPage->IsEmptyPage() ) 1514 ++nRet; 1515 1516 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1517 } 1518 1519 return nRet; 1520 } 1521 1522 /** Convert relative to absolute page numbers (see PrintEmptyPages) 1523 1524 @author FME 1525 */ 1526 sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const 1527 { 1528 if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum ) 1529 { 1530 return _nRelPageNum; 1531 } 1532 1533 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1534 const SwPageFrm* pRet = 0; 1535 1536 sal_uInt16 i = 0; 1537 while( pTmpPage && i != _nRelPageNum ) 1538 { 1539 if ( !pTmpPage->IsEmptyPage() ) 1540 ++i; 1541 1542 pRet = pTmpPage; 1543 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1544 } 1545 1546 return pRet->GetPhyPageNum(); 1547 } 1548