sw/CppunitTest_sw_core_text.mk | 1 sw/qa/core/text/text.cxx | 46 ++++++++++++++++++++++++++++++++++++++++ sw/source/core/text/itrcrsr.cxx | 4 ++- 3 files changed, 50 insertions(+), 1 deletion(-)
New commits: commit a24dd76ca6c1d0f2876e1eca698c73fcccc815fe Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Apr 26 15:40:44 2022 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Wed Apr 27 09:05:53 2022 +0200 sw: fix double-click opening frame dialog, not graphic dialog on images The user-visible problem was that once a user clicks on an image a lot (e.g. 5 times), then the slot ID dispatched on double-click in SwEditWin::MouseButtonDown() is no longer FN_FORMAT_GRAFIC_DLG, but it's FN_FORMAT_FRAME_DLG. This is already inconsistent, but it's especially problematic in case an UNO client intercepts only the first UNO command, but not the second one. The other inconsistency is that in practice this only happens for as-char images, at-char anchored images work fine. The reason for this seems to be how we get the doc model position for a twips view point. At-char anchored images are handled at lcl_GetModelPositionForViewPoint_Objects(), and there we return the SwGrfNode in case the view point is inside the frame of the matching fly frame. SwTextCursor::GetModelPositionForViewPoint() restricted the same to as-char fly frames which have text or layout frame children. Fix the problem by allowing non-text frame children for as-char images. Change-Id: If08e7dd2a72f46ebcfb8c6ddf110703eaeb7df6d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133443 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133462 diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk index 6f19ff690f5a..19d8cd422edc 100644 --- a/sw/CppunitTest_sw_core_text.mk +++ b/sw/CppunitTest_sw_core_text.mk @@ -23,6 +23,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \ cppuhelper \ sal \ sfx \ + svl \ sw \ swqahelper \ test \ diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index 4358fe03df75..845eb2fd5b15 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -27,6 +27,9 @@ #include <porlay.hxx> #include <pormulti.hxx> +#include <sortedobjs.hxx> +#include <anchoredobject.hxx> +#include <fmtcntnt.hxx> constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/core/text/data/"; @@ -232,6 +235,49 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testEmptyNumberingPageSplit) dispatchCommand(mxComponent, ".uno:InsertGraphic", aArgs); } +CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testAsCharImageDocModelFromViewPoint) +{ + // Given a document with an as-char image: + SwDoc* pDoc = createSwDoc(); + uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xTextGraphic( + xFactory->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY); + // Only set the anchor type, the actual bitmap content is not interesting. + xTextGraphic->setPropertyValue("AnchorType", + uno::makeAny(text::TextContentAnchorType_AS_CHARACTER)); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> xBodyText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor(xBodyText->createTextCursor()); + uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY); + xBodyText->insertTextContent(xCursor, xTextContent, false); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + SwRootFrame* pRootFrame = pWrtShell->GetLayout(); + SwFrame* pPageFrame = pRootFrame->GetLower(); + SwFrame* pBodyFrame = pPageFrame->GetLower(); + SwFrame* pTextFrame = pBodyFrame->GetLower(); + const SwSortedObjs& rSortedObjs = *pTextFrame->GetDrawObjs(); + const SwAnchoredObject* pAnchoredObject = rSortedObjs[0]; + // The content points to the start node, the next node is the graphic node. + SwNodeIndex aGraphicNode = *pAnchoredObject->GetFrameFormat().GetContent().GetContentIdx(); + ++aGraphicNode; + tools::Rectangle aFlyFrame = pAnchoredObject->GetDrawObj()->GetLastBoundRect(); + Point aDocPos = aFlyFrame.Center(); + + // When translating the view point to the model position: + pWrtShell->SttCursorMove(); + pWrtShell->CallSetCursor(&aDocPos, /*bOnlyText=*/false); + pWrtShell->EndCursorMove(); + + // Then make sure that we find the graphic node, and not its anchor: + SwShellCursor* pShellCursor = pWrtShell->getShellCursor(/*bBlock=*/false); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: SwNodeIndex (node 6) + // - Actual : SwNodeIndex (node 12) + // i.e. the cursor position was the text node hosting the as-char image, not the graphic node of + // the image. + CPPUNIT_ASSERT_EQUAL(aGraphicNode, pShellCursor->GetMark()->nNode); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index d9d87aaa713c..f6c8ed380107 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -1761,8 +1761,10 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con // (BugId: 9692 + Change in feshview) SwFlyInContentFrame *pTmp = pFlyPor->GetFlyFrame(); SwFrame* pLower = pTmp->GetLower(); + // Allow non-text-frames to get SwGrfNode for as-char anchored images into pPos + // instead of the closest SwTextNode, to be consistent with at-char behavior. bool bChgNodeInner = pLower - && (pLower->IsTextFrame() || pLower->IsLayoutFrame()); + && (pLower->IsTextFrame() || pLower->IsLayoutFrame() || pLower->IsNoTextFrame()); Point aTmpPoint( rPoint ); if ( m_pFrame->IsRightToLeft() )