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 ( 3 * 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 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1116 aPageIter != maPrevwPages.end(); 1117 ++aPageIter ) 1118 { 1119 if ( !(*aPageIter)->bVisible ) 1120 continue; 1121 1122 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); 1123 aMapMode.SetOrigin( (*aPageIter)->aMapOffset ); 1124 pOutputDev->SetMapMode( aMapMode ); 1125 Rectangle aPxPaintRect = pOutputDev->LogicToPixel( aPageRect ); 1126 if ( aPxOutRect.IsOver( aPxPaintRect) ) 1127 { 1128 if ( (*aPageIter)->pPage->IsEmptyPage() ) 1129 { 1130 const Color aRetouche( mrParentViewShell.Imp()->GetRetoucheColor() ); 1131 if( pOutputDev->GetFillColor() != aRetouche ) 1132 pOutputDev->SetFillColor( aRetouche ); 1133 pOutputDev->SetLineColor(); // OD 20.02.2003 #107369# - no line color 1134 // OD 20.02.2003 #107369# - use aligned page rectangle 1135 { 1136 SwRect aTmpPageRect( aPageRect ); 1137 ::SwAlignRect( aTmpPageRect, &mrParentViewShell); 1138 aPageRect = aTmpPageRect.SVRect(); 1139 } 1140 pOutputDev->DrawRect( aPageRect ); 1141 1142 // paint empty page text 1143 Font aOldFont( pOutputDev->GetFont() ); 1144 pOutputDev->SetFont( rEmptyPgFont ); 1145 pOutputDev->DrawText( aPageRect, SW_RESSTR( STR_EMPTYPAGE ), 1146 TEXT_DRAW_VCENTER | 1147 TEXT_DRAW_CENTER | 1148 TEXT_DRAW_CLIP ); 1149 pOutputDev->SetFont( aOldFont ); 1150 // paint border for empty page (shadow removed now) 1151 // OD 19.02.2003 #107369# - use new method to paint page border 1152 SwPageFrm::PaintPageBorder( aPageRect, &mrParentViewShell, true ); 1153 } 1154 else 1155 { 1156 mrParentViewShell.aVisArea = aPageRect; 1157 aPxPaintRect.Intersection( aPxOutRect ); 1158 Rectangle aPaintRect = pOutputDev->PixelToLogic( aPxPaintRect ); 1159 mrParentViewShell.Paint( aPaintRect ); 1160 // --> OD 2007-08-15 #i80691# 1161 // paint page border (shadow removed now) 1162 { 1163 SwRect aPageBorderRect; 1164 SwPageFrm::GetBorderAndShadowBoundRect( SwRect( aPageRect ), &mrParentViewShell, aPageBorderRect, true ); 1165 const Region aDLRegion(aPageBorderRect.SVRect()); 1166 mrParentViewShell.DLPrePaint2(aDLRegion); 1167 SwPageFrm::PaintPageBorder( aPageRect, &mrParentViewShell, true ); 1168 mrParentViewShell.DLPostPaint2(true); 1169 } 1170 // <-- 1171 } 1172 // OD 07.11.2003 #i22014# - stop painting, because new print 1173 // preview layout is created during paint. 1174 if ( mbNewLayoutDuringPaint ) 1175 { 1176 break; 1177 } 1178 1179 if ( (*aPageIter)->pPage->GetPhyPageNum() == mnSelectedPageNum ) 1180 { 1181 _PaintSelectMarkAtPage( (*aPageIter) ); 1182 } 1183 1184 } 1185 } 1186 1187 // OD 17.11.2003 #i22014# - no update of accessible preview, if a new 1188 // print preview layout is created during paint. 1189 if ( !mbNewLayoutDuringPaint ) 1190 { 1191 // update at accessibility interface 1192 mrParentViewShell.Imp()->UpdateAccessiblePreview( 1193 maPrevwPages, 1194 aMapMode.GetScaleX(), 1195 mrLayoutRootFrm.GetPageByPageNum( mnSelectedPageNum ), 1196 maWinSize ); 1197 } 1198 1199 pOutputDev->SetMapMode( aSavedMapMode ); 1200 mrParentViewShell.aVisArea.Clear(); 1201 1202 // OD 07.11.2003 #i22014# 1203 mbInPaint = false; 1204 mbNewLayoutDuringPaint = false; 1205 1206 return true; 1207 } 1208 1209 /** repaint pages on page preview 1210 1211 OD 18.12.2002 #103492# 1212 1213 @author OD 1214 */ 1215 void SwPagePreviewLayout::Repaint( const Rectangle _aInvalidCoreRect ) const 1216 { 1217 // check environment and parameters 1218 { 1219 if ( !mrParentViewShell.GetWin() && 1220 !mrParentViewShell.GetOut()->GetConnectMetaFile() ) 1221 return; 1222 1223 ASSERT( mbPaintInfoValid, 1224 "invalid preview settings - no paint of preview" ); 1225 if ( !mbPaintInfoValid ) 1226 return; 1227 } 1228 1229 // environment and parameter OK 1230 1231 // prepare paint 1232 if ( maPrevwPages.size() > 0 ) 1233 { 1234 mrParentViewShell.Imp()->bFirstPageInvalid = sal_False; 1235 mrParentViewShell.Imp()->pFirstVisPage = 1236 const_cast<SwPageFrm*>(maPrevwPages[0]->pPage); 1237 } 1238 1239 // invalidate visible pages, which overlap the invalid core rectangle 1240 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1241 aPageIter != maPrevwPages.end(); 1242 ++aPageIter ) 1243 { 1244 if ( !(*aPageIter)->bVisible ) 1245 continue; 1246 1247 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); 1248 if ( _aInvalidCoreRect.IsOver( aPageRect ) ) 1249 { 1250 aPageRect.Intersection( _aInvalidCoreRect ); 1251 Rectangle aInvalidPrevwRect = aPageRect; 1252 aInvalidPrevwRect.SetPos( aInvalidPrevwRect.TopLeft() - 1253 (*aPageIter)->aLogicPos + 1254 (*aPageIter)->aPrevwWinPos ); 1255 mrParentViewShell.GetWin()->Invalidate( aInvalidPrevwRect ); 1256 } 1257 } 1258 } 1259 1260 /** paint selection mark at page 1261 1262 OD 17.12.2002 #103492# 1263 1264 @author OD 1265 */ 1266 void SwPagePreviewLayout::_PaintSelectMarkAtPage( 1267 const PrevwPage* _aSelectedPrevwPage ) const 1268 { 1269 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1270 MapMode aMapMode( pOutputDev->GetMapMode() ); 1271 // save mapping mode of output device 1272 MapMode aSavedMapMode = aMapMode; 1273 // save fill and line color of output device 1274 Color aFill( pOutputDev->GetFillColor() ); 1275 Color aLine( pOutputDev->GetLineColor() ); 1276 1277 // determine selection mark color 1278 Color aSelPgLineColor(COL_LIGHTBLUE); 1279 const StyleSettings& rSettings = 1280 mrParentViewShell.GetWin()->GetSettings().GetStyleSettings(); 1281 if ( rSettings.GetHighContrastMode() ) 1282 aSelPgLineColor = rSettings.GetHighlightTextColor(); 1283 1284 // set needed mapping mode at output device 1285 aMapMode.SetOrigin( _aSelectedPrevwPage->aMapOffset ); 1286 pOutputDev->SetMapMode( aMapMode ); 1287 1288 // calculate page rectangle in pixel coordinates 1289 SwRect aPageRect( _aSelectedPrevwPage->aLogicPos, 1290 _aSelectedPrevwPage->aPageSize ); 1291 // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for 1292 // page border paint - see <SwPageFrm::PaintPageBorder(..)> 1293 ::SwAlignRect( aPageRect, &mrParentViewShell); 1294 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1295 1296 // draw two rectangles 1297 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1298 Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(), 1299 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1300 aRect = pOutputDev->PixelToLogic( aRect ); 1301 pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color 1302 pOutputDev->SetLineColor( aSelPgLineColor ); 1303 pOutputDev->DrawRect( aRect ); 1304 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1305 aRect = Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1, 1306 aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 ); 1307 aRect = pOutputDev->PixelToLogic( aRect ); 1308 pOutputDev->DrawRect( aRect ); 1309 1310 // reset fill and line color of output device 1311 pOutputDev->SetFillColor( aFill ); 1312 pOutputDev->SetLineColor( aLine ); 1313 1314 // reset mapping mode of output device 1315 pOutputDev->SetMapMode( aSavedMapMode ); 1316 } 1317 1318 /** paint to mark new selected page 1319 1320 OD 17.12.2002 #103492# 1321 Perform paint for current selected page in order to unmark it. 1322 Set new selected page and perform paint to mark this page. 1323 1324 @author OD, _nSelectedPage, mnSelectedPage are absolute 1325 */ 1326 void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage ) 1327 { 1328 sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum; 1329 mnSelectedPageNum = _nSelectedPage; 1330 1331 // re-paint for current selected page in order to unmark it. 1332 const PrevwPage* pOldSelectedPrevwPage = _GetPrevwPageByPageNum( nOldSelectedPageNum ); 1333 if ( pOldSelectedPrevwPage && pOldSelectedPrevwPage->bVisible ) 1334 { 1335 // OD 20.02.2003 #107369# - invalidate only areas of selection mark. 1336 SwRect aPageRect( pOldSelectedPrevwPage->aPrevwWinPos, 1337 pOldSelectedPrevwPage->aPageSize ); 1338 ::SwAlignRect( aPageRect, &mrParentViewShell); 1339 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1340 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1341 // invalidate top mark line 1342 Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(), 1343 aPxPageRect.Right(), aPxPageRect.Top()+1 ); 1344 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1345 // invalidate right mark line 1346 aInvalPxRect = Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(), 1347 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1348 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1349 // invalidate bottom mark line 1350 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1, 1351 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1352 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1353 // invalidate left mark line 1354 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Top(), 1355 aPxPageRect.Left()+1, aPxPageRect.Bottom() ); 1356 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1357 } 1358 1359 // re-paint for new selected page in order to mark it. 1360 const PrevwPage* pNewSelectedPrevwPage = _GetPrevwPageByPageNum( _nSelectedPage ); 1361 if ( pNewSelectedPrevwPage && pNewSelectedPrevwPage->bVisible ) 1362 _PaintSelectMarkAtPage( pNewSelectedPrevwPage ); 1363 } 1364 1365 1366 // ============================================================================= 1367 // helper methods 1368 // ============================================================================= 1369 /** get preview page by physical page number 1370 1371 OD 17.12.2002 #103492# 1372 1373 @author OD 1374 */ 1375 struct EqualsPageNumPred 1376 { 1377 const sal_uInt16 mnPageNum; 1378 EqualsPageNumPred( const sal_uInt16 _nPageNum ) : mnPageNum( _nPageNum ) {}; 1379 bool operator() ( const PrevwPage* _pPrevwPage ) 1380 { 1381 return _pPrevwPage->pPage->GetPhyPageNum() == mnPageNum; 1382 } 1383 }; 1384 1385 const PrevwPage* SwPagePreviewLayout::_GetPrevwPageByPageNum( const sal_uInt16 _nPageNum ) const 1386 { 1387 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter = 1388 std::find_if( maPrevwPages.begin(), maPrevwPages.end(), 1389 EqualsPageNumPred( _nPageNum ) ); 1390 1391 if ( aFoundPrevwPageIter == maPrevwPages.end() ) 1392 return 0; 1393 else 1394 return (*aFoundPrevwPageIter); 1395 } 1396 1397 /** determine row the page with the given number is in 1398 1399 OD 17.01.2003 #103492# 1400 1401 @author OD, _nPageNum is relative 1402 */ 1403 sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const 1404 { 1405 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1406 // by <mbBookPreview>. 1407 if ( mbBookPreview ) 1408 { 1409 // Note: increase given physical page number by one, because left-top-corner 1410 // in the preview layout is left blank. 1411 ++_nPageNum; 1412 } 1413 1414 sal_uInt16 nRow = (_nPageNum) / mnCols; 1415 if ( ( (_nPageNum) % mnCols ) > 0 ) 1416 ++nRow; 1417 1418 return nRow; 1419 } 1420 1421 /** determine column the page with the given number is in 1422 1423 OD 17.01.2003 #103492# 1424 1425 @author OD, _nPageNum is relative 1426 */ 1427 sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const 1428 { 1429 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1430 // by <mbBookPreview>. 1431 if ( mbBookPreview ) 1432 { 1433 // Note: increase given physical page number by one, because left-top-corner 1434 // in the preview layout is left blank. 1435 ++_nPageNum; 1436 } 1437 1438 sal_uInt16 nCol = (_nPageNum) % mnCols; 1439 if ( nCol == 0 ) 1440 nCol = mnCols; 1441 1442 return nCol; 1443 } 1444 1445 Size SwPagePreviewLayout::GetPrevwDocSize() const 1446 { 1447 ASSERT( PreviewLayoutValid(), "PagePreviewLayout not valid" ); 1448 return maPreviewDocRect.GetSize(); 1449 } 1450 1451 /** get size of a preview page by its physical page number 1452 1453 OD 15.01.2003 #103492# 1454 1455 @author OD 1456 */ 1457 Size SwPagePreviewLayout::GetPrevwPageSizeByPageNum( sal_uInt16 _nPageNum ) const 1458 { 1459 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1460 if ( pPrevwPage ) 1461 { 1462 return pPrevwPage->aPageSize; 1463 } 1464 else 1465 { 1466 return Size( 0, 0 ); 1467 } 1468 } 1469 1470 /** get virtual page number by its physical page number 1471 1472 OD 21.03.2003 #108282# 1473 1474 @author OD 1475 */ 1476 sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const 1477 { 1478 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1479 if ( pPrevwPage ) 1480 { 1481 return pPrevwPage->pPage->GetVirtPageNum(); 1482 } 1483 else 1484 { 1485 return 0; 1486 } 1487 } 1488 1489 /** Convert absolute to relative page numbers (see PrintEmptyPages) 1490 1491 @author FME 1492 */ 1493 sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const 1494 { 1495 if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum ) 1496 { 1497 return _nAbsPageNum; 1498 } 1499 1500 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1501 1502 sal_uInt16 nRet = 1; 1503 1504 while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum ) 1505 { 1506 if ( !pTmpPage->IsEmptyPage() ) 1507 ++nRet; 1508 1509 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1510 } 1511 1512 return nRet; 1513 } 1514 1515 /** Convert relative to absolute page numbers (see PrintEmptyPages) 1516 1517 @author FME 1518 */ 1519 sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const 1520 { 1521 if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum ) 1522 { 1523 return _nRelPageNum; 1524 } 1525 1526 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1527 const SwPageFrm* pRet = 0; 1528 1529 sal_uInt16 i = 0; 1530 while( pTmpPage && i != _nRelPageNum ) 1531 { 1532 if ( !pTmpPage->IsEmptyPage() ) 1533 ++i; 1534 1535 pRet = pTmpPage; 1536 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1537 } 1538 1539 return pRet->GetPhyPageNum(); 1540 } 1541