sw/qa/extras/uiwriter/uiwriter6.cxx | 62 ++++++++++++++++++++++++++++++++++++ sw/source/core/frmedt/feshview.cxx | 24 +++++++++++++ 2 files changed, 86 insertions(+)
New commits: commit 014e5f559a9acf319af24c721dbe6b0bc3bc5882 Author: László Németh <nem...@numbertext.org> AuthorDate: Fri May 31 12:38:12 2024 +0200 Commit: László Németh <nem...@numbertext.org> CommitDate: Fri May 31 20:46:16 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 <nem...@numbertext.org> Tested-by: Jenkins diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx b/sw/qa/extras/uiwriter/uiwriter6.cxx index aedec9304791..a27f506095b3 100644 --- a/sw/qa/extras/uiwriter/uiwriter6.cxx +++ b/sw/qa/extras/uiwriter/uiwriter6.cxx @@ -1683,6 +1683,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 c10a87110d8e..9a8d7304b4cc 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 ); }