diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-12-13 12:31:11 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-12-13 12:19:27 +0000 |
commit | 41071f58415927b257eab66b2674d521607bdee5 (patch) | |
tree | e75eb4907c34f7184edfb986bfdb43cba298c7ae | |
parent | 96198cbf9cca1090d5bb3dc2a5f85885d4262b4a (diff) |
sw, createTextRangeByPixelPosition(): fix crash with at-page anchored images
When createTextRangeByPixelPosition() was called with a position that is
inside an at-page anchored image, we crashed.
The problem is that in general we can't create an XTextRange for a
graphic node. We already tried to return the anchor position for graphic
nodes since 2302ebefb2e25878e8fe1e64d208f265f87d5b9b (sw,
createTextRangeByPixelPosition(): fix crash when the position is an
image, 2022-11-22), but that fixed the problem only in case
GetContentAnchor() gave us a doc model position.
Fix the problem by returning an empty reference in the "graphic node but
no content anchor" case, that is still better for at-page and at-frame
anchored images than a crash.
A follow-up change could be to add a new API that has a more generic
return type (similar to how getSelection() returns `any`) and then
return the image itself, not its anchor in the image case. That approach
would work for at-page and at-frame anchored images as well.
Change-Id: If850ec945c24052568230a83da2ae2aa004b4265
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144043
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/uibase/uno/uno.cxx | 42 | ||||
-rw-r--r-- | sw/source/uibase/uno/unotxvw.cxx | 5 |
2 files changed, 47 insertions, 0 deletions
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx index e0806672e6af..45fc50999e65 100644 --- a/sw/qa/uibase/uno/uno.cxx +++ b/sw/qa/uibase/uno/uno.cxx @@ -158,6 +158,48 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testCreateTextRangeByPixelPositionGraphic) CPPUNIT_ASSERT_EQUAL(aAnchorPos, *aPaM.GetPoint()); } +CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testCreateTextRangeByPixelPositionAtPageGraphic) +{ + // Given a document with an at-page anchored image: + 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); + xTextGraphic->setPropertyValue("AnchorType", uno::Any(text::TextContentAnchorType_AT_PAGE)); + xTextGraphic->setPropertyValue("AnchorPageNo", uno::Any(static_cast<sal_Int16>(1))); + xTextGraphic->setPropertyValue("Width", uno::Any(static_cast<sal_Int32>(10000))); + xTextGraphic->setPropertyValue("Height", uno::Any(static_cast<sal_Int32>(10000))); + 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); + SwDoc* pDoc = getSwDoc(); + SwDocShell* pDocShell = pDoc->GetDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + SwRootFrame* pLayout = pWrtShell->GetLayout(); + SwFrame* pPage = pLayout->GetLower(); + SwSortedObjs& rDrawObjs = *pPage->GetDrawObjs(); + SwAnchoredObject* pAnchored = rDrawObjs[0]; + Point aLogic = pAnchored->GetObjRect().Center(); + SwView* pView = pDocShell->GetView(); + SwEditWin& rEditWin = pView->GetEditWin(); + Point aPixel = rEditWin.LogicToPixel(aLogic); + + // When asking for the doc model pos of the image's anchor by pixel position: + uno::Reference<frame::XModel2> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xControllers = xModel->getControllers(); + uno::Reference<text::XTextViewTextRangeSupplier> xController(xControllers->nextElement(), + uno::UNO_QUERY); + awt::Point aPoint(aPixel.getX(), aPixel.getY()); + // Without the accompanying fix in place, this test would have crashed. + uno::Reference<text::XTextRange> xTextRange + = xController->createTextRangeByPixelPosition(aPoint); + + // Then make sure that the result is empty, since the image is at-page anchored: + CPPUNIT_ASSERT(!xTextRange.is()); +} + CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetTextFormFields) { // Given a document with 3 fieldmarks: 2 zotero items and a zotero diff --git a/sw/source/uibase/uno/unotxvw.cxx b/sw/source/uibase/uno/unotxvw.cxx index 416defb125ef..16804f83f753 100644 --- a/sw/source/uibase/uno/unotxvw.cxx +++ b/sw/source/uibase/uno/unotxvw.cxx @@ -550,6 +550,11 @@ SwXTextView::createTextRangeByPixelPosition(const awt::Point& rPixelPosition) { aPosition = *pAnchor; } + else + { + // Page-anchored graphics have no anchor. + return {}; + } } } |