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