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 Color aSelPgLineColor(0, 120, 215); 1277 const StyleSettings& rSettings = 1278 mrParentViewShell.GetWin()->GetSettings().GetStyleSettings(); 1279 if ( rSettings.GetHighContrastMode() ) 1280 aSelPgLineColor = rSettings.GetHighlightTextColor(); 1281 1282 // set needed mapping mode at output device 1283 aMapMode.SetOrigin( _aSelectedPrevwPage->aMapOffset ); 1284 pOutputDev->SetMapMode( aMapMode ); 1285 1286 // calculate page rectangle in pixel coordinates 1287 SwRect aPageRect( _aSelectedPrevwPage->aLogicPos, 1288 _aSelectedPrevwPage->aPageSize ); 1289 // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for 1290 // page border paint - see <SwPageFrm::PaintPageBorder(..)> 1291 ::SwAlignRect( aPageRect, &mrParentViewShell); 1292 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1293 1294 // draw two rectangles 1295 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1296 Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(), 1297 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1298 aRect = pOutputDev->PixelToLogic( aRect ); 1299 pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color 1300 pOutputDev->SetLineColor( aSelPgLineColor ); 1301 pOutputDev->DrawRect( aRect ); 1302 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1303 aRect = Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1, 1304 aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 ); 1305 aRect = pOutputDev->PixelToLogic( aRect ); 1306 pOutputDev->DrawRect( aRect ); 1307 1308 // reset fill and line color of output device 1309 pOutputDev->SetFillColor( aFill ); 1310 pOutputDev->SetLineColor( aLine ); 1311 1312 // reset mapping mode of output device 1313 pOutputDev->SetMapMode( aSavedMapMode ); 1314 } 1315 1316 /** paint to mark new selected page 1317 1318 OD 17.12.2002 #103492# 1319 Perform paint for current selected page in order to unmark it. 1320 Set new selected page and perform paint to mark this page. 1321 1322 @author OD, _nSelectedPage, mnSelectedPage are absolute 1323 */ 1324 void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage ) 1325 { 1326 sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum; 1327 mnSelectedPageNum = _nSelectedPage; 1328 1329 // re-paint for current selected page in order to unmark it. 1330 const PrevwPage* pOldSelectedPrevwPage = _GetPrevwPageByPageNum( nOldSelectedPageNum ); 1331 if ( pOldSelectedPrevwPage && pOldSelectedPrevwPage->bVisible ) 1332 { 1333 // OD 20.02.2003 #107369# - invalidate only areas of selection mark. 1334 SwRect aPageRect( pOldSelectedPrevwPage->aPrevwWinPos, 1335 pOldSelectedPrevwPage->aPageSize ); 1336 ::SwAlignRect( aPageRect, &mrParentViewShell); 1337 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1338 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1339 // invalidate top mark line 1340 Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(), 1341 aPxPageRect.Right(), aPxPageRect.Top()+1 ); 1342 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1343 // invalidate right mark line 1344 aInvalPxRect = Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(), 1345 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1346 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1347 // invalidate bottom mark line 1348 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1, 1349 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1350 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1351 // invalidate left mark line 1352 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Top(), 1353 aPxPageRect.Left()+1, aPxPageRect.Bottom() ); 1354 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1355 } 1356 1357 // re-paint for new selected page in order to mark it. 1358 const PrevwPage* pNewSelectedPrevwPage = _GetPrevwPageByPageNum( _nSelectedPage ); 1359 if ( pNewSelectedPrevwPage && pNewSelectedPrevwPage->bVisible ) 1360 _PaintSelectMarkAtPage( pNewSelectedPrevwPage ); 1361 } 1362 1363 1364 // ============================================================================= 1365 // helper methods 1366 // ============================================================================= 1367 /** get preview page by physical page number 1368 1369 OD 17.12.2002 #103492# 1370 1371 @author OD 1372 */ 1373 struct EqualsPageNumPred 1374 { 1375 const sal_uInt16 mnPageNum; 1376 EqualsPageNumPred( const sal_uInt16 _nPageNum ) : mnPageNum( _nPageNum ) {}; 1377 bool operator() ( const PrevwPage* _pPrevwPage ) 1378 { 1379 return _pPrevwPage->pPage->GetPhyPageNum() == mnPageNum; 1380 } 1381 }; 1382 1383 const PrevwPage* SwPagePreviewLayout::_GetPrevwPageByPageNum( const sal_uInt16 _nPageNum ) const 1384 { 1385 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter = 1386 std::find_if( maPrevwPages.begin(), maPrevwPages.end(), 1387 EqualsPageNumPred( _nPageNum ) ); 1388 1389 if ( aFoundPrevwPageIter == maPrevwPages.end() ) 1390 return 0; 1391 else 1392 return (*aFoundPrevwPageIter); 1393 } 1394 1395 /** determine row the page with the given number is in 1396 1397 OD 17.01.2003 #103492# 1398 1399 @author OD, _nPageNum is relative 1400 */ 1401 sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const 1402 { 1403 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1404 // by <mbBookPreview>. 1405 if ( mbBookPreview ) 1406 { 1407 // Note: increase given physical page number by one, because left-top-corner 1408 // in the preview layout is left blank. 1409 ++_nPageNum; 1410 } 1411 1412 sal_uInt16 nRow = (_nPageNum) / mnCols; 1413 if ( ( (_nPageNum) % mnCols ) > 0 ) 1414 ++nRow; 1415 1416 return nRow; 1417 } 1418 1419 /** determine column the page with the given number is in 1420 1421 OD 17.01.2003 #103492# 1422 1423 @author OD, _nPageNum is relative 1424 */ 1425 sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const 1426 { 1427 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1428 // by <mbBookPreview>. 1429 if ( mbBookPreview ) 1430 { 1431 // Note: increase given physical page number by one, because left-top-corner 1432 // in the preview layout is left blank. 1433 ++_nPageNum; 1434 } 1435 1436 sal_uInt16 nCol = (_nPageNum) % mnCols; 1437 if ( nCol == 0 ) 1438 nCol = mnCols; 1439 1440 return nCol; 1441 } 1442 1443 Size SwPagePreviewLayout::GetPrevwDocSize() const 1444 { 1445 ASSERT( PreviewLayoutValid(), "PagePreviewLayout not valid" ); 1446 return maPreviewDocRect.GetSize(); 1447 } 1448 1449 /** get size of a preview page by its physical page number 1450 1451 OD 15.01.2003 #103492# 1452 1453 @author OD 1454 */ 1455 Size SwPagePreviewLayout::GetPrevwPageSizeByPageNum( sal_uInt16 _nPageNum ) const 1456 { 1457 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1458 if ( pPrevwPage ) 1459 { 1460 return pPrevwPage->aPageSize; 1461 } 1462 else 1463 { 1464 return Size( 0, 0 ); 1465 } 1466 } 1467 1468 /** get virtual page number by its physical page number 1469 1470 OD 21.03.2003 #108282# 1471 1472 @author OD 1473 */ 1474 sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const 1475 { 1476 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1477 if ( pPrevwPage ) 1478 { 1479 return pPrevwPage->pPage->GetVirtPageNum(); 1480 } 1481 else 1482 { 1483 return 0; 1484 } 1485 } 1486 1487 /** Convert absolute to relative page numbers (see PrintEmptyPages) 1488 1489 @author FME 1490 */ 1491 sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const 1492 { 1493 if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum ) 1494 { 1495 return _nAbsPageNum; 1496 } 1497 1498 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1499 1500 sal_uInt16 nRet = 1; 1501 1502 while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum ) 1503 { 1504 if ( !pTmpPage->IsEmptyPage() ) 1505 ++nRet; 1506 1507 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1508 } 1509 1510 return nRet; 1511 } 1512 1513 /** Convert relative to absolute page numbers (see PrintEmptyPages) 1514 1515 @author FME 1516 */ 1517 sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const 1518 { 1519 if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum ) 1520 { 1521 return _nRelPageNum; 1522 } 1523 1524 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1525 const SwPageFrm* pRet = 0; 1526 1527 sal_uInt16 i = 0; 1528 while( pTmpPage && i != _nRelPageNum ) 1529 { 1530 if ( !pTmpPage->IsEmptyPage() ) 1531 ++i; 1532 1533 pRet = pTmpPage; 1534 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1535 } 1536 1537 return pRet->GetPhyPageNum(); 1538 } 1539 1540 /* vim: set noet sw=4 ts=4: */ 1541