diff options
-rw-r--r-- | sc/source/core/data/column3.cxx | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 3af350d2aaf9..73da282cc1f2 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -541,21 +541,33 @@ class DeleteAreaHandler bool mbNumeric:1; bool mbString:1; bool mbFormula:1; + bool mbDateTime:1; + ScColumn& mrCol; public: - DeleteAreaHandler(ScDocument& rDoc, InsertDeleteFlags nDelFlag) : + DeleteAreaHandler(ScDocument& rDoc, InsertDeleteFlags nDelFlag, ScColumn& rCol) : mrDoc(rDoc), mbNumeric(nDelFlag & InsertDeleteFlags::VALUE), mbString(nDelFlag & InsertDeleteFlags::STRING), - mbFormula(nDelFlag & InsertDeleteFlags::FORMULA) {} + mbFormula(nDelFlag & InsertDeleteFlags::FORMULA), + mbDateTime(nDelFlag & InsertDeleteFlags::DATETIME), + mrCol(rCol) {} void operator() (const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize) { switch (node.type) { case sc::element_type_numeric: - if (!mbNumeric) + // Numeric type target datetime and number, thus we have a dedicated function + if (!mbNumeric && !mbDateTime) return; + + // If numeric and datetime selected, delete full range + if (mbNumeric && mbDateTime) + break; + + deleteNumeric(node, nOffset, nDataSize); + return; break; case sc::element_type_string: case sc::element_type_edittext: @@ -587,6 +599,55 @@ public: maDeleteRanges.set(nRow1, nRow2, true); } + void deleteNumeric(const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize) + { + size_t nStart = node.position + nOffset; + size_t nElements = 1; + bool bLastTypeDateTime = isDateTime(nStart); // true = datetime, false = numeric + size_t nCount = nStart + nDataSize; + + for (size_t i = nStart + 1; i < nCount; i++) + { + bool bIsDateTime = isDateTime(i); + + // same type as previous + if (bIsDateTime == bLastTypeDateTime) + { + nElements++; + } + // type switching + else + { + deleteNumberOrDateTime(nStart, nStart + nElements - 1, bLastTypeDateTime); + nStart += nElements; + nElements = 1; + } + + bLastTypeDateTime = bIsDateTime; + } + + // delete last cells + deleteNumberOrDateTime(nStart, nStart + nElements - 1, bLastTypeDateTime); + } + + void deleteNumberOrDateTime(SCROW nRow1, SCROW nRow2, bool dateTime) + { + if (!dateTime && !mbNumeric) // numeric flag must be selected + return; + if (dateTime && !mbDateTime) // datetime flag must be selected + return; + maDeleteRanges.set(nRow1, nRow2, true); + } + + bool isDateTime(size_t position) + { + short nType = mrDoc.GetFormatTable()->GetType(static_cast<const SfxUInt32Item&>( + mrCol.GetAttr(position, ATTR_VALUE_FORMAT)).GetValue()); + + return (nType == css::util::NumberFormat::DATE) || (nType == css::util::NumberFormat::TIME) || + (nType == css::util::NumberFormat::DATETIME); + } + void endFormulas() { mrDoc.EndListeningFormulaCells(maFormulaCells); @@ -639,7 +700,7 @@ void ScColumn::DeleteCells( sc::SingleColumnSpanSet& rDeleted ) { // Determine which cells to delete based on the deletion flags. - DeleteAreaHandler aFunc(*pDocument, nDelFlag); + DeleteAreaHandler aFunc(*pDocument, nDelFlag, *this); sc::CellStoreType::iterator itPos = maCells.position(rBlockPos.miCellPos, nRow1).first; sc::ProcessBlock(itPos, maCells, aFunc, nRow1, nRow2); aFunc.endFormulas(); // Have the formula cells stop listening. |