/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include #ifndef _PREVWPAGE_HXX #include #endif #include #include #include #include #include #include #include #include #ifndef _COMCORE_HRC #include #endif // OD 19.02.2003 #107369# - method #include // OD 24.09.2003 #i19975# #include #include #include // OD 20.02.2003 #107369# - method to update statics for paint // Note: method defined in '/sw/source/core/layout/paintfrm.cxx' extern void SwCalcPixStatics( OutputDevice *pOut ); // ============================================================================= // methods to initialize page preview layout // ============================================================================= SwPagePreviewLayout::SwPagePreviewLayout( ViewShell& _rParentViewShell, const SwRootFrm& _rLayoutRootFrm ) : mnXFree ( 4*142 ), mnYFree ( 4*142 ), mrParentViewShell( _rParentViewShell ), mrLayoutRootFrm ( _rLayoutRootFrm ) { _Clear(); // OD 2004-03-05 #i18143# mbBookPreview = false; mbBookPreviewModeToggled = false; mbPrintEmptyPages = mrParentViewShell.getIDocumentDeviceAccess()->getPrintData().IsPrintEmptyPages(); } void SwPagePreviewLayout::_Clear() { mbLayoutInfoValid = mbLayoutSizesValid = mbPaintInfoValid = false; maWinSize.Width() = 0; maWinSize.Height() = 0; mnCols = mnRows = 0; _ClearPrevwLayoutSizes(); mbDoesLayoutRowsFitIntoWindow = false; mbDoesLayoutColsFitIntoWindow = false; mnPaintPhyStartPageNum = 0; mnPaintStartCol = mnPaintStartRow = 0; mbNoPageVisible = false; maPaintStartPageOffset.X() = 0; maPaintStartPageOffset.Y() = 0; maPaintPreviewDocOffset.X() = 0; maPaintPreviewDocOffset.Y() = 0; maAdditionalPaintOffset.X() = 0; maAdditionalPaintOffset.Y() = 0; maPaintedPrevwDocRect.Left() = 0; maPaintedPrevwDocRect.Top() = 0; maPaintedPrevwDocRect.Right() = 0; maPaintedPrevwDocRect.Bottom() = 0; mnSelectedPageNum = 0; _ClearPrevwPageData(); // OD 07.11.2003 #i22014# mbInPaint = false; mbNewLayoutDuringPaint = false; } void SwPagePreviewLayout::_ClearPrevwLayoutSizes() { mnPages = 0; maMaxPageSize.Width() = 0; maMaxPageSize.Height() = 0; maPreviewDocRect.Left() = maPreviewDocRect.Top() = 0; maPreviewDocRect.Right() = maPreviewDocRect.Bottom() = 0; mnColWidth = mnRowHeight = 0; mnPrevwLayoutWidth = mnPrevwLayoutHeight = 0; } void SwPagePreviewLayout::_ClearPrevwPageData() { for ( std::vector::iterator aPageDelIter = maPrevwPages.begin(); aPageDelIter != maPrevwPages.end(); ++aPageDelIter ) { delete (*aPageDelIter); } maPrevwPages.clear(); } /** calculate page preview layout sizes OD 18.12.2002 #103492# @author OD */ void SwPagePreviewLayout::_CalcPrevwLayoutSizes() { // calculate maximal page size; calculate also number of pages const SwPageFrm* pPage = static_cast(mrLayoutRootFrm.Lower()); while ( pPage ) { if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() ) { pPage = static_cast(pPage->GetNext()); continue; } ++mnPages; pPage->Calc(); const Size& rPageSize = pPage->Frm().SSize(); if ( rPageSize.Width() > maMaxPageSize.Width() ) maMaxPageSize.Width() = rPageSize.Width(); if ( rPageSize.Height() > maMaxPageSize.Height() ) maMaxPageSize.Height() = rPageSize.Height(); pPage = static_cast(pPage->GetNext()); } // calculate and set column width and row height mnColWidth = maMaxPageSize.Width() + mnXFree; mnRowHeight = maMaxPageSize.Height() + mnYFree; // calculate and set preview layout width and height mnPrevwLayoutWidth = mnCols * mnColWidth + mnXFree; mnPrevwLayoutHeight = mnRows * mnRowHeight + mnYFree; // calculate document rectangle in preview layout { Size aDocSize; // document width aDocSize.Width() = mnPrevwLayoutWidth; // document height // determine number of rows needed for in preview layout // OD 19.02.2003 #107369# - use method . sal_uInt16 nDocRows = GetRowOfPage( mnPages ); aDocSize.Height() = nDocRows * maMaxPageSize.Height() + (nDocRows+1) * mnYFree; maPreviewDocRect.SetPos( Point( 0, 0 ) ); maPreviewDocRect.SetSize( aDocSize ); } } /** init page preview layout OD 11.12.2002 #103492# initialize the page preview settings for a given layout. side effects: (1) If parameter <_bCalcScale> is true, mapping mode with calculated scaling is set at the output device and the zoom at the view options of the given view shell is set with the calculated scaling. @author OD */ bool SwPagePreviewLayout::Init( const sal_uInt16 _nCols, const sal_uInt16 _nRows, const Size& _rPxWinSize, const bool _bCalcScale ) { // check environment and parameters { bool bColsRowsValid = (_nCols != 0) && (_nRows != 0); ASSERT( bColsRowsValid, "preview layout parameters not correct - preview layout can *not* be initialized" ); if ( !bColsRowsValid ) return false; bool bPxWinSizeValid = (_rPxWinSize.Width() >= 0) && (_rPxWinSize.Height() >= 0); ASSERT( bPxWinSizeValid, "no window size - preview layout can *not* be initialized" ); if ( !bPxWinSizeValid ) return false; } // environment and parameters OK // clear existing preview settings _Clear(); // set layout information columns and rows mnCols = _nCols; mnRows = _nRows; _CalcPrevwLayoutSizes(); // validate layout information mbLayoutInfoValid = true; if ( _bCalcScale ) { // calculate scaling MapMode aMapMode( MAP_TWIP ); Size aWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize, aMapMode ); Fraction aXScale( aWinSize.Width(), mnPrevwLayoutWidth ); Fraction aYScale( aWinSize.Height(), mnPrevwLayoutHeight ); if( aXScale < aYScale ) aYScale = aXScale; { // adjust scaling for Drawing layer. aYScale *= Fraction( 1000, 1 ); long nNewNuminator = aYScale.operator long(); if( nNewNuminator < 1 ) nNewNuminator = 1; aYScale = Fraction( nNewNuminator, 1000 ); // propagate scaling as zoom percentage to view options for font cache _ApplyNewZoomAtViewShell( static_cast(nNewNuminator/10) ); } aMapMode.SetScaleY( aYScale ); aMapMode.SetScaleX( aYScale ); // set created mapping mode with calculated scaling at output device. mrParentViewShell.GetOut()->SetMapMode( aMapMode ); // OD 20.02.2003 #107369# - update statics for paint. ::SwCalcPixStatics( mrParentViewShell.GetOut() ); } // set window size in twips maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize ); // validate layout sizes mbLayoutSizesValid = true; return true; } /** apply new zoom at given view shell OD 11.12.2002 #103492# - implementation of <_ApplyNewZoomAtViewShell> @author OD */ void SwPagePreviewLayout::_ApplyNewZoomAtViewShell( sal_uInt8 _aNewZoom ) { SwViewOption aNewViewOptions = *(mrParentViewShell.GetViewOptions()); if ( aNewViewOptions.GetZoom() != _aNewZoom ) { aNewViewOptions.SetZoom( _aNewZoom ); // OD 24.09.2003 #i19975# - consider zoom type. enum SvxZoomType eZoomType = SVX_ZOOM_PERCENT; aNewViewOptions.SetZoomType( eZoomType ); mrParentViewShell.ApplyViewOptions( aNewViewOptions ); } } /** method to adjust page preview layout to document changes OD 18.12.2002 #103492# @author OD */ bool SwPagePreviewLayout::ReInit() { // check environment and parameters { bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid; ASSERT( bLayoutSettingsValid, "no valid preview layout info/sizes - no re-init of page preview layout"); if ( !bLayoutSettingsValid ) return false; } _ClearPrevwLayoutSizes(); _CalcPrevwLayoutSizes(); return true; } // ============================================================================= // methods to prepare paint of page preview // ============================================================================= /** prepare paint of page preview OD 12.12.2002 #103492# OD 21.03.2003 #108282# - delete parameter _onStartPageVirtNum @author OD, _nProposedStartPageNum, _onStartPageNum are absolute */ bool SwPagePreviewLayout::Prepare( const sal_uInt16 _nProposedStartPageNum, const Point _aProposedStartPos, const Size& _rPxWinSize, sal_uInt16& _onStartPageNum, Rectangle& _orDocPreviewPaintRect, const bool _bStartWithPageAtFirstCol ) { sal_uInt16 nProposedStartPageNum = ConvertAbsoluteToRelativePageNum( _nProposedStartPageNum ); // check environment and parameters { bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid; ASSERT( bLayoutSettingsValid, "no valid preview layout info/sizes - no prepare of preview paint"); if ( !bLayoutSettingsValid ) return false; bool bStartPageRangeValid = nProposedStartPageNum <= mnPages; ASSERT( bStartPageRangeValid, "proposed start page not existing - no prepare of preview paint"); if ( !bStartPageRangeValid ) return false; bool bStartPosRangeValid = _aProposedStartPos.X() >= 0 && _aProposedStartPos.Y() >= 0 && _aProposedStartPos.X() <= maPreviewDocRect.Right() && _aProposedStartPos.Y() <= maPreviewDocRect.Bottom(); ASSERT( bStartPosRangeValid, "proposed start position out of range - no prepare of preview paint"); if ( !bStartPosRangeValid ) return false; bool bWinSizeValid = _rPxWinSize.Width() != 0 && _rPxWinSize.Height() != 0; ASSERT ( bWinSizeValid, "no window size - no prepare of preview paint"); if ( !bWinSizeValid ) return false; bool bStartInfoValid = _nProposedStartPageNum > 0 || _aProposedStartPos != Point(0,0); if ( !bStartInfoValid ) nProposedStartPageNum = 1; } // environment and parameter OK // update window size at preview setting data maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize ); mbNoPageVisible = false; if ( nProposedStartPageNum > 0 ) { // determine column and row of proposed start page in virtual preview layout sal_uInt16 nColOfProposed = GetColOfPage( nProposedStartPageNum ); sal_uInt16 nRowOfProposed = GetRowOfPage( nProposedStartPageNum ); // determine start page if ( _bStartWithPageAtFirstCol ) { // OD 19.02.2003 #107369# - leaving left-top-corner blank is // controlled by . if ( mbBookPreview && ( nProposedStartPageNum == 1 || nRowOfProposed == 1 ) ) mnPaintPhyStartPageNum = 1; else mnPaintPhyStartPageNum = nProposedStartPageNum - (nColOfProposed-1); } else mnPaintPhyStartPageNum = nProposedStartPageNum; mnPaintPhyStartPageNum = ConvertRelativeToAbsolutePageNum( mnPaintPhyStartPageNum ); // set starting column if ( _bStartWithPageAtFirstCol ) mnPaintStartCol = 1; else mnPaintStartCol = nColOfProposed; // set starting row mnPaintStartRow = nRowOfProposed; // page offset == (-1,-1), indicating no offset and paint of free space. maPaintStartPageOffset.X() = -1; maPaintStartPageOffset.Y() = -1; // virtual preview document offset. if ( _bStartWithPageAtFirstCol ) maPaintPreviewDocOffset.X() = 0; else maPaintPreviewDocOffset.X() = (nColOfProposed-1) * mnColWidth; maPaintPreviewDocOffset.Y() = (nRowOfProposed-1) * mnRowHeight; } else { // determine column and row of proposed start position. // Note: paint starts at point (0,0) sal_uInt16 nColOfProposed = static_cast(_aProposedStartPos.X() / mnColWidth) + 1; sal_uInt16 nRowOfProposed = static_cast(_aProposedStartPos.Y() / mnRowHeight) + 1; // determine start page == page at proposed start position // OD 19.02.2003 #107369# - leaving left-top-corner blank is // controlled by . if ( mbBookPreview && ( nRowOfProposed == 1 && nColOfProposed == 1 ) ) mnPaintPhyStartPageNum = 1; else { // OD 19.02.2003 #107369# - leaving left-top-corner blank is // controlled by . mnPaintPhyStartPageNum = (nRowOfProposed-1) * mnCols + nColOfProposed; if ( mbBookPreview ) --mnPaintPhyStartPageNum; if ( mnPaintPhyStartPageNum > mnPages ) { // no page will be visible, because shown part of document // preview is the last row to the right of the last page mnPaintPhyStartPageNum = mnPages; mbNoPageVisible = true; } } // set starting column and starting row mnPaintStartCol = nColOfProposed; mnPaintStartRow = nRowOfProposed; // page offset maPaintStartPageOffset.X() = (_aProposedStartPos.X() % mnColWidth) - mnXFree; maPaintStartPageOffset.Y() = (_aProposedStartPos.Y() % mnRowHeight) - mnYFree; // virtual preview document offset. maPaintPreviewDocOffset = _aProposedStartPos; } // determine additional paint offset, if preview layout fits into window. _CalcAdditionalPaintOffset(); // determine rectangle to be painted from document preview _CalcDocPrevwPaintRect(); _orDocPreviewPaintRect = maPaintedPrevwDocRect; // OD 20.01.2003 #103492# - shift visible preview document area to the left, // if on the right is an area left blank. if ( !mbDoesLayoutColsFitIntoWindow && maPaintedPrevwDocRect.GetWidth() < maWinSize.Width() ) { maPaintedPrevwDocRect.Move( -(maWinSize.Width() - maPaintedPrevwDocRect.GetWidth()), 0 ); Prepare( 0, maPaintedPrevwDocRect.TopLeft(), _rPxWinSize, _onStartPageNum, _orDocPreviewPaintRect, _bStartWithPageAtFirstCol ); } // OD 20.01.2003 #103492# - shift visible preview document area to the top, // if at the bottom is an area left blank. if ( mbBookPreviewModeToggled && maPaintedPrevwDocRect.Bottom() == maPreviewDocRect.Bottom() && maPaintedPrevwDocRect.GetHeight() < maWinSize.Height() ) { if ( mbDoesLayoutRowsFitIntoWindow ) { if ( maPaintedPrevwDocRect.GetHeight() < mnPrevwLayoutHeight) { maPaintedPrevwDocRect.Move( 0, -(mnPrevwLayoutHeight - maPaintedPrevwDocRect.GetHeight()) ); Prepare( 0, maPaintedPrevwDocRect.TopLeft(), _rPxWinSize, _onStartPageNum, _orDocPreviewPaintRect, _bStartWithPageAtFirstCol ); } } else { maPaintedPrevwDocRect.Move( 0, -(maWinSize.Height() - maPaintedPrevwDocRect.GetHeight()) ); Prepare( 0, maPaintedPrevwDocRect.TopLeft(), _rPxWinSize, _onStartPageNum, _orDocPreviewPaintRect, _bStartWithPageAtFirstCol ); } } // determine preview pages - visible pages with needed data for paint and // accessible pages with needed data. _CalcPreviewPages(); // OD 07.11.2003 #i22014# - indicate new layout, if print preview is in paint if ( mbInPaint ) { mbNewLayoutDuringPaint = true; } // validate paint data mbPaintInfoValid = true; // return start page _onStartPageNum = mnPaintPhyStartPageNum; return true; } /** calculate additional paint offset OD 12.12.2002 #103492# @author OD */ void SwPagePreviewLayout::_CalcAdditionalPaintOffset() { if ( mnPrevwLayoutWidth <= maWinSize.Width() && maPaintStartPageOffset.X() <= 0 ) { mbDoesLayoutColsFitIntoWindow = true; maAdditionalPaintOffset.X() = (maWinSize.Width() - mnPrevwLayoutWidth) / 2; } else { mbDoesLayoutColsFitIntoWindow = false; maAdditionalPaintOffset.X() = 0; } if ( mnPrevwLayoutHeight <= maWinSize.Height() && maPaintStartPageOffset.Y() <= 0 ) { mbDoesLayoutRowsFitIntoWindow = true; maAdditionalPaintOffset.Y() = (maWinSize.Height() - mnPrevwLayoutHeight) / 2; } else { mbDoesLayoutRowsFitIntoWindow = false; maAdditionalPaintOffset.Y() = 0; } } /** calculate painted preview document rectangle OD 12.12.2002 #103492# @author OD */ void SwPagePreviewLayout::_CalcDocPrevwPaintRect() { Point aTopLeftPos = maPaintPreviewDocOffset; maPaintedPrevwDocRect.SetPos( aTopLeftPos ); Size aSize; if ( mbDoesLayoutColsFitIntoWindow ) //aSize.Width() = mnPrevwLayoutWidth; aSize.Width() = Min( mnPrevwLayoutWidth, maPreviewDocRect.GetWidth() - aTopLeftPos.X() ); else aSize.Width() = Min( maPreviewDocRect.GetWidth() - aTopLeftPos.X(), maWinSize.Width() - maAdditionalPaintOffset.X() ); if ( mbDoesLayoutRowsFitIntoWindow ) //aSize.Height() = mnPrevwLayoutHeight; aSize.Height() = Min( mnPrevwLayoutHeight, maPreviewDocRect.GetHeight() - aTopLeftPos.Y() ); else aSize.Height() = Min( maPreviewDocRect.GetHeight() - aTopLeftPos.Y(), maWinSize.Height() - maAdditionalPaintOffset.Y() ); maPaintedPrevwDocRect.SetSize( aSize ); } /** calculate preview pages OD 12.12.2002 #103492# @author OD */ void SwPagePreviewLayout::_CalcPreviewPages() { _ClearPrevwPageData(); if ( mbNoPageVisible ) return; // determine start page frame const SwPageFrm* pStartPage = mrLayoutRootFrm.GetPageByPageNum( mnPaintPhyStartPageNum ); // calculate initial paint offset Point aInitialPaintOffset; if ( maPaintStartPageOffset != Point( -1, -1 ) ) aInitialPaintOffset = Point(0,0) - maPaintStartPageOffset; else aInitialPaintOffset = Point( mnXFree, mnYFree ); aInitialPaintOffset += maAdditionalPaintOffset; // prepare loop data const SwPageFrm* pPage = pStartPage; sal_uInt16 nCurrCol = mnPaintStartCol; sal_uInt16 nConsideredRows = 0; Point aCurrPaintOffset = aInitialPaintOffset; // loop on pages to determine preview background rectangles while ( pPage && (!mbDoesLayoutRowsFitIntoWindow || nConsideredRows < mnRows) && aCurrPaintOffset.Y() < maWinSize.Height() ) { if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() ) { pPage = static_cast(pPage->GetNext()); continue; } pPage->Calc(); // consider only pages, which have to be painted. if ( nCurrCol < mnPaintStartCol ) { // calculate data of invisible page needed for accessibility PrevwPage* pPrevwPage = new PrevwPage; Point aCurrAccOffset = aCurrPaintOffset - Point( (mnPaintStartCol-nCurrCol) * mnColWidth, 0 ); _CalcPreviewDataForPage( *(pPage), aCurrAccOffset, pPrevwPage ); pPrevwPage->bVisible = false; maPrevwPages.push_back( pPrevwPage ); // continue with next page and next column pPage = static_cast(pPage->GetNext()); ++nCurrCol; continue; } if ( aCurrPaintOffset.X() < maWinSize.Width() ) { // OD 19.02.2003 #107369# - leaving left-top-corner blank is // controlled by . if ( mbBookPreview && pPage->GetPhyPageNum() == 1 && mnCols != 1 && nCurrCol == 1 ) { // first page in 2nd column // --> continue with increased paint offset and next column aCurrPaintOffset.X() += mnColWidth; ++nCurrCol; continue; } // calculate data of visible page PrevwPage* pPrevwPage = new PrevwPage; _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPrevwPage ); pPrevwPage->bVisible = true; maPrevwPages.push_back( pPrevwPage ); } else { // calculate data of invisible page needed for accessibility PrevwPage* pPrevwPage = new PrevwPage; _CalcPreviewDataForPage( *(pPage), aCurrPaintOffset, pPrevwPage ); pPrevwPage->bVisible = false; maPrevwPages.push_back( pPrevwPage ); } // prepare data for next loop pPage = static_cast(pPage->GetNext()); aCurrPaintOffset.X() += mnColWidth; ++nCurrCol; if ( nCurrCol > mnCols ) { ++nConsideredRows; aCurrPaintOffset.X() = aInitialPaintOffset.X(); nCurrCol = 1; aCurrPaintOffset.Y() += mnRowHeight; } } } /** determines preview data for a given page and a given preview offset OD 13.12.2002 #103492# @author OD */ bool SwPagePreviewLayout::_CalcPreviewDataForPage( const SwPageFrm& _rPage, const Point& _rPrevwOffset, PrevwPage* _opPrevwPage ) { // page frame _opPrevwPage->pPage = &_rPage; // size of page frame if ( _rPage.IsEmptyPage() ) { if ( _rPage.GetPhyPageNum() % 2 == 0 ) _opPrevwPage->aPageSize = _rPage.GetPrev()->Frm().SSize(); else _opPrevwPage->aPageSize = _rPage.GetNext()->Frm().SSize(); } else _opPrevwPage->aPageSize = _rPage.Frm().SSize(); // position of page in preview window Point aPrevwWinOffset( _rPrevwOffset ); if ( _opPrevwPage->aPageSize.Width() < maMaxPageSize.Width() ) aPrevwWinOffset.X() += ( maMaxPageSize.Width() - _opPrevwPage->aPageSize.Width() ) / 2; if ( _opPrevwPage->aPageSize.Height() < maMaxPageSize.Height() ) aPrevwWinOffset.Y() += ( maMaxPageSize.Height() - _opPrevwPage->aPageSize.Height() ) / 2; _opPrevwPage->aPrevwWinPos = aPrevwWinOffset; // logic position of page and mapping offset for paint if ( _rPage.IsEmptyPage() ) { _opPrevwPage->aLogicPos = _opPrevwPage->aPrevwWinPos; _opPrevwPage->aMapOffset = Point( 0, 0 ); } else { _opPrevwPage->aLogicPos = _rPage.Frm().Pos(); _opPrevwPage->aMapOffset = _opPrevwPage->aPrevwWinPos - _opPrevwPage->aLogicPos; } return true; } /** enable/disable book preview OD 2004-03-04 #i18143# @author OD */ bool SwPagePreviewLayout::SetBookPreviewMode( const bool _bEnableBookPreview, sal_uInt16& _onStartPageNum, Rectangle& _orDocPreviewPaintRect ) { bool bRet = false; if ( mbBookPreview != _bEnableBookPreview) { mbBookPreview = _bEnableBookPreview; // re-initialize page preview layout ReInit(); // re-prepare page preview layout { mbBookPreviewModeToggled = true; Point aProposedStartPos( maPaintPreviewDocOffset ); // if proposed start position is below virtual preview document // bottom, adjust it to the virtual preview document bottom if ( aProposedStartPos.Y() > maPreviewDocRect.Bottom() ) { aProposedStartPos.Y() = maPreviewDocRect.Bottom(); } Prepare( 0, aProposedStartPos, mrParentViewShell.GetOut()->LogicToPixel( maWinSize ), _onStartPageNum, _orDocPreviewPaintRect ); mbBookPreviewModeToggled = false; } bRet = true; } return bRet; } // ============================================================================= // methods to determine new data for changing the current shown part of the // document preview. // ============================================================================= /** calculate start position for new scale OD 12.12.2002 #103492# @author OD */ Point SwPagePreviewLayout::GetPreviewStartPosForNewScale( const Fraction& _aNewScale, const Fraction& _aOldScale, const Size& _aNewWinSize ) const { Point aNewPaintStartPos = maPaintedPrevwDocRect.TopLeft(); if ( _aNewScale < _aOldScale ) { // increase paint width by moving start point to left. if ( mnPrevwLayoutWidth < _aNewWinSize.Width() ) aNewPaintStartPos.X() = 0; else if ( maPaintedPrevwDocRect.GetWidth() < _aNewWinSize.Width() ) { aNewPaintStartPos.X() -= (_aNewWinSize.Width() - maPaintedPrevwDocRect.GetWidth()) / 2; if ( aNewPaintStartPos.X() < 0) aNewPaintStartPos.X() = 0; } if ( !mbDoesLayoutRowsFitIntoWindow ) { // increase paint height by moving start point to top. if ( mnPrevwLayoutHeight < _aNewWinSize.Height() ) { aNewPaintStartPos.Y() = ( (mnPaintStartRow - 1) * mnRowHeight ); } else if ( maPaintedPrevwDocRect.GetHeight() < _aNewWinSize.Height() ) { aNewPaintStartPos.Y() -= (_aNewWinSize.Height() - maPaintedPrevwDocRect.GetHeight()) / 2; if ( aNewPaintStartPos.Y() < 0) aNewPaintStartPos.Y() = 0; } } } else { // decrease paint width by moving start point to right if ( maPaintedPrevwDocRect.GetWidth() > _aNewWinSize.Width() ) aNewPaintStartPos.X() += (maPaintedPrevwDocRect.GetWidth() - _aNewWinSize.Width()) / 2; // decrease paint height by moving start point to bottom if ( maPaintedPrevwDocRect.GetHeight() > _aNewWinSize.Height() ) { aNewPaintStartPos.Y() += (maPaintedPrevwDocRect.GetHeight() - _aNewWinSize.Height()) / 2; // check, if new y-position is outside document preview if ( aNewPaintStartPos.Y() > maPreviewDocRect.Bottom() ) aNewPaintStartPos.Y() = Max( 0L, maPreviewDocRect.Bottom() - mnPrevwLayoutHeight ); } } return aNewPaintStartPos; } /** determines, if page with given page number is visible in preview OD 12.12.2002 #103492# @author OD, _nPageNum is absolute! */ bool SwPagePreviewLayout::IsPageVisible( const sal_uInt16 _nPageNum ) const { const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); return pPrevwPage && pPrevwPage->bVisible; } /** calculate data to bring new selected page into view. OD 12.12.2002 #103492# @author OD, IN/OUT parameters are absolute page numbers!!! */ bool SwPagePreviewLayout::CalcStartValuesForSelectedPageMove( const sal_Int16 _nHoriMove, const sal_Int16 _nVertMove, sal_uInt16& _orNewSelectedPage, sal_uInt16& _orNewStartPage, Point& _orNewStartPos ) const { // determine position of current selected page sal_uInt16 nTmpRelSelPageNum = ConvertAbsoluteToRelativePageNum( mnSelectedPageNum ); sal_uInt16 nNewRelSelectedPageNum = nTmpRelSelPageNum; // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled // by . if ( mbBookPreview ) { // Note: consider that left-top-corner is left blank --> +1 ++nTmpRelSelPageNum; } sal_uInt16 nTmpCol = nTmpRelSelPageNum % mnCols; sal_uInt16 nCurrRow = nTmpRelSelPageNum / mnCols; if ( nTmpCol > 0 ) ++nCurrRow; // determine new selected page number { if ( _nHoriMove != 0 ) { if ( (nNewRelSelectedPageNum + _nHoriMove) < 1 ) nNewRelSelectedPageNum = 1; else if ( (nNewRelSelectedPageNum + _nHoriMove) > mnPages ) nNewRelSelectedPageNum = mnPages; else nNewRelSelectedPageNum = nNewRelSelectedPageNum + _nHoriMove; } if ( _nVertMove != 0 ) { if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) < 1 ) nNewRelSelectedPageNum = 1; else if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) > mnPages ) nNewRelSelectedPageNum = mnPages; else nNewRelSelectedPageNum += ( _nVertMove * mnCols ); } } sal_uInt16 nNewStartPage = mnPaintPhyStartPageNum; Point aNewStartPos = Point(0,0); sal_uInt16 nNewAbsSelectedPageNum = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum ); if ( !IsPageVisible( nNewAbsSelectedPageNum ) ) { if ( _nHoriMove != 0 && _nVertMove != 0 ) { ASSERT( false, "missing implementation for moving preview selected page horizontal AND vertical"); return false; } // new selected page has to be brought into view considering current // visible preview. sal_Int16 nTotalRows = GetRowOfPage( mnPages ); if ( (_nHoriMove > 0 || _nVertMove > 0) && mbDoesLayoutRowsFitIntoWindow && mbDoesLayoutColsFitIntoWindow && // OD 20.02.2003 #107369# - add condition nCurrRow > nTotalRows - mnRows ) { // new proposed start page = left-top-corner of last possible // preview page. nNewStartPage = (nTotalRows - mnRows) * mnCols + 1; // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled // by . if ( mbBookPreview ) { // Note: decrease new proposed start page number by one, // because of blank left-top-corner --nNewStartPage; } nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewStartPage ); } else { // new proposed start page = new selected page. nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum ); } } _orNewSelectedPage = nNewAbsSelectedPageNum; _orNewStartPage = nNewStartPage; _orNewStartPos = aNewStartPos; return true; } /** checks, if given position is inside a shown document page OD 17.12.2002 #103492# @author OD */ struct PrevwPosInsidePagePred { const Point mnPrevwPos; PrevwPosInsidePagePred( const Point _nPrevwPos ) : mnPrevwPos( _nPrevwPos ) {}; bool operator() ( const PrevwPage* _pPrevwPage ) { if ( _pPrevwPage->bVisible ) { Rectangle aPrevwPageRect( _pPrevwPage->aPrevwWinPos, _pPrevwPage->aPageSize ); return aPrevwPageRect.IsInside( mnPrevwPos ) ? true : false; } else return false; } }; bool SwPagePreviewLayout::IsPrevwPosInDocPrevwPage( const Point _aPrevwPos, Point& _orDocPos, bool& _obPosInEmptyPage, sal_uInt16& _onPageNum ) const { bool bIsPosInsideDoc; // initialize variable parameter values. _orDocPos.X() = 0; _orDocPos.Y() = 0; _obPosInEmptyPage = false; _onPageNum = 0; std::vector::const_iterator aFoundPrevwPageIter = std::find_if( maPrevwPages.begin(), maPrevwPages.end(), PrevwPosInsidePagePred( _aPrevwPos ) ); if ( aFoundPrevwPageIter == maPrevwPages.end() ) // given preview position outside a document page. bIsPosInsideDoc = false; else { _onPageNum = (*aFoundPrevwPageIter)->pPage->GetPhyPageNum(); if ( (*aFoundPrevwPageIter)->pPage->IsEmptyPage() ) { // given preview position inside an empty page bIsPosInsideDoc = false; _obPosInEmptyPage = true; } else { // given preview position inside a normal page bIsPosInsideDoc = true; _orDocPos = _aPrevwPos - (*aFoundPrevwPageIter)->aPrevwWinPos + (*aFoundPrevwPageIter)->aLogicPos; } } return bIsPosInsideDoc; } /** determine window page scroll amount OD 17.12.2002 #103492# @author OD */ SwTwips SwPagePreviewLayout::GetWinPagesScrollAmount( const sal_Int16 _nWinPagesToScroll ) const { SwTwips nScrollAmount; if ( mbDoesLayoutRowsFitIntoWindow ) { nScrollAmount = (mnPrevwLayoutHeight - mnYFree) * _nWinPagesToScroll; } else nScrollAmount = _nWinPagesToScroll * maPaintedPrevwDocRect.GetHeight(); // OD 19.02.2003 #107369# - check, if preview layout size values are valid. // If not, the checks for an adjustment of the scroll amount aren't useful. if ( mbLayoutSizesValid ) { if ( (maPaintedPrevwDocRect.Top() + nScrollAmount) <= 0 ) nScrollAmount = -maPaintedPrevwDocRect.Top(); // OD 14.02.2003 #107369# - correct scroll amount if ( nScrollAmount > 0 && maPaintedPrevwDocRect.Bottom() == maPreviewDocRect.Bottom() ) { nScrollAmount = 0; } else { while ( (maPaintedPrevwDocRect.Top() + nScrollAmount + mnYFree) >= maPreviewDocRect.GetHeight() ) { nScrollAmount -= mnRowHeight; } } } return nScrollAmount; } // ============================================================================= // methods to paint page preview layout // ============================================================================= /** paint prepared preview OD 12.12.2002 #103492# @author OD */ bool SwPagePreviewLayout::Paint( const Rectangle _aOutRect ) const { // check environment and parameters { if ( !mrParentViewShell.GetWin() && !mrParentViewShell.GetOut()->GetConnectMetaFile() ) return false; ASSERT( mbPaintInfoValid, "invalid preview settings - no paint of preview" ); if ( !mbPaintInfoValid ) return false; } // OD 17.11.2003 #i22014# - no paint, if flag is set at layout if ( mrLayoutRootFrm.IsSuperfluous() ) { return true; } // environment and parameter ok // OD 07.11.2003 #i22014# if ( mbInPaint ) { return false; } mbInPaint = true; OutputDevice* pOutputDev = mrParentViewShell.GetOut(); // prepare paint if ( maPrevwPages.size() > 0 ) { mrParentViewShell.Imp()->bFirstPageInvalid = sal_False; mrParentViewShell.Imp()->pFirstVisPage = const_cast(maPrevwPages[0]->pPage); } // paint preview background { SwRegionRects aPreviewBackgrdRegion( _aOutRect ); // calculate preview background rectangles for ( std::vector::const_iterator aPageIter = maPrevwPages.begin(); aPageIter != maPrevwPages.end(); ++aPageIter ) { if ( (*aPageIter)->bVisible ) { aPreviewBackgrdRegion -= SwRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize ); } } // paint preview background rectangles mrParentViewShell._PaintDesktop( aPreviewBackgrdRegion ); } // prepare data for paint of pages const Rectangle aPxOutRect( pOutputDev->LogicToPixel( _aOutRect ) ); MapMode aMapMode( pOutputDev->GetMapMode() ); MapMode aSavedMapMode = aMapMode; const Font& rEmptyPgFont = SwPageFrm::GetEmptyPageFont(); Color aEmptyPgShadowBorderColor = SwViewOption::GetFontColor(); for ( std::vector::const_iterator aPageIter = maPrevwPages.begin(); aPageIter != maPrevwPages.end(); ++aPageIter ) { if ( !(*aPageIter)->bVisible ) continue; Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); aMapMode.SetOrigin( (*aPageIter)->aMapOffset ); pOutputDev->SetMapMode( aMapMode ); Rectangle aPxPaintRect = pOutputDev->LogicToPixel( aPageRect ); if ( aPxOutRect.IsOver( aPxPaintRect) ) { if ( (*aPageIter)->pPage->IsEmptyPage() ) { const Color aRetouche( mrParentViewShell.Imp()->GetRetoucheColor() ); if( pOutputDev->GetFillColor() != aRetouche ) pOutputDev->SetFillColor( aRetouche ); pOutputDev->SetLineColor(); // OD 20.02.2003 #107369# - no line color // OD 20.02.2003 #107369# - use aligned page rectangle { SwRect aTmpPageRect( aPageRect ); ::SwAlignRect( aTmpPageRect, &mrParentViewShell); aPageRect = aTmpPageRect.SVRect(); } pOutputDev->DrawRect( aPageRect ); // paint empty page text Font aOldFont( pOutputDev->GetFont() ); pOutputDev->SetFont( rEmptyPgFont ); pOutputDev->DrawText( aPageRect, SW_RESSTR( STR_EMPTYPAGE ), TEXT_DRAW_VCENTER | TEXT_DRAW_CENTER | TEXT_DRAW_CLIP ); pOutputDev->SetFont( aOldFont ); // paint shadow and border for empty page // OD 19.02.2003 #107369# - use new method to paint page border and // shadow SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, true ); } else { mrParentViewShell.aVisArea = aPageRect; aPxPaintRect.Intersection( aPxOutRect ); Rectangle aPaintRect = pOutputDev->PixelToLogic( aPxPaintRect ); mrParentViewShell.Paint( aPaintRect ); // --> OD 2007-08-15 #i80691# // paint page border and shadow { SwRect aPageBorderRect; SwPageFrm::GetBorderAndShadowBoundRect( SwRect( aPageRect ), &mrParentViewShell, aPageBorderRect, true ); const Region aDLRegion(aPageBorderRect.SVRect()); mrParentViewShell.DLPrePaint2(aDLRegion); SwPageFrm::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, true ); mrParentViewShell.DLPostPaint2(true); } // <-- } // OD 07.11.2003 #i22014# - stop painting, because new print // preview layout is created during paint. if ( mbNewLayoutDuringPaint ) { break; } if ( (*aPageIter)->pPage->GetPhyPageNum() == mnSelectedPageNum ) { _PaintSelectMarkAtPage( (*aPageIter) ); } } } // OD 17.11.2003 #i22014# - no update of accessible preview, if a new // print preview layout is created during paint. if ( !mbNewLayoutDuringPaint ) { // update at accessiblilty interface mrParentViewShell.Imp()->UpdateAccessiblePreview( maPrevwPages, aMapMode.GetScaleX(), mrLayoutRootFrm.GetPageByPageNum( mnSelectedPageNum ), maWinSize ); } pOutputDev->SetMapMode( aSavedMapMode ); mrParentViewShell.aVisArea.Clear(); // OD 07.11.2003 #i22014# mbInPaint = false; mbNewLayoutDuringPaint = false; return true; } /** repaint pages on page preview OD 18.12.2002 #103492# @author OD */ void SwPagePreviewLayout::Repaint( const Rectangle _aInvalidCoreRect ) const { // check environment and parameters { if ( !mrParentViewShell.GetWin() && !mrParentViewShell.GetOut()->GetConnectMetaFile() ) return; ASSERT( mbPaintInfoValid, "invalid preview settings - no paint of preview" ); if ( !mbPaintInfoValid ) return; } // environment and parameter ok // prepare paint if ( maPrevwPages.size() > 0 ) { mrParentViewShell.Imp()->bFirstPageInvalid = sal_False; mrParentViewShell.Imp()->pFirstVisPage = const_cast(maPrevwPages[0]->pPage); } // invalidate visible pages, which overlap the invalid core rectangle for ( std::vector::const_iterator aPageIter = maPrevwPages.begin(); aPageIter != maPrevwPages.end(); ++aPageIter ) { if ( !(*aPageIter)->bVisible ) continue; Rectangle aPageRect( (*aPageIter)->aLogicPos, (*aPageIter)->aPageSize ); if ( _aInvalidCoreRect.IsOver( aPageRect ) ) { aPageRect.Intersection( _aInvalidCoreRect ); Rectangle aInvalidPrevwRect = aPageRect; aInvalidPrevwRect.SetPos( aInvalidPrevwRect.TopLeft() - (*aPageIter)->aLogicPos + (*aPageIter)->aPrevwWinPos ); mrParentViewShell.GetWin()->Invalidate( aInvalidPrevwRect ); } } } /** paint selection mark at page OD 17.12.2002 #103492# @author OD */ void SwPagePreviewLayout::_PaintSelectMarkAtPage( const PrevwPage* _aSelectedPrevwPage ) const { OutputDevice* pOutputDev = mrParentViewShell.GetOut(); MapMode aMapMode( pOutputDev->GetMapMode() ); // save mapping mode of output device MapMode aSavedMapMode = aMapMode; // save fill and line color of output device Color aFill( pOutputDev->GetFillColor() ); Color aLine( pOutputDev->GetLineColor() ); // determine selection mark color Color aSelPgLineColor(COL_LIGHTBLUE); const StyleSettings& rSettings = mrParentViewShell.GetWin()->GetSettings().GetStyleSettings(); if ( rSettings.GetHighContrastMode() ) aSelPgLineColor = rSettings.GetHighlightTextColor(); // set needed mapping mode at output device aMapMode.SetOrigin( _aSelectedPrevwPage->aMapOffset ); pOutputDev->SetMapMode( aMapMode ); // calculate page rectangle in pixel coordinates SwRect aPageRect( _aSelectedPrevwPage->aLogicPos, _aSelectedPrevwPage->aPageSize ); // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for // page border and shadow paint - see ::SwAlignRect( aPageRect, &mrParentViewShell); Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); // draw two rectangle // OD 19.02.2003 #107369# - adjust position of select mark rectangle Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(), aPxPageRect.Right(), aPxPageRect.Bottom() ); aRect = pOutputDev->PixelToLogic( aRect ); pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color pOutputDev->SetLineColor( aSelPgLineColor ); pOutputDev->DrawRect( aRect ); // OD 19.02.2003 #107369# - adjust position of select mark rectangle aRect = Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1, aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 ); aRect = pOutputDev->PixelToLogic( aRect ); pOutputDev->DrawRect( aRect ); // reset fill and line color of output device pOutputDev->SetFillColor( aFill ); pOutputDev->SetLineColor( aLine ); // reset mapping mode of output device pOutputDev->SetMapMode( aSavedMapMode ); } /** paint to mark new selected page OD 17.12.2002 #103492# Perform paint for current selected page in order to unmark it. Set new selected page and perform paint to mark this page. @author OD, _nSelectedPage, mnSelectedPage are absolute */ void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage ) { sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum; mnSelectedPageNum = _nSelectedPage; // re-paint for current selected page in order to unmark it. const PrevwPage* pOldSelectedPrevwPage = _GetPrevwPageByPageNum( nOldSelectedPageNum ); if ( pOldSelectedPrevwPage && pOldSelectedPrevwPage->bVisible ) { // OD 20.02.2003 #107369# - invalidate only areas of selection mark. SwRect aPageRect( pOldSelectedPrevwPage->aPrevwWinPos, pOldSelectedPrevwPage->aPageSize ); ::SwAlignRect( aPageRect, &mrParentViewShell); OutputDevice* pOutputDev = mrParentViewShell.GetOut(); Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() ); // invalidate top mark line Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(), aPxPageRect.Right(), aPxPageRect.Top()+1 ); mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); // invalidate right mark line aInvalPxRect = Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(), aPxPageRect.Right(), aPxPageRect.Bottom() ); mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); // invalidate bottom mark line aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1, aPxPageRect.Right(), aPxPageRect.Bottom() ); mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); // invalidate left mark line aInvalPxRect = Rectangle( aPxPageRect.Left(), aPxPageRect.Top(), aPxPageRect.Left()+1, aPxPageRect.Bottom() ); mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) ); } // re-paint for new selected page in order to mark it. const PrevwPage* pNewSelectedPrevwPage = _GetPrevwPageByPageNum( _nSelectedPage ); if ( pNewSelectedPrevwPage && pNewSelectedPrevwPage->bVisible ) _PaintSelectMarkAtPage( pNewSelectedPrevwPage ); } // ============================================================================= // helper methods // ============================================================================= /** get preview page by physical page number OD 17.12.2002 #103492# @author OD */ struct EqualsPageNumPred { const sal_uInt16 mnPageNum; EqualsPageNumPred( const sal_uInt16 _nPageNum ) : mnPageNum( _nPageNum ) {}; bool operator() ( const PrevwPage* _pPrevwPage ) { return _pPrevwPage->pPage->GetPhyPageNum() == mnPageNum; } }; const PrevwPage* SwPagePreviewLayout::_GetPrevwPageByPageNum( const sal_uInt16 _nPageNum ) const { std::vector::const_iterator aFoundPrevwPageIter = std::find_if( maPrevwPages.begin(), maPrevwPages.end(), EqualsPageNumPred( _nPageNum ) ); if ( aFoundPrevwPageIter == maPrevwPages.end() ) return 0; else return (*aFoundPrevwPageIter); } /** determine row the page with the given number is in OD 17.01.2003 #103492# @author OD, _nPageNum is relative */ sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const { // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled // by . if ( mbBookPreview ) { // Note: increase given physical page number by one, because left-top-corner // in the preview layout is left blank. ++_nPageNum; } sal_uInt16 nRow = (_nPageNum) / mnCols; if ( ( (_nPageNum) % mnCols ) > 0 ) ++nRow; return nRow; } /** determine column the page with the given number is in OD 17.01.2003 #103492# @author OD, _nPageNum is relative */ sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const { // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled // by . if ( mbBookPreview ) { // Note: increase given physical page number by one, because left-top-corner // in the preview layout is left blank. ++_nPageNum; } sal_uInt16 nCol = (_nPageNum) % mnCols; if ( nCol == 0 ) nCol = mnCols; return nCol; } Size SwPagePreviewLayout::GetPrevwDocSize() const { ASSERT( PreviewLayoutValid(), "PagePreviewLayout not valid" ); return maPreviewDocRect.GetSize(); } /** get size of a preview page by its physical page number OD 15.01.2003 #103492# @author OD */ Size SwPagePreviewLayout::GetPrevwPageSizeByPageNum( sal_uInt16 _nPageNum ) const { const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); if ( pPrevwPage ) { return pPrevwPage->aPageSize; } else { return Size( 0, 0 ); } } /** get virtual page number by its physical page number OD 21.03.2003 #108282# @author OD */ sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const { const PrevwPage* pPrevwPage = _GetPrevwPageByPageNum( _nPageNum ); if ( pPrevwPage ) { return pPrevwPage->pPage->GetVirtPageNum(); } else { return 0; } } /** Convert absolute to relative page numbers (see PrintEmptyPages) @author FME */ sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const { if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum ) { return _nAbsPageNum; } const SwPageFrm* pTmpPage = static_cast(mrLayoutRootFrm.Lower()); sal_uInt16 nRet = 1; while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum ) { if ( !pTmpPage->IsEmptyPage() ) ++nRet; pTmpPage = static_cast( pTmpPage->GetNext() ); } return nRet; } /** Convert relative to absolute page numbers (see PrintEmptyPages) @author FME */ sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const { if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum ) { return _nRelPageNum; } const SwPageFrm* pTmpPage = static_cast(mrLayoutRootFrm.Lower()); const SwPageFrm* pRet = 0; sal_uInt16 i = 0; while( pTmpPage && i != _nRelPageNum ) { if ( !pTmpPage->IsEmptyPage() ) ++i; pRet = pTmpPage; pTmpPage = static_cast( pTmpPage->GetNext() ); } return pRet->GetPhyPageNum(); }