sc/qa/unit/tiledrendering/SheetViewTest.cxx         |  129 ++++++++++++++++++++
 sc/source/ui/docshell/SheetViewOperationsTester.cxx |   34 +++++
 sc/source/ui/inc/SheetViewOperationsTester.hxx      |    2 
 sc/source/ui/operation/DeleteCellOperation.cxx      |    5 
 sc/source/ui/view/viewfunc.cxx                      |    2 
 5 files changed, 169 insertions(+), 3 deletions(-)

New commits:
commit 6a87e40ab9f8baa36607d73e47a0dccd00523503
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Tue Feb 3 15:29:31 2026 +0900
Commit:     Miklos Vajna <[email protected]>
CommitDate: Fri Feb 13 14:45:11 2026 +0100

    sc: Implement sync of sheet views with delete cell operation
    
    Implement sync between default view and sheet view by changing
    (deleting in this case) the default view and overwriting the
    sheet view data (for all sheet views currently registered) from
    the default view.
    
    Change-Id: I023d7295fa8ffebe079ef40cbe67607b52f83740
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198734
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/qa/unit/tiledrendering/SheetViewTest.cxx 
b/sc/qa/unit/tiledrendering/SheetViewTest.cxx
index 0c45fae4bb43..7bd56d6ed019 100644
--- a/sc/qa/unit/tiledrendering/SheetViewTest.cxx
+++ b/sc/qa/unit/tiledrendering/SheetViewTest.cxx
@@ -63,6 +63,30 @@ protected:
 
         return aString;
     }
+
+    static OUString getValues(ScDocument* pDocument, SCCOL nCol, SCROW 
nStartRow, SCROW nEndRow,
+                              SCTAB nTab)
+    {
+        OUString aString;
+
+        size_t nSize = nEndRow - nStartRow + 1;
+
+        bool bFirst = true;
+
+        for (size_t nIndex = 0; nIndex < nSize; nIndex++)
+        {
+            OUString aValue = pDocument->GetString({ nCol, SCROW(nStartRow + 
nIndex), nTab });
+            if (bFirst)
+            {
+                bFirst = false;
+                aString = u"\""_ustr + aValue + u"\""_ustr;
+            }
+            else
+                aString += u", \""_ustr + aValue + u"\""_ustr;
+        }
+
+        return aString;
+    }
 };
 
 /** Check auto-filter sorting.
@@ -968,6 +992,111 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, 
testSyncAfterSorting_SortInDefaultAndSheetVi
     }
 }
 
+/** Test class that contains methods commonly used for testing sync of sheet 
views. */
+class SyncTest : public SheetViewTest
+{
+public:
+    void tearDown() override
+    {
+        maSheetView = std::nullopt;
+        maDefaultView = std::nullopt;
+        SheetViewTest::tearDown();
+    }
+
+protected:
+    std::optional<ScTestViewCallback> maSheetView;
+    std::optional<ScTestViewCallback> maDefaultView;
+    ScTabViewShell* mpTabViewSheetView = nullptr;
+    ScTabViewShell* mpTabViewDefaultView = nullptr;
+
+    void setupViews()
+    {
+        maSheetView.emplace();
+        mpTabViewSheetView = maSheetView->getTabViewShell();
+
+        SfxLokHelper::createView();
+        Scheduler::ProcessEventsToIdle();
+
+        maDefaultView.emplace();
+        mpTabViewDefaultView = maDefaultView->getTabViewShell();
+
+        CPPUNIT_ASSERT(mpTabViewSheetView != mpTabViewDefaultView);
+        CPPUNIT_ASSERT(maSheetView->getViewID() != maDefaultView->getViewID());
+    }
+
+    void switchToSheetView()
+    {
+        SfxLokHelper::setView(maSheetView->getViewID());
+        Scheduler::ProcessEventsToIdle();
+    }
+
+    void switchToDefaultView()
+    {
+        SfxLokHelper::setView(maDefaultView->getViewID());
+        Scheduler::ProcessEventsToIdle();
+    }
+};
+
+CPPUNIT_TEST_FIXTURE(SyncTest, testSync_DefaultView_DeleteCellOperation)
+{
+    // Create two views, and leave the second one current.
+    ScModelObj* pModelObj = createDoc("SheetView_AutoFilter.ods");
+    
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+    ScDocument* pDocument = pModelObj->GetDocument();
+
+    setupViews();
+
+    // Switch to Sheet View and Create
+    {
+        switchToSheetView();
+        dispatchCommand(mxComponent, u".uno:NewSheetView"_ustr, {});
+    }
+
+    // Switch to Default View
+    {
+        switchToDefaultView();
+
+        dispatchCommand(mxComponent, u".uno:GoToCell"_ustr,
+                        comphelper::InitPropertySequence({ { "ToPoint", 
uno::Any(u"A3"_ustr) } }));
+
+        dispatchCommand(mxComponent, u".uno:ClearContents"_ustr, {});
+    }
+
+    OUString aExpected = expectedValues({ u"4", u"", u"3", u"7" });
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(mpTabViewDefaultView, 0, 1, 4));
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(mpTabViewSheetView, 0, 1, 4));
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(pDocument, 0, 1, 4, 0));
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(pDocument, 0, 1, 4, 1));
+}
+
+CPPUNIT_TEST_FIXTURE(SyncTest, testSync_SheetView_DeleteCellOperation)
+{
+    // Create two views, and leave the second one current.
+    ScModelObj* pModelObj = createDoc("SheetView_AutoFilter.ods");
+    
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+    ScDocument* pDocument = pModelObj->GetDocument();
+
+    setupViews();
+
+    // Switch to Sheet View and Create
+    {
+        switchToSheetView();
+
+        dispatchCommand(mxComponent, u".uno:NewSheetView"_ustr, {});
+
+        dispatchCommand(mxComponent, u".uno:GoToCell"_ustr,
+                        comphelper::InitPropertySequence({ { "ToPoint", 
uno::Any(u"A3"_ustr) } }));
+
+        dispatchCommand(mxComponent, u".uno:ClearContents"_ustr, {});
+    }
+
+    OUString aExpected = expectedValues({ u"4", u"", u"3", u"7" });
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(mpTabViewDefaultView, 0, 1, 4));
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(mpTabViewSheetView, 0, 1, 4));
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(pDocument, 0, 1, 4, 0));
+    CPPUNIT_ASSERT_EQUAL(aExpected, getValues(pDocument, 0, 1, 4, 1));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/docshell/SheetViewOperationsTester.cxx 
b/sc/source/ui/docshell/SheetViewOperationsTester.cxx
index 91f6cd0e4c11..37593c7382ab 100644
--- a/sc/source/ui/docshell/SheetViewOperationsTester.cxx
+++ b/sc/source/ui/docshell/SheetViewOperationsTester.cxx
@@ -137,6 +137,40 @@ constexpr bool doesUnsyncSheetView(OperationType 
eOperationType)
 
 } // end anonymous namespace
 
+bool SheetViewOperationsTester::doesUnsync(OperationType eOperationType)
+{
+    bool bOperationAllowed = eOperationType == OperationType::EnterData
+                             || eOperationType == 
OperationType::SetNormalString;
+    return !bOperationAllowed;
+}
+
+void SheetViewOperationsTester::sync()
+{
+    if (!mpViewData)
+    {
+        return;
+    }
+
+    auto& rDocument = mpViewData->GetDocument();
+    SCTAB nTab = mpViewData->GetTabNumber();
+
+    if (rDocument.IsSheetViewHolder(nTab))
+    {
+        return;
+    }
+
+    std::shared_ptr<sc::SheetViewManager> pManager = 
rDocument.GetSheetViewManager(nTab);
+
+    if (!pManager->isEmpty())
+    {
+        for (auto const& pSheetView : pManager->getSheetViews())
+        {
+            SCTAB nSheetViewTab = pSheetView->getTableNumber();
+            rDocument.OverwriteContent(nTab, nSheetViewTab);
+        }
+    }
+}
+
 bool SheetViewOperationsTester::check(OperationType eOperationType) const
 {
     if (!mpViewData)
diff --git a/sc/source/ui/inc/SheetViewOperationsTester.hxx 
b/sc/source/ui/inc/SheetViewOperationsTester.hxx
index 1c25fba0e2ed..b0e3281b308b 100644
--- a/sc/source/ui/inc/SheetViewOperationsTester.hxx
+++ b/sc/source/ui/inc/SheetViewOperationsTester.hxx
@@ -77,7 +77,9 @@ public:
     {
     }
 
+    static bool doesUnsync(OperationType eOperationType);
     bool check(OperationType eOperationType) const;
+    void sync();
 };
 }
 
diff --git a/sc/source/ui/operation/DeleteCellOperation.cxx 
b/sc/source/ui/operation/DeleteCellOperation.cxx
index 1eefcf4479d1..b07decd047e4 100644
--- a/sc/source/ui/operation/DeleteCellOperation.cxx
+++ b/sc/source/ui/operation/DeleteCellOperation.cxx
@@ -44,8 +44,6 @@ bool DeleteCellOperation::runImplementation()
         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);
@@ -102,6 +100,9 @@ bool DeleteCellOperation::runImplementation()
         mrDocShell.PostPaint(rPos.Col(), rPos.Row(), rPos.Tab(), rPos.Col(), 
rPos.Row(), rPos.Tab(),
                              PaintPartFlags::Grid, nExtFlags, nBefore);
 
+    if (sc::SheetViewOperationsTester::doesUnsync(meType))
+        aSheetViewTester.sync();
+
     aModificator.SetDocumentModified();
 
     return true;
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 23d4e1b718b3..91cb4f23ce5b 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -2346,7 +2346,7 @@ void ScViewFunc::DeleteContents( InsertDeleteFlags nFlags 
)
     {
         aMarkRange.aStart.SetCol(GetViewData().GetCurX());
         aMarkRange.aStart.SetRow(GetViewData().GetCurY());
-        aMarkRange.aStart.SetTab(GetViewData().CurrentTabForData());
+        aMarkRange.aStart.SetTab(GetViewData().GetTabNumber());
         aMarkRange.aEnd = aMarkRange.aStart;
         if ( rDoc.HasAttrib( aMarkRange, HasAttrFlags::Merged ) )
         {

Reply via email to