sw/qa/uibase/uno/uno.cxx         |   42 +++++++++++++++++++++++++++++++++++++++
 sw/source/uibase/uno/unotxvw.cxx |    5 ++++
 2 files changed, 47 insertions(+)

New commits:
commit 5102157de7d4747304ca6024b44a25fa914049e0
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Dec 13 12:31:11 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Dec 14 07:15:41 2022 +0000

    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 <vmik...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 41071f58415927b257eab66b2674d521607bdee5)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144071

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 {};
+            }
         }
     }
 

Reply via email to