| /************************************************************** |
| * |
| * 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 <tools/table.hxx> |
| |
| #include "chartpos.hxx" |
| #include "document.hxx" |
| #include "rechead.hxx" |
| |
| namespace |
| { |
| bool lcl_hasValueDataButNoDates( ScDocument* pDocument, SCCOL nCol, SCROW nRow, SCTAB nTab ) |
| { |
| bool bReturn = false; |
| if (pDocument->HasValueData( nCol, nRow, nTab )) |
| { |
| //treat dates like text #i25706# |
| sal_uInt32 nNumberFormat = pDocument->GetNumberFormat( ScAddress( nCol, nRow, nTab ) ); |
| short nType = pDocument->GetFormatTable()->GetType(nNumberFormat); |
| bool bIsDate = (nType & NUMBERFORMAT_DATE); |
| bReturn = !bIsDate; |
| } |
| return bReturn; |
| } |
| } |
| |
| ScChartPositioner::ScChartPositioner( ScDocument* pDoc, SCTAB nTab, |
| SCCOL nStartColP, SCROW nStartRowP, SCCOL nEndColP, SCROW nEndRowP) : |
| pDocument( pDoc ), |
| pPositionMap( NULL ), |
| eGlue( SC_CHARTGLUE_NA ), |
| nStartCol(0), |
| nStartRow(0), |
| bColHeaders( sal_False ), |
| bRowHeaders( sal_False ), |
| bDummyUpperLeft( sal_False ) |
| { |
| SetRangeList( ScRange( nStartColP, nStartRowP, nTab, nEndColP, nEndRowP, nTab ) ); |
| CheckColRowHeaders(); |
| } |
| |
| ScChartPositioner::ScChartPositioner( ScDocument* pDoc, const ScRangeListRef& rRangeList ) : |
| aRangeListRef( rRangeList ), |
| pDocument( pDoc ), |
| pPositionMap( NULL ), |
| eGlue( SC_CHARTGLUE_NA ), |
| nStartCol(0), |
| nStartRow(0), |
| bColHeaders( sal_False ), |
| bRowHeaders( sal_False ), |
| bDummyUpperLeft( sal_False ) |
| { |
| if ( aRangeListRef.Is() ) |
| CheckColRowHeaders(); |
| } |
| |
| ScChartPositioner::ScChartPositioner( const ScChartPositioner& rPositioner ) : |
| aRangeListRef( rPositioner.aRangeListRef ), |
| pDocument(rPositioner.pDocument), |
| pPositionMap( NULL ), |
| eGlue(rPositioner.eGlue), |
| nStartCol(rPositioner.nStartCol), |
| nStartRow(rPositioner.nStartRow), |
| bColHeaders(rPositioner.bColHeaders), |
| bRowHeaders(rPositioner.bRowHeaders), |
| bDummyUpperLeft( rPositioner.bDummyUpperLeft ) |
| { |
| } |
| |
| ScChartPositioner::~ScChartPositioner() |
| { |
| delete pPositionMap; |
| } |
| |
| sal_Bool ScChartPositioner::operator==(const ScChartPositioner& rCmp) const |
| { |
| return bColHeaders == rCmp.bColHeaders |
| && bRowHeaders == rCmp.bRowHeaders |
| && *aRangeListRef == *rCmp.aRangeListRef; |
| } |
| |
| void ScChartPositioner::SetRangeList( const ScRange& rRange ) |
| { |
| aRangeListRef = new ScRangeList; |
| aRangeListRef->Append( rRange ); |
| InvalidateGlue(); |
| } |
| |
| void ScChartPositioner::GlueState() |
| { |
| if ( eGlue != SC_CHARTGLUE_NA ) |
| return; |
| bDummyUpperLeft = sal_False; |
| ScRangePtr pR; |
| if ( aRangeListRef->Count() <= 1 ) |
| { |
| if ( (pR = aRangeListRef->First())!=NULL ) |
| { |
| if ( pR->aStart.Tab() == pR->aEnd.Tab() ) |
| eGlue = SC_CHARTGLUE_NONE; |
| else |
| eGlue = SC_CHARTGLUE_COLS; // mehrere Tabellen spaltenweise |
| nStartCol = pR->aStart.Col(); |
| nStartRow = pR->aStart.Row(); |
| } |
| else |
| { |
| InvalidateGlue(); |
| nStartCol = 0; |
| nStartRow = 0; |
| } |
| return; |
| } |
| // sal_uLong nOldPos = aRangeListRef->GetCurPos(); |
| |
| pR = aRangeListRef->First(); |
| nStartCol = pR->aStart.Col(); |
| nStartRow = pR->aStart.Row(); |
| SCCOL nMaxCols, nEndCol; |
| SCROW nMaxRows, nEndRow; |
| nMaxCols = nEndCol = 0; |
| nMaxRows = nEndRow = 0; |
| do |
| { // umspannenden Bereich etc. feststellen |
| SCCOLROW nTmp, n1, n2; |
| if ( (n1 = pR->aStart.Col()) < nStartCol ) |
| nStartCol = static_cast<SCCOL>(n1); |
| if ( (n2 = pR->aEnd.Col()) > nEndCol ) |
| nEndCol = static_cast<SCCOL>(n2); |
| if ( (nTmp = n2 - n1 + 1) > nMaxCols ) |
| nMaxCols = static_cast<SCCOL>(nTmp); |
| if ( (n1 = pR->aStart.Row()) < nStartRow ) |
| nStartRow = static_cast<SCROW>(n1); |
| if ( (n2 = pR->aEnd.Row()) > nEndRow ) |
| nEndRow = static_cast<SCROW>(n2); |
| if ( (nTmp = n2 - n1 + 1) > nMaxRows ) |
| nMaxRows = static_cast<SCROW>(nTmp); |
| } while ( (pR = aRangeListRef->Next())!=NULL ); |
| SCCOL nC = nEndCol - nStartCol + 1; |
| if ( nC == 1 ) |
| { |
| eGlue = SC_CHARTGLUE_ROWS; |
| return; |
| } |
| SCROW nR = nEndRow - nStartRow + 1; |
| if ( nR == 1 ) |
| { |
| eGlue = SC_CHARTGLUE_COLS; |
| return; |
| } |
| sal_uLong nCR = (sal_uLong)nC * nR; |
| //2do: |
| /* |
| Erstmal simpel ohne Bitmaskiererei, maximal koennten so 8MB alloziert |
| werden (256 Cols mal 32000 Rows), das liesse sich mit 2 Bit je Eintrag |
| auf 2MB reduzieren, andererseits ist es so schneller. |
| Weitere Platz-Optimierung waere, in dem Array nur die wirklich benutzten |
| Zeilen/Spalten abzulegen, wuerde aber ein weiteres durchlaufen der |
| RangeList und indirekten Zugriff auf das Array bedeuten. |
| */ |
| const sal_uInt8 nHole = 0; |
| const sal_uInt8 nOccu = 1; |
| const sal_uInt8 nFree = 2; |
| const sal_uInt8 nGlue = 3; |
| sal_uInt8* p; |
| sal_uInt8* pA = new sal_uInt8[ nCR ]; |
| memset( pA, 0, nCR * sizeof(sal_uInt8) ); |
| |
| SCCOL nCol, nCol1, nCol2; |
| SCROW nRow, nRow1, nRow2; |
| for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() ) |
| { // Selektionen 2D als belegt markieren |
| nCol1 = pR->aStart.Col() - nStartCol; |
| nCol2 = pR->aEnd.Col() - nStartCol; |
| nRow1 = pR->aStart.Row() - nStartRow; |
| nRow2 = pR->aEnd.Row() - nStartRow; |
| for ( nCol = nCol1; nCol <= nCol2; nCol++ ) |
| { |
| p = pA + (sal_uLong)nCol * nR + nRow1; |
| for ( nRow = nRow1; nRow <= nRow2; nRow++, p++ ) |
| *p = nOccu; |
| } |
| } |
| sal_Bool bGlue = sal_True; |
| |
| sal_Bool bGlueCols = sal_False; |
| for ( nCol = 0; bGlue && nCol < nC; nCol++ ) |
| { // Spalten probieren durchzugehen und als frei markieren |
| p = pA + (sal_uLong)nCol * nR; |
| for ( nRow = 0; bGlue && nRow < nR; nRow++, p++ ) |
| { |
| if ( *p == nOccu ) |
| { // Wenn einer mittendrin liegt ist keine Zusammenfassung |
| // moeglich. Am Rand koennte ok sein, wenn in dieser Spalte |
| // in jeder belegten Zeile einer belegt ist. |
| if ( nRow > 0 && nCol > 0 ) |
| bGlue = sal_False; // nCol==0 kann DummyUpperLeft sein |
| else |
| nRow = nR; |
| } |
| else |
| *p = nFree; |
| } |
| if ( bGlue && *(p = (pA + ((((sal_uLong)nCol+1) * nR) - 1))) == nFree ) |
| { // Spalte als komplett frei markieren |
| *p = nGlue; |
| bGlueCols = sal_True; // mindestens eine freie Spalte |
| } |
| } |
| |
| sal_Bool bGlueRows = sal_False; |
| for ( nRow = 0; bGlue && nRow < nR; nRow++ ) |
| { // Zeilen probieren durchzugehen und als frei markieren |
| p = pA + nRow; |
| for ( nCol = 0; bGlue && nCol < nC; nCol++, p+=nR ) |
| { |
| if ( *p == nOccu ) |
| { |
| if ( nCol > 0 && nRow > 0 ) |
| bGlue = sal_False; // nRow==0 kann DummyUpperLeft sein |
| else |
| nCol = nC; |
| } |
| else |
| *p = nFree; |
| } |
| if ( bGlue && *(p = (pA + ((((sal_uLong)nC-1) * nR) + nRow))) == nFree ) |
| { // Zeile als komplett frei markieren |
| *p = nGlue; |
| bGlueRows = sal_True; // mindestens eine freie Zeile |
| } |
| } |
| |
| // n=1: die linke obere Ecke koennte bei Beschriftung automagisch |
| // hinzugezogen werden |
| p = pA + 1; |
| for ( sal_uLong n = 1; bGlue && n < nCR; n++, p++ ) |
| { // ein unberuehrtes Feld heisst, dass es weder spaltenweise noch |
| // zeilenweise zu erreichen war, also nichts zusamenzufassen |
| if ( *p == nHole ) |
| bGlue = sal_False; |
| } |
| if ( bGlue ) |
| { |
| if ( bGlueCols && bGlueRows ) |
| eGlue = SC_CHARTGLUE_BOTH; |
| else if ( bGlueRows ) |
| eGlue = SC_CHARTGLUE_ROWS; |
| else |
| eGlue = SC_CHARTGLUE_COLS; |
| if ( *pA != nOccu ) |
| bDummyUpperLeft = sal_True; |
| } |
| else |
| { |
| eGlue = SC_CHARTGLUE_NONE; |
| } |
| |
| delete [] pA; |
| } |
| |
| void ScChartPositioner::CheckColRowHeaders() |
| { |
| SCCOL nCol1, nCol2, iCol; |
| SCROW nRow1, nRow2, iRow; |
| SCTAB nTab1, nTab2; |
| |
| sal_Bool bColStrings = sal_True; |
| sal_Bool bRowStrings = sal_True; |
| GlueState(); |
| if ( aRangeListRef->Count() == 1 ) |
| { |
| aRangeListRef->First()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); |
| if ( nCol1 > nCol2 || nRow1 > nRow2 ) |
| bColStrings = bRowStrings = sal_False; |
| else |
| { |
| for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++) |
| { |
| if (lcl_hasValueDataButNoDates( pDocument, iCol, nRow1, nTab1 )) |
| bColStrings = sal_False; |
| } |
| for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++) |
| { |
| if (lcl_hasValueDataButNoDates( pDocument, nCol1, iRow, nTab1 )) |
| bRowStrings = sal_False; |
| } |
| } |
| } |
| else |
| { |
| sal_Bool bVert = (eGlue == SC_CHARTGLUE_NONE || eGlue == SC_CHARTGLUE_ROWS); |
| for ( ScRangePtr pR = aRangeListRef->First(); |
| pR && (bColStrings || bRowStrings); |
| pR = aRangeListRef->Next() ) |
| { |
| pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); |
| sal_Bool bTopRow = (nRow1 == nStartRow); |
| if ( bRowStrings && (bVert || nCol1 == nStartCol) ) |
| { // NONE oder ROWS: RowStrings in jeder Selektion moeglich |
| // COLS oder BOTH: nur aus der ersten Spalte |
| if ( nCol1 <= nCol2 ) |
| for (iRow=nRow1; iRow<=nRow2 && bRowStrings; iRow++) |
| { |
| if (lcl_hasValueDataButNoDates( pDocument, nCol1, iRow, nTab1 )) |
| bRowStrings = sal_False; |
| } |
| } |
| if ( bColStrings && bTopRow ) |
| { // ColStrings nur aus der ersten Zeile |
| if ( nRow1 <= nRow2 ) |
| for (iCol=nCol1; iCol<=nCol2 && bColStrings; iCol++) |
| { |
| if (lcl_hasValueDataButNoDates( pDocument, iCol, nRow1, nTab1 )) |
| bColStrings = sal_False; |
| } |
| } |
| } |
| } |
| bColHeaders = bColStrings; |
| bRowHeaders = bRowStrings; |
| } |
| |
| const ScChartPositionMap* ScChartPositioner::GetPositionMap() |
| { |
| CreatePositionMap(); |
| return pPositionMap; |
| } |
| |
| |
| void ScChartPositioner::CreatePositionMap() |
| { |
| if ( eGlue == SC_CHARTGLUE_NA && pPositionMap ) |
| { |
| delete pPositionMap; |
| pPositionMap = NULL; |
| } |
| |
| if ( pPositionMap ) |
| return ; |
| |
| SCSIZE nColAdd = bRowHeaders ? 1 : 0; |
| SCSIZE nRowAdd = bColHeaders ? 1 : 0; |
| |
| SCCOL nCol, nCol1, nCol2; |
| SCROW nRow, nRow1, nRow2; |
| SCTAB nTab, nTab1, nTab2; |
| |
| // |
| // wirkliche Groesse (ohne versteckte Zeilen/Spalten) |
| // |
| |
| SCSIZE nColCount = 0; |
| SCSIZE nRowCount = 0; |
| |
| GlueState(); |
| |
| sal_Bool bNoGlue = (eGlue == SC_CHARTGLUE_NONE); |
| Table* pCols = new Table; |
| Table* pNewRowTable = new Table; |
| ScAddress* pNewAddress = new ScAddress; |
| ScRangePtr pR; |
| Table* pCol; |
| ScAddress* pPos; |
| SCROW nNoGlueRow = 0; |
| for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() ) |
| { |
| pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); |
| for ( nTab = nTab1; nTab <= nTab2; nTab++ ) |
| { |
| // nTab im ColKey, um gleiche Col/Row in anderer Table haben zu koennen |
| sal_uLong nInsCol = (static_cast<sal_uLong>(nTab) << 16) | (bNoGlue ? 0 : |
| static_cast<sal_uLong>(nCol1)); |
| for ( nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol ) |
| { |
| if ( bNoGlue || eGlue == SC_CHARTGLUE_ROWS ) |
| { // meistens gleiche Cols |
| if ( (pCol = (Table*) pCols->Get( nInsCol ))==NULL ) |
| { |
| pCols->Insert( nInsCol, pNewRowTable ); |
| pCol = pNewRowTable; |
| pNewRowTable = new Table; |
| } |
| } |
| else |
| { // meistens neue Cols |
| if ( pCols->Insert( nInsCol, pNewRowTable ) ) |
| { |
| pCol = pNewRowTable; |
| pNewRowTable = new Table; |
| } |
| else |
| pCol = (Table*) pCols->Get( nInsCol ); |
| } |
| // bei anderer Tabelle wurde bereits neuer ColKey erzeugt, |
| // die Zeilen muessen fuer's Dummy fuellen gleich sein! |
| sal_uLong nInsRow = (bNoGlue ? nNoGlueRow : nRow1); |
| for ( nRow = nRow1; nRow <= nRow2; nRow++, nInsRow++ ) |
| { |
| if ( pCol->Insert( nInsRow, pNewAddress ) ) |
| { |
| pNewAddress->Set( nCol, nRow, nTab ); |
| pNewAddress = new ScAddress; |
| } |
| } |
| } |
| } |
| // bei NoGlue werden zusammengehoerige Tabellen als ColGlue dargestellt |
| nNoGlueRow += nRow2 - nRow1 + 1; |
| } |
| delete pNewAddress; |
| delete pNewRowTable; |
| |
| // Anzahl der Daten |
| nColCount = static_cast< SCSIZE >( pCols->Count()); |
| if ( (pCol = (Table*) pCols->First())!=NULL ) |
| { |
| if ( bDummyUpperLeft ) |
| pCol->Insert( 0, (void*)0 ); // Dummy fuer Beschriftung |
| nRowCount = static_cast< SCSIZE >( pCol->Count()); |
| } |
| else |
| nRowCount = 0; |
| if ( nColCount > 0 ) |
| nColCount -= nColAdd; |
| if ( nRowCount > 0 ) |
| nRowCount -= nRowAdd; |
| |
| if ( nColCount==0 || nRowCount==0 ) |
| { // einen Eintrag ohne Daten erzeugen |
| pR = aRangeListRef->First(); |
| if ( pCols->Count() > 0 ) |
| pCol = (Table*) pCols->First(); |
| else |
| { |
| pCol = new Table; |
| pCols->Insert( 0, pCol ); |
| } |
| nColCount = 1; |
| if ( pCol->Count() > 0 ) |
| { // kann ja eigentlich nicht sein, wenn nColCount==0 || nRowCount==0 |
| pPos = (ScAddress*) pCol->First(); |
| if ( pPos ) |
| { |
| delete pPos; |
| pCol->Replace( pCol->GetCurKey(), (void*)0 ); |
| } |
| } |
| else |
| pCol->Insert( 0, (void*)0 ); |
| nRowCount = 1; |
| nColAdd = 0; |
| nRowAdd = 0; |
| } |
| else |
| { |
| if ( bNoGlue ) |
| { // Luecken mit Dummies fuellen, erste Spalte ist Master |
| Table* pFirstCol = (Table*) pCols->First(); |
| sal_uLong nCount = pFirstCol->Count(); |
| pFirstCol->First(); |
| for ( sal_uLong n = 0; n < nCount; n++, pFirstCol->Next() ) |
| { |
| sal_uLong nKey = pFirstCol->GetCurKey(); |
| pCols->First(); |
| while ( (pCol = (Table*) pCols->Next())!=NULL ) |
| pCol->Insert( nKey, (void*)0 ); // keine Daten |
| } |
| } |
| } |
| |
| pPositionMap = new ScChartPositionMap( static_cast<SCCOL>(nColCount), static_cast<SCROW>(nRowCount), |
| static_cast<SCCOL>(nColAdd), static_cast<SCROW>(nRowAdd), *pCols ); |
| |
| // Aufraeumen |
| for ( pCol = (Table*) pCols->First(); pCol; pCol = (Table*) pCols->Next() ) |
| { //! nur Tables loeschen, nicht die ScAddress* |
| delete pCol; |
| } |
| delete pCols; |
| } |
| |
| |
| ScChartPositionMap::ScChartPositionMap( SCCOL nChartCols, SCROW nChartRows, |
| SCCOL nColAdd, SCROW nRowAdd, Table& rCols ) : |
| ppData( new ScAddress* [ nChartCols * nChartRows ] ), |
| ppColHeader( new ScAddress* [ nChartCols ] ), |
| ppRowHeader( new ScAddress* [ nChartRows ] ), |
| nCount( (sal_uLong) nChartCols * nChartRows ), |
| nColCount( nChartCols ), |
| nRowCount( nChartRows ) |
| { |
| DBG_ASSERT( nColCount && nRowCount, "ScChartPositionMap without dimension" ); |
| |
| ScAddress* pPos; |
| SCCOL nCol; |
| SCROW nRow; |
| |
| Table* pCol = (Table*) rCols.First(); |
| |
| // Zeilen-Header |
| pPos = (ScAddress*) pCol->First(); |
| if ( nRowAdd ) |
| pPos = (ScAddress*) pCol->Next(); |
| if ( nColAdd ) |
| { // eigenstaendig |
| for ( nRow = 0; nRow < nRowCount; nRow++ ) |
| { |
| ppRowHeader[ nRow ] = pPos; |
| pPos = (ScAddress*) pCol->Next(); |
| } |
| } |
| else |
| { // Kopie |
| for ( nRow = 0; nRow < nRowCount; nRow++ ) |
| { |
| ppRowHeader[ nRow ] = ( pPos ? new ScAddress( *pPos ) : NULL ); |
| pPos = (ScAddress*) pCol->Next(); |
| } |
| } |
| if ( nColAdd ) |
| pCol = (Table*) rCols.Next(); |
| |
| // Daten spaltenweise und Spalten-Header |
| sal_uLong nIndex = 0; |
| for ( nCol = 0; nCol < nColCount; nCol++ ) |
| { |
| if ( pCol ) |
| { |
| pPos = (ScAddress*) pCol->First(); |
| if ( nRowAdd ) |
| { |
| ppColHeader[ nCol ] = pPos; // eigenstaendig |
| pPos = (ScAddress*) pCol->Next(); |
| } |
| else |
| ppColHeader[ nCol ] = ( pPos ? new ScAddress( *pPos ) : NULL ); |
| for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ ) |
| { |
| ppData[ nIndex ] = pPos; |
| pPos = (ScAddress*) pCol->Next(); |
| } |
| } |
| else |
| { |
| ppColHeader[ nCol ] = NULL; |
| for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ ) |
| { |
| ppData[ nIndex ] = NULL; |
| } |
| } |
| pCol = (Table*) rCols.Next(); |
| } |
| } |
| |
| |
| ScChartPositionMap::~ScChartPositionMap() |
| { |
| for ( sal_uLong nIndex=0; nIndex < nCount; nIndex++ ) |
| { |
| delete ppData[nIndex]; |
| } |
| delete [] ppData; |
| |
| SCCOL j; |
| for ( j=0; j < nColCount; j++ ) |
| { |
| delete ppColHeader[j]; |
| } |
| delete [] ppColHeader; |
| SCROW i; |
| for ( i=0; i < nRowCount; i++ ) |
| { |
| delete ppRowHeader[i]; |
| } |
| delete [] ppRowHeader; |
| } |
| |
| |
| //UNUSED2009-05 ScRangeListRef ScChartPositionMap::GetColRanges( SCCOL nChartCol ) const |
| //UNUSED2009-05 { |
| //UNUSED2009-05 ScRangeListRef xRangeList = new ScRangeList; |
| //UNUSED2009-05 if ( nChartCol < nColCount ) |
| //UNUSED2009-05 { |
| //UNUSED2009-05 sal_uLong nStop = GetIndex( nChartCol, nRowCount ); |
| //UNUSED2009-05 for ( sal_uLong nIndex = GetIndex( nChartCol, 0 ); nIndex < nStop; nIndex++ ) |
| //UNUSED2009-05 { |
| //UNUSED2009-05 if ( ppData[ nIndex ] ) |
| //UNUSED2009-05 xRangeList->Join( *ppData[ nIndex ] ); |
| //UNUSED2009-05 } |
| //UNUSED2009-05 } |
| //UNUSED2009-05 return xRangeList; |
| //UNUSED2009-05 } |
| |
| |
| //UNUSED2009-05 ScRangeListRef ScChartPositionMap::GetRowRanges( SCROW nChartRow ) const |
| //UNUSED2009-05 { |
| //UNUSED2009-05 ScRangeListRef xRangeList = new ScRangeList; |
| //UNUSED2009-05 if ( nChartRow < nRowCount ) |
| //UNUSED2009-05 { |
| //UNUSED2009-05 sal_uLong nStop = GetIndex( nColCount, nChartRow ); |
| //UNUSED2009-05 for ( sal_uLong nIndex = GetIndex( 0, nChartRow ); nIndex < nStop; |
| //UNUSED2009-05 nIndex += nRowCount ) |
| //UNUSED2009-05 { |
| //UNUSED2009-05 if ( ppData[ nIndex ] ) |
| //UNUSED2009-05 xRangeList->Join( *ppData[ nIndex ] ); |
| //UNUSED2009-05 } |
| //UNUSED2009-05 } |
| //UNUSED2009-05 return xRangeList; |
| //UNUSED2009-05 } |