sc/CppunitTest_sc_tiledrendering.mk                       |    2 
 sc/CppunitTest_sc_tiledrendering2.mk                      |    2 
 sc/Library_scqahelper.mk                                  |    2 
 sc/qa/unit/helper/sctestviewcallback.cxx                  |  360 +++++++++
 sc/qa/unit/helper/sctestviewcallback.hxx                  |   94 ++
 sc/qa/unit/helper/sctiledrenderingtest.cxx                |  171 ++++
 sc/qa/unit/helper/sctiledrenderingtest.hxx                |   53 +
 sc/qa/unit/tiledrendering/tiledrendering.cxx              |  247 ++----
 sc/qa/unit/tiledrendering/tiledrendering2.cxx             |   21 
 sc/qa/unit/tiledrendering/tiledrenderingmodeltestbase.cxx |  521 --------------
 10 files changed, 799 insertions(+), 674 deletions(-)

New commits:
commit 36c01a613866e2c3208c376175b77d1d3ec8d841
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Apr 14 15:59:50 2025 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Apr 15 09:15:43 2025 +0200

    sc: move ScTiledRenderingTest to Library_scqahelper
    
    Allows not including .cxx files in Calc tests.
    
    [ Pick to co-25.04, to reduce conflicts vs master. ]
    
    Change-Id: Ib68cd406df1ed1c9d36cbab9701a47bd016eaab4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184191
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sc/CppunitTest_sc_tiledrendering.mk 
b/sc/CppunitTest_sc_tiledrendering.mk
index 5a2f4d971332..a00fdb0259f0 100644
--- a/sc/CppunitTest_sc_tiledrendering.mk
+++ b/sc/CppunitTest_sc_tiledrendering.mk
@@ -31,6 +31,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sc_tiledrendering, 
\
     sc \
     scfilt \
     scui \
+    scqahelper \
     subsequenttest \
     test \
     unotest \
@@ -49,6 +50,7 @@ $(eval $(call gb_CppunitTest_use_externals,sc_tiledrendering,\
 $(eval $(call gb_CppunitTest_set_include,sc_tiledrendering,\
     -I$(SRCDIR)/sc/source/ui/inc \
     -I$(SRCDIR)/sc/inc \
+       -I$(SRCDIR)/sc/qa/unit/helper \
     $$(INCLUDE) \
 ))
 
diff --git a/sc/CppunitTest_sc_tiledrendering2.mk 
b/sc/CppunitTest_sc_tiledrendering2.mk
index 9acb0bffe924..2d70c6dcbb47 100644
--- a/sc/CppunitTest_sc_tiledrendering2.mk
+++ b/sc/CppunitTest_sc_tiledrendering2.mk
@@ -31,6 +31,7 @@ $(eval $(call 
gb_CppunitTest_use_libraries,sc_tiledrendering2, \
     sc \
     scfilt \
     scui \
+    scqahelper \
     subsequenttest \
     test \
     unotest \
@@ -49,6 +50,7 @@ $(eval $(call 
gb_CppunitTest_use_externals,sc_tiledrendering2,\
 $(eval $(call gb_CppunitTest_set_include,sc_tiledrendering2,\
     -I$(SRCDIR)/sc/source/ui/inc \
     -I$(SRCDIR)/sc/inc \
+       -I$(SRCDIR)/sc/qa/unit/helper \
     $$(INCLUDE) \
 ))
 
diff --git a/sc/Library_scqahelper.mk b/sc/Library_scqahelper.mk
index 6e8c9eca7327..071a69dcfbc2 100644
--- a/sc/Library_scqahelper.mk
+++ b/sc/Library_scqahelper.mk
@@ -69,6 +69,8 @@ $(eval $(call gb_Library_use_libraries,scqahelper,\
 $(eval $(call gb_Library_add_exception_objects,scqahelper,\
        sc/qa/unit/helper/qahelper \
        sc/qa/unit/helper/scfiltertestbase \
+       sc/qa/unit/helper/sctiledrenderingtest \
+       sc/qa/unit/helper/sctestviewcallback \
        sc/qa/unit/functions_test \
 ))
 
diff --git a/sc/qa/unit/helper/sctestviewcallback.cxx 
b/sc/qa/unit/helper/sctestviewcallback.cxx
new file mode 100644
index 000000000000..f590c79879cf
--- /dev/null
+++ b/sc/qa/unit/helper/sctestviewcallback.cxx
@@ -0,0 +1,360 @@
+/* -*- 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 "sctestviewcallback.hxx"
+
+#include <boost/property_tree/json_parser.hpp>
+
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <comphelper/lok.hxx>
+#include <comphelper/string.hxx>
+#include <test/unoapixml_test.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/lokhelper.hxx>
+
+using namespace com::sun::star;
+
+void ScTestEditCursorMessage::clear()
+{
+    m_aRelRect.SetEmpty();
+    m_aRefPoint = Point(-1, -1);
+}
+
+bool ScTestEditCursorMessage::empty()
+{
+    return m_aRelRect.IsEmpty() && m_aRefPoint.X() == -1 && m_aRefPoint.Y() == 
-1;
+}
+
+void ScTestEditCursorMessage::parseMessage(const char* pMessage)
+{
+    clear();
+    if (!pMessage
+        || !comphelper::LibreOfficeKit::isCompatFlagSet(
+               comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs)
+        || !comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation())
+        return;
+
+    std::stringstream aStream(pMessage);
+    boost::property_tree::ptree aTree;
+    boost::property_tree::read_json(aStream, aTree);
+    std::string aVal;
+    boost::property_tree::ptree::const_assoc_iterator it = 
aTree.find("refpoint");
+    if (it != aTree.not_found())
+        aVal = aTree.get_child("refpoint").get_value<std::string>();
+    else
+        return; // happens in testTextBoxInsert test
+
+    uno::Sequence<OUString> aSeq
+        = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(aVal));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aSeq.getLength());
+    m_aRefPoint.setX(aSeq[0].toInt32());
+    m_aRefPoint.setY(aSeq[1].toInt32());
+
+    aVal = aTree.get_child("relrect").get_value<std::string>();
+    aSeq = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(aVal));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aSeq.getLength());
+    m_aRelRect.SetLeft(aSeq[0].toInt32());
+    m_aRelRect.SetTop(aSeq[1].toInt32());
+    m_aRelRect.setWidth(aSeq[2].toInt32());
+    m_aRelRect.setHeight(aSeq[3].toInt32());
+}
+
+tools::Rectangle ScTestEditCursorMessage::getBounds()
+{
+    tools::Rectangle aBounds = m_aRelRect;
+    aBounds.Move(m_aRefPoint.X(), m_aRefPoint.Y());
+    return aBounds;
+}
+
+void ScTestTextSelectionMessage::clear()
+{
+    m_aRefPoint.setX(0);
+    m_aRefPoint.setY(0);
+    m_aRelRects.clear();
+}
+
+bool ScTestTextSelectionMessage::empty() { return m_aRelRects.empty(); }
+
+void ScTestTextSelectionMessage::parseMessage(const char* pMessage)
+{
+    clear();
+    if (!pMessage)
+        return;
+
+    std::string aStr(pMessage);
+    if (aStr.find(",") == std::string::npos)
+        return;
+
+    size_t nRefDelimStart = aStr.find("::");
+    std::string aRectListString
+        = (nRefDelimStart == std::string::npos) ? aStr : aStr.substr(0, 
nRefDelimStart);
+    std::string aRefPointString
+        = (nRefDelimStart == std::string::npos)
+              ? std::string("0, 0")
+              : aStr.substr(nRefDelimStart + 2, aStr.length() - 2 - 
nRefDelimStart);
+    uno::Sequence<OUString> aSeq
+        = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(aRefPointString));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aSeq.getLength());
+    m_aRefPoint.setX(aSeq[0].toInt32());
+    m_aRefPoint.setY(aSeq[1].toInt32());
+
+    size_t nStart = 0;
+    size_t nEnd = aRectListString.find(";");
+    if (nEnd == std::string::npos)
+        nEnd = aRectListString.length();
+    do
+    {
+        std::string aRectString = aRectListString.substr(nStart, nEnd - 
nStart);
+        {
+            aSeq
+                = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(aRectString));
+            CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aSeq.getLength());
+            tools::Rectangle aRect;
+            aRect.SetLeft(aSeq[0].toInt32());
+            aRect.SetTop(aSeq[1].toInt32());
+            aRect.setWidth(aSeq[2].toInt32());
+            aRect.setHeight(aSeq[3].toInt32());
+
+            m_aRelRects.push_back(aRect);
+        }
+
+        nStart = nEnd + 1;
+        nEnd = aRectListString.find(";", nStart);
+    } while (nEnd != std::string::npos);
+}
+
+tools::Rectangle ScTestTextSelectionMessage::getBounds(size_t nIndex)
+{
+    if (nIndex >= m_aRelRects.size())
+        return tools::Rectangle();
+
+    tools::Rectangle aBounds = m_aRelRects[nIndex];
+    aBounds.Move(m_aRefPoint.X(), m_aRefPoint.Y());
+    return aBounds;
+}
+
+ScTestViewCallback::ScTestViewCallback(bool bDeleteListenerOnDestruct)
+    : m_bOwnCursorInvalidated(false)
+    , m_bViewCursorInvalidated(false)
+    , m_textCursorVisible(false)
+    , m_bTextViewSelectionInvalidated(false)
+    , m_bGraphicSelection(false)
+    , m_bGraphicViewSelection(false)
+    , m_bFullInvalidateTiles(false)
+    , m_bInvalidateTiles(false)
+    , m_bViewLock(false)
+    , m_callbackWrapper(&callback, this)
+{
+    mpViewShell = SfxViewShell::Current();
+    mpViewShell->setLibreOfficeKitViewCallback(&m_callbackWrapper);
+    mnView = SfxLokHelper::getView();
+    m_callbackWrapper.setLOKViewId(mnView);
+    if (!bDeleteListenerOnDestruct)
+        mpViewShell = nullptr;
+}
+
+ScTestViewCallback::~ScTestViewCallback()
+{
+    if (mpViewShell)
+    {
+        SfxLokHelper::setView(mnView);
+        mpViewShell->setLibreOfficeKitViewCallback(nullptr);
+    }
+}
+
+void ScTestViewCallback::callback(int nType, const char* pPayload, void* pData)
+{
+    static_cast<ScTestViewCallback*>(pData)->callbackImpl(nType, pPayload);
+}
+
+void ScTestViewCallback::callbackImpl(int nType, const char* pPayload)
+{
+    switch (nType)
+    {
+        case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
+        {
+            boost::property_tree::ptree aTree;
+            std::stringstream aStream(pPayload);
+            boost::property_tree::read_json(aStream, aTree);
+            m_textCursorVisible = 
aTree.get_child("visible").get_value<std::string>() == "true";
+        }
+        break;
+        case LOK_CALLBACK_CELL_CURSOR:
+        {
+            m_bOwnCursorInvalidated = true;
+            uno::Sequence<OUString> aSeq
+                = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(pPayload));
+            m_aCellCursorBounds = tools::Rectangle();
+            if (aSeq.getLength() == 6)
+            {
+                m_aCellCursorBounds.SetLeft(aSeq[0].toInt32());
+                m_aCellCursorBounds.SetTop(aSeq[1].toInt32());
+                m_aCellCursorBounds.setWidth(aSeq[2].toInt32());
+                m_aCellCursorBounds.setHeight(aSeq[3].toInt32());
+            }
+        }
+        break;
+        case LOK_CALLBACK_CELL_VIEW_CURSOR:
+        {
+            m_bViewCursorInvalidated = true;
+        }
+        break;
+        case LOK_CALLBACK_TEXT_VIEW_SELECTION:
+        {
+            m_bTextViewSelectionInvalidated = true;
+        }
+        break;
+        case LOK_CALLBACK_VIEW_LOCK:
+        {
+            std::stringstream aStream(pPayload);
+            boost::property_tree::ptree aTree;
+            boost::property_tree::read_json(aStream, aTree);
+            m_bViewLock = 
aTree.get_child("rectangle").get_value<std::string>() != "EMPTY";
+        }
+        break;
+        case LOK_CALLBACK_GRAPHIC_SELECTION:
+        {
+            m_bGraphicSelection = true;
+            m_ShapeSelection = OString(pPayload);
+        }
+        break;
+        case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
+        {
+            m_bGraphicViewSelection = true;
+        }
+        break;
+        case LOK_CALLBACK_INVALIDATE_TILES:
+        {
+            OString text(pPayload);
+            if (text.startsWith("EMPTY"))
+            {
+                m_bFullInvalidateTiles = true;
+            }
+            else
+            {
+                uno::Sequence<OUString> aSeq = 
comphelper::string::convertCommaSeparated(
+                    OUString::createFromAscii(pPayload));
+                CPPUNIT_ASSERT(aSeq.getLength() == 4 || aSeq.getLength() == 6);
+                tools::Rectangle aInvalidationRect;
+                aInvalidationRect.SetLeft(aSeq[0].toInt32());
+                aInvalidationRect.SetTop(aSeq[1].toInt32());
+                aInvalidationRect.setWidth(aSeq[2].toInt32());
+                aInvalidationRect.setHeight(aSeq[3].toInt32());
+                m_aInvalidations.push_back(aInvalidationRect);
+                if (aSeq.getLength() == 6)
+                {
+                    m_aInvalidationsParts.push_back(aSeq[4].toInt32());
+                    m_aInvalidationsMode.push_back(aSeq[5].toInt32());
+                }
+                m_bInvalidateTiles = true;
+            }
+        }
+        break;
+        case LOK_CALLBACK_CELL_FORMULA:
+        {
+            m_sCellFormula = pPayload;
+        }
+        break;
+        case LOK_CALLBACK_COMMENT:
+        {
+            m_aCommentCallbackResult.clear();
+            std::stringstream aStream(pPayload);
+            boost::property_tree::read_json(aStream, m_aCommentCallbackResult);
+            m_aCommentCallbackResult = 
m_aCommentCallbackResult.get_child("comment");
+        }
+        break;
+        case LOK_CALLBACK_INVALIDATE_HEADER:
+        {
+            m_sInvalidateHeader = pPayload;
+        }
+        break;
+        case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
+        {
+            m_sInvalidateSheetGeometry = pPayload;
+        }
+        break;
+        case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
+        {
+            m_aInvalidateCursorResult.parseMessage(pPayload);
+        }
+        break;
+        case LOK_CALLBACK_HYPERLINK_CLICKED:
+        {
+            m_aHyperlinkClicked = pPayload;
+        }
+        break;
+        case LOK_CALLBACK_TEXT_SELECTION:
+        {
+            m_aTextSelectionResult.parseMessage(pPayload);
+        }
+        break;
+        case LOK_CALLBACK_STATE_CHANGED:
+        {
+            std::stringstream aStream(pPayload);
+            boost::property_tree::ptree aTree;
+            std::string aCommandName;
+
+            if (aStream.str().starts_with("{"))
+            {
+                boost::property_tree::read_json(aStream, aTree);
+                auto it = aTree.find("commandName");
+                if (it == aTree.not_found())
+                {
+                    break;
+                }
+
+                aCommandName = it->second.get_value<std::string>();
+            }
+            else
+            {
+                std::string aState = aStream.str();
+                auto it = aState.find("=");
+                if (it == std::string::npos)
+                {
+                    break;
+                }
+                aCommandName = aState.substr(0, it);
+                aTree.put("state", aState.substr(it + 1));
+            }
+
+            m_aStateChanges[aCommandName] = aTree;
+        }
+        break;
+        case LOK_CALLBACK_JSDIALOG:
+        {
+            std::stringstream aStream(pPayload);
+            boost::property_tree::ptree aTree;
+            boost::property_tree::read_json(aStream, aTree);
+            if (aTree.get_child("jsontype").get_value<std::string>() == 
"formulabar")
+            {
+                if (aTree.find("data") != aTree.not_found())
+                {
+                    if (aTree.get_child("data").find("separator")
+                        != aTree.get_child("data").not_found())
+                    {
+                        decimalSeparator = aTree.get_child("data")
+                                               .get_child("separator")
+                                               .get_value<std::string>();
+                    }
+                }
+            }
+        }
+        break;
+    }
+}
+
+void ScTestViewCallback::ClearAllInvalids()
+{
+    m_bInvalidateTiles = false;
+    m_aInvalidations.clear();
+    m_aInvalidationsParts.clear();
+    m_aInvalidationsMode.clear();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/helper/sctestviewcallback.hxx 
b/sc/qa/unit/helper/sctestviewcallback.hxx
new file mode 100644
index 000000000000..a5452a1f8f3e
--- /dev/null
+++ b/sc/qa/unit/helper/sctestviewcallback.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 <map>
+
+#include <boost/property_tree/ptree.hpp>
+
+#include <tools/gen.hxx>
+#include <rtl/string.hxx>
+#include <test/lokcallback.hxx>
+
+#include "scqahelperdllapi.h"
+
+class SfxViewShell;
+
+struct SCQAHELPER_DLLPUBLIC ScTestEditCursorMessage final
+{
+    tools::Rectangle m_aRelRect;
+    Point m_aRefPoint;
+
+    void clear();
+
+    bool empty();
+
+    void parseMessage(const char* pMessage);
+
+    tools::Rectangle getBounds();
+};
+
+struct SCQAHELPER_DLLPUBLIC ScTestTextSelectionMessage
+{
+    std::vector<tools::Rectangle> m_aRelRects;
+    Point m_aRefPoint;
+
+    void clear();
+
+    bool empty();
+
+    void parseMessage(const char* pMessage);
+
+    tools::Rectangle getBounds(size_t nIndex);
+};
+/// A view callback tracks callbacks invoked on one specific view.
+class SCQAHELPER_DLLPUBLIC ScTestViewCallback final
+{
+    SfxViewShell* mpViewShell;
+    int mnView;
+
+public:
+    bool m_bOwnCursorInvalidated;
+    bool m_bViewCursorInvalidated;
+    bool m_textCursorVisible;
+    bool m_bTextViewSelectionInvalidated;
+    bool m_bGraphicSelection;
+    bool m_bGraphicViewSelection;
+    bool m_bFullInvalidateTiles;
+    bool m_bInvalidateTiles;
+    std::vector<tools::Rectangle> m_aInvalidations;
+    tools::Rectangle m_aCellCursorBounds;
+    std::vector<int> m_aInvalidationsParts;
+    std::vector<int> m_aInvalidationsMode;
+    bool m_bViewLock;
+    OString m_sCellFormula;
+    boost::property_tree::ptree m_aCommentCallbackResult;
+    ScTestEditCursorMessage m_aInvalidateCursorResult;
+    ScTestTextSelectionMessage m_aTextSelectionResult;
+    OString m_sInvalidateHeader;
+    OString m_sInvalidateSheetGeometry;
+    OString m_aHyperlinkClicked;
+    OString m_ShapeSelection;
+    std::map<std::string, boost::property_tree::ptree> m_aStateChanges;
+    std::string decimalSeparator;
+    TestLokCallbackWrapper m_callbackWrapper;
+
+    ScTestViewCallback(bool bDeleteListenerOnDestruct = true);
+
+    ~ScTestViewCallback();
+
+    static void callback(int nType, const char* pPayload, void* pData);
+
+    void callbackImpl(int nType, const char* pPayload);
+
+    void ClearAllInvalids();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/helper/sctiledrenderingtest.cxx 
b/sc/qa/unit/helper/sctiledrenderingtest.cxx
new file mode 100644
index 000000000000..7d835209dd9b
--- /dev/null
+++ b/sc/qa/unit/helper/sctiledrenderingtest.cxx
@@ -0,0 +1,171 @@
+/* -*- 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 "sctiledrenderingtest.hxx"
+
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <comphelper/lok.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <vcl/scheduler.hxx>
+
+#include <docuno.hxx>
+#include <tabvwsh.hxx>
+
+#include "sctestviewcallback.hxx"
+
+using namespace com::sun::star;
+
+ScTiledRenderingTest::ScTiledRenderingTest()
+    : UnoApiXmlTest(u"/sc/qa/unit/tiledrendering/data/"_ustr)
+    , m_callbackWrapper(&callback, this)
+{
+}
+
+void ScTiledRenderingTest::setUp()
+{
+    UnoApiXmlTest::setUp();
+
+    comphelper::LibreOfficeKit::setActive(true);
+}
+
+void ScTiledRenderingTest::tearDown()
+{
+    if (mxComponent.is())
+    {
+        mxComponent->dispose();
+        mxComponent.clear();
+    }
+
+    m_callbackWrapper.clear();
+
+    comphelper::LibreOfficeKit::resetCompatFlag();
+
+    comphelper::LibreOfficeKit::setActive(false);
+
+    UnoApiXmlTest::tearDown();
+}
+
+ScModelObj* ScTiledRenderingTest::createDoc(const char* pName)
+{
+    loadFromFile(OUString::createFromAscii(pName));
+
+    ScModelObj* pModelObj = 
comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
+    CPPUNIT_ASSERT(pModelObj);
+    
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+    return pModelObj;
+}
+
+void ScTiledRenderingTest::setupLibreOfficeKitViewCallback(SfxViewShell* 
pViewShell)
+{
+    pViewShell->setLibreOfficeKitViewCallback(&m_callbackWrapper);
+    m_callbackWrapper.setLOKViewId(SfxLokHelper::getView(pViewShell));
+}
+
+void ScTiledRenderingTest::callback(int nType, const char* pPayload, void* 
pData)
+{
+    static_cast<ScTiledRenderingTest*>(pData)->callbackImpl(nType, pPayload);
+}
+
+void ScTiledRenderingTest::callbackImpl(int nType, const char* pPayload)
+{
+    switch (nType)
+    {
+        case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
+        {
+            OString aPayload(pPayload);
+            sal_Int32 nIndex = 0;
+            OString aToken = aPayload.getToken(0, ',', nIndex);
+            m_aDocumentSize.setWidth(aToken.toInt32());
+            aToken = aPayload.getToken(0, ',', nIndex);
+            m_aDocumentSize.setHeight(aToken.toInt32());
+            m_aDocSizeCondition.set();
+        }
+        break;
+    }
+}
+
+void ScTiledRenderingTest::checkSampleInvalidation(const ScTestViewCallback& 
rView, bool bFullRow)
+{
+    // we expect invalidations, but that isn't really important
+    CPPUNIT_ASSERT(rView.m_bInvalidateTiles);
+    tools::Rectangle aInvalidation;
+    for (const auto& rRect : rView.m_aInvalidations)
+        aInvalidation.Union(rRect);
+    if (!bFullRow)
+    {
+        // What matters is that we expect that the invalidation does not 
extend all the
+        // way to the max right of the sheet.
+        // Here we originally got 32212306 and now ~5056 for a single cell case
+        CPPUNIT_ASSERT_LESSEQUAL(tools::Long(8000), aInvalidation.GetWidth());
+    }
+    else
+    {
+        // We expect RTL to continue to invalidate the entire row
+        // from 0 to end of sheet (see ScDocShell::PostPaint, 'Extend to whole 
rows'),
+        // which is different to the adjusted LTR case which
+        // invalidated the row from left of edited cell to right of end
+        // of sheet.
+        CPPUNIT_ASSERT_LESSEQUAL(tools::Long(0), aInvalidation.Left());
+        CPPUNIT_ASSERT_EQUAL(tools::Long(32212230), aInvalidation.Right());
+    }
+}
+
+void ScTiledRenderingTest::cellInvalidationHelper(ScModelObj* pModelObj, 
ScTabViewShell* pView,
+                                                  const ScAddress& rAdr, bool 
bAddText,
+                                                  bool bFullRow)
+{
+    // view
+    ScTestViewCallback aView;
+
+    if (bAddText)
+    {
+        // Type "Hello World" in D8, process events to idle and don't commit 
yet
+        typeCharsInCell("Hello World", rAdr.Col(), rAdr.Row(), pView, 
pModelObj, false, false);
+
+        aView.m_bInvalidateTiles = false;
+        aView.m_aInvalidations.clear();
+
+        // commit text and process events to idle
+        typeCharsInCell("", rAdr.Col(), rAdr.Row(), pView, pModelObj, true, 
true);
+    }
+    else // DeleteText
+    {
+        pView->SetCursor(rAdr.Col(), rAdr.Row());
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::DELETE);
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::DELETE);
+        Scheduler::ProcessEventsToIdle();
+    }
+
+    checkSampleInvalidation(aView, bFullRow);
+}
+
+void ScTiledRenderingTest::typeCharsInCell(const std::string& aStr, SCCOL 
nCol, SCROW nRow,
+                                           ScTabViewShell* pView, ScModelObj* 
pModelObj,
+                                           bool bInEdit, bool bCommit)
+{
+    if (!bInEdit)
+        pView->SetCursor(nCol, nRow);
+
+    for (const char& cChar : aStr)
+    {
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, cChar, 0);
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, cChar, 0);
+        Scheduler::ProcessEventsToIdle();
+    }
+
+    if (bCommit)
+    {
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN);
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN);
+        Scheduler::ProcessEventsToIdle();
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/helper/sctiledrenderingtest.hxx 
b/sc/qa/unit/helper/sctiledrenderingtest.hxx
new file mode 100644
index 000000000000..4bd7769e57a8
--- /dev/null
+++ b/sc/qa/unit/helper/sctiledrenderingtest.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 <test/unoapixml_test.hxx>
+
+#include <osl/conditn.hxx>
+#include <test/lokcallback.hxx>
+
+#include <types.hxx>
+
+#include "scqahelperdllapi.h"
+
+class ScTestViewCallback;
+class ScModelObj;
+class ScTabViewShell;
+class ScAddress;
+class SfxViewShell;
+
+class SCQAHELPER_DLLPUBLIC ScTiledRenderingTest : public UnoApiXmlTest
+{
+public:
+    ScTiledRenderingTest();
+    virtual void setUp() override;
+    virtual void tearDown() override;
+
+    void checkSampleInvalidation(const ScTestViewCallback& rView, bool 
bFullRow);
+    void cellInvalidationHelper(ScModelObj* pModelObj, ScTabViewShell* pView, 
const ScAddress& rAdr,
+                                bool bAddText, bool bFullRow);
+
+    ScModelObj* createDoc(const char* pName);
+    void setupLibreOfficeKitViewCallback(SfxViewShell* pViewShell);
+    static void callback(int nType, const char* pPayload, void* pData);
+    void callbackImpl(int nType, const char* pPayload);
+
+    void typeCharsInCell(const std::string& aStr, SCCOL nCol, SCROW nRow, 
ScTabViewShell* pView,
+                         ScModelObj* pModelObj, bool bInEdit = false, bool 
bCommit = true);
+
+    /// document size changed callback.
+    osl::Condition m_aDocSizeCondition;
+    Size m_aDocumentSize;
+
+    TestLokCallbackWrapper m_callbackWrapper;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx 
b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index be54455154dd..e4966adc2f4a 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -7,11 +7,14 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include "tiledrenderingmodeltestbase.cxx"
-#include <test/helper/transferable.hxx>
+#include <sctiledrenderingtest.hxx>
+
+#include <boost/property_tree/json_parser.hpp>
 
 #include <com/sun/star/datatransfer/clipboard/LokClipboard.hpp>
 #include <com/sun/star/util/URLTransformer.hpp>
+
+#include <test/helper/transferable.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertysequence.hxx>
 #include <comphelper/servicehelper.hxx>
@@ -20,7 +23,8 @@
 #include <svl/stritem.hxx>
 #include <svl/numformat.hxx>
 #include <svl/zformat.hxx>
-
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <vcl/scheduler.hxx>
 #include <comphelper/lok.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/dispatchcommand.hxx>
@@ -30,11 +34,11 @@
 #include <svx/svdpage.hxx>
 #include <vcl/vclevent.hxx>
 #include <vcl/virdev.hxx>
-#include <sc.hrc>
 #include <tools/json_writer.hxx>
-#include <postit.hxx>
 #include <unotools/syslocaleoptions.hxx>
 
+#include <sc.hrc>
+#include <postit.hxx>
 #include <attrib.hxx>
 #include <scitems.hxx>
 #include <document.hxx>
@@ -42,6 +46,11 @@
 #include <drwlayer.hxx>
 #include <editutil.hxx>
 #include <undomanager.hxx>
+#include <docsh.hxx>
+#include <tabvwsh.hxx>
+#include <sctestviewcallback.hxx>
+
+using namespace com::sun::star;
 
 static std::ostream& operator<<(std::ostream& os, ViewShellId const & id)
 {
@@ -207,10 +216,10 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testEmptyColumnSelection)
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testViewCursors)
 {
     ScModelObj* pModelObj = createDoc("select-row-cols.ods");
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2(/*bDeleteListenerOnDestruct*/false);
+    ScTestViewCallback aView2(/*bDeleteListenerOnDestruct*/false);
     // This was false, the new view did not get the view (cell) cursor of the 
old view.
     CPPUNIT_ASSERT(aView2.m_bViewCursorInvalidated);
     CPPUNIT_ASSERT(aView2.m_bOwnCursorInvalidated);
@@ -243,10 +252,10 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testTextViewSelection)
 {
     // Create two views, and leave the second one current.
     ScModelObj* pModelObj = createDoc("select-row-cols.ods");
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // Create a selection on two cells in the second view, that's a text 
selection in LOK terms.
     aView1.m_bTextViewSelectionInvalidated = false;
@@ -276,10 +285,10 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testViewLock)
 {
     // Load a document that has a shape and create two views.
     ScModelObj* pModelObj = createDoc("shape.ods");
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // Begin text edit in the second view and assert that the first gets a lock
     // notification.
@@ -325,7 +334,7 @@ void lcl_extractHandleParameters(std::string_view 
selection, sal_uInt32& id, sal
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testMoveShapeHandle)
 {
     ScModelObj* pModelObj = createDoc("shape.ods");
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, /*x=*/ 1,/*y=*/ 
1,/*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
     pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, /*x=*/ 1, /*y=*/ 
1, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
     Scheduler::ProcessEventsToIdle();
@@ -423,7 +432,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testTextEditViews)
     CPPUNIT_ASSERT(pViewData);
 
     // view #1
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     // text edit a cell in view #1
@@ -435,7 +444,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testTextEditViews)
     // view #2
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // move cell cursor i view #2
     pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::DOWN);
@@ -455,13 +464,13 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testTextEditViewInvalidations)
 
     // view #1
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     // view #2
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // text edit a cell in view #1
     SfxLokHelper::setView(nView1);
@@ -492,7 +501,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testTextEditViewInvalidations)
     // view #3
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView3;
+    ScTestViewCallback aView3;
 
     // text edit a cell in view #1
     SfxLokHelper::setView(nView1);
@@ -507,7 +516,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCreateViewGraphicSelection)
 {
     // Load a document that has a shape and create two views.
     ScModelObj* pModelObj = createDoc("shape.ods");
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // Mark the graphic in the first view.
     const ScViewData* pViewData = ScDocShell::GetViewData();
@@ -527,7 +536,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCreateViewGraphicSelection)
     int nView1 = SfxLokHelper::getView();
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     CPPUNIT_ASSERT(aView2.m_bGraphicViewSelection);
     CPPUNIT_ASSERT(aView1.m_bGraphicViewSelection);
 
@@ -539,7 +548,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testGraphicInvalidate)
 {
     // Load a document that has a shape and create two views.
     ScModelObj* pModelObj = createDoc("shape.ods");
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     // Click to select graphic
     aView.m_bGraphicSelection = false;
@@ -565,7 +574,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testAutoSum)
 {
     createDoc("small.ods");
 
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     uno::Sequence<beans::PropertyValue> aArgs;
     dispatchCommand(mxComponent, u".uno:AutoSum"_ustr, aArgs);
@@ -635,7 +644,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidateOnCopyPasteCells)
     CPPUNIT_ASSERT(pModelObj);
 
     // view
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     uno::Sequence<beans::PropertyValue> aArgs;
     // select and copy cells
@@ -669,7 +678,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidateOnInserRowCol)
     CPPUNIT_ASSERT(pModelObj);
 
     // view
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     uno::Sequence<beans::PropertyValue> aArgs;
     // move downward
@@ -715,13 +724,13 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCommentCallback)
 
     {
         ScModelObj* pModelObj = createDoc("small.ods");
-        ViewCallback aView1;
+        ScTestViewCallback aView1;
         int nView1 = SfxLokHelper::getView();
 
         // Create a 2nd view
         SfxLokHelper::createView();
         pModelObj->initializeForTiledRendering({});
-        ViewCallback aView2;
+        ScTestViewCallback aView2;
 
         SfxLokHelper::setView(nView1);
 
@@ -825,13 +834,13 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testUndoLimiting)
 
     // view #1
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // text edit a cell in view #1
     SfxLokHelper::setView(nView1);
@@ -883,13 +892,13 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testUndoRepairDispatch)
 
     // view #1
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // text edit a cell in view #1
     SfxLokHelper::setView(nView1);
@@ -927,7 +936,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInsertGraphicInvalidations)
     CPPUNIT_ASSERT(pViewData);
 
     // view
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     // we need to paint a tile in the view for triggering the tile 
invalidation solution
     int nCanvasWidth = 256;
@@ -1377,7 +1386,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testPageDownInvalidation)
     CPPUNIT_ASSERT(pViewData);
 
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     SfxLokHelper::setView(nView1);
@@ -1422,7 +1431,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testSheetChangeNoInvalidation)
     CPPUNIT_ASSERT(pView);
 
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     SfxLokHelper::setView(nView1);
@@ -1454,7 +1463,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testSheetChangeNoInvalidation)
     // we change B1 there should be an invalidation in the second sheet for the
     // range that depends on it. Because this is a single user document with no
     // active view on the 2nd sheet this will happen on switching back to 
sheet 2
-    lcl_typeCharsInCell("101", 1, 0, pView, pModelObj); // Type '101' in B1
+    typeCharsInCell("101", 1, 0, pView, pModelObj); // Type '101' in B1
     aView1.ClearAllInvalids();
 
     pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::PAGEDOWN | 
KEY_MOD1);
@@ -1490,7 +1499,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInsertDeletePageInvalidation)
     CPPUNIT_ASSERT(pViewData);
 
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     SfxLokHelper::setView(nView1);
@@ -1531,7 +1540,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testGetRowColumnHeadersInvalidation)
     CPPUNIT_ASSERT(pViewData);
 
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     SfxLokHelper::setView(nView1);
@@ -1575,7 +1584,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testJumpHorizontallyInvalidation)
     CPPUNIT_ASSERT(pViewData);
 
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     SfxLokHelper::setView(nView1);
@@ -1599,7 +1608,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testJumpToLastRowInvalidation)
     CPPUNIT_ASSERT(pViewData);
 
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     SfxLokHelper::setView(nView1);
@@ -1622,14 +1631,14 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testRowColumnHeaders)
     CPPUNIT_ASSERT(pViewData);
 
     // view #1
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     int nView1 = SfxLokHelper::getView();
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     // view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
 
     // ViewRowColumnHeaders test
@@ -1863,13 +1872,13 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testSheetGeometryDataInvariance)
     CPPUNIT_ASSERT(pViewData);
 
     // view #1
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     int nView1 = SfxLokHelper::getView();
 
     // view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
 
     // Try with the default empty document once (nIdx = 0) and then with sheet 
geometry settings (nIdx = 1)
@@ -1987,7 +1996,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testSheetGeometryDataCorrectness)
     CPPUNIT_ASSERT(pViewData);
 
     // view #1
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // with the default empty sheet and test the JSON encoding.
     OString aGeomDefaultStr = pModelObj->getSheetGeometryData(/*bColumns*/ 
true, /*bRows*/ true, /*bSizes*/ true,
@@ -2013,7 +2022,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testDeleteCellMultilineContent)
     CPPUNIT_ASSERT(pDocSh);
 
     // view #1
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     aView1.m_sInvalidateHeader = ""_ostr;
@@ -2051,7 +2060,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testPasteIntoWrapTextCell)
     ScViewData* pViewData = ScDocShell::GetViewData();
     CPPUNIT_ASSERT(pViewData);
 
-    ViewCallback aView;
+    ScTestViewCallback aView;
     CPPUNIT_ASSERT(!lcl_hasEditView(*pViewData));
 
     ScTabViewShell* pView = 
dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
@@ -2128,7 +2137,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testSortAscendingDescending)
     ScModelObj* pModelObj = createDoc("sort-range.ods");
     ScDocument* pDoc = pModelObj->GetDocument();
 
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     // select the values in the first column
     pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, 551, 129, 1, 
MOUSE_LEFT, 0);
@@ -2186,19 +2195,19 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testAutoInputStringBlock)
     pDoc->SetString(ScAddress(0, 7, 0), u"ZZZ"_ustr);  // A8
 
     ScAddress aA1(0, 0, 0);
-    lcl_typeCharsInCell("X", aA1.Col(), aA1.Row(), pView, pModelObj); // Type 
'X' in A1
+    typeCharsInCell("X", aA1.Col(), aA1.Row(), pView, pModelObj); // Type 'X' 
in A1
     CPPUNIT_ASSERT_EQUAL_MESSAGE("A1 should autocomplete", u"XYZ"_ustr, 
pDoc->GetString(aA1));
 
     ScAddress aA3(0, 2, 0); // Adjacent to the string "superblock" A4:A8
-    lcl_typeCharsInCell("X", aA3.Col(), aA3.Row(), pView, pModelObj); // Type 
'X' in A3
+    typeCharsInCell("X", aA3.Col(), aA3.Row(), pView, pModelObj); // Type 'X' 
in A3
     CPPUNIT_ASSERT_EQUAL_MESSAGE("A3 should autocomplete", u"XYZ"_ustr, 
pDoc->GetString(aA3));
 
     ScAddress aA9(0, 8, 0); // Adjacent to the string "superblock" A4:A8
-    lcl_typeCharsInCell("X", aA9.Col(), aA9.Row(), pView, pModelObj); // Type 
'X' in A9
+    typeCharsInCell("X", aA9.Col(), aA9.Row(), pView, pModelObj); // Type 'X' 
in A9
     CPPUNIT_ASSERT_EQUAL_MESSAGE("A9 should autocomplete", u"XYZ"_ustr, 
pDoc->GetString(aA9));
 
     ScAddress aA11(0, 10, 0);
-    lcl_typeCharsInCell("X", aA11.Col(), aA11.Row(), pView, pModelObj); // 
Type 'X' in A11
+    typeCharsInCell("X", aA11.Col(), aA11.Row(), pView, pModelObj); // Type 
'X' in A11
     CPPUNIT_ASSERT_EQUAL_MESSAGE("A11 should autocomplete", u"XYZ"_ustr, 
pDoc->GetString(aA11));
 }
 
@@ -2220,31 +2229,31 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testAutoInputExactMatch)
     pDoc->SetString(ScAddress(0, 6, 0), u"Castle"_ustr);  // A7
 
     ScAddress aA8(0, 7, 0);
-    lcl_typeCharsInCell("S", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"S" in A8
+    typeCharsInCell("S", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "S" 
in A8
     // Should show the partial completion "i".
     CPPUNIT_ASSERT_EQUAL_MESSAGE("1: A8 should have partial completion Si", 
u"Si"_ustr, pDoc->GetString(aA8));
 
-    lcl_typeCharsInCell("Si", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"Si" in A8
+    typeCharsInCell("Si", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"Si" in A8
     // Should not show any suggestions.
     CPPUNIT_ASSERT_EQUAL_MESSAGE("2: A8 should not show suggestions", 
u"Si"_ustr, pDoc->GetString(aA8));
 
-    lcl_typeCharsInCell("Sim", aA8.Col(), aA8.Row(), pView, pModelObj); // 
Type "Sim" in A8
+    typeCharsInCell("Sim", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"Sim" in A8
     // Should autocomplete to "Simple" which is the only match.
     CPPUNIT_ASSERT_EQUAL_MESSAGE("3: A8 should autocomplete", u"Simple"_ustr, 
pDoc->GetString(aA8));
 
-    lcl_typeCharsInCell("Sin", aA8.Col(), aA8.Row(), pView, pModelObj); // 
Type "Sin" in A8
+    typeCharsInCell("Sin", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"Sin" in A8
     // Should autocomplete to "Sing" which is the only match.
     CPPUNIT_ASSERT_EQUAL_MESSAGE("4: A8 should autocomplete", u"Sing"_ustr, 
pDoc->GetString(aA8));
 
-    lcl_typeCharsInCell("C", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"C" in A8
+    typeCharsInCell("C", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "C" 
in A8
     // Should show the partial completion "as".
     CPPUNIT_ASSERT_EQUAL_MESSAGE("5: A8 should have partial completion Cas", 
u"Cas"_ustr, pDoc->GetString(aA8));
 
-    lcl_typeCharsInCell("Cast", aA8.Col(), aA8.Row(), pView, pModelObj); // 
Type "Cast" in A8
+    typeCharsInCell("Cast", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"Cast" in A8
     // Should autocomplete to "Castle" which is the only match.
     CPPUNIT_ASSERT_EQUAL_MESSAGE("6: A8 should autocomplete", u"Castle"_ustr, 
pDoc->GetString(aA8));
 
-    lcl_typeCharsInCell("T", aA8.Col(), aA8.Row(), pView, pModelObj); // Type 
"T" in A8
+    typeCharsInCell("T", aA8.Col(), aA8.Row(), pView, pModelObj); // Type "T" 
in A8
     // Should autocomplete to "Time" which is the only match.
     CPPUNIT_ASSERT_EQUAL_MESSAGE("7: A8 should autocomplete", u"Time"_ustr, 
pDoc->GetString(aA8));
 }
@@ -2256,7 +2265,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testEditCursorBounds)
     ScModelObj* pModelObj = createDoc("empty.ods");
     ScDocument* pDoc = pModelObj->GetDocument();
 
-    ViewCallback aView;
+    ScTestViewCallback aView;
     ScTabViewShell* pView = 
dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
     CPPUNIT_ASSERT(pView);
     comphelper::LibreOfficeKit::setViewIdForVisCursorInvalidation(true);
@@ -2299,7 +2308,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testTextSelectionBounds)
     ScModelObj* pModelObj = createDoc("empty.ods");
     ScDocument* pDoc = pModelObj->GetDocument();
 
-    ViewCallback aView;
+    ScTestViewCallback aView;
     ScTabViewShell* pView = 
dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
     CPPUNIT_ASSERT(pView);
     comphelper::LibreOfficeKit::setViewIdForVisCursorInvalidation(true);
@@ -2381,7 +2390,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testSheetViewDataCrash)
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testTextBoxInsert)
 {
     createDoc("empty.ods");
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // insert textbox
     uno::Sequence<beans::PropertyValue> aArgs(
@@ -2407,7 +2416,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCommentCellCopyPaste)
 
     {
         ScModelObj* pModelObj = createDoc("empty.ods");
-        ViewCallback aView;
+        ScTestViewCallback aView;
         int nView = SfxLokHelper::getView();
 
         SfxLokHelper::setView(nView);
@@ -2415,7 +2424,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCommentCellCopyPaste)
         ScTabViewShell* pTabViewShell = 
dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
         CPPUNIT_ASSERT(pTabViewShell);
 
-        lcl_typeCharsInCell("ABC", 0, 0, pTabViewShell, pModelObj); // Type 
"ABC" in A1
+        typeCharsInCell("ABC", 0, 0, pTabViewShell, pModelObj); // Type "ABC" 
in A1
 
         pTabViewShell->SetCursor(1, 1);
 
@@ -2499,7 +2508,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidEntrySave)
     CPPUNIT_ASSERT(pModelObj);
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
     const ScDocument* pDoc = pModelObj->GetDocument();
-    ViewCallback aView;
+    ScTestViewCallback aView;
     int nView = SfxLokHelper::getView();
 
     SfxLokHelper::setView(nView);
@@ -2510,7 +2519,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidEntrySave)
 
     // Type partial date "7/8" of "7/8/2013" that
     // the validation cell at A8 can accept
-    lcl_typeCharsInCell("7/8", 0, 7, pTabViewShell, pModelObj,
+    typeCharsInCell("7/8", 0, 7, pTabViewShell, pModelObj,
         false /* bInEdit */, false /* bCommit */); // Type "7/8" in A8
 
     uno::Sequence<beans::PropertyValue> aArgs;
@@ -2519,7 +2528,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidEntrySave)
     CPPUNIT_ASSERT_MESSAGE("Should not be marked modified after save", 
!pDocSh->IsModified());
 
     // Complete the date in A8 by appending "/2013" and commit.
-    lcl_typeCharsInCell("/2013", 0, 7, pTabViewShell, pModelObj,
+    typeCharsInCell("/2013", 0, 7, pTabViewShell, pModelObj,
         true /* bInEdit */, true /* bCommit */);
 
     // This would hang if the date entered "7/8/2013" is not acceptable.
@@ -2540,13 +2549,13 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testUndoReordering)
 
     // view #1
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // text edit a cell in view #1
     SfxLokHelper::setView(nView1);
@@ -2601,14 +2610,14 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testUndoReorderingRedo)
     // view #1
     int nView1 = SfxLokHelper::getView();
     SfxViewShell* pView1 = SfxViewShell::Current();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
     SfxViewShell* pView2 = SfxViewShell::Current();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // text edit a cell in view #1
     SfxLokHelper::setView(nView1);
@@ -2690,13 +2699,13 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testUndoReorderingMulti)
 
     // view #1
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // text edit a cell in view #1
     SfxLokHelper::setView(nView1);
@@ -2756,12 +2765,12 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testGetViewRenderState)
 
     ScModelObj* pModelObj = createDoc("empty.ods");
     int nFirstViewId = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     CPPUNIT_ASSERT_EQUAL("S;Default"_ostr, pModelObj->getViewRenderState());
     // Create a second view
     SfxLokHelper::createView();
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     CPPUNIT_ASSERT_EQUAL("S;Default"_ostr, pModelObj->getViewRenderState());
     // Set second view to dark scheme
     {
@@ -2823,7 +2832,7 @@ void 
testInvalidateOnTextEditWithDifferentZoomLevels::TestBody(const ColRowZoom&
         sZoomUnoCmd = ".uno:ZoomMinus";
     }
     // view #1
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     // set zoom level
     for (int i = 0; i < nZoomLevel; ++i)
         dispatchCommand(mxComponent, sZoomUnoCmd, {});
@@ -2849,7 +2858,7 @@ void 
testInvalidateOnTextEditWithDifferentZoomLevels::TestBody(const ColRowZoom&
     // view #2
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     Scheduler::ProcessEventsToIdle();
     auto* pTabViewShell2 = 
dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
     CPPUNIT_ASSERT(pTabViewShell2);
@@ -2872,9 +2881,9 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testOpenURL)
     // Given a document that has 2 views:
     createDoc("empty.ods");
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     SfxLokHelper::createView();
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // When clicking on a link in view 2, but switching to view 1 before 
processing async events:
     ScGlobal::OpenURL(/*aUrl=*/u"http://www.example.com/"_ustr, 
/*aTarget=*/u""_ustr,
@@ -2900,7 +2909,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidateForSplitPanes)
     CPPUNIT_ASSERT(pView);
 
     // view
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     // move way over to the right where BP:20 exists, enough so that rows A 
and B
     // would scroll off the page and not be visible, if they were not frozen
@@ -2915,7 +2924,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidateForSplitPanes)
     aView.m_bInvalidateTiles = false;
     aView.m_aInvalidations.clear();
 
-    lcl_typeCharsInCell("X", aBP20.Col(), aBP20.Row(), pView, pModelObj); // 
Type 'X' in A1
+    typeCharsInCell("X", aBP20.Col(), aBP20.Row(), pView, pModelObj); // Type 
'X' in A1
 
     CPPUNIT_ASSERT(aView.m_bInvalidateTiles);
 
@@ -2952,7 +2961,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testNoInvalidateOnSave)
     Scheduler::ProcessEventsToIdle();
 
     // track invalidations
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     uno::Sequence<beans::PropertyValue> aArgs;
     dispatchCommand(mxComponent, u".uno:Save"_ustr, aArgs);
@@ -2962,60 +2971,6 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testNoInvalidateOnSave)
     CPPUNIT_ASSERT(!aView.m_bInvalidateTiles);
 }
 
-void ScTiledRenderingTest::checkSampleInvalidation(const ViewCallback& rView, 
bool bFullRow)
-{
-    // we expect invalidations, but that isn't really important
-    CPPUNIT_ASSERT(rView.m_bInvalidateTiles);
-    tools::Rectangle aInvalidation;
-    for (const auto& rRect : rView.m_aInvalidations)
-        aInvalidation.Union(rRect);
-    if (!bFullRow)
-    {
-        // What matters is that we expect that the invalidation does not 
extend all the
-        // way to the max right of the sheet.
-        // Here we originally got 32212306 and now ~5056 for a single cell case
-        CPPUNIT_ASSERT_LESSEQUAL(tools::Long(8000), aInvalidation.GetWidth());
-    }
-    else
-    {
-        // We expect RTL to continue to invalidate the entire row
-        // from 0 to end of sheet (see ScDocShell::PostPaint, 'Extend to whole 
rows'),
-        // which is different to the adjusted LTR case which
-        // invalidated the row from left of edited cell to right of end
-        // of sheet.
-        CPPUNIT_ASSERT_LESSEQUAL(tools::Long(0), aInvalidation.Left());
-        CPPUNIT_ASSERT_EQUAL(tools::Long(32212230), aInvalidation.Right());
-    }
-}
-
-void ScTiledRenderingTest::cellInvalidationHelper(ScModelObj* pModelObj, 
ScTabViewShell* pView, const ScAddress& rAdr,
-                                                  bool bAddText, bool bFullRow)
-{
-    // view
-    ViewCallback aView;
-
-    if (bAddText)
-    {
-        // Type "Hello World" in D8, process events to idle and don't commit 
yet
-        lcl_typeCharsInCell("Hello World", rAdr.Col(), rAdr.Row(), pView, 
pModelObj, false, false);
-
-        aView.m_bInvalidateTiles = false;
-        aView.m_aInvalidations.clear();
-
-        // commit text and process events to idle
-        lcl_typeCharsInCell("", rAdr.Col(), rAdr.Row(), pView, pModelObj, 
true, true);
-    }
-    else // DeleteText
-    {
-        pView->SetCursor(rAdr.Col(), rAdr.Row());
-        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::DELETE);
-        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::DELETE);
-        Scheduler::ProcessEventsToIdle();
-    }
-
-    checkSampleInvalidation(aView, bFullRow);
-}
-
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testCellMinimalInvalidations)
 {
     ScAddress aA8(0, 7, 0);
@@ -3045,7 +3000,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCellMinimalInvalidations)
         pView->SetCursor(aA8.Col(), aA8.Row());
         Scheduler::ProcessEventsToIdle();
 
-        ViewCallback aView;
+        ScTestViewCallback aView;
         dispatchCommand(mxComponent, u".uno:Paste"_ustr, aArgs);
         Scheduler::ProcessEventsToIdle();
 
@@ -3089,14 +3044,14 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCellInvalidationDocWithExistingZo
 
     int nView1 = SfxLokHelper::getView();
     // register to track View #1 invalidations
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // Create a View #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
     // register to track View #1 invalidations
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
 
     // Set View #2 to initial 100% and generate a paint
     pModelObj->setClientVisibleArea(tools::Rectangle(0, 0, 19845, 6405));
@@ -3224,9 +3179,9 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testStatusBarLocale)
     // Given 2 views, the second's locale is set to German:
     createDoc("empty.ods");
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     SfxLokHelper::createView();
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     SfxViewShell* pView2 = SfxViewShell::Current();
     pView2->SetLOKLocale(u"de-DE"_ustr);
     {
@@ -3295,7 +3250,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testLongFirstColumnMouseClick)
     int y = 1 / nPPTY;
 
     // Setup view #1
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     // Set client rect to 2000 x 2000 pixels
     pModelObj->setClientVisibleArea(tools::Rectangle(0, 0, 2000 / nPPTX, 2000 
/ nPPTY));
     Scheduler::ProcessEventsToIdle();
@@ -3323,7 +3278,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testLongFirstColumnMouseClick)
     // Setup view #2
     SfxLokHelper::createView();
     int nView2 = SfxLokHelper::getView();
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     // Set client rect to 2000 x 2000 pixels
     pModelObj->setClientVisibleArea(tools::Rectangle(0, 0, 2000 / nPPTX, 2000 
/ nPPTY));
 
@@ -3369,7 +3324,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testExtendedAreasDontOverlap)
     Scheduler::ProcessEventsToIdle();
 
     // register to track View #1 invalidations
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // extend to the right and bottom
     pModelObj->setClientVisibleArea(tools::Rectangle(0, 0, 39750, 12780));
@@ -3421,7 +3376,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testEditShapeText)
     Bitmap aBitmapBefore = getTile(pModelObj, 4096, 3584, 15360, 7680);
 
     // reuse this to type into the active shape edit
-    lcl_typeCharsInCell("MMMMMMM", 0, 0, pView, pModelObj, true, false);
+    typeCharsInCell("MMMMMMM", 0, 0, pView, pModelObj, true, false);
 
     // Grab a new snapshot of the center of the shape
     Bitmap aBitmapAfter = getTile(pModelObj, 4096, 3584, 15360, 7680);
@@ -3449,7 +3404,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testNumberFormatLocaleMultiUser)
         ScDocument* pDoc = pModelObj->GetDocument();
 
         int nViewFR = SfxLokHelper::getView();
-        ViewCallback aView1;
+        ScTestViewCallback aView1;
         SfxViewShell* pViewFR = SfxViewShell::Current();
         pViewFR->SetLOKLocale(u"fr-FR"_ustr);
 
@@ -3505,7 +3460,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testLeftOverflowEdit)
 {
     
comphelper::LibreOfficeKit::setCompatFlag(comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
     ScModelObj* pModelObj = createDoc("right-aligned-with-overflow.ods");
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     // Go to Cell B5000
     uno::Sequence<beans::PropertyValue> aPropertyValues = {
@@ -3532,7 +3487,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testLeftOverflowEdit)
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testFreezeRowOrColumn)
 {
     createDoc("empty.ods");
-    ViewCallback aView;
+    ScTestViewCallback aView;
     SfxViewShell* pView = SfxViewShell::Current();
 
     // Freeze panes on a column and receive the proper state back
@@ -3572,7 +3527,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testFreezeRowOrColumn)
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testCursorVisibilityAfterPaste)
 {
     ScModelObj* pModelObj = createDoc("empty.ods");
-    ViewCallback aView;
+    ScTestViewCallback aView;
     SfxLokHelper::createView();
     
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
 
diff --git a/sc/qa/unit/tiledrendering/tiledrendering2.cxx 
b/sc/qa/unit/tiledrendering/tiledrendering2.cxx
index ccf2acd92e51..b3625d3128e6 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering2.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering2.cxx
@@ -7,12 +7,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include "tiledrenderingmodeltestbase.cxx"
+#include <sctiledrenderingtest.hxx>
 
 #include <com/sun/star/datatransfer/XTransferable2.hpp>
 
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/propertysequence.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <vcl/scheduler.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+
+#include <sctestviewcallback.hxx>
+#include <docuno.hxx>
+#include <tabvwsh.hxx>
 
 using namespace com::sun::star;
 
@@ -20,11 +27,11 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testSidebarLocale)
 {
     ScModelObj* pModelObj = createDoc("chart.ods");
     int nView1 = SfxLokHelper::getView();
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     SfxViewShell* pView1 = SfxViewShell::Current();
     pView1->SetLOKLocale(u"en-US"_ustr);
     SfxLokHelper::createView();
-    ViewCallback aView2;
+    ScTestViewCallback aView2;
     SfxViewShell* pView2 = SfxViewShell::Current();
     pView2->SetLOKLocale(u"de-DE"_ustr);
     TestLokCallbackWrapper::InitializeSidebar();
@@ -48,7 +55,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCopyMultiSelection)
 {
     // Given a document with A1 and A3 as selected cells:
     ScModelObj* pModelObj = createDoc("multi-selection.ods");
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
     // Get the center of A3:
     uno::Sequence<beans::PropertyValue> aPropertyValues = {
         comphelper::makePropertyValue(u"ToPoint"_ustr, u"$A$3"_ustr),
@@ -81,7 +88,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testCopyMultiSelection)
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testCursorJumpOnFailedSearch)
 {
     createDoc("empty.ods");
-    ViewCallback aView;
+    ScTestViewCallback aView;
 
     // Go to lower cell
     uno::Sequence<beans::PropertyValue> aPropertyValues = {
@@ -112,7 +119,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testLocaleFormulaSeparator)
     ScDocument* pDoc = pModelObj->GetDocument();
 
     ScAddress addr(2, 0, 0);
-    lcl_typeCharsInCell("=subtotal(9,A1:A8", addr.Col(), addr.Row(), pView, 
pModelObj, false, true);
+    typeCharsInCell("=subtotal(9,A1:A8", addr.Col(), addr.Row(), pView, 
pModelObj, false, true);
     // Without the fix it would fail with
     // - Expected: 0
     // - Actual  : Err:508
@@ -123,7 +130,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testDecimalSeparatorInfo)
 {
     createDoc("decimal-separator.ods");
 
-    ViewCallback aView1;
+    ScTestViewCallback aView1;
 
     // Go to cell A1.
     uno::Sequence<beans::PropertyValue> aPropertyValues
diff --git a/sc/qa/unit/tiledrendering/tiledrenderingmodeltestbase.cxx 
b/sc/qa/unit/tiledrendering/tiledrenderingmodeltestbase.cxx
deleted file mode 100644
index 99917ea72ca2..000000000000
--- a/sc/qa/unit/tiledrendering/tiledrenderingmodeltestbase.cxx
+++ /dev/null
@@ -1,521 +0,0 @@
-/* -*- 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 <test/unoapixml_test.hxx>
-#include <boost/property_tree/json_parser.hpp>
-
-#include <LibreOfficeKit/LibreOfficeKitEnums.h>
-#include <osl/conditn.hxx>
-#include <sfx2/lokhelper.hxx>
-#include <comphelper/string.hxx>
-#include <tabvwsh.hxx>
-#include <test/lokcallback.hxx>
-#include <docuno.hxx>
-#include <vcl/scheduler.hxx>
-
-using namespace css;
-
-class ViewCallback;
-
-class ScTiledRenderingTest : public UnoApiXmlTest
-{
-public:
-    ScTiledRenderingTest();
-    virtual void setUp() override;
-    virtual void tearDown() override;
-
-    void checkSampleInvalidation(const ViewCallback& rView, bool bFullRow);
-    void cellInvalidationHelper(ScModelObj* pModelObj, ScTabViewShell* pView, 
const ScAddress& rAdr,
-                                bool bAddText, bool bFullRow);
-
-    ScModelObj* createDoc(const char* pName);
-    void setupLibreOfficeKitViewCallback(SfxViewShell* pViewShell);
-    static void callback(int nType, const char* pPayload, void* pData);
-    void callbackImpl(int nType, const char* pPayload);
-
-    /// document size changed callback.
-    osl::Condition m_aDocSizeCondition;
-    Size m_aDocumentSize;
-
-    TestLokCallbackWrapper m_callbackWrapper;
-};
-
-ScTiledRenderingTest::ScTiledRenderingTest()
-    : UnoApiXmlTest(u"/sc/qa/unit/tiledrendering/data/"_ustr)
-    , m_callbackWrapper(&callback, this)
-{
-}
-
-void ScTiledRenderingTest::setUp()
-{
-    UnoApiXmlTest::setUp();
-
-    comphelper::LibreOfficeKit::setActive(true);
-}
-
-void ScTiledRenderingTest::tearDown()
-{
-    if (mxComponent.is())
-    {
-        mxComponent->dispose();
-        mxComponent.clear();
-    }
-
-    m_callbackWrapper.clear();
-
-    comphelper::LibreOfficeKit::resetCompatFlag();
-
-    comphelper::LibreOfficeKit::setActive(false);
-
-    UnoApiXmlTest::tearDown();
-}
-
-ScModelObj* ScTiledRenderingTest::createDoc(const char* pName)
-{
-    loadFromFile(OUString::createFromAscii(pName));
-
-    ScModelObj* pModelObj = 
comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
-    CPPUNIT_ASSERT(pModelObj);
-    
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
-    return pModelObj;
-}
-
-void ScTiledRenderingTest::setupLibreOfficeKitViewCallback(SfxViewShell* 
pViewShell)
-{
-    pViewShell->setLibreOfficeKitViewCallback(&m_callbackWrapper);
-    m_callbackWrapper.setLOKViewId(SfxLokHelper::getView(pViewShell));
-}
-
-void ScTiledRenderingTest::callback(int nType, const char* pPayload, void* 
pData)
-{
-    static_cast<ScTiledRenderingTest*>(pData)->callbackImpl(nType, pPayload);
-}
-
-void ScTiledRenderingTest::callbackImpl(int nType, const char* pPayload)
-{
-    switch (nType)
-    {
-        case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
-        {
-            OString aPayload(pPayload);
-            sal_Int32 nIndex = 0;
-            OString aToken = aPayload.getToken(0, ',', nIndex);
-            m_aDocumentSize.setWidth(aToken.toInt32());
-            aToken = aPayload.getToken(0, ',', nIndex);
-            m_aDocumentSize.setHeight(aToken.toInt32());
-            m_aDocSizeCondition.set();
-        }
-        break;
-    }
-}
-
-struct EditCursorMessage final
-{
-    tools::Rectangle m_aRelRect;
-    Point m_aRefPoint;
-
-    void clear()
-    {
-        m_aRelRect.SetEmpty();
-        m_aRefPoint = Point(-1, -1);
-    }
-
-    bool empty() { return m_aRelRect.IsEmpty() && m_aRefPoint.X() == -1 && 
m_aRefPoint.Y() == -1; }
-
-    void parseMessage(const char* pMessage)
-    {
-        clear();
-        if (!pMessage
-            || !comphelper::LibreOfficeKit::isCompatFlagSet(
-                   comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs)
-            || !comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation())
-            return;
-
-        std::stringstream aStream(pMessage);
-        boost::property_tree::ptree aTree;
-        boost::property_tree::read_json(aStream, aTree);
-        std::string aVal;
-        boost::property_tree::ptree::const_assoc_iterator it = 
aTree.find("refpoint");
-        if (it != aTree.not_found())
-            aVal = aTree.get_child("refpoint").get_value<std::string>();
-        else
-            return; // happens in testTextBoxInsert test
-
-        uno::Sequence<OUString> aSeq
-            = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(aVal));
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aSeq.getLength());
-        m_aRefPoint.setX(aSeq[0].toInt32());
-        m_aRefPoint.setY(aSeq[1].toInt32());
-
-        aVal = aTree.get_child("relrect").get_value<std::string>();
-        aSeq = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(aVal));
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aSeq.getLength());
-        m_aRelRect.SetLeft(aSeq[0].toInt32());
-        m_aRelRect.SetTop(aSeq[1].toInt32());
-        m_aRelRect.setWidth(aSeq[2].toInt32());
-        m_aRelRect.setHeight(aSeq[3].toInt32());
-    }
-
-    tools::Rectangle getBounds()
-    {
-        tools::Rectangle aBounds = m_aRelRect;
-        aBounds.Move(m_aRefPoint.X(), m_aRefPoint.Y());
-        return aBounds;
-    }
-};
-
-struct TextSelectionMessage
-{
-    std::vector<tools::Rectangle> m_aRelRects;
-    Point m_aRefPoint;
-
-    void clear()
-    {
-        m_aRefPoint.setX(0);
-        m_aRefPoint.setY(0);
-        m_aRelRects.clear();
-    }
-
-    bool empty() { return m_aRelRects.empty(); }
-
-    void parseMessage(const char* pMessage)
-    {
-        clear();
-        if (!pMessage)
-            return;
-
-        std::string aStr(pMessage);
-        if (aStr.find(",") == std::string::npos)
-            return;
-
-        size_t nRefDelimStart = aStr.find("::");
-        std::string aRectListString
-            = (nRefDelimStart == std::string::npos) ? aStr : aStr.substr(0, 
nRefDelimStart);
-        std::string aRefPointString
-            = (nRefDelimStart == std::string::npos)
-                  ? std::string("0, 0")
-                  : aStr.substr(nRefDelimStart + 2, aStr.length() - 2 - 
nRefDelimStart);
-        uno::Sequence<OUString> aSeq
-            = 
comphelper::string::convertCommaSeparated(OUString::createFromAscii(aRefPointString));
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aSeq.getLength());
-        m_aRefPoint.setX(aSeq[0].toInt32());
-        m_aRefPoint.setY(aSeq[1].toInt32());
-
-        size_t nStart = 0;
-        size_t nEnd = aRectListString.find(";");
-        if (nEnd == std::string::npos)
-            nEnd = aRectListString.length();
-        do
-        {
-            std::string aRectString = aRectListString.substr(nStart, nEnd - 
nStart);
-            {
-                aSeq = comphelper::string::convertCommaSeparated(
-                    OUString::createFromAscii(aRectString));
-                CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aSeq.getLength());
-                tools::Rectangle aRect;
-                aRect.SetLeft(aSeq[0].toInt32());
-                aRect.SetTop(aSeq[1].toInt32());
-                aRect.setWidth(aSeq[2].toInt32());
-                aRect.setHeight(aSeq[3].toInt32());
-
-                m_aRelRects.push_back(aRect);
-            }
-
-            nStart = nEnd + 1;
-            nEnd = aRectListString.find(";", nStart);
-        } while (nEnd != std::string::npos);
-    }
-
-    tools::Rectangle getBounds(size_t nIndex)
-    {
-        if (nIndex >= m_aRelRects.size())
-            return tools::Rectangle();
-
-        tools::Rectangle aBounds = m_aRelRects[nIndex];
-        aBounds.Move(m_aRefPoint.X(), m_aRefPoint.Y());
-        return aBounds;
-    }
-};
-
-/// A view callback tracks callbacks invoked on one specific view.
-class ViewCallback final
-{
-    SfxViewShell* mpViewShell;
-    int mnView;
-
-public:
-    bool m_bOwnCursorInvalidated;
-    bool m_bViewCursorInvalidated;
-    bool m_textCursorVisible;
-    bool m_bTextViewSelectionInvalidated;
-    bool m_bGraphicSelection;
-    bool m_bGraphicViewSelection;
-    bool m_bFullInvalidateTiles;
-    bool m_bInvalidateTiles;
-    std::vector<tools::Rectangle> m_aInvalidations;
-    tools::Rectangle m_aCellCursorBounds;
-    std::vector<int> m_aInvalidationsParts;
-    std::vector<int> m_aInvalidationsMode;
-    bool m_bViewLock;
-    OString m_sCellFormula;
-    boost::property_tree::ptree m_aCommentCallbackResult;
-    EditCursorMessage m_aInvalidateCursorResult;
-    TextSelectionMessage m_aTextSelectionResult;
-    OString m_sInvalidateHeader;
-    OString m_sInvalidateSheetGeometry;
-    OString m_aHyperlinkClicked;
-    OString m_ShapeSelection;
-    std::map<std::string, boost::property_tree::ptree> m_aStateChanges;
-    std::string decimalSeparator;
-    TestLokCallbackWrapper m_callbackWrapper;
-
-    ViewCallback(bool bDeleteListenerOnDestruct = true)
-        : m_bOwnCursorInvalidated(false)
-        , m_bViewCursorInvalidated(false)
-        , m_textCursorVisible(false)
-        , m_bTextViewSelectionInvalidated(false)
-        , m_bGraphicSelection(false)
-        , m_bGraphicViewSelection(false)
-        , m_bFullInvalidateTiles(false)
-        , m_bInvalidateTiles(false)
-        , m_bViewLock(false)
-        , m_callbackWrapper(&callback, this)
-    {
-        mpViewShell = SfxViewShell::Current();
-        mpViewShell->setLibreOfficeKitViewCallback(&m_callbackWrapper);
-        mnView = SfxLokHelper::getView();
-        m_callbackWrapper.setLOKViewId(mnView);
-        if (!bDeleteListenerOnDestruct)
-            mpViewShell = nullptr;
-    }
-
-    ~ViewCallback()
-    {
-        if (mpViewShell)
-        {
-            SfxLokHelper::setView(mnView);
-            mpViewShell->setLibreOfficeKitViewCallback(nullptr);
-        }
-    }
-
-    static void callback(int nType, const char* pPayload, void* pData)
-    {
-        static_cast<ViewCallback*>(pData)->callbackImpl(nType, pPayload);
-    }
-
-    void callbackImpl(int nType, const char* pPayload)
-    {
-        switch (nType)
-        {
-            case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
-            {
-                boost::property_tree::ptree aTree;
-                std::stringstream aStream(pPayload);
-                boost::property_tree::read_json(aStream, aTree);
-                m_textCursorVisible = 
aTree.get_child("visible").get_value<std::string>() == "true";
-            }
-            break;
-            case LOK_CALLBACK_CELL_CURSOR:
-            {
-                m_bOwnCursorInvalidated = true;
-                uno::Sequence<OUString> aSeq = 
comphelper::string::convertCommaSeparated(
-                    OUString::createFromAscii(pPayload));
-                m_aCellCursorBounds = tools::Rectangle();
-                if (aSeq.getLength() == 6)
-                {
-                    m_aCellCursorBounds.SetLeft(aSeq[0].toInt32());
-                    m_aCellCursorBounds.SetTop(aSeq[1].toInt32());
-                    m_aCellCursorBounds.setWidth(aSeq[2].toInt32());
-                    m_aCellCursorBounds.setHeight(aSeq[3].toInt32());
-                }
-            }
-            break;
-            case LOK_CALLBACK_CELL_VIEW_CURSOR:
-            {
-                m_bViewCursorInvalidated = true;
-            }
-            break;
-            case LOK_CALLBACK_TEXT_VIEW_SELECTION:
-            {
-                m_bTextViewSelectionInvalidated = true;
-            }
-            break;
-            case LOK_CALLBACK_VIEW_LOCK:
-            {
-                std::stringstream aStream(pPayload);
-                boost::property_tree::ptree aTree;
-                boost::property_tree::read_json(aStream, aTree);
-                m_bViewLock = 
aTree.get_child("rectangle").get_value<std::string>() != "EMPTY";
-            }
-            break;
-            case LOK_CALLBACK_GRAPHIC_SELECTION:
-            {
-                m_bGraphicSelection = true;
-                m_ShapeSelection = OString(pPayload);
-            }
-            break;
-            case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
-            {
-                m_bGraphicViewSelection = true;
-            }
-            break;
-            case LOK_CALLBACK_INVALIDATE_TILES:
-            {
-                OString text(pPayload);
-                if (text.startsWith("EMPTY"))
-                {
-                    m_bFullInvalidateTiles = true;
-                }
-                else
-                {
-                    uno::Sequence<OUString> aSeq = 
comphelper::string::convertCommaSeparated(
-                        OUString::createFromAscii(pPayload));
-                    CPPUNIT_ASSERT(aSeq.getLength() == 4 || aSeq.getLength() 
== 6);
-                    tools::Rectangle aInvalidationRect;
-                    aInvalidationRect.SetLeft(aSeq[0].toInt32());
-                    aInvalidationRect.SetTop(aSeq[1].toInt32());
-                    aInvalidationRect.setWidth(aSeq[2].toInt32());
-                    aInvalidationRect.setHeight(aSeq[3].toInt32());
-                    m_aInvalidations.push_back(aInvalidationRect);
-                    if (aSeq.getLength() == 6)
-                    {
-                        m_aInvalidationsParts.push_back(aSeq[4].toInt32());
-                        m_aInvalidationsMode.push_back(aSeq[5].toInt32());
-                    }
-                    m_bInvalidateTiles = true;
-                }
-            }
-            break;
-            case LOK_CALLBACK_CELL_FORMULA:
-            {
-                m_sCellFormula = pPayload;
-            }
-            break;
-            case LOK_CALLBACK_COMMENT:
-            {
-                m_aCommentCallbackResult.clear();
-                std::stringstream aStream(pPayload);
-                boost::property_tree::read_json(aStream, 
m_aCommentCallbackResult);
-                m_aCommentCallbackResult = 
m_aCommentCallbackResult.get_child("comment");
-            }
-            break;
-            case LOK_CALLBACK_INVALIDATE_HEADER:
-            {
-                m_sInvalidateHeader = pPayload;
-            }
-            break;
-            case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
-            {
-                m_sInvalidateSheetGeometry = pPayload;
-            }
-            break;
-            case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
-            {
-                m_aInvalidateCursorResult.parseMessage(pPayload);
-            }
-            break;
-            case LOK_CALLBACK_HYPERLINK_CLICKED:
-            {
-                m_aHyperlinkClicked = pPayload;
-            }
-            break;
-            case LOK_CALLBACK_TEXT_SELECTION:
-            {
-                m_aTextSelectionResult.parseMessage(pPayload);
-            }
-            break;
-            case LOK_CALLBACK_STATE_CHANGED:
-            {
-                std::stringstream aStream(pPayload);
-                boost::property_tree::ptree aTree;
-                std::string aCommandName;
-
-                if (aStream.str().starts_with("{"))
-                {
-                    boost::property_tree::read_json(aStream, aTree);
-                    auto it = aTree.find("commandName");
-                    if (it == aTree.not_found())
-                    {
-                        break;
-                    }
-
-                    aCommandName = it->second.get_value<std::string>();
-                }
-                else
-                {
-                    std::string aState = aStream.str();
-                    auto it = aState.find("=");
-                    if (it == std::string::npos)
-                    {
-                        break;
-                    }
-                    aCommandName = aState.substr(0, it);
-                    aTree.put("state", aState.substr(it + 1));
-                }
-
-                m_aStateChanges[aCommandName] = aTree;
-            }
-            break;
-            case LOK_CALLBACK_JSDIALOG:
-            {
-                std::stringstream aStream(pPayload);
-                boost::property_tree::ptree aTree;
-                boost::property_tree::read_json(aStream, aTree);
-                if (aTree.get_child("jsontype").get_value<std::string>() == 
"formulabar")
-                {
-                    if (aTree.find("data") != aTree.not_found())
-                    {
-                        if (aTree.get_child("data").find("separator")
-                            != aTree.get_child("data").not_found())
-                        {
-                            decimalSeparator = aTree.get_child("data")
-                                                   .get_child("separator")
-                                                   .get_value<std::string>();
-                        }
-                    }
-                }
-            }
-            break;
-        }
-    }
-
-    void ClearAllInvalids()
-    {
-        m_bInvalidateTiles = false;
-        m_aInvalidations.clear();
-        m_aInvalidationsParts.clear();
-        m_aInvalidationsMode.clear();
-    }
-};
-
-namespace
-{
-void lcl_typeCharsInCell(const std::string& aStr, SCCOL nCol, SCROW nRow, 
ScTabViewShell* pView,
-                         ScModelObj* pModelObj, bool bInEdit = false, bool 
bCommit = true)
-{
-    if (!bInEdit)
-        pView->SetCursor(nCol, nRow);
-
-    for (const char& cChar : aStr)
-    {
-        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, cChar, 0);
-        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, cChar, 0);
-        Scheduler::ProcessEventsToIdle();
-    }
-
-    if (bCommit)
-    {
-        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN);
-        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN);
-        Scheduler::ProcessEventsToIdle();
-    }
-}
-} //namespace
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to