summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-04-26 15:40:44 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-04-26 17:02:15 +0200
commit651527b4efe9700c8c8dff58ce5aa86ad5681f16 (patch)
treedc963ba89c644d9a4f934ce628407e70bf9aca7c
parent3524e4f7352993517ebdd514435378f6de0ca713 (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.mk1
-rw-r--r--sw/qa/core/text/text.cxx46
-rw-r--r--sw/source/core/text/itrcrsr.cxx4
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() )