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 );
 

Reply via email to