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 bool bRet = false; 725 if ( mbBookPreview != _bEnableBookPreview) 726 { 727 mbBookPreview = _bEnableBookPreview; 728 // re-initialize page preview layout 729 ReInit(); 730 // re-prepare page preview layout 731 { 732 733 mbBookPreviewModeToggled = true; 734 Point aProposedStartPos( maPaintPreviewDocOffset ); 735 // if proposed start position is below virtual preview document 736 // bottom, adjust it to the virtual preview document bottom 737 if ( aProposedStartPos.Y() > maPreviewDocRect.Bottom() ) 738 { 739 aProposedStartPos.Y() = maPreviewDocRect.Bottom(); 740 } 741 Prepare( 0, aProposedStartPos, 742 mrParentViewShell.GetOut()->LogicToPixel( maWinSize ), 743 _onStartPageNum, _orDocPreviewPaintRect ); 744 mbBookPreviewModeToggled = false; 745 } 746 747 bRet = true; 748 } 749 750 return bRet; 751 } 752 753 // ============================================================================= 754 // methods to determine new data for changing the current shown part of the 755 // document preview. 756 // ============================================================================= 757 /** calculate start position for new scale 758 759 OD 12.12.2002 #103492# 760 761 @author OD 762 */ 763 Point SwPagePreviewLayout::GetPreviewStartPosForNewScale( 764 const Fraction& _aNewScale, 765 const Fraction& _aOldScale, 766 const Size& _aNewWinSize ) const 767 { 768 Point aNewPaintStartPos = maPaintedPrevwDocRect.TopLeft(); 769 if ( _aNewScale < _aOldScale ) 770 { 771 // increase paint width by moving start point to left. 772 if ( mnPrevwLayoutWidth < _aNewWinSize.Width() ) 773 aNewPaintStartPos.X() = 0; 774 else if ( maPaintedPrevwDocRect.GetWidth() < _aNewWinSize.Width() ) 775 { 776 aNewPaintStartPos.X() -= 777 (_aNewWinSize.Width() - maPaintedPrevwDocRect.GetWidth()) / 2; 778 if ( aNewPaintStartPos.X() < 0) 779 aNewPaintStartPos.X() = 0; 780 } 781 782 if ( !mbDoesLayoutRowsFitIntoWindow ) 783 { 784 // increase paint height by moving start point to top. 785 if ( mnPrevwLayoutHeight < _aNewWinSize.Height() ) 786 { 787 aNewPaintStartPos.Y() = 788 ( (mnPaintStartRow - 1) * mnRowHeight ); 789 } 790 else if ( maPaintedPrevwDocRect.GetHeight() < _aNewWinSize.Height() ) 791 { 792 aNewPaintStartPos.Y() -= 793 (_aNewWinSize.Height() - maPaintedPrevwDocRect.GetHeight()) / 2; 794 if ( aNewPaintStartPos.Y() < 0) 795 aNewPaintStartPos.Y() = 0; 796 } 797 } 798 } 799 else 800 { 801 // decrease paint width by moving start point to right 802 if ( maPaintedPrevwDocRect.GetWidth() > _aNewWinSize.Width() ) 803 aNewPaintStartPos.X() += 804 (maPaintedPrevwDocRect.GetWidth() - _aNewWinSize.Width()) / 2; 805 // decrease paint height by moving start point to bottom 806 if ( maPaintedPrevwDocRect.GetHeight() > _aNewWinSize.Height() ) 807 { 808 aNewPaintStartPos.Y() += 809 (maPaintedPrevwDocRect.GetHeight() - _aNewWinSize.Height()) / 2; 810 // check, if new y-position is outside document preview 811 if ( aNewPaintStartPos.Y() > maPreviewDocRect.Bottom() ) 812 aNewPaintStartPos.Y() = 813 Max( 0L, maPreviewDocRect.Bottom() - mnPrevwLayoutHeight ); 814 } 815 } 816 817 return aNewPaintStartPos; 818 } 819 820 /** determines, if page with given page number is visible in preview 821 822 OD 12.12.2002 #103492# 823 824 @author OD, _nPageNum is absolute! 825 */ 826 bool SwPagePreviewLayout::IsPageVisible( const sal_uInt16 _nPageNum ) const 827 { 828 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 829 return pPrevwPage && pPrevwPage->bVisible; 830 } 831 832 /** calculate data to bring new selected page into view. 833 834 OD 12.12.2002 #103492# 835 836 @author OD, IN/OUT parameters are absolute page numbers! 837 */ 838 bool SwPagePreviewLayout::CalcStartValuesForSelectedPageMove( 839 const sal_Int16 _nHoriMove, 840 const sal_Int16 _nVertMove, 841 sal_uInt16& _orNewSelectedPage, 842 sal_uInt16& _orNewStartPage, 843 Point& _orNewStartPos ) const 844 { 845 // determine position of current selected page 846 sal_uInt16 nTmpRelSelPageNum = ConvertAbsoluteToRelativePageNum( mnSelectedPageNum ); 847 sal_uInt16 nNewRelSelectedPageNum = nTmpRelSelPageNum; 848 849 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 850 // by <mbBookPreview>. 851 if ( mbBookPreview ) 852 { 853 // Note: consider that left-top-corner is left blank --> +1 854 ++nTmpRelSelPageNum; 855 } 856 sal_uInt16 nTmpCol = nTmpRelSelPageNum % mnCols; 857 sal_uInt16 nCurrRow = nTmpRelSelPageNum / mnCols; 858 if ( nTmpCol > 0 ) 859 ++nCurrRow; 860 861 // determine new selected page number 862 { 863 if ( _nHoriMove != 0 ) 864 { 865 if ( (nNewRelSelectedPageNum + _nHoriMove) < 1 ) 866 nNewRelSelectedPageNum = 1; 867 else if ( (nNewRelSelectedPageNum + _nHoriMove) > mnPages ) 868 nNewRelSelectedPageNum = mnPages; 869 else 870 nNewRelSelectedPageNum = nNewRelSelectedPageNum + _nHoriMove; 871 } 872 if ( _nVertMove != 0 ) 873 { 874 if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) < 1 ) 875 nNewRelSelectedPageNum = 1; 876 else if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) > mnPages ) 877 nNewRelSelectedPageNum = mnPages; 878 else 879 nNewRelSelectedPageNum += ( _nVertMove * mnCols ); 880 } 881 } 882 883 sal_uInt16 nNewStartPage = mnPaintPhyStartPageNum; 884 Point aNewStartPos = Point(0,0); 885 886 sal_uInt16 nNewAbsSelectedPageNum = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum ); 887 if ( !IsPageVisible( nNewAbsSelectedPageNum ) ) 888 { 889 if ( _nHoriMove != 0 && _nVertMove != 0 ) 890 { 891 ASSERT( false, "missing implementation for moving preview selected page horizontal AND vertical"); 892 return false; 893 } 894 895 // new selected page has to be brought into view considering current 896 // visible preview. 897 sal_Int16 nTotalRows = GetRowOfPage( mnPages ); 898 if ( (_nHoriMove > 0 || _nVertMove > 0) && 899 mbDoesLayoutRowsFitIntoWindow && 900 mbDoesLayoutColsFitIntoWindow && // OD 20.02.2003 #107369# - add condition 901 nCurrRow > nTotalRows - mnRows ) 902 { 903 // new proposed start page = left-top-corner of last possible 904 // preview page. 905 nNewStartPage = (nTotalRows - mnRows) * mnCols + 1; 906 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 907 // by <mbBookPreview>. 908 if ( mbBookPreview ) 909 { 910 // Note: decrease new proposed start page number by one, 911 // because of blank left-top-corner 912 --nNewStartPage; 913 } 914 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewStartPage ); 915 } 916 else 917 { 918 // new proposed start page = new selected page. 919 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum ); 920 } 921 } 922 923 _orNewSelectedPage = nNewAbsSelectedPageNum; 924 _orNewStartPage = nNewStartPage; 925 _orNewStartPos = aNewStartPos; 926 927 return true; 928 } 929 930 /** checks, if given position is inside a shown document page 931 932 OD 17.12.2002 #103492# 933 934 @author OD 935 */ 936 struct PrevwPosInsidePagePred 937 { 938 const Point mnPrevwPos; 939 PrevwPosInsidePagePred( const Point _nPrevwPos ) : mnPrevwPos( _nPrevwPos ) {}; 940 bool operator() ( const PrevwPage* _pPrevwPage ) 941 { 942 if ( _pPrevwPage->bVisible ) 943 { 944 Rectangle aPrevwPageRect( _pPrevwPage->aPrevwWinPos, _pPrevwPage->aPageSize ); 945 return aPrevwPageRect.IsInside( mnPrevwPos ) ? true : false; 946 } 947 else 948 return false; 949 } 950 }; 951 952 bool SwPagePreviewLayout::IsPrevwPosInDocPrevwPage( const Point _aPrevwPos, 953 Point& _orDocPos, 954 bool& _obPosInEmptyPage, 955 sal_uInt16& _onPageNum ) const 956 { 957 bool bIsPosInsideDoc; 958 959 // initialize variable parameter values. 960 _orDocPos.X() = 0; 961 _orDocPos.Y() = 0; 962 _obPosInEmptyPage = false; 963 _onPageNum = 0; 964 965 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter = 966 std::find_if( maPrevwPages.begin(), maPrevwPages.end(), 967 PrevwPosInsidePagePred( _aPrevwPos ) ); 968 969 if ( aFoundPrevwPageIter == maPrevwPages.end() ) 970 // given preview position outside a document page. 971 bIsPosInsideDoc = false; 972 else 973 { 974 _onPageNum = (*aFoundPrevwPageIter)->pPage->GetPhyPageNum(); 975 if ( (*aFoundPrevwPageIter)->pPage->IsEmptyPage() ) 976 { 977 // given preview position inside an empty page 978 bIsPosInsideDoc = false; 979 _obPosInEmptyPage = true; 980 } 981 else 982 { 983 // given preview position inside a normal page 984 bIsPosInsideDoc = true; 985 _orDocPos = _aPrevwPos - 986 (*aFoundPrevwPageIter)->aPrevwWinPos + 987 (*aFoundPrevwPageIter)->aLogicPos; 988 } 989 } 990 991 return bIsPosInsideDoc; 992 } 993 994 /** determine window page scroll amount 995 996 OD 17.12.2002 #103492# 997 998 @author OD 999 */ 1000 SwTwips SwPagePreviewLayout::GetWinPagesScrollAmount( 1001 const sal_Int16 _nWinPagesToScroll ) const 1002 { 1003 SwTwips nScrollAmount; 1004 if ( mbDoesLayoutRowsFitIntoWindow ) 1005 { 1006 nScrollAmount = (mnPrevwLayoutHeight - mnYFree) * _nWinPagesToScroll; 1007 } 1008 else 1009 nScrollAmount = _nWinPagesToScroll * maPaintedPrevwDocRect.GetHeight(); 1010 1011 // OD 19.02.2003 #107369# - check, if preview layout size values are valid. 1012 // If not, the checks for an adjustment of the scroll amount aren't useful. 1013 if ( mbLayoutSizesValid ) 1014 { 1015 if ( (maPaintedPrevwDocRect.Top() + nScrollAmount) <= 0 ) 1016 nScrollAmount = -maPaintedPrevwDocRect.Top(); 1017 1018 // OD 14.02.2003 #107369# - correct scroll amount 1019 if ( nScrollAmount > 0 && 1020 maPaintedPrevwDocRect.Bottom() == maPreviewDocRect.Bottom() 1021 ) 1022 { 1023 nScrollAmount = 0; 1024 } 1025 else 1026 { 1027 while ( (maPaintedPrevwDocRect.Top() + nScrollAmount + mnYFree) >= maPreviewDocRect.GetHeight() ) 1028 { 1029 nScrollAmount -= mnRowHeight; 1030 } 1031 } 1032 } 1033 1034 return nScrollAmount; 1035 } 1036 1037 // ============================================================================= 1038 // methods to paint page preview layout 1039 // ============================================================================= 1040 /** paint prepared preview 1041 1042 OD 12.12.2002 #103492# 1043 1044 @author OD 1045 */ 1046 bool SwPagePreviewLayout::Paint( const Rectangle _aOutRect ) const 1047 { 1048 // check environment and parameters 1049 { 1050 if ( !mrParentViewShell.GetWin() && 1051 !mrParentViewShell.GetOut()->GetConnectMetaFile() ) 1052 return false; 1053 1054 ASSERT( mbPaintInfoValid, 1055 "invalid preview settings - no paint of preview" ); 1056 if ( !mbPaintInfoValid ) 1057 return false; 1058 } 1059 1060 // OD 17.11.2003 #i22014# - no paint, if <superfluous> flag is set at layout 1061 if ( mrLayoutRootFrm.IsSuperfluous() ) 1062 { 1063 return true; 1064 } 1065 1066 // environment and parameter ok 1067 1068 // OD 07.11.2003 #i22014# 1069 if ( mbInPaint ) 1070 { 1071 return false; 1072 } 1073 mbInPaint = true; 1074 1075 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1076 1077 // prepare paint 1078 if ( maPrevwPages.size() > 0 ) 1079 { 1080 mrParentViewShell.Imp()->bFirstPageInvalid = sal_False; 1081 mrParentViewShell.Imp()->pFirstVisPage = 1082 const_cast<SwPageFrm*>(maPrevwPages[0]->pPage); 1083 } 1084 1085 // paint preview background 1086 { 1087 SwRegionRects aPreviewBackgrdRegion( _aOutRect ); 1088 // calculate preview background rectangles 1089 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1090 aPageIter != maPrevwPages.end(); 1091 ++aPageIter ) 1092 { 1093 if ( (*aPageIter)->bVisible ) 1094 { 1095 aPreviewBackgrdRegion -= 1096 SwRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize ); 1097 } 1098 } 1099 // paint preview background rectangles 1100 mrParentViewShell._PaintDesktop( aPreviewBackgrdRegion ); 1101 } 1102 1103 // prepare data for paint of pages 1104 const Rectangle aPxOutRect( pOutputDev->LogicToPixel( _aOutRect ) ); 1105 1106 MapMode aMapMode( pOutputDev->GetMapMode() ); 1107 MapMode aSavedMapMode = aMapMode; 1108 1109 const Font& rEmptyPgFont = SwPageFrm::GetEmptyPageFont(); 1110 1111 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1112 aPageIter != maPrevwPages.end(); 1113 ++aPageIter ) 1114 { 1115 if ( !(*aPageIter)->bVisible ) 1116 continue; 1117 1118 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); 1119 aMapMode.SetOrigin( (*aPageIter)->aMapOffset ); 1120 pOutputDev->SetMapMode( aMapMode ); 1121 Rectangle aPxPaintRect = pOutputDev->LogicToPixel( aPageRect ); 1122 if ( aPxOutRect.IsOver( aPxPaintRect) ) 1123 { 1124 if ( (*aPageIter)->pPage->IsEmptyPage() ) 1125 { 1126 const Color aRetouche( mrParentViewShell.Imp()->GetRetoucheColor() ); 1127 if( pOutputDev->GetFillColor() != aRetouche ) 1128 pOutputDev->SetFillColor( aRetouche ); 1129 pOutputDev->SetLineColor(); // OD 20.02.2003 #107369# - no line color 1130 // OD 20.02.2003 #107369# - use aligned page rectangle 1131 { 1132 SwRect aTmpPageRect( aPageRect ); 1133 ::SwAlignRect( aTmpPageRect, &mrParentViewShell); 1134 aPageRect = aTmpPageRect.SVRect(); 1135 } 1136 pOutputDev->DrawRect( aPageRect ); 1137 1138 // paint empty page text 1139 Font aOldFont( pOutputDev->GetFont() ); 1140 pOutputDev->SetFont( rEmptyPgFont ); 1141 pOutputDev->DrawText( aPageRect, SW_RESSTR( STR_EMPTYPAGE ), 1142 TEXT_DRAW_VCENTER | 1143 TEXT_DRAW_CENTER | 1144 TEXT_DRAW_CLIP ); 1145 pOutputDev->SetFont( aOldFont ); 1146 // paint border for empty page (shadow removed now) 1147 // OD 19.02.2003 #107369# - use new method to paint page border 1148 SwPageFrm::PaintPageBorder( aPageRect, &mrParentViewShell, true ); 1149 } 1150 else 1151 { 1152 mrParentViewShell.aVisArea = aPageRect; 1153 aPxPaintRect.Intersection( aPxOutRect ); 1154 Rectangle aPaintRect = pOutputDev->PixelToLogic( aPxPaintRect ); 1155 mrParentViewShell.Paint( aPaintRect ); 1156 // --> OD 2007-08-15 #i80691# 1157 // paint page border (shadow removed now) 1158 { 1159 SwRect aPageBorderRect; 1160 SwPageFrm::GetBorderAndShadowBoundRect( SwRect( aPageRect ), &mrParentViewShell, aPageBorderRect, true ); 1161 const Region aDLRegion(aPageBorderRect.SVRect()); 1162 mrParentViewShell.DLPrePaint2(aDLRegion); 1163 SwPageFrm::PaintPageBorder( aPageRect, &mrParentViewShell, true ); 1164 mrParentViewShell.DLPostPaint2(true); 1165 } 1166 // <-- 1167 } 1168 // OD 07.11.2003 #i22014# - stop painting, because new print 1169 // preview layout is created during paint. 1170 if ( mbNewLayoutDuringPaint ) 1171 { 1172 break; 1173 } 1174 1175 if ( (*aPageIter)->pPage->GetPhyPageNum() == mnSelectedPageNum ) 1176 { 1177 _PaintSelectMarkAtPage( (*aPageIter) ); 1178 } 1179 1180 } 1181 } 1182 1183 // OD 17.11.2003 #i22014# - no update of accessible preview, if a new 1184 // print preview layout is created during paint. 1185 if ( !mbNewLayoutDuringPaint ) 1186 { 1187 // update at accessibility interface 1188 mrParentViewShell.Imp()->UpdateAccessiblePreview( 1189 maPrevwPages, 1190 aMapMode.GetScaleX(), 1191 mrLayoutRootFrm.GetPageByPageNum( mnSelectedPageNum ), 1192 maWinSize ); 1193 } 1194 1195 pOutputDev->SetMapMode( aSavedMapMode ); 1196 mrParentViewShell.aVisArea.Clear(); 1197 1198 // OD 07.11.2003 #i22014# 1199 mbInPaint = false; 1200 mbNewLayoutDuringPaint = false; 1201 1202 return true; 1203 } 1204 1205 /** repaint pages on page preview 1206 1207 OD 18.12.2002 #103492# 1208 1209 @author OD 1210 */ 1211 void SwPagePreviewLayout::Repaint( const Rectangle _aInvalidCoreRect ) const 1212 { 1213 // check environment and parameters 1214 { 1215 if ( !mrParentViewShell.GetWin() && 1216 !mrParentViewShell.GetOut()->GetConnectMetaFile() ) 1217 return; 1218 1219 ASSERT( mbPaintInfoValid, 1220 "invalid preview settings - no paint of preview" ); 1221 if ( !mbPaintInfoValid ) 1222 return; 1223 } 1224 1225 // environment and parameter OK 1226 1227 // prepare paint 1228 if ( maPrevwPages.size() > 0 ) 1229 { 1230 mrParentViewShell.Imp()->bFirstPageInvalid = sal_False; 1231 mrParentViewShell.Imp()->pFirstVisPage = 1232 const_cast<SwPageFrm*>(maPrevwPages[0]->pPage); 1233 } 1234 1235 // invalidate visible pages, which overlap the invalid core rectangle 1236 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin(); 1237 aPageIter != maPrevwPages.end(); 1238 ++aPageIter ) 1239 { 1240 if ( !(*aPageIter)->bVisible ) 1241 continue; 1242 1243 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); 1244 if ( _aInvalidCoreRect.IsOver( aPageRect ) ) 1245 { 1246 aPageRect.Intersection( _aInvalidCoreRect ); 1247 Rectangle aInvalidPrevwRect = aPageRect; 1248 aInvalidPrevwRect.SetPos( aInvalidPrevwRect.TopLeft() - 1249 (*aPageIter)->aLogicPos + 1250 (*aPageIter)->aPrevwWinPos ); 1251 mrParentViewShell.GetWin()->Invalidate( aInvalidPrevwRect ); 1252 } 1253 } 1254 } 1255 1256 /** paint selection mark at page 1257 1258 OD 17.12.2002 #103492# 1259 1260 @author OD 1261 */ 1262 void SwPagePreviewLayout::_PaintSelectMarkAtPage( 1263 const PrevwPage* _aSelectedPrevwPage ) const 1264 { 1265 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1266 MapMode aMapMode( pOutputDev->GetMapMode() ); 1267 // save mapping mode of output device 1268 MapMode aSavedMapMode = aMapMode; 1269 // save fill and line color of output device 1270 Color aFill( pOutputDev->GetFillColor() ); 1271 Color aLine( pOutputDev->GetLineColor() ); 1272 1273 // determine selection mark color 1274 const StyleSettings& rSettings = mrParentViewShell.GetWin()->GetSettings().GetStyleSettings(); 1275 Color aSelPgLineColor( rSettings.GetHighlightColor() ); 1276 if ( rSettings.GetHighContrastMode() ) 1277 aSelPgLineColor = rSettings.GetActiveBorderColor(); 1278 1279 // set needed mapping mode at output device 1280 aMapMode.SetOrigin( _aSelectedPrevwPage->aMapOffset ); 1281 pOutputDev->SetMapMode( aMapMode ); 1282 1283 // calculate page rectangle in pixel coordinates 1284 SwRect aPageRect( _aSelectedPrevwPage->aLogicPos, 1285 _aSelectedPrevwPage->aPageSize ); 1286 // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for 1287 // page border paint - see <SwPageFrm::PaintPageBorder(..)> 1288 ::SwAlignRect( aPageRect, &mrParentViewShell); 1289 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1290 1291 // draw two rectangles 1292 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1293 Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(), 1294 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1295 aRect = pOutputDev->PixelToLogic( aRect ); 1296 pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color 1297 pOutputDev->SetLineColor( aSelPgLineColor ); 1298 pOutputDev->DrawRect( aRect ); 1299 // OD 19.02.2003 #107369# - adjust position of select mark rectangle 1300 aRect = Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1, 1301 aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 ); 1302 aRect = pOutputDev->PixelToLogic( aRect ); 1303 pOutputDev->DrawRect( aRect ); 1304 1305 // reset fill and line color of output device 1306 pOutputDev->SetFillColor( aFill ); 1307 pOutputDev->SetLineColor( aLine ); 1308 1309 // reset mapping mode of output device 1310 pOutputDev->SetMapMode( aSavedMapMode ); 1311 } 1312 1313 /** paint to mark new selected page 1314 1315 OD 17.12.2002 #103492# 1316 Perform paint for current selected page in order to unmark it. 1317 Set new selected page and perform paint to mark this page. 1318 1319 @author OD, _nSelectedPage, mnSelectedPage are absolute 1320 */ 1321 void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage ) 1322 { 1323 sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum; 1324 mnSelectedPageNum = _nSelectedPage; 1325 1326 // re-paint for current selected page in order to unmark it. 1327 const PrevwPage* pOldSelectedPrevwPage = _GetPrevwPageByPageNum( nOldSelectedPageNum ); 1328 if ( pOldSelectedPrevwPage && pOldSelectedPrevwPage->bVisible ) 1329 { 1330 // OD 20.02.2003 #107369# - invalidate only areas of selection mark. 1331 SwRect aPageRect( pOldSelectedPrevwPage->aPrevwWinPos, 1332 pOldSelectedPrevwPage->aPageSize ); 1333 ::SwAlignRect( aPageRect, &mrParentViewShell); 1334 OutputDevice* pOutputDev = mrParentViewShell.GetOut(); 1335 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); 1336 // invalidate top mark line 1337 Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(), 1338 aPxPageRect.Right(), aPxPageRect.Top()+1 ); 1339 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1340 // invalidate right mark line 1341 aInvalPxRect = Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(), 1342 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1343 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1344 // invalidate bottom mark line 1345 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1, 1346 aPxPageRect.Right(), aPxPageRect.Bottom() ); 1347 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1348 // invalidate left mark line 1349 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Top(), 1350 aPxPageRect.Left()+1, aPxPageRect.Bottom() ); 1351 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); 1352 } 1353 1354 // re-paint for new selected page in order to mark it. 1355 const PrevwPage* pNewSelectedPrevwPage = _GetPrevwPageByPageNum( _nSelectedPage ); 1356 if ( pNewSelectedPrevwPage && pNewSelectedPrevwPage->bVisible ) 1357 _PaintSelectMarkAtPage( pNewSelectedPrevwPage ); 1358 } 1359 1360 1361 // ============================================================================= 1362 // helper methods 1363 // ============================================================================= 1364 /** get preview page by physical page number 1365 1366 OD 17.12.2002 #103492# 1367 1368 @author OD 1369 */ 1370 struct EqualsPageNumPred 1371 { 1372 const sal_uInt16 mnPageNum; 1373 EqualsPageNumPred( const sal_uInt16 _nPageNum ) : mnPageNum( _nPageNum ) {}; 1374 bool operator() ( const PrevwPage* _pPrevwPage ) 1375 { 1376 return _pPrevwPage->pPage->GetPhyPageNum() == mnPageNum; 1377 } 1378 }; 1379 1380 const PrevwPage* SwPagePreviewLayout::_GetPrevwPageByPageNum( const sal_uInt16 _nPageNum ) const 1381 { 1382 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter = 1383 std::find_if( maPrevwPages.begin(), maPrevwPages.end(), 1384 EqualsPageNumPred( _nPageNum ) ); 1385 1386 if ( aFoundPrevwPageIter == maPrevwPages.end() ) 1387 return 0; 1388 else 1389 return (*aFoundPrevwPageIter); 1390 } 1391 1392 /** determine row the page with the given number is in 1393 1394 OD 17.01.2003 #103492# 1395 1396 @author OD, _nPageNum is relative 1397 */ 1398 sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const 1399 { 1400 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1401 // by <mbBookPreview>. 1402 if ( mbBookPreview ) 1403 { 1404 // Note: increase given physical page number by one, because left-top-corner 1405 // in the preview layout is left blank. 1406 ++_nPageNum; 1407 } 1408 1409 sal_uInt16 nRow = (_nPageNum) / mnCols; 1410 if ( ( (_nPageNum) % mnCols ) > 0 ) 1411 ++nRow; 1412 1413 return nRow; 1414 } 1415 1416 /** determine column the page with the given number is in 1417 1418 OD 17.01.2003 #103492# 1419 1420 @author OD, _nPageNum is relative 1421 */ 1422 sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const 1423 { 1424 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled 1425 // by <mbBookPreview>. 1426 if ( mbBookPreview ) 1427 { 1428 // Note: increase given physical page number by one, because left-top-corner 1429 // in the preview layout is left blank. 1430 ++_nPageNum; 1431 } 1432 1433 sal_uInt16 nCol = (_nPageNum) % mnCols; 1434 if ( nCol == 0 ) 1435 nCol = mnCols; 1436 1437 return nCol; 1438 } 1439 1440 Size SwPagePreviewLayout::GetPrevwDocSize() const 1441 { 1442 ASSERT( PreviewLayoutValid(), "PagePreviewLayout not valid" ); 1443 return maPreviewDocRect.GetSize(); 1444 } 1445 1446 /** get size of a preview page by its physical page number 1447 1448 OD 15.01.2003 #103492# 1449 1450 @author OD 1451 */ 1452 Size SwPagePreviewLayout::GetPrevwPageSizeByPageNum( sal_uInt16 _nPageNum ) const 1453 { 1454 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1455 if ( pPrevwPage ) 1456 { 1457 return pPrevwPage->aPageSize; 1458 } 1459 else 1460 { 1461 return Size( 0, 0 ); 1462 } 1463 } 1464 1465 /** get virtual page number by its physical page number 1466 1467 OD 21.03.2003 #108282# 1468 1469 @author OD 1470 */ 1471 sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const 1472 { 1473 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); 1474 if ( pPrevwPage ) 1475 { 1476 return pPrevwPage->pPage->GetVirtPageNum(); 1477 } 1478 else 1479 { 1480 return 0; 1481 } 1482 } 1483 1484 /** Convert absolute to relative page numbers (see PrintEmptyPages) 1485 1486 @author FME 1487 */ 1488 sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const 1489 { 1490 if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum ) 1491 { 1492 return _nAbsPageNum; 1493 } 1494 1495 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1496 1497 sal_uInt16 nRet = 1; 1498 1499 while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum ) 1500 { 1501 if ( !pTmpPage->IsEmptyPage() ) 1502 ++nRet; 1503 1504 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1505 } 1506 1507 return nRet; 1508 } 1509 1510 /** Convert relative to absolute page numbers (see PrintEmptyPages) 1511 1512 @author FME 1513 */ 1514 sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const 1515 { 1516 if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum ) 1517 { 1518 return _nRelPageNum; 1519 } 1520 1521 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower()); 1522 const SwPageFrm* pRet = 0; 1523 1524 sal_uInt16 i = 0; 1525 while( pTmpPage && i != _nRelPageNum ) 1526 { 1527 if ( !pTmpPage->IsEmptyPage() ) 1528 ++i; 1529 1530 pRet = pTmpPage; 1531 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() ); 1532 } 1533 1534 return pRet->GetPhyPageNum(); 1535 } 1536 1537 /* vim: set noet sw=4 ts=4: */ 1538