diff options
Diffstat (limited to 'sc/source/core/data')
-rw-r--r-- | sc/source/core/data/column2.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/conditio.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/dpcache.cxx | 21 | ||||
-rw-r--r-- | sc/source/core/data/dpcachetable.cxx | 204 | ||||
-rw-r--r-- | sc/source/core/data/dpgroup.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/dptabdat.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 18 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 4 |
9 files changed, 169 insertions, 107 deletions
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index c28249a6d827..03f7b5421ac9 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1131,7 +1131,8 @@ bool ScColumn::IsEmptyVisData() const SCSIZE i; for (i=0; i<maItems.size() && !bVisData; i++) { - bVisData = true; + if(!maItems[i].pCell->IsBlank()) + bVisData = true; } return !bVisData; } @@ -1165,8 +1166,11 @@ SCROW ScColumn::GetLastVisDataPos() const for (i=maItems.size(); i>0 && !bFound; ) { --i; - bFound = true; - nRet = maItems[i].nRow; + if(!maItems[i].pCell->IsBlank()) + { + bFound = true; + nRet = maItems[i].nRow; + } } } return nRet; diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 48d77dc6f5fc..475299da6293 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -1501,6 +1501,10 @@ void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, std::vector<ScTy } break; + // skip broadcaster cells + case CELLTYPE_NOTE: + continue; + default: ; } diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx index 9561d64d1e62..ea6657addea2 100644 --- a/sc/source/core/data/conditio.cxx +++ b/sc/source/core/data/conditio.cxx @@ -66,7 +66,6 @@ bool ScFormatEntry::operator==( const ScFormatEntry& r ) const { case condformat::CONDITION: return static_cast<const ScCondFormatEntry&>(*this) == static_cast<const ScCondFormatEntry&>(r); - break; default: // TODO: implement also this case // actually return false for these cases is not that bad @@ -74,8 +73,6 @@ bool ScFormatEntry::operator==( const ScFormatEntry& r ) const // to think about the range return false; } - - return true; } bool lcl_HasRelRef( ScDocument* pDoc, ScTokenArray* pFormula, sal_uInt16 nRecursion = 0 ) diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx index f1e45318cb7e..c754fba1549d 100644 --- a/sc/source/core/data/dpcache.cxx +++ b/sc/source/core/data/dpcache.cxx @@ -73,6 +73,7 @@ ScDPCache::ScDPCache(ScDocument* pDoc) : mpDoc( pDoc ), mnColumnCount ( 0 ), maEmptyRows(0, MAXROW, true), + mnDataSize(-1), mbDisposing(false) { } @@ -751,7 +752,21 @@ public: void ScDPCache::PostInit() { + OSL_ENSURE(!maFields.empty(), "Cache not initialized!"); + maEmptyRows.build_tree(); + typedef mdds::flat_segment_tree<SCROW, bool>::const_reverse_iterator itr_type; + itr_type it = maEmptyRows.rbegin(), itEnd = maEmptyRows.rend(); + OSL_ENSURE(it != itEnd, "corrupt flat_segment_tree instance!"); + mnDataSize = maFields[0].maData.size(); + ++it; // Skip the first position. + OSL_ENSURE(it != itEnd, "buggy version of flat_segment_tree is used."); + if (it->second) + { + SCROW nLastNonEmpty = it->first - 1; + if (nLastNonEmpty+1 < mnDataSize) + mnDataSize = nLastNonEmpty+1; + } } void ScDPCache::Clear() @@ -850,6 +865,12 @@ SCROW ScDPCache::GetRowCount() const return maFields[0].maData.size(); } +SCROW ScDPCache::GetDataSize() const +{ + OSL_ENSURE(mnDataSize <= GetRowCount(), "Data size should never be larger than the row count."); + return mnDataSize >= 0 ? mnDataSize : 0; +} + const ScDPCache::ItemsType& ScDPCache::GetDimMemberValues(SCCOL nDim) const { OSL_ENSURE( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount "); diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx index dc7a63a8b637..14f4e8e2e48e 100644 --- a/sc/source/core/data/dpcachetable.cxx +++ b/sc/source/core/data/dpcachetable.cxx @@ -64,17 +64,6 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::sheet::DataPilotFieldFilter; -bool ScDPCacheTable::RowFlag::isActive() const -{ - return mbShowByFilter && mbShowByPage; -} - -ScDPCacheTable::RowFlag::RowFlag() : - mbShowByFilter(true), - mbShowByPage(true) -{ -} - ScDPCacheTable::SingleFilter::SingleFilter(const ScDPItemData& rItem) : maItem(rItem) {} @@ -125,7 +114,7 @@ ScDPCacheTable::Criterion::Criterion() : // ---------------------------------------------------------------------------- ScDPCacheTable::ScDPCacheTable(const ScDPCache* pCache) : - mpCache(pCache) + maShowByFilter(0, MAXROW+1, false), maShowByPage(0, MAXROW+1, true), mpCache(pCache) { } @@ -146,124 +135,145 @@ sal_Int32 ScDPCacheTable::getColSize() const void ScDPCacheTable::fillTable( const ScQueryParam& rQuery, bool bIgnoreEmptyRows, bool bRepeatIfEmpty) { - const SCROW nRowCount = getRowSize(); - const SCCOL nColCount = (SCCOL) getColSize(); - if ( nRowCount <= 0 || nColCount <= 0) + SCROW nRowCount = getRowSize(); + SCROW nDataSize = mpCache->GetDataSize(); + SCCOL nColCount = getColSize(); + if (nRowCount <= 0 || nColCount <= 0) return; - maRowFlags.clear(); - maRowFlags.reserve(nRowCount); + maShowByFilter.clear(); + maShowByPage.clear(); - // Initialize field entries container. - maFieldEntries.clear(); - maFieldEntries.reserve(nColCount); - - // Data rows - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) + // Process the non-empty data rows. + for (SCROW nRow = 0; nRow < nDataSize; ++nRow) { - maFieldEntries.push_back( vector<SCROW>() ); - SCROW nMemCount = getCache()->GetDimMemberCount( nCol ); - if ( nMemCount ) - { - std::vector<SCROW> aAdded( nMemCount, -1 ); - - for (SCROW nRow = 0; nRow < nRowCount; ++nRow ) - { - SCROW nIndex = getCache()->GetItemDataId( nCol, nRow, bRepeatIfEmpty ); - SCROW nOrder = getOrder( nCol, nIndex ); - - if ( nCol == 0 ) - { - maRowFlags.push_back(RowFlag()); - maRowFlags.back().mbShowByFilter = false; - } - - if (!getCache()->ValidQuery(nRow, rQuery)) - continue; - - if ( bIgnoreEmptyRows && getCache()->IsRowEmpty( nRow ) ) - continue; + if (!getCache()->ValidQuery(nRow, rQuery)) + continue; - if ( nCol == 0 ) - maRowFlags.back().mbShowByFilter = true; + if (bIgnoreEmptyRows && getCache()->IsRowEmpty(nRow)) + continue; - aAdded[nOrder] = nIndex; - } - for ( SCROW nRow = 0; nRow < nMemCount; nRow++ ) - { - if ( aAdded[nRow] != -1 ) - maFieldEntries.back().push_back( aAdded[nRow] ); - } - } + maShowByFilter.insert_back(nRow, nRow+1, true); } -} -void ScDPCacheTable::fillTable() -{ - const SCROW nRowCount = getRowSize(); - const SCCOL nColCount = (SCCOL) getColSize(); - if ( nRowCount <= 0 || nColCount <= 0) - return; - - maRowFlags.clear(); - maRowFlags.reserve(nRowCount); + // Process the trailing empty rows. + if (!bIgnoreEmptyRows) + maShowByFilter.insert_back(nDataSize, nRowCount, true); + maShowByFilter.build_tree(); // Initialize field entries container. maFieldEntries.clear(); maFieldEntries.reserve(nColCount); - // Data rows + // Build unique field entries. for (SCCOL nCol = 0; nCol < nColCount; ++nCol) { maFieldEntries.push_back( vector<SCROW>() ); SCROW nMemCount = getCache()->GetDimMemberCount( nCol ); - if ( nMemCount ) - { - std::vector< SCROW > pAdded( nMemCount, -1 ); + if (!nMemCount) + continue; - for (SCROW nRow = 0; nRow < nRowCount; ++nRow ) + std::vector<SCROW> aAdded(nMemCount, -1); + bool bShow = false; + SCROW nEndSegment = -1; + for (SCROW nRow = 0; nRow < nRowCount; ++nRow) + { + if (nRow > nEndSegment) { - SCROW nIndex = getCache()->GetItemDataId( nCol, nRow, false ); - SCROW nOrder = getOrder( nCol, nIndex ); - - if ( nCol == 0 ) + if (!maShowByFilter.search_tree(nRow, bShow, NULL, &nEndSegment)) { - maRowFlags.push_back(RowFlag()); - maRowFlags.back().mbShowByFilter = true; + OSL_FAIL("Tree search failed!"); + continue; } - - pAdded[nOrder] = nIndex; + --nEndSegment; // End position is not inclusive. Move back one. } - for ( SCROW nRow = 0; nRow < nMemCount; nRow++ ) + + if (!bShow) { - if ( pAdded[nRow] != -1 ) - maFieldEntries.back().push_back( pAdded[nRow] ); + nRow = nEndSegment; + continue; } + + SCROW nIndex = getCache()->GetItemDataId(nCol, nRow, bRepeatIfEmpty); + SCROW nOrder = getOrder(nCol, nIndex); + aAdded[nOrder] = nIndex; + } + for (SCROW nRow = 0; nRow < nMemCount; ++nRow) + { + if (aAdded[nRow] != -1) + maFieldEntries.back().push_back(aAdded[nRow]); } } } -bool ScDPCacheTable::isRowActive(sal_Int32 nRow) const +void ScDPCacheTable::fillTable() { - if (nRow < 0 || static_cast<size_t>(nRow) >= maRowFlags.size()) - // row index out of bound - return false; + SCROW nRowCount = getRowSize(); + SCCOL nColCount = getColSize(); + if (nRowCount <= 0 || nColCount <= 0) + return; + + maShowByFilter.clear(); + maShowByPage.clear(); + maShowByFilter.insert_front(0, nRowCount, true); + + // Initialize field entries container. + maFieldEntries.clear(); + maFieldEntries.reserve(nColCount); + + // Data rows + for (SCCOL nCol = 0; nCol < nColCount; ++nCol) + { + maFieldEntries.push_back( vector<SCROW>() ); + SCROW nMemCount = getCache()->GetDimMemberCount( nCol ); + if (!nMemCount) + continue; + + std::vector<SCROW> aAdded(nMemCount, -1); + + for (SCROW nRow = 0; nRow < nRowCount; ++nRow) + { + SCROW nIndex = getCache()->GetItemDataId(nCol, nRow, false); + SCROW nOrder = getOrder(nCol, nIndex); + aAdded[nOrder] = nIndex; + } + for (SCROW nRow = 0; nRow < nMemCount; ++nRow) + { + if (aAdded[nRow] != -1) + maFieldEntries.back().push_back(aAdded[nRow]); + } + } +} + +bool ScDPCacheTable::isRowActive(sal_Int32 nRow, sal_Int32* pLastRow) const +{ + bool bFilter = false, bPage = true; + SCROW nLastRowFilter = MAXROW, nLastRowPage = MAXROW; + maShowByFilter.search_tree(nRow, bFilter, NULL, &nLastRowFilter); + maShowByPage.search_tree(nRow, bPage, NULL, &nLastRowPage); + if (pLastRow) + { + // Return the last row of current segment. + *pLastRow = nLastRowFilter < nLastRowPage ? nLastRowFilter : nLastRowPage; + *pLastRow -= 1; // End position is not inclusive. Move back one. + } - return maRowFlags[nRow].isActive(); + return bFilter && bPage; } void ScDPCacheTable::filterByPageDimension(const vector<Criterion>& rCriteria, const boost::unordered_set<sal_Int32>& rRepeatIfEmptyDims) { - sal_Int32 nRowSize = getRowSize(); - if (nRowSize != static_cast<sal_Int32>(maRowFlags.size())) + SCROW nRowSize = getRowSize(); + + maShowByPage.clear(); + for (SCROW nRow = 0; nRow < nRowSize; ++nRow) { - // sizes of the two tables differ! - return; + bool bShow = isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims); + maShowByPage.insert_back(nRow, nRow+1, bShow); } - for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow) - maRowFlags[nRow].mbShowByPage = isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims); + maShowByPage.build_tree(); } const ScDPItemData* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const @@ -333,12 +343,15 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S } tableData.push_back(headerRow); - for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow) { - if (!maRowFlags[nRow].isActive()) + sal_Int32 nLastRow; + if (!isRowActive(nRow, &nLastRow)) + { // This row is filtered out. + nRow = nLastRow; continue; + } if (!isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims)) continue; @@ -378,7 +391,8 @@ SCROW ScDPCacheTable::getOrder(long nDim, SCROW nIndex) const void ScDPCacheTable::clear() { maFieldEntries.clear(); - maRowFlags.clear(); + maShowByFilter.clear(); + maShowByPage.clear(); } bool ScDPCacheTable::empty() const diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index 91e9ccee3c8d..ea04b7c32fd8 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -767,8 +767,12 @@ void ScDPGroupTableData::CalcResults(CalcInfo& rInfo, bool bAutoShow) sal_Int32 nRowSize = rCacheTable.getRowSize(); for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow) { - if (!rCacheTable.isRowActive(nRow)) + sal_Int32 nLastRow; + if (!rCacheTable.isRowActive(nRow, &nLastRow)) + { + nRow = nLastRow; continue; + } CalcRowData aData; FillRowDataFromCacheTable(nRow, rCacheTable, rInfo, aData); diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx index a2566bec5d2e..060090876b97 100644 --- a/sc/source/core/data/dptabdat.cxx +++ b/sc/source/core/data/dptabdat.cxx @@ -226,8 +226,12 @@ void ScDPTableData::CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, sal_Int32 nRowSize = rCacheTable.getRowSize(); for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow) { - if (!rCacheTable.isRowActive(nRow)) + sal_Int32 nLastRow; + if (!rCacheTable.isRowActive(nRow, &nLastRow)) + { + nRow = nLastRow; continue; + } CalcRowData aData; FillRowDataFromCacheTable(nRow, rCacheTable, rInfo, aData); diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 4230cbd764a5..cd193c142009 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -267,8 +267,13 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE if (nRow >= nStartRow) { - aNotes.insert(nCol, nRow - nSize, pPostIt); - maNotes.ReleaseNote(nCol, nRow); + if(nRow - nStartRow > static_cast<SCROW>(nSize)) + { + aNotes.insert(nCol, nRow - nSize, pPostIt); + maNotes.ReleaseNote(nCol, nRow); + } + else + maNotes.erase(nCol, nRow); } } @@ -486,8 +491,13 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE if (nCol >= nStartCol) { - aNotes.insert(nCol - nSize, nRow, pPostIt); - maNotes.ReleaseNote(nCol, nRow); + if(nCol - nStartCol > static_cast<SCCOL>(nSize)) + { + aNotes.insert(nCol - nSize, nRow, pPostIt); + maNotes.ReleaseNote(nCol, nRow); + } + else + maNotes.erase(nCol, nRow); } } diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 15087c551f72..7be749ed91e9 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -386,10 +386,14 @@ short ScTable::CompareCell( sal_uInt16 nSort, if (pCell1) { eType1 = pCell1->GetCellType(); + if (eType1 == CELLTYPE_NOTE) + pCell1 = NULL; } if (pCell2) { eType2 = pCell2->GetCellType(); + if (eType2 == CELLTYPE_NOTE) + pCell2 = NULL; } if (pCell1) |