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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 <mst...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits