sw/qa/extras/uiwriter/uiwriter6.cxx |   62 ++++++++++++++++++++++++++++++++++++
 sw/source/core/frmedt/feshview.cxx  |   24 +++++++++++++
 2 files changed, 86 insertions(+)

New commits:
commit 96a4b71bc39ab4f16dd9cc609d4d218dd36dd8d6
Author:     László Németh <[email protected]>
AuthorDate: Fri May 31 12:38:12 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jun 4 11:58:46 2024 +0200

    tdf#161360 sw: fix cursor position deselecting image in table
    
    In tables, when the selected image was anchored as character
    at beginning of the table row, pressing Escape resulted completely
    lost text cursor (after a short blinking, not visible, missing
    typing etc.) or – in the case of floating tables – cursor in
    a bad position (after the table instead of before the image).
    
    Change-Id: Ib49211ec3531110fc8f5f65fb700318884519666
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168289
    Reviewed-by: László Németh <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 014e5f559a9acf319af24c721dbe6b0bc3bc5882)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168312
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index 7ef7a1df186e..4b994cc9322c 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -1687,6 +1687,68 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161332)
     CPPUNIT_ASSERT_EQUAL(SelectionType::Frame, eType2);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161360)
+{
+    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 image by clicking on it at the center of the upper cell
+    Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, 
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 image is selected:
+    SelectionType eType = pWrtShell->GetSelectionType();
+    CPPUNIT_ASSERT_EQUAL(SelectionType::Graphic, eType);
+
+    // select the text frame instead of the image
+    // by pressing Escape
+    dispatchCommand(mxComponent, ".uno:Escape", {});
+
+    // Then make sure that the cursor in the table:
+    SelectionType eType2 = pWrtShell->GetSelectionType();
+    // This was false (only SelectionType::Text)
+    bool bCursorInTable = eType2 == (SelectionType::Text | 
SelectionType::Table);
+    CPPUNIT_ASSERT(bCursorInTable);
+
+    // select the text frame by pressing Escape again
+    dispatchCommand(mxComponent, ".uno:Escape", {});
+
+    eType2 = pWrtShell->GetSelectionType();
+    CPPUNIT_ASSERT_EQUAL(SelectionType::Frame, eType2);
+
+    // deselect the text frame by pressing Escape again
+    dispatchCommand(mxComponent, ".uno:Escape", {});
+
+    eType2 = pWrtShell->GetSelectionType();
+    // The text cursor is after the floating table
+    CPPUNIT_ASSERT_EQUAL(SelectionType::Text, eType2);
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf115132)
 {
     createSwDoc();
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index 45229e3b9ff9..e24574371ad6 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -191,6 +191,7 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 
nFlag, SdrObject *pObj )
                     ( 
pOldSelFly->GetFormat()->GetProtect().IsContentProtected()
                      && !IsReadOnlyAvailable() ))
                 {
+                    SdrObject *pOldObj = 
rMrkList.GetMark(0)->GetMarkedSdrObj();
                     // If a fly is deselected, which contains graphic, OLE or
                     // otherwise, the cursor should be removed from it.
                     // Similar if a fly with protected content is deselected.
@@ -201,6 +202,29 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 
nFlag, SdrObject *pObj )
                     bool bUnLockView = !IsViewLocked();
                     LockView( true );
                     SetCursor( aPt, true );
+
+                    // in tables, fix lost position, when the selected image 
was
+                    // anchored as character at beginning of the table row:
+                    // in this case, the text cursor was positionated after the
+                    // floating table, and not before the image, as in other 
positions
+                    // in the table row (and if the table wasn't a floating 
one,
+                    // the text cursor lost completely)
+                    if ( SW_LEAVE_FRAME & nFlag )
+                    {
+                        const SwContact* pContact = GetUserCall(pOldObj);
+                        if ( pContact && pContact->ObjAnchoredAsChar() )
+                        {
+                            const SwNode * pOldNd = 
pContact->GetAnchorNode().FindTableNode();
+                            // the original image was in a table, but the 
cursor is not in that
+                            if ( pOldNd && pOldNd != 
GetCursor()->GetPointNode().FindTableNode() )
+                            {
+                                if ( SwWrtShell* pWrtShell = 
dynamic_cast<SwWrtShell*>(this) )
+                                    // put the text cursor in the same row
+                                    pWrtShell->SelectTableRowCol( aPt );
+                            }
+                        }
+                    }
+
                     if( bUnLockView )
                         LockView( false );
                 }

Reply via email to