diff options
-rwxr-xr-x | sw/inc/fmtmeta.hxx | 8 | ||||
-rw-r--r-- | sw/inc/txtatr.hxx | 2 | ||||
-rwxr-xr-x | sw/qa/complex/writer/TextPortionEnumerationTest.java | 2 | ||||
-rw-r--r-- | sw/source/core/docnode/nodes.cxx | 11 | ||||
-rw-r--r-- | sw/source/core/txtnode/fmtatr2.cxx | 35 | ||||
-rw-r--r-- | sw/source/core/txtnode/thints.cxx | 7 | ||||
-rw-r--r-- | sw/source/core/txtnode/txtatr2.cxx | 10 |
7 files changed, 60 insertions, 15 deletions
diff --git a/sw/inc/fmtmeta.hxx b/sw/inc/fmtmeta.hxx index 952181d0498c..6d3f63ece477 100755 --- a/sw/inc/fmtmeta.hxx +++ b/sw/inc/fmtmeta.hxx @@ -122,8 +122,8 @@ public: virtual SfxPoolItem * Clone( SfxItemPool *pPool = 0 ) const; // TYPEINFO(); - // notify clients registered at m_pMeta that this meta is being removed - void NotifyRemoval(); + /// notify clients registered at m_pMeta that this meta is being (re-)moved + void NotifyChangeTxtNode(SwTxtNode *const pTxtNode); static SwFmtMeta * CreatePoolDefault( const USHORT i_nWhich ); ::sw::Meta * GetMeta() { return m_pMeta.get(); } /// this method <em>must</em> be called when the hint is actually copied @@ -140,7 +140,7 @@ class Meta , public SwModify { protected: - friend class ::SwFmtMeta; // SetFmtMeta + friend class ::SwFmtMeta; // SetFmtMeta, NotifyChangeTxtNode friend class ::SwXMeta; // GetTxtNode, GetTxtAttr SwFmtMeta * m_pFmt; @@ -151,6 +151,8 @@ protected: SwFmtMeta * GetFmtMeta() const { return m_pFmt; } void SetFmtMeta( SwFmtMeta * const i_pFmt ) { m_pFmt = i_pFmt; }; + void NotifyChangeTxtNode(); + public: explicit Meta(SwFmtMeta * const i_pFmt = 0); virtual ~Meta(); diff --git a/sw/inc/txtatr.hxx b/sw/inc/txtatr.hxx index d9e9463a30a7..8c0ad5854665 100644 --- a/sw/inc/txtatr.hxx +++ b/sw/inc/txtatr.hxx @@ -80,7 +80,7 @@ public: const xub_StrLen i_nStart, const xub_StrLen i_nEnd ); virtual ~SwTxtMeta(); - void ChgTxtNode( SwTxtNode * const pNode ) { m_pTxtNode = pNode; } + void ChgTxtNode(SwTxtNode * const pNode); SwTxtNode * GetTxtNode() const { return m_pTxtNode; } }; diff --git a/sw/qa/complex/writer/TextPortionEnumerationTest.java b/sw/qa/complex/writer/TextPortionEnumerationTest.java index a07b3cccadef..8110c82a6e58 100755 --- a/sw/qa/complex/writer/TextPortionEnumerationTest.java +++ b/sw/qa/complex/writer/TextPortionEnumerationTest.java @@ -3097,7 +3097,7 @@ public class TextPortionEnumerationTest extends ComplexTestCase XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xPortion); String type = (String) xPropSet.getPropertyValue("TextPortionType"); - assure("first: not text", type.equals("Text")); + assure("first: not text: " + type, type.equals("Text")); String txt = xPortion.getString(); assure("first: text differs: " + txt, "45".equals(txt)); } diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx index ce24e4ba06b5..29d9c61e1ad8 100644 --- a/sw/source/core/docnode/nodes.cxx +++ b/sw/source/core/docnode/nodes.cxx @@ -47,7 +47,7 @@ #include <ddefld.hxx> #include <swddetbl.hxx> #include <frame.hxx> -#include <fmtmeta.hxx> +#include <txtatr.hxx> #include <docsh.hxx> #include <svtools/smplhint.hxx> @@ -350,8 +350,13 @@ void SwNodes::ChgNode( SwNodeIndex& rDelPos, ULONG nSz, case RES_TXTATR_META: case RES_TXTATR_METAFIELD: - static_cast<SwFmtMeta&>(pAttr->GetAttr()) - .NotifyRemoval(); + { + SwTxtMeta *const pTxtMeta( + static_cast<SwTxtMeta*>(pAttr)); + // force removal of UNO object + pTxtMeta->ChgTxtNode(0); + pTxtMeta->ChgTxtNode(pTxtNd); + } break; default: diff --git a/sw/source/core/txtnode/fmtatr2.cxx b/sw/source/core/txtnode/fmtatr2.cxx index 405358adac59..f7fe06d6b006 100644 --- a/sw/source/core/txtnode/fmtatr2.cxx +++ b/sw/source/core/txtnode/fmtatr2.cxx @@ -650,19 +650,28 @@ void SwFmtMeta::SetTxtAttr(SwTxtMeta * const i_pTxtAttr) } } -void SwFmtMeta::NotifyRemoval() +void SwFmtMeta::NotifyChangeTxtNode(SwTxtNode *const pTxtNode) { // N.B.: do not reset m_pTxtAttr here: see call in nodes.cxx, // where the hint is not deleted! ASSERT(m_pMeta, "NotifyRemoval: no meta ?"); if (m_pMeta) { - SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, - &static_cast<SwModify&>(*m_pMeta) ); // cast to proper base class! - m_pMeta->Modify(&aMsgHint, &aMsgHint); + if (!pTxtNode) + { + SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, + &static_cast<SwModify&>(*m_pMeta) ); // cast to base class! + m_pMeta->Modify(&aMsgHint, &aMsgHint); + } + else + { // do not call Modify, that would call SwXMeta::Modify! + m_pMeta->NotifyChangeTxtNode(); + } } } +// UGLY: this really awful method fixes up an inconsistent state, +// and if it is not called when copying, total chaos will undoubtedly ensue void SwFmtMeta::DoCopy(SwFmtMeta & rOriginalMeta) { ASSERT(m_pMeta, "DoCopy called for SwFmtMeta with no sw::Meta?"); @@ -673,6 +682,8 @@ void SwFmtMeta::DoCopy(SwFmtMeta & rOriginalMeta) // inserted via MakeTxtAttr! so fix it up to point at the original item // (maybe would be better to tell MakeTxtAttr that it creates a copy?) pOriginal->SetFmtMeta(&rOriginalMeta); + // force pOriginal to register in original text node! + pOriginal->NotifyChangeTxtNode(); if (RES_TXTATR_META == Which()) { m_pMeta.reset( new ::sw::Meta(this) ); @@ -685,7 +696,10 @@ void SwFmtMeta::DoCopy(SwFmtMeta & rOriginalMeta) m_pMeta = pTargetDoc->GetMetaFieldManager().makeMetaField( this, pMetaField->m_nNumberFormat, pMetaField->IsFixedLanguage() ); } + // this cannot be done in Clone: a Clone is not necessarily a copy! m_pMeta->RegisterAsCopyOf(*pOriginal); + // force copy Meta to register in target text node! + m_pMeta->NotifyChangeTxtNode(); } } @@ -718,14 +732,23 @@ SwTxtNode * Meta::GetTxtNode() const return (pTxtAttr) ? pTxtAttr->GetTxtNode() : 0; } -// SwClient -void Meta::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +void Meta::NotifyChangeTxtNode() { SwTxtNode * const pTxtNode( GetTxtNode() ); if (pTxtNode && (GetRegisteredIn() != pTxtNode)) { pTxtNode->Add(this); } + else if (!pTxtNode && GetRegisteredIn()) + { + const_cast<SwModify *>(GetRegisteredIn())->Remove(this); + } +} + +// SwClient +void Meta::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +{ + NotifyChangeTxtNode(); SwModify::Modify(pOld, pNew); } diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index ba471381cad4..3300294f9e4b 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -114,6 +114,11 @@ struct TxtAttrDeleter TxtAttrDeleter( SwDoc & rDoc ) : m_rPool( rDoc.GetAttrPool() ) { } void operator() (SwTxtAttr * const pAttr) { + if (RES_TXTATR_META == pAttr->Which() || + RES_TXTATR_METAFIELD == pAttr->Which()) + { + static_cast<SwTxtMeta *>(pAttr)->ChgTxtNode(0); // prevents ASSERT + } SwTxtAttr::Destroy( pAttr, m_rPool ); } }; @@ -1178,7 +1183,7 @@ void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr ) case RES_TXTATR_META: case RES_TXTATR_METAFIELD: - static_cast<SwFmtMeta&>(pAttr->GetAttr()).NotifyRemoval(); + static_cast<SwTxtMeta*>(pAttr)->ChgTxtNode(0); break; default: diff --git a/sw/source/core/txtnode/txtatr2.cxx b/sw/source/core/txtnode/txtatr2.cxx index afed4e1af732..e3f1d1386a95 100644 --- a/sw/source/core/txtnode/txtatr2.cxx +++ b/sw/source/core/txtnode/txtatr2.cxx @@ -329,3 +329,13 @@ SwTxtMeta::~SwTxtMeta() } } +void SwTxtMeta::ChgTxtNode(SwTxtNode * const pNode) +{ + m_pTxtNode = pNode; // before Notify! + SwFmtMeta & rFmtMeta( static_cast<SwFmtMeta &>(GetAttr()) ); + if (rFmtMeta.GetTxtAttr() == this) + { + rFmtMeta.NotifyChangeTxtNode(pNode); + } +} + |