diff options
author | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-01-15 10:46:42 +0000 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-01-22 20:47:16 +0100 |
commit | 6d71c21890c908225945f0fc3566255ed150f660 (patch) | |
tree | f26acef68dc527f6bb3e369544be4cfe1247992f /sc/qa | |
parent | ca324febda317a725e214b24c0d479d8dbbf1f03 (diff) |
don't always invalidate the entire width of the calc window
If know the max width affected we can avoid redrawing much of
the row
LTR cell edits, deletes, single line paste
Change-Id: Ib7e3d8bfa3a5ce7df97f28bcf7858b3abcb752a4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162408
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sc/qa')
-rw-r--r-- | sc/qa/unit/tiledrendering/data/cell-invalidations.ods | bin | 0 -> 9050 bytes | |||
-rw-r--r-- | sc/qa/unit/tiledrendering/tiledrendering.cxx | 128 |
2 files changed, 119 insertions, 9 deletions
diff --git a/sc/qa/unit/tiledrendering/data/cell-invalidations.ods b/sc/qa/unit/tiledrendering/data/cell-invalidations.ods Binary files differnew file mode 100644 index 000000000000..0f117775a467 --- /dev/null +++ b/sc/qa/unit/tiledrendering/data/cell-invalidations.ods diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx index db2af2fca1f8..eeaabd962b5f 100644 --- a/sc/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx @@ -92,6 +92,10 @@ inline std::string toString(const ColRowZoom& item) } CPPUNIT_NS_END +namespace { +class ViewCallback; +} + class ScTiledRenderingTest : public UnoApiXmlTest { public: @@ -99,6 +103,11 @@ public: 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); @@ -3354,6 +3363,112 @@ 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); + ScAddress aD4(3, 7, 0); + ScAddress aD13(3, 12, 0); + ScAddress aD17(3, 16, 0); + + ScModelObj* pModelObj = createDoc("cell-invalidations.ods"); + CPPUNIT_ASSERT(pModelObj); + ScTabViewShell* pView = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); + CPPUNIT_ASSERT(pView); + + // Changed: Minimized invalidations (bFullRow: false) + + // Common case, LTR, default cell formatting + cellInvalidationHelper(pModelObj, pView, aA8, true, false); + cellInvalidationHelper(pModelObj, pView, aD4, true, false); + // Left-aligned merged cells + cellInvalidationHelper(pModelObj, pView, aD17, true, false); + // Delete single cell text case + cellInvalidationHelper(pModelObj, pView, aA8, false, false); + // Paste into a single cell + { + pView->SetCursor(aD4.Col(), aD4.Row()); + uno::Sequence<beans::PropertyValue> aArgs; + dispatchCommand(mxComponent, ".uno:Copy", aArgs); + pView->SetCursor(aA8.Col(), aA8.Row()); + Scheduler::ProcessEventsToIdle(); + + ViewCallback aView; + dispatchCommand(mxComponent, ".uno:Paste", aArgs); + Scheduler::ProcessEventsToIdle(); + + checkSampleInvalidation(aView, false); + } + + // Unchanged: Non-minimized invalidations (bFullRow: true) + + // Centered merged cells; + cellInvalidationHelper(pModelObj, pView, aD13, true, true); + + // switch to RTL sheet + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::PAGEDOWN | KEY_MOD1); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::PAGEDOWN | KEY_MOD1); + Scheduler::ProcessEventsToIdle(); + + cellInvalidationHelper(pModelObj, pView, aA8, true, true); + cellInvalidationHelper(pModelObj, pView, aD4, true, true); + // Delete Text + cellInvalidationHelper(pModelObj, pView, aA8, false, true); +} + // That we don't end up with two views on different zooms that invalidate different // rectangles, each should invalidate the same rectangle CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testCellInvalidationDocWithExistingZoom) @@ -3431,15 +3546,10 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testCellInvalidationDocWithExistingZo // That they don't exactly match doesn't matter, we're not checking rounding issues, // what matters is that they are not utterly different rectangles // Without fix result is originally: - // Comparing invalidation rects Left expected 278 actual 1213 Tolerance 50 - CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE( - aView1.m_aInvalidations[0].TopLeft(), - aView2.m_aInvalidations[0].TopLeft(), - 100); - CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE( - aView1.m_aInvalidations[0].BottomLeft(), - aView2.m_aInvalidations[0].BottomLeft(), - 100); + // Comparing invalidation rectangles Width expected 6214742 actual 26716502 Tolerance 50 + CPPUNIT_ASSERT_RECTANGLE_EQUAL_WITH_TOLERANCE(aView2.m_aInvalidations[0], + aView1.m_aInvalidations[0], + 50); } CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testStatusBarLocale) |