summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-08-20 14:05:03 +0200
committerMichael Stahl <mstahl@redhat.com>2014-08-20 16:40:18 +0200
commit2c057a59e8241b42c7c44a1b53ffb63dd0e92cea (patch)
tree9739ab0ee12f69048077c30234688b1ff550b0b1 /sw
parente54015d06f103e3ce9edc899f0d839ead88add8a (diff)
i#107771: sw: implement thread-safe instance caching for SwXFootnote
Change-Id: I3fffb321877168dfa9844b4ad75a9a9efc9602a6
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/fmtftn.hxx16
-rw-r--r--sw/source/core/inc/unofootnote.hxx5
-rw-r--r--sw/source/core/txtnode/atrftn.cxx9
-rw-r--r--sw/source/core/unocore/unoftn.cxx29
-rw-r--r--sw/source/core/unocore/unoobj2.cxx4
5 files changed, 39 insertions, 24 deletions
diff --git a/sw/inc/fmtftn.hxx b/sw/inc/fmtftn.hxx
index fdfaee578d4e..0e2b52cc20e9 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 2a7643b31c62..b5b6a2f0d91b 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 9ada9dfbb567..5227ba9087ac 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 158e7292f699..ebafc93054f6 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 e1b4615a3379..a63fc6a13006 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;
}
}