sw/inc/unoframe.hxx                          |    5 +
 sw/inc/unoredline.hxx                        |    4 
 sw/inc/unotbl.hxx                            |    5 +
 sw/inc/unotext.hxx                           |   10 ++
 sw/inc/unotextbodyhf.hxx                     |   10 ++
 sw/inc/unotextcursor.hxx                     |    9 ++
 sw/inc/unotextrange.hxx                      |    3 
 sw/source/core/inc/unofootnote.hxx           |    5 +
 sw/source/core/unocore/unocontentcontrol.cxx |   10 ++
 sw/source/core/unocore/unoframe.cxx          |   29 +++++--
 sw/source/core/unocore/unoftn.cxx            |   23 ++++-
 sw/source/core/unocore/unoobj.cxx            |   29 +++++--
 sw/source/core/unocore/unoobj2.cxx           |   24 +++++
 sw/source/core/unocore/unoredline.cxx        |   15 +++
 sw/source/core/unocore/unorefmk.cxx          |   11 ++
 sw/source/core/unocore/unotbl.cxx            |   23 ++++-
 sw/source/core/unocore/unotext.cxx           |  111 ++++++++++++++++++---------
 17 files changed, 267 insertions(+), 59 deletions(-)

New commits:
commit 54a9b4a20e5da303ed01e570a424f38b49ba911f
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Sat Aug 10 17:27:08 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sun Aug 11 14:35:08 2024 +0200

    reduce dynamic_cast and SolarMutex overhead in sw UNO layer
    
    since we can pass the concrete type and avoid a bunch of unnecessary
    work
    
    Change-Id: Ic95e4b4306210a7c11ce70ad981c3dc5b979b402
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171719
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sw/inc/unoframe.hxx b/sw/inc/unoframe.hxx
index 3760bb311200..cac695f2125a 100644
--- a/sw/inc/unoframe.hxx
+++ b/sw/inc/unoframe.hxx
@@ -44,6 +44,7 @@
 class SdrObject;
 class SwDoc;
 class SwFormat;
+class SwUnoInternalPaM;
 class SfxItemPropertySet;
 namespace com::sun::star::frame { class XModel; }
 
@@ -204,6 +205,8 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
 
     //XEnumerationAccess - was: XParagraphEnumerationAccess
     virtual css::uno::Reference< css::container::XEnumeration >  SAL_CALL 
createEnumeration() override;
@@ -232,6 +235,8 @@ public:
     //XPropertySet
     virtual SW_DLLPUBLIC css::uno::Any SAL_CALL getPropertyValue( const 
OUString& PropertyName ) override;
     using SwXFrame::setPropertyValue;
+private:
+    rtl::Reference< SwXTextCursor > 
createXTextCursorByRangeImpl(SwUnoInternalPaM& rPam);
 };
 
 typedef cppu::ImplInheritanceHelper
diff --git a/sw/inc/unoredline.hxx b/sw/inc/unoredline.hxx
index 90f9d212a168..5f069fde1121 100644
--- a/sw/inc/unoredline.hxx
+++ b/sw/inc/unoredline.hxx
@@ -53,6 +53,8 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
 
     //XEnumerationAccess
     virtual css::uno::Reference< css::container::XEnumeration >  SAL_CALL 
createEnumeration() override;
@@ -87,6 +89,8 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
 
     //XPropertySet
     virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL 
getPropertySetInfo(  ) override;
diff --git a/sw/inc/unotbl.hxx b/sw/inc/unotbl.hxx
index 323a4f7b8e79..b56b2d79d4e9 100644
--- a/sw/inc/unotbl.hxx
+++ b/sw/inc/unotbl.hxx
@@ -46,6 +46,7 @@ class SwTable;
 class SwTableBox;
 class SwTableLine;
 class SwTableCursor;
+class SwUnoInternalPaM;
 class SfxItemPropertySet;
 
 typedef
@@ -110,6 +111,8 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
     virtual void SAL_CALL  setString(const OUString& aString) override;
 
     //XPropertySet
@@ -139,6 +142,8 @@ public:
     SwFrameFormat* GetFrameFormat() const { return m_pTableFormat; }
     double GetForcedNumericalValue() const;
     css::uno::Any GetAny() const;
+private:
+    rtl::Reference< SwXTextCursor > 
createXTextCursorByRangeImpl(SwUnoInternalPaM& rPam);
 };
 
 class SwXTextTableRow final
diff --git a/sw/inc/unotext.hxx b/sw/inc/unotext.hxx
index 237a1e4b31f5..96173ea32ba7 100644
--- a/sw/inc/unotext.hxx
+++ b/sw/inc/unotext.hxx
@@ -45,6 +45,7 @@ class SwNodeRange;
 class SwPaM;
 class SwXTextCursor;
 class SwXParagraph;
+class SwXTextRange;
 
 class SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") SwXText
     : public css::lang::XTypeProvider
@@ -148,6 +149,8 @@ public:
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override final;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) = 0;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) = 0;
     virtual css::uno::Reference< css::text::XTextCursor >  SAL_CALL 
createTextCursor() override final;
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() = 0;
 
@@ -246,6 +249,13 @@ public:
             const css::uno::Reference< css::text::XTextContent>& xPredecessor) 
override;
 
 private:
+    rtl::Reference< SwXTextCursor > getEndImpl(SolarMutexGuard& rGuard);
+    rtl::Reference< SwXTextRange > insertTextPortionImpl(
+            SolarMutexGuard& rGuard,
+            std::u16string_view rText,
+            const css::uno::Sequence< css::beans::PropertyValue >& 
rCharacterAndParagraphProperties,
+            const rtl::Reference<SwXTextCursor>& xTextCursor);
+
     SfxItemPropertySet const&   m_rPropSet;
     const CursorType            m_eType;
     SwDoc *                     m_pDoc;
diff --git a/sw/inc/unotextbodyhf.hxx b/sw/inc/unotextbodyhf.hxx
index cdaeb8e102af..a94ea4ada0fd 100644
--- a/sw/inc/unotextbodyhf.hxx
+++ b/sw/inc/unotextbodyhf.hxx
@@ -31,6 +31,7 @@ class SwDoc;
 class SwFrameFormat;
 class SwXTextCursor;
 struct SwXParagraphEnumeration;
+class SwUnoInternalPaM;
 
 typedef ::cppu::WeakImplHelper
 <   css::lang::XServiceInfo
@@ -82,7 +83,11 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
 
+private:
+    rtl::Reference< SwXTextCursor > 
createXTextCursorByRangeImpl(SwUnoInternalPaM& rPam);
 };
 
 typedef ::cppu::WeakImplHelper
@@ -141,7 +146,10 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
-
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
+private:
+    rtl::Reference< SwXTextCursor > 
createXTextCursorByRangeImpl(SwUnoInternalPaM& rPam);
 };
 
 #endif // INCLUDED_SW_INC_UNOTEXTBODYHF_HXX
diff --git a/sw/inc/unotextcursor.hxx b/sw/inc/unotextcursor.hxx
index 779c6a4982ae..ab245e5d18c9 100644
--- a/sw/inc/unotextcursor.hxx
+++ b/sw/inc/unotextcursor.hxx
@@ -46,6 +46,7 @@
 class SwDoc;
 struct SwPosition;
 class SwUnoCursor;
+class SwXTextRange;
 class SfxItemPropertySet;
 
 typedef ::cppu::WeakImplHelper
@@ -224,6 +225,9 @@ public:
     virtual void SAL_CALL gotoRange(
             const css::uno::Reference< css::text::XTextRange >& xRange,
             sal_Bool bExpand) override;
+    void gotoRange(
+            const rtl::Reference< SwXTextCursor >& xRange,
+            bool bExpand);
 
     // XWordCursor
     virtual sal_Bool SAL_CALL isStartOfWord() override;
@@ -257,6 +261,11 @@ public:
     //XMarkingAccess
     virtual void SAL_CALL invalidateMarkings(::sal_Int32 nType) override;
 
+private:
+    void gotoRangeImpl(
+            SwXTextRange* pRange,
+            OTextCursorHelper* pCursor,
+            bool bExpand);
 };
 
 #endif // INCLUDED_SW_INC_UNOTEXTCURSOR_HXX
diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx
index 7e43d72c2f30..57156523c396 100644
--- a/sw/inc/unotextrange.hxx
+++ b/sw/inc/unotextrange.hxx
@@ -40,6 +40,7 @@ class SwDoc;
 class SwUnoCursor;
 class SwFrameFormat;
 class SwXText;
+class SwXTextCursor;
 class SfxItemPropertySet;
 
 class SW_DLLPUBLIC SwUnoInternalPaM final
@@ -69,6 +70,8 @@ namespace sw {
     SW_DLLPUBLIC bool XTextRangeToSwPaM(SwUnoInternalPaM& rToFill,
             const css::uno::Reference<css::text::XTextRange> & xTextRange,
             TextRangeMode eMode = TextRangeMode::RequireTextNode);
+    bool XTextRangeToSwPaM(SwUnoInternalPaM& rToFill,
+            const rtl::Reference< SwXTextCursor > & xTextRange);
 
     css::uno::Reference< SwXText >
         CreateParentXText(SwDoc & rDoc, const SwPosition& rPos);
diff --git a/sw/source/core/inc/unofootnote.hxx 
b/sw/source/core/inc/unofootnote.hxx
index c1fb2b5b1eb6..5306df0363b0 100644
--- a/sw/source/core/inc/unofootnote.hxx
+++ b/sw/source/core/inc/unofootnote.hxx
@@ -31,6 +31,7 @@
 
 class SwDoc;
 class SwFormatFootnote;
+class SwUnoInternalPaM;
 
 typedef ::cppu::WeakImplHelper
 <   css::lang::XServiceInfo
@@ -129,6 +130,10 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
+private:
+    rtl::Reference< SwXTextCursor > 
createXTextCursorByRangeImpl(SwUnoInternalPaM& rPam);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx 
b/sw/source/core/unocore/unocontentcontrol.cxx
index e9c7563a59fa..fcc6dc1f05ae 100644
--- a/sw/source/core/unocore/unocontentcontrol.cxx
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -71,6 +71,8 @@ public:
     virtual rtl::Reference<SwXTextCursor> createXTextCursor() override;
     virtual rtl::Reference<SwXTextCursor> createXTextCursorByRange(
         const ::css::uno::Reference<::css::text::XTextRange>& aTextPosition) 
override;
+    virtual rtl::Reference<SwXTextCursor>
+    createXTextCursorByRange(const rtl::Reference<SwXTextCursor>& 
aTextPosition) override;
 };
 }
 
@@ -130,6 +132,14 @@ rtl::Reference<SwXTextCursor> 
SwXContentControlText::createXTextCursorByRange(
     return xCursor;
 }
 
+rtl::Reference<SwXTextCursor>
+SwXContentControlText::createXTextCursorByRange(const 
rtl::Reference<SwXTextCursor>& xTextPosition)
+{
+    const rtl::Reference<SwXTextCursor> xCursor(createXTextCursor());
+    xCursor->gotoRange(xTextPosition, false);
+    return xCursor;
+}
+
 /**
  * The inner part SwXContentControl, which is deleted with a locked SolarMutex.
  *
diff --git a/sw/source/core/unocore/unoframe.cxx 
b/sw/source/core/unocore/unoframe.cxx
index f91e627e3320..b77828a998c2 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -3310,22 +3310,35 @@ rtl::Reference<SwXTextCursor>  
SwXTextFrame::createXTextCursor()
 
 rtl::Reference< SwXTextCursor > SwXTextFrame::createXTextCursorByRange(const 
uno::Reference< text::XTextRange > & aTextPosition)
 {
-    SwFrameFormat* pFormat = GetFrameFormat();
-    if (!pFormat)
+    SwUnoInternalPaM aPam(*GetDoc());
+    if (!::sw::XTextRangeToSwPaM(aPam, aTextPosition))
         throw uno::RuntimeException();
+    return createXTextCursorByRangeImpl(aPam);
+}
+
+rtl::Reference< SwXTextCursor > SwXTextFrame::createXTextCursorByRange(
+    const rtl::Reference< SwXTextCursor > & aTextPosition)
+{
     SwUnoInternalPaM aPam(*GetDoc());
     if (!::sw::XTextRangeToSwPaM(aPam, aTextPosition))
         throw uno::RuntimeException();
+    return createXTextCursorByRangeImpl(aPam);
+}
 
-    rtl::Reference< SwXTextCursor > aRef;
+rtl::Reference< SwXTextCursor > SwXTextFrame::createXTextCursorByRangeImpl(
+        SwUnoInternalPaM& rPam)
+{
+    SwFrameFormat* pFormat = GetFrameFormat();
+    if (!pFormat)
+        throw uno::RuntimeException();
+    rtl::Reference< SwXTextCursor > xRef;
     SwNode& rNode = pFormat->GetContent().GetContentIdx()->GetNode();
-    if(aPam.GetPointNode().FindFlyStartNode() == rNode.FindFlyStartNode())
+    if(rPam.GetPointNode().FindFlyStartNode() == rNode.FindFlyStartNode())
     {
-        aRef = new SwXTextCursor(*pFormat->GetDoc(), this, CursorType::Frame,
-                    *aPam.GetPoint(), aPam.GetMark());
+        xRef = new SwXTextCursor(*pFormat->GetDoc(), this, CursorType::Frame,
+                    *rPam.GetPoint(), rPam.GetMark());
     }
-
-    return aRef;
+    return xRef;
 }
 
 uno::Reference< container::XEnumeration >  SwXTextFrame::createEnumeration()
diff --git a/sw/source/core/unocore/unoftn.cxx 
b/sw/source/core/unocore/unoftn.cxx
index d20ff1a9e15a..30c8badc421c 100644
--- a/sw/source/core/unocore/unoftn.cxx
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -405,18 +405,35 @@ rtl::Reference< SwXTextCursor >
 SwXFootnote::createXTextCursorByRange(
     const uno::Reference< text::XTextRange > & xTextPosition)
 {
-    SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() );
+    SwUnoInternalPaM aPam(*GetDoc());
+    if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+    {
+        throw uno::RuntimeException();
+    }
+    return createXTextCursorByRangeImpl(aPam);
+}
 
+rtl::Reference< SwXTextCursor >
+SwXFootnote::createXTextCursorByRange(
+    const rtl::Reference< SwXTextCursor > & xTextPosition)
+{
     SwUnoInternalPaM aPam(*GetDoc());
     if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
     {
         throw uno::RuntimeException();
     }
+    return createXTextCursorByRangeImpl(aPam);
+}
+
+rtl::Reference< SwXTextCursor > SwXFootnote::createXTextCursorByRangeImpl(
+        SwUnoInternalPaM& rPam)
+{
+    SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() );
 
     SwTextFootnote const*const pTextFootnote = rFormat.GetTextFootnote();
     SwNode const*const pFootnoteStartNode = 
&pTextFootnote->GetStartNode()->GetNode();
 
-    const SwNode* pStart = aPam.GetPointNode().FindFootnoteStartNode();
+    const SwNode* pStart = rPam.GetPointNode().FindFootnoteStartNode();
     if (pStart != pFootnoteStartNode)
     {
         throw uno::RuntimeException();
@@ -424,7 +441,7 @@ SwXFootnote::createXTextCursorByRange(
 
     const rtl::Reference< SwXTextCursor > xRet =
                 new SwXTextCursor(*GetDoc(), this, CursorType::Footnote,
-                    *aPam.GetPoint(), aPam.GetMark());
+                    *rPam.GetPoint(), rPam.GetMark());
     return xRet;
 }
 
diff --git a/sw/source/core/unocore/unoobj.cxx 
b/sw/source/core/unocore/unoobj.cxx
index 84bc53608a26..7a6eaaef53b4 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -1153,29 +1153,46 @@ SwXTextCursor::gotoRange(
     const uno::Reference< text::XTextRange > & xRange, sal_Bool bExpand)
 {
     SolarMutexGuard aGuard;
-
     if (!xRange.is())
     {
         throw uno::RuntimeException();
     }
-
-    SwUnoCursor & rOwnCursor( GetCursorOrThrow() );
-
     SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xRange.get());
     OTextCursorHelper* pCursor = 
dynamic_cast<OTextCursorHelper*>(xRange.get());
-
     if (!pRange && !pCursor)
     {
         throw uno::RuntimeException();
     }
 
+    gotoRangeImpl(pRange, pCursor, bExpand);
+}
+
+void
+SwXTextCursor::gotoRange(
+    const rtl::Reference< SwXTextCursor > & xRange, bool bExpand)
+{
+    assert(xRange);
+    gotoRangeImpl(nullptr, xRange.get(), bExpand);
+}
+
+void
+SwXTextCursor::gotoRangeImpl(
+    SwXTextRange* pRange,
+    OTextCursorHelper* pCursor,
+    bool bExpand)
+{
+    DBG_TESTSOLARMUTEX();
+    assert((pRange || pCursor) && "one of these parameters must be non-null");
+
+    SwUnoCursor & rOwnCursor( GetCursorOrThrow() );
+
     SwPaM aPam(GetDoc()->GetNodes());
     const SwPaM * pPam(nullptr);
     if (pCursor)
     {
         pPam = pCursor->GetPaM();
     }
-    else if (pRange)
+    else
     {
         if (pRange->GetPositions(aPam))
         {
diff --git a/sw/source/core/unocore/unoobj2.cxx 
b/sw/source/core/unocore/unoobj2.cxx
index 620c1b50a1b1..534c34a841f3 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -1143,6 +1143,19 @@ void SwXTextRange::GetStartPaM(std::optional<SwPaM>& 
roPaM)
 
 namespace sw {
 
+static bool XTextRangeToSwPaMImpl( SwUnoInternalPaM & rToFill,
+        SwDoc* pDoc,
+        const SwPaM* pUnoCursor);
+
+bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
+        const rtl::Reference< SwXTextCursor > & xTextRange)
+{
+    assert(xTextRange);
+    SwDoc* pDoc = xTextRange->GetDoc();
+    const SwPaM* pUnoCursor = xTextRange->GetPaM();
+    return XTextRangeToSwPaMImpl(rToFill, pDoc, pUnoCursor);
+}
+
 bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
         const uno::Reference<text::XTextRange> & xTextRange,
         ::sw::TextRangeMode const eMode)
@@ -1157,8 +1170,6 @@ bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
         return pPara->SelectPaM(rToFill);
     }
 
-    bool bRet = false;
-
     SwXHeadFootText* pHeadText
         = eMode == TextRangeMode::AllowTableNode ? 
dynamic_cast<SwXHeadFootText*>(xTextRange.get()) : nullptr;
 
@@ -1187,7 +1198,6 @@ bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
     {
         pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
     }
-
     SwDoc* pDoc = nullptr;
     const SwPaM* pUnoCursor = nullptr;
     if (pCursor)
@@ -1200,6 +1210,14 @@ bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
         pDoc = &pPortion->GetCursor().GetDoc();
         pUnoCursor = &pPortion->GetCursor();
     }
+    return XTextRangeToSwPaMImpl(rToFill, pDoc, pUnoCursor);
+}
+
+static bool XTextRangeToSwPaMImpl( SwUnoInternalPaM & rToFill,
+        SwDoc* pDoc,
+        const SwPaM* pUnoCursor)
+{
+    bool bRet = false;
     if (pUnoCursor && pDoc == &rToFill.GetDoc())
     {
         OSL_ENSURE(!pUnoCursor->IsMultiSelection(),
diff --git a/sw/source/core/unocore/unoredline.cxx 
b/sw/source/core/unocore/unoredline.cxx
index 414bebbc1056..145e5d45b34e 100644
--- a/sw/source/core/unocore/unoredline.cxx
+++ b/sw/source/core/unocore/unoredline.cxx
@@ -138,6 +138,15 @@ rtl::Reference< SwXTextCursor > 
SwXRedlineText::createXTextCursorByRange(
     return xCursor;
 }
 
+rtl::Reference< SwXTextCursor > SwXRedlineText::createXTextCursorByRange(
+    const rtl::Reference< SwXTextCursor > & aTextRange)
+{
+    rtl::Reference< SwXTextCursor > xCursor = createXTextCursor();
+    xCursor->gotoRange(aTextRange->getStart(), false);
+    xCursor->gotoRange(aTextRange->getEnd(), true);
+    return xCursor;
+}
+
 uno::Reference<container::XEnumeration> SwXRedlineText::createEnumeration()
 {
     SolarMutexGuard aGuard;
@@ -561,6 +570,12 @@ rtl::Reference< SwXTextCursor > 
SwXRedline::createXTextCursorByRange(
     throw uno::RuntimeException();
 }
 
+rtl::Reference< SwXTextCursor > SwXRedline::createXTextCursorByRange(
+    const rtl::Reference< SwXTextCursor > & /*aTextPosition*/)
+{
+    throw uno::RuntimeException();
+}
+
 uno::Any SwXRedline::queryInterface( const uno::Type& rType )
 {
     uno::Any aRet = SwXText::queryInterface(rType);
diff --git a/sw/source/core/unocore/unorefmk.cxx 
b/sw/source/core/unocore/unorefmk.cxx
index b5aa314be008..d0be1fe75643 100644
--- a/sw/source/core/unocore/unorefmk.cxx
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -504,6 +504,8 @@ public:
     virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
     virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
             const ::css::uno::Reference< ::css::text::XTextRange >& 
aTextPosition ) override;
+    virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+            const rtl::Reference< SwXTextCursor >& aTextPosition ) override;
 };
 
 }
@@ -570,6 +572,15 @@ SwXMetaText::createXTextCursorByRange(
     return xCursor;
 }
 
+rtl::Reference< SwXTextCursor >
+SwXMetaText::createXTextCursorByRange(
+        const rtl::Reference< SwXTextCursor > & xTextPosition)
+{
+    const rtl::Reference< SwXTextCursor > xCursor( createXTextCursor() );
+    xCursor->gotoRange(xTextPosition, false);
+    return xCursor;
+}
+
 /**
  * the Meta has a cached list of text portions for its contents
  * this list is created by SwXTextPortionEnumeration
diff --git a/sw/source/core/unocore/unotbl.cxx 
b/sw/source/core/unocore/unotbl.cxx
index fa442954a55f..a8b99eccba91 100644
--- a/sw/source/core/unocore/unotbl.cxx
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -910,17 +910,34 @@ rtl::Reference< SwXTextCursor > 
SwXCell::createXTextCursor()
 rtl::Reference<SwXTextCursor> SwXCell::createXTextCursorByRange(const 
uno::Reference< text::XTextRange > & xTextPosition)
 {
     SwUnoInternalPaM aPam(*GetDoc());
-    if((!m_pStartNode && !IsValid()) || !::sw::XTextRangeToSwPaM(aPam, 
xTextPosition))
+    if(!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+        throw uno::RuntimeException();
+    return createXTextCursorByRangeImpl(aPam);
+}
+
+rtl::Reference<SwXTextCursor> SwXCell::createXTextCursorByRange(
+    const rtl::Reference< SwXTextCursor > & xTextPosition)
+{
+    SwUnoInternalPaM aPam(*GetDoc());
+    if(!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+        throw uno::RuntimeException();
+    return createXTextCursorByRangeImpl(aPam);
+}
+
+rtl::Reference< SwXTextCursor > SwXCell::createXTextCursorByRangeImpl(
+        SwUnoInternalPaM& rPam)
+{
+    if(!m_pStartNode && !IsValid())
         throw uno::RuntimeException();
     const SwStartNode* pSttNd = m_pStartNode ? m_pStartNode : 
m_pBox->GetSttNd();
     // skip sections
-    SwStartNode* p1 = aPam.GetPointNode().StartOfSectionNode();
+    SwStartNode* p1 = rPam.GetPointNode().StartOfSectionNode();
     while(p1->IsSectionNode())
         p1 = p1->StartOfSectionNode();
     if( p1 != pSttNd )
         return nullptr;
     return new SwXTextCursor(*GetDoc(), this, CursorType::TableText,
-                *aPam.GetPoint(), aPam.GetMark());
+                *rPam.GetPoint(), rPam.GetMark());
 }
 
 uno::Reference< beans::XPropertySetInfo >  SwXCell::getPropertySetInfo()
diff --git a/sw/source/core/unocore/unotext.cxx 
b/sw/source/core/unocore/unotext.cxx
index b189bc6d9167..cee7303853e1 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -767,12 +767,17 @@ uno::Reference< text::XTextRange > SAL_CALL
 SwXText::getEnd()
 {
     SolarMutexGuard aGuard;
+    return static_cast<text::XWordCursor*>(getEndImpl(aGuard).get());
+}
 
+rtl::Reference< SwXTextCursor >
+SwXText::getEndImpl(SolarMutexGuard& /*rGuard*/)
+{
     const rtl::Reference< SwXTextCursor > xRef = createXTextCursor();
     if(!xRef.is())
         throw uno::RuntimeException(cInvalidObject);
     xRef->gotoEnd(false);
-    return static_cast<text::XWordCursor*>(xRef.get());
+    return xRef;
 }
 
 OUString SAL_CALL SwXText::getString()
@@ -1258,9 +1263,18 @@ SwXText::insertTextPortion(
     {
         throw  uno::RuntimeException();
     }
-    uno::Reference< text::XTextRange > xRet;
+
     const rtl::Reference<SwXTextCursor> xTextCursor = 
createXTextCursorByRange(xInsertPosition);
+    return insertTextPortionImpl(aGuard, rText, 
rCharacterAndParagraphProperties, xTextCursor);
+}
 
+rtl::Reference< SwXTextRange >
+SwXText::insertTextPortionImpl(
+        SolarMutexGuard& /*rGuard*/,
+        std::u16string_view rText,
+        const uno::Sequence< beans::PropertyValue > & 
rCharacterAndParagraphProperties,
+        const rtl::Reference<SwXTextCursor>& xTextCursor)
+{
     bool bIllegalException = false;
     bool bRuntimeException = false;
     OUString sMessage;
@@ -1269,7 +1283,7 @@ SwXText::insertTextPortion(
     auto& rCursor(xTextCursor->GetCursor());
     m_pDoc->DontExpandFormat( *rCursor.Start() );
 
-    if (!rText.isEmpty())
+    if (!rText.empty())
     {
         SwNodeIndex const nodeIndex(rCursor.GetPoint()->GetNode(), -1);
         const sal_Int32 nContentPos = rCursor.GetPoint()->GetContentIndex();
@@ -1310,7 +1324,7 @@ SwXText::insertTextPortion(
             throw uno::RuntimeException(sMessage);
         }
     }
-    xRet = new SwXTextRange(rCursor, this);
+    rtl::Reference< SwXTextRange > xRet = new SwXTextRange(rCursor, this);
     return xRet;
 }
 
@@ -1322,10 +1336,11 @@ SwXText::appendTextPortion(
         const uno::Sequence< beans::PropertyValue > &
             rCharacterAndParagraphProperties)
 {
-    // Right now this doesn't need a guard, as it's just calling the insert
-    // version, that has it already.
-    uno::Reference<text::XTextRange> xInsertPosition = getEnd();
-    return insertTextPortion(rText, rCharacterAndParagraphProperties, 
xInsertPosition);
+    SolarMutexGuard aGuard;
+    rtl::Reference< SwXTextCursor > xInsertPosition = getEndImpl(aGuard);
+    rtl::Reference<SwXTextCursor> xTextCursor = 
createXTextCursorByRange(xInsertPosition);
+    rtl::Reference< SwXTextRange > xRange = insertTextPortionImpl(aGuard, 
rText, rCharacterAndParagraphProperties, xTextCursor);
+    return xRange;
 }
 
 // enable inserting/appending text contents like graphic objects, shapes and 
so on to
@@ -2429,38 +2444,48 @@ rtl::Reference< SwXTextCursor >
 SwXBodyText::createXTextCursorByRange(
     const uno::Reference< text::XTextRange > & xTextPosition)
 {
-    if(!IsValid())
-        throw uno::RuntimeException(cInvalidObject);
+    SwUnoInternalPaM aPam(*GetDoc());
+    if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+        throw uno::RuntimeException();
+    return createXTextCursorByRangeImpl(aPam);
+}
 
-    rtl::Reference< SwXTextCursor > aRef;
+rtl::Reference< SwXTextCursor >
+SwXBodyText::createXTextCursorByRange(
+    const rtl::Reference< SwXTextCursor > & xTextPosition)
+{
     SwUnoInternalPaM aPam(*GetDoc());
-    if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
-    {
-        if ( !aPam.GetPointNode().GetTextNode() )
-            throw uno::RuntimeException(u"Invalid text range"_ustr );
+    if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+        throw uno::RuntimeException();
+    return createXTextCursorByRangeImpl(aPam);
+}
 
-        SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+rtl::Reference< SwXTextCursor > SwXBodyText::createXTextCursorByRangeImpl(
+        SwUnoInternalPaM& rPam)
+{
+    if(!IsValid())
+        throw uno::RuntimeException(cInvalidObject);
 
-        SwStartNode* p1 = aPam.GetPointNode().StartOfSectionNode();
-        //document starts with a section?
-        while(p1->IsSectionNode())
-        {
-            p1 = p1->StartOfSectionNode();
-        }
-        SwStartNode *const p2 = rNode.StartOfSectionNode();
+    if ( !rPam.GetPointNode().GetTextNode() )
+        throw uno::RuntimeException(u"Invalid text range"_ustr );
 
-        if(p1 == p2)
-        {
-            aRef = new SwXTextCursor(*GetDoc(), this, CursorType::Body,
-                        *aPam.GetPoint(), aPam.GetMark());
-        }
-    }
-    if(!aRef.is())
+    SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+
+    SwStartNode* p1 = rPam.GetPointNode().StartOfSectionNode();
+    //document starts with a section?
+    while(p1->IsSectionNode())
     {
+        p1 = p1->StartOfSectionNode();
+    }
+    SwStartNode *const p2 = rNode.StartOfSectionNode();
+
+    if(p1 != p2)
         throw uno::RuntimeException( u"End of content node doesn't have the 
proper start node"_ustr,
                uno::Reference< uno::XInterface >( *this ) );
-    }
-    return aRef;
+
+    rtl::Reference< SwXTextCursor > xRef = new SwXTextCursor(*GetDoc(), this, 
CursorType::Body,
+                    *rPam.GetPoint(), rPam.GetMark());
+    return xRef;
 }
 
 uno::Reference< container::XEnumeration > SAL_CALL
@@ -2657,13 +2682,29 @@ SwXHeadFootText::createXTextCursor()
 rtl::Reference<SwXTextCursor> SwXHeadFootText::createXTextCursorByRange(
     const uno::Reference<text::XTextRange>& xTextPosition)
 {
-    SwFrameFormat& rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
+    SwUnoInternalPaM aPam(*GetDoc());
+    if (!sw::XTextRangeToSwPaM(aPam, xTextPosition))
+    {
+        throw uno::RuntimeException(cInvalidObject);
+    }
+    return createXTextCursorByRangeImpl(aPam);
+}
 
+rtl::Reference<SwXTextCursor> SwXHeadFootText::createXTextCursorByRange(
+    const rtl::Reference< SwXTextCursor >& xTextPosition)
+{
     SwUnoInternalPaM aPam(*GetDoc());
     if (!sw::XTextRangeToSwPaM(aPam, xTextPosition))
     {
         throw uno::RuntimeException(cInvalidObject);
     }
+    return createXTextCursorByRangeImpl(aPam);
+}
+
+rtl::Reference< SwXTextCursor > SwXHeadFootText::createXTextCursorByRangeImpl(
+        SwUnoInternalPaM& rPam)
+{
+    SwFrameFormat& rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
 
     SwNode& rNode = rHeadFootFormat.GetContent().GetContentIdx()->GetNode();
     SwPosition aPos(rNode);
@@ -2671,7 +2712,7 @@ rtl::Reference<SwXTextCursor> 
SwXHeadFootText::createXTextCursorByRange(
     aHFPam.Move(fnMoveForward, GoInNode);
     SwStartNode* const pOwnStartNode = aHFPam.GetPointNode().FindSttNodeByType(
             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
-    SwStartNode* const p1 = aPam.GetPointNode().FindSttNodeByType(
+    SwStartNode* const p1 = rPam.GetPointNode().FindSttNodeByType(
             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
     if (p1 == pOwnStartNode)
     {
@@ -2679,7 +2720,7 @@ rtl::Reference<SwXTextCursor> 
SwXHeadFootText::createXTextCursorByRange(
                     *GetDoc(),
                     this,
                     (m_pImpl->m_bIsHeader) ? CursorType::Header : 
CursorType::Footer,
-                    *aPam.GetPoint(), aPam.GetMark());
+                    *rPam.GetPoint(), rPam.GetMark());
     }
     return nullptr;
 }

Reply via email to