diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-04-26 15:40:44 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-04-26 17:02:15 +0200 |
commit | 651527b4efe9700c8c8dff58ce5aa86ad5681f16 (patch) | |
tree | dc963ba89c644d9a4f934ce628407e70bf9aca7c | |
parent | 3524e4f7352993517ebdd514435378f6de0ca713 (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/CppunitTest_sw_core_text.mk | 1 | ||||
-rw-r--r-- | sw/qa/core/text/text.cxx | 46 | ||||
-rw-r--r-- | sw/source/core/text/itrcrsr.cxx | 4 |
3 files changed, 50 insertions, 1 deletions
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 8ad0d230bebc..f847df9c5e56 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -28,6 +28,9 @@ #include <porlay.hxx> #include <pormulti.hxx> #include <formatlinebreak.hxx> +#include <sortedobjs.hxx> +#include <anchoredobject.hxx> +#include <fmtcntnt.hxx> constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/core/text/data/"; @@ -382,6 +385,49 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testClearingLineBreakHeader) assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout[1]", "height", "276"); } +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 a6384b166af2..546d91b17403 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -1766,8 +1766,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() ) |