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