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