summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2024-01-11 15:08:21 +0900
committerMiklos Vajna <vmiklos@collabora.com>2024-01-11 17:16:53 +0100
commit22a185a977f90d706c3e9d182adeaac310b6f348 (patch)
tree5bb04760e7ca111b4b3427b284705a1decc70075
parentb6aff926cac0dbb3b07c08a69499c0656a0995a5 (diff)
sc lok: set the GridWindow size to the client area size + test
This solves the issue when we click on a long first column (size 800px - default GridWindow size) at a right end position (>800px) and the selection jumped to the neighbouring cell. This solution reverts the workaround for this issue and properly sets the GridWindow to the current reported client visible area size (set with the ScModelObj::setClientVisibleArea call). Also includes a test for this issue. Change-Id: Ia5449893a90ffa0072aad68d772ad9b00206f113 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161907 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r--sc/qa/unit/tiledrendering/data/DocumentWithLongFirstColumn.odsbin0 -> 8096 bytes
-rw-r--r--sc/qa/unit/tiledrendering/tiledrendering.cxx88
-rw-r--r--sc/source/ui/unoobj/docuno.cxx7
-rw-r--r--sc/source/ui/view/viewdata.cxx8
4 files changed, 97 insertions, 6 deletions
diff --git a/sc/qa/unit/tiledrendering/data/DocumentWithLongFirstColumn.ods b/sc/qa/unit/tiledrendering/data/DocumentWithLongFirstColumn.ods
new file mode 100644
index 000000000000..27fc3f45c543
--- /dev/null
+++ b/sc/qa/unit/tiledrendering/data/DocumentWithLongFirstColumn.ods
Binary files differ
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 62155a3efd81..d49fa95c62c5 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -162,6 +162,7 @@ public:
void testOpenURL();
void testInvalidateForSplitPanes();
void testStatusBarLocale();
+ void testLongFirstColumnMouseClick();
CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
CPPUNIT_TEST(testRowColumnHeaders);
@@ -234,6 +235,7 @@ public:
CPPUNIT_TEST(testOpenURL);
CPPUNIT_TEST(testInvalidateForSplitPanes);
CPPUNIT_TEST(testStatusBarLocale);
+ CPPUNIT_TEST(testLongFirstColumnMouseClick);
CPPUNIT_TEST_SUITE_END();
private:
@@ -3540,6 +3542,92 @@ void ScTiledRenderingTest::testStatusBarLocale()
CPPUNIT_ASSERT_EQUAL(std::string("de-DE"), aLocale);
}
+void ScTiledRenderingTest::testLongFirstColumnMouseClick()
+{
+ // Document has a long first column. We want to mouse-click on the column and
+ // check the selection changed to this column.
+
+ // The issue we want to reproduce is that the click on a cell in the first column that is
+ // very long (longer than ~800px default size of GridWindow) triggers a code-path where the cell
+ // selected is the neighbouring cell even when we clicked on the area of the first cell.
+
+ ScModelObj* pModelObj = createDoc("DocumentWithLongFirstColumn.ods");
+ CPPUNIT_ASSERT(pModelObj);
+ pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+
+ // Fetch current view data
+ ScViewData* pViewData = ScDocShell::GetViewData();
+ CPPUNIT_ASSERT(pViewData);
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTX();
+
+ // Set click position
+
+ // Left side of the first cell
+ int leftCellSideX = 1 / nPPTX; // convert pixels to logical units
+
+ // Right side of the first cell. First cell is long so click somewhere more than 800px (default of GridWindow size).
+ int rightCellSideX = 1000 / nPPTX; // convert pixels to logical units
+
+ // Vettical position - doesn't matter - select the first row
+ int y = 1 / nPPTY;
+
+ // Setup view #1
+ ViewCallback aView1;
+ // Set client rect to 2000 x 2000 pixels
+ pModelObj->setClientVisibleArea(tools::Rectangle(0, 0, 2000 / nPPTX, 2000 / nPPTY));
+ Scheduler::ProcessEventsToIdle();
+
+ // Click at on the left side of A1 cell
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, leftCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, leftCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ Scheduler::ProcessEventsToIdle();
+
+ // Check the A1 cell is selected in view #1
+ CPPUNIT_ASSERT_EQUAL(SCCOL(0), ScDocShell::GetViewData()->GetCurX());
+ CPPUNIT_ASSERT_EQUAL(SCROW(0), ScDocShell::GetViewData()->GetCurY());
+
+ // Click at on the right side of A1 cell
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, rightCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, rightCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ Scheduler::ProcessEventsToIdle();
+
+ // Check the A1 cell is selected in view #1
+ CPPUNIT_ASSERT_EQUAL(SCCOL(0), ScDocShell::GetViewData()->GetCurX());
+ CPPUNIT_ASSERT_EQUAL(SCROW(0), ScDocShell::GetViewData()->GetCurY());
+
+ // Try to check the same scenario in a new view
+
+ // Setup view #2
+ SfxLokHelper::createView();
+ int nView2 = SfxLokHelper::getView();
+ ViewCallback aView2;
+ // Set client rect to 2000 x 2000 pixels
+ pModelObj->setClientVisibleArea(tools::Rectangle(0, 0, 2000 / nPPTX, 2000 / nPPTY));
+
+ // Lets make sure we are in view #2
+ SfxLokHelper::setView(nView2);
+ Scheduler::ProcessEventsToIdle();
+
+ // Click at on the left side of A1 cell
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, leftCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, leftCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ Scheduler::ProcessEventsToIdle();
+
+ // Check the A1 cell is selected in view #2
+ CPPUNIT_ASSERT_EQUAL(SCCOL(0), ScDocShell::GetViewData()->GetCurX());
+ CPPUNIT_ASSERT_EQUAL(SCROW(0), ScDocShell::GetViewData()->GetCurY());
+
+ // Click at on the right side of A1 cell
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, rightCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ pModelObj->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, rightCellSideX, y, /*count=*/ 1, /*buttons=*/ 1, /*modifier=*/0);
+ Scheduler::ProcessEventsToIdle();
+
+ // Check the A1 cell is selected in view #2
+ CPPUNIT_ASSERT_EQUAL(SCCOL(0), ScDocShell::GetViewData()->GetCurX());
+ CPPUNIT_ASSERT_EQUAL(SCROW(0), ScDocShell::GetViewData()->GetCurY());
+}
+
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest);
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index c8a56bc4df14..83db29153bca 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -1155,6 +1155,13 @@ void ScModelObj::setClientVisibleArea(const tools::Rectangle& rRectangle)
if (pTabView)
pTabView->extendTiledAreaIfNeeded();
}
+
+ // Set the GridWindow size to the client area size, so that the logic in GridWindow works correctly
+ // for the current view and doesn't cause any unexpected behaviour related to window size and checks if we are
+ // outside of the window.
+
+ ScGridWindow* pGridWindow = pViewData->GetActiveWin();
+ pGridWindow->SetOutputSizePixel(Size(rRectangle.GetWidth() * pViewData->GetPPTX(), rRectangle.GetHeight() * pViewData->GetPPTY()));
}
void ScModelObj::setOutlineState(bool bColumn, int nLevel, int nIndex, bool bHidden)
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index 8fc254aa8fce..496e5257e77a 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -2849,19 +2849,15 @@ void ScViewData::GetPosFromPixel( tools::Long nClickX, tools::Long nClickY, ScSp
}
}
- bool bLOK = comphelper::LibreOfficeKit::isActive();
// cells too big?
- // Work-around this for LOK, because the screen size is in not set correctly
- // for all views and we will geturn the wrong position in case we send a click
- // that is outside the set screen grid area
- if (rPosX == nStartPosX && nClickX > 0 && !bLOK)
+ if (rPosX == nStartPosX && nClickX > 0)
{
if (pView)
aScrSize.setWidth( pView->GetGridWidth(eHWhich) );
if ( nClickX > aScrSize.Width() )
++rPosX;
}
- if (rPosY == nStartPosY && nClickY > 0 && !bLOK)
+ if (rPosY == nStartPosY && nClickY > 0)
{
if (pView)
aScrSize.setHeight( pView->GetGridHeight(eVWhich) );