diff options
Diffstat (limited to 'sc/source/core')
-rw-r--r-- | sc/source/core/data/column.cxx | 114 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 13 |
3 files changed, 142 insertions, 0 deletions
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index d40e359c5a67..462abe7c5561 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1205,6 +1205,120 @@ void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, bool bKee } } +namespace { + +class FindInRows : std::unary_function<ColEntry, bool> +{ + SCROW mnRow1; + SCROW mnRow2; +public: + FindInRows(SCROW nRow1, SCROW nRow2) : mnRow1(nRow1), mnRow2(nRow2) {} + bool operator() (const ColEntry& rEntry) + { + return mnRow1 <= rEntry.nRow && rEntry.nRow <= mnRow2; + } +}; + +class FindAboveRow : std::unary_function<ColEntry, bool> +{ + SCROW mnRow; +public: + FindAboveRow(SCROW nRow) : mnRow(nRow) {} + bool operator() (const ColEntry& rEntry) + { + return mnRow < rEntry.nRow; + } +}; + +struct DeleteCell : std::unary_function<ColEntry, void> +{ + void operator() (ColEntry& rEntry) + { + rEntry.pCell->Delete(); + } +}; + +} + +void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) +{ + if (nRow1 > nRow2) + return; + + // First, clear the destination column for the row range specified. + std::vector<ColEntry>::iterator it, itEnd; + + it = std::find_if(rDestCol.maItems.begin(), rDestCol.maItems.end(), FindInRows(nRow1, nRow2)); + if (it != rDestCol.maItems.end()) + { + itEnd = std::find_if(it, rDestCol.maItems.end(), FindAboveRow(nRow2)); + std::for_each(it, itEnd, DeleteCell()); + rDestCol.maItems.erase(it, itEnd); + } + + // Determine the range of cells in the original column that need to be copied. + it = std::find_if(maItems.begin(), maItems.end(), FindInRows(nRow1, nRow2)); + if (it != maItems.end()) + itEnd = std::find_if(it, maItems.end(), FindAboveRow(nRow2)); + + // Clone and staticize all cells that need to be copied. + std::vector<ColEntry> aCopied; + aCopied.reserve(std::distance(it, itEnd)); + for (; it != itEnd; ++it) + { + ColEntry aEntry; + aEntry.nRow = it->nRow; + switch (it->pCell->GetCellType()) + { + case CELLTYPE_VALUE: + { + const ScValueCell& rCell = static_cast<const ScValueCell&>(*it->pCell); + aEntry.pCell = new ScValueCell(rCell.GetValue()); + aCopied.push_back(aEntry); + } + break; + case CELLTYPE_STRING: + { + const ScStringCell& rCell = static_cast<const ScStringCell&>(*it->pCell); + aEntry.pCell = new ScStringCell(rCell.GetString()); + aCopied.push_back(aEntry); + } + break; + case CELLTYPE_EDIT: + { + // Convert to a simple string cell. + const ScEditCell& rCell = static_cast<const ScEditCell&>(*it->pCell); + aEntry.pCell = new ScStringCell(rCell.GetString()); + aCopied.push_back(aEntry); + } + break; + case CELLTYPE_FORMULA: + { + ScFormulaCell& rCell = static_cast<ScFormulaCell&>(*it->pCell); + if (rCell.GetDirty() && pDocument->GetAutoCalc()) + rCell.Interpret(); + + if (rCell.GetErrorCode()) + // Skip cells with error. + break; + + if (rCell.IsValue()) + aEntry.pCell = new ScValueCell(rCell.GetValue()); + else + aEntry.pCell = new ScStringCell(rCell.GetString()); + aCopied.push_back(aEntry); + } + break; + default: + ; // ignore the rest. + } + } + + // Insert the cells into destination column. At this point the + // destination column shouldn't have any cells within the specified range. + it = std::find_if(rDestCol.maItems.begin(), rDestCol.maItems.end(), FindAboveRow(nRow2)); + rDestCol.maItems.insert(it, aCopied.begin(), aCopied.end()); +} void ScColumn::CopyToColumn( SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked, ScColumn& rColumn, diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 65e904f1c923..95018d741a2f 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -1956,6 +1956,21 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam, pClipDoc->ExtendMerge(aClipRange, true); } +void ScDocument::CopyStaticToDocument(const ScRange& rSrcRange, SCTAB nDestTab, ScDocument* pDestDoc) +{ + if (!pDestDoc) + return; + + ScTable* pSrcTab = rSrcRange.aStart.Tab() < static_cast<SCTAB>(maTabs.size()) ? maTabs[rSrcRange.aStart.Tab()] : NULL; + ScTable* pDestTab = nDestTab < static_cast<SCTAB>(pDestDoc->maTabs.size()) ? pDestDoc->maTabs[nDestTab] : NULL; + + if (!pSrcTab || !pDestTab) + return; + + pSrcTab->CopyStaticToDocument( + rSrcRange.aStart.Col(), rSrcRange.aStart.Row(), rSrcRange.aEnd.Col(), rSrcRange.aEnd.Row(), pDestTab); +} + void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument* pClipDoc) diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 07ab79e8652c..f0bd119a0cc7 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -653,6 +653,19 @@ void ScTable::CopyToClip(const ScRangeList& rRanges, ScTable* pTable, } } +void ScTable::CopyStaticToDocument(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable* pDestTab) +{ + if (nCol1 > nCol2) + return; + + for (SCCOL i = nCol1; i <= nCol2; ++i) + { + ScColumn& rSrcCol = aCol[i]; + ScColumn& rDestCol = pDestTab->aCol[i]; + rSrcCol.CopyStaticToDocument(nRow1, nRow2, rDestCol); + } +} + void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCsCOL nDx, SCsROW nDy, ScTable* pTable) { |