diff options
author | Gökay Şatır <gokaysatir@collabora.com> | 2023-10-30 12:37:23 +0300 |
---|---|---|
committer | Gökay ŞATIR <gokaysatir@collabora.com> | 2024-05-10 08:07:11 +0200 |
commit | 8ab95722bc2e64a8cc1fd6b5aa36ecc599a8e1b6 (patch) | |
tree | 150490a8801cc0ddb55d5f85bb08aaa4a18497bb /sc | |
parent | 61ada4483c50d78387ff0ac45a97f2ee5b328029 (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.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/address.cxx | 21 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/view/viewfunc.cxx | 14 |
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); |