sc/source/ui/inc/tabvwsh.hxx | 8 +- sc/source/ui/view/tabvwsh3.cxx | 14 ++- sc/source/ui/view/tabvwsh4.cxx | 150 +++++++++++++++++++++++++++++------------ 3 files changed, 124 insertions(+), 48 deletions(-)
New commits: commit f9fcd884a37bc8adb3fab72b781985a652e1af12 Author: Noel Grandin <[email protected]> AuthorDate: Thu Jan 29 16:59:55 2026 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Thu Jan 29 19:09:29 2026 +0100 tdf#166121 split HandleDuplicateRecords method into two different methods for the different cases, so we can optimise the remove case more easily. Change-Id: Id57875f2b28b7ac5909b32c7df3dbfb817642e82 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198373 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx index a7ba9ed4b659..5feca801d4e0 100644 --- a/sc/source/ui/inc/tabvwsh.hxx +++ b/sc/source/ui/inc/tabvwsh.hxx @@ -273,8 +273,12 @@ public: SC_DLLPUBLIC bool IsRefInputMode() const; void ExecuteInputDirect(); - void HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj>& ActiveSheet, - const css::table::CellRangeAddress& aRange, bool bRemove, + void HandleDuplicateRecordsHighlight(const rtl::Reference<ScTableSheetObj>& ActiveSheet, + const css::table::CellRangeAddress& aRange, + bool bIncludesHeaders, bool bDuplicateRows, + const std::vector<int>& rSelectedEntries); + void HandleDuplicateRecordsRemove(const rtl::Reference<ScTableSheetObj>& ActiveSheet, + const css::table::CellRangeAddress& aRange, bool bIncludesHeaders, bool bDuplicateRows, const std::vector<int>& rSelectedEntries); rtl::Reference<ScTableSheetObj> GetRangeWithSheet(css::table::CellRangeAddress& rRangeData, bool& bHasData, bool bHasUnoArguments); diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx index a4536393a88b..8fe42865d631 100644 --- a/sc/source/ui/view/tabvwsh3.cxx +++ b/sc/source/ui/view/tabvwsh3.cxx @@ -16,7 +16,6 @@ * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> #include <sfx2/passwd.hxx> @@ -938,9 +937,16 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) } if (bHasData) - GetViewData().GetViewShell()->HandleDuplicateRecords( - xActiveSheet, aCellRange, aResponse.bRemove, aResponse.bIncludesHeaders, - aResponse.bDuplicateRows, aResponse.vEntries); + { + if (aResponse.bRemove) + GetViewData().GetViewShell()->HandleDuplicateRecordsRemove( + xActiveSheet, aCellRange, aResponse.bIncludesHeaders, + aResponse.bDuplicateRows, aResponse.vEntries); + else + GetViewData().GetViewShell()->HandleDuplicateRecordsHighlight( + xActiveSheet, aCellRange, aResponse.bIncludesHeaders, + aResponse.bDuplicateRows, aResponse.vEntries); + } rReq.Done(); } diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index dc26f75673da..7e2cb7ebe91f 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -1924,9 +1924,8 @@ void ScTabViewShell::ExtendSingleSelection(css::table::CellRangeAddress& rRangeD rRangeData.EndColumn = aEndCol; } -/* bool bRemove == false ==> highlight duplicate rows */ -void ScTabViewShell::HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj>& ActiveSheet, - const css::table::CellRangeAddress& aRange, bool bRemove, +void ScTabViewShell::HandleDuplicateRecordsHighlight(const rtl::Reference<ScTableSheetObj>& ActiveSheet, + const css::table::CellRangeAddress& aRange, bool bIncludesHeaders, bool bDuplicateRows, const std::vector<int>& rSelectedEntries) { @@ -1946,14 +1945,11 @@ void ScTabViewShell::HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj uno::Reference<document::XActionLockable> xLockable(xModel, uno::UNO_QUERY); uno::Reference<sheet::XCalculatable> xCalculatable(xModel, uno::UNO_QUERY); - bool bAutoCalc = xCalculatable->isAutomaticCalculationEnabled(); ScDocument& rDoc = GetViewData().GetDocShell()->GetDocument(); comphelper::ScopeGuard aUndoContextGuard( - [&xUndoManager, &xLockable, &xModel, &xCalculatable, &bAutoCalc, &bRemove, &rDoc] { + [&xUndoManager, &xLockable, &xModel, &rDoc] { xUndoManager->getUndoManager()->leaveUndoContext(); - if (bRemove) - xCalculatable->enableAutomaticCalculation(bAutoCalc); xLockable->removeActionLock(); if (xModel->hasControllersLocked()) xModel->unlockControllers(); @@ -1963,8 +1959,6 @@ void ScTabViewShell::HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj rDoc.LockAdjustHeight(); xModel->lockControllers(); xLockable->addActionLock(); - if (bRemove) - xCalculatable->enableAutomaticCalculation(true); xUndoManager->getUndoManager()->enterUndoContext("HandleDuplicateRecords"); bool nModifier = false; // modifier key pressed? @@ -1975,28 +1969,17 @@ void ScTabViewShell::HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj std::vector<uno::Sequence<uno::Any>> aUnionArray; sal_uInt32 nRow = bIncludesHeaders ? 1 : 0; sal_uInt32 lRows = aDataArray.getLength(); - sal_uInt32 nDeleteCount = 0; while (nRow < lRows) { if (lcl_CheckInArray(aUnionArray, aDataArray[nRow], rSelectedEntries, true)) { - if (bRemove) - { - lcl_RemoveCells(ActiveSheet, aRange.Sheet, aRange.StartColumn, - aRange.StartRow + nRow - nDeleteCount, aRange.EndColumn, - aRange.StartRow + nRow - nDeleteCount, true); - ++nDeleteCount; - } - else + for (int nCol = aRange.StartColumn; nCol <= aRange.EndColumn; ++nCol) { - for (int nCol = aRange.StartColumn; nCol <= aRange.EndColumn; ++nCol) - { - bNoDuplicatesForSelection = false; - DoneBlockMode( nModifier ); - nModifier = true; - InitBlockMode( nCol, aRange.StartRow + nRow, aRange.Sheet, false, false); - } + bNoDuplicatesForSelection = false; + DoneBlockMode( nModifier ); + nModifier = true; + InitBlockMode( nCol, aRange.StartRow + nRow, aRange.Sheet, false, false); } } else @@ -2009,7 +1992,6 @@ void ScTabViewShell::HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj else { std::vector<uno::Sequence<uno::Any>> aUnionArray; - sal_uInt32 nDeleteCount = 0; sal_uInt32 nColumn = bIncludesHeaders ? 1 : 0; sal_uInt32 lColumns = aDataArray[0].getLength(); @@ -2022,22 +2004,12 @@ void ScTabViewShell::HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj if (lcl_CheckInArray(aUnionArray, aSeq, rSelectedEntries, false)) { - if (bRemove) - { - lcl_RemoveCells(ActiveSheet, aRange.Sheet, - aRange.StartColumn + nColumn - nDeleteCount, aRange.StartRow, - aRange.StartColumn + nColumn - nDeleteCount, aRange.EndRow, false); - ++nDeleteCount; - } - else + for (int nRow = aRange.StartRow; nRow <= aRange.EndRow; ++nRow) { - for (int nRow = aRange.StartRow; nRow <= aRange.EndRow; ++nRow) - { - bNoDuplicatesForSelection = false; - DoneBlockMode( nModifier ); - nModifier = true; - InitBlockMode( aRange.StartColumn + nColumn, nRow, aRange.Sheet, false, false); - } + bNoDuplicatesForSelection = false; + DoneBlockMode( nModifier ); + nModifier = true; + InitBlockMode( aRange.StartColumn + nColumn, nRow, aRange.Sheet, false, false); } } else @@ -2049,10 +2021,104 @@ void ScTabViewShell::HandleDuplicateRecords(const rtl::Reference<ScTableSheetObj } - if (bNoDuplicatesForSelection && !bRemove) + if (bNoDuplicatesForSelection) Unmark(); } +void ScTabViewShell::HandleDuplicateRecordsRemove(const rtl::Reference<ScTableSheetObj>& ActiveSheet, + const css::table::CellRangeAddress& aRange, + bool bIncludesHeaders, bool bDuplicateRows, + const std::vector<int>& rSelectedEntries) +{ + if (rSelectedEntries.size() == 0) + { + Unmark(); + return; + } + + uno::Reference<frame::XModel> xModel(GetViewData().GetDocShell()->GetModel()); + rtl::Reference<ScCellRangeObj> xSheetRange( + ActiveSheet->getScCellRangeByPosition(aRange.StartColumn, aRange.StartRow, aRange.EndColumn, aRange.EndRow)); + + uno::Sequence<uno::Sequence<uno::Any>> aDataArray = xSheetRange->getDataArray(); + + uno::Reference< document::XUndoManagerSupplier > xUndoManager( xModel, uno::UNO_QUERY ); + uno::Reference<document::XActionLockable> xLockable(xModel, uno::UNO_QUERY); + + uno::Reference<sheet::XCalculatable> xCalculatable(xModel, uno::UNO_QUERY); + bool bAutoCalc = xCalculatable->isAutomaticCalculationEnabled(); + ScDocument& rDoc = GetViewData().GetDocShell()->GetDocument(); + + comphelper::ScopeGuard aUndoContextGuard( + [&xUndoManager, &xLockable, &xModel, &xCalculatable, &bAutoCalc, &rDoc] { + xUndoManager->getUndoManager()->leaveUndoContext(); + xCalculatable->enableAutomaticCalculation(bAutoCalc); + xLockable->removeActionLock(); + if (xModel->hasControllersLocked()) + xModel->unlockControllers(); + rDoc.UnlockAdjustHeight(); + }); + + rDoc.LockAdjustHeight(); + xModel->lockControllers(); + xLockable->addActionLock(); + xCalculatable->enableAutomaticCalculation(true); + xUndoManager->getUndoManager()->enterUndoContext("HandleDuplicateRecords"); + + if (bDuplicateRows) + { + std::vector<uno::Sequence<uno::Any>> aUnionArray; + sal_uInt32 nRow = bIncludesHeaders ? 1 : 0; + sal_uInt32 lRows = aDataArray.getLength(); + sal_uInt32 nDeleteCount = 0; + + while (nRow < lRows) + { + if (lcl_CheckInArray(aUnionArray, aDataArray[nRow], rSelectedEntries, true)) + { + lcl_RemoveCells(ActiveSheet, aRange.Sheet, aRange.StartColumn, + aRange.StartRow + nRow - nDeleteCount, aRange.EndColumn, + aRange.StartRow + nRow - nDeleteCount, true); + ++nDeleteCount; + } + else + { + aUnionArray.push_back(aDataArray[nRow]); + } + ++nRow; + } + } + else + { + std::vector<uno::Sequence<uno::Any>> aUnionArray; + sal_uInt32 nDeleteCount = 0; + sal_uInt32 nColumn = bIncludesHeaders ? 1 : 0; + sal_uInt32 lColumns = aDataArray[0].getLength(); + + while (nColumn < lColumns) + { + uno::Sequence<uno::Any> aSeq; + aSeq.realloc(rSelectedEntries.size()); + for (size_t i = 0; i < rSelectedEntries.size(); ++i) + aSeq.getArray()[i] = aDataArray[rSelectedEntries[i]][nColumn]; + + if (lcl_CheckInArray(aUnionArray, aSeq, rSelectedEntries, false)) + { + lcl_RemoveCells(ActiveSheet, aRange.Sheet, + aRange.StartColumn + nColumn - nDeleteCount, aRange.StartRow, + aRange.StartColumn + nColumn - nDeleteCount, aRange.EndRow, false); + ++nDeleteCount; + } + else + { + aUnionArray.push_back(aSeq); + } + ++nColumn; + } + + } +} + ScTabViewShell::ScTabViewShell( SfxViewFrame& rViewFrame, SfxViewShell* pOldSh ) : SfxViewShell(rViewFrame, SfxViewShellFlags::HAS_PRINTOPTIONS),
