summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsw/inc/fmtmeta.hxx8
-rw-r--r--sw/inc/txtatr.hxx2
-rwxr-xr-xsw/qa/complex/writer/TextPortionEnumerationTest.java2
-rw-r--r--sw/source/core/docnode/nodes.cxx11
-rw-r--r--sw/source/core/txtnode/fmtatr2.cxx35
-rw-r--r--sw/source/core/txtnode/thints.cxx7
-rw-r--r--sw/source/core/txtnode/txtatr2.cxx10
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);
+ }
+}
+