sc/Library_sc.mk | 1 sc/source/ui/docshell/docfunc.cxx | 69 ------------- sc/source/ui/inc/docfunc.hxx | 2 sc/source/ui/inc/operation/DeleteCellOperation.hxx | 42 +++++++ sc/source/ui/operation/DeleteCellOperation.cxx | 111 +++++++++++++++++++++ 5 files changed, 159 insertions(+), 66 deletions(-)
New commits: commit 19ade62d7778a97b642b165166325b7dce778613 Author: Tomaž Vajngerl <[email protected]> AuthorDate: Sun Feb 1 19:01:06 2026 +0900 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Feb 10 14:51:07 2026 +0100 sc: Introduce DeleteCellOperation and move impl. from ScDocFunc Operation that deletes the content of one cell. No other functional change. Move the impl. from ScDocFunc. Change-Id: I64e7dfc6a0553bf92bc0ee11c5a4c2c9ed93a024 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198731 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index cd5056f670f3..652f41d9eede 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -529,6 +529,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/ui/navipi/navcitem \ sc/source/ui/navipi/navipi \ sc/source/ui/navipi/scenwnd \ + sc/source/ui/operation/DeleteCellOperation \ sc/source/ui/operation/DeleteContentOperation \ sc/source/ui/operation/Operation \ sc/source/ui/pagedlg/areasdlg \ diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 45232a35df67..71f2039e74e1 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -111,6 +111,7 @@ #include <memory> #include <operation/DeleteContentOperation.hxx> +#include <operation/DeleteCellOperation.hxx> #include <basic/basmgr.hxx> #include <set> #include <vector> @@ -617,72 +618,8 @@ tools::Long ScDocShell::GetTwipWidthHint(const ScAddress& rPos) bool ScDocFunc::DeleteCell( const ScAddress& rPos, const ScMarkData& rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi ) { - ScDocShellModificator aModificator(rDocShell); - - ScDocument& rDoc = rDocShell.GetDocument(); - - if (bRecord && !rDoc.IsUndoEnabled()) - bRecord = false; - - if (!CheckSheetViewProtection(sc::OperationType::DeleteCell)) - return false; - - ScEditableTester aTester = ScEditableTester::CreateAndTestSelectedBlock(rDoc, rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark); - if (!aTester.IsEditable()) - { - rDocShell.ErrorMessage(aTester.GetMessageId()); - return false; - } - - // no objects on protected tabs - bool bObjects = (nFlags & InsertDeleteFlags::OBJECTS) && !sc::DocFuncUtil::hasProtectedTab(rDoc, rMark); - - sal_uInt16 nExtFlags = 0; // extra flags are needed only if attributes are deleted - if (nFlags & InsertDeleteFlags::ATTRIB) - rDocShell.UpdatePaintExt(nExtFlags, ScRange(rPos)); - - // order of operations: - // 1) BeginDrawUndo - // 2) delete objects (DrawUndo is filled) - // 3) copy contents for undo - // 4) delete contents - // 5) add undo-action - - bool bDrawUndo = bObjects || (nFlags & InsertDeleteFlags::NOTE); // needed for shown notes - if (bDrawUndo && bRecord) - rDoc.BeginDrawUndo(); - - if (bObjects) - rDoc.DeleteObjectsInArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark); - - // To keep track of all non-empty cells within the deleted area. - std::shared_ptr<ScSimpleUndo::DataSpansType> pDataSpans; - - ScDocumentUniquePtr pUndoDoc; - if (bRecord) - { - pUndoDoc = sc::DocFuncUtil::createDeleteContentsUndoDoc(rDoc, rMark, ScRange(rPos), nFlags, false); - pDataSpans = sc::DocFuncUtil::getNonEmptyCellSpans(rDoc, rMark, ScRange(rPos)); - } - - tools::Long nBefore(rDocShell.GetTwipWidthHint(rPos)); - rDoc.DeleteArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark, nFlags); - - if (bRecord) - { - sc::DocFuncUtil::addDeleteContentsUndo( - rDocShell.GetUndoManager(), &rDocShell, rMark, ScRange(rPos), std::move(pUndoDoc), - nFlags, pDataSpans, false, bDrawUndo); - } - - if (!AdjustRowHeight(ScRange(rPos), true, bApi)) - rDocShell.PostPaint( - rPos.Col(), rPos.Row(), rPos.Tab(), rPos.Col(), rPos.Row(), rPos.Tab(), - PaintPartFlags::Grid, nExtFlags, nBefore); - - aModificator.SetDocumentModified(); - - return true; + sc::DeleteCellOperation aOperation(*this, rDocShell, rPos, rMark, nFlags, bRecord, bApi); + return aOperation.run(); } bool ScDocFunc::TransliterateText( const ScMarkData& rMark, TransliterationFlags nType, diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index 13b4cc1354f5..e74fd3ddf16e 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -60,6 +60,7 @@ namespace sc class Sparkline; enum class OperationType; class DeleteContentOperation; + class DeleteCellOperation; } namespace tools { @@ -69,6 +70,7 @@ namespace tools class ScDocFunc { friend class sc::DeleteContentOperation; + friend class sc::DeleteCellOperation; ScDocShell& rDocShell; static bool CheckSheetViewProtection(sc::OperationType eOperation); diff --git a/sc/source/ui/inc/operation/DeleteCellOperation.hxx b/sc/source/ui/inc/operation/DeleteCellOperation.hxx new file mode 100644 index 000000000000..b7a7899fc99f --- /dev/null +++ b/sc/source/ui/inc/operation/DeleteCellOperation.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Operation.hxx" +#include <sal/types.h> + +class ScDocShell; +class ScMarkData; +class ScDocFunc; +class ScAddress; +enum class InsertDeleteFlags : sal_Int32; + +namespace sc +{ +/** Operation which deletes content of one cells. */ +class DeleteCellOperation : public Operation +{ +private: + ScDocFunc& mrDocFunc; + ScDocShell& mrDocShell; + ScAddress const& mrPosition; + ScMarkData const& mrMark; + InsertDeleteFlags mnFlags; + + bool runImplementation() override; + +public: + DeleteCellOperation(ScDocFunc& rDocFunc, ScDocShell& rDocShell, const ScAddress& rPos, + const ScMarkData& rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi); +}; + +} // end sc namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/operation/DeleteCellOperation.cxx b/sc/source/ui/operation/DeleteCellOperation.cxx new file mode 100644 index 000000000000..1eefcf4479d1 --- /dev/null +++ b/sc/source/ui/operation/DeleteCellOperation.cxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <operation/DeleteCellOperation.hxx> + +#include <docfuncutil.hxx> +#include <docfunc.hxx> +#include <markdata.hxx> +#include <editable.hxx> +#include <address.hxx> + +#include <memory> + +namespace sc +{ +DeleteCellOperation::DeleteCellOperation(ScDocFunc& rDocFunc, ScDocShell& rDocShell, + ScAddress const& rPosition, const ScMarkData& rMark, + InsertDeleteFlags nFlags, bool bRecord, bool bApi) + : Operation(OperationType::DeleteCell, bRecord, bApi) + , mrDocFunc(rDocFunc) + , mrDocShell(rDocShell) + , mrPosition(rPosition) + , mrMark(rMark) + , mnFlags(nFlags) +{ +} + +bool DeleteCellOperation::runImplementation() +{ + ScDocShellModificator aModificator(mrDocShell); + + ScAddress const& rPos = mrPosition; + ScMarkData const& rMark = mrMark; + + ScDocument& rDoc = mrDocShell.GetDocument(); + + if (mbRecord && !rDoc.IsUndoEnabled()) + mbRecord = false; + + sc::SheetViewOperationsTester aSheetViewTester(ScDocShell::GetViewData()); + if (!aSheetViewTester.check(meType)) + return false; + + ScEditableTester aTester = ScEditableTester::CreateAndTestSelectedBlock( + rDoc, rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark); + if (!aTester.IsEditable()) + { + mrDocShell.ErrorMessage(aTester.GetMessageId()); + return false; + } + + // no objects on protected tabs + bool bObjects + = (mnFlags & InsertDeleteFlags::OBJECTS) && !sc::DocFuncUtil::hasProtectedTab(rDoc, rMark); + + sal_uInt16 nExtFlags = 0; // extra flags are needed only if attributes are deleted + if (mnFlags & InsertDeleteFlags::ATTRIB) + mrDocShell.UpdatePaintExt(nExtFlags, ScRange(rPos)); + + // order of operations: + // 1) BeginDrawUndo + // 2) delete objects (DrawUndo is filled) + // 3) copy contents for undo + // 4) delete contents + // 5) add undo-action + + bool bDrawUndo = bObjects || (mnFlags & InsertDeleteFlags::NOTE); // needed for shown notes + if (bDrawUndo && mbRecord) + rDoc.BeginDrawUndo(); + + if (bObjects) + rDoc.DeleteObjectsInArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark); + + // To keep track of all non-empty cells within the deleted area. + std::shared_ptr<ScSimpleUndo::DataSpansType> pDataSpans; + + ScDocumentUniquePtr pUndoDoc; + if (mbRecord) + { + pUndoDoc = sc::DocFuncUtil::createDeleteContentsUndoDoc(rDoc, rMark, ScRange(rPos), mnFlags, + false); + pDataSpans = sc::DocFuncUtil::getNonEmptyCellSpans(rDoc, rMark, ScRange(rPos)); + } + + tools::Long nBefore(mrDocShell.GetTwipWidthHint(rPos)); + rDoc.DeleteArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark, mnFlags); + + if (mbRecord) + { + sc::DocFuncUtil::addDeleteContentsUndo(mrDocShell.GetUndoManager(), &mrDocShell, rMark, + ScRange(rPos), std::move(pUndoDoc), mnFlags, + pDataSpans, false, bDrawUndo); + } + + if (!mrDocFunc.AdjustRowHeight(ScRange(rPos), true, mbApi)) + mrDocShell.PostPaint(rPos.Col(), rPos.Row(), rPos.Tab(), rPos.Col(), rPos.Row(), rPos.Tab(), + PaintPartFlags::Grid, nExtFlags, nBefore); + + aModificator.SetDocumentModified(); + + return true; +} +} // end sc namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
