[Libreoffice-commits] core.git: sw/CppunitTest_sw_apitests.mk sw/inc sw/qa sw/source

Bjoern Michaelsen (via logerrit) logerrit at kemper.freedesktop.org
Sun May 5 20:28:39 UTC 2019


 sw/CppunitTest_sw_apitests.mk       |    1 
 sw/inc/fmtfld.hxx                   |    2 
 sw/qa/api/SwXTextField.cxx          |   89 ++++++++++++++++++
 sw/qa/python/xtext.py               |    8 +
 sw/source/core/txtnode/atrfld.cxx   |    4 
 sw/source/core/unocore/unofield.cxx |  174 ++++++++++++++++--------------------
 6 files changed, 177 insertions(+), 101 deletions(-)

New commits:
commit e18359445fabad9ba1a704600e9ee327112cc6ae
Author:     Bjoern Michaelsen <bjoern.michaelsen at libreoffice.org>
AuthorDate: Sun Apr 14 13:33:35 2019 +0200
Commit:     Björn Michaelsen <bjoern.michaelsen at libreoffice.org>
CommitDate: Sun May 5 22:27:54 2019 +0200

    [API CHANGE] SwXTextField: no more SwModify/SwClient
    
    - fix unittest assuming the double-insertion of annotation
      throwing an IllegalArgumentException was intentional
    - remove SwModify/SwClient in SwXTextField
    - also: add basic C++ api test
    
    Change-Id: Ia4657dc65dfadc3e975bdf409bd5e43413ea1f5a
    Reviewed-on: https://gerrit.libreoffice.org/71452
    Tested-by: Jenkins
    Reviewed-by: Björn Michaelsen <bjoern.michaelsen at libreoffice.org>

diff --git a/sw/CppunitTest_sw_apitests.mk b/sw/CppunitTest_sw_apitests.mk
index ca2c919e0aa6..370ed779d8b9 100644
--- a/sw/CppunitTest_sw_apitests.mk
+++ b/sw/CppunitTest_sw_apitests.mk
@@ -16,6 +16,7 @@ $(eval $(call gb_CppunitTest_use_external,sw_apitests,boost_headers))
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_apitests, \
     sw/qa/api/SwXDocumentIndex \
     sw/qa/api/SwXDocumentSettings \
+    sw/qa/api/SwXTextField \
     sw/qa/api/SwXTextTable \
 ))
 
diff --git a/sw/inc/fmtfld.hxx b/sw/inc/fmtfld.hxx
index b144243ec4c9..d9eafeea82a3 100644
--- a/sw/inc/fmtfld.hxx
+++ b/sw/inc/fmtfld.hxx
@@ -36,7 +36,7 @@ namespace com { namespace sun { namespace star { namespace text { class XTextFie
 // ATT_FLD
 class SW_DLLPUBLIC SwFormatField
     : public SfxPoolItem
-    , public SwModify
+    , public sw::BroadcastingModify
     , public SfxBroadcaster
 {
     friend void InitCore();
diff --git a/sw/qa/api/SwXTextField.cxx b/sw/qa/api/SwXTextField.cxx
new file mode 100644
index 000000000000..1de775d1e3d7
--- /dev/null
+++ b/sw/qa/api/SwXTextField.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <test/lang/xcomponent.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/text/XDependentTextField.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+
+namespace
+{
+/**
+ * Initial tests for SwXTextField.
+ */
+struct SwXTextField final : public test::BootstrapFixture,
+                            public unotest::MacrosTest,
+                            public apitest::XComponent
+{
+    virtual void setUp() override;
+
+    Reference<XInterface> init() override;
+    void triggerDesktopTerminate() override;
+
+    CPPUNIT_TEST_SUITE(SwXTextField);
+    CPPUNIT_TEST(testAddEventListener);
+    CPPUNIT_TEST(testRemoveEventListener);
+    //CPPUNIT_TEST(testDisposedByDesktopTerminate);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void SwXTextField::setUp()
+{
+    test::BootstrapFixture::setUp();
+    mxDesktop.set(
+        frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
+}
+
+void SwXTextField::triggerDesktopTerminate() { mxDesktop->terminate(); }
+
+Reference<XInterface> SwXTextField::init()
+{
+    auto xComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
+    CPPUNIT_ASSERT(xComponent.is());
+    Reference<text::XTextDocument> xTextDocument(xComponent, UNO_QUERY_THROW);
+    Reference<lang::XMultiServiceFactory> xMSF(xComponent, UNO_QUERY_THROW);
+
+    Reference<XPropertySet> xFieldMaster(
+        xMSF->createInstance("com.sun.star.text.FieldMaster.Database"), UNO_QUERY_THROW);
+    xFieldMaster->setPropertyValue("DataBaseName", makeAny(OUString("Address Book File")));
+    xFieldMaster->setPropertyValue("DataTableName", makeAny(OUString("address")));
+    xFieldMaster->setPropertyValue("DataColumnName", makeAny(OUString("FIRSTNAME")));
+
+    Reference<text::XDependentTextField> xField(
+        xMSF->createInstance("com.sun.star.text.TextField.Database"), UNO_QUERY_THROW);
+    xField->attachTextFieldMaster(xFieldMaster);
+    Reference<text::XText> xText = xTextDocument->getText();
+    Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    Reference<text::XTextContent> xFieldAsContent(xField, UNO_QUERY_THROW);
+    xText->insertTextContent(xCursor, xFieldAsContent, false);
+    return Reference<XInterface>(xField, UNO_QUERY_THROW);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SwXTextField);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/python/xtext.py b/sw/qa/python/xtext.py
index d137cb1f69ce..b8bc25d90e92 100644
--- a/sw/qa/python/xtext.py
+++ b/sw/qa/python/xtext.py
@@ -37,9 +37,11 @@ class TestXText(unittest.TestCase):
         # And the same once again, actually not inserted
         x_text.insertTextContent(x_cursor, x_annotation, False)
 
-        # Exception if we try to replace object by itself
-        with self.assertRaises(IllegalArgumentException):
-            x_text.insertTextContent(x_cursor, x_annotation, True)
+        # no exception if we try to replace object by itself:
+        # this did throw in the past, but only because the inserted
+        # UNO annotation had a core object assigned, but no document
+        # which insertTextContent then didnt like on another call.
+        x_text.insertTextContent(x_cursor, x_annotation, True)
 
         # We expect just one annotation actually
         self.check_annotations(["John Doe"])
diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx
index 3e7ffb0604fa..6f433b2056f5 100644
--- a/sw/source/core/txtnode/atrfld.cxx
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -47,7 +47,6 @@
 // constructor for default item in attribute-pool
 SwFormatField::SwFormatField( sal_uInt16 nWhich )
     : SfxPoolItem( nWhich )
-    , SwModify(nullptr)
     , SfxBroadcaster()
     , mpTextField( nullptr )
 {
@@ -55,11 +54,11 @@ SwFormatField::SwFormatField( sal_uInt16 nWhich )
 
 SwFormatField::SwFormatField( const SwField &rField )
     : SfxPoolItem( RES_TXTATR_FIELD )
-    , SwModify( rField.GetTyp() )
     , SfxBroadcaster()
     , mpField( rField.CopyField() )
     , mpTextField( nullptr )
 {
+    rField.GetTyp()->Add(this);
     if ( mpField->GetTyp()->Which() == SwFieldIds::Input )
     {
         // input field in-place editing
@@ -93,7 +92,6 @@ SwFormatField::SwFormatField( const SwField &rField )
 // corrected
 SwFormatField::SwFormatField( const SwFormatField& rAttr )
     : SfxPoolItem( rAttr )
-    , SwModify(nullptr)
     , SfxBroadcaster()
     , mpTextField( nullptr )
 {
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index 14f8f3ca0b98..63614495ab9c 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1117,39 +1117,37 @@ struct SwFieldProperties_Impl
 };
 
 class SwXTextField::Impl
-    : public SwClient, public SvtListener
+    : public SvtListener
 {
 private:
     ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
     SwFieldType* m_pFieldType;
+    SwFormatField* m_pFormatField;
 
 public:
     uno::WeakReference<uno::XInterface> m_wThis;
     ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
 
-    SwFormatField const*            m_pFormatField;
-    SwDoc *                         m_pDoc;
+    SwDoc* m_pDoc;
     rtl::Reference<SwTextAPIObject> m_xTextObject;
-
-    bool                m_bIsDescriptor;
-    bool                m_bCallUpdate;
-    SwServiceType const       m_nServiceId;
-    OUString            m_sTypeName;
+    bool m_bCallUpdate;
+    SwServiceType const m_nServiceId;
+    OUString m_sTypeName;
     std::unique_ptr<SwFieldProperties_Impl> m_pProps;
 
-    Impl(SwDoc *const pDoc, SwFormatField *const pFormat,
-            SwServiceType nServiceId)
-        : SwClient(pFormat)
+    Impl(SwDoc *const pDoc, SwFormatField *const pFormat, SwServiceType nServiceId)
+        : m_pFormatField(pFormat)
         , m_EventListeners(m_Mutex)
-        , m_pFormatField(pFormat)
         , m_pDoc(pDoc)
-        , m_bIsDescriptor(pFormat == nullptr)
         , m_bCallUpdate(false)
         , m_nServiceId(pFormat
                 ? lcl_GetServiceForField(*pFormat->GetField())
                 : nServiceId)
         , m_pProps(pFormat ? nullptr : new SwFieldProperties_Impl)
-    { }
+    {
+        if(m_pFormatField)
+            StartListening(m_pFormatField->GetNotifier());
+    }
 
     virtual ~Impl() override
     {
@@ -1159,21 +1157,37 @@ public:
         }
     }
 
+    void SetFormatField(SwFormatField* pFormatField, SwDoc* pDoc)
+    {
+        m_pFormatField = pFormatField;
+        m_pDoc = pDoc;
+        if(m_pFormatField)
+        {
+            EndListeningAll();
+            StartListening(m_pFormatField->GetNotifier());
+        }
+    }
+    SwFormatField* GetFormatField()
+    {
+        return m_pFormatField;
+    }
+    bool IsDescriptor() const
+    {
+        return !m_pFormatField;
+    }
     void Invalidate();
 
-    const SwField*      GetField() const;
+    const SwField* GetField() const;
 
-    SwFieldType* GetFieldType()
+    SwFieldType* GetFieldType() const
     {
-        if (m_bIsDescriptor)
+        if (IsDescriptor())
             return m_pFieldType;
-        if (!GetRegisteredIn())
-            throw uno::RuntimeException();
         return m_pFormatField->GetField()->GetTyp();
     }
     void SetFieldType(SwFieldType& rType)
     {
-        SvtListener::EndListeningAll();
+        EndListeningAll();
         m_pFieldType = &rType;
         StartListening(m_pFieldType->GetNotifier());
     }
@@ -1182,9 +1196,6 @@ public:
         SvtListener::EndListeningAll();
         m_pFieldType = nullptr;
     }
-protected:
-    // SwClient
-    virtual void Modify(SfxPoolItem const* pOld, SfxPoolItem const* pNew) override;
     virtual void Notify(const SfxHint&) override;
 };
 
@@ -1292,12 +1303,8 @@ void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField)
                 uno::Reference<lang::XUnoTunnel>(xField, uno::UNO_QUERY_THROW)
                     ->getSomething(getUnoTunnelId())))
         : nullptr;
-    if (xField.is())
-    {
-        assert(pXField->m_pImpl->m_pFormatField == rField.GetFormatField());
-        rField.GetFormatField()->Remove(pXField->m_pImpl.get());
-        pXField->m_pImpl->m_pFormatField = nullptr;
-    }
+    if (pXField)
+        pXField->m_pImpl->SetFormatField(nullptr, nullptr);
     SwTextField *const pOldAttr(rField.GetFormatField()->GetTextField());
     SwSetExpField tempField(rField);
     tempField.SetInputFlag(!rField.GetInputFlag());
@@ -1323,8 +1330,7 @@ void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField)
     assert(static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() == (dynamic_cast<SwTextInputField const*>(pNewAttr) != nullptr));
     if (xField.is())
     {
-        pXField->m_pImpl->m_pFormatField = &rNewFormat;
-        const_cast<SwFormatField&>(rNewFormat).Add(pXField->m_pImpl.get());
+        pXField->m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rNewFormat), rNode.GetDoc());
         const_cast<SwFormatField&>(rNewFormat).SetXTextField(xField);
     }
 }
@@ -1334,7 +1340,7 @@ void SAL_CALL SwXTextField::attachTextFieldMaster(
 {
     SolarMutexGuard aGuard;
 
-    if (!m_pImpl->m_bIsDescriptor)
+    if (!m_pImpl->IsDescriptor())
         throw uno::RuntimeException();
     uno::Reference< lang::XUnoTunnel > xMasterTunnel(xFieldMaster, uno::UNO_QUERY);
     if (!xMasterTunnel.is())
@@ -1378,7 +1384,7 @@ void SAL_CALL SwXTextField::attach(
         const uno::Reference< text::XTextRange > & xTextRange)
 {
     SolarMutexGuard aGuard;
-    if (m_pImpl->m_bIsDescriptor)
+    if (m_pImpl->IsDescriptor())
     {
     uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
     SwXTextRange* pRange = nullptr;
@@ -2005,7 +2011,7 @@ void SAL_CALL SwXTextField::attach(
         throw uno::RuntimeException("no SwTextAttr inserted?");  // could theoretically happen, if paragraph is full
 
     const SwFormatField& rField = pTextAttr->GetFormatField();
-    m_pImpl->m_pFormatField = &rField;
+    m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rField), pDoc);
 
     if ( pTextAttr->Which() == RES_TXTATR_ANNOTATION
          && *aPam.GetPoint() != *aPam.GetMark() )
@@ -2022,18 +2028,16 @@ void SAL_CALL SwXTextField::attach(
 
     xField.reset();
 
-    assert(m_pImpl->m_pFormatField);
+    assert(m_pImpl->GetFormatField());
     m_pImpl->m_pDoc = pDoc;
-    const_cast<SwFormatField *>(m_pImpl->m_pFormatField)->Add(m_pImpl.get());
-    const_cast<SwFormatField *>(m_pImpl->m_pFormatField)->SetXTextField(this);
+    m_pImpl->GetFormatField()->SetXTextField(this);
     m_pImpl->m_wThis = *this;
-    m_pImpl->m_bIsDescriptor = false;
     m_pImpl->ClearFieldType();
     m_pImpl->m_pProps.reset();
     if (m_pImpl->m_bCallUpdate)
         update();
     }
-    else if ( m_pImpl->m_pFormatField != nullptr
+    else if ( !m_pImpl->IsDescriptor()
               && m_pImpl->m_pDoc != nullptr
               && m_pImpl->m_nServiceId == SwServiceType::FieldTypeAnnotation )
     {
@@ -2047,14 +2051,14 @@ void SAL_CALL SwXTextField::attach(
         {
             UnoActionContext aCont( m_pImpl->m_pDoc );
             // insert copy of annotation at new text range
-            std::unique_ptr<SwPostItField> pPostItField(static_cast< SwPostItField* >(m_pImpl->m_pFormatField->GetField()->CopyField().release()));
+            std::unique_ptr<SwPostItField> pPostItField(static_cast< SwPostItField* >(m_pImpl->GetFormatField()->GetField()->CopyField().release()));
             SwFormatField aFormatField( *pPostItField );
             pPostItField.reset();
             SwPaM aEnd( *aIntPam.End(), *aIntPam.End() );
             m_pImpl->m_pDoc->getIDocumentContentOperations().InsertPoolItem( aEnd, aFormatField );
             // delete former annotation
             {
-                const SwTextField* pTextField = m_pImpl->m_pFormatField->GetTextField();
+                const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
                 SwTextNode& rTextNode = *pTextField->GetpTextNode();
                 SwPaM aPam( rTextNode, pTextField->GetStart() );
                 aPam.SetMark();
@@ -2066,7 +2070,7 @@ void SAL_CALL SwXTextField::attach(
                 SwTextField* pTextAttr = aEnd.GetNode().GetTextNode()->GetFieldTextAttrAt( aEnd.End()->nContent.GetIndex()-1, true );
                 if ( pTextAttr != nullptr )
                 {
-                    m_pImpl->m_pFormatField = &pTextAttr->GetFormatField();
+                    m_pImpl->SetFormatField(const_cast<SwFormatField*>(&pTextAttr->GetFormatField()), m_pImpl->m_pDoc);
 
                     if ( *aIntPam.GetPoint() != *aIntPam.GetMark() )
                     {
@@ -2097,7 +2101,7 @@ SwXTextField::getAnchor()
     if (!pField)
         return nullptr;
 
-    const SwTextField* pTextField = m_pImpl->m_pFormatField->GetTextField();
+    const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
     if (!pTextField)
         throw uno::RuntimeException();
 
@@ -2130,12 +2134,11 @@ void SAL_CALL SwXTextField::dispose()
 {
     SolarMutexGuard aGuard;
     SwField const*const pField = m_pImpl->GetField();
-    if(pField)
+    if(pField && m_pImpl->m_pDoc)
     {
         UnoActionContext aContext(m_pImpl->m_pDoc);
-
-        assert(m_pImpl->m_pFormatField->GetTextField() && "<SwXTextField::dispose()> - missing <SwTextField> --> crash");
-        SwTextField::DeleteTextField(*(m_pImpl->m_pFormatField->GetTextField()));
+        assert(m_pImpl->GetFormatField()->GetTextField() && "<SwXTextField::dispose()> - missing <SwTextField> --> crash");
+        SwTextField::DeleteTextField(*(m_pImpl->GetFormatField()->GetTextField()));
     }
 
     if (m_pImpl->m_xTextObject.is())
@@ -2143,6 +2146,7 @@ void SAL_CALL SwXTextField::dispose()
         m_pImpl->m_xTextObject->DisposeEditSource();
         m_pImpl->m_xTextObject.clear();
     }
+    m_pImpl->Invalidate();
 }
 
 void SAL_CALL SwXTextField::addEventListener(
@@ -2213,7 +2217,7 @@ SwXTextField::setPropertyValue(
         {
             SwDoc * pDoc = m_pImpl->m_pDoc;
             assert(pDoc);
-            const SwTextField* pTextField = m_pImpl->m_pFormatField->GetTextField();
+            const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
             if(!pTextField)
                 throw uno::RuntimeException();
             SwPosition aPosition( pTextField->GetTextNode() );
@@ -2222,16 +2226,16 @@ SwXTextField::setPropertyValue(
         }
 
         //#i100374# notify SwPostIt about new field content
-        if (SwFieldIds::Postit == nWhich && m_pImpl->m_pFormatField)
+        if (SwFieldIds::Postit == nWhich && !m_pImpl->IsDescriptor())
         {
-            const_cast<SwFormatField*>(m_pImpl->m_pFormatField)->Broadcast(
+            m_pImpl->GetFormatField()->Broadcast(
                     SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::CHANGED ));
         }
 
         // fdo#42073 notify SwTextField about changes of the expanded string
-        if (m_pImpl->m_pFormatField->GetTextField())
+        if (m_pImpl->GetFormatField()->GetTextField())
         {
-            m_pImpl->m_pFormatField->GetTextField()->ExpandTextField();
+            m_pImpl->GetFormatField()->GetTextField()->ExpandTextField();
         }
 
         //#i100374# changing a document field should set the modify flag
@@ -2396,9 +2400,9 @@ uno::Any SAL_CALL SwXTextField::getPropertyValue(const OUString& rPropertyName)
 
                 // get text node for the text field
                 const SwFormatField *pFieldFormat =
-                    (m_pImpl->GetField()) ? m_pImpl->m_pFormatField : nullptr;
+                    (m_pImpl->GetField()) ? m_pImpl->GetFormatField() : nullptr;
                 const SwTextField* pTextField = pFieldFormat
-                    ? m_pImpl->m_pFormatField->GetTextField() : nullptr;
+                    ? m_pImpl->GetFormatField()->GetTextField() : nullptr;
                 if(!pTextField)
                     throw uno::RuntimeException();
                 const SwTextNode& rTextNode = pTextField->GetTextNode();
@@ -2586,7 +2590,7 @@ void SAL_CALL SwXTextField::update()
             default: break;
         }
         // Text formatting has to be triggered.
-        const_cast<SwFormatField*>(m_pImpl->m_pFormatField)->ModifyNotification(nullptr, nullptr);
+        m_pImpl->GetFormatField()->ModifyNotification(nullptr, nullptr);
     }
     else
         m_pImpl->m_bCallUpdate = true;
@@ -2637,56 +2641,38 @@ uno::Sequence< OUString > SAL_CALL SwXTextField::getSupportedServiceNames()
 
 void SwXTextField::Impl::Invalidate()
 {
-    if (GetRegisteredIn())
-    {
-        SwClient::EndListeningAll();
-        m_pFormatField = nullptr;
-        m_pDoc = nullptr;
-        uno::Reference<uno::XInterface> const xThis(m_wThis);
-        if (!xThis.is())
-        {   // fdo#72695: if UNO object is already dead, don't revive it with event
-            return;
-        }
-        lang::EventObject const ev(xThis);
-        m_EventListeners.disposeAndClear(ev);
-    }
-}
-
-void SwXTextField::Impl::Modify(
-        SfxPoolItem const*const pOld, SfxPoolItem const*const pNew)
-{
-    switch( pOld ? pOld->Which() : 0 )
-    {
-    case RES_REMOVE_UNO_OBJECT:
-    case RES_OBJECTDYING:
-        if( static_cast<void*>(GetRegisteredIn()) == static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject )
-            Invalidate();
-        break;
-
-    case RES_FMT_CHG:
-        // Am I re-attached to a new one and will the old one be deleted?
-        if( static_cast<const SwFormatChg*>(pNew)->pChangedFormat == GetRegisteredIn() &&
-            static_cast<const SwFormatChg*>(pOld)->pChangedFormat->IsFormatInDTOR() )
-            Invalidate();
-        break;
+    EndListeningAll();
+    m_pFormatField = nullptr;
+    m_pDoc = nullptr;
+    uno::Reference<uno::XInterface> const xThis(m_wThis);
+    if (!xThis.is())
+    {   // fdo#72695: if UNO object is already dead, don't revive it with event
+        return;
     }
+    lang::EventObject const ev(xThis);
+    m_EventListeners.disposeAndClear(ev);
 }
 
 void SwXTextField::Impl::Notify(const SfxHint& rHint)
 {
+
     if(rHint.GetId() == SfxHintId::Dying)
+        Invalidate();
+    else if (auto pLegacyHint = dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
     {
-        m_pFieldType = nullptr;
+        switch(pLegacyHint->m_pOld ? pLegacyHint->m_pOld->Which() : 0)
+        {
+            case RES_REMOVE_UNO_OBJECT:
+            case RES_OBJECTDYING:
+                Invalidate();
+                break;
+        }
     }
 }
 
-const SwField*  SwXTextField::Impl::GetField() const
+const SwField* SwXTextField::Impl::GetField() const
 {
-    if (GetRegisteredIn() && m_pFormatField)
-    {
-        return m_pFormatField->GetField();
-    }
-    return nullptr;
+    return IsDescriptor() ? nullptr : m_pFormatField->GetField();
 }
 
 OUString SwXTextFieldMasters::getImplementationName()


More information about the Libreoffice-commits mailing list