sw/inc/fesh.hxx | 2 - sw/qa/extras/uiwriter/uiwriter6.cxx | 65 ++++++++++++++++++++++++++++++++++-- sw/source/core/frmedt/feshview.cxx | 30 ++++++++++++++-- sw/source/uibase/docvw/edtwin.cxx | 11 +++++- 4 files changed, 101 insertions(+), 7 deletions(-)
New commits: commit 2f7bb481c57458a38769ebd961f07cc45767f1f7 Author: László Németh <nem...@numbertext.org> AuthorDate: Thu May 30 01:22:59 2024 +0200 Commit: László Németh <nem...@numbertext.org> CommitDate: Fri May 31 09:47:59 2024 +0200 tdf#161332 sw: fix missing selection of floating table A fixed-height cell can contain a bigger image, which is cropped by cell boundaries. In this case, it was not possible to select the floating table by clicking on its right border. Note: fix also tests of tdf#44773 and tdf#160836 related to DPI-dependent platforms, see tdf#160992. Follow-up to commit 30de13743f144aced83bc43d310592f82788c910 "tdf#160836 sw: resize rows at images cropped by row height" and commit f3b899655018397e71300dbb32cdf4f82940a68b "tdf#160842 sw: select cell content instead of cropped part of image". Change-Id: I22c3e34f4c8147736c29b62722f7fc43c862ba48 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168237 Reviewed-by: László Németh <nem...@numbertext.org> Tested-by: Jenkins diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index 1c2d917ffd7c..b032a0b05b7b 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -297,7 +297,7 @@ public: /** Test if there is a draw object at that position and if it should be selected. The 'should' is aimed at Writer text fly frames which may be in front of the draw object. */ - bool ShouldObjectBeSelected(const Point& rPt); + bool ShouldObjectBeSelected(const Point& rPt, bool *pSelectFrameInsteadOfCroppedImage = nullptr); bool MoveAnchor( SwMove nDir ); diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx b/sw/qa/extras/uiwriter/uiwriter6.cxx index 6322120748da..aedec9304791 100644 --- a/sw/qa/extras/uiwriter/uiwriter6.cxx +++ b/sw/qa/extras/uiwriter/uiwriter6.cxx @@ -1470,7 +1470,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf44773) rEditWin.ReleaseMouse(); // this was 396 (not modified row height previously) - CPPUNIT_ASSERT_EQUAL(tools::Long(810), pCellA1->getFrameArea().Height()); + CPPUNIT_ASSERT_GREATER(tools::Long(750), pCellA1->getFrameArea().Height()); } CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160842) @@ -1557,7 +1557,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160836) rEditWin.ReleaseMouse(); // this was 3910 (not modified row height previously) - CPPUNIT_ASSERT_EQUAL(tools::Long(1980), pCellA1->getFrameArea().Height()); + CPPUNIT_ASSERT_LESS(tools::Long(2000), pCellA1->getFrameArea().Height()); } CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161261) @@ -1622,6 +1622,67 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161261) CPPUNIT_ASSERT_GREATER(sal_Int32(8000), xShape->getSize().Height); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161332) +{ + createSwDoc("tdf160842.fodt"); + SwDoc* pDoc = getSwDoc(); + CPPUNIT_ASSERT(pDoc); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + // the cursor is not in the table + CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable()); + + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage); + const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs.size()); + auto pPageFly = dynamic_cast<SwFlyAtContentFrame*>(rPageObjs[0]); + CPPUNIT_ASSERT(pPageFly); + auto pTable = dynamic_cast<SwTabFrame*>(pPageFly->GetLower()); + CPPUNIT_ASSERT(pTable); + auto pRow1 = pTable->GetLower(); + CPPUNIT_ASSERT(pRow1->IsRowFrame()); + auto pCellA1 = pRow1->GetLower(); + CPPUNIT_ASSERT(pCellA1); + const SwRect& rCellA1Rect = pCellA1->getFrameArea(); + auto nRowHeight = rCellA1Rect.Height(); + + // select text frame by clicking on it at the right side of the upper cell + Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width(), rCellA1Rect.Top() + nRowHeight / 2); + vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin(); + Point aFrom = rEditWin.LogicToPixel(ptFrom); + MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT); + rEditWin.MouseButtonDown(aClickEvent); + rEditWin.MouseButtonUp(aClickEvent); + + // Then make sure that the text frame is selected: + SelectionType eType = pWrtShell->GetSelectionType(); + // This was false (SelectionType::Graphic) + CPPUNIT_ASSERT_EQUAL(SelectionType::Frame, eType); + + // remove selection + dispatchCommand(mxComponent, ".uno:Escape", {}); + + // select text frame by clicking on it at the right side of the bottom cell + auto pRow2 = pRow1->GetNext(); + CPPUNIT_ASSERT(pRow2->IsRowFrame()); + auto pCellA2 = pRow2->GetLower(); + CPPUNIT_ASSERT(pCellA2); + const SwRect& rCellA2Rect = pCellA2->getFrameArea(); + auto nRow2Height = rCellA2Rect.Height(); + Point ptFrom2(rCellA2Rect.Left() + rCellA2Rect.Width(), rCellA2Rect.Top() + nRow2Height / 2); + Point aFrom2 = rEditWin.LogicToPixel(ptFrom2); + MouseEvent aClickEvent2(aFrom2, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT); + rEditWin.MouseButtonDown(aClickEvent2); + rEditWin.MouseButtonUp(aClickEvent2); + + // Then make sure that the text frame is selected: + SelectionType eType2 = pWrtShell->GetSelectionType(); + // This was false (SelectionType::Graphic) + CPPUNIT_ASSERT_EQUAL(SelectionType::Frame, eType2); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf115132) { createSwDoc(); diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index 5644769b1aaf..c10a87110d8e 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -1300,7 +1300,7 @@ SdrObject* SwFEShell::GetObjAt( const Point& rPt ) } // Test if there is an object at that position and if it should be selected. -bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) +bool SwFEShell::ShouldObjectBeSelected(const Point& rPt, bool *pSelectFrameInsteadOfCroppedImage) { CurrShell aCurr(this); SwDrawView *pDrawView = Imp()->GetDrawView(); @@ -1310,9 +1310,10 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) { SdrPageView* pPV; const auto nOld(pDrawView->GetHitTolerancePixel()); + sal_uInt16 nHitTol = pDrawView->getHitTolLog(); pDrawView->SetHitTolerancePixel(pDrawView->GetMarkHdlSizePixel()/2); - SdrObject* pObj = pDrawView->PickObj(rPt, pDrawView->getHitTolLog(), pPV, SdrSearchOptions::PICKMARKABLE); + SdrObject* pObj = pDrawView->PickObj(rPt, nHitTol, pPV, SdrSearchOptions::PICKMARKABLE); pDrawView->SetHitTolerancePixel(nOld); if (pObj) @@ -1416,11 +1417,34 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) bool bContainsClickPosition = false; for (SwRowFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next()) { - if ( pFrame->getFrameArea().Contains( rPt ) ) + const SwRect& rRect = pFrame->getFrameArea(); + // click inside the cell which contains the cropped image + if ( rRect.Contains( rPt ) ) { + // click next to the right cell border + if ( pSelectFrameInsteadOfCroppedImage && + !rRect.Contains( Point(rPt.X() + 2 * nHitTol, rPt.Y()) ) ) + { + *pSelectFrameInsteadOfCroppedImage = true; + } bContainsClickPosition = true; break; } + else if ( pSelectFrameInsteadOfCroppedImage && ( + // Click outside of the right border + rRect.Contains( Point(rPt.X() - 2 * nHitTol, rPt.Y()) ) || + // or handle the right border of bottom cells covered by the cropped + // image instead putting the cursor inside the cell (see tdf#160842). + // Click inside the same table, or outside its right border + ( pFrame->GetUpper() && pFrame->GetUpper()->getFrameArea().Contains( + Point(rPt.X() - 2 * nHitTol, rPt.Y()) ) && + // and the click inside is next to the right table border + !rRect.Contains( Point(rPt.X() + 2 * nHitTol, rRect.Bottom()) ) + ) ) ) + { + *pSelectFrameInsteadOfCroppedImage = true; + bContainsClickPosition = true; + } } if ( !bContainsClickPosition ) bRet = false; diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index b0d7adcf36c3..3752d4a418f4 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -3361,7 +3361,8 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) !GetView().GetViewFrame().GetDispatcher()->IsLocked()) { // Test if there is a draw object at that position and if it should be selected. - bool bShould = rSh.ShouldObjectBeSelected(aDocPos); + bool bSelectFrameInsteadOfCroppedImage = false; + bool bShould = rSh.ShouldObjectBeSelected(aDocPos, &bSelectFrameInsteadOfCroppedImage); if(bShould) { @@ -3372,6 +3373,14 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) rSh.LockView( true ); bool bSelObj = rSh.SelectObj(aDocPos, aMEvt.IsMod1() ? SW_ENTER_GROUP : 0); + if ( bSelObj && bSelectFrameInsteadOfCroppedImage ) + { + bool bWrapped(false); + const SdrObject* pFly = rSh.GetBestObject(false, GotoObjFlags::FlyAny, true, nullptr, &bWrapped); + pSdrView->UnmarkAllObj(); + bSelObj = + rSh.SelectObj(aDocPos, aMEvt.IsMod1() ? SW_ENTER_GROUP : 0, const_cast<SdrObject*>(pFly)); + } if( bUnLockView ) rSh.LockView( false );