[Libreoffice-commits] core.git: 38 commits - sc/source solenv/gdb sw/inc sw/README sw/source xmloff/source xmlscript/source

Michael Stahl mstahl at redhat.com
Wed Aug 20 07:45:17 PDT 2014


 sc/source/filter/excel/xiescher.cxx                |    3 
 solenv/gdb/libreoffice/sw.py                       |    8 -
 sw/README                                          |   43 ++++++-
 sw/inc/doc.hxx                                     |    4 
 sw/inc/expfld.hxx                                  |    4 
 sw/inc/fmtfld.hxx                                  |    7 -
 sw/inc/fmtftn.hxx                                  |   24 +++
 sw/inc/fmtrfmrk.hxx                                |   24 +++
 sw/inc/hintids.hxx                                 |    4 
 sw/inc/unocoll.hxx                                 |    4 
 sw/inc/unoframe.hxx                                |   32 ++++-
 sw/inc/unoparagraph.hxx                            |    6 
 sw/inc/unotbl.hxx                                  |    5 
 sw/source/core/attr/calbck.cxx                     |    7 -
 sw/source/core/crsr/bookmrk.cxx                    |    2 
 sw/source/core/doc/docftn.cxx                      |    3 
 sw/source/core/doc/docnew.cxx                      |    2 
 sw/source/core/doc/textboxhelper.cxx               |   12 +
 sw/source/core/docnode/nodes.cxx                   |   20 +--
 sw/source/core/fields/expfld.cxx                   |    6 
 sw/source/core/inc/unobookmark.hxx                 |   18 +-
 sw/source/core/inc/unofield.hxx                    |   14 +-
 sw/source/core/inc/unofootnote.hxx                 |   13 --
 sw/source/core/inc/unoidx.hxx                      |   13 +-
 sw/source/core/inc/unometa.hxx                     |   12 +
 sw/source/core/inc/unorefmark.hxx                  |   11 -
 sw/source/core/layout/atrfrm.cxx                   |    4 
 sw/source/core/tox/tox.cxx                         |    4 
 sw/source/core/txtnode/atrfld.cxx                  |   38 +++++-
 sw/source/core/txtnode/atrftn.cxx                  |   28 +++-
 sw/source/core/txtnode/atrref.cxx                  |   34 ++++-
 sw/source/core/txtnode/ndtxt.cxx                   |    2 
 sw/source/core/txtnode/thints.cxx                  |   14 --
 sw/source/core/unocore/unobkm.cxx                  |   75 +++++++-----
 sw/source/core/unocore/unocoll.cxx                 |  122 ++++++++------------
 sw/source/core/unocore/unocrsrhelper.cxx           |   21 +--
 sw/source/core/unocore/unodraw.cxx                 |   18 +-
 sw/source/core/unocore/unofield.cxx                |  128 +++++++++++++--------
 sw/source/core/unocore/unoframe.cxx                |   64 +++++++++-
 sw/source/core/unocore/unoftn.cxx                  |   75 +++++-------
 sw/source/core/unocore/unoidx.cxx                  |   84 +++++++++----
 sw/source/core/unocore/unoobj2.cxx                 |   36 +++--
 sw/source/core/unocore/unoparagraph.cxx            |   37 +++---
 sw/source/core/unocore/unoportenum.cxx             |   43 ++++---
 sw/source/core/unocore/unorefmk.cxx                |  106 +++++++++--------
 sw/source/core/unocore/unosect.cxx                 |   18 ++
 sw/source/core/unocore/unotbl.cxx                  |   31 ++++-
 sw/source/core/unocore/unotext.cxx                 |   19 +--
 sw/source/filter/ww8/docxattributeoutput.cxx       |    6 
 sw/source/filter/ww8/ww8par.cxx                    |    3 
 sw/source/filter/ww8/ww8par6.cxx                   |    6 
 sw/source/filter/xml/xmltexti.cxx                  |   45 ++++---
 sw/source/uibase/uno/unotxvw.cxx                   |   46 +++----
 sw/source/uibase/wrtsh/wrtsh2.cxx                  |   37 ++++--
 xmloff/source/forms/elementexport.cxx              |    4 
 xmloff/source/forms/layerimport.cxx                |    6 
 xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx |    1 
 xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx |    8 -
 58 files changed, 943 insertions(+), 521 deletions(-)

New commits:
commit 9f01ba1b78edf6a08d36be39658327451120d613
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 14:19:31 2014 +0200

    i#107771: sw: burn, UnoCallBack, burn!
    
    Change-Id: Ifdb6d4b2e404bd160e6fcec3229691e750bdf698

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 1fbb206..2ff506b 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -346,7 +346,6 @@ class SW_DLLPUBLIC SwDoc :
     SwLayoutCache   *mpLayoutCache;  /**< Layout cache to read and save with the
                                      document for a faster formatting */
 
-    SwModify *mpUnoCallBack;
     IGrammarContact *mpGrammarContact;   //< for grammar checking in paragraphs during editing
 
     // table of forbidden characters of this document
@@ -1562,9 +1561,6 @@ public:
     */
     bool ContainsHiddenChars() const;
 
-    // call back for API wrapper
-    SwModify*   GetUnoCallBack() const { return mpUnoCallBack; }
-
     IGrammarContact* getGrammarContact() const { return mpGrammarContact; }
 
     /** Marks/Unmarks a list level of a certain list
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index c5ec7fe..c18fe20 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -254,7 +254,6 @@ SwDoc::SwDoc()
     mpExtInputRing( 0 ),
     mpStyleAccess( 0 ),
     mpLayoutCache( 0 ),
-    mpUnoCallBack(new SwModify(0)),
     mpGrammarContact(createGrammarContact()),
     m_pXmlIdRegistry(),
     mReferenceCount(0),
@@ -446,7 +445,6 @@ SwDoc::~SwDoc()
 
     getIDocumentTimerAccess().StopIdling();   // stop idle timer
 
-    delete mpUnoCallBack, mpUnoCallBack = 0;
     delete mpURLStateChgd;
 
     // Deactivate Undo notification from Draw
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index b654296..253a792 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -263,7 +263,6 @@ void SwNodes::ChgNode( SwNodeIndex& rDelPos, sal_uLong nSz,
                             GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(rNds);
                         for( size_t i = pHts->Count(); i; )
                         {
-                            sal_uInt16 nDelMsg = 0;
                             SwTxtAttr * const pAttr = pHts->GetTextHint( --i );
                             switch ( pAttr->Which() )
                             {
@@ -325,14 +324,6 @@ void SwNodes::ChgNode( SwNodeIndex& rDelPos, sal_uLong nSz,
                             default:
                                 break;
                             }
-
-                            if( nDelMsg && bToUndo )
-                            {
-                                SwPtrMsgPoolItem aMsgHint( nDelMsg,
-                                    (void*)&pAttr->GetAttr() );
-                                rNds.GetDoc()->GetUnoCallBack()->
-                                    ModifyNotification( &aMsgHint, &aMsgHint );
-                            }
                         }
                     }
                     //FEATURE::CONDCOLL
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index 2ca92ba..3e228ac 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1114,7 +1114,6 @@ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr )
     {
         // einige Sachen muessen vorm Loeschen der "Format-Attribute" erfolgen
         SwDoc* pDoc = GetDoc();
-        sal_uInt16 nDelMsg = 0;
         switch( pAttr->Which() )
         {
         case RES_TXTATR_FLYCNT:
@@ -1198,12 +1197,6 @@ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr )
             break;
         }
 
-        if( nDelMsg && !pDoc->IsInDtor() && GetNodes().IsDocNodes() )
-        {
-            SwPtrMsgPoolItem aMsgHint( nDelMsg, (void*)&pAttr->GetAttr() );
-            pDoc->GetUnoCallBack()->ModifyNotification( &aMsgHint, &aMsgHint );
-        }
-
         SwTxtAttr::Destroy( pAttr, pDoc->GetAttrPool() );
     }
 }
commit bd6f0559af3cd07e42ebefc55529c7e1ea77366f
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 14:09:44 2014 +0200

    fdo#72695: avoid double-free race condition for SwXFootnote
    
    Change-Id: Id7832d8e65723ae30ad2b5ce95d145def53998f0

diff --git a/sw/source/core/inc/unofootnote.hxx b/sw/source/core/inc/unofootnote.hxx
index b5b6a2f..c974096 100644
--- a/sw/source/core/inc/unofootnote.hxx
+++ b/sw/source/core/inc/unofootnote.hxx
@@ -67,13 +67,13 @@ protected:
     virtual ~SwXFootnote();
 
     SwXFootnote(SwDoc & rDoc, SwFmtFtn & rFmt);
+    SwXFootnote(const bool bEndnote);
 
 public:
 
-    SwXFootnote(const bool bEndnote);
-
     static css::uno::Reference<css::text::XFootnote>
-        CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt);
+        CreateXFootnote(SwDoc & rDoc, SwFmtFtn * pFootnoteFmt,
+                bool isEndnote = false);
 
     // XInterface
     virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 36fd4ba..d08e8b9 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -613,10 +613,10 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
         break;
 
         case  SW_SERVICE_TYPE_FOOTNOTE :
-            xRet =  (cppu::OWeakObject*)new SwXFootnote(false);
+            xRet = SwXFootnote::CreateXFootnote(*pDoc, 0, false);
         break;
         case  SW_SERVICE_TYPE_ENDNOTE  :
-            xRet =  (cppu::OWeakObject*)new SwXFootnote(true);
+            xRet = SwXFootnote::CreateXFootnote(*pDoc, 0, true);
         break;
         case  SW_SERVICE_CONTENT_INDEX_MARK :
         case  SW_SERVICE_USER_INDEX_MARK    :
@@ -1836,7 +1836,7 @@ uno::Any SwXFootnotes::getByIndex(sal_Int32 nIndex)
             if(nCount == nIndex)
             {
                 xRef = SwXFootnote::CreateXFootnote(*GetDoc(),
-                        const_cast<SwFmtFtn&>(rFtn));
+                        &const_cast<SwFmtFtn&>(rFtn));
                 aRet <<= xRef;
                 break;
             }
@@ -1865,7 +1865,7 @@ sal_Bool SwXFootnotes::hasElements(void) throw( uno::RuntimeException, std::exce
 
 Reference<XFootnote>    SwXFootnotes::GetObject( SwDoc& rDoc, const SwFmtFtn& rFmt )
 {
-    return SwXFootnote::CreateXFootnote(rDoc, const_cast<SwFmtFtn&>(rFmt));
+    return SwXFootnote::CreateXFootnote(rDoc, &const_cast<SwFmtFtn&>(rFmt));
 }
 
 OUString SwXReferenceMarks::getImplementationName(void) throw( RuntimeException, std::exception )
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index 6ea70b4..6b511ae 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -608,7 +608,7 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
                     {
                         const uno::Reference< text::XFootnote > xFootnote =
                             SwXFootnote::CreateXFootnote(*rPam.GetDoc(),
-                                    const_cast<SwFmtFtn&>(rFtn));
+                                    &const_cast<SwFmtFtn&>(rFtn));
                         *pAny <<= xFootnote;
                     }
                 }
diff --git a/sw/source/core/unocore/unoftn.cxx b/sw/source/core/unocore/unoftn.cxx
index ebafc93..e3bd6b5 100644
--- a/sw/source/core/unocore/unoftn.cxx
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -50,6 +50,7 @@ private:
 public:
 
     SwXFootnote &               m_rThis;
+    uno::WeakReference<uno::XInterface> m_wThis;
     const bool                  m_bIsEndnote;
     ::cppu::OInterfaceContainerHelper m_EventListeners;
     bool                        m_bIsDescriptor;
@@ -96,7 +97,12 @@ void SwXFootnote::Impl::Invalidate()
     }
     m_pFmtFtn = 0;
     m_rThis.SetDoc(0);
-    lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis));
+    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);
 }
 
@@ -127,16 +133,27 @@ SwXFootnote::~SwXFootnote()
 }
 
 uno::Reference<text::XFootnote>
-SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt)
+SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFmtFtn *const pFootnoteFmt,
+        bool const isEndnote)
 {
     // i#105557: do not iterate over the registered clients: race condition
     uno::Reference<text::XFootnote> xNote;
-    xNote = rFootnoteFmt.GetXFootnote();
+    if (pFootnoteFmt)
+    {
+        xNote = pFootnoteFmt->GetXFootnote();
+    }
     if (!xNote.is())
     {
-        SwXFootnote *const pNote(new SwXFootnote(rDoc, rFootnoteFmt));
+        SwXFootnote *const pNote((pFootnoteFmt)
+                ? new SwXFootnote(rDoc, *pFootnoteFmt)
+                : new SwXFootnote(isEndnote));
         xNote.set(pNote);
-        rFootnoteFmt.SetXFootnote(xNote);
+        if (pFootnoteFmt)
+        {
+            pFootnoteFmt->SetXFootnote(xNote);
+        }
+        // need a permanent Reference to initialize m_wThis
+        pNote->m_pImpl->m_wThis = xNote;
     }
     return xNote;
 }
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index a63fc6a..8ec6e71 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -1239,7 +1239,7 @@ CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
                                     FindSttNodeByType(SwFootnoteStartNode))
                 {
                     xParentText.set(SwXFootnote::CreateXFootnote(rDoc,
-                            const_cast<SwFmtFtn&>(rFtn)), uno::UNO_QUERY);
+                            &const_cast<SwFmtFtn&>(rFtn)), uno::UNO_QUERY);
                     break;
                 }
             }
commit 2c057a59e8241b42c7c44a1b53ffb63dd0e92cea
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 14:05:03 2014 +0200

    i#107771: sw: implement thread-safe instance caching for SwXFootnote
    
    Change-Id: I3fffb321877168dfa9844b4ad75a9a9efc9602a6

diff --git a/sw/inc/fmtftn.hxx b/sw/inc/fmtftn.hxx
index fdfaee5..0e2b52c 100644
--- a/sw/inc/fmtftn.hxx
+++ b/sw/inc/fmtftn.hxx
@@ -20,11 +20,16 @@
 #define INCLUDED_SW_INC_FMTFTN_HXX
 
 #include <rtl/ustring.hxx>
+#include <cppuhelper/weakref.hxx>
 #include <svl/poolitem.hxx>
 
 #include "swdllapi.h"
 #include <calbck.hxx>
 
+namespace com { namespace sun { namespace star {
+    namespace text { class XFootnote; }
+} } }
+
 class SwDoc;
 class SwTxtFtn;
 
@@ -40,6 +45,8 @@ class SW_DLLPUBLIC SwFmtFtn
     sal_uInt16 m_nNumber;   ///< Automatische Nummerierung
     bool    m_bEndNote;     ///< Is it an End note?
 
+    css::uno::WeakReference<css::text::XFootnote> m_wXFootnote;
+
     /// Protected CopyCtor.
     SwFmtFtn& operator=(const SwFmtFtn& rFtn);
     SwFmtFtn( const SwFmtFtn& );
@@ -52,6 +59,10 @@ public:
     virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;
     virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 ) const SAL_OVERRIDE;
 
+    // SwClient
+    virtual void Modify(SfxPoolItem const* pOld, SfxPoolItem const* pNew)
+        SAL_OVERRIDE;
+
     void InvalidateFootnote();
 
     OUString   GetNumStr() const { return m_aNumber; }
@@ -75,6 +86,11 @@ public:
 
     /// Returns string to be displayed of footnote / endnote.
     OUString GetViewNumStr( const SwDoc& rDoc, bool bInclStrs = false ) const;
+
+    css::uno::WeakReference<css::text::XFootnote> const& GetXFootnote() const
+        { return m_wXFootnote; }
+    void SetXFootnote(css::uno::Reference<css::text::XFootnote> const& xNote)
+        { m_wXFootnote = xNote; }
 };
 
 #endif
diff --git a/sw/source/core/inc/unofootnote.hxx b/sw/source/core/inc/unofootnote.hxx
index 2a7643b..b5b6a2f 100644
--- a/sw/source/core/inc/unofootnote.hxx
+++ b/sw/source/core/inc/unofootnote.hxx
@@ -72,11 +72,8 @@ public:
 
     SwXFootnote(const bool bEndnote);
 
-    static SwXFootnote *
+    static css::uno::Reference<css::text::XFootnote>
         CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt);
-    /// may return 0
-    static SwXFootnote *
-        GetXFootnote(SwModify const& rUnoCB, SwFmtFtn const& rFootnoteFmt);
 
     // XInterface
     virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
diff --git a/sw/source/core/txtnode/atrftn.cxx b/sw/source/core/txtnode/atrftn.cxx
index 9ada9df..5227ba9 100644
--- a/sw/source/core/txtnode/atrftn.cxx
+++ b/sw/source/core/txtnode/atrftn.cxx
@@ -141,6 +141,15 @@ SfxPoolItem* SwFmtFtn::Clone( SfxItemPool* ) const
     return pNew;
 }
 
+void SwFmtFtn::Modify(SfxPoolItem const* pOld, SfxPoolItem const* pNew)
+{
+    NotifyClients(pOld, pNew);
+    if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
+    {   // invalidate cached UNO object
+        SetXFootnote(css::uno::Reference<css::text::XFootnote>(0));
+    }
+}
+
 void SwFmtFtn::InvalidateFootnote()
 {
     SwPtrMsgPoolItem const item(RES_REMOVE_UNO_OBJECT,
diff --git a/sw/source/core/unocore/unoftn.cxx b/sw/source/core/unocore/unoftn.cxx
index 158e729..ebafc93 100644
--- a/sw/source/core/unocore/unoftn.cxx
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -126,26 +126,19 @@ SwXFootnote::~SwXFootnote()
 {
 }
 
-SwXFootnote *
-SwXFootnote::GetXFootnote(
-        SwModify const& /*rUnoCB*/, SwFmtFtn const& /*rFootnoteFmt*/)
-{
-    // re-use existing SwXFootnote
-    // #i105557#: do not iterate over the registered clients: race condition
-    // to do this properly requires the SwXFootnote to register at the
-    // SwFmtFtn directly, not at the unocallback
-    // also this function must return a uno Reference!
-    return 0;
-}
-
-SwXFootnote *
+uno::Reference<text::XFootnote>
 SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt)
 {
-    SwXFootnote *const pXFootnote(
-        GetXFootnote(rFootnoteFmt, rFootnoteFmt));
-    return (pXFootnote)
-        ?   pXFootnote
-        :   new SwXFootnote(rDoc, rFootnoteFmt);
+    // i#105557: do not iterate over the registered clients: race condition
+    uno::Reference<text::XFootnote> xNote;
+    xNote = rFootnoteFmt.GetXFootnote();
+    if (!xNote.is())
+    {
+        SwXFootnote *const pNote(new SwXFootnote(rDoc, rFootnoteFmt));
+        xNote.set(pNote);
+        rFootnoteFmt.SetXFootnote(xNote);
+    }
+    return xNote;
 }
 
 namespace
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index e1b4615..a63fc6a 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -1238,8 +1238,8 @@ CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
                 if (pSttNode == pTxtFtn->GetStartNode()->GetNode().
                                     FindSttNodeByType(SwFootnoteStartNode))
                 {
-                    xParentText = SwXFootnote::CreateXFootnote(rDoc,
-                            const_cast<SwFmtFtn&>(rFtn));
+                    xParentText.set(SwXFootnote::CreateXFootnote(rDoc,
+                            const_cast<SwFmtFtn&>(rFtn)), uno::UNO_QUERY);
                     break;
                 }
             }
commit e54015d06f103e3ce9edc899f0d839ead88add8a
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 12:56:12 2014 +0200

    i#107771: sw: make SwXFootnote a client of its format poolitem
    
    In other words, stop registering at SwDoc's "UnoCallBack".
    
    Change-Id: Ie73c707b0f43559cc78717c0879d5e9a9335a7ac

diff --git a/sw/inc/fmtftn.hxx b/sw/inc/fmtftn.hxx
index 038b682..fdfaee5 100644
--- a/sw/inc/fmtftn.hxx
+++ b/sw/inc/fmtftn.hxx
@@ -21,14 +21,18 @@
 
 #include <rtl/ustring.hxx>
 #include <svl/poolitem.hxx>
+
 #include "swdllapi.h"
+#include <calbck.hxx>
 
 class SwDoc;
 class SwTxtFtn;
 
 // ATT_FTN
 
-class SW_DLLPUBLIC SwFmtFtn: public SfxPoolItem
+class SW_DLLPUBLIC SwFmtFtn
+    : public SfxPoolItem
+    , public SwModify
 {
     friend class SwTxtFtn;
     SwTxtFtn* m_pTxtAttr;   ///< My TextAttribute.
@@ -48,6 +52,8 @@ public:
     virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;
     virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 ) const SAL_OVERRIDE;
 
+    void InvalidateFootnote();
+
     OUString   GetNumStr() const { return m_aNumber; }
     sal_uInt16 GetNumber() const { return m_nNumber; }
     bool       IsEndNote() const { return m_bEndNote;}
diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index 3c5db6b..6877276 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -329,7 +329,6 @@ RES_MSG_BEGIN = RES_FMT_END,
     RES_SECTION_RESETHIDDENFLAG,
     RES_FINDNEARESTNODE,
     RES_CONTENT_VISIBLE,
-    RES_FOOTNOTE_DELETED,
     RES_GRAPHIC_SWAPIN,
     RES_NAME_CHANGED,
     RES_TITLE_CHANGED,
diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx
index 75d46e5..44d54c4 100644
--- a/sw/source/core/attr/calbck.cxx
+++ b/sw/source/core/attr/calbck.cxx
@@ -173,10 +173,6 @@ void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* p
             bLockClientList = ((SwPtrMsgPoolItem*)pOldValue)->pObject != this;
             break;
 
-        case RES_FOOTNOTE_DELETED:
-            bLockClientList = false;
-            break;
-
         default:
             bLockClientList = true;
         }
diff --git a/sw/source/core/doc/docftn.cxx b/sw/source/core/doc/docftn.cxx
index 258a336..8814552 100644
--- a/sw/source/core/doc/docftn.cxx
+++ b/sw/source/core/doc/docftn.cxx
@@ -437,8 +437,7 @@ bool SwDoc::SetCurFtn( const SwPaM& rPam, const OUString& rNumStr,
                     bTypeChgd = true;
                     pTxtFtn->CheckCondColl();
                     //#i11339# dispose UNO wrapper when a footnote is changed to an endnote or vice versa
-                    SwPtrMsgPoolItem aMsgHint( RES_FOOTNOTE_DELETED, (void*)&pTxtFtn->GetAttr() );
-                    GetUnoCallBack()->ModifyNotification( &aMsgHint, &aMsgHint );
+                    const_cast<SwFmtFtn&>(rFtn).InvalidateFootnote();
                 }
             }
         }
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index 19e7190..b654296 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -40,6 +40,7 @@
 #include <txtatr.hxx>
 #include <tox.hxx>
 #include <fmtrfmrk.hxx>
+#include <fmtftn.hxx>
 
 #include <docsh.hxx>
 #include <svl/smplhint.hxx>
@@ -296,7 +297,8 @@ void SwNodes::ChgNode( SwNodeIndex& rDelPos, sal_uLong nSz,
                                 break;
 
                             case RES_TXTATR_FTN:
-                                nDelMsg = RES_FOOTNOTE_DELETED;
+                                static_cast<SwFmtFtn&>(pAttr->GetAttr())
+                                    .InvalidateFootnote();
                                 break;
 
                             case RES_TXTATR_TOXMARK:
diff --git a/sw/source/core/inc/unofootnote.hxx b/sw/source/core/inc/unofootnote.hxx
index bc8d40b..2a7643b 100644
--- a/sw/source/core/inc/unofootnote.hxx
+++ b/sw/source/core/inc/unofootnote.hxx
@@ -66,14 +66,14 @@ protected:
 
     virtual ~SwXFootnote();
 
-    SwXFootnote(SwDoc & rDoc, const SwFmtFtn & rFmt);
+    SwXFootnote(SwDoc & rDoc, SwFmtFtn & rFmt);
 
 public:
 
     SwXFootnote(const bool bEndnote);
 
     static SwXFootnote *
-        CreateXFootnote(SwDoc & rDoc, SwFmtFtn const& rFootnoteFmt);
+        CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt);
     /// may return 0
     static SwXFootnote *
         GetXFootnote(SwModify const& rUnoCB, SwFmtFtn const& rFootnoteFmt);
diff --git a/sw/source/core/txtnode/atrftn.cxx b/sw/source/core/txtnode/atrftn.cxx
index f7f2aa5..9ada9df 100644
--- a/sw/source/core/txtnode/atrftn.cxx
+++ b/sw/source/core/txtnode/atrftn.cxx
@@ -17,12 +17,13 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <fmtftn.hxx>
+
 #include <doc.hxx>
 #include <DocumentContentOperationsManager.hxx>
 #include <IDocumentStylePoolAccess.hxx>
 #include <cntfrm.hxx>
 #include <pagefrm.hxx>
-#include <fmtftn.hxx>
 #include <txtftn.hxx>
 #include <ftnidx.hxx>
 #include <ftninfo.hxx>
@@ -115,10 +116,11 @@ namespace {
 }
 
 SwFmtFtn::SwFmtFtn( bool bEndNote )
-    : SfxPoolItem( RES_TXTATR_FTN ),
-    m_pTxtAttr( 0 ),
-    m_nNumber( 0 ),
-    m_bEndNote( bEndNote )
+    : SfxPoolItem( RES_TXTATR_FTN )
+    , SwModify(0)
+    , m_pTxtAttr(0)
+    , m_nNumber(0)
+    , m_bEndNote(bEndNote)
 {
 }
 
@@ -139,6 +141,13 @@ SfxPoolItem* SwFmtFtn::Clone( SfxItemPool* ) const
     return pNew;
 }
 
+void SwFmtFtn::InvalidateFootnote()
+{
+    SwPtrMsgPoolItem const item(RES_REMOVE_UNO_OBJECT,
+            &static_cast<SwModify&>(*this)); // cast to base class (void*)
+    NotifyClients(&item, &item);
+}
+
 void SwFmtFtn::SetEndNote( bool b )
 {
     if ( b != m_bEndNote )
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index 4d84c91..2ca92ba 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1133,7 +1133,7 @@ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr )
 
         case RES_TXTATR_FTN:
             ((SwTxtFtn*)pAttr)->SetStartNode( 0 );
-            nDelMsg = RES_FOOTNOTE_DELETED;
+            static_cast<SwFmtFtn&>(pAttr->GetAttr()).InvalidateFootnote();
             break;
 
         case RES_TXTATR_FIELD:
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 4f3a825..36fd4ba 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -1835,7 +1835,8 @@ uno::Any SwXFootnotes::getByIndex(sal_Int32 nIndex)
 
             if(nCount == nIndex)
             {
-                xRef = SwXFootnote::CreateXFootnote(*GetDoc(), rFtn);
+                xRef = SwXFootnote::CreateXFootnote(*GetDoc(),
+                        const_cast<SwFmtFtn&>(rFtn));
                 aRet <<= xRef;
                 break;
             }
@@ -1864,7 +1865,7 @@ sal_Bool SwXFootnotes::hasElements(void) throw( uno::RuntimeException, std::exce
 
 Reference<XFootnote>    SwXFootnotes::GetObject( SwDoc& rDoc, const SwFmtFtn& rFmt )
 {
-    return SwXFootnote::CreateXFootnote(rDoc, rFmt);
+    return SwXFootnote::CreateXFootnote(rDoc, const_cast<SwFmtFtn&>(rFmt));
 }
 
 OUString SwXReferenceMarks::getImplementationName(void) throw( RuntimeException, std::exception )
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index a80c496..6ea70b4 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -607,7 +607,8 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
                     if( pAny )
                     {
                         const uno::Reference< text::XFootnote > xFootnote =
-                            SwXFootnote::CreateXFootnote(*rPam.GetDoc(), rFtn);
+                            SwXFootnote::CreateXFootnote(*rPam.GetDoc(),
+                                    const_cast<SwFmtFtn&>(rFtn));
                         *pAny <<= xFootnote;
                     }
                 }
diff --git a/sw/source/core/unocore/unoftn.cxx b/sw/source/core/unocore/unoftn.cxx
index 1aab582..158e729 100644
--- a/sw/source/core/unocore/unoftn.cxx
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -57,9 +57,9 @@ public:
     OUString             m_sLabel;
 
     Impl(   SwXFootnote & rThis,
-            SwDoc *const pDoc, SwFmtFtn const*const pFootnote,
+            SwFmtFtn *const pFootnote,
             const bool bIsEndnote)
-        : SwClient((pDoc) ? pDoc->GetUnoCallBack() : 0)
+        : SwClient(pFootnote)
         , m_rThis(rThis)
         , m_bIsEndnote(bIsEndnote)
         , m_EventListeners(m_Mutex)
@@ -108,30 +108,17 @@ void SwXFootnote::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
     {
         Invalidate();
     }
-    else if (pOld)
-    {
-        switch (pOld->Which())
-        {
-            case RES_FOOTNOTE_DELETED:
-                if (static_cast<const void*>(m_pFmtFtn) ==
-                        static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject)
-                {
-                    Invalidate();
-                }
-                break;
-        }
-    }
 }
 
 SwXFootnote::SwXFootnote(const bool bEndnote)
     : SwXText(0, CURSOR_FOOTNOTE)
-    , m_pImpl( new SwXFootnote::Impl(*this, 0, 0, bEndnote) )
+    , m_pImpl( new SwXFootnote::Impl(*this, 0, bEndnote) )
 {
 }
 
-SwXFootnote::SwXFootnote(SwDoc & rDoc, const SwFmtFtn& rFmt)
+SwXFootnote::SwXFootnote(SwDoc & rDoc, SwFmtFtn & rFmt)
     : SwXText(& rDoc, CURSOR_FOOTNOTE)
-    , m_pImpl( new SwXFootnote::Impl(*this, &rDoc, &rFmt, rFmt.IsEndNote()) )
+    , m_pImpl( new SwXFootnote::Impl(*this, &rFmt, rFmt.IsEndNote()) )
 {
 }
 
@@ -152,10 +139,10 @@ SwXFootnote::GetXFootnote(
 }
 
 SwXFootnote *
-SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFmtFtn const& rFootnoteFmt)
+SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt)
 {
     SwXFootnote *const pXFootnote(
-        GetXFootnote(*rDoc.GetUnoCallBack(), rFootnoteFmt));
+        GetXFootnote(rFootnoteFmt, rFootnoteFmt));
     return (pXFootnote)
         ?   pXFootnote
         :   new SwXFootnote(rDoc, rFootnoteFmt);
@@ -335,7 +322,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
     {
         const SwFmtFtn& rFtn = pTxtAttr->GetFtn();
         m_pImpl->m_pFmtFtn = &rFtn;
-        pNewDoc->GetUnoCallBack()->Add(m_pImpl.get());
+        const_cast<SwFmtFtn*>(m_pImpl->m_pFmtFtn)->Add(m_pImpl.get());
         // force creation of sequence id - is used for references
         if (pNewDoc->IsInReading())
         {
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index f237680..e1b4615 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -1238,7 +1238,8 @@ CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
                 if (pSttNode == pTxtFtn->GetStartNode()->GetNode().
                                     FindSttNodeByType(SwFootnoteStartNode))
                 {
-                    xParentText = SwXFootnote::CreateXFootnote(rDoc, rFtn);
+                    xParentText = SwXFootnote::CreateXFootnote(rDoc,
+                            const_cast<SwFmtFtn&>(rFtn));
                     break;
                 }
             }
commit eee8b6eed6145f695d532aa62c33e3a0c44cba86
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 12:56:12 2014 +0200

    SwWrtShell::StartInputFldDlg() can be called with RES_SETEXPFLD too
    
    ... and there's no way to get the SwFmtFld from a SwSetExpField, so add
    a member for it like SwInputField has.  That's still better than the
    UnoCallBack nonsense.
    
    Change-Id: I59c82e95414dbae284432b8a318a6ce1a34256c7

diff --git a/sw/inc/expfld.hxx b/sw/inc/expfld.hxx
index 121125e..071967e 100644
--- a/sw/inc/expfld.hxx
+++ b/sw/inc/expfld.hxx
@@ -216,6 +216,7 @@ class SW_DLLPUBLIC SwSetExpField : public SwFormulaField
     bool            bInput;
     sal_uInt16          nSeqNo;
     sal_uInt16          nSubType;
+    SwFmtFld * mpFmtFld; /// pool item to which the SwSetExpField belongs
 
     virtual OUString            Expand() const SAL_OVERRIDE;
     virtual SwField*            Copy() const SAL_OVERRIDE;
@@ -223,6 +224,9 @@ class SW_DLLPUBLIC SwSetExpField : public SwFormulaField
 public:
     SwSetExpField(SwSetExpFieldType*, const OUString& rFormel, sal_uLong nFmt = 0);
 
+    void SetFmtFld(SwFmtFld & rFmtFld);
+    SwFmtFld* GetFmtFld() { return mpFmtFld;}
+
     virtual void                SetValue( const double& rVal ) SAL_OVERRIDE;
 
     inline OUString             GetExpStr() const;
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
index 8433e67..46c0620 100644
--- a/sw/source/core/fields/expfld.cxx
+++ b/sw/source/core/fields/expfld.cxx
@@ -765,6 +765,7 @@ SwSetExpField::SwSetExpField(SwSetExpFieldType* pTyp, const OUString& rFormel,
                                         sal_uLong nFmt)
     : SwFormulaField( pTyp, nFmt, 0.0 ), nSeqNo( USHRT_MAX ),
     nSubType(0)
+    , mpFmtFld(0)
 {
     SetFormula(rFormel);
     // ignore SubType
@@ -779,6 +780,11 @@ SwSetExpField::SwSetExpField(SwSetExpFieldType* pTyp, const OUString& rFormel,
     }
 }
 
+void SwSetExpField::SetFmtFld(SwFmtFld & rFmtFld)
+{
+    mpFmtFld = &rFmtFld;
+}
+
 OUString SwSetExpField::Expand() const
 {
     if (nSubType & nsSwExtendedSubType::SUB_CMD)
diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx
index 7b7dbac..327768f 100644
--- a/sw/source/core/txtnode/atrfld.cxx
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -64,6 +64,11 @@ SwFmtFld::SwFmtFld( const SwField &rFld )
         SetWhich( RES_TXTATR_INPUTFIELD );
         static_cast<SwInputField*>(GetField())->SetFmtFld( *this );
     }
+    else if (GetField()->GetTyp()->Which() == RES_SETEXPFLD)
+    {
+        // see SwWrtShell::StartInputFldDlg
+        static_cast<SwSetExpField *>(GetField())->SetFmtFld(*this);
+    }
     else if ( GetField()->GetTyp()->Which() == RES_POSTITFLD )
     {
         // text annotation field
@@ -95,6 +100,11 @@ SwFmtFld::SwFmtFld( const SwFmtFld& rAttr )
             if (pField)
                 pField->SetFmtFld( *this );
         }
+        else if (GetField()->GetTyp()->Which() == RES_SETEXPFLD)
+        {
+            // see SwWrtShell::StartInputFldDlg
+            static_cast<SwSetExpField *>(GetField())->SetFmtFld(*this);
+        }
         else if ( GetField()->GetTyp()->Which() == RES_POSTITFLD )
         {
             // text annotation field
@@ -156,6 +166,11 @@ void SwFmtFld::SetField(SwField * _pField)
     {
         static_cast<SwInputField* >(GetField())->SetFmtFld( *this );
     }
+    else if (GetField()->GetTyp()->Which() == RES_SETEXPFLD)
+    {
+        // see SwWrtShell::StartInputFldDlg
+        static_cast<SwSetExpField *>(GetField())->SetFmtFld(*this);
+    }
     Broadcast( SwFmtFldHint( this, SWFMTFLD_CHANGED ) );
 }
 
diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx
index 9777940..e6f000c 100644
--- a/sw/source/uibase/wrtsh/wrtsh2.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh2.cxx
@@ -210,11 +210,16 @@ bool SwWrtShell::StartInputFldDlg( SwField* pFld, bool bNextButton,
 
     FieldDeletionModify aModify(pDlg.get());
     SwInputField *const pInputField(dynamic_cast<SwInputField*>(pFld));
+    SwSetExpField *const pSetExpFld(dynamic_cast<SwSetExpField*>(pFld));
     if (pInputField)
     {
         // Register for possible input field deletion while dialog is open
         pInputField->GetFmtFld()->Add(&aModify);
     }
+    else if (pSetExpFld)
+    {
+        pSetExpFld->GetFmtFld()->Add(&aModify);
+    }
 
     bool bRet = RET_CANCEL == pDlg->Execute();
 
@@ -223,6 +228,10 @@ bool SwWrtShell::StartInputFldDlg( SwField* pFld, bool bNextButton,
         // Dialog closed, remove modification listener
         pInputField->GetFmtFld()->Remove(&aModify);
     }
+    else if (pSetExpFld)
+    {
+        pSetExpFld->GetFmtFld()->Remove(&aModify);
+    }
 
     if(pWindowState)
         *pWindowState = pDlg->GetWindowState();
commit bbd97fe57d9ec184ef6aee36bd57d6d7e53b4719
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 12:41:51 2014 +0200

    i#107771: sw: make SwXTextField a client of its format poolitem
    
    In other words, stop registering at SwDoc's "UnoCallBack"
    
    Change-Id: Ieb2639497fe5e8d71aa1c47952c007da76fcee84

diff --git a/sw/inc/fmtfld.hxx b/sw/inc/fmtfld.hxx
index 7ab3d68..6245f20 100644
--- a/sw/inc/fmtfld.hxx
+++ b/sw/inc/fmtfld.hxx
@@ -36,7 +36,10 @@ class SwView;
 class SwFieldType;
 
 // ATT_FLD
-class SW_DLLPUBLIC SwFmtFld : public SfxPoolItem, public SwClient, public SfxBroadcaster
+class SW_DLLPUBLIC SwFmtFld
+    : public SfxPoolItem
+    , public SwModify
+    , public SfxBroadcaster
 {
     friend void _InitCore();
     SwFmtFld( sal_uInt16 nWhich ); // for default-Attibute
@@ -71,6 +74,8 @@ public:
 
     virtual bool GetInfo( SfxPoolItem& rInfo ) const SAL_OVERRIDE;
 
+    void InvalidateField();
+
     const SwField* GetField() const
     {
         return mpField;
diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index 80408ce..3c5db6b 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -331,7 +331,6 @@ RES_MSG_BEGIN = RES_FMT_END,
     RES_CONTENT_VISIBLE,
     RES_FOOTNOTE_DELETED,
     RES_GRAPHIC_SWAPIN,
-    RES_FIELD_DELETED,
     RES_NAME_CHANGED,
     RES_TITLE_CHANGED,
     RES_DESCRIPTION_CHANGED,
diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx
index f664943..75d46e5 100644
--- a/sw/source/core/attr/calbck.cxx
+++ b/sw/source/core/attr/calbck.cxx
@@ -174,7 +174,6 @@ void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* p
             break;
 
         case RES_FOOTNOTE_DELETED:
-        case RES_FIELD_DELETED:
             bLockClientList = false;
             break;
 
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index 3dc6ff6..19e7190 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -290,7 +290,8 @@ void SwNodes::ChgNode( SwNodeIndex& rDelPos, sal_uLong nSz,
                                         else
                                             ((SwDDEFieldType*)pTyp)->IncRefCnt();
                                     }
-                                    nDelMsg = RES_FIELD_DELETED;
+                                    static_cast<SwFmtFld&>(pAttr->GetAttr())
+                                        .InvalidateField();
                                 }
                                 break;
 
diff --git a/sw/source/core/inc/unofield.hxx b/sw/source/core/inc/unofield.hxx
index 90b6594..c3e0088 100644
--- a/sw/source/core/inc/unofield.hxx
+++ b/sw/source/core/inc/unofield.hxx
@@ -169,7 +169,7 @@ private:
 
     virtual ~SwXTextField();
 
-    SwXTextField(const SwFmtFld& rFmt, SwDoc & rDoc);
+    SwXTextField(SwFmtFld& rFmt, SwDoc & rDoc);
 
     /// descriptor
     SwXTextField(sal_uInt16 nServiceId, SwDoc* pDoc=0);
diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx
index 3e06ec9..7b7dbac 100644
--- a/sw/source/core/txtnode/atrfld.cxx
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -38,13 +38,13 @@
 #include <fieldhint.hxx>
 #include <svl/smplhint.hxx>
 
-TYPEINIT3( SwFmtFld, SfxPoolItem, SwClient,SfxBroadcaster)
+TYPEINIT3(SwFmtFld, SfxPoolItem, SwModify, SfxBroadcaster)
 TYPEINIT1(SwFmtFldHint, SfxHint);
 
 // constructor for default item in attribute-pool
 SwFmtFld::SwFmtFld( sal_uInt16 nWhich )
     : SfxPoolItem( nWhich )
-    , SwClient()
+    , SwModify(0)
     , SfxBroadcaster()
     , mpField( NULL )
     , mpTxtFld( NULL )
@@ -53,7 +53,7 @@ SwFmtFld::SwFmtFld( sal_uInt16 nWhich )
 
 SwFmtFld::SwFmtFld( const SwField &rFld )
     : SfxPoolItem( RES_TXTATR_FIELD )
-    , SwClient( rFld.GetTyp() )
+    , SwModify( rFld.GetTyp() )
     , SfxBroadcaster()
     , mpField( rFld.CopyField() )
     , mpTxtFld( NULL )
@@ -77,7 +77,7 @@ SwFmtFld::SwFmtFld( const SwField &rFld )
 // corrected
 SwFmtFld::SwFmtFld( const SwFmtFld& rAttr )
     : SfxPoolItem( RES_TXTATR_FIELD )
-    , SwClient()
+    , SwModify(0)
     , SfxBroadcaster()
     , mpField( NULL )
     , mpTxtFld( NULL )
@@ -183,6 +183,13 @@ SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const
     return new SwFmtFld( *this );
 }
 
+void SwFmtFld::InvalidateField()
+{
+    SwPtrMsgPoolItem const item(RES_REMOVE_UNO_OBJECT,
+            &static_cast<SwModify&>(*this)); // cast to base class (void*)
+    NotifyClients(&item, &item);
+}
+
 void SwFmtFld::SwClientNotify( const SwModify&, const SfxHint& rHint )
 {
     if( !mpTxtFld )
@@ -208,6 +215,14 @@ void SwFmtFld::SwClientNotify( const SwModify&, const SfxHint& rHint )
 
 void SwFmtFld::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
 {
+    if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
+    {   // invalidate cached UNO object
+        SetXTextField(css::uno::Reference<css::text::XTextField>(0));
+        // ??? why does this Modify method not already do this?
+        NotifyClients(pOld, pNew);
+        return;
+    }
+
     if( !mpTxtFld )
         return;
 
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index d98790a..4d84c91 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1178,7 +1178,7 @@ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr )
                     }
                 }
             }
-            nDelMsg = RES_FIELD_DELETED;
+            static_cast<SwFmtFld&>(pAttr->GetAttr()).InvalidateField();
             break;
 
         case RES_TXTATR_TOXMARK:
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index 5ae7deb..566381e 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1152,9 +1152,9 @@ public:
     OUString            m_sTypeName;
     boost::scoped_ptr<SwFieldProperties_Impl> m_pProps;
 
-    Impl(SwDoc *const pDoc, SwFmtFld const*const pFmt,
+    Impl(SwDoc *const pDoc, SwFmtFld *const pFmt,
             sal_uInt16 const nServiceId)
-        : SwClient((pFmt) ? pDoc->GetUnoCallBack() : 0)
+        : SwClient(pFmt)
         , m_EventListeners(m_Mutex)
         , m_pFmtFld(pFmt)
         , m_pDoc(pDoc)
@@ -1225,9 +1225,7 @@ SwXTextField::SwXTextField(
     }
 }
 
-SwXTextField::SwXTextField(
-    const SwFmtFld& rFmt,
-    SwDoc & rDoc)
+SwXTextField::SwXTextField(SwFmtFld& rFmt, SwDoc & rDoc)
     : m_pImpl(new Impl(&rDoc, &rFmt, USHRT_MAX))
 {
 }
@@ -1251,7 +1249,7 @@ SwXTextField::CreateXTextField(SwDoc *const pDoc, SwFmtFld const* pFmt,
     if (!xField.is())
     {
         SwXTextField *const pField( (pFmt)
-                ? new SwXTextField(*pFmt, *pDoc)
+                ? new SwXTextField(const_cast<SwFmtFld&>(*pFmt), *pDoc)
                 : new SwXTextField(nServiceId, pDoc));
         xField.set(pField);
         if (pFmt)
@@ -1995,7 +1993,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
 
     assert(m_pImpl->m_pFmtFld);
     m_pImpl->m_pDoc = pDoc;
-    m_pImpl->m_pDoc->GetUnoCallBack()->Add(m_pImpl.get());
+    const_cast<SwFmtFld *>(m_pImpl->m_pFmtFld)->Add(m_pImpl.get());
     m_pImpl->m_bIsDescriptor = false;
     if (m_pImpl->m_FieldTypeClient.GetRegisteredIn())
     {
@@ -2649,10 +2647,6 @@ void SwXTextField::Impl::Modify(
             ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() )
             Invalidate();
         break;
-    case RES_FIELD_DELETED:
-        if ((void*)m_pFmtFld == ((SwPtrMsgPoolItem *)pOld)->pObject)
-            Invalidate();
-        break;
     }
 }
 
diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx
index 4ea08d5..9777940 100644
--- a/sw/source/uibase/wrtsh/wrtsh2.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh2.cxx
@@ -43,6 +43,7 @@
 #include <IDocumentUndoRedo.hxx>
 #include <viewopt.hxx>
 #include <frmfmt.hxx>
+#include <fmtfld.hxx>
 #include <swtable.hxx>
 #include <mdiexp.hxx>
 #include <view.hxx>
@@ -178,10 +179,16 @@ class FieldDeletionModify : public SwModify
 
         void Modify( const SfxPoolItem* pOld, const SfxPoolItem *) SAL_OVERRIDE
         {
-            // Input fields have been deleted: better to close the dialog
-            if (pOld->Which() == RES_FIELD_DELETED)
+            // Input field has been deleted: better to close the dialog
+            if (pOld)
             {
-                mpInputFieldDlg->EndDialog(RET_CANCEL);
+                switch (pOld->Which())
+                {
+                case RES_REMOVE_UNO_OBJECT:
+                case RES_OBJECTDYING:
+                    mpInputFieldDlg->EndDialog(RET_CANCEL);
+                    break;
+                }
             }
         }
     private:
@@ -201,14 +208,21 @@ bool SwWrtShell::StartInputFldDlg( SwField* pFld, bool bNextButton,
     if(pWindowState && !pWindowState->isEmpty())
         pDlg->SetWindowState(*pWindowState);
 
-    // Register for possible input field deletion while dialog is open
     FieldDeletionModify aModify(pDlg.get());
-    GetDoc()->GetUnoCallBack()->Add(&aModify);
+    SwInputField *const pInputField(dynamic_cast<SwInputField*>(pFld));
+    if (pInputField)
+    {
+        // Register for possible input field deletion while dialog is open
+        pInputField->GetFmtFld()->Add(&aModify);
+    }
 
     bool bRet = RET_CANCEL == pDlg->Execute();
 
-    // Dialog closed, remove modification listener
-    GetDoc()->GetUnoCallBack()->Remove(&aModify);
+    if (pInputField)
+    {
+        // Dialog closed, remove modification listener
+        pInputField->GetFmtFld()->Remove(&aModify);
+    }
 
     if(pWindowState)
         *pWindowState = pDlg->GetWindowState();
commit b8a28f81ecfabbbac7992f120aeedc7b36dfcbf8
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 00:16:32 2014 +0200

    better error handing in SwXTextField::attach()
    
    Change-Id: I4b8b4ef1f34ba5662bd56bfbb335b87fb5aa4b51

diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index c271a82..5ae7deb 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1933,6 +1933,8 @@ throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
         break;
         default: OSL_FAIL("was ist das fuer ein Typ?");
     }
+    if (!pFld)
+        throw uno::RuntimeException("no SwField created?");
     if (pFld)
     {
         pFld->SetAutomaticLanguage(!m_pImpl->m_pProps->bBool4);
@@ -1986,9 +1988,12 @@ throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
                 }
             }
         }
+        else // could theoretically happen, if paragraph is full
+            throw uno::RuntimeException("no SwTxtAttr inserted?");
     }
     delete pFld;
 
+    assert(m_pImpl->m_pFmtFld);
     m_pImpl->m_pDoc = pDoc;
     m_pImpl->m_pDoc->GetUnoCallBack()->Add(m_pImpl.get());
     m_pImpl->m_bIsDescriptor = false;
commit eb09b803aa578d11b61ec9052ceccd0d9270ff68
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Aug 19 23:37:21 2014 +0200

    fdo#72695: avoid double-free race condition for SwXReferenceMark
    
    Change-Id: I66a988f17adebba72a71af5b770abbebfa4e12b2

diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx
index 10f0a06..9861801 100644
--- a/sw/source/core/unocore/unorefmk.cxx
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -43,19 +43,17 @@ class SwXReferenceMark::Impl
 {
 private:
     ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper
-    SwXReferenceMark & m_rThis;
 
 public:
+    uno::WeakReference<uno::XInterface> m_wThis;
     ::cppu::OInterfaceContainerHelper m_EventListeners;
     bool                        m_bIsDescriptor;
     SwDoc *                     m_pDoc;
     const SwFmtRefMark *        m_pMarkFmt;
     OUString             m_sMarkName;
 
-    Impl(   SwXReferenceMark & rThis,
-            SwDoc *const pDoc, SwFmtRefMark *const pRefMark)
+    Impl(   SwDoc *const pDoc, SwFmtRefMark *const pRefMark)
         : SwClient(pRefMark)
-        , m_rThis(rThis)
         , m_EventListeners(m_Mutex)
         , m_bIsDescriptor(0 == pRefMark)
         , m_pDoc(pDoc)
@@ -84,7 +82,12 @@ void SwXReferenceMark::Impl::Invalidate()
     }
     m_pDoc = 0;
     m_pMarkFmt = 0;
-    lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis));
+    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);
 }
 
@@ -100,7 +103,7 @@ void SwXReferenceMark::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem
 
 SwXReferenceMark::SwXReferenceMark(
         SwDoc *const pDoc, SwFmtRefMark *const pRefMark)
-    : m_pImpl( new SwXReferenceMark::Impl(*this, pDoc, pRefMark) )
+    : m_pImpl( new SwXReferenceMark::Impl(pDoc, pRefMark) )
 {
 }
 
@@ -126,6 +129,8 @@ SwXReferenceMark::CreateXReferenceMark(
         {
             pMarkFmt->SetXRefMark(xMark);
         }
+        // need a permanent Reference to initialize m_wThis
+        pMark->m_pImpl->m_wThis = xMark;
     }
     return xMark;
 }
commit 14eb485c5c62a4f745b24a3798f313623f283e55
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Aug 19 23:29:32 2014 +0200

    i#107771: sw: implement thread-safe instance caching for SwXReferenceMark
    
    Change-Id: I4f3b6789dde053ca913e12233b20d45dfe50c7ec

diff --git a/sw/inc/fmtrfmrk.hxx b/sw/inc/fmtrfmrk.hxx
index d8e807d..4825699 100644
--- a/sw/inc/fmtrfmrk.hxx
+++ b/sw/inc/fmtrfmrk.hxx
@@ -20,10 +20,15 @@
 #define INCLUDED_SW_INC_FMTRFMRK_HXX
 
 #include <rtl/ustring.hxx>
+#include <cppuhelper/weakref.hxx>
 #include <svl/poolitem.hxx>
 
 #include <calbck.hxx>
 
+namespace com { namespace sun { namespace star {
+    namespace text { class XTextContent; }
+} } }
+
 class SwTxtRefMark;
 
 // ATT_REFMARK
@@ -39,6 +44,8 @@ class SwFmtRefMark
     SwFmtRefMark& operator=(const SwFmtRefMark& rRefMark);
     OUString aRefName;
 
+    css::uno::WeakReference<css::text::XTextContent> m_wXReferenceMark;
+
 public:
     SwFmtRefMark( const OUString& rTxt );
     SwFmtRefMark( const SwFmtRefMark& rRefMark );
@@ -48,6 +55,10 @@ public:
     virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;
     virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 ) const SAL_OVERRIDE;
 
+    // SwClient
+    virtual void Modify(SfxPoolItem const* pOld, SfxPoolItem const* pNew)
+        SAL_OVERRIDE;
+
     void InvalidateRefMark();
 
     const SwTxtRefMark *GetTxtRefMark() const   { return pTxtAttr; }
@@ -55,6 +66,11 @@ public:
 
     inline       OUString &GetRefName()       { return aRefName; }
     inline const OUString &GetRefName() const { return aRefName; }
+
+    css::uno::WeakReference<css::text::XTextContent> const& GetXRefMark() const
+        { return m_wXReferenceMark; }
+    void SetXRefMark(css::uno::Reference<css::text::XTextContent> const& xMark)
+        { m_wXReferenceMark = xMark; }
 };
 
 #endif
diff --git a/sw/inc/unocoll.hxx b/sw/inc/unocoll.hxx
index eb55c81..d5c97bb 100644
--- a/sw/inc/unocoll.hxx
+++ b/sw/inc/unocoll.hxx
@@ -521,7 +521,6 @@ public:
     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
 
-    static SwXReferenceMark* GetObject( SwDoc* pDoc, const SwFmtRefMark* pMark );
 };
 
 #endif
diff --git a/sw/source/core/inc/unorefmark.hxx b/sw/source/core/inc/unorefmark.hxx
index 78dac4b..73d8d41 100644
--- a/sw/source/core/inc/unorefmark.hxx
+++ b/sw/source/core/inc/unorefmark.hxx
@@ -53,15 +53,12 @@ private:
 
     virtual ~SwXReferenceMark();
 
-public:
-
     SwXReferenceMark(SwDoc *const pDoc, SwFmtRefMark *const pMark);
 
-    static SwXReferenceMark *
-        CreateXReferenceMark(SwDoc & rDoc, SwFmtRefMark & rMarkFmt);
-    /// may return 0
-    static SwXReferenceMark *
-        GetReferenceMark(SwModify const& rUnoCB, SwFmtRefMark const& rMarkFmt);
+public:
+
+    static css::uno::Reference<css::text::XTextContent>
+        CreateXReferenceMark(SwDoc & rDoc, SwFmtRefMark * pMarkFmt);
 
     static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId();
 
diff --git a/sw/source/core/txtnode/atrref.cxx b/sw/source/core/txtnode/atrref.cxx
index 1b9fe63..35f338b 100644
--- a/sw/source/core/txtnode/atrref.cxx
+++ b/sw/source/core/txtnode/atrref.cxx
@@ -55,6 +55,15 @@ SfxPoolItem* SwFmtRefMark::Clone( SfxItemPool* ) const
     return new SwFmtRefMark( *this );
 }
 
+void SwFmtRefMark::Modify(SfxPoolItem const* pOld, SfxPoolItem const* pNew)
+{
+    NotifyClients(pOld, pNew);
+    if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
+    {   // invalidate cached UNO object
+        SetXRefMark(css::uno::Reference<css::text::XTextContent>(0));
+    }
+}
+
 void SwFmtRefMark::InvalidateRefMark()
 {
     SwPtrMsgPoolItem const item(RES_REMOVE_UNO_OBJECT,
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index d954097..4f3a825 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -669,7 +669,7 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
 
         break;
         case SW_SERVICE_REFERENCE_MARK :
-            xRet =  (cppu::OWeakObject*)new SwXReferenceMark(0, 0);
+            xRet = SwXReferenceMark::CreateXReferenceMark(*pDoc, 0);
         break;
         case SW_SERVICE_STYLE_CHARACTER_STYLE:
         case SW_SERVICE_STYLE_PARAGRAPH_STYLE:
@@ -1912,10 +1912,11 @@ uno::Any SwXReferenceMarks::getByIndex(sal_Int32 nIndex)
     uno::Reference< XTextContent >  xRef;
     if(0 <= nIndex && nIndex < USHRT_MAX)
     {
-        const SwFmtRefMark* pMark = GetDoc()->GetRefMark( (sal_uInt16) nIndex );
+        SwFmtRefMark *const pMark = const_cast<SwFmtRefMark*>(
+                GetDoc()->GetRefMark(static_cast<sal_uInt16>(nIndex)));
         if(pMark)
         {
-            xRef = SwXReferenceMarks::GetObject( GetDoc(), pMark );
+            xRef = SwXReferenceMark::CreateXReferenceMark(*GetDoc(), pMark);
             aRet.setValue(&xRef, cppu::UnoType<XTextContent>::get());
         }
     }
@@ -1931,10 +1932,12 @@ uno::Any SwXReferenceMarks::getByName(const OUString& rName)
     uno::Any aRet;
     if(IsValid())
     {
-        const SwFmtRefMark* pMark = GetDoc()->GetRefMark(rName);
+        SwFmtRefMark *const pMark =
+            const_cast<SwFmtRefMark*>(GetDoc()->GetRefMark(rName));
         if(pMark)
         {
-            uno::Reference< XTextContent >  xRef = SwXReferenceMarks::GetObject( GetDoc(), pMark );
+            uno::Reference<XTextContent> const xRef =
+                SwXReferenceMark::CreateXReferenceMark(*GetDoc(), pMark);
             aRet.setValue(&xRef, cppu::UnoType<XTextContent>::get());
         }
         else
@@ -1984,12 +1987,6 @@ sal_Bool SwXReferenceMarks::hasElements(void) throw( uno::RuntimeException, std:
     return 0 != GetDoc()->GetRefMarks();
 }
 
-SwXReferenceMark* SwXReferenceMarks::GetObject( SwDoc* pDoc, const SwFmtRefMark* pMark )
-{
-    return SwXReferenceMark::CreateXReferenceMark(
-                *pDoc, *const_cast<SwFmtRefMark*>(pMark));
-}
-
 void SwUnoCollection::Invalidate()
 {
     bObjectValid = false;
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index 7161059..a80c496 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -632,7 +632,9 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
                 if( pAny )
                 {   // hmm... can only return 1 here
                     const SwFmtRefMark& rRef = (*marks.begin())->GetRefMark();
-                    uno::Reference< XTextContent >  xRef = SwXReferenceMarks::GetObject( rPam.GetDoc(), &rRef );
+                    uno::Reference<XTextContent> const xRef =
+                        SwXReferenceMark::CreateXReferenceMark(*rPam.GetDoc(),
+                                const_cast<SwFmtRefMark*>(&rRef));
                     pAny->setValue(&xRef, cppu::UnoType<XTextContent>::get());
                 }
             }
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 3b5cba4..5e02a02 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -496,7 +496,7 @@ lcl_CreateRefMarkPortion(
     Reference<XTextContent> xContent;
     if (!xContent.is())
     {
-        xContent = new SwXReferenceMark(pDoc, &rRefMark);
+        xContent = SwXReferenceMark::CreateXReferenceMark(*pDoc, &rRefMark);
     }
 
     SwXTextPortion* pPortion = 0;
diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx
index abcb746..10f0a06 100644
--- a/sw/source/core/unocore/unorefmk.cxx
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -108,25 +108,26 @@ SwXReferenceMark::~SwXReferenceMark()
 {
 }
 
-SwXReferenceMark *
-SwXReferenceMark::GetReferenceMark(
-        SwModify const& /*rUnoCB*/, SwFmtRefMark const& /*rMarkFmt*/)
-{
-    // #i105557#: do not iterate over the registered clients: race condition
-    // to do this properly requires the SwXReferenceMark to register at the
-    // SwFmtRefMark directly, not at the unocallback
-    return 0;
-}
-
-SwXReferenceMark *
+uno::Reference<text::XTextContent>
 SwXReferenceMark::CreateXReferenceMark(
-        SwDoc & rDoc, SwFmtRefMark & rMarkFmt)
+        SwDoc & rDoc, SwFmtRefMark *const pMarkFmt)
 {
-    SwXReferenceMark *const pXMark(
-        GetReferenceMark(rMarkFmt, rMarkFmt) );
-    return (pXMark)
-        ?   pXMark
-        :   new SwXReferenceMark(&rDoc, &rMarkFmt);
+    // i#105557: do not iterate over the registered clients: race condition
+    uno::Reference<text::XTextContent> xMark;
+    if (pMarkFmt)
+    {
+        xMark = pMarkFmt->GetXRefMark();
+    }
+    if (!xMark.is())
+    {
+        SwXReferenceMark *const pMark(new SwXReferenceMark(&rDoc, pMarkFmt));
+        xMark.set(pMark);
+        if (pMarkFmt)
+        {
+            pMarkFmt->SetXRefMark(xMark);
+        }
+    }
+    return xMark;
 }
 
 namespace
commit 1e28d7901dbebf77f75e5770d11a49fef036976c
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Aug 19 22:57:46 2014 +0200

    SwXReferenceMarks::GetObject() has no need for a mutex guard
    
    Change-Id: Icc6b0eebf57b07f06bccc9a57036f0611a67c4a3

diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 5081022..d954097 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -1986,8 +1986,6 @@ sal_Bool SwXReferenceMarks::hasElements(void) throw( uno::RuntimeException, std:
 
 SwXReferenceMark* SwXReferenceMarks::GetObject( SwDoc* pDoc, const SwFmtRefMark* pMark )
 {
-    SolarMutexGuard aGuard;
-
     return SwXReferenceMark::CreateXReferenceMark(
                 *pDoc, *const_cast<SwFmtRefMark*>(pMark));
 }
commit e7c96f3e8f2c2f6bf31ec21fe0d1fbaecb07c3f9
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Aug 19 22:54:57 2014 +0200

    i#107771: sw: make SwXReferenceMark a client of its format poolitem
    
    In other words, stop registering at SwDoc's "UnoCallBack"
    
    Change-Id: I9e08966cf8e2d2a373867d81549c8887f73993c8

diff --git a/sw/inc/fmtrfmrk.hxx b/sw/inc/fmtrfmrk.hxx
index 88e7861..d8e807d 100644
--- a/sw/inc/fmtrfmrk.hxx
+++ b/sw/inc/fmtrfmrk.hxx
@@ -22,11 +22,15 @@
 #include <rtl/ustring.hxx>
 #include <svl/poolitem.hxx>
 
+#include <calbck.hxx>
+
 class SwTxtRefMark;
 
 // ATT_REFMARK
 
-class SwFmtRefMark : public SfxPoolItem
+class SwFmtRefMark
+    : public SfxPoolItem
+    , public SwModify
 {
     friend class SwTxtRefMark;
     SwTxtRefMark* pTxtAttr;
@@ -44,6 +48,8 @@ public:
     virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;
     virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 ) const SAL_OVERRIDE;
 
+    void InvalidateRefMark();
+
     const SwTxtRefMark *GetTxtRefMark() const   { return pTxtAttr; }
     SwTxtRefMark *GetTxtRefMark()               { return pTxtAttr; }
 
diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index 8ca47b7..80408ce 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -330,7 +330,6 @@ RES_MSG_BEGIN = RES_FMT_END,
     RES_FINDNEARESTNODE,
     RES_CONTENT_VISIBLE,
     RES_FOOTNOTE_DELETED,
-    RES_REFMARK_DELETED,
     RES_GRAPHIC_SWAPIN,
     RES_FIELD_DELETED,
     RES_NAME_CHANGED,
diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx
index 0d3a5ba..f664943 100644
--- a/sw/source/core/attr/calbck.cxx
+++ b/sw/source/core/attr/calbck.cxx
@@ -174,7 +174,6 @@ void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* p
             break;
 
         case RES_FOOTNOTE_DELETED:
-        case RES_REFMARK_DELETED:
         case RES_FIELD_DELETED:
             bLockClientList = false;
             break;
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index 9806cba..3dc6ff6 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -39,6 +39,7 @@
 #include <frame.hxx>
 #include <txtatr.hxx>
 #include <tox.hxx>
+#include <fmtrfmrk.hxx>
 
 #include <docsh.hxx>
 #include <svl/smplhint.hxx>
@@ -303,7 +304,8 @@ void SwNodes::ChgNode( SwNodeIndex& rDelPos, sal_uLong nSz,
                                 break;
 
                             case RES_TXTATR_REFMARK:
-                                nDelMsg = RES_REFMARK_DELETED;
+                                static_cast<SwFmtRefMark&>(pAttr->GetAttr())
+                                    .InvalidateRefMark();
                                 break;
 
                             case RES_TXTATR_META:
diff --git a/sw/source/core/inc/unorefmark.hxx b/sw/source/core/inc/unorefmark.hxx
index 75db5ee..78dac4b 100644
--- a/sw/source/core/inc/unorefmark.hxx
+++ b/sw/source/core/inc/unorefmark.hxx
@@ -55,10 +55,10 @@ private:
 
 public:
 
-    SwXReferenceMark(SwDoc *const pDoc, const SwFmtRefMark *const pMark);
+    SwXReferenceMark(SwDoc *const pDoc, SwFmtRefMark *const pMark);
 
     static SwXReferenceMark *
-        CreateXReferenceMark(SwDoc & rDoc, SwFmtRefMark const& rMarkFmt);
+        CreateXReferenceMark(SwDoc & rDoc, SwFmtRefMark & rMarkFmt);
     /// may return 0
     static SwXReferenceMark *
         GetReferenceMark(SwModify const& rUnoCB, SwFmtRefMark const& rMarkFmt);
diff --git a/sw/source/core/txtnode/atrref.cxx b/sw/source/core/txtnode/atrref.cxx
index 8628b1b..1b9fe63 100644
--- a/sw/source/core/txtnode/atrref.cxx
+++ b/sw/source/core/txtnode/atrref.cxx
@@ -17,9 +17,11 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <fmtrfmrk.hxx>
+
 #include <hintids.hxx>
+#include <hints.hxx>
 #include <txtrfmrk.hxx>
-#include <fmtrfmrk.hxx>
 #include <swfont.hxx>
 
 SwFmtRefMark::~SwFmtRefMark( )
@@ -27,16 +29,18 @@ SwFmtRefMark::~SwFmtRefMark( )
 }
 
 SwFmtRefMark::SwFmtRefMark( const OUString& rName )
-    : SfxPoolItem( RES_TXTATR_REFMARK ),
-    pTxtAttr( 0 ),
-    aRefName( rName )
+    : SfxPoolItem(RES_TXTATR_REFMARK)
+    , SwModify(0)
+    , pTxtAttr(0)
+    , aRefName(rName)
 {
 }
 
 SwFmtRefMark::SwFmtRefMark( const SwFmtRefMark& rAttr )
-    : SfxPoolItem( RES_TXTATR_REFMARK ),
-    pTxtAttr( 0 ),
-    aRefName( rAttr.aRefName )
+    : SfxPoolItem(RES_TXTATR_REFMARK)
+    , SwModify(0)
+    , pTxtAttr(0)
+    , aRefName(rAttr.aRefName)
 {
 }
 
@@ -51,6 +55,13 @@ SfxPoolItem* SwFmtRefMark::Clone( SfxItemPool* ) const
     return new SwFmtRefMark( *this );
 }
 
+void SwFmtRefMark::InvalidateRefMark()
+{
+    SwPtrMsgPoolItem const item(RES_REMOVE_UNO_OBJECT,
+            &static_cast<SwModify&>(*this)); // cast to base class (void*)
+    NotifyClients(&item, &item);
+}
+
 // Attribut fuer Inhalts-/Positions-Referenzen im Text
 
 SwTxtRefMark::SwTxtRefMark( SwFmtRefMark& rAttr,
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index 4b327f7..d98790a 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -32,6 +32,7 @@
 #include <txtinet.hxx>
 #include <txtflcnt.hxx>
 #include <fmtfld.hxx>
+#include <fmtrfmrk.hxx>
 #include <fmtanchr.hxx>
 #include <fmtinfmt.hxx>
 #include <txtatr.hxx>
@@ -1185,7 +1186,7 @@ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr )
             break;
 
         case RES_TXTATR_REFMARK:
-            nDelMsg = RES_REFMARK_DELETED;
+            static_cast<SwFmtRefMark&>(pAttr->GetAttr()).InvalidateRefMark();
             break;
 
         case RES_TXTATR_META:
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 584293d..5081022 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -1988,7 +1988,8 @@ SwXReferenceMark* SwXReferenceMarks::GetObject( SwDoc* pDoc, const SwFmtRefMark*
 {
     SolarMutexGuard aGuard;
 
-    return SwXReferenceMark::CreateXReferenceMark(*pDoc, *pMark);
+    return SwXReferenceMark::CreateXReferenceMark(
+                *pDoc, *const_cast<SwFmtRefMark*>(pMark));
 }
 
 void SwUnoCollection::Invalidate()
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index e021622..3b5cba4 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -491,8 +491,8 @@ lcl_CreateRefMarkPortion(
     const SwTxtAttr & rAttr, const bool bEnd)
 {
     SwDoc* pDoc = pUnoCrsr->GetDoc();
-    const SwFmtRefMark& rRefMark =
-        static_cast<const SwFmtRefMark&>(rAttr.GetAttr());
+    SwFmtRefMark& rRefMark = const_cast<SwFmtRefMark&>(
+            static_cast<const SwFmtRefMark&>(rAttr.GetAttr()));
     Reference<XTextContent> xContent;
     if (!xContent.is())
     {
diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx
index 5817d90..abcb746 100644
--- a/sw/source/core/unocore/unorefmk.cxx
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -53,8 +53,8 @@ public:
     OUString             m_sMarkName;
 
     Impl(   SwXReferenceMark & rThis,
-            SwDoc *const pDoc, SwFmtRefMark const*const pRefMark)
-        : SwClient((pDoc) ? pDoc->GetUnoCallBack() : 0)
+            SwDoc *const pDoc, SwFmtRefMark *const pRefMark)
+        : SwClient(pRefMark)
         , m_rThis(rThis)
         , m_EventListeners(m_Mutex)
         , m_bIsDescriptor(0 == pRefMark)
@@ -96,23 +96,10 @@ void SwXReferenceMark::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem
     {
         Invalidate();
     }
-    else if (pOld)
-    {
-        switch (pOld->Which())
-        {
-            case RES_REFMARK_DELETED:
-                if (static_cast<const void*>(m_pMarkFmt) ==
-                        static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject)
-                {
-                    Invalidate();
-                }
-                break;
-        }
-    }
 }
 
 SwXReferenceMark::SwXReferenceMark(
-        SwDoc *const pDoc, SwFmtRefMark const*const pRefMark)
+        SwDoc *const pDoc, SwFmtRefMark *const pRefMark)
     : m_pImpl( new SwXReferenceMark::Impl(*this, pDoc, pRefMark) )
 {
 }
@@ -133,10 +120,10 @@ SwXReferenceMark::GetReferenceMark(
 
 SwXReferenceMark *
 SwXReferenceMark::CreateXReferenceMark(
-        SwDoc & rDoc, SwFmtRefMark const& rMarkFmt)
+        SwDoc & rDoc, SwFmtRefMark & rMarkFmt)
 {
     SwXReferenceMark *const pXMark(
-        GetReferenceMark(*rDoc.GetUnoCallBack(), rMarkFmt) );
+        GetReferenceMark(rMarkFmt, rMarkFmt) );
     return (pXMark)
         ?   pXMark
         :   new SwXReferenceMark(&rDoc, &rMarkFmt);
@@ -266,7 +253,7 @@ void SwXReferenceMark::Impl::InsertRefMark(SwPaM& rPam,
 
     m_pMarkFmt = &pTxtAttr->GetRefMark();
 
-    pDoc2->GetUnoCallBack()->Add(this);
+    const_cast<SwFmtRefMark*>(m_pMarkFmt)->Add(this);
 }
 
 void SAL_CALL
commit b684cd4b071be9b26dd35e3104450135ffbfea98
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Aug 19 22:07:01 2014 +0200

    sw: RES_TOXMARK_DELETED is unused since swunolocking1
    
    Change-Id: I98b21573ebbc8543609bd63eee30bc5b4cbdfb2c

diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index 4e48193..8ca47b7 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -331,7 +331,6 @@ RES_MSG_BEGIN = RES_FMT_END,
     RES_CONTENT_VISIBLE,
     RES_FOOTNOTE_DELETED,
     RES_REFMARK_DELETED,
-    RES_TOXMARK_DELETED,
     RES_GRAPHIC_SWAPIN,
     RES_FIELD_DELETED,
     RES_NAME_CHANGED,
diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx
index be678fe..0d3a5ba 100644
--- a/sw/source/core/attr/calbck.cxx
+++ b/sw/source/core/attr/calbck.cxx
@@ -175,7 +175,6 @@ void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* p
 
         case RES_FOOTNOTE_DELETED:
         case RES_REFMARK_DELETED:
-        case RES_TOXMARK_DELETED:
         case RES_FIELD_DELETED:
             bLockClientList = false;
             break;
commit c5390b3ee9d04a22817335208d8db673c4463a95
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Aug 18 23:03:35 2014 +0200

    SwXDocumentIndexMark::CreateXDocumentIndexMark does not need SwTOXType
    
    ... passed in as parameter since it's always the one from pMark.
    
    Change-Id: Ia5981b0f281c8cac70cbb305c82bb6785918168a

diff --git a/sw/source/core/inc/unoidx.hxx b/sw/source/core/inc/unoidx.hxx
index 246bd9c..4dfcc24 100644
--- a/sw/source/core/inc/unoidx.hxx
+++ b/sw/source/core/inc/unoidx.hxx
@@ -222,7 +222,7 @@ public:
     static ::com::sun::star::uno::Reference<
             ::com::sun::star::text::XDocumentIndexMark>
         CreateXDocumentIndexMark(SwDoc & rDoc,
-            SwTOXType * pType, SwTOXMark * pMark, TOXTypes eType = TOX_INDEX);
+            SwTOXMark * pMark, TOXTypes eType = TOX_INDEX);
 
     static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();
 
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 1ac957a..584293d 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -627,7 +627,7 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
                 eType = TOX_CONTENT;
             else if(SW_SERVICE_USER_INDEX_MARK == nObjectType)
                 eType = TOX_USER;
-            xRet = SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc, 0, 0, eType);
+            xRet = SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc, 0, eType);
         }
         break;
         case  SW_SERVICE_CONTENT_INDEX      :
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index ef7e417..7161059 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -481,8 +481,7 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
                         static_cast<SwTOXMark &>((*marks.begin())->GetAttr());
                     const uno::Reference< text::XDocumentIndexMark > xRef =
                         SwXDocumentIndexMark::CreateXDocumentIndexMark(
-                            *rPam.GetDoc(),
-                            const_cast<SwTOXType*>(rMark.GetTOXType()), &rMark);
+                            *rPam.GetDoc(), &rMark);
                     (*pAny) <<= xRef;
                 }
             }
diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx
index 550f9f8..bde57ed 100644
--- a/sw/source/core/unocore/unoidx.cxx
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -1197,8 +1197,7 @@ throw (beans::UnknownPropertyException, lang::WrappedTargetException,
                 {
                     SwTOXMark* pMark = aMarks[i];
                     pxMarks[i] = SwXDocumentIndexMark::CreateXDocumentIndexMark(
-                        *m_pImpl->m_pDoc,
-                        const_cast<SwTOXType*>(pType), pMark);
+                        *m_pImpl->m_pDoc, pMark);
                 }
                 aRet <<= aXMarks;
             }
@@ -1674,10 +1673,8 @@ SwXDocumentIndexMark::~SwXDocumentIndexMark()
 
 uno::Reference<text::XDocumentIndexMark>
 SwXDocumentIndexMark::CreateXDocumentIndexMark(
-        SwDoc & rDoc, SwTOXType *const pType, SwTOXMark *const pMark,
-        TOXTypes const eType)
+        SwDoc & rDoc, SwTOXMark *const pMark, TOXTypes const eType)
 {
-    assert((pType != 0) == (pMark != 0));
     // re-use existing SwXDocumentIndexMark
     // NB: xmloff depends on this caching to generate ID from the address!
     // #i105557#: do not iterate over the registered clients: race condition
@@ -1689,7 +1686,8 @@ SwXDocumentIndexMark::CreateXDocumentIndexMark(
     if (!xTOXMark.is())
     {
         SwXDocumentIndexMark *const pNew((pMark)
-            ? new SwXDocumentIndexMark(rDoc, *pType, *pMark)
+            ? new SwXDocumentIndexMark(rDoc,
+                    *const_cast<SwTOXType*>(pMark->GetTOXType()), *pMark)
             : new SwXDocumentIndexMark(eType));
         xTOXMark.set(pNew);
         if (pMark)
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 9eabdcf..e021622 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -537,8 +537,7 @@ lcl_CreateTOXMarkPortion(
     SwTOXMark & rTOXMark = static_cast<SwTOXMark&>(rAttr.GetAttr());
 
     const Reference<XTextContent> xContent(
-        SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc,
-                    const_cast<SwTOXType*>(rTOXMark.GetTOXType()), & rTOXMark),
+        SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc, & rTOXMark),
         uno::UNO_QUERY);
 
     SwXTextPortion* pPortion = 0;
commit 57b29dc9d475b8b674b32bf5d073175bac61ac14
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Aug 18 22:42:53 2014 +0200

    RegisterToTOXType has a silly parameter name
    
    Change-Id: I1cfd5c077f4b1ac809ace91fe76308f0e1892e09

diff --git a/sw/source/core/tox/tox.cxx b/sw/source/core/tox/tox.cxx
index bdda482..ee68b8d 100644
--- a/sw/source/core/tox/tox.cxx
+++ b/sw/source/core/tox/tox.cxx
@@ -177,9 +177,9 @@ SwTOXMark::~SwTOXMark()
 {
 }
 
-void SwTOXMark::RegisterToTOXType( SwTOXType& rMark )
+void SwTOXMark::RegisterToTOXType(SwTOXType& rType)
 {
-    rMark.Add(this);
+    rType.Add(this);
 }
 
 bool SwTOXMark::operator==( const SfxPoolItem& rAttr ) const
commit 2d4b87f0c1bfd97185a89c18d5b7680d11a958d6
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Aug 18 18:08:37 2014 +0200

    ODF export: don't write invalid "group-name" attribute
    
    Radio buttons are grouped via their "form:name" attribute already.
    
    Change-Id: I9f8b27a2904d947c3d4665495d36961e3e41d2c6

diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
index c463097..944e083 100644
--- a/sc/source/filter/excel/xiescher.cxx
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -2288,7 +2288,8 @@ void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
                 ScfPropertySet aProps( xCtrlModel );
                 OUString sGroupName = OUString::number( pLeader->GetDffShapeId() );
 
-                aProps.SetStringProperty( "GroupName", sGroupName );
+                // for radio buttons, "Name" is the group name
+                aProps.SetStringProperty( "Name", sGroupName );
                 aProps.SetStringProperty( "RefValue", OUString::number( nRefVal++ ) );
                 if ( pLeader->HasCellLink() && !pTbxObj->HasCellLink() )
                 {
diff --git a/xmloff/source/forms/elementexport.cxx b/xmloff/source/forms/elementexport.cxx
index 7112847..2a25317 100644
--- a/xmloff/source/forms/elementexport.cxx
+++ b/xmloff/source/forms/elementexport.cxx
@@ -1159,11 +1159,9 @@ namespace xmloff
         {
             static const sal_Int32 nStringPropertyAttributeIds[] =
             {   // attribute flags
-                SCA_GROUP_NAME
             };
             static const OUString pStringPropertyNames[] =
             {   // property names
-                OUString(PROPERTY_GROUP_NAME)
             };
 
             static const sal_Int32 nIdCount = sizeof( nStringPropertyAttributeIds ) / sizeof( nStringPropertyAttributeIds[0] );
@@ -1659,8 +1657,6 @@ namespace xmloff
                 }
                 if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_IMAGE_POSITION ) )
                     m_nIncludeSpecial |= SCA_IMAGE_POSITION;
-                if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_GROUP_NAME ) )
-                    m_nIncludeSpecial |= SCA_GROUP_NAME;
                 m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
                 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE;
                 break;
diff --git a/xmloff/source/forms/layerimport.cxx b/xmloff/source/forms/layerimport.cxx
index 4da67a7..57703c1 100644
--- a/xmloff/source/forms/layerimport.cxx
+++ b/xmloff/source/forms/layerimport.cxx
@@ -76,9 +76,11 @@ OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl(SvXMLImport& _rImporter)
     // string properties which are exported as attributes
     m_aAttributeMetaData.addStringProperty(
         OAttributeMetaData::getCommonControlAttributeName(CCA_NAME), PROPERTY_NAME);
+    // map invalid "group-name" attribute to "name"
+    // (since radio buttons are grouped by name)
+    m_aAttributeMetaData.addStringProperty(
+            OAttributeMetaData::getSpecialAttributeName(SCA_GROUP_NAME), PROPERTY_NAME);
     m_aAttributeMetaData.addStringProperty(
-            OAttributeMetaData::getSpecialAttributeName(SCA_GROUP_NAME), PROPERTY_GROUP_NAME);
-        m_aAttributeMetaData.addStringProperty(
         OAttributeMetaData::getCommonControlAttributeName(CCA_IMAGE_DATA), PROPERTY_IMAGEURL);
     m_aAttributeMetaData.addStringProperty(
         OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL), PROPERTY_LABEL);
diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx
index 844a445..db43d54 100644
--- a/xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx
+++ b/xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx
@@ -419,7 +419,6 @@ void ElementDescriptor::readRadioButtonModel( StyleBag * all_styles  )
     readImageURLAttr( "ImageURL", XMLNS_DIALOGS_PREFIX ":image-src" );
     readImagePositionAttr( "ImagePosition", XMLNS_DIALOGS_PREFIX ":image-position" );
     readBoolAttr( "MultiLine", XMLNS_DIALOGS_PREFIX ":multiline" );
-    readStringAttr( "GroupName", XMLNS_DIALOGS_PREFIX ":group-name" );
 
     sal_Int16 nState = 0;
     if (readProp( "State" ) >>= nState)
diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
index cabfb29..af40e4d 100644
--- a/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
+++ b/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx
@@ -1174,7 +1174,9 @@ void TitledBoxElement::endElement()
         ctx.importImageURLProperty( "ImageURL" ,  "image-src" , _xAttributes );
         ctx.importImagePositionProperty( "ImagePosition", "image-position", xAttributes );
         ctx.importBooleanProperty( "MultiLine", "multiline", xAttributes );
-        ctx.importStringProperty( "GroupName", "group-name", xAttributes );
+        // map invalid "group-name" attribute to "name"
+        // (since radio buttons are grouped by name)
+        ctx.importStringProperty( "Name", "group-name", xAttributes );
 
         sal_Int16 nVal = 0;
         sal_Bool bChecked = sal_False;
@@ -1269,7 +1271,9 @@ void RadioGroupElement::endElement()
         ctx.importImageURLProperty( "ImageURL" , "image-src" , xAttributes );
         ctx.importImagePositionProperty( "ImagePosition", "image-position", xAttributes );
         ctx.importBooleanProperty( "MultiLine", "multiline", xAttributes );
-        ctx.importStringProperty( "GroupName", "group-name", xAttributes );
+        // map invalid "group-name" attribute to "name"
+        // (since radio buttons are grouped by name)
+        ctx.importStringProperty( "Name", "group-name", xAttributes );
         sal_Int16 nVal = 0;
         sal_Bool bChecked = sal_False;
         if (getBoolAttr( &bChecked, "checked", xAttributes, _pImport->XMLNS_DIALOGS_UID ) && bChecked)
commit f05273aa478135b199577877ecd16325e0df95d2
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Aug 17 23:03:02 2014 +0200

    fdo#72695: avoid double-free race condition for SwXParagraph
    
    Change-Id: Ie207d9400bc3a55e17497b309dfbc263e7b12e30

diff --git a/sw/inc/unoparagraph.hxx b/sw/inc/unoparagraph.hxx
index ede6304..c8dbda9 100644
--- a/sw/inc/unoparagraph.hxx
+++ b/sw/inc/unoparagraph.hxx
@@ -77,14 +77,14 @@ private:
             SwTxtNode & rTxtNode,
             const sal_Int32 nSelStart = -1, const sal_Int32 nSelEnd = - 1);
 
-public:
-
     /// descriptor
     SwXParagraph();
 
+public:
+
     static ::com::sun::star::uno::Reference<
             ::com::sun::star::text::XTextContent>
-        CreateXParagraph(SwDoc & rDoc, SwTxtNode& rTxtNode,
+        CreateXParagraph(SwDoc & rDoc, SwTxtNode * pTxtNode,
             ::com::sun::star::uno::Reference< ::com::sun::star::text::XText>
                 const& xParentText = 0,
             const sal_Int32 nSelStart = -1, const sal_Int32 nSelEnd = - 1);
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index f7c208b..18835fc 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -5037,7 +5037,7 @@ uno::Reference< rdf::XMetadatable >
 SwTxtNode::MakeUnoObject()
 {
     const uno::Reference<rdf::XMetadatable> xMeta(
-            SwXParagraph::CreateXParagraph(*GetDoc(), *this), uno::UNO_QUERY);
+            SwXParagraph::CreateXParagraph(*GetDoc(), this), uno::UNO_QUERY);
     return xMeta;
 }
 
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 9e0ce2a..1ac957a 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -789,7 +789,7 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
         }
         break;
         case SW_SERVICE_PARAGRAPH :
-            xRet = (cppu::OWeakObject*)new SwXParagraph();
+            xRet = SwXParagraph::CreateXParagraph(*pDoc, 0);
         break;
         case SW_SERVICE_NUMBERING_RULES :
             xRet = (cppu::OWeakObject*)new SwXNumberingRules(*pDoc);
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index 95ff2c6..f237680 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -670,7 +670,7 @@ throw (container::NoSuchElementException, lang::WrappedTargetException,
         {
             text::XText *const pText = m_xParentText.get();
             xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(),
-                *pStart->nNode.GetNode().GetTxtNode(),
+                pStart->nNode.GetNode().GetTxtNode(),
                 static_cast<SwXText*>(pText), nFirstContent, nLastContent);
         }
     }
diff --git a/sw/source/core/unocore/unoparagraph.cxx b/sw/source/core/unocore/unoparagraph.cxx
index ebb5733..c6c3e20 100644
--- a/sw/source/core/unocore/unoparagraph.cxx
+++ b/sw/source/core/unocore/unoparagraph.cxx
@@ -110,6 +110,7 @@ private:
 
 public:
     SwXParagraph &              m_rThis;
+    uno::WeakReference<uno::XInterface> m_wThis;
     ::cppu::OInterfaceContainerHelper m_EventListeners;
     SfxItemPropertySet const&   m_rPropSet;
     bool                        m_bIsDescriptor;
@@ -181,11 +182,18 @@ protected:
 void SwXParagraph::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew )
 {
     ClientModify(this, pOld, pNew);
-    if (!GetRegisteredIn())
+    if (GetRegisteredIn())
     {
-        lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis));
-        m_EventListeners.disposeAndClear(ev);
+        return; // core object still alive
     }
+
+    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);
 }
 
 SwXParagraph::SwXParagraph()
@@ -217,16 +225,16 @@ bool SwXParagraph::IsDescriptor() const
 }
 
 uno::Reference<text::XTextContent>
-SwXParagraph::CreateXParagraph(SwDoc & rDoc, SwTxtNode& rTxtNode,
+SwXParagraph::CreateXParagraph(SwDoc & rDoc, SwTxtNode *const pTxtNode,
         uno::Reference< text::XText> const& i_xParent,
         const sal_Int32 nSelStart, const sal_Int32 nSelEnd)
 {
     // re-use existing SwXParagraph
     // #i105557#: do not iterate over the registered clients: race condition
     uno::Reference<text::XTextContent> xParagraph;
-    if ((-1 == nSelStart) && (-1 == nSelEnd)) // only use cache if no selection!
-    {
-        xParagraph.set(rTxtNode.GetXParagraph());
+    if (pTxtNode && (-1 == nSelStart) && (-1 == nSelEnd))
+    {   // only use cache if no selection!
+        xParagraph.set(pTxtNode->GetXParagraph());
     }
     if (xParagraph.is())
     {
@@ -235,20 +243,23 @@ SwXParagraph::CreateXParagraph(SwDoc & rDoc, SwTxtNode& rTxtNode,
 
     // create new SwXParagraph
     uno::Reference<text::XText> xParentText(i_xParent);
-    if (!xParentText.is())
+    if (!xParentText.is() && pTxtNode)
     {
-        SwPosition Pos( rTxtNode );
+        SwPosition Pos(*pTxtNode);
         xParentText.set(::sw::CreateParentXText( rDoc, Pos ));
     }
-    SwXParagraph *const pXPara(
-            new SwXParagraph(xParentText, rTxtNode, nSelStart, nSelEnd) );
+    SwXParagraph *const pXPara( (pTxtNode)
+            ? new SwXParagraph(xParentText, *pTxtNode, nSelStart, nSelEnd)
+            : new SwXParagraph);
     // this is why the constructor is private: need to acquire pXPara here
     xParagraph.set(pXPara);
     // in order to initialize the weak pointer cache in the core object
-    if ((-1 == nSelStart) && (-1 == nSelEnd))
+    if (pTxtNode && (-1 == nSelStart) && (-1 == nSelEnd))
     {
-        rTxtNode.SetXParagraph(xParagraph);
+        pTxtNode->SetXParagraph(xParagraph);
     }
+    // need a permanent Reference to initialize m_wThis
+    pXPara->m_pImpl->m_wThis = xParagraph;
     return xParagraph;
 }
 
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index 85feda2..4f05654 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1349,7 +1349,7 @@ SwXText::Impl::finishOrAppendParagraph(
     OSL_ENSURE(pTxtNode, "no SwTxtNode?");
     if (pTxtNode)
     {
-        xRet.set(SwXParagraph::CreateXParagraph(*m_pDoc, *pTxtNode, &m_rThis),
+        xRet.set(SwXParagraph::CreateXParagraph(*m_pDoc, pTxtNode, &m_rThis),
                 uno::UNO_QUERY);
     }
 
commit 7a3716bd7b90587974b50455c927bc330c2a6a63
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Aug 17 22:58:49 2014 +0200

    fdo#72695: avoid double-free race condition for SwXTextSection
    
    Change-Id: I6a4cd076deef63f172c42dcc22cc44c47a4aa293

diff --git a/sw/source/core/unocore/unosect.cxx b/sw/source/core/unocore/unosect.cxx
index f88fee0..8f67eb8 100644
--- a/sw/source/core/unocore/unosect.cxx
+++ b/sw/source/core/unocore/unosect.cxx
@@ -108,6 +108,7 @@ private:
 
 public:
     SwXTextSection &            m_rThis;
+    uno::WeakReference<uno::XInterface> m_wThis;
     const SfxItemPropertySet &  m_rPropSet;
     ::cppu::OInterfaceContainerHelper m_EventListeners;
     const bool                  m_bIndexHeader;
@@ -163,11 +164,18 @@ protected:
 void SwXTextSection::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
 {
     ClientModify(this, pOld, pNew);
-    if (!GetRegisteredIn())
+    if (GetRegisteredIn())
     {
-        lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis));
-        m_EventListeners.disposeAndClear(ev);
+        return; // core object still alive
     }
+
+    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);
 }
 
 SwSectionFmt * SwXTextSection::GetFmt() const
@@ -194,6 +202,8 @@ SwXTextSection::CreateXTextSection(
         {
             pFmt->SetXTextSection(xSection);
         }
+        // need a permanent Reference to initialize m_wThis
+        pNew->m_pImpl->m_wThis = xSection;
     }
     return xSection;
 }
commit 7fa2a363332620de869c67b8c9cca72cd093f2c4
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 15:44:39 2014 +0200

    fdo#72695: avoid double-free race condition for SwXDocumentIndex
    
    Change-Id: I9264ea023ee12b24561e86d893b1f7abb2765621

diff --git a/sw/source/core/inc/unoidx.hxx b/sw/source/core/inc/unoidx.hxx
index a877774..246bd9c 100644
--- a/sw/source/core/inc/unoidx.hxx
+++ b/sw/source/core/inc/unoidx.hxx
@@ -66,14 +66,15 @@ private:
 
     SwXDocumentIndex(SwTOXBaseSection const&, SwDoc &);
 
-public:
-
     /// descriptor
     SwXDocumentIndex(const TOXTypes eToxType, SwDoc& rDoc);
 
+public:
+
     static ::com::sun::star::uno::Reference<
             ::com::sun::star::text::XDocumentIndex>
-        CreateXDocumentIndex(SwDoc & rDoc, SwTOXBaseSection const& rSection);
+        CreateXDocumentIndex(SwDoc & rDoc, SwTOXBaseSection const* pSection,
+                TOXTypes eTypes = TOX_INDEX);
 
     // MetadatableMixin
     virtual ::sfx2::Metadatable* GetCoreObject() SAL_OVERRIDE;
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 7dc282f..9e0ce2a 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -659,7 +659,7 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
             {
                 eType = TOX_TABLES;
             }
-            xRet =  (cppu::OWeakObject*)new SwXDocumentIndex(eType, *pDoc);
+            xRet = SwXDocumentIndex::CreateXDocumentIndex(*pDoc, 0, eType);
         }
         break;
         case SW_SERVICE_INDEX_HEADER_SECTION :
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index faa62ae..ef7e417 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -501,7 +501,7 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
                 {
                     const uno::Reference< text::XDocumentIndex > xRef =
                         SwXDocumentIndex::CreateXDocumentIndex(*rPam.GetDoc(),
-                            *static_cast<SwTOXBaseSection const*>(pBase));
+                            static_cast<SwTOXBaseSection const*>(pBase));
                     (*pAny) <<= xRef;
                 }
             }
diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx
index ef76573..550f9f8 100644
--- a/sw/source/core/unocore/unoidx.cxx
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -321,7 +321,7 @@ private:
     ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper
 
 public:
-    SwXDocumentIndex &          m_rThis;
+    uno::WeakReference<uno::XInterface> m_wThis;
     ::cppu::OMultiTypeInterfaceContainerHelper m_Listeners;
     SfxItemPropertySet const&   m_rPropSet;
     const TOXTypes              m_eTOXType;
@@ -331,12 +331,10 @@ public:
     uno::WeakReference<container::XIndexReplace> m_wStyleAccess;
     uno::WeakReference<container::XIndexReplace> m_wTokenAccess;
 
-    Impl(   SwXDocumentIndex & rThis,
-            SwDoc & rDoc,
+    Impl(   SwDoc & rDoc,
             const TOXTypes eType,
             SwTOXBaseSection const*const pBaseSection)
         : SwClient((pBaseSection) ? pBaseSection->GetFmt() : 0)
-        , m_rThis(rThis)
         , m_Listeners(m_Mutex)
         , m_rPropSet(
             *aSwMapProvider.GetPropertySet(lcl_TypeToPropertyMap_Index(eType)))
@@ -386,23 +384,29 @@ protected:
 void SwXDocumentIndex::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
 {
     ClientModify(this, pOld, pNew);
-
-    if (!GetRegisteredIn())
+    if (GetRegisteredIn())
     {
-        lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis));
-        m_Listeners.disposeAndClear(ev);
+        return; // core object still alive
+    }
+
+    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_Listeners.disposeAndClear(ev);
 }
 
 SwXDocumentIndex::SwXDocumentIndex(
         SwTOXBaseSection const& rBaseSection, SwDoc & rDoc)
-    : m_pImpl( new SwXDocumentIndex::Impl( *this,
+    : m_pImpl( new SwXDocumentIndex::Impl(
                 rDoc, rBaseSection.SwTOXBase::GetType(), & rBaseSection) )
 {
 }
 
 SwXDocumentIndex::SwXDocumentIndex(const TOXTypes eType, SwDoc& rDoc)
-    : m_pImpl( new SwXDocumentIndex::Impl( *this, rDoc, eType, 0) )
+    : m_pImpl( new SwXDocumentIndex::Impl(rDoc, eType, 0) )
 {
 }
 
@@ -412,18 +416,28 @@ SwXDocumentIndex::~SwXDocumentIndex()
 
 uno::Reference<text::XDocumentIndex>
 SwXDocumentIndex::CreateXDocumentIndex(
-        SwDoc & rDoc, SwTOXBaseSection const& rSection)
+        SwDoc & rDoc, SwTOXBaseSection const* pSection, TOXTypes const eTypes)
 {
     // re-use existing SwXDocumentIndex
     // #i105557#: do not iterate over the registered clients: race condition
-    SwSectionFmt *const pFmt = rSection.GetFmt();
-    uno::Reference<text::XDocumentIndex> xIndex(pFmt->GetXObject(),
-            uno::UNO_QUERY);
+    uno::Reference<text::XDocumentIndex> xIndex;
+    if (pSection)
+    {
+        SwSectionFmt *const pFmt = pSection->GetFmt();
+        xIndex.set(pFmt->GetXObject(), uno::UNO_QUERY);
+    }
     if (!xIndex.is())
     {
-        SwXDocumentIndex *const pIndex(new SwXDocumentIndex(rSection, rDoc));
+        SwXDocumentIndex *const pIndex((pSection)
+                ? new SwXDocumentIndex(*pSection, rDoc)
+                : new SwXDocumentIndex(eTypes, rDoc));
         xIndex.set(pIndex);
-        pFmt->SetXObject(uno::Reference<uno::XInterface>(xIndex));
+        if (pSection)
+        {
+            pSection->GetFmt()->SetXObject(xIndex);
+        }
+        // need a permanent Reference to initialize m_wThis
+        pIndex->m_pImpl->m_wThis = xIndex;
     }
     return xIndex;
 }
@@ -2498,7 +2512,7 @@ throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException,
         {
            const uno::Reference< text::XDocumentIndex > xTmp =
                SwXDocumentIndex::CreateXDocumentIndex(
-                   *GetDoc(), static_cast<SwTOXBaseSection const&>(*pSect));
+                   *GetDoc(), static_cast<SwTOXBaseSection const*>(pSect));
            uno::Any aRet;
            aRet <<= xTmp;
            return aRet;
@@ -2529,7 +2543,7 @@ throw (container::NoSuchElementException, lang::WrappedTargetException,
         {
            const uno::Reference< text::XDocumentIndex > xTmp =
                SwXDocumentIndex::CreateXDocumentIndex(
-                   *GetDoc(), static_cast<SwTOXBaseSection const&>(*pSect));
+                   *GetDoc(), static_cast<SwTOXBaseSection const*>(pSect));
            uno::Any aRet;
            aRet <<= xTmp;
            return aRet;
diff --git a/sw/source/core/unocore/unosect.cxx b/sw/source/core/unocore/unosect.cxx
index a47875b..f88fee0 100644
--- a/sw/source/core/unocore/unosect.cxx
+++ b/sw/source/core/unocore/unosect.cxx
@@ -1105,7 +1105,7 @@ throw (beans::UnknownPropertyException, lang::WrappedTargetException,
                     // convert section to TOXBase and get SwXDocumentIndex
                     const uno::Reference<text::XDocumentIndex> xIndex =
                         SwXDocumentIndex::CreateXDocumentIndex(
-                            *pTOXBaseSect->GetFmt()->GetDoc(), *pTOXBaseSect);
+                            *pTOXBaseSect->GetFmt()->GetDoc(), pTOXBaseSect);
                     pRet[nProperty] <<= xIndex;
                 }
                 // else: no enclosing index found -> empty return value
commit 939edde802b4de9abb5c9d23c61abb37916ce357
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Aug 17 22:50:01 2014 +0200

    fdo#72695: avoid double-free race condition for SwXDocumentIndexMark
    
    Change-Id: I08fef7f1de4cce468a4936e33d3684f847e1aa5b

diff --git a/sw/source/core/inc/unoidx.hxx b/sw/source/core/inc/unoidx.hxx
index a1b5d1d..a877774 100644
--- a/sw/source/core/inc/unoidx.hxx
+++ b/sw/source/core/inc/unoidx.hxx
@@ -213,15 +213,15 @@ private:
     SwXDocumentIndexMark(SwDoc & rDoc,
                 SwTOXType & rType, SwTOXMark & rMark);
 
-public:
-
     /// descriptor
     SwXDocumentIndexMark(const TOXTypes eToxType);
 
+public:
+
     static ::com::sun::star::uno::Reference<
             ::com::sun::star::text::XDocumentIndexMark>
         CreateXDocumentIndexMark(SwDoc & rDoc,
-                SwTOXType & rType, SwTOXMark & rMark);
+            SwTOXType * pType, SwTOXMark * pMark, TOXTypes eType = TOX_INDEX);
 
     static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();
 
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index a7ff947..7dc282f 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -627,7 +627,7 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
                 eType = TOX_CONTENT;
             else if(SW_SERVICE_USER_INDEX_MARK == nObjectType)
                 eType = TOX_USER;
-            xRet =  (cppu::OWeakObject*)new SwXDocumentIndexMark(eType);
+            xRet = SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc, 0, 0, eType);
         }
         break;
         case  SW_SERVICE_CONTENT_INDEX      :
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index 51dcd9b..faa62ae 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -482,7 +482,7 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
                     const uno::Reference< text::XDocumentIndexMark > xRef =
                         SwXDocumentIndexMark::CreateXDocumentIndexMark(
                             *rPam.GetDoc(),
-                            *const_cast<SwTOXType*>(rMark.GetTOXType()), rMark);
+                            const_cast<SwTOXType*>(rMark.GetTOXType()), &rMark);
                     (*pAny) <<= xRef;
                 }
             }
diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx
index 00baf17..ef76573 100644
--- a/sw/source/core/unocore/unoidx.cxx
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -1184,7 +1184,7 @@ throw (beans::UnknownPropertyException, lang::WrappedTargetException,
                     SwTOXMark* pMark = aMarks[i];
                     pxMarks[i] = SwXDocumentIndexMark::CreateXDocumentIndexMark(
                         *m_pImpl->m_pDoc,
-                        *const_cast<SwTOXType*>(pType), *pMark);
+                        const_cast<SwTOXType*>(pType), pMark);
                 }
                 aRet <<= aXMarks;
             }
@@ -1529,6 +1529,7 @@ private:
 
 public:
 
+    uno::WeakReference<uno::XInterface> m_wThis;
     SfxItemPropertySet const&   m_rPropSet;
     const TOXTypes              m_eTOXType;
     ::cppu::OInterfaceContainerHelper m_EventListeners;
@@ -1619,8 +1620,13 @@ void SwXDocumentIndexMark::Impl::Invalidate()
     }
     if (!m_bInReplaceMark) // #i109983# only dispose on delete, not on replace!
     {
-        lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis));
-        m_EventListeners.disposeAndClear(ev);
+        uno::Reference<uno::XInterface> const xThis(m_wThis);
+        // fdo#72695: if UNO object is already dead, don't revive it with event
+        if (xThis.is())
+        {
+            lang::EventObject const ev(xThis);
+            m_EventListeners.disposeAndClear(ev);
+        }
     }
     m_pDoc = 0;
     m_pTOXMark = 0;
@@ -1654,18 +1660,30 @@ SwXDocumentIndexMark::~SwXDocumentIndexMark()
 
 uno::Reference<text::XDocumentIndexMark>
 SwXDocumentIndexMark::CreateXDocumentIndexMark(
-        SwDoc & rDoc, SwTOXType & rType, SwTOXMark & rMark)
+        SwDoc & rDoc, SwTOXType *const pType, SwTOXMark *const pMark,
+        TOXTypes const eType)
 {
+    assert((pType != 0) == (pMark != 0));
     // re-use existing SwXDocumentIndexMark
     // NB: xmloff depends on this caching to generate ID from the address!
     // #i105557#: do not iterate over the registered clients: race condition
-    uno::Reference< text::XDocumentIndexMark > xTOXMark(rMark.GetXTOXMark());
+    uno::Reference<text::XDocumentIndexMark> xTOXMark;
+    if (pMark)
+    {
+        xTOXMark = pMark->GetXTOXMark();
+    }
     if (!xTOXMark.is())
     {
-        SwXDocumentIndexMark *const pNew =
-            new SwXDocumentIndexMark(rDoc, rType, rMark);
+        SwXDocumentIndexMark *const pNew((pMark)
+            ? new SwXDocumentIndexMark(rDoc, *pType, *pMark)
+            : new SwXDocumentIndexMark(eType));
         xTOXMark.set(pNew);
-        rMark.SetXTOXMark(xTOXMark);
+        if (pMark)
+        {
+            pMark->SetXTOXMark(xTOXMark);
+        }
+        // need a permanent Reference to initialize m_wThis
+        pNew->m_pImpl->m_wThis = xTOXMark;
     }
     return xTOXMark;
 }
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index d79d3e3..9eabdcf 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -538,7 +538,7 @@ lcl_CreateTOXMarkPortion(
 
     const Reference<XTextContent> xContent(
         SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc,
-                    *const_cast<SwTOXType*>(rTOXMark.GetTOXType()), rTOXMark),
+                    const_cast<SwTOXType*>(rTOXMark.GetTOXType()), & rTOXMark),
         uno::UNO_QUERY);
 
     SwXTextPortion* pPortion = 0;
commit c71c1b2bb3b0a1767cd062e46e7dd81cc1027fb1
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Aug 20 15:24:21 2014 +0200

    fdo#72695: avoid double-free race condition for SwXFieldMaster
    
    Change-Id: Id3dfe1c68f00964200ad53922a0f41ebdbc4c3f8

diff --git a/sw/source/core/inc/unofield.hxx b/sw/source/core/inc/unofield.hxx
index 0e30e97..90b6594 100644
--- a/sw/source/core/inc/unofield.hxx
+++ b/sw/source/core/inc/unofield.hxx
@@ -58,14 +58,15 @@ private:
 
     SwXFieldMaster(SwFieldType& rType, SwDoc & rDoc);
 
-public:
-
     /// descriptor
     SwXFieldMaster(SwDoc* pDoc, sal_uInt16 nResId);
 
+public:
+
     static ::com::sun::star::uno::Reference<
             ::com::sun::star::beans::XPropertySet>
-        CreateXFieldMaster(SwDoc & rDoc, SwFieldType & rType);
+        CreateXFieldMaster(SwDoc & rDoc, SwFieldType * pType,
+                sal_uInt16 nResId = 0xFFFF);
 
     static OUString GetProgrammaticName(const SwFieldType& rType, SwDoc& rDoc);
     static OUString LocalizeFormula(const SwSetExpField& rFld, const OUString& rFormula, bool bQuery);
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index e9dcf83..a7ff947 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -774,7 +774,7 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
                 case SW_SERVICE_FIELDMASTER_SET_EXP : nResId = RES_SETEXPFLD; break;
                 case SW_SERVICE_FIELDMASTER_DATABASE: nResId = RES_DBFLD; break;
             }
-            xRet =  (cppu::OWeakObject*)new SwXFieldMaster(pDoc, nResId);
+            xRet = SwXFieldMaster::CreateXFieldMaster(*pDoc, 0, nResId);
         }
         break;
         case SW_SERVICE_FIELDMASTER_BIBLIOGRAPHY:
@@ -785,7 +785,7 @@ uno::Reference< uno::XInterface >   SwXServiceProvider::MakeInstance(sal_uInt16
                 SwAuthorityFieldType aType(pDoc);
                 pType = pDoc->getIDocumentFieldsAccess().InsertFldType(aType);
             }
-            xRet = SwXFieldMaster::CreateXFieldMaster(*pDoc, *pType);
+            xRet = SwXFieldMaster::CreateXFieldMaster(*pDoc, pType);
         }
         break;
         case SW_SERVICE_PARAGRAPH :

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list