summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mst@openoffice.org>2010-01-08 17:13:49 +0100
committerMichael Stahl <mst@openoffice.org>2010-01-08 17:13:49 +0100
commit1115bc8db0a08bd3bc99e20919f700d30f286664 (patch)
treed96a61f8c47d054225ca87981f256461e159a8fd
parent7aebbae28405cfd42be4d2d681942ed395e4e2af (diff)
swunolocking1: #i105557#: fix locking for SwXMeta:
move SwClient base to pImpl struct, and use UnoImplPtr to lock destructor. replace broken SwClient iteration with a WeakReference in sw::Meta. make constructor protected, and add factory function CreateXMeta. use new XUnoTunnel and XServiceInfo helpers.
-rwxr-xr-xsw/inc/fmtmeta.hxx14
-rwxr-xr-xsw/source/core/inc/unometa.hxx193
-rw-r--r--sw/source/core/txtnode/fmtatr2.cxx31
-rw-r--r--sw/source/core/unocore/unoportenum.cxx57
-rw-r--r--sw/source/core/unocore/unorefmk.cxx251
5 files changed, 311 insertions, 235 deletions
diff --git a/sw/inc/fmtmeta.hxx b/sw/inc/fmtmeta.hxx
index 6d3f63ece4..792a7d8374 100755
--- a/sw/inc/fmtmeta.hxx
+++ b/sw/inc/fmtmeta.hxx
@@ -31,6 +31,8 @@
#ifndef SW_FMTMETA_HXX
#define SW_FMTMETA_HXX
+#include <cppuhelper/weakref.hxx>
+
#include <svtools/poolitem.hxx>
#include <sfx2/Metadatable.hxx>
@@ -141,7 +143,10 @@ class Meta
{
protected:
friend class ::SwFmtMeta; // SetFmtMeta, NotifyChangeTxtNode
- friend class ::SwXMeta; // GetTxtNode, GetTxtAttr
+ friend class ::SwXMeta; // GetTxtNode, GetTxtAttr, Get/SetXMeta
+
+ ::com::sun::star::uno::WeakReference<
+ ::com::sun::star::rdf::XMetadatable> m_wXMeta;
SwFmtMeta * m_pFmt;
@@ -153,6 +158,13 @@ protected:
void NotifyChangeTxtNode();
+ ::com::sun::star::uno::WeakReference<
+ ::com::sun::star::rdf::XMetadatable> const& GetXMeta() const
+ { return m_wXMeta; }
+ void SetXMeta(::com::sun::star::uno::Reference<
+ ::com::sun::star::rdf::XMetadatable> const& xMeta)
+ { m_wXMeta = xMeta; }
+
public:
explicit Meta(SwFmtMeta * const i_pFmt = 0);
virtual ~Meta();
diff --git a/sw/source/core/inc/unometa.hxx b/sw/source/core/inc/unometa.hxx
index 1dc1985f7d..5568aa88b5 100755
--- a/sw/source/core/inc/unometa.hxx
+++ b/sw/source/core/inc/unometa.hxx
@@ -31,19 +31,21 @@
#ifndef SW_UNOMETA_HXX
#define SW_UNOMETA_HXX
-#include "calbck.hxx"
-
-#include <sfx2/Metadatable.hxx>
-#include <cppuhelper/implbase2.hxx>
-#include <cppuhelper/implbase5.hxx>
+#include <deque>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/text/XTextContent.hpp>
#include <com/sun/star/text/XTextField.hpp>
-#include <deque>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/implbase5.hxx>
+
+#include <sfx2/Metadatable.hxx>
+
+#include <unobaseclass.hxx>
typedef ::std::deque<
@@ -52,42 +54,78 @@ typedef ::std::deque<
class SwXTextRange;
class SwPaM;
-class SwTxtMeta;
+class SwTxtNode;
+
namespace sw {
class Meta;
class MetaField;
}
-typedef
-::cppu::ImplInheritanceHelper5
-< ::sfx2::MetadatableMixin
-, ::com::sun::star::lang::XUnoTunnel
-, ::com::sun::star::lang::XServiceInfo
-, ::com::sun::star::text::XTextContent
-, ::com::sun::star::text::XText
-, ::com::sun::star::container::XEnumerationAccess
-> SwXMetaBaseClass;
+typedef ::cppu::ImplInheritanceHelper5
+< ::sfx2::MetadatableMixin
+, ::com::sun::star::lang::XUnoTunnel
+, ::com::sun::star::lang::XServiceInfo
+, ::com::sun::star::container::XEnumerationAccess
+, ::com::sun::star::text::XTextContent
+, ::com::sun::star::text::XText
+> SwXMeta_Base;
class SwXMeta
- : public SwXMetaBaseClass
- , public SwClient
+ : public SwXMeta_Base
, private ::boost::noncopyable
{
-private:
- struct Impl;
- ::std::auto_ptr<Impl> m_pImpl;
+
+public:
+
+ class Impl;
protected:
+
+ ::sw::UnoImplPtr<Impl> m_pImpl;
+
+ virtual void SAL_CALL AttachImpl(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::text::XTextRange > & xTextRange,
+ const USHORT nWhich)
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+
virtual ~SwXMeta();
-public:
- SwXMeta(SwDoc *const pDoc,
+ /// @param pDoc and pMeta != 0, but not & because of ImplInheritanceHelper
+ SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
::com::sun::star::uno::Reference< ::com::sun::star::text::XText> const&
xParentText,
- TextRangeList_t * const pPortions, SwTxtMeta * const pHint);
+ TextRangeList_t const*const pPortions);
+
+public:
+
SwXMeta(SwDoc *const pDoc);
- TYPEINFO();
+ static ::com::sun::star::uno::Reference<
+ ::com::sun::star::rdf::XMetadatable >
+ CreateXMeta(
+ ::sw::Meta & rMeta,
+ ::com::sun::star::uno::Reference< ::com::sun::star::text::XText>
+ const& xParentText = 0,
+ ::std::auto_ptr<TextRangeList_t const> pPortions =
+ ::std::auto_ptr<TextRangeList_t const>(0));
+
+ /// init params with position of the attribute content (w/out CH_TXTATR)
+ bool SetContentRange(
+ SwTxtNode *& rpNode, xub_StrLen & rStart, xub_StrLen & rEnd) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >
+ GetParentText() const;
+
+ bool CheckForOwnMemberMeta(const SwXTextRange* const pRange,
+ const SwPaM* const pPam, bool bAbsorb)
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException);
+
+ // MetadatableMixin
+ virtual ::sfx2::Metadatable * GetCoreObject();
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
+ GetModel();
static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();
@@ -118,6 +156,18 @@ public:
::com::sun::star::lang::XEventListener > & xListener)
throw (::com::sun::star::uno::RuntimeException);
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XEnumeration > SAL_CALL
+ createEnumeration()
+ throw (::com::sun::star::uno::RuntimeException);
+
// XTextContent
virtual void SAL_CALL attach(
const ::com::sun::star::uno::Reference<
@@ -180,72 +230,37 @@ public:
throw (::com::sun::star::container::NoSuchElementException,
::com::sun::star::uno::RuntimeException);
- // XElementAccess
- virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
- throw (::com::sun::star::uno::RuntimeException);
- virtual sal_Bool SAL_CALL hasElements()
- throw (::com::sun::star::uno::RuntimeException);
-
- // XEnumerationAccess
- virtual ::com::sun::star::uno::Reference<
- ::com::sun::star::container::XEnumeration > SAL_CALL
- createEnumeration()
- throw (::com::sun::star::uno::RuntimeException);
-
- // MetadatableMixin
- virtual ::sfx2::Metadatable * GetCoreObject();
- virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
- GetModel();
-
- // SwClient
- virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew );
-
- /// init params with position of the attribute content (w/out CH_TXTATR)
- bool SetContentRange(
- SwTxtNode *& rpNode, xub_StrLen & rStart, xub_StrLen & rEnd) const;
- ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >
- GetParentText() const;
-
- bool CheckForOwnMemberMeta(const SwXTextRange* const pRange,
- const SwPaM* const pPam, bool bAbsorb)
- throw (::com::sun::star::lang::IllegalArgumentException,
- ::com::sun::star::uno::RuntimeException);
-
-protected:
- virtual void SAL_CALL AttachImpl(
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::text::XTextRange > & xTextRange,
- const USHORT nWhich)
- throw ( ::com::sun::star::lang::IllegalArgumentException,
- ::com::sun::star::uno::RuntimeException );
-
-private:
- inline const ::sw::Meta * GetMeta() const;
-
};
-typedef
-::cppu::ImplInheritanceHelper2
-< SwXMeta
-, ::com::sun::star::beans::XPropertySet
-, ::com::sun::star::text::XTextField
-> SwXMetaFieldBaseClass;
+typedef ::cppu::ImplInheritanceHelper2
+< SwXMeta
+, ::com::sun::star::beans::XPropertySet
+, ::com::sun::star::text::XTextField
+> SwXMetaField_Base;
class SwXMetaField
- : public SwXMetaFieldBaseClass
+ : public SwXMetaField_Base
{
+
private:
+
virtual ~SwXMetaField();
-private:
- inline const ::sw::MetaField * GetMetaField() const;
+ friend ::com::sun::star::uno::Reference<
+ ::com::sun::star::rdf::XMetadatable >
+ SwXMeta::CreateXMeta(::sw::Meta &,
+ ::com::sun::star::uno::Reference< ::com::sun::star::text::XText>
+ const&,
+ ::std::auto_ptr<TextRangeList_t const> pPortions);
-public:
- SwXMetaField(SwDoc *const pDoc,
+ SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta,
::com::sun::star::uno::Reference< ::com::sun::star::text::XText> const&
xParentText,
- TextRangeList_t * const pPortions, SwTxtMeta * const pHint);
+ TextRangeList_t const*const pPortions);
+
+public:
+
SwXMetaField(SwDoc *const pDoc);
// XServiceInfo
@@ -270,16 +285,6 @@ public:
::com::sun::star::lang::XEventListener > & xListener)
throw (::com::sun::star::uno::RuntimeException);
- // XTextContent
- virtual void SAL_CALL attach(
- const ::com::sun::star::uno::Reference<
- ::com::sun::star::text::XTextRange > & xTextRange)
- throw ( ::com::sun::star::lang::IllegalArgumentException,
- ::com::sun::star::uno::RuntimeException );
- virtual ::com::sun::star::uno::Reference<
- ::com::sun::star::text::XTextRange > SAL_CALL getAnchor()
- throw (::com::sun::star::uno::RuntimeException);
-
// XPropertySet
virtual ::com::sun::star::uno::Reference<
::com::sun::star::beans::XPropertySetInfo > SAL_CALL
@@ -327,6 +332,16 @@ public:
::com::sun::star::lang::WrappedTargetException,
::com::sun::star::uno::RuntimeException);
+ // XTextContent
+ virtual void SAL_CALL attach(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::text::XTextRange > & xTextRange)
+ throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::text::XTextRange > SAL_CALL getAnchor()
+ throw (::com::sun::star::uno::RuntimeException);
+
// XTextField
virtual rtl::OUString SAL_CALL getPresentation(sal_Bool bShowCommand)
throw (::com::sun::star::uno::RuntimeException);
diff --git a/sw/source/core/txtnode/fmtatr2.cxx b/sw/source/core/txtnode/fmtatr2.cxx
index 066817d5b0..686b4a67af 100644
--- a/sw/source/core/txtnode/fmtatr2.cxx
+++ b/sw/source/core/txtnode/fmtatr2.cxx
@@ -57,7 +57,6 @@
#include <ndtxt.hxx> // for meta
#include <doc.hxx> // for meta
#include <unometa.hxx>
-#include <unotextrange.hxx>
#include <docsh.hxx>
#include <svtools/zforlist.hxx> // GetNumberFormat
@@ -750,6 +749,10 @@ void Meta::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
{
NotifyChangeTxtNode();
SwModify::Modify(pOld, pNew);
+ if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
+ { // invalidate cached uno object
+ SetXMeta(uno::Reference<rdf::XMetadatable>(0));
+ }
}
// sw::Metadatable
@@ -788,31 +791,7 @@ bool Meta::IsInContent() const
::com::sun::star::uno::Reference< ::com::sun::star::rdf::XMetadatable >
Meta::MakeUnoObject()
{
- // re-use existing SwXMeta
- SwClientIter iter( *this );
- SwClient * pClient( iter.First( TYPE( SwXMeta ) ) );
- while (pClient) {
- SwXMeta *const pMeta( dynamic_cast<SwXMeta*>(pClient) );
- if (pMeta && pMeta->GetCoreObject() == this) {
- return pMeta;
- }
- pClient = iter.Next();
- }
-
- // create new SwXMeta
- SwTxtMeta * const pTxtAttr( GetTxtAttr() );
- OSL_ENSURE(pTxtAttr, "MakeUnoObject: no text attr?");
- if (!pTxtAttr) return 0;
- SwTxtNode * const pTxtNode( pTxtAttr->GetTxtNode() );
- OSL_ENSURE(pTxtNode, "MakeUnoObject: no text node?");
- if (!pTxtNode) return 0;
- const SwPosition aPos(*pTxtNode, *pTxtAttr->GetStart());
- const uno::Reference<text::XText> xParentText(
- SwXTextRange::CreateParentXText(pTxtNode->GetDoc(), aPos) );
- if (!xParentText.is()) return 0;
- return (RES_TXTATR_META == m_pFmt->Which())
- ? new SwXMeta (pTxtNode->GetDoc(), xParentText, 0, pTxtAttr)
- : new SwXMetaField(pTxtNode->GetDoc(), xParentText, 0, pTxtAttr);
+ return SwXMeta::CreateXMeta(*this);
}
/*************************************************************************
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 07f27201f6..2cff59cf41 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -54,6 +54,7 @@
#include <unoredline.hxx>
#include <unofield.hxx>
#include <unometa.hxx>
+#include <fmtmeta.hxx>
#include <fmtanchr.hxx>
#include <fmtrfmrk.hxx>
#include <frmfmt.hxx>
@@ -493,6 +494,33 @@ lcl_CreateTOXMarkPortion(
}
//-----------------------------------------------------------------------------
+static uno::Reference<text::XTextRange>
+lcl_CreateMetaPortion(
+ uno::Reference<text::XText> const& xParent,
+ const SwUnoCrsr * const pUnoCrsr,
+ SwTxtAttr & rAttr, ::std::auto_ptr<TextRangeList_t const> & pPortions)
+{
+ const uno::Reference<rdf::XMetadatable> xMeta( SwXMeta::CreateXMeta(
+ *static_cast<SwFmtMeta &>(rAttr.GetAttr()).GetMeta(),
+ xParent, pPortions));
+ SwXTextPortion * pPortion(0);
+ if (RES_TXTATR_META == rAttr.Which())
+ {
+ const uno::Reference<text::XTextContent> xContent(xMeta,
+ uno::UNO_QUERY);
+ pPortion = new SwXTextPortion(pUnoCrsr, xParent, PORTION_META);
+ pPortion->SetMeta(xContent);
+ }
+ else
+ {
+ const uno::Reference<text::XTextField> xField(xMeta, uno::UNO_QUERY);
+ pPortion = new SwXTextPortion(pUnoCrsr, xParent, PORTION_FIELD);
+ pPortion->SetTextField(xField);
+ }
+ return pPortion;
+}
+
+//-----------------------------------------------------------------------------
static void
lcl_ExportBookmark(
TextRangeList_t & rPortions,
@@ -692,30 +720,13 @@ lcl_ExportHints(
}
else
{
- TextRangeList_t *const pCurrentPortions(Top.first);
+ ::std::auto_ptr<const TextRangeList_t>
+ pCurrentPortions(Top.first);
rPortionStack.pop();
- SwXTextPortion * pPortion;
- if (RES_TXTATR_META == nWhich)
- {
- SwXMeta * const pMeta =
- new SwXMeta(pDoc, xParent,
- pCurrentPortions,
- static_cast<SwTxtMeta * const>(pAttr));
- pPortion = new SwXTextPortion(
- pUnoCrsr, xParent, PORTION_META);
- pPortion->SetMeta(pMeta);
- }
- else
- {
- SwXMetaField * const pMeta =
- new SwXMetaField(pDoc, xParent,
- pCurrentPortions,
- static_cast<SwTxtMeta * const>(pAttr));
- pPortion = new SwXTextPortion(
- pUnoCrsr, xParent, PORTION_FIELD);
- pPortion->SetTextField(pMeta);
- }
- rPortionStack.top().first->push_back(pPortion);
+ const uno::Reference<text::XTextRange> xPortion(
+ lcl_CreateMetaPortion(xParent, pUnoCrsr,
+ *pAttr, pCurrentPortions));
+ rPortionStack.top().first->push_back(xPortion);
}
}
break;
diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx
index 42ef834cbf..18a72831f8 100644
--- a/sw/source/core/unocore/unorefmk.cxx
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -493,6 +493,8 @@ public:
const uno::Reference< text::XTextRange > & xTextPosition)
throw (uno::RuntimeException);
+ SwXMeta & GetXMeta() { return m_rMeta; }
+
};
SwXMetaText::SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta)
@@ -598,8 +600,12 @@ SwXMetaText::createTextCursorByRange(
// this list is created by SwXTextPortionEnumeration
// the Meta listens at the SwTxtNode and throws away the cache when it changes
-struct SwXMeta::Impl
+class SwXMeta::Impl
+ : public SwClient
{
+
+public:
+
SwEventListenerContainer m_ListenerContainer;
::std::auto_ptr<const TextRangeList_t> m_pTextPortions;
// 3 possible states: not attached, attached, disposed
@@ -608,37 +614,132 @@ struct SwXMeta::Impl
uno::Reference<text::XText> m_xParentText;
SwXMetaText m_Text;
- Impl(SwXMeta & rThis, SwDoc & rDoc,
+ Impl( SwXMeta & rThis, SwDoc & rDoc,
+ ::sw::Meta * const pMeta,
uno::Reference<text::XText> const& xParentText,
- TextRangeList_t const * const pPortions,
- SwTxtMeta const * const pHint)
- : m_ListenerContainer(
- static_cast< ::cppu::OWeakObject* >(&rThis))
+ TextRangeList_t const * const pPortions)
+ : SwClient(pMeta)
+ , m_ListenerContainer(static_cast< ::cppu::OWeakObject* >(&rThis))
, m_pTextPortions( pPortions )
, m_bIsDisposed( false )
- , m_bIsDescriptor( 0 == pHint )
+ , m_bIsDescriptor(0 == pMeta)
, m_xParentText(xParentText)
, m_Text(rDoc, rThis)
{
}
-};
-TYPEINIT1(SwXMeta, SwClient);
+ inline const ::sw::Meta * GetMeta() const;
+ // only for SwXMetaField!
+ inline const ::sw::MetaField * GetMetaField() const;
+
+ // SwClient
+ virtual void Modify(SfxPoolItem *pOld, SfxPoolItem *pNew);
-inline const ::sw::Meta * SwXMeta::GetMeta() const
+};
+
+inline const ::sw::Meta * SwXMeta::Impl::GetMeta() const
{
return static_cast< const ::sw::Meta * >(GetRegisteredIn());
}
+// SwModify
+void SwXMeta::Impl::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+ m_pTextPortions.reset(); // throw away cache (SwTxtNode changed)
+
+ ClientModify(this, pOld, pNew);
+
+ if (!GetRegisteredIn()) // removed => dispose
+ {
+ m_ListenerContainer.Disposing();
+ m_bIsDisposed = true;
+ m_Text.Invalidate();
+ }
+}
+
uno::Reference<text::XText> SwXMeta::GetParentText() const
{
return m_pImpl->m_xParentText;
}
+SwXMeta::SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
+ uno::Reference<text::XText> const& xParentText,
+ TextRangeList_t const*const pPortions)
+ : m_pImpl( new SwXMeta::Impl(*this, *pDoc, pMeta, xParentText, pPortions) )
+{
+}
+
+SwXMeta::SwXMeta(SwDoc *const pDoc)
+ : m_pImpl( new SwXMeta::Impl(*this, *pDoc, 0, 0, 0) )
+{
+}
+
+SwXMeta::~SwXMeta()
+{
+}
+
+uno::Reference<rdf::XMetadatable>
+SwXMeta::CreateXMeta(::sw::Meta & rMeta,
+ uno::Reference<text::XText> const& i_xParent,
+ ::std::auto_ptr<TextRangeList_t const> pPortions)
+{
+ // re-use existing SwXMeta
+ // #i105557#: do not iterate over the registered clients: race condition
+ uno::Reference<rdf::XMetadatable> xMeta(rMeta.GetXMeta());
+ if (xMeta.is())
+ {
+ if (pPortions.get()) // set cache in the XMeta to the given portions
+ {
+ const uno::Reference<lang::XUnoTunnel> xUT(xMeta, uno::UNO_QUERY);
+ SwXMeta *const pXMeta(
+ ::sw::UnoTunnelGetImplementation<SwXMeta>(xUT));
+ OSL_ENSURE(pXMeta, "no pXMeta?");
+ // NB: the meta must always be created with the complete content
+ // if SwXTextPortionEnumeration is created for a selection,
+ // it must be checked that the Meta is contained in the selection!
+ pXMeta->m_pImpl->m_pTextPortions = pPortions;
+ // ??? is this necessary?
+ if (pXMeta->m_pImpl->m_xParentText.get() != i_xParent.get())
+ {
+ OSL_ENSURE(false, "SwXMeta with different parent?");
+ pXMeta->m_pImpl->m_xParentText.set(i_xParent);
+ }
+ }
+ return xMeta;
+ }
+
+ // create new SwXMeta
+ SwTxtNode * const pTxtNode( rMeta.GetTxtNode() );
+ OSL_ENSURE(pTxtNode, "CreateXMeta: no text node?");
+ if (!pTxtNode) { return 0; }
+ uno::Reference<text::XText> xParentText(i_xParent);
+ if (!xParentText.is())
+ {
+ SwTxtMeta * const pTxtAttr( rMeta.GetTxtAttr() );
+ OSL_ENSURE(pTxtAttr, "CreateXMeta: no text attr?");
+ if (!pTxtAttr) { return 0; }
+ const SwPosition aPos(*pTxtNode, *pTxtAttr->GetStart());
+ xParentText.set(
+ SwXTextRange::CreateParentXText(pTxtNode->GetDoc(), aPos) );
+ }
+ if (!xParentText.is()) { return 0; }
+ SwXMeta *const pXMeta( (RES_TXTATR_META == rMeta.GetFmtMeta()->Which())
+ ? new SwXMeta (pTxtNode->GetDoc(), &rMeta, xParentText,
+ pPortions.release()) // temporarily un-auto_ptr :-(
+ : new SwXMetaField(pTxtNode->GetDoc(), &rMeta, xParentText,
+ pPortions.release()));
+ // this is why the constructor is private: need to acquire pXMeta here
+ xMeta.set(pXMeta);
+ // in order to initialize the weak pointer cache in the core object
+ rMeta.SetXMeta(xMeta);
+ return xMeta;
+}
+
+
bool SwXMeta::SetContentRange(
SwTxtNode *& rpNode, xub_StrLen & rStart, xub_StrLen & rEnd ) const
{
- ::sw::Meta const * const pMeta( GetMeta() );
+ ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
if (pMeta)
{
SwTxtMeta const * const pTxtAttr( pMeta->GetTxtAttr() );
@@ -657,23 +758,6 @@ bool SwXMeta::SetContentRange(
return false;
}
-SwXMeta::SwXMeta(SwDoc *const pDoc,
- uno::Reference<text::XText> const& xParentText,
- TextRangeList_t * const pPortions, SwTxtMeta * const pHint)
- : m_pImpl( new SwXMeta::Impl(*this, *pDoc, xParentText, pPortions, pHint) )
-{
- if (pHint)
- {
- ::sw::Meta * const pMeta(
- static_cast<SwFmtMeta&>(pHint->GetAttr()).GetMeta() );
- ASSERT(pMeta, "SwXMeta: no meta?")
- if (pMeta)
- {
- pMeta->Add(this);
- }
- }
-}
-
bool SwXMeta::CheckForOwnMemberMeta(const SwXTextRange* const pRange,
const SwPaM* const pPam, bool bAbsorb)
throw (lang::IllegalArgumentException, uno::RuntimeException)
@@ -744,16 +828,6 @@ bool SwXMeta::CheckForOwnMemberMeta(const SwXTextRange* const pRange,
return bForceExpandHints;
}
-
-SwXMeta::SwXMeta(SwDoc *const pDoc)
- : m_pImpl( new SwXMeta::Impl(*this, *pDoc, 0, 0, 0) )
-{
-}
-
-SwXMeta::~SwXMeta()
-{
-}
-
const uno::Sequence< sal_Int8 > & SwXMeta::getUnoTunnelId()
{
static uno::Sequence< sal_Int8 > aSeq( ::CreateUnoTunnelId() );
@@ -765,14 +839,7 @@ sal_Int64 SAL_CALL
SwXMeta::getSomething( const uno::Sequence< sal_Int8 > & i_rId )
throw (uno::RuntimeException)
{
- if ( i_rId.getLength() == 16 &&
- 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
- i_rId.getConstArray(), 16 ) )
- {
- return sal::static_int_cast< sal_Int64 >(
- reinterpret_cast< sal_IntPtr >(this) );
- }
- return 0;
+ return ::sw::UnoTunnelImpl<SwXMeta>(i_rId, this);
}
// XServiceInfo
@@ -782,21 +849,26 @@ SwXMeta::getImplementationName() throw (uno::RuntimeException)
return C2U("SwXMeta");
}
+static char const*const g_ServicesMeta[] =
+{
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.InContentMetadata",
+};
+static const size_t g_nServicesMeta(
+ sizeof(g_ServicesMeta)/sizeof(g_ServicesMeta[0]));
+
sal_Bool SAL_CALL
SwXMeta::supportsService(const ::rtl::OUString& rServiceName)
throw (uno::RuntimeException)
{
- return rServiceName.equalsAscii("com.sun.star.text.TextContent")
- || rServiceName.equalsAscii("com.sun.star.text.InContentMetadata");
+ return ::sw::SupportsServiceImpl(
+ g_nServicesMeta, g_ServicesMeta, rServiceName);
}
uno::Sequence< ::rtl::OUString > SAL_CALL
SwXMeta::getSupportedServiceNames() throw (uno::RuntimeException)
{
- uno::Sequence< ::rtl::OUString > aRet(2);
- aRet[0] = C2U("com.sun.star.text.TextContent");
- aRet[1] = C2U("com.sun.star.text.InContentMetadata");
- return aRet;
+ return ::sw::GetSupportedServiceNamesImpl(g_nServicesMeta, g_ServicesMeta);
}
@@ -886,14 +958,10 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
C2S("SwXMeta::attach(): argument is no XUnoTunnel"),
static_cast< ::cppu::OWeakObject* >(this), 0);
}
- SwXTextRange * const pRange(
- reinterpret_cast< SwXTextRange * >(
- sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething(
- SwXTextRange::getUnoTunnelId() ))) );
- OTextCursorHelper * const pCursor( pRange ? 0 :
- reinterpret_cast< OTextCursorHelper * >(
- sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething(
- OTextCursorHelper::getUnoTunnelId() ))) );
+ SwXTextRange *const pRange(
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel));
+ OTextCursorHelper *const pCursor( (pRange) ? 0 :
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel));
if (!pRange && !pCursor)
{
throw lang::IllegalArgumentException(
@@ -945,7 +1013,8 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
static_cast< ::cppu::OWeakObject* >(this));
}
- pMeta->Add(this);
+ pMeta->Add(m_pImpl.get());
+ pMeta->SetXMeta(uno::Reference<rdf::XMetadatable>(this));
m_pImpl->m_xParentText =
SwXTextRange::CreateParentXText(pDoc, *aPam.GetPoint());
@@ -1102,7 +1171,7 @@ SwXMeta::hasElements() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
- return GetRegisteredIn() ? sal_True : sal_False;
+ return m_pImpl->GetRegisteredIn() ? sal_True : sal_False;
}
// XEnumerationAccess
@@ -1118,7 +1187,7 @@ SwXMeta::createEnumeration() throw (uno::RuntimeException)
if (m_pImpl->m_bIsDescriptor)
{
throw uno::RuntimeException(
- C2S("getAnchor(): not inserted"),
+ C2S("createEnumeration(): not inserted"),
static_cast< ::cppu::OWeakObject* >(this));
}
@@ -1147,12 +1216,12 @@ SwXMeta::createEnumeration() throw (uno::RuntimeException)
// MetadatableMixin
::sfx2::Metadatable* SwXMeta::GetCoreObject()
{
- return const_cast< ::sw::Meta * >(GetMeta());
+ return const_cast< ::sw::Meta * >(m_pImpl->GetMeta());
}
uno::Reference<frame::XModel> SwXMeta::GetModel()
{
- ::sw::Meta const * const pMeta( GetMeta() );
+ ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
if (pMeta)
{
SwTxtNode const * const pTxtNode( pMeta->GetTxtNode() );
@@ -1165,42 +1234,27 @@ uno::Reference<frame::XModel> SwXMeta::GetModel()
return 0;
}
-// SwModify
-void SwXMeta::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
-{
- m_pImpl->m_pTextPortions.reset(); // throw away cache (SwTxtNode changed)
-
- ClientModify(this, pOld, pNew);
-
- if (!GetRegisteredIn()) // removed => dispose
- {
- m_pImpl->m_ListenerContainer.Disposing();
- m_pImpl->m_bIsDisposed = true;
- m_pImpl->m_Text.Invalidate();
- }
-}
-
/******************************************************************
* SwXMetaField
******************************************************************/
-inline const ::sw::MetaField * SwXMetaField::GetMetaField() const
+inline const ::sw::MetaField * SwXMeta::Impl::GetMetaField() const
{
return static_cast< const ::sw::MetaField * >(GetRegisteredIn());
}
-SwXMetaField::SwXMetaField(SwDoc *const pDoc,
+SwXMetaField::SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta,
uno::Reference<text::XText> const& xParentText,
- TextRangeList_t * const pPortions, SwTxtMeta * const pHint)
- : SwXMetaFieldBaseClass(pDoc, xParentText, pPortions, pHint)
+ TextRangeList_t const*const pPortions)
+ : SwXMetaField_Base(pDoc, pMeta, xParentText, pPortions)
{
- ASSERT(!pHint || RES_TXTATR_METAFIELD == pHint->Which(),
+ ASSERT(pMeta && dynamic_cast< ::sw::MetaField* >(pMeta),
"SwXMetaField created for wrong hint!");
}
SwXMetaField::SwXMetaField(SwDoc *const pDoc)
- : SwXMetaFieldBaseClass(pDoc)
+ : SwXMetaField_Base(pDoc)
{
}
@@ -1215,23 +1269,28 @@ SwXMetaField::getImplementationName() throw (uno::RuntimeException)
return C2U("SwXMetaField");
}
+static char const*const g_ServicesMetaField[] =
+{
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.TextField",
+ "com.sun.star.text.textfield.MetadataField",
+};
+static const size_t g_nServicesMetaField(
+ sizeof(g_ServicesMetaField)/sizeof(g_ServicesMetaField[0]));
+
sal_Bool SAL_CALL
SwXMetaField::supportsService(const ::rtl::OUString& rServiceName)
throw (uno::RuntimeException)
{
- return rServiceName.equalsAscii("com.sun.star.text.TextContent")
- || rServiceName.equalsAscii("com.sun.star.text.TextField")
- || rServiceName.equalsAscii("com.sun.star.text.textfield.MetadataField");
+ return ::sw::SupportsServiceImpl(
+ g_nServicesMetaField, g_ServicesMetaField, rServiceName);
}
uno::Sequence< ::rtl::OUString > SAL_CALL
SwXMetaField::getSupportedServiceNames() throw (uno::RuntimeException)
{
- uno::Sequence< ::rtl::OUString > aRet(3);
- aRet[0] = C2U("com.sun.star.text.TextContent");
- aRet[1] = C2U("com.sun.star.text.TextField");
- aRet[2] = C2U("com.sun.star.text.textfield.MetadataField");
- return aRet;
+ return ::sw::GetSupportedServiceNamesImpl(
+ g_nServicesMetaField, g_ServicesMetaField);
}
// XComponent
@@ -1293,7 +1352,7 @@ throw (beans::UnknownPropertyException, beans::PropertyVetoException,
vos::OGuard g(Application::GetSolarMutex());
::sw::MetaField * const pMeta(
- const_cast< ::sw::MetaField * >(GetMetaField()) );
+ const_cast< ::sw::MetaField * >(m_pImpl->GetMetaField()) );
if (!pMeta)
throw lang::DisposedException();
@@ -1326,7 +1385,7 @@ throw (beans::UnknownPropertyException, lang::WrappedTargetException,
{
vos::OGuard g(Application::GetSolarMutex());
- ::sw::MetaField const * const pMeta( GetMetaField() );
+ ::sw::MetaField const * const pMeta( m_pImpl->GetMetaField() );
if (!pMeta)
throw lang::DisposedException();