summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorGökay Şatır <gokaysatir@collabora.com>2023-10-30 12:37:23 +0300
committerGökay ŞATIR <gokaysatir@collabora.com>2024-05-10 08:07:11 +0200
commit8ab95722bc2e64a8cc1fd6b5aa36ecc599a8e1b6 (patch)
tree150490a8801cc0ddb55d5f85bb08aaa4a18497bb /sc
parent61ada4483c50d78387ff0ac45a97f2ee5b328029 (diff)
Fix row deletion bug.
When multiple users are editing a Calc document: * If one user selects a whole row and another one deletes a range of rows including or above the selected row, app crashes. * This PR fixes the crash. * Also when multiple rows are deleted, other user's selected row is moved only one row. This PR moves the selected row according to the deleted row count. * The cursor position was also causing a crash, fixed. Signed-off-by: Gökay Şatır <gokaysatir@collabora.com> Change-Id: Ie4b893fee7192492efacbb167b747434336384e3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158650 Reviewed-by: Marco Cecchetti <marco.cecchetti@collabora.com> Tested-by: Marco Cecchetti <marco.cecchetti@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167374 Tested-by: Jenkins
Diffstat (limited to 'sc')
-rw-r--r--sc/source/core/data/markdata.cxx6
-rw-r--r--sc/source/core/tool/address.cxx21
-rw-r--r--sc/source/ui/docshell/docfunc.cxx4
-rw-r--r--sc/source/ui/view/viewfunc.cxx14
4 files changed, 31 insertions, 14 deletions
diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx
index afc875983ab1..98a3aebe5c8b 100644
--- a/sc/source/core/data/markdata.cxx
+++ b/sc/source/core/data/markdata.cxx
@@ -670,13 +670,11 @@ void ScMarkData::ShiftCols(const ScDocument& rDoc, SCCOL nStartCol, sal_Int32 nC
void ScMarkData::ShiftRows(const ScDocument& rDoc, SCROW nStartRow, sal_Int32 nRowOffset)
{
if (bMarked)
- {
aMarkRange.IncRowIfNotLessThan(rDoc, nStartRow, nRowOffset);
- }
- else if (bMultiMarked)
+ if (bMultiMarked)
{
- aMultiSel.ShiftRows(nStartRow, nRowOffset);
aMultiRange.IncRowIfNotLessThan(rDoc, nStartRow, nRowOffset);
+ aMultiSel.ShiftRows(nStartRow, nRowOffset);
}
}
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index ba6f73f47bec..b976443fc649 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -2405,17 +2405,30 @@ void ScRange::IncColIfNotLessThan(const ScDocument& rDoc, SCCOL nStartCol, SCCOL
void ScRange::IncRowIfNotLessThan(const ScDocument& rDoc, SCROW nStartRow, SCROW nOffset)
{
- if (aStart.Row() >= nStartRow)
+ SCROW offset;
+ if (aStart.Row() > nStartRow)
{
- aStart.IncRow(nOffset);
+ offset = nOffset;
+ if (nStartRow + nOffset > aStart.Row())
+ offset = aStart.Row() - nStartRow;
+ else if (nStartRow - nOffset > aStart.Row())
+ offset = -1 * (aStart.Row() - nStartRow);
+
+ aStart.IncRow(offset);
if (aStart.Row() < 0)
aStart.SetRow(0);
else if(aStart.Row() > rDoc.MaxRow())
aStart.SetRow(rDoc.MaxRow());
}
- if (aEnd.Row() >= nStartRow)
+ if (aEnd.Row() > nStartRow)
{
- aEnd.IncRow(nOffset);
+ offset = nOffset;
+ if (nStartRow + nOffset > aEnd.Row())
+ offset = aEnd.Row() - nStartRow;
+ else if (nStartRow - nOffset > aEnd.Row())
+ offset = -1 * (aEnd.Row() - nStartRow);
+
+ aEnd.IncRow(offset);
if (aEnd.Row() < 0)
aEnd.SetRow(0);
else if(aEnd.Row() > rDoc.MaxRow())
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 55f9c209f599..556cd6e6c940 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -2280,7 +2280,7 @@ bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
if (bInsertRows)
{
- pViewSh->OnLOKInsertDeleteRow(rRange.aStart.Row(), 1);
+ pViewSh->OnLOKInsertDeleteRow(rRange.aStart.Row() - (eCmd == INS_INSROWS_BEFORE ? 1: 0), 1);
}
}
@@ -2860,7 +2860,7 @@ bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
}
if (eCmd == DelCellCmd::Rows)
{
- pViewSh->OnLOKInsertDeleteRow(rRange.aStart.Row(), -1);
+ pViewSh->OnLOKInsertDeleteRow(rRange.aStart.Row(), -1 * (rRange.aEnd.Row() - rRange.aStart.Row() + 1));
}
}
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index d0945c76febc..679f60295aff 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -1776,11 +1776,17 @@ void ScViewFunc::OnLOKInsertDeleteRow(SCROW nStartRow, tools::Long nOffset)
if (pTabViewShell->getPart() == nCurrentTabIndex)
{
SCROW nY = pTabViewShell->GetViewData().GetCurY();
- if (nY > nStartRow || (nY == nStartRow && nOffset > 0))
+ if (nY > nStartRow)
{
+ tools::Long offset = nOffset;
+ if (nOffset + nStartRow > nY)
+ offset = nY - nStartRow;
+ else if (nOffset < 0 && nStartRow - nOffset > nY)
+ offset = -1 * (nY - nStartRow);
+
ScInputHandler* pInputHdl = pTabViewShell->GetInputHandler();
SCCOL nX = pTabViewShell->GetViewData().GetCurX();
- pTabViewShell->SetCursor(nX, nY + nOffset);
+ pTabViewShell->SetCursor(nX, nY + offset);
if (pInputHdl && pInputHdl->IsInputMode())
{
pInputHdl->SetModified();
@@ -1789,8 +1795,8 @@ void ScViewFunc::OnLOKInsertDeleteRow(SCROW nStartRow, tools::Long nOffset)
ScMarkData aMultiMark( pTabViewShell->GetViewData().GetMarkData() );
aMultiMark.SetMarking( false );
- aMultiMark.MarkToMulti();
- if (aMultiMark.IsMultiMarked())
+
+ if (aMultiMark.IsMultiMarked() || aMultiMark.IsMarked())
{
aMultiMark.ShiftRows(pTabViewShell->GetViewData().GetDocument(), nStartRow, nOffset);
pTabViewShell->SetMarkData(aMultiMark);