Update ooo320-m1
[ooovba.git] / sw / source / core / view / pagepreviewlayout.cxx
blobfc62061a19f290065e849258e0d34c4ca4f3924d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pagepreviewlayout.cxx,v $
10 * $Revision: 1.15.214.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <pagepreviewlayout.hxx>
34 #ifndef _PREVWPAGE_HXX
35 #include <prevwpage.hxx>
36 #endif
38 #include <algorithm>
39 #include <vcl/window.hxx>
40 #include <rootfrm.hxx>
41 #include <pagefrm.hxx>
42 #include <viewsh.hxx>
43 #include <viewimp.hxx>
44 #include <viewopt.hxx>
45 #include <swregion.hxx>
46 #ifndef _COMCORE_HRC
47 #include <comcore.hrc>
48 #endif
49 // OD 19.02.2003 #107369# - method <SwAlignRect(..)>
50 #include <frmtool.hxx>
51 // OD 24.09.2003 #i19975#
52 #include <svx/zoomitem.hxx>
53 #include <printdata.hxx>
55 #include <IDocumentDeviceAccess.hxx>
57 // OD 20.02.2003 #107369# - method to update statics for paint
58 // Note: method defined in '/sw/source/core/layout/paintfrm.cxx'
59 extern void SwCalcPixStatics( OutputDevice *pOut );
61 // =============================================================================
62 // methods to initialize page preview layout
63 // =============================================================================
64 SwPagePreviewLayout::SwPagePreviewLayout( ViewShell& _rParentViewShell,
65 const SwRootFrm& _rLayoutRootFrm )
66 : mnXFree ( 4*142 ),
67 mnYFree ( 4*142 ),
68 mrParentViewShell( _rParentViewShell ),
69 mrLayoutRootFrm ( _rLayoutRootFrm )
71 _Clear();
73 // OD 2004-03-05 #i18143#
74 mbBookPreview = false;
75 mbBookPreviewModeToggled = false;
77 const SwPrintData* pPrintData = mrParentViewShell.getIDocumentDeviceAccess()->getPrintData();
78 mbPrintEmptyPages = pPrintData ? pPrintData->IsPrintEmptyPages() : true;
81 void SwPagePreviewLayout::_Clear()
83 mbLayoutInfoValid = mbLayoutSizesValid = mbPaintInfoValid = false;
85 maWinSize.Width() = 0;
86 maWinSize.Height() = 0;
87 mnCols = mnRows = 0;
89 _ClearPrevwLayoutSizes();
91 mbDoesLayoutRowsFitIntoWindow = false;
92 mbDoesLayoutColsFitIntoWindow = false;
94 mnPaintPhyStartPageNum = 0;
95 mnPaintStartCol = mnPaintStartRow = 0;
96 mbNoPageVisible = false;
97 maPaintStartPageOffset.X() = 0;
98 maPaintStartPageOffset.Y() = 0;
99 maPaintPreviewDocOffset.X() = 0;
100 maPaintPreviewDocOffset.Y() = 0;
101 maAdditionalPaintOffset.X() = 0;
102 maAdditionalPaintOffset.Y() = 0;
103 maPaintedPrevwDocRect.Left() = 0;
104 maPaintedPrevwDocRect.Top() = 0;
105 maPaintedPrevwDocRect.Right() = 0;
106 maPaintedPrevwDocRect.Bottom() = 0;
107 mnSelectedPageNum = 0;
108 _ClearPrevwPageData();
110 // OD 07.11.2003 #i22014#
111 mbInPaint = false;
112 mbNewLayoutDuringPaint = false;
115 void SwPagePreviewLayout::_ClearPrevwLayoutSizes()
117 mnPages = 0;
119 maMaxPageSize.Width() = 0;
120 maMaxPageSize.Height() = 0;
121 maPreviewDocRect.Left() = maPreviewDocRect.Top() = 0;
122 maPreviewDocRect.Right() = maPreviewDocRect.Bottom() = 0;
123 mnColWidth = mnRowHeight = 0;
124 mnPrevwLayoutWidth = mnPrevwLayoutHeight = 0;
127 void SwPagePreviewLayout::_ClearPrevwPageData()
129 for ( std::vector<PrevwPage*>::iterator aPageDelIter = maPrevwPages.begin();
130 aPageDelIter != maPrevwPages.end();
131 ++aPageDelIter )
133 delete (*aPageDelIter);
135 maPrevwPages.clear();
138 /** calculate page preview layout sizes
140 OD 18.12.2002 #103492#
142 @author OD
144 void SwPagePreviewLayout::_CalcPrevwLayoutSizes()
146 // calculate maximal page size; calculate also number of pages
148 const SwPageFrm* pPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower());
149 while ( pPage )
151 if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() )
153 pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
154 continue;
157 ++mnPages;
158 pPage->Calc();
159 const Size& rPageSize = pPage->Frm().SSize();
160 if ( rPageSize.Width() > maMaxPageSize.Width() )
161 maMaxPageSize.Width() = rPageSize.Width();
162 if ( rPageSize.Height() > maMaxPageSize.Height() )
163 maMaxPageSize.Height() = rPageSize.Height();
164 pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
166 // calculate and set column width and row height
167 mnColWidth = maMaxPageSize.Width() + mnXFree;
168 mnRowHeight = maMaxPageSize.Height() + mnYFree;
170 // calculate and set preview layout width and height
171 mnPrevwLayoutWidth = mnCols * mnColWidth + mnXFree;
172 mnPrevwLayoutHeight = mnRows * mnRowHeight + mnYFree;
174 // calculate document rectangle in preview layout
176 Size aDocSize;
177 // document width
178 aDocSize.Width() = mnPrevwLayoutWidth;
180 // document height
181 // determine number of rows needed for <nPages> in preview layout
182 // OD 19.02.2003 #107369# - use method <GetRowOfPage(..)>.
183 sal_uInt16 nDocRows = GetRowOfPage( mnPages );
184 aDocSize.Height() = nDocRows * maMaxPageSize.Height() +
185 (nDocRows+1) * mnYFree;
186 maPreviewDocRect.SetPos( Point( 0, 0 ) );
187 maPreviewDocRect.SetSize( aDocSize );
191 /** init page preview layout
193 OD 11.12.2002 #103492#
194 initialize the page preview settings for a given layout.
195 side effects:
196 (1) If parameter <_bCalcScale> is true, mapping mode with calculated
197 scaling is set at the output device and the zoom at the view options of
198 the given view shell is set with the calculated scaling.
200 @author OD
202 bool SwPagePreviewLayout::Init( const sal_uInt16 _nCols,
203 const sal_uInt16 _nRows,
204 const Size& _rPxWinSize,
205 const bool _bCalcScale
208 // check environment and parameters
210 bool bColsRowsValid = (_nCols != 0) && (_nRows != 0);
211 ASSERT( bColsRowsValid, "preview layout parameters not correct - preview layout can *not* be initialized" );
212 if ( !bColsRowsValid )
213 return false;
215 bool bPxWinSizeValid = (_rPxWinSize.Width() >= 0) &&
216 (_rPxWinSize.Height() >= 0);
217 ASSERT( bPxWinSizeValid, "no window size - preview layout can *not* be initialized" );
218 if ( !bPxWinSizeValid )
219 return false;
222 // environment and parameters ok
224 // clear existing preview settings
225 _Clear();
227 // set layout information columns and rows
228 mnCols = _nCols;
229 mnRows = _nRows;
231 _CalcPrevwLayoutSizes();
233 // validate layout information
234 mbLayoutInfoValid = true;
236 if ( _bCalcScale )
238 // calculate scaling
239 MapMode aMapMode( MAP_TWIP );
240 Size aWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize, aMapMode );
241 Fraction aXScale( aWinSize.Width(), mnPrevwLayoutWidth );
242 Fraction aYScale( aWinSize.Height(), mnPrevwLayoutHeight );
243 if( aXScale < aYScale )
244 aYScale = aXScale;
246 // adjust scaling for Drawing layer.
247 aYScale *= Fraction( 1000, 1 );
248 long nNewNuminator = aYScale.operator long();
249 if( nNewNuminator < 1 )
250 nNewNuminator = 1;
251 aYScale = Fraction( nNewNuminator, 1000 );
252 // propagate scaling as zoom percentage to view options for font cache
253 _ApplyNewZoomAtViewShell( static_cast<sal_uInt8>(nNewNuminator/10) );
255 aMapMode.SetScaleY( aYScale );
256 aMapMode.SetScaleX( aYScale );
257 // set created mapping mode with calculated scaling at output device.
258 mrParentViewShell.GetOut()->SetMapMode( aMapMode );
259 // OD 20.02.2003 #107369# - update statics for paint.
260 ::SwCalcPixStatics( mrParentViewShell.GetOut() );
263 // set window size in twips
264 maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize );
265 // validate layout sizes
266 mbLayoutSizesValid = true;
268 return true;
271 /** apply new zoom at given view shell
273 OD 11.12.2002 #103492# - implementation of <_ApplyNewZoomAtViewShell>
275 @author OD
277 void SwPagePreviewLayout::_ApplyNewZoomAtViewShell( sal_uInt8 _aNewZoom )
279 SwViewOption aNewViewOptions = *(mrParentViewShell.GetViewOptions());
280 if ( aNewViewOptions.GetZoom() != _aNewZoom )
282 aNewViewOptions.SetZoom( _aNewZoom );
283 // OD 24.09.2003 #i19975# - consider zoom type.
284 enum SvxZoomType eZoomType = SVX_ZOOM_PERCENT;
285 aNewViewOptions.SetZoomType( eZoomType );
286 mrParentViewShell.ApplyViewOptions( aNewViewOptions );
290 /** method to adjust page preview layout to document changes
292 OD 18.12.2002 #103492#
294 @author OD
296 bool SwPagePreviewLayout::ReInit()
298 // check environment and parameters
300 bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid;
301 ASSERT( bLayoutSettingsValid,
302 "no valid preview layout info/sizes - no re-init of page preview layout");
303 if ( !bLayoutSettingsValid )
304 return false;
307 _ClearPrevwLayoutSizes();
308 _CalcPrevwLayoutSizes();
310 return true;
313 // =============================================================================
314 // methods to prepare paint of page preview
315 // =============================================================================
316 /** prepare paint of page preview
318 OD 12.12.2002 #103492#
319 OD 21.03.2003 #108282# - delete parameter _onStartPageVirtNum
321 @author OD, _nProposedStartPageNum, _onStartPageNum are absolute
323 bool SwPagePreviewLayout::Prepare( const sal_uInt16 _nProposedStartPageNum,
324 const Point _aProposedStartPos,
325 const Size& _rPxWinSize,
326 sal_uInt16& _onStartPageNum,
327 Rectangle& _orDocPreviewPaintRect,
328 const bool _bStartWithPageAtFirstCol
331 sal_uInt16 nProposedStartPageNum = ConvertAbsoluteToRelativePageNum( _nProposedStartPageNum );
332 // check environment and parameters
334 bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid;
335 ASSERT( bLayoutSettingsValid,
336 "no valid preview layout info/sizes - no prepare of preview paint");
337 if ( !bLayoutSettingsValid )
338 return false;
340 bool bStartPageRangeValid = nProposedStartPageNum <= mnPages;
341 ASSERT( bStartPageRangeValid,
342 "proposed start page not existing - no prepare of preview paint");
343 if ( !bStartPageRangeValid )
344 return false;
346 bool bStartPosRangeValid =
347 _aProposedStartPos.X() >= 0 && _aProposedStartPos.Y() >= 0 &&
348 _aProposedStartPos.X() <= maPreviewDocRect.Right() &&
349 _aProposedStartPos.Y() <= maPreviewDocRect.Bottom();
350 ASSERT( bStartPosRangeValid,
351 "proposed start position out of range - no prepare of preview paint");
352 if ( !bStartPosRangeValid )
353 return false;
355 bool bWinSizeValid = _rPxWinSize.Width() != 0 && _rPxWinSize.Height() != 0;
356 ASSERT ( bWinSizeValid, "no window size - no prepare of preview paint");
357 if ( !bWinSizeValid )
358 return false;
360 bool bStartInfoValid = _nProposedStartPageNum > 0 ||
361 _aProposedStartPos != Point(0,0);
362 if ( !bStartInfoValid )
363 nProposedStartPageNum = 1;
366 // environment and parameter ok
368 // update window size at preview setting data
369 maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize );
371 mbNoPageVisible = false;
372 if ( nProposedStartPageNum > 0 )
374 // determine column and row of proposed start page in virtual preview layout
375 sal_uInt16 nColOfProposed = GetColOfPage( nProposedStartPageNum );
376 sal_uInt16 nRowOfProposed = GetRowOfPage( nProposedStartPageNum );
377 // determine start page
378 if ( _bStartWithPageAtFirstCol )
380 // OD 19.02.2003 #107369# - leaving left-top-corner blank is
381 // controlled by <mbBookPreview>.
382 if ( mbBookPreview &&
383 ( nProposedStartPageNum == 1 || nRowOfProposed == 1 )
385 mnPaintPhyStartPageNum = 1;
386 else
387 mnPaintPhyStartPageNum = nProposedStartPageNum - (nColOfProposed-1);
389 else
390 mnPaintPhyStartPageNum = nProposedStartPageNum;
392 mnPaintPhyStartPageNum = ConvertRelativeToAbsolutePageNum( mnPaintPhyStartPageNum );
394 // set starting column
395 if ( _bStartWithPageAtFirstCol )
396 mnPaintStartCol = 1;
397 else
398 mnPaintStartCol = nColOfProposed;
399 // set starting row
400 mnPaintStartRow = nRowOfProposed;
401 // page offset == (-1,-1), indicating no offset and paint of free space.
402 maPaintStartPageOffset.X() = -1;
403 maPaintStartPageOffset.Y() = -1;
404 // virtual preview document offset.
405 if ( _bStartWithPageAtFirstCol )
406 maPaintPreviewDocOffset.X() = 0;
407 else
408 maPaintPreviewDocOffset.X() = (nColOfProposed-1) * mnColWidth;
409 maPaintPreviewDocOffset.Y() = (nRowOfProposed-1) * mnRowHeight;
411 else
413 // determine column and row of proposed start position.
414 // Note: paint starts at point (0,0)
415 sal_uInt16 nColOfProposed =
416 static_cast<sal_uInt16>(_aProposedStartPos.X() / mnColWidth) + 1;
417 sal_uInt16 nRowOfProposed =
418 static_cast<sal_uInt16>(_aProposedStartPos.Y() / mnRowHeight) + 1;
419 // determine start page == page at proposed start position
420 // OD 19.02.2003 #107369# - leaving left-top-corner blank is
421 // controlled by <mbBookPreview>.
422 if ( mbBookPreview &&
423 ( nRowOfProposed == 1 && nColOfProposed == 1 )
425 mnPaintPhyStartPageNum = 1;
426 else
428 // OD 19.02.2003 #107369# - leaving left-top-corner blank is
429 // controlled by <mbBookPreview>.
430 mnPaintPhyStartPageNum = (nRowOfProposed-1) * mnCols + nColOfProposed;
431 if ( mbBookPreview )
432 --mnPaintPhyStartPageNum;
433 if ( mnPaintPhyStartPageNum > mnPages )
435 // no page will be visible, because shown part of document
436 // preview is the last row to the right of the last page
437 mnPaintPhyStartPageNum = mnPages;
438 mbNoPageVisible = true;
441 // set starting column and starting row
442 mnPaintStartCol = nColOfProposed;
443 mnPaintStartRow = nRowOfProposed;
444 // page offset
445 maPaintStartPageOffset.X() =
446 (_aProposedStartPos.X() % mnColWidth) - mnXFree;
447 maPaintStartPageOffset.Y() =
448 (_aProposedStartPos.Y() % mnRowHeight) - mnYFree;
449 // virtual preview document offset.
450 maPaintPreviewDocOffset = _aProposedStartPos;
453 // determine additional paint offset, if preview layout fits into window.
454 _CalcAdditionalPaintOffset();
456 // determine rectangle to be painted from document preview
457 _CalcDocPrevwPaintRect();
458 _orDocPreviewPaintRect = maPaintedPrevwDocRect;
460 // OD 20.01.2003 #103492# - shift visible preview document area to the left,
461 // if on the right is an area left blank.
462 if ( !mbDoesLayoutColsFitIntoWindow &&
463 maPaintedPrevwDocRect.GetWidth() < maWinSize.Width() )
465 maPaintedPrevwDocRect.Move(
466 -(maWinSize.Width() - maPaintedPrevwDocRect.GetWidth()), 0 );
467 Prepare( 0, maPaintedPrevwDocRect.TopLeft(),
468 _rPxWinSize, _onStartPageNum,
469 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
472 // OD 20.01.2003 #103492# - shift visible preview document area to the top,
473 // if on the botton is an area left blank.
474 if ( mbBookPreviewModeToggled &&
475 maPaintedPrevwDocRect.Bottom() == maPreviewDocRect.Bottom() &&
476 maPaintedPrevwDocRect.GetHeight() < maWinSize.Height() )
478 if ( mbDoesLayoutRowsFitIntoWindow )
480 if ( maPaintedPrevwDocRect.GetHeight() < mnPrevwLayoutHeight)
482 maPaintedPrevwDocRect.Move(
483 0, -(mnPrevwLayoutHeight - maPaintedPrevwDocRect.GetHeight()) );
484 Prepare( 0, maPaintedPrevwDocRect.TopLeft(),
485 _rPxWinSize, _onStartPageNum,
486 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
489 else
491 maPaintedPrevwDocRect.Move(
492 0, -(maWinSize.Height() - maPaintedPrevwDocRect.GetHeight()) );
493 Prepare( 0, maPaintedPrevwDocRect.TopLeft(),
494 _rPxWinSize, _onStartPageNum,
495 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
499 // determine preview pages - visible pages with needed data for paint and
500 // accessible pages with needed data.
501 _CalcPreviewPages();
503 // OD 07.11.2003 #i22014# - indicate new layout, if print preview is in paint
504 if ( mbInPaint )
506 mbNewLayoutDuringPaint = true;
509 // validate paint data
510 mbPaintInfoValid = true;
512 // return start page
513 _onStartPageNum = mnPaintPhyStartPageNum;
515 return true;
518 /** calculate additional paint offset
520 OD 12.12.2002 #103492#
522 @author OD
524 void SwPagePreviewLayout::_CalcAdditionalPaintOffset()
526 if ( mnPrevwLayoutWidth <= maWinSize.Width() &&
527 maPaintStartPageOffset.X() <= 0 )
529 mbDoesLayoutColsFitIntoWindow = true;
530 maAdditionalPaintOffset.X() = (maWinSize.Width() - mnPrevwLayoutWidth) / 2;
532 else
534 mbDoesLayoutColsFitIntoWindow = false;
535 maAdditionalPaintOffset.X() = 0;
538 if ( mnPrevwLayoutHeight <= maWinSize.Height() &&
539 maPaintStartPageOffset.Y() <= 0 )
541 mbDoesLayoutRowsFitIntoWindow = true;
542 maAdditionalPaintOffset.Y() = (maWinSize.Height() - mnPrevwLayoutHeight) / 2;
544 else
546 mbDoesLayoutRowsFitIntoWindow = false;
547 maAdditionalPaintOffset.Y() = 0;
551 /** calculate painted preview document rectangle
553 OD 12.12.2002 #103492#
555 @author OD
557 void SwPagePreviewLayout::_CalcDocPrevwPaintRect()
559 Point aTopLeftPos = maPaintPreviewDocOffset;
560 maPaintedPrevwDocRect.SetPos( aTopLeftPos );
562 Size aSize;
563 if ( mbDoesLayoutColsFitIntoWindow )
564 //aSize.Width() = mnPrevwLayoutWidth;
565 aSize.Width() = Min( mnPrevwLayoutWidth,
566 maPreviewDocRect.GetWidth() - aTopLeftPos.X() );
567 else
568 aSize.Width() = Min( maPreviewDocRect.GetWidth() - aTopLeftPos.X(),
569 maWinSize.Width() - maAdditionalPaintOffset.X() );
570 if ( mbDoesLayoutRowsFitIntoWindow )
571 //aSize.Height() = mnPrevwLayoutHeight;
572 aSize.Height() = Min( mnPrevwLayoutHeight,
573 maPreviewDocRect.GetHeight() - aTopLeftPos.Y() );
574 else
575 aSize.Height() = Min( maPreviewDocRect.GetHeight() - aTopLeftPos.Y(),
576 maWinSize.Height() - maAdditionalPaintOffset.Y() );
577 maPaintedPrevwDocRect.SetSize( aSize );
580 /** calculate preview pages
582 OD 12.12.2002 #103492#
584 @author OD
586 void SwPagePreviewLayout::_CalcPreviewPages()
588 _ClearPrevwPageData();
590 if ( mbNoPageVisible )
591 return;
593 // determine start page frame
594 const SwPageFrm* pStartPage = mrLayoutRootFrm.GetPageByPageNum( mnPaintPhyStartPageNum );
596 // calculate initial paint offset
597 Point aInitialPaintOffset;
598 if ( maPaintStartPageOffset != Point( -1, -1 ) )
599 aInitialPaintOffset = Point(0,0) - maPaintStartPageOffset;
600 else
601 aInitialPaintOffset = Point( mnXFree, mnYFree );
602 aInitialPaintOffset += maAdditionalPaintOffset;
604 // prepare loop data
605 const SwPageFrm* pPage = pStartPage;
606 sal_uInt16 nCurrCol = mnPaintStartCol;
607 sal_uInt16 nConsideredRows = 0;
608 Point aCurrPaintOffset = aInitialPaintOffset;
609 // loop on pages to determine preview background retangles
610 while ( pPage &&
611 (!mbDoesLayoutRowsFitIntoWindow || nConsideredRows < mnRows) &&
612 aCurrPaintOffset.Y() < maWinSize.Height()
615 if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() )
617 pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
618 continue;
621 pPage->Calc();
623 // consider only pages, which have to be painted.
624 if ( nCurrCol < mnPaintStartCol )
626 // calculate data of unvisible page needed for accessibility
627 PrevwPage* pPrevwPage = new PrevwPage;
628 Point aCurrAccOffset = aCurrPaintOffset -
629 Point( (mnPaintStartCol-nCurrCol) * mnColWidth, 0 );
630 _CalcPreviewDataForPage( *(pPage), aCurrAccOffset, pPrevwPage );
631 pPrevwPage->bVisible = false;
632 maPrevwPages.push_back( pPrevwPage );
633 // continue with next page and next column
634 pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
635 ++nCurrCol;
636 continue;
638 if ( aCurrPaintOffset.X() < maWinSize.Width() )
640 // OD 19.02.2003 #107369# - leaving left-top-corner blank is
641 // controlled by <mbBookPreview>.
642 if ( mbBookPreview && pPage->GetPhyPageNum() == 1 && mnCols != 1 && nCurrCol == 1
645 // first page in 2nd column
646 // --> continue with increased paint offset and next column
647 aCurrPaintOffset.X() += mnColWidth;
648 ++nCurrCol;
649 continue;
652 // calculate data of visible page
653 PrevwPage* pPrevwPage = new PrevwPage;
654 _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPrevwPage );
655 pPrevwPage->bVisible = true;
656 maPrevwPages.push_back( pPrevwPage );
658 else
660 // calculate data of unvisible page needed for accessibility
661 PrevwPage* pPrevwPage = new PrevwPage;
662 _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPrevwPage );
663 pPrevwPage->bVisible = false;
664 maPrevwPages.push_back( pPrevwPage );
667 // prepare data for next loop
668 pPage = static_cast<const SwPageFrm*>(pPage->GetNext());
670 aCurrPaintOffset.X() += mnColWidth;
671 ++nCurrCol;
672 if ( nCurrCol > mnCols )
674 ++nConsideredRows;
675 aCurrPaintOffset.X() = aInitialPaintOffset.X();
676 nCurrCol = 1;
677 aCurrPaintOffset.Y() += mnRowHeight;
682 /** determines preview data for a given page and a given preview offset
684 OD 13.12.2002 #103492#
686 @author OD
688 bool SwPagePreviewLayout::_CalcPreviewDataForPage( const SwPageFrm& _rPage,
689 const Point& _rPrevwOffset,
690 PrevwPage* _opPrevwPage )
692 // page frame
693 _opPrevwPage->pPage = &_rPage;
694 // size of page frame
695 if ( _rPage.IsEmptyPage() )
697 if ( _rPage.GetPhyPageNum() % 2 == 0 )
698 _opPrevwPage->aPageSize = _rPage.GetPrev()->Frm().SSize();
699 else
700 _opPrevwPage->aPageSize = _rPage.GetNext()->Frm().SSize();
702 else
703 _opPrevwPage->aPageSize = _rPage.Frm().SSize();
704 // position of page in preview window
705 Point aPrevwWinOffset( _rPrevwOffset );
706 if ( _opPrevwPage->aPageSize.Width() < maMaxPageSize.Width() )
707 aPrevwWinOffset.X() += ( maMaxPageSize.Width() - _opPrevwPage->aPageSize.Width() ) / 2;
708 if ( _opPrevwPage->aPageSize.Height() < maMaxPageSize.Height() )
709 aPrevwWinOffset.Y() += ( maMaxPageSize.Height() - _opPrevwPage->aPageSize.Height() ) / 2;
710 _opPrevwPage->aPrevwWinPos = aPrevwWinOffset;
711 // logic position of page and mapping offset for paint
712 if ( _rPage.IsEmptyPage() )
714 _opPrevwPage->aLogicPos = _opPrevwPage->aPrevwWinPos;
715 _opPrevwPage->aMapOffset = Point( 0, 0 );
717 else
719 _opPrevwPage->aLogicPos = _rPage.Frm().Pos();
720 _opPrevwPage->aMapOffset = _opPrevwPage->aPrevwWinPos - _opPrevwPage->aLogicPos;
723 return true;
726 /** enable/disable book preview
728 OD 2004-03-04 #i18143#
730 @author OD
732 bool SwPagePreviewLayout::SetBookPreviewMode( const bool _bEnableBookPreview,
733 sal_uInt16& _onStartPageNum,
734 Rectangle& _orDocPreviewPaintRect )
736 bool bRet = false;
738 if ( mbBookPreview != _bEnableBookPreview)
740 mbBookPreview = _bEnableBookPreview;
741 // re-initialize page preview layout
742 ReInit();
743 // re-prepare page preview layout
745 mbBookPreviewModeToggled = true;
746 Point aProposedStartPos( maPaintPreviewDocOffset );
747 // if proposed start position is below virtual preview document
748 // bottom, adjust it to the virtual preview document bottom
749 if ( aProposedStartPos.Y() > maPreviewDocRect.Bottom() )
751 aProposedStartPos.Y() = maPreviewDocRect.Bottom();
753 Prepare( 0, aProposedStartPos,
754 mrParentViewShell.GetOut()->LogicToPixel( maWinSize ),
755 _onStartPageNum, _orDocPreviewPaintRect );
756 mbBookPreviewModeToggled = false;
759 bRet = true;
762 return bRet;
765 // =============================================================================
766 // methods to determine new data for changing the current shown part of the
767 // document preview.
768 // =============================================================================
769 /** calculate start position for new scale
771 OD 12.12.2002 #103492#
773 @author OD
775 Point SwPagePreviewLayout::GetPreviewStartPosForNewScale(
776 const Fraction& _aNewScale,
777 const Fraction& _aOldScale,
778 const Size& _aNewWinSize ) const
780 Point aNewPaintStartPos = maPaintedPrevwDocRect.TopLeft();
781 if ( _aNewScale < _aOldScale )
783 // increase paint width by moving start point to left.
784 if ( mnPrevwLayoutWidth < _aNewWinSize.Width() )
785 aNewPaintStartPos.X() = 0;
786 else if ( maPaintedPrevwDocRect.GetWidth() < _aNewWinSize.Width() )
788 aNewPaintStartPos.X() -=
789 (_aNewWinSize.Width() - maPaintedPrevwDocRect.GetWidth()) / 2;
790 if ( aNewPaintStartPos.X() < 0)
791 aNewPaintStartPos.X() = 0;
794 if ( !mbDoesLayoutRowsFitIntoWindow )
796 // increase paint height by moving start point to top.
797 if ( mnPrevwLayoutHeight < _aNewWinSize.Height() )
799 aNewPaintStartPos.Y() =
800 ( (mnPaintStartRow - 1) * mnRowHeight );
802 else if ( maPaintedPrevwDocRect.GetHeight() < _aNewWinSize.Height() )
804 aNewPaintStartPos.Y() -=
805 (_aNewWinSize.Height() - maPaintedPrevwDocRect.GetHeight()) / 2;
806 if ( aNewPaintStartPos.Y() < 0)
807 aNewPaintStartPos.Y() = 0;
811 else
813 // decrease paint width by moving start point to right
814 if ( maPaintedPrevwDocRect.GetWidth() > _aNewWinSize.Width() )
815 aNewPaintStartPos.X() +=
816 (maPaintedPrevwDocRect.GetWidth() - _aNewWinSize.Width()) / 2;
817 // decrease paint height by moving start point to bottom
818 if ( maPaintedPrevwDocRect.GetHeight() > _aNewWinSize.Height() )
820 aNewPaintStartPos.Y() +=
821 (maPaintedPrevwDocRect.GetHeight() - _aNewWinSize.Height()) / 2;
822 // check, if new y-position is outside document preview
823 if ( aNewPaintStartPos.Y() > maPreviewDocRect.Bottom() )
824 aNewPaintStartPos.Y() =
825 Max( 0L, maPreviewDocRect.Bottom() - mnPrevwLayoutHeight );
829 return aNewPaintStartPos;
832 /** determines, if page with given page number is visible in preview
834 OD 12.12.2002 #103492#
836 @author OD, _nPageNum is absolut!
838 bool SwPagePreviewLayout::IsPageVisible( const sal_uInt16 _nPageNum ) const
840 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum );
841 return pPrevwPage && pPrevwPage->bVisible;
844 /** calculate data to bring new selected page into view.
846 OD 12.12.2002 #103492#
848 @author OD, IN/OUT parameters are absolute page numbers!!!
850 bool SwPagePreviewLayout::CalcStartValuesForSelectedPageMove(
851 const sal_Int16 _nHoriMove,
852 const sal_Int16 _nVertMove,
853 sal_uInt16& _orNewSelectedPage,
854 sal_uInt16& _orNewStartPage,
855 Point& _orNewStartPos ) const
857 // determine position of current selected page
858 sal_uInt16 nTmpRelSelPageNum = ConvertAbsoluteToRelativePageNum( mnSelectedPageNum );
859 sal_uInt16 nNewRelSelectedPageNum = nTmpRelSelPageNum;
861 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
862 // by <mbBookPreview>.
863 if ( mbBookPreview )
865 // Note: consider that left-top-corner is left blank --> +1
866 ++nTmpRelSelPageNum;
868 sal_uInt16 nTmpCol = nTmpRelSelPageNum % mnCols;
869 sal_uInt16 nCurrRow = nTmpRelSelPageNum / mnCols;
870 if ( nTmpCol > 0 )
871 ++nCurrRow;
873 // determine new selected page number
875 if ( _nHoriMove != 0 )
877 if ( (nNewRelSelectedPageNum + _nHoriMove) < 1 )
878 nNewRelSelectedPageNum = 1;
879 else if ( (nNewRelSelectedPageNum + _nHoriMove) > mnPages )
880 nNewRelSelectedPageNum = mnPages;
881 else
882 nNewRelSelectedPageNum = nNewRelSelectedPageNum + _nHoriMove;
884 if ( _nVertMove != 0 )
886 if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) < 1 )
887 nNewRelSelectedPageNum = 1;
888 else if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) > mnPages )
889 nNewRelSelectedPageNum = mnPages;
890 else
891 nNewRelSelectedPageNum += ( _nVertMove * mnCols );
895 sal_uInt16 nNewStartPage = mnPaintPhyStartPageNum;
896 Point aNewStartPos = Point(0,0);
898 sal_uInt16 nNewAbsSelectedPageNum = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum );
899 if ( !IsPageVisible( nNewAbsSelectedPageNum ) )
901 if ( _nHoriMove != 0 && _nVertMove != 0 )
903 ASSERT( false, "missing implementation for moving preview selected page horizontal AND vertical");
904 return false;
907 // new selected page has to be brought into view considering current
908 // visible preview.
909 sal_Int16 nTotalRows = GetRowOfPage( mnPages );
910 if ( (_nHoriMove > 0 || _nVertMove > 0) &&
911 mbDoesLayoutRowsFitIntoWindow &&
912 mbDoesLayoutColsFitIntoWindow && // OD 20.02.2003 #107369# - add condition
913 nCurrRow > nTotalRows - mnRows )
915 // new proposed start page = left-top-corner of last possible
916 // preview page.
917 nNewStartPage = (nTotalRows - mnRows) * mnCols + 1;
918 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
919 // by <mbBookPreview>.
920 if ( mbBookPreview )
922 // Note: decrease new proposed start page number by one,
923 // because of blank left-top-corner
924 --nNewStartPage;
926 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewStartPage );
928 else
930 // new proposed start page = new selected page.
931 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum );
935 _orNewSelectedPage = nNewAbsSelectedPageNum;
936 _orNewStartPage = nNewStartPage;
937 _orNewStartPos = aNewStartPos;
939 return true;
942 /** checks, if given position is inside a shown document page
944 OD 17.12.2002 #103492#
946 @author OD
948 struct PrevwPosInsidePagePred
950 const Point mnPrevwPos;
951 PrevwPosInsidePagePred( const Point _nPrevwPos ) : mnPrevwPos( _nPrevwPos ) {};
952 bool operator() ( const PrevwPage* _pPrevwPage )
954 if ( _pPrevwPage->bVisible )
956 Rectangle aPrevwPageRect( _pPrevwPage->aPrevwWinPos, _pPrevwPage->aPageSize );
957 return aPrevwPageRect.IsInside( mnPrevwPos ) ? true : false;
959 else
960 return false;
964 bool SwPagePreviewLayout::IsPrevwPosInDocPrevwPage( const Point _aPrevwPos,
965 Point& _orDocPos,
966 bool& _obPosInEmptyPage,
967 sal_uInt16& _onPageNum ) const
969 bool bIsPosInsideDoc;
971 // initialize variable parameter values.
972 _orDocPos.X() = 0;
973 _orDocPos.Y() = 0;
974 _obPosInEmptyPage = false;
975 _onPageNum = 0;
977 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter =
978 std::find_if( maPrevwPages.begin(), maPrevwPages.end(),
979 PrevwPosInsidePagePred( _aPrevwPos ) );
981 if ( aFoundPrevwPageIter == maPrevwPages.end() )
982 // given preview position outside a document page.
983 bIsPosInsideDoc = false;
984 else
986 _onPageNum = (*aFoundPrevwPageIter)->pPage->GetPhyPageNum();
987 if ( (*aFoundPrevwPageIter)->pPage->IsEmptyPage() )
989 // given preview position inside an empty page
990 bIsPosInsideDoc = false;
991 _obPosInEmptyPage = true;
993 else
995 // given preview position inside a normal page
996 bIsPosInsideDoc = true;
997 _orDocPos = _aPrevwPos -
998 (*aFoundPrevwPageIter)->aPrevwWinPos +
999 (*aFoundPrevwPageIter)->aLogicPos;
1003 return bIsPosInsideDoc;
1006 /** determine window page scroll amount
1008 OD 17.12.2002 #103492#
1010 @author OD
1012 SwTwips SwPagePreviewLayout::GetWinPagesScrollAmount(
1013 const sal_Int16 _nWinPagesToScroll ) const
1015 SwTwips nScrollAmount;
1016 if ( mbDoesLayoutRowsFitIntoWindow )
1018 nScrollAmount = (mnPrevwLayoutHeight - mnYFree) * _nWinPagesToScroll;
1020 else
1021 nScrollAmount = _nWinPagesToScroll * maPaintedPrevwDocRect.GetHeight();
1023 // OD 19.02.2003 #107369# - check, if preview layout size values are valid.
1024 // If not, the checks for an adjustment of the scroll amount aren't useful.
1025 if ( mbLayoutSizesValid )
1027 if ( (maPaintedPrevwDocRect.Top() + nScrollAmount) <= 0 )
1028 nScrollAmount = -maPaintedPrevwDocRect.Top();
1030 // OD 14.02.2003 #107369# - correct scroll amount
1031 if ( nScrollAmount > 0 &&
1032 maPaintedPrevwDocRect.Bottom() == maPreviewDocRect.Bottom()
1035 nScrollAmount = 0;
1037 else
1039 while ( (maPaintedPrevwDocRect.Top() + nScrollAmount + mnYFree) >= maPreviewDocRect.GetHeight() )
1041 nScrollAmount -= mnRowHeight;
1046 return nScrollAmount;
1049 // =============================================================================
1050 // methods to paint page preview layout
1051 // =============================================================================
1052 /** paint prepared preview
1054 OD 12.12.2002 #103492#
1056 @author OD
1058 bool SwPagePreviewLayout::Paint( const Rectangle _aOutRect ) const
1060 // check environment and parameters
1062 if ( !mrParentViewShell.GetWin() &&
1063 !mrParentViewShell.GetOut()->GetConnectMetaFile() )
1064 return false;
1066 ASSERT( mbPaintInfoValid,
1067 "invalid preview settings - no paint of preview" );
1068 if ( !mbPaintInfoValid )
1069 return false;
1072 // OD 17.11.2003 #i22014# - no paint, if <superfluous> flag is set at layout
1073 if ( mrLayoutRootFrm.IsSuperfluous() )
1075 return true;
1078 // environment and parameter ok
1080 // OD 07.11.2003 #i22014#
1081 if ( mbInPaint )
1083 return false;
1085 mbInPaint = true;
1087 OutputDevice* pOutputDev = mrParentViewShell.GetOut();
1089 // prepare paint
1090 if ( maPrevwPages.size() > 0 )
1092 mrParentViewShell.Imp()->bFirstPageInvalid = FALSE;
1093 mrParentViewShell.Imp()->pFirstVisPage =
1094 const_cast<SwPageFrm*>(maPrevwPages[0]->pPage);
1097 // paint preview background
1099 SwRegionRects aPreviewBackgrdRegion( _aOutRect );
1100 // calculate preview background rectangles
1101 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin();
1102 aPageIter != maPrevwPages.end();
1103 ++aPageIter )
1105 if ( (*aPageIter)->bVisible )
1107 aPreviewBackgrdRegion -=
1108 SwRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize );
1111 // paint preview background rectangles
1112 mrParentViewShell._PaintDesktop( aPreviewBackgrdRegion );
1115 // prepare data for paint of pages
1116 const Rectangle aPxOutRect( pOutputDev->LogicToPixel( _aOutRect ) );
1118 MapMode aMapMode( pOutputDev->GetMapMode() );
1119 MapMode aSavedMapMode = aMapMode;
1121 const Font& rEmptyPgFont = SwPageFrm::GetEmptyPageFont();
1123 Color aEmptyPgShadowBorderColor = SwViewOption::GetFontColor();
1125 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin();
1126 aPageIter != maPrevwPages.end();
1127 ++aPageIter )
1129 if ( !(*aPageIter)->bVisible )
1130 continue;
1132 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize );
1133 aMapMode.SetOrigin( (*aPageIter)->aMapOffset );
1134 pOutputDev->SetMapMode( aMapMode );
1135 Rectangle aPxPaintRect = pOutputDev->LogicToPixel( aPageRect );
1136 if ( aPxOutRect.IsOver( aPxPaintRect) )
1138 if ( (*aPageIter)->pPage->IsEmptyPage() )
1140 const Color aRetouche( mrParentViewShell.Imp()->GetRetoucheColor() );
1141 if( pOutputDev->GetFillColor() != aRetouche )
1142 pOutputDev->SetFillColor( aRetouche );
1143 pOutputDev->SetLineColor(); // OD 20.02.2003 #107369# - no line color
1144 // OD 20.02.2003 #107369# - use aligned page rectangle
1146 SwRect aTmpPageRect( aPageRect );
1147 ::SwAlignRect( aTmpPageRect, &mrParentViewShell);
1148 aPageRect = aTmpPageRect.SVRect();
1150 pOutputDev->DrawRect( aPageRect );
1152 // paint empty page text
1153 Font aOldFont( pOutputDev->GetFont() );
1154 pOutputDev->SetFont( rEmptyPgFont );
1155 pOutputDev->DrawText( aPageRect, SW_RESSTR( STR_EMPTYPAGE ),
1156 TEXT_DRAW_VCENTER |
1157 TEXT_DRAW_CENTER |
1158 TEXT_DRAW_CLIP );
1159 pOutputDev->SetFont( aOldFont );
1160 // paint shadow and border for empty page
1161 // OD 19.02.2003 #107369# - use new method to paint page border and
1162 // shadow
1163 SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, true );
1165 else
1167 mrParentViewShell.aVisArea = aPageRect;
1168 aPxPaintRect.Intersection( aPxOutRect );
1169 Rectangle aPaintRect = pOutputDev->PixelToLogic( aPxPaintRect );
1170 mrParentViewShell.Paint( aPaintRect );
1171 // --> OD 2007-08-15 #i80691#
1172 // paint page border and shadow
1174 SwRect aPageBorderRect;
1175 SwPageFrm::GetBorderAndShadowBoundRect( SwRect( aPageRect ), &mrParentViewShell, aPageBorderRect, true );
1176 const Region aDLRegion(aPageBorderRect.SVRect());
1177 mrParentViewShell.DLPrePaint2(aDLRegion);
1178 SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, true );
1179 mrParentViewShell.DLPostPaint2(true);
1181 // <--
1183 // OD 07.11.2003 #i22014# - stop painting, because new print
1184 // preview layout is created during paint.
1185 if ( mbNewLayoutDuringPaint )
1187 break;
1190 if ( (*aPageIter)->pPage->GetPhyPageNum() == mnSelectedPageNum )
1192 _PaintSelectMarkAtPage( (*aPageIter) );
1198 // OD 17.11.2003 #i22014# - no update of accessible preview, if a new
1199 // print preview layout is created during paint.
1200 if ( !mbNewLayoutDuringPaint )
1202 // update at accessiblilty interface
1203 mrParentViewShell.Imp()->UpdateAccessiblePreview(
1204 maPrevwPages,
1205 aMapMode.GetScaleX(),
1206 mrLayoutRootFrm.GetPageByPageNum( mnSelectedPageNum ),
1207 maWinSize );
1210 pOutputDev->SetMapMode( aSavedMapMode );
1211 mrParentViewShell.aVisArea.Clear();
1213 // OD 07.11.2003 #i22014#
1214 mbInPaint = false;
1215 mbNewLayoutDuringPaint = false;
1217 return true;
1220 /** repaint pages on page preview
1222 OD 18.12.2002 #103492#
1224 @author OD
1226 void SwPagePreviewLayout::Repaint( const Rectangle _aInvalidCoreRect ) const
1228 // check environment and parameters
1230 if ( !mrParentViewShell.GetWin() &&
1231 !mrParentViewShell.GetOut()->GetConnectMetaFile() )
1232 return;
1234 ASSERT( mbPaintInfoValid,
1235 "invalid preview settings - no paint of preview" );
1236 if ( !mbPaintInfoValid )
1237 return;
1240 // environment and parameter ok
1242 // prepare paint
1243 if ( maPrevwPages.size() > 0 )
1245 mrParentViewShell.Imp()->bFirstPageInvalid = FALSE;
1246 mrParentViewShell.Imp()->pFirstVisPage =
1247 const_cast<SwPageFrm*>(maPrevwPages[0]->pPage);
1250 // invalidate visible pages, which overlap the invalid core rectangle
1251 for ( std::vector<PrevwPage*>::const_iterator aPageIter = maPrevwPages.begin();
1252 aPageIter != maPrevwPages.end();
1253 ++aPageIter )
1255 if ( !(*aPageIter)->bVisible )
1256 continue;
1258 Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize );
1259 if ( _aInvalidCoreRect.IsOver( aPageRect ) )
1261 aPageRect.Intersection( _aInvalidCoreRect );
1262 Rectangle aInvalidPrevwRect = aPageRect;
1263 aInvalidPrevwRect.SetPos( aInvalidPrevwRect.TopLeft() -
1264 (*aPageIter)->aLogicPos +
1265 (*aPageIter)->aPrevwWinPos );
1266 mrParentViewShell.GetWin()->Invalidate( aInvalidPrevwRect );
1271 /** paint selection mark at page
1273 OD 17.12.2002 #103492#
1275 @author OD
1277 void SwPagePreviewLayout::_PaintSelectMarkAtPage(
1278 const PrevwPage* _aSelectedPrevwPage ) const
1280 OutputDevice* pOutputDev = mrParentViewShell.GetOut();
1281 MapMode aMapMode( pOutputDev->GetMapMode() );
1282 // save mapping mode of output device
1283 MapMode aSavedMapMode = aMapMode;
1284 // save fill and line color of output device
1285 Color aFill( pOutputDev->GetFillColor() );
1286 Color aLine( pOutputDev->GetLineColor() );
1288 // determine selection mark color
1289 Color aSelPgLineColor(COL_LIGHTBLUE);
1290 const StyleSettings& rSettings =
1291 mrParentViewShell.GetWin()->GetSettings().GetStyleSettings();
1292 if ( rSettings.GetHighContrastMode() )
1293 aSelPgLineColor = rSettings.GetHighlightTextColor();
1295 // set needed mapping mode at output device
1296 aMapMode.SetOrigin( _aSelectedPrevwPage->aMapOffset );
1297 pOutputDev->SetMapMode( aMapMode );
1299 // calculate page rectangle in pixel coordinates
1300 SwRect aPageRect( _aSelectedPrevwPage->aLogicPos,
1301 _aSelectedPrevwPage->aPageSize );
1302 // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for
1303 // page border and shadow paint - see <SwPageFrm::PaintBorderAndShadow(..)>
1304 ::SwAlignRect( aPageRect, &mrParentViewShell);
1305 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() );
1307 // draw two rectangle
1308 // OD 19.02.2003 #107369# - adjust position of select mark rectangle
1309 Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(),
1310 aPxPageRect.Right(), aPxPageRect.Bottom() );
1311 aRect = pOutputDev->PixelToLogic( aRect );
1312 pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color
1313 pOutputDev->SetLineColor( aSelPgLineColor );
1314 pOutputDev->DrawRect( aRect );
1315 // OD 19.02.2003 #107369# - adjust position of select mark rectangle
1316 aRect = Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1,
1317 aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 );
1318 aRect = pOutputDev->PixelToLogic( aRect );
1319 pOutputDev->DrawRect( aRect );
1321 // reset fill and line color of output device
1322 pOutputDev->SetFillColor( aFill );
1323 pOutputDev->SetLineColor( aLine );
1325 // reset mapping mode of output device
1326 pOutputDev->SetMapMode( aSavedMapMode );
1329 /** paint to mark new selected page
1331 OD 17.12.2002 #103492#
1332 Perform paint for current selected page in order to unmark it.
1333 Set new selected page and perform paint to mark this page.
1335 @author OD, _nSelectedPage, mnSelectedPage are absolut
1337 void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage )
1339 sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum;
1340 mnSelectedPageNum = _nSelectedPage;
1342 // re-paint for current selected page in order to umark it.
1343 const PrevwPage* pOldSelectedPrevwPage = _GetPrevwPageByPageNum( nOldSelectedPageNum );
1344 if ( pOldSelectedPrevwPage && pOldSelectedPrevwPage->bVisible )
1346 // OD 20.02.2003 #107369# - invalidate only areas of selection mark.
1347 SwRect aPageRect( pOldSelectedPrevwPage->aPrevwWinPos,
1348 pOldSelectedPrevwPage->aPageSize );
1349 ::SwAlignRect( aPageRect, &mrParentViewShell);
1350 OutputDevice* pOutputDev = mrParentViewShell.GetOut();
1351 Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() );
1352 // invalidate top mark line
1353 Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(),
1354 aPxPageRect.Right(), aPxPageRect.Top()+1 );
1355 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1356 // invalidate right mark line
1357 aInvalPxRect = Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(),
1358 aPxPageRect.Right(), aPxPageRect.Bottom() );
1359 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1360 // invalidate bottom mark line
1361 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1,
1362 aPxPageRect.Right(), aPxPageRect.Bottom() );
1363 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1364 // invalidate left mark line
1365 aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Top(),
1366 aPxPageRect.Left()+1, aPxPageRect.Bottom() );
1367 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1370 // re-paint for new selected page in order to mark it.
1371 const PrevwPage* pNewSelectedPrevwPage = _GetPrevwPageByPageNum( _nSelectedPage );
1372 if ( pNewSelectedPrevwPage && pNewSelectedPrevwPage->bVisible )
1373 _PaintSelectMarkAtPage( pNewSelectedPrevwPage );
1377 // =============================================================================
1378 // helper methods
1379 // =============================================================================
1380 /** get preview page by physical page number
1382 OD 17.12.2002 #103492#
1384 @author OD
1386 struct EqualsPageNumPred
1388 const sal_uInt16 mnPageNum;
1389 EqualsPageNumPred( const sal_uInt16 _nPageNum ) : mnPageNum( _nPageNum ) {};
1390 bool operator() ( const PrevwPage* _pPrevwPage )
1392 return _pPrevwPage->pPage->GetPhyPageNum() == mnPageNum;
1396 const PrevwPage* SwPagePreviewLayout::_GetPrevwPageByPageNum( const sal_uInt16 _nPageNum ) const
1398 std::vector<PrevwPage*>::const_iterator aFoundPrevwPageIter =
1399 std::find_if( maPrevwPages.begin(), maPrevwPages.end(),
1400 EqualsPageNumPred( _nPageNum ) );
1402 if ( aFoundPrevwPageIter == maPrevwPages.end() )
1403 return 0;
1404 else
1405 return (*aFoundPrevwPageIter);
1408 /** determine row the page with the given number is in
1410 OD 17.01.2003 #103492#
1412 @author OD, _nPageNum is relative
1414 sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const
1416 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
1417 // by <mbBookPreview>.
1418 if ( mbBookPreview )
1420 // Note: increase given physical page number by one, because left-top-corner
1421 // in the preview layout is left blank.
1422 ++_nPageNum;
1425 sal_uInt16 nRow = (_nPageNum) / mnCols;
1426 if ( ( (_nPageNum) % mnCols ) > 0 )
1427 ++nRow;
1429 return nRow;
1432 /** determine column the page with the given number is in
1434 OD 17.01.2003 #103492#
1436 @author OD, _nPageNum is relative
1438 sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const
1440 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
1441 // by <mbBookPreview>.
1442 if ( mbBookPreview )
1444 // Note: increase given physical page number by one, because left-top-corner
1445 // in the preview layout is left blank.
1446 ++_nPageNum;
1449 sal_uInt16 nCol = (_nPageNum) % mnCols;
1450 if ( nCol == 0 )
1451 nCol = mnCols;
1453 return nCol;
1456 Size SwPagePreviewLayout::GetMaxPageSize() const
1458 ASSERT( PreviewLayoutValid(), "PagePreviewLayout not valid" );
1459 return maMaxPageSize;
1462 Size SwPagePreviewLayout::GetPrevwDocSize() const
1464 ASSERT( PreviewLayoutValid(), "PagePreviewLayout not valid" );
1465 return maPreviewDocRect.GetSize();
1468 /** get size of a preview page by its physical page number
1470 OD 15.01.2003 #103492#
1472 @author OD
1474 Size SwPagePreviewLayout::GetPrevwPageSizeByPageNum( sal_uInt16 _nPageNum ) const
1476 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum );
1477 if ( pPrevwPage )
1479 return pPrevwPage->aPageSize;
1481 else
1483 return Size( 0, 0 );
1487 /** get virtual page number by its physical page number
1489 OD 21.03.2003 #108282#
1491 @author OD
1493 sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const
1495 const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum );
1496 if ( pPrevwPage )
1498 return pPrevwPage->pPage->GetVirtPageNum();
1500 else
1502 return 0;
1506 /** Convert absolute to relative page numbers (see PrintEmptyPages)
1508 @author FME
1510 sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const
1512 if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum )
1514 return _nAbsPageNum;
1517 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower());
1519 sal_uInt16 nRet = 1;
1521 while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum )
1523 if ( !pTmpPage->IsEmptyPage() )
1524 ++nRet;
1526 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() );
1529 return nRet;
1532 /** Convert relative to absolute page numbers (see PrintEmptyPages)
1534 @author FME
1536 sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const
1538 if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum )
1540 return _nRelPageNum;
1543 const SwPageFrm* pTmpPage = static_cast<const SwPageFrm*>(mrLayoutRootFrm.Lower());
1544 const SwPageFrm* pRet = 0;
1546 USHORT i = 0;
1547 while( pTmpPage && i != _nRelPageNum )
1549 if ( !pTmpPage->IsEmptyPage() )
1550 ++i;
1552 pRet = pTmpPage;
1553 pTmpPage = static_cast<const SwPageFrm*>( pTmpPage->GetNext() );
1556 return pRet->GetPhyPageNum();