sw/inc/ddefld.hxx                |   22 ++++++++++++++
 sw/inc/swddetbl.hxx              |    4 +-
 sw/source/core/fields/ddefld.cxx |   59 +++++----------------------------------
 sw/source/core/fields/ddetbl.cxx |   48 +++++++++++++++++++++++--------
 4 files changed, 69 insertions(+), 64 deletions(-)

New commits:
commit fa585ae736246126cf1b574f72750b7a57cba947
Author: Bjoern Michaelsen <bjoern.michael...@libreoffice.org>
Date:   Tue Mar 13 00:04:04 2018 +0100

    use sw::WriterMultiListener instead of SwDepend in SwDDETable
    
    Change-Id: Iaf3b3429d48ecebae5aaf27b384377aec607d3ba
    Reviewed-on: https://gerrit.libreoffice.org/51188
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Björn Michaelsen <bjoern.michael...@libreoffice.org>

diff --git a/sw/inc/ddefld.hxx b/sw/inc/ddefld.hxx
index e8c444676e16..938e515caef5 100644
--- a/sw/inc/ddefld.hxx
+++ b/sw/inc/ddefld.hxx
@@ -20,11 +20,33 @@
 #define INCLUDED_SW_INC_DDEFLD_HXX
 
 #include <sfx2/lnkbase.hxx>
+#include <svl/hint.hxx>
 #include "swdllapi.h"
 #include "fldbas.hxx"
+#include "ndarr.hxx"
 
 class SwDoc;
 
+namespace sw
+{
+    struct LinkAnchorSearchHint final : public SfxHint
+    {
+        SwNodes& m_rNodes;
+        const SwNode*& m_rpFoundNode;
+        LinkAnchorSearchHint(SwNodes& rNodes, const SwNode*& rpFoundNode) : 
m_rNodes(rNodes), m_rpFoundNode(rpFoundNode) {};
+        virtual ~LinkAnchorSearchHint() override;
+    };
+    struct InRangeSearchHint final : public SfxHint
+    {
+        SwNodes& m_rNodes;
+        const sal_uLong m_nSttNd, m_nEndNd;
+        const sal_Int32 m_nStt, m_nEnd;
+        bool& m_rIsInRange;
+        InRangeSearchHint(SwNodes& rNodes, const sal_uLong nSttNd, const 
sal_uLong nEndNd, const sal_Int32 nStt, const sal_Int32 nEnd, bool& rIsInRange)
+            : m_rNodes(rNodes), m_nSttNd(nSttNd), m_nEndNd(nEndNd), 
m_nStt(nStt), m_nEnd(nEnd), m_rIsInRange(rIsInRange) {}
+    };
+}
+
 // FieldType for DDE
 class SW_DLLPUBLIC SwDDEFieldType : public SwFieldType
 {
diff --git a/sw/inc/swddetbl.hxx b/sw/inc/swddetbl.hxx
index ea56c56b6be9..6e5cbf090a06 100644
--- a/sw/inc/swddetbl.hxx
+++ b/sw/inc/swddetbl.hxx
@@ -20,12 +20,14 @@
 #define INCLUDED_SW_INC_SWDDETBL_HXX
 
 #include "swtable.hxx"
+#include "ddefld.hxx"
 
 class SwDDEFieldType;
 
 class SwDDETable : public SwTable
 {
-    SwDepend aDepend;
+    sw::WriterMultiListener m_aDepends;
+    SwDDEFieldType* m_pDDEType;
 public:
 
     // Ctor moves all lines/boxes from SwTable to it.
diff --git a/sw/source/core/fields/ddefld.cxx b/sw/source/core/fields/ddefld.cxx
index 557124dcf7f2..f25b012953d5 100644
--- a/sw/source/core/fields/ddefld.cxx
+++ b/sw/source/core/fields/ddefld.cxx
@@ -168,66 +168,25 @@ void SwIntrnlRefLink::Closed()
     SvBaseLink::Closed();
 }
 
+sw::LinkAnchorSearchHint::~LinkAnchorSearchHint() {};
+
 const SwNode* SwIntrnlRefLink::GetAnchor() const
 {
     // here, any anchor of the normal NodesArray should be sufficient
     const SwNode* pNd = nullptr;
-    SwIterator<SwClient,SwFieldType> aIter(rFieldType);
-    for(SwClient* pLast = aIter.First(); pLast; pLast = aIter.Next())
-    {
-        // a DDE table or a DDE field attribute in the text
-        if( dynamic_cast<const SwFormatField *>(pLast) == nullptr)
-        {
-            SwDepend* pDep = static_cast<SwDepend*>(pLast);
-            SwDDETable* pDDETable = 
static_cast<SwDDETable*>(pDep->GetToTell());
-            pNd = pDDETable->GetTabSortBoxes()[0]->GetSttNd();
-        }
-        else if( static_cast<SwFormatField*>(pLast)->GetTextField() )
-            pNd = 
static_cast<SwFormatField*>(pLast)->GetTextField()->GetpTextNode();
-
-        if( pNd && &rFieldType.GetDoc()->GetNodes() == &pNd->GetNodes() )
-            break;
-        pNd = nullptr;
-    }
+    
rFieldType.CallSwClientNotify(sw::LinkAnchorSearchHint(rFieldType.GetDoc()->GetNodes(),
 pNd));
     return pNd;
 }
 
 bool SwIntrnlRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd,
                                 sal_Int32 nStt, sal_Int32 nEnd ) const
 {
-    // here, any anchor of the normal NodesArray should be sufficient
-    SwNodes* pNds = &rFieldType.GetDoc()->GetNodes();
-    SwIterator<SwClient,SwFieldType> aIter(rFieldType);
-    for(SwClient* pLast = aIter.First(); pLast; pLast = aIter.Next())
-    {
-        // a DDE table or a DDE field attribute in the text
-        if( dynamic_cast<const SwFormatField *>(pLast) == nullptr)
-        {
-            SwDepend* pDep = static_cast<SwDepend*>(pLast);
-            SwDDETable* pDDETable = 
static_cast<SwDDETable*>(pDep->GetToTell());
-            const SwTableNode* pTableNd = pDDETable->GetTabSortBoxes()[0]->
-                            GetSttNd()->FindTableNode();
-            if( pTableNd->GetNodes().IsDocNodes() &&
-                nSttNd < pTableNd->EndOfSectionIndex() &&
-                nEndNd > pTableNd->GetIndex() )
-                return true;
-        }
-        else if( static_cast<SwFormatField*>(pLast)->GetTextField() )
-        {
-            const SwTextField* pTField = 
static_cast<SwFormatField*>(pLast)->GetTextField();
-            const SwTextNode* pNd = pTField->GetpTextNode();
-            if( pNd && pNds == &pNd->GetNodes() )
-            {
-                sal_uLong nNdPos = pNd->GetIndex();
-                if( nSttNd <= nNdPos && nNdPos <= nEndNd &&
-                    ( nNdPos != nSttNd || pTField->GetStart() >= nStt ) &&
-                    ( nNdPos != nEndNd || pTField->GetStart() < nEnd ))
-                    return true;
-            }
-        }
-    }
-
-    return false;
+    bool bInRange = false;
+    rFieldType.CallSwClientNotify(sw::InRangeSearchHint(
+        rFieldType.GetDoc()->GetNodes(),
+        nSttNd, nEndNd, nStt, nEnd,
+        bInRange));
+    return bInRange;
 }
 
 SwDDEFieldType::SwDDEFieldType(const OUString& rName,
diff --git a/sw/source/core/fields/ddetbl.cxx b/sw/source/core/fields/ddetbl.cxx
index 0047f22f8296..174e0aacaee4 100644
--- a/sw/source/core/fields/ddetbl.cxx
+++ b/sw/source/core/fields/ddetbl.cxx
@@ -32,13 +32,15 @@
 #include <fldupde.hxx>
 #include <swtblfmt.hxx>
 #include <fieldhint.hxx>
+#include <ddefld.hxx>
 
 
 /// Ctor moves all lines/boxes from a SwTable into itself.
 /// Afterwards the SwTable is empty and must be deleted.
 SwDDETable::SwDDETable( SwTable& rTable, SwDDEFieldType* pDDEType, bool 
bUpdate )
-    : SwTable( rTable ), aDepend( this, pDDEType )
+    : SwTable(rTable), m_aDepends(*this), m_pDDEType(pDDEType)
 {
+    m_aDepends.StartListening(m_pDDEType);
     // copy the table data
     m_TabSortContentBoxes.insert(rTable.GetTabSortBoxes());
     rTable.GetTabSortBoxes().clear();
@@ -63,22 +65,22 @@ SwDDETable::SwDDETable( SwTable& rTable, SwDDEFieldType* 
pDDEType, bool bUpdate
 
 SwDDETable::~SwDDETable()
 {
-    SwDDEFieldType* pFieldTyp = 
static_cast<SwDDEFieldType*>(aDepend.GetRegisteredIn());
     SwDoc* pDoc = GetFrameFormat()->GetDoc();
     if (!pDoc->IsInDtor() && !m_aLines.empty())
     {
         assert(m_pTableNode);
         if (m_pTableNode->GetNodes().IsDocNodes())
         {
-            pFieldTyp->DecRefCnt();
+            m_pDDEType->DecRefCnt();
         }
     }
 
     // If it is the last dependent of the "deleted field" than delete it 
finally
-    if( pFieldTyp->IsDeleted() && pFieldTyp->HasOnlyOneListener() )
+    if( m_pDDEType->IsDeleted() && m_pDDEType->HasOnlyOneListener() )
     {
-        pFieldTyp->Remove( &aDepend );
-        delete pFieldTyp;
+        m_aDepends.EndListeningAll();
+        delete m_pDDEType;
+        m_pDDEType = nullptr;
     }
 }
 
@@ -93,10 +95,32 @@ void SwDDETable::Modify( const SfxPoolItem* pOld, const 
SfxPoolItem* pNew )
 void SwDDETable::SwClientNotify( const SwModify& rModify, const SfxHint& rHint 
)
 {
     SwClient::SwClientNotify(rModify, rHint);
-    const SwFieldHint* pHint = dynamic_cast<const SwFieldHint*>( &rHint );
-    if ( pHint )
+    if(dynamic_cast<const SwFieldHint*>(&rHint))
         // replace DDETable by real table
         NoDDETable();
+    else if(const auto pLinkAnchorHint = dynamic_cast<const 
sw::LinkAnchorSearchHint*>(&rHint))
+    {
+        if(pLinkAnchorHint->m_rpFoundNode)
+            return;
+        const auto pNd = GetTabSortBoxes()[0]->GetSttNd();
+        if( pNd && &pLinkAnchorHint->m_rNodes == &pNd->GetNodes() )
+            pLinkAnchorHint->m_rpFoundNode = pNd;
+    }
+    else if(const sw::InRangeSearchHint* pInRangeHint = dynamic_cast<const 
sw::InRangeSearchHint*>(&rHint))
+    {
+        if(pInRangeHint->m_rIsInRange)
+            return;
+        const SwTableNode* pTableNd = 
GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
+        if( pTableNd->GetNodes().IsDocNodes() &&
+                pInRangeHint->m_nSttNd < pTableNd->EndOfSectionIndex() &&
+                pInRangeHint->m_nEndNd > pTableNd->GetIndex() )
+            pInRangeHint->m_rIsInRange = true;
+    }
+    else if (auto pModifyChangedHint = dynamic_cast<const 
sw::ModifyChangedHint*>(&rHint))
+    {
+        if(m_pDDEType == &rModify)
+            m_pDDEType = const_cast<SwDDEFieldType*>(static_cast<const 
SwDDEFieldType*>(pModifyChangedHint->m_pNew));
+    }
 }
 
 void SwDDETable::ChangeContent()
@@ -110,10 +134,8 @@ void SwDDETable::ChangeContent()
     if( !GetTabSortBoxes()[0]->GetSttNd()->GetNodes().IsDocNodes() )
         return;
 
-    // access to DDEFieldType
-    SwDDEFieldType* pDDEType = 
static_cast<SwDDEFieldType*>(aDepend.GetRegisteredIn());
 
-    OUString aExpand = pDDEType->GetExpansion().replaceAll("\r", "");
+    OUString aExpand = m_pDDEType->GetExpansion().replaceAll("\r", "");
     sal_Int32 nExpandTokenPos = 0;
 
     for( size_t n = 0; n < m_aLines.size(); ++n )
@@ -147,7 +169,7 @@ void SwDDETable::ChangeContent()
 
 SwDDEFieldType* SwDDETable::GetDDEFieldType()
 {
-    return static_cast<SwDDEFieldType*>(aDepend.GetRegisteredIn());
+    return m_pDDEType;
 }
 
 bool SwDDETable::NoDDETable()
@@ -178,7 +200,7 @@ bool SwDDETable::NoDDETable()
     GetTabLines().clear();
 
     if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() )
-        static_cast<SwDDEFieldType*>(aDepend.GetRegisteredIn())->DecRefCnt();
+        m_pDDEType->DecRefCnt();
 
     pTableNd->SetNewTable( pNewTable );       // replace table
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to