| /************************************************************** |
| * |
| * 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_sc.hxx" |
| |
| |
| |
| // INCLUDE --------------------------------------------------------------- |
| |
| #include <vcl/outdev.hxx> |
| #include <tools/debug.hxx> |
| |
| #include "prevloc.hxx" |
| #include "document.hxx" |
| |
| //================================================================== |
| |
| enum ScPreviewLocationType |
| { |
| SC_PLOC_CELLRANGE, |
| SC_PLOC_COLHEADER, |
| SC_PLOC_ROWHEADER, |
| SC_PLOC_LEFTHEADER, |
| SC_PLOC_RIGHTHEADER, |
| SC_PLOC_LEFTFOOTER, |
| SC_PLOC_RIGHTFOOTER, |
| SC_PLOC_NOTEMARK, |
| SC_PLOC_NOTETEXT |
| }; |
| |
| struct ScPreviewLocationEntry |
| { |
| ScPreviewLocationType eType; |
| Rectangle aPixelRect; |
| ScRange aCellRange; |
| sal_Bool bRepeatCol; |
| sal_Bool bRepeatRow; |
| |
| ScPreviewLocationEntry( ScPreviewLocationType eNewType, const Rectangle& rPixel, const ScRange& rRange, |
| sal_Bool bRepCol, sal_Bool bRepRow ) : |
| eType( eNewType ), |
| aPixelRect( rPixel ), |
| aCellRange( rRange ), |
| bRepeatCol( bRepCol ), |
| bRepeatRow( bRepRow ) |
| { |
| } |
| }; |
| |
| //================================================================== |
| |
| ScPreviewTableInfo::ScPreviewTableInfo() : |
| nTab(0), |
| nCols(0), |
| nRows(0), |
| pColInfo(NULL), |
| pRowInfo(NULL) |
| { |
| } |
| |
| ScPreviewTableInfo::~ScPreviewTableInfo() |
| { |
| delete[] pColInfo; |
| delete[] pRowInfo; |
| } |
| |
| void ScPreviewTableInfo::SetTab( SCTAB nNewTab ) |
| { |
| nTab = nNewTab; |
| } |
| |
| void ScPreviewTableInfo::SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo ) |
| { |
| delete[] pColInfo; |
| pColInfo = pNewInfo; |
| nCols = nCount; |
| } |
| |
| void ScPreviewTableInfo::SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo ) |
| { |
| delete[] pRowInfo; |
| pRowInfo = pNewInfo; |
| nRows = nCount; |
| } |
| |
| void ScPreviewTableInfo::LimitToArea( const Rectangle& rPixelArea ) |
| { |
| if ( pColInfo ) |
| { |
| // cells completely left of the visible area |
| SCCOL nStart = 0; |
| while ( nStart < nCols && pColInfo[nStart].nPixelEnd < rPixelArea.Left() ) |
| ++nStart; |
| |
| // cells completely right of the visible area |
| SCCOL nEnd = nCols; |
| while ( nEnd > 0 && pColInfo[nEnd-1].nPixelStart > rPixelArea.Right() ) |
| --nEnd; |
| |
| if ( nStart > 0 || nEnd < nCols ) |
| { |
| if ( nEnd > nStart ) |
| { |
| SCCOL nNewCount = nEnd - nStart; |
| ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount]; |
| for (SCCOL i=0; i<nNewCount; i++) |
| pNewInfo[i] = pColInfo[nStart + i]; |
| SetColInfo( nNewCount, pNewInfo ); |
| } |
| else |
| SetColInfo( 0, NULL ); // all invisible |
| } |
| } |
| |
| if ( pRowInfo ) |
| { |
| // cells completely above the visible area |
| SCROW nStart = 0; |
| while ( nStart < nRows && pRowInfo[nStart].nPixelEnd < rPixelArea.Top() ) |
| ++nStart; |
| |
| // cells completely below the visible area |
| SCROW nEnd = nRows; |
| while ( nEnd > 0 && pRowInfo[nEnd-1].nPixelStart > rPixelArea.Bottom() ) |
| --nEnd; |
| |
| if ( nStart > 0 || nEnd < nRows ) |
| { |
| if ( nEnd > nStart ) |
| { |
| SCROW nNewCount = nEnd - nStart; |
| ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount]; |
| for (SCROW i=0; i<nNewCount; i++) |
| pNewInfo[i] = pRowInfo[nStart + i]; |
| SetRowInfo( nNewCount, pNewInfo ); |
| } |
| else |
| SetRowInfo( 0, NULL ); // all invisible |
| } |
| } |
| } |
| |
| //------------------------------------------------------------------ |
| |
| ScPreviewLocationData::ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin ) : |
| pWindow( pWin ), |
| pDoc( pDocument ), |
| nDrawRanges( 0 ), |
| nPrintTab( 0 ) |
| { |
| } |
| |
| ScPreviewLocationData::~ScPreviewLocationData() |
| { |
| Clear(); |
| } |
| |
| void ScPreviewLocationData::SetCellMapMode( const MapMode& rMapMode ) |
| { |
| aCellMapMode = rMapMode; |
| } |
| |
| void ScPreviewLocationData::SetPrintTab( SCTAB nNew ) |
| { |
| nPrintTab = nNew; |
| } |
| |
| void ScPreviewLocationData::Clear() |
| { |
| void* pEntry = aEntries.First(); |
| while ( pEntry ) |
| { |
| delete (ScPreviewLocationEntry*) pEntry; |
| pEntry = aEntries.Next(); |
| } |
| aEntries.Clear(); |
| |
| nDrawRanges = 0; |
| } |
| |
| void ScPreviewLocationData::AddCellRange( const Rectangle& rRect, const ScRange& rRange, sal_Bool bRepCol, sal_Bool bRepRow, |
| const MapMode& rDrawMap ) |
| { |
| Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) ); |
| aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_CELLRANGE, aPixelRect, rRange, bRepCol, bRepRow ) ); |
| |
| DBG_ASSERT( nDrawRanges < SC_PREVIEW_MAXRANGES, "too many ranges" ); |
| if ( nDrawRanges < SC_PREVIEW_MAXRANGES ) |
| { |
| aDrawRectangle[nDrawRanges] = aPixelRect; |
| aDrawMapMode[nDrawRanges] = rDrawMap; |
| if (bRepCol) |
| if (bRepRow) |
| aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_EDGE; |
| else |
| aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPCOL; |
| else |
| if (bRepRow) |
| aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPROW; |
| else |
| aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_TAB; |
| ++nDrawRanges; |
| } |
| } |
| |
| void ScPreviewLocationData::AddColHeaders( const Rectangle& rRect, SCCOL nStartCol, SCCOL nEndCol, sal_Bool bRepCol ) |
| { |
| SCTAB nTab = 0; //! ? |
| ScRange aRange( nStartCol, 0, nTab, nEndCol, 0, nTab ); |
| Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) ); |
| aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_COLHEADER, aPixelRect, aRange, bRepCol, sal_False ) ); |
| } |
| |
| void ScPreviewLocationData::AddRowHeaders( const Rectangle& rRect, SCROW nStartRow, SCROW nEndRow, sal_Bool bRepRow ) |
| { |
| SCTAB nTab = 0; //! ? |
| ScRange aRange( 0, nStartRow, nTab, 0, nEndRow, nTab ); |
| Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) ); |
| aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_ROWHEADER, aPixelRect, aRange, sal_False, bRepRow ) ); |
| } |
| |
| void ScPreviewLocationData::AddHeaderFooter( const Rectangle& rRect, sal_Bool bHeader, sal_Bool bLeft ) |
| { |
| ScRange aRange; //! ? |
| Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) ); |
| |
| ScPreviewLocationType eType = bHeader ? |
| ( bLeft ? SC_PLOC_LEFTHEADER : SC_PLOC_RIGHTHEADER ) : |
| ( bLeft ? SC_PLOC_LEFTFOOTER : SC_PLOC_RIGHTFOOTER ); |
| aEntries.Insert( new ScPreviewLocationEntry( eType, aPixelRect, aRange, sal_False, sal_False ) ); |
| } |
| |
| void ScPreviewLocationData::AddNoteMark( const Rectangle& rRect, const ScAddress& rPos ) |
| { |
| ScRange aRange( rPos ); |
| Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) ); |
| aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_NOTEMARK, aPixelRect, aRange, sal_False, sal_False ) ); |
| } |
| |
| void ScPreviewLocationData::AddNoteText( const Rectangle& rRect, const ScAddress& rPos ) |
| { |
| ScRange aRange( rPos ); |
| Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) ); |
| aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_NOTETEXT, aPixelRect, aRange, sal_False, sal_False ) ); |
| } |
| |
| //------------------------------------------------------------------ |
| |
| void ScPreviewLocationData::GetDrawRange( sal_uInt16 nPos, Rectangle& rPixelRect, MapMode& rMapMode, sal_uInt8& rRangeId ) const |
| { |
| DBG_ASSERT( nPos < nDrawRanges, "wrong position" ); |
| if ( nPos < nDrawRanges ) |
| { |
| rPixelRect = aDrawRectangle[nPos]; |
| rMapMode = aDrawMapMode[nPos]; |
| rRangeId = aDrawRangeId[nPos]; |
| } |
| } |
| |
| ScPreviewLocationEntry* lcl_GetEntryByAddress( const List& rEntries, const ScAddress& rPos, ScPreviewLocationType eType ) |
| { |
| sal_uLong nCount = rEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)rEntries.GetObject(nListPos); |
| if ( pEntry->eType == eType && pEntry->aCellRange.In( rPos ) ) |
| return pEntry; |
| } |
| return NULL; |
| } |
| |
| //UNUSED2008-05 ScAddress ScPreviewLocationData::GetCellFromRange( const Size& rOffsetPixel, const ScRange& rRange ) const |
| //UNUSED2008-05 { |
| //UNUSED2008-05 const double nScaleX = HMM_PER_TWIPS; |
| //UNUSED2008-05 const double nScaleY = HMM_PER_TWIPS; |
| //UNUSED2008-05 |
| //UNUSED2008-05 Size aOffsetLogic = pWindow->PixelToLogic( rOffsetPixel, aCellMapMode ); |
| //UNUSED2008-05 SCTAB nTab = rRange.aStart.Tab(); |
| //UNUSED2008-05 |
| //UNUSED2008-05 long nPosX = 0; |
| //UNUSED2008-05 SCCOL nCol = rRange.aStart.Col(); |
| //UNUSED2008-05 SCCOL nEndCol = rRange.aEnd.Col(); |
| //UNUSED2008-05 while ( nCol <= nEndCol && nPosX < aOffsetLogic.Width() ) |
| //UNUSED2008-05 { |
| //UNUSED2008-05 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab ); |
| //UNUSED2008-05 if (nDocW) |
| //UNUSED2008-05 nPosX += (long) (nDocW * nScaleX); |
| //UNUSED2008-05 ++nCol; |
| //UNUSED2008-05 } |
| //UNUSED2008-05 if ( nCol > rRange.aStart.Col() ) |
| //UNUSED2008-05 --nCol; |
| //UNUSED2008-05 |
| //UNUSED2008-05 long nPosY = 0; |
| //UNUSED2008-05 ScCoupledCompressedArrayIterator< SCROW, sal_uInt8, sal_uInt16> aIter( |
| //UNUSED2008-05 pDoc->GetRowFlagsArray( nTab), rRange.aStart.Row(), |
| //UNUSED2008-05 rRange.aEnd.Row(), CR_HIDDEN, 0, pDoc->GetRowHeightArray( nTab)); |
| //UNUSED2008-05 while ( aIter && nPosY < aOffsetLogic.Height() ) |
| //UNUSED2008-05 { |
| //UNUSED2008-05 sal_uInt16 nDocH = *aIter; |
| //UNUSED2008-05 if (nDocH) |
| //UNUSED2008-05 nPosY += (long) (nDocH * nScaleY); |
| //UNUSED2008-05 ++aIter; |
| //UNUSED2008-05 } |
| //UNUSED2008-05 SCROW nRow = aIter.GetPos(); |
| //UNUSED2008-05 if ( nRow > rRange.aStart.Row() ) |
| //UNUSED2008-05 --nRow; |
| //UNUSED2008-05 |
| //UNUSED2008-05 return ScAddress( nCol, nRow, nTab ); |
| //UNUSED2008-05 } |
| |
| Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, const ScRange& rRange ) const |
| { |
| const double nScaleX = HMM_PER_TWIPS; |
| const double nScaleY = HMM_PER_TWIPS; |
| SCTAB nTab = rRange.aStart.Tab(); |
| |
| long nPosX = 0; |
| SCCOL nEndCol = rCellPos.Col(); |
| for (SCCOL nCol = rRange.aStart.Col(); nCol < nEndCol; nCol++) |
| { |
| sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab ); |
| if (nDocW) |
| nPosX += (long) (nDocW * nScaleX); |
| } |
| long nSizeX = (long) ( pDoc->GetColWidth( nEndCol, nTab ) * nScaleX ); |
| |
| SCROW nEndRow = rCellPos.Row(); |
| long nPosY = (long) pDoc->GetScaledRowHeight( rRange.aStart.Row(), |
| nEndRow, nTab, nScaleY); |
| long nSizeY = (long) ( pDoc->GetRowHeight( nEndRow, nTab ) * nScaleY ); |
| |
| Size aOffsetLogic( nPosX, nPosY ); |
| Size aSizeLogic( nSizeX, nSizeY ); |
| Size aOffsetPixel = pWindow->LogicToPixel( aOffsetLogic, aCellMapMode ); |
| Size aSizePixel = pWindow->LogicToPixel( aSizeLogic, aCellMapMode ); |
| |
| return Rectangle( Point( aOffsetPixel.Width(), aOffsetPixel.Height() ), aSizePixel ); |
| } |
| |
| sal_Bool ScPreviewLocationData::GetCellPosition( const ScAddress& rCellPos, Rectangle& rCellRect ) const |
| { |
| ScPreviewLocationEntry* pEntry = lcl_GetEntryByAddress( aEntries, rCellPos, SC_PLOC_CELLRANGE ); |
| if ( pEntry ) |
| { |
| Rectangle aOffsetRect = GetOffsetPixel( rCellPos, pEntry->aCellRange ); |
| rCellRect = Rectangle( aOffsetRect.Left() + pEntry->aPixelRect.Left(), |
| aOffsetRect.Top() + pEntry->aPixelRect.Top(), |
| aOffsetRect.Right() + pEntry->aPixelRect.Left(), |
| aOffsetRect.Bottom() + pEntry->aPixelRect.Top() ); |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| sal_Bool ScPreviewLocationData::HasCellsInRange( const Rectangle& rVisiblePixel ) const |
| { |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| ScPreviewLocationType eType = pEntry->eType; |
| if ( eType == SC_PLOC_CELLRANGE || eType == SC_PLOC_COLHEADER || eType == SC_PLOC_ROWHEADER ) |
| if ( pEntry->aPixelRect.IsOver( rVisiblePixel ) ) |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| sal_Bool ScPreviewLocationData::GetHeaderPosition( Rectangle& rRect ) const |
| { |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == SC_PLOC_LEFTHEADER || pEntry->eType == SC_PLOC_RIGHTHEADER ) |
| { |
| rRect = pEntry->aPixelRect; |
| return sal_True; |
| } |
| } |
| return sal_False; |
| } |
| |
| sal_Bool ScPreviewLocationData::GetFooterPosition( Rectangle& rRect ) const |
| { |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == SC_PLOC_LEFTFOOTER || pEntry->eType == SC_PLOC_RIGHTFOOTER ) |
| { |
| rRect = pEntry->aPixelRect; |
| return sal_True; |
| } |
| } |
| return sal_False; |
| } |
| |
| sal_Bool ScPreviewLocationData::IsHeaderLeft() const |
| { |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == SC_PLOC_LEFTHEADER ) |
| return sal_True; |
| if ( pEntry->eType == SC_PLOC_RIGHTHEADER ) |
| return sal_False; |
| } |
| return sal_False; |
| } |
| |
| sal_Bool ScPreviewLocationData::IsFooterLeft() const |
| { |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == SC_PLOC_LEFTFOOTER ) |
| return sal_True; |
| if ( pEntry->eType == SC_PLOC_RIGHTFOOTER ) |
| return sal_False; |
| } |
| return sal_False; |
| } |
| |
| long ScPreviewLocationData::GetNoteCountInRange( const Rectangle& rVisiblePixel, sal_Bool bNoteMarks ) const |
| { |
| ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT; |
| |
| sal_uLong nRet = 0; |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) ) |
| ++nRet; |
| } |
| return nRet; |
| } |
| |
| sal_Bool ScPreviewLocationData::GetNoteInRange( const Rectangle& rVisiblePixel, long nIndex, sal_Bool bNoteMarks, |
| ScAddress& rCellPos, Rectangle& rNoteRect ) const |
| { |
| ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT; |
| |
| sal_uLong nPos = 0; |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) ) |
| { |
| if ( nPos == sal::static_int_cast<sal_uLong>(nIndex) ) |
| { |
| rCellPos = pEntry->aCellRange.aStart; |
| rNoteRect = pEntry->aPixelRect; |
| return sal_True; |
| } |
| ++nPos; |
| } |
| } |
| return sal_False; |
| } |
| |
| Rectangle ScPreviewLocationData::GetNoteInRangeOutputRect(const Rectangle& rVisiblePixel, sal_Bool bNoteMarks, const ScAddress& aCellPos) const |
| { |
| ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT; |
| |
| sal_uLong nPos = 0; |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) ) |
| { |
| if ( aCellPos == pEntry->aCellRange.aStart ) |
| return pEntry->aPixelRect; |
| ++nPos; |
| } |
| } |
| return Rectangle(); |
| } |
| |
| void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPreviewTableInfo& rInfo ) const |
| { |
| const double nScaleX = HMM_PER_TWIPS; |
| const double nScaleY = HMM_PER_TWIPS; |
| |
| // from left to right: |
| sal_Bool bHasHeaderCol = sal_False; |
| sal_Bool bHasRepCols = sal_False; |
| sal_Bool bHasMainCols = sal_False; |
| SCCOL nRepeatColStart = 0; |
| SCCOL nRepeatColEnd = 0; |
| SCCOL nMainColStart = 0; |
| SCCOL nMainColEnd = 0; |
| |
| // from top to bottom: |
| sal_Bool bHasHeaderRow = sal_False; |
| sal_Bool bHasRepRows = sal_False; |
| sal_Bool bHasMainRows = sal_False; |
| SCROW nRepeatRowStart = 0; |
| SCROW nRepeatRowEnd = 0; |
| SCROW nMainRowStart = 0; |
| SCROW nMainRowEnd = 0; |
| |
| Rectangle aHeaderRect, aRepeatRect, aMainRect; |
| SCTAB nTab = 0; |
| |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == SC_PLOC_CELLRANGE ) |
| { |
| if ( pEntry->bRepeatCol ) |
| { |
| bHasRepCols = sal_True; |
| nRepeatColStart = pEntry->aCellRange.aStart.Col(); |
| nRepeatColEnd = pEntry->aCellRange.aEnd.Col(); |
| aRepeatRect.Left() = pEntry->aPixelRect.Left(); |
| aRepeatRect.Right() = pEntry->aPixelRect.Right(); |
| } |
| else |
| { |
| bHasMainCols = sal_True; |
| nMainColStart = pEntry->aCellRange.aStart.Col(); |
| nMainColEnd = pEntry->aCellRange.aEnd.Col(); |
| aMainRect.Left() = pEntry->aPixelRect.Left(); |
| aMainRect.Right() = pEntry->aPixelRect.Right(); |
| } |
| if ( pEntry->bRepeatRow ) |
| { |
| bHasRepRows = sal_True; |
| nRepeatRowStart = pEntry->aCellRange.aStart.Row(); |
| nRepeatRowEnd = pEntry->aCellRange.aEnd.Row(); |
| aRepeatRect.Top() = pEntry->aPixelRect.Top(); |
| aRepeatRect.Bottom() = pEntry->aPixelRect.Bottom(); |
| } |
| else |
| { |
| bHasMainRows = sal_True; |
| nMainRowStart = pEntry->aCellRange.aStart.Row(); |
| nMainRowEnd = pEntry->aCellRange.aEnd.Row(); |
| aMainRect.Top() = pEntry->aPixelRect.Top(); |
| aMainRect.Bottom() = pEntry->aPixelRect.Bottom(); |
| } |
| nTab = pEntry->aCellRange.aStart.Tab(); //! store separately? |
| } |
| else if ( pEntry->eType == SC_PLOC_ROWHEADER ) |
| { |
| // row headers result in an additional column |
| bHasHeaderCol = sal_True; |
| aHeaderRect.Left() = pEntry->aPixelRect.Left(); |
| aHeaderRect.Right() = pEntry->aPixelRect.Right(); |
| } |
| else if ( pEntry->eType == SC_PLOC_COLHEADER ) |
| { |
| // column headers result in an additional row |
| bHasHeaderRow = sal_True; |
| aHeaderRect.Top() = pEntry->aPixelRect.Top(); |
| aHeaderRect.Bottom() = pEntry->aPixelRect.Bottom(); |
| } |
| } |
| |
| // |
| // get column info |
| // |
| |
| SCCOL nColCount = 0; |
| SCCOL nCol; |
| if ( bHasHeaderCol ) |
| ++nColCount; |
| if ( bHasRepCols ) |
| for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ ) |
| if (!pDoc->ColHidden(nCol, nTab)) |
| ++nColCount; |
| if ( bHasMainCols ) |
| for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ ) |
| if (!pDoc->ColHidden(nCol, nTab)) |
| ++nColCount; |
| |
| if ( nColCount > 0 ) |
| { |
| ScPreviewColRowInfo* pColInfo = new ScPreviewColRowInfo[ nColCount ]; |
| SCCOL nColPos = 0; |
| |
| if ( bHasHeaderCol ) |
| { |
| pColInfo[nColPos].Set( sal_True, 0, aHeaderRect.Left(), aHeaderRect.Right() ); |
| ++nColPos; |
| } |
| if ( bHasRepCols ) |
| { |
| long nPosX = 0; |
| for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ ) |
| if (!pDoc->ColHidden(nCol, nTab)) |
| { |
| sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab ); |
| long nNextX = nPosX + (long) (nDocW * nScaleX); |
| |
| long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width(); |
| long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1; |
| pColInfo[nColPos].Set( sal_False, nCol, |
| aRepeatRect.Left() + nPixelStart, |
| aRepeatRect.Left() + nPixelEnd ); |
| |
| nPosX = nNextX; |
| ++nColPos; |
| } |
| } |
| if ( bHasMainCols ) |
| { |
| long nPosX = 0; |
| for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ ) |
| if (!pDoc->ColHidden(nCol, nTab)) |
| { |
| sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab ); |
| long nNextX = nPosX + (long) (nDocW * nScaleX); |
| |
| long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width(); |
| long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1; |
| pColInfo[nColPos].Set( sal_False, nCol, |
| aMainRect.Left() + nPixelStart, |
| aMainRect.Left() + nPixelEnd ); |
| |
| nPosX = nNextX; |
| ++nColPos; |
| } |
| } |
| rInfo.SetColInfo( nColCount, pColInfo ); |
| } |
| else |
| rInfo.SetColInfo( 0, NULL ); |
| |
| // |
| // get row info |
| // |
| |
| SCROW nRowCount = 0; |
| if ( bHasHeaderRow ) |
| ++nRowCount; |
| if ( bHasRepRows ) |
| nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab); |
| if ( bHasMainRows ) |
| nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab); |
| |
| if ( nRowCount > 0 ) |
| { |
| ScPreviewColRowInfo* pRowInfo = new ScPreviewColRowInfo[ nRowCount ]; |
| SCROW nRowPos = 0; |
| |
| if ( bHasHeaderRow ) |
| { |
| pRowInfo[nRowPos].Set( sal_True, 0, aHeaderRect.Top(), aHeaderRect.Bottom() ); |
| ++nRowPos; |
| } |
| if ( bHasRepRows ) |
| { |
| long nPosY = 0; |
| for (SCROW nRow = nRepeatRowStart; nRow <= nRepeatRowEnd; ++nRow) |
| { |
| if (pDoc->RowHidden(nRow, nTab)) |
| continue; |
| |
| sal_uInt16 nDocH = pDoc->GetOriginalHeight( nRow, nTab ); |
| long nNextY = nPosY + (long) (nDocH * nScaleY); |
| |
| long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); |
| long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; |
| pRowInfo[nRowPos].Set( sal_False, nRow, |
| aRepeatRect.Top() + nPixelStart, |
| aRepeatRect.Top() + nPixelEnd ); |
| |
| nPosY = nNextY; |
| ++nRowPos; |
| } |
| } |
| if ( bHasMainRows ) |
| { |
| long nPosY = 0; |
| for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow) |
| { |
| if (pDoc->RowHidden(nRow, nTab)) |
| continue; |
| |
| sal_uInt16 nDocH = pDoc->GetOriginalHeight( nRow, nTab ); |
| long nNextY = nPosY + (long) (nDocH * nScaleY); |
| |
| long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); |
| long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; |
| pRowInfo[nRowPos].Set( sal_False, nRow, |
| aMainRect.Top() + nPixelStart, |
| aMainRect.Top() + nPixelEnd ); |
| |
| nPosY = nNextY; |
| ++nRowPos; |
| } |
| } |
| rInfo.SetRowInfo( nRowCount, pRowInfo ); |
| } |
| else |
| rInfo.SetRowInfo( 0, NULL ); |
| |
| // |
| // limit to visible area |
| // |
| |
| rInfo.SetTab( nTab ); |
| rInfo.LimitToArea( rVisiblePixel ); |
| } |
| |
| Rectangle ScPreviewLocationData::GetHeaderCellOutputRect(const Rectangle& rVisRect, const ScAddress& rCellPos, sal_Bool bColHeader) const |
| { |
| // first a stupid implementation |
| // NN says here should be done more |
| Rectangle aClipRect; |
| ScPreviewTableInfo aTableInfo; |
| GetTableInfo( rVisRect, aTableInfo ); |
| |
| if ( (rCellPos.Col() >= 0) && |
| (rCellPos.Row() >= 0) && (rCellPos.Col() < aTableInfo.GetCols()) && |
| (rCellPos.Row() < aTableInfo.GetRows()) ) |
| { |
| SCCOL nCol(0); |
| SCROW nRow(0); |
| if (bColHeader) |
| nCol = rCellPos.Col(); |
| else |
| nRow = rCellPos.Row(); |
| const ScPreviewColRowInfo& rColInfo = aTableInfo.GetColInfo()[nCol]; |
| const ScPreviewColRowInfo& rRowInfo = aTableInfo.GetRowInfo()[nRow]; |
| |
| if ( rColInfo.bIsHeader || rRowInfo.bIsHeader ) |
| aClipRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd ); |
| } |
| return aClipRect; |
| } |
| |
| Rectangle ScPreviewLocationData::GetCellOutputRect(const ScAddress& rCellPos) const |
| { |
| // first a stupid implementation |
| // NN says here should be done more |
| Rectangle aRect; |
| GetCellPosition(rCellPos, aRect); |
| return aRect; |
| } |
| |
| // GetMainCellRange is used for links in PDF export |
| |
| sal_Bool ScPreviewLocationData::GetMainCellRange( ScRange& rRange, Rectangle& rPixRect ) const |
| { |
| sal_uLong nCount = aEntries.Count(); |
| for (sal_uLong nListPos=0; nListPos<nCount; nListPos++) |
| { |
| ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos); |
| if ( pEntry->eType == SC_PLOC_CELLRANGE && !pEntry->bRepeatCol && !pEntry->bRepeatRow ) |
| { |
| rRange = pEntry->aCellRange; |
| rPixRect = pEntry->aPixelRect; |
| return sal_True; |
| } |
| } |
| return sal_False; // not found |
| } |
| |