summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/source/core/data/column3.cxx69
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.