sw/CppunitTest_sw_core_text.mk | 1 sw/qa/core/text/text.cxx | 50 ++++++++++++++++++++++++++++++++++++++++ sw/source/core/text/itrcrsr.cxx | 4 ++- 3 files changed, 54 insertions(+), 1 deletion(-)
New commits: commit da9e2b202fb13c6633a813ceb5cc0968799b785d Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Apr 26 15:40:44 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Apr 27 09:17:00 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. (cherry picked from commit 651527b4efe9700c8c8dff58ce5aa86ad5681f16) Conflicts: sw/qa/core/text/text.cxx Change-Id: If08e7dd2a72f46ebcfb8c6ddf110703eaeb7df6d diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk index cb901fde29f2..f0947a36c65b 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 \ test \ unotest \ diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index 23f3294b5303..8be07818e7bd 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -15,6 +15,10 @@ static char const DATA_DIRECTORY[] = "/sw/qa/core/text/data/"; +#include <sortedobjs.hxx> +#include <anchoredobject.hxx> +#include <fmtcntnt.hxx> + /// Covers sw/source/core/text/ fixes. class SwCoreTextTest : public SwModelTestBase { @@ -113,6 +117,52 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testLineWidth) CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(65536), nNewLeft - nOldLeft); } +CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testAsCharImageDocModelFromViewPoint) +{ + // Given a document with an as-char image: + loadURL("private:factory/swriter", nullptr); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + 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 550dc19054cc..4804eda9dfe0 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -1731,8 +1731,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() )