[Libreoffice-commits] core.git: 8 commits - external/python3 sw/inc sw/source

Michael Stahl mstahl at redhat.com
Sat May 9 02:17:15 PDT 2015


 external/python3/python-3.3.3-py17797.patch.1 |   87 +++++++++---------------
 sw/inc/doc.hxx                                |    5 -
 sw/inc/frmfmt.hxx                             |   23 ------
 sw/inc/node.hxx                               |    9 ++
 sw/source/core/doc/DocumentRedlineManager.cxx |   22 ++----
 sw/source/core/doc/doclay.cxx                 |   21 ++---
 sw/source/core/doc/docnew.cxx                 |    2 
 sw/source/core/docnode/node.cxx               |   30 ++++++++
 sw/source/core/docnode/nodes.cxx              |   52 +++++++++++---
 sw/source/core/layout/atrfrm.cxx              |   94 +++++++++++++++++---------
 sw/source/core/layout/frmtool.cxx             |    9 +-
 sw/source/core/txtnode/ndtxt.cxx              |    8 --
 sw/source/core/undo/undoflystrattr.cxx        |    6 -
 13 files changed, 207 insertions(+), 161 deletions(-)

New commits:
commit 3dcef4ba3f2a14663f84e25d01fa4fd4266f62fb
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sat May 9 03:10:24 2015 +0200

    sw: deploy asserts in lcl_CheckRedline()
    
    Change-Id: Ib5c5758eab44532b383ca49542288a65cb10d548

diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 76e5fec..36fcc4b 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -40,34 +40,26 @@ using namespace com::sun::star;
     {
         // helper function for lcl_CheckRedline
         // 1. make sure that pPos->nContent points into pPos->nNode
-        //    (or into the 'special' no-content-node-IndexReg)
         // 2. check that position is valid and doesn't point after text
         static void lcl_CheckPosition( const SwPosition* pPos )
         {
-            SwPosition aComparePos( *pPos );
-            aComparePos.nContent.Assign(
-                aComparePos.nNode.GetNode().GetCntntNode(), 0 );
-            OSL_ENSURE( pPos->nContent.GetIdxReg() ==
-                        aComparePos.nContent.GetIdxReg(),
-                        _ERROR_PREFIX "illegal position" );
+            assert(dynamic_cast<SwIndexReg*>(&pPos->nNode.GetNode())
+                    == pPos->nContent.GetIdxReg());
 
             SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
             if( pTxtNode == NULL )
             {
-                OSL_ENSURE( pPos->nContent == 0,
-                            _ERROR_PREFIX "non-text-node with content" );
+                assert(pPos->nContent == 0);
             }
             else
             {
-                OSL_ENSURE( pPos->nContent >= 0  &&
-                            pPos->nContent <= pTxtNode->Len(),
-                            _ERROR_PREFIX "index after text" );
+                assert(pPos->nContent >= 0 && pPos->nContent <= pTxtNode->Len());
             }
         }
 
         static void lcl_CheckPam( const SwPaM* pPam )
         {
-            OSL_ENSURE( pPam != NULL, _ERROR_PREFIX "illegal argument" );
+            assert(pPam);
             lcl_CheckPosition( pPam->GetPoint() );
             lcl_CheckPosition( pPam->GetMark() );
         }
commit d60db2401198421d8b69707e49113c89a0ea1616
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sat May 9 00:06:40 2015 +0200

    sw: add assertions to check invariants of frame anchoring
    
    Change-Id: Iddb5936c088dfba0245a0d921c7122a0587bdc9b

diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 5659a96..76e5fec 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -598,6 +598,8 @@ RedlineMode_t DocumentRedlineManager::GetRedlineMode() const
     return meRedlineMode;
 }
 
+void CheckAnchoredFlyConsistency(SwDoc const& rDoc);
+
 void DocumentRedlineManager::SetRedlineMode( RedlineMode_t eMode )
 {
     if( meRedlineMode != eMode )
@@ -628,6 +630,7 @@ void DocumentRedlineManager::SetRedlineMode( RedlineMode_t eMode )
                 break;
             }
 
+            CheckAnchoredFlyConsistency(m_rDoc);
             _CHECK_REDLINE( *this )
 
             if (pFnc)
@@ -641,6 +644,7 @@ void DocumentRedlineManager::SetRedlineMode( RedlineMode_t eMode )
                 mpRedlineTbl->Resort();
             }
 
+            CheckAnchoredFlyConsistency(m_rDoc);
             _CHECK_REDLINE( *this )
             m_rDoc.SetInXMLImport( bSaveInXMLImportFlag );
         }
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 335c85e..e78ae9b 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -3487,4 +3487,65 @@ bool IsFlyFrmFmtInHeader(const SwFrmFmt& rFmt)
     return false;
 }
 
+namespace sw {
+
+void CheckAnchoredFlyConsistency(SwDoc const& rDoc)
+{
+#if OSL_DEBUG_LEVEL > 0
+    SwNodes const& rNodes(rDoc.GetNodes());
+    sal_uLong const count(rNodes.Count());
+    for (sal_uLong i = 0; i != count; ++i)
+    {
+        SwNode const*const pNode(rNodes[i]);
+        std::vector<SwFrmFmt*> const*const pFlys(pNode->GetAnchoredFlys());
+        if (pFlys)
+        {
+            for (auto it = pFlys->begin(); it != pFlys->end(); ++it)
+            {
+                SwFmtAnchor const& rAnchor((**it).GetAnchor(false));
+                assert(&rAnchor.GetCntntAnchor()->nNode.GetNode() == pNode);
+            }
+        }
+    }
+    SwFrmFmts const*const pSpzFrmFmts(rDoc.GetSpzFrmFmts());
+    if (pSpzFrmFmts)
+    {
+        for (auto it = pSpzFrmFmts->begin(); it != pSpzFrmFmts->end(); ++it)
+        {
+            SwFmtAnchor const& rAnchor((**it).GetAnchor(false));
+            if (FLY_AT_PAGE == rAnchor.GetAnchorId())
+            {
+                assert(!rAnchor.GetCntntAnchor());
+            }
+            else
+            {
+                SwNode & rNode(rAnchor.GetCntntAnchor()->nNode.GetNode());
+                std::vector<SwFrmFmt*> const*const pFlys(rNode.GetAnchoredFlys());
+                assert(std::find(pFlys->begin(), pFlys->end(), *it) != pFlys->end());
+                switch (rAnchor.GetAnchorId())
+                {
+                    case FLY_AT_FLY:
+                        assert(rNode.IsStartNode());
+                    break;
+                    case FLY_AT_PARA:
+                        assert(rNode.IsTxtNode() || rNode.IsTableNode());
+                    break;
+                    case FLY_AS_CHAR:
+                    case FLY_AT_CHAR:
+                        assert(rNode.IsTxtNode());
+                    break;
+                    default:
+                        assert(false);
+                    break;
+                }
+            }
+        }
+    }
+#else
+    (void) rDoc;
+#endif
+}
+
+} // namespace sw
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 94be2168635e5305f3dfa3b1baf7f97d85ab026c
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri May 8 23:55:00 2015 +0200

    sw: remove debug code
    
    Change-Id: I187c0b2bd2f9e4ddeeac80b6046c25d5cf674d71

diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index e733d10..ee96eb7 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -2048,23 +2048,6 @@ void SwNode::RemoveAnchoredFly(SwFrmFmt *const pFlyFmt)
     // cannot assert this in Remove because it is called when new anchor is already set
 //    assert(&pFlyFmt->GetAnchor(false).GetCntntAnchor()->nNode.GetNode() == this);
     assert(IsTxtNode() || IsStartNode() || IsTableNode());
-    if (!m_pAnchoredFlys)
-    {
-        SwNodeIndex idx(GetNodes());
-        while (true)
-        {
-            SwNode & rNode(idx.GetNode());
-            if (rNode.m_pAnchoredFlys)
-            {
-                auto it(std::find(rNode.m_pAnchoredFlys->begin(), rNode.m_pAnchoredFlys->end(), pFlyFmt));
-                if (it != rNode.m_pAnchoredFlys->end())
-                {
-                    //XXX bug
-                }
-            }
-            ++idx;
-        }
-    }
     assert(m_pAnchoredFlys);
     auto it(std::find(m_pAnchoredFlys->begin(), m_pAnchoredFlys->end(), pFlyFmt));
     assert(it != m_pAnchoredFlys->end());
commit 4dd2e61e2a52d0b5c582f16732de544391bad3d2
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri May 8 23:53:16 2015 +0200

    sw: fix assert with frames anchored as-char in redlines on rhbz490395-1.odt
    
    SwRangeRedline::Hide() will copy and delete the redlined text range,
    and during the delete it happens that FLY_AS_CHAR frames are not deleted
    before their anchor SwTxtNode is destroyed, so SwFmtAnchor::m_pCntntAnchor
    will have its NodeIndex adjusted by SwNodes::RemoveNode() to a wrong
    node and then it cannot call RemoveAnchoredFly() on the proper node.
    
    Avoid the problem by manually deleting all FLY_AS_CHAR from nodes
    before they are deleted and before the SwNodeIndex adjustment.
    
    (regression from 738fb2ad77e5a1a4d6e2dc540886a17f4527e4db, which had
     the equivalent problem with differing SwNodeIndex keys)
    
    Change-Id: I13c9577c01e3b8976b74fb9c58dc2ef2c2fc0666

diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index 25f94bf..380c103 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -2210,17 +2210,10 @@ void SwNodes::ForEach( const SwNodeIndex& rStart, const SwNodeIndex& rEnd,
 
 void SwNodes::RemoveNode( sal_uLong nDelPos, sal_uLong nSz, bool bDel )
 {
-    sal_uLong nEnd = nDelPos + nSz;
-    SwNode* pNew = (*this)[ nEnd ];
-
-    for(SwNodeIndex& rIndex : vIndices->GetRingContainer())
-    {
-        sal_uLong nIdx = rIndex.GetIndex();
-        if( nDelPos <= nIdx && nIdx < nEnd )
-            rIndex = *pNew;
-    }
-
     {
+#if OSL_DEBUG_LEVEL > 0
+        SwNode *const pFirst((*this)[nDelPos]);
+#endif
         for (sal_uLong nCnt = 0; nCnt < nSz; nCnt++)
         {
             SwNode* pNode = ((*this)[ nDelPos + nCnt ]);
@@ -2229,6 +2222,35 @@ void SwNodes::RemoveNode( sal_uLong nDelPos, sal_uLong nSz, bool bDel )
             if (pTxtNd)
             {
                 pTxtNd->RemoveFromList();
+                // remove FLY_AS_CHAR *before* adjusting SwNodeIndex
+                // so their anchor still points to correct node when deleted!
+                // NOTE: this will call RemoveNode() recursively!
+                // so adjust our indexes to account for removed nodes
+                sal_uLong const nPos = pTxtNd->GetIndex();
+                SwpHints *const pHints(pTxtNd->GetpSwpHints());
+                if (pHints)
+                {
+                    std::vector<SwTxtAttr*> flys;
+                    for (size_t i = 0; i < pHints->Count(); ++i)
+                    {
+                        SwTxtAttr *const pHint(pHints->GetTextHint(i));
+                        if (RES_TXTATR_FLYCNT == pHint->Which())
+                        {
+                            flys.push_back(pHint);
+                        }
+                    }
+                    for (SwTxtAttr * pHint : flys)
+                    {
+                        pTxtNd->DeleteAttribute(pHint);
+                    }   // pHints may be dead now
+                    sal_uLong const nDiff = nPos - pTxtNd->GetIndex();
+                    if (nDiff)
+                    {
+                        nDelPos -= nDiff;
+                    }
+                    assert(pTxtNd == (*this)[nDelPos + nCnt]);
+                    assert(pFirst == (*this)[nDelPos]);
+                }
             }
             SwTableNode* pTableNode = pNode->GetTableNode();
             if (pTableNode)
@@ -2242,6 +2264,16 @@ void SwNodes::RemoveNode( sal_uLong nDelPos, sal_uLong nSz, bool bDel )
         }
     }
 
+    sal_uLong nEnd = nDelPos + nSz;
+    SwNode* pNew = (*this)[ nEnd ];
+
+    for (SwNodeIndex& rIndex : vIndices->GetRingContainer())
+    {
+        sal_uLong const nIdx = rIndex.GetIndex();
+        if (nDelPos <= nIdx && nIdx < nEnd)
+            rIndex = *pNew;
+    }
+
     std::vector<BigPtrEntry> aTempEntries;
     if( bDel )
     {
commit fb0553d6b4905fe2c923a2b5591c001d0be52398
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sat May 9 00:30:45 2015 +0200

    sw: remove bogus assert in SwDoc::IsInHeaderFooter()
    
    If the for loop has a break after the first frame anchored on that node,
    it makes no sense to assert that all frames have been visited.
    
    (regression from bb95f7e6f7c9b1281875e6d729b66b6018794ee0)
    
    Change-Id: Ibd8d65f286b441127be7735c63f4b84ba94dcb6f

diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index 454caac49..e894c92 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -1553,9 +1553,6 @@ bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const
             OSL_ENSURE(mbInReading, "Found a FlySection but not a Format!");
             return false;
         }
-#if OSL_DEBUG_LEVEL > 0
-        assert( checkFmts.empty());
-#endif
     }
 
     return 0 != pNd->FindHeaderStartNode() ||
commit e07feb9457f2ffb373ae69b73dda290140e4005f
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri May 8 23:27:49 2015 +0200

    sw: fix assert with frames anchored in redlines on rhbz490395-1.odt
    
    SwRangeRedline::Show() will move nodes around in the nodes-array, which
    means that using SwNodeIndex as a key in a map that has a lifetime
    not limited by the stack is a bad idea, as the map will become unsorted.
    
    Remove SwFrmFmtAnchorMap from SwDoc and replace it with new
    SwNode::m_pAnchoredFlys to do the same mapping.
    
    (regression from 738fb2ad77e5a1a4d6e2dc540886a17f4527e4db)
    
    Change-Id: I396d92b9d0b2045e98bad6d0b374303cd4e62b59

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 7969c69..1868650 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -103,7 +103,6 @@ class SwFmt;
 class SwFmtINetFmt;
 class SwFmtRefMark;
 class SwFrmFmt;
-class SwFrmFmtAnchorMap;
 class SwFrmFmts;
 class SwFtnIdxs;
 class SwFtnInfo;
@@ -300,7 +299,6 @@ class SW_DLLPUBLIC SwDoc :
     SwGrfFmtColl    *mpDfltGrfFmtColl;
 
     SwFrmFmts       *mpFrmFmtTbl;        //< Format table
-    SwFrmFmtAnchorMap *mpFrmFmtAnchorMap;
     SwCharFmts      *mpCharFmtTbl;
     SwFrmFmts       *mpSpzFrmFmtTbl;
     SwSectionFmts   *mpSectionFmtTbl;
@@ -808,9 +806,6 @@ public:
     const SwCharFmt *GetDfltCharFmt() const { return mpDfltCharFmt;}
           SwCharFmt *GetDfltCharFmt()       { return mpDfltCharFmt;}
 
-    const SwFrmFmtAnchorMap* GetFrmFmtAnchorMap() const { return mpFrmFmtAnchorMap; }
-    SwFrmFmtAnchorMap* GetFrmFmtAnchorMap() { return mpFrmFmtAnchorMap; }
-
     // @return the interface of the management of (auto)styles
     IStyleAccess& GetIStyleAccess() { return *mpStyleAccess; }
 
diff --git a/sw/inc/frmfmt.hxx b/sw/inc/frmfmt.hxx
index 53f3694..33a16b2 100644
--- a/sw/inc/frmfmt.hxx
+++ b/sw/inc/frmfmt.hxx
@@ -23,8 +23,6 @@
 #include <cppuhelper/weakref.hxx>
 #include <tools/gen.hxx>
 #include <format.hxx>
-#include <map>
-#include <ndindex.hxx>
 #include "swdllapi.h"
 
 class SwFlyFrm;
@@ -304,27 +302,6 @@ public:
 
 SW_DLLPUBLIC bool IsFlyFrmFmtInHeader(const SwFrmFmt& rFmt);
 
-/**
- Fast mapping from node positions to SwFrmFmt objects anchored at them.
-
- SwFrmFmt::GetAnchor().GetCntntAnchor() provides the position where the object is anchored.
- This class provides the reverse mapping. It intentionally uses SwNodeIndex instead of SwPosition
- to allow simpler implementation, do SwIndex checking explicitly if needed.
-*/
-class SwFrmFmtAnchorMap
-{
-public:
-    SwFrmFmtAnchorMap( const SwDoc* doc );
-    void Add( SwFrmFmt* fmt, const SwNodeIndex& index );
-    void Remove( SwFrmFmt* fmt, const SwNodeIndex& index );
-    typedef std::multimap< SwNodeIndex, SwFrmFmt* >::const_iterator const_iterator;
-    typedef std::pair< const_iterator, const_iterator > const_iterator_pair;
-    const_iterator_pair equal_range( const SwNodeIndex& pos ) const;
-private:
-    std::multimap< SwNodeIndex, SwFrmFmt* > items;
-    const SwDoc* doc;
-};
-
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx
index d7621be..f3990c6 100644
--- a/sw/inc/node.hxx
+++ b/sw/inc/node.hxx
@@ -94,6 +94,11 @@ class SW_DLLPUBLIC SwNode
     long m_nSerial;
 #endif
 
+    /// all SwFrmFmt that are anchored at the node
+    /// invariant: SwFrmFmt is in the list iff
+    /// SwFrmFmt::GetAnchor().GetCntntAnchor() points to this node
+    std::unique_ptr<std::vector<SwFrmFmt*>> m_pAnchoredFlys;
+
 protected:
     SwStartNode* pStartOfSection;
 
@@ -277,6 +282,10 @@ public:
 
     sal_uInt8 HasPrevNextLayNode() const;
 
+    std::vector<SwFrmFmt *> const* GetAnchoredFlys() const { return m_pAnchoredFlys.get(); }
+    void AddAnchoredFly(SwFrmFmt *);
+    void RemoveAnchoredFly(SwFrmFmt *);
+
     /**
      * Dumps the node structure to the given destination (file nodes.xml in the current directory by default)
      * @since 3.5
diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index c1a1627..454caac49 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -1521,18 +1521,17 @@ bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const
                 checkFmts.push_back( pFmt );
         }
 #endif
-        SwFrmFmtAnchorMap::const_iterator_pair range = GetFrmFmtAnchorMap()->equal_range( SwNodeIndex( *pFlyNd ));
-        SwFrmFmtAnchorMap::const_iterator it;
-        for( it = range.first;
-             it != range.second;
-             ++it )
+        std::vector<SwFrmFmt*> const*const pFlys(pFlyNd->GetAnchoredFlys());
+        bool bFound(false);
+        for (size_t i = 0; pFlys && i < pFlys->size(); ++i)
         {
-            const SwFrmFmt* pFmt = it->second;
+            const SwFrmFmt *const pFmt = (*pFlys)[i];
             const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
             if( pIdx && pFlyNd == &pIdx->GetNode() )
             {
 #if OSL_DEBUG_LEVEL > 0
-                std::list<const SwFrmFmt*>::iterator checkPos = std::find( checkFmts.begin(), checkFmts.end(), pFmt );
+                std::list<const SwFrmFmt*>::iterator checkPos = std::find(
+                        checkFmts.begin(), checkFmts.end(), pFmt );
                 assert( checkPos != checkFmts.end());
                 checkFmts.erase( checkPos );
 #endif
@@ -1545,12 +1544,13 @@ bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const
 
                 pNd = &rAnchor.GetCntntAnchor()->nNode.GetNode();
                 pFlyNd = pNd->FindFlyStartNode();
+                bFound = true;
                 break;
             }
         }
-        if( it == range.second )
+        if (!bFound)
         {
-            OSL_ENSURE( mbInReading, "Found a FlySection but not a Format!" );
+            OSL_ENSURE(mbInReading, "Found a FlySection but not a Format!");
             return false;
         }
 #if OSL_DEBUG_LEVEL > 0
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 0e945b3..899c03a 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -230,7 +230,6 @@ SwDoc::SwDoc()
     mpDfltTxtFmtColl( new SwTxtFmtColl( GetAttrPool(), sTxtCollStr ) ),
     mpDfltGrfFmtColl( new SwGrfFmtColl( GetAttrPool(), sGrfCollStr ) ),
     mpFrmFmtTbl( new SwFrmFmts() ),
-    mpFrmFmtAnchorMap( new SwFrmFmtAnchorMap( this ) ),
     mpCharFmtTbl( new SwCharFmts() ),
     mpSpzFrmFmtTbl( new SwFrmFmts() ),
     mpSectionFmtTbl( new SwSectionFmts() ),
@@ -577,7 +576,6 @@ SwDoc::~SwDoc()
     delete mpDfltCharFmt;
     delete mpDfltFrmFmt;
     delete mpLayoutCache;
-    delete mpFrmFmtAnchorMap;
 
     SfxItemPool::Free(mpAttrPool);
 }
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index 7ad39ab..e733d10 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -342,6 +342,7 @@ SwNode::SwNode( SwNodes& rNodes, sal_uLong nPos, const sal_uInt8 nNdType )
 
 SwNode::~SwNode()
 {
+    assert(!m_pAnchoredFlys || GetDoc()->IsInDtor()); // must all be deleted
 }
 
 /// Find the TableNode in which it is located.
@@ -2028,4 +2029,50 @@ bool SwNode::IsInRedlines() const
     return bResult;
 }
 
+void SwNode::AddAnchoredFly(SwFrmFmt *const pFlyFmt)
+{
+    assert(pFlyFmt);
+    assert(&pFlyFmt->GetAnchor(false).GetCntntAnchor()->nNode.GetNode() == this);
+    // check node type, cf. SwFmtAnchor::SetAnchor()
+    assert(IsTxtNode() || IsStartNode() || IsTableNode());
+    if (!m_pAnchoredFlys)
+    {
+        m_pAnchoredFlys.reset(new std::vector<SwFrmFmt*>);
+    }
+    m_pAnchoredFlys->push_back(pFlyFmt);
+}
+
+void SwNode::RemoveAnchoredFly(SwFrmFmt *const pFlyFmt)
+{
+    assert(pFlyFmt);
+    // cannot assert this in Remove because it is called when new anchor is already set
+//    assert(&pFlyFmt->GetAnchor(false).GetCntntAnchor()->nNode.GetNode() == this);
+    assert(IsTxtNode() || IsStartNode() || IsTableNode());
+    if (!m_pAnchoredFlys)
+    {
+        SwNodeIndex idx(GetNodes());
+        while (true)
+        {
+            SwNode & rNode(idx.GetNode());
+            if (rNode.m_pAnchoredFlys)
+            {
+                auto it(std::find(rNode.m_pAnchoredFlys->begin(), rNode.m_pAnchoredFlys->end(), pFlyFmt));
+                if (it != rNode.m_pAnchoredFlys->end())
+                {
+                    //XXX bug
+                }
+            }
+            ++idx;
+        }
+    }
+    assert(m_pAnchoredFlys);
+    auto it(std::find(m_pAnchoredFlys->begin(), m_pAnchoredFlys->end(), pFlyFmt));
+    assert(it != m_pAnchoredFlys->end());
+    m_pAnchoredFlys->erase(it);
+    if (m_pAnchoredFlys->empty())
+    {
+        m_pAnchoredFlys.reset();
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index f92ec8b..335c85e 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -2532,9 +2532,11 @@ SwFrmFmt::~SwFrmFmt()
 {
     if( !GetDoc()->IsInDtor())
     {
-        const SwFmtAnchor& anchor = GetAnchor();
-        if( anchor.GetCntntAnchor() != NULL )
-            GetDoc()->GetFrmFmtAnchorMap()->Remove( this, anchor.GetCntntAnchor()->nNode );
+        const SwFmtAnchor& rAnchor = GetAnchor();
+        if (rAnchor.GetCntntAnchor() != nullptr)
+        {
+            rAnchor.GetCntntAnchor()->nNode.GetNode().RemoveAnchoredFly(this);
+        }
     }
 }
 
@@ -2627,9 +2629,13 @@ void SwFrmFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
     if( pOld && pOld->Which() == RES_ANCHOR )
         oldAnchorPosition = static_cast< const SwFmtAnchor* >( pOld )->GetCntntAnchor();
     if( oldAnchorPosition != NULL && ( newAnchorPosition == NULL || oldAnchorPosition->nNode.GetIndex() != newAnchorPosition->nNode.GetIndex()))
-        GetDoc()->GetFrmFmtAnchorMap()->Remove( this, oldAnchorPosition->nNode );
+    {
+        oldAnchorPosition->nNode.GetNode().RemoveAnchoredFly(this);
+    }
     if( newAnchorPosition != NULL && ( oldAnchorPosition == NULL || oldAnchorPosition->nNode.GetIndex() != newAnchorPosition->nNode.GetIndex()))
-        GetDoc()->GetFrmFmtAnchorMap()->Add( this, newAnchorPosition->nNode );
+    {
+        newAnchorPosition->nNode.GetNode().AddAnchoredFly(this);
+    }
 }
 
 void SwFrmFmt::RegisterToFormat( SwFmt& rFmt )
@@ -3481,39 +3487,4 @@ bool IsFlyFrmFmtInHeader(const SwFrmFmt& rFmt)
     return false;
 }
 
-
-SwFrmFmtAnchorMap::SwFrmFmtAnchorMap( const SwDoc* _doc )
-: doc( _doc )
-{
-}
-
-void SwFrmFmtAnchorMap::Add( SwFrmFmt* fmt, const SwNodeIndex& pos )
-{
-    (void) doc;
-    assert( pos.GetNode().GetDoc() == doc );
-    items.insert( std::make_pair( pos, fmt ));
-}
-
-void SwFrmFmtAnchorMap::Remove( SwFrmFmt* fmt, const SwNodeIndex& pos )
-{
-    (void) doc;
-    assert( pos.GetNode().GetDoc() == doc );
-    typedef std::multimap< SwNodeIndex, SwFrmFmt* >::iterator iterator;
-    std::pair< iterator, iterator > range = items.equal_range( pos );
-    for( iterator it = range.first; it != range.second; ++it )
-    {
-        if( it->second == fmt )
-        {
-            items.erase( it );
-            return;
-        }
-    }
-    assert( false );
-}
-
-SwFrmFmtAnchorMap::const_iterator_pair SwFrmFmtAnchorMap::equal_range( const SwNodeIndex& pos ) const
-{
-    return items.equal_range( pos );
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 234f2b9..39fdfae 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -1019,12 +1019,11 @@ void AppendObjs( const SwFrmFmts *pTbl, sal_uLong nIndex,
 #else
     (void)pTbl;
 #endif
-    SwFrmFmtAnchorMap::const_iterator_pair range = doc->GetFrmFmtAnchorMap()->equal_range( SwNodeIndex( doc->GetNodes(), nIndex ));
-    for( std::multimap< SwNodeIndex, SwFrmFmt* >::const_iterator it = range.first;
-         it != range.second;
-         )
+    SwNode const& rNode(*doc->GetNodes()[nIndex]);
+    std::vector<SwFrmFmt*> const*const pFlys(rNode.GetAnchoredFlys());
+    for (size_t it = 0; pFlys && it != pFlys->size(); )
     {
-        SwFrmFmt *pFmt = it->second;
+        SwFrmFmt *const pFmt = (*pFlys)[it];
         const SwFmtAnchor &rAnch = pFmt->GetAnchor();
         if ( rAnch.GetCntntAnchor() &&
              (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index c291f14..f1a0a7b 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1133,12 +1133,10 @@ void SwTxtNode::Update(
             }
         }
 #endif
-        SwFrmFmtAnchorMap::const_iterator_pair range = GetDoc()->GetFrmFmtAnchorMap()->equal_range( SwNodeIndex( *this ));
-        for( SwFrmFmtAnchorMap::const_iterator it = range.first;
-             it != range.second;
-             ++it )
+        std::vector<SwFrmFmt*> const*const pFlys(GetAnchoredFlys());
+        for (size_t i = 0; pFlys && i != pFlys->size(); ++i)
         {
-            SwFrmFmt *pFmt = it->second;
+            SwFrmFmt const*const pFmt = (*pFlys)[i];
             const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
             const SwPosition* pCntntAnchor = rAnchor.GetCntntAnchor();
             if (rAnchor.GetAnchorId() == FLY_AT_CHAR && pCntntAnchor)
commit fb73274fcce1edd3d898b7f79700fea96d0040f9
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu May 7 13:39:07 2015 +0200

    sw: convert to assert
    
    Change-Id: Ie5376106adb3df901b9762097e59d7627790443f

diff --git a/sw/source/core/undo/undoflystrattr.cxx b/sw/source/core/undo/undoflystrattr.cxx
index e5a194a..3993ef2 100644
--- a/sw/source/core/undo/undoflystrattr.cxx
+++ b/sw/source/core/undo/undoflystrattr.cxx
@@ -20,6 +20,7 @@
 #include <undoflystrattr.hxx>
 #include <frmfmt.hxx>
 
+
 SwUndoFlyStrAttr::SwUndoFlyStrAttr( SwFlyFrmFmt& rFlyFrmFmt,
                                     const SwUndoId eUndoId,
                                     const OUString& sOldStr,
@@ -29,9 +30,8 @@ SwUndoFlyStrAttr::SwUndoFlyStrAttr( SwFlyFrmFmt& rFlyFrmFmt,
       msOldStr( sOldStr ),
       msNewStr( sNewStr )
 {
-    OSL_ENSURE( eUndoId == UNDO_FLYFRMFMT_TITLE ||
-            eUndoId == UNDO_FLYFRMFMT_DESCRIPTION,
-            "<SwUndoFlyStrAttr::SwUndoFlyStrAttr(..)> - unexpected undo id --> Undo will not work" );
+    assert(eUndoId == UNDO_FLYFRMFMT_TITLE
+        || eUndoId == UNDO_FLYFRMFMT_DESCRIPTION);
 }
 
 SwUndoFlyStrAttr::~SwUndoFlyStrAttr()
commit be3e1d65f50fe8b4ce5e4a87a82ff231c00aae79
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed May 6 22:28:05 2015 +0200

    tdf#82968: python3: fix stdio detection on WNT harder
    
    Upgrade to the latest patch from http://bugs.python.org/issue17797
    which appears to work even if you invoke from cmd.exe
    
    Change-Id: I85f1cc5ad7d8c059d972ae2a6fd2be1bb5604c2c

diff --git a/external/python3/python-3.3.3-py17797.patch.1 b/external/python3/python-3.3.3-py17797.patch.1
index d4f7ab8..8fcb703 100644
--- a/external/python3/python-3.3.3-py17797.patch.1
+++ b/external/python3/python-3.3.3-py17797.patch.1
@@ -4,59 +4,42 @@ http://connect.microsoft.com/VisualStudio/feedback/details/785119/
 Visual Studio 2012 changed return value for fileno function that breaks
 when python tries to check/setup stdin/out/err
 GetStdHandle on Windows XP behaves contrary to the documentation...
-diff -ur python3.org/Python/pythonrun.c python3/Python/pythonrun.c
---- python3.org/Python/pythonrun.c	2014-05-24 16:36:20.361672900 +0200
-+++ python3/Python/pythonrun.c	2014-05-24 16:37:38.424159100 +0200
-@@ -1036,7 +1036,15 @@
-     int status = 0, fd;
-     PyObject * encoding_attr;
-     char *encoding = NULL, *errors;
--
-+#ifdef MS_WINDOWS
-+    OSVERSIONINFOEX osvi;
-+    BOOL bIsWindowsXP;
+
+diff --git a/Python/pythonrun.c b/Python/pythonrun.c
+index 91d56b7..d28ffc7 100644
+--- a/Python/pythonrun.c
++++ b/Python/pythonrun.c
+@@ -1015,13 +1015,28 @@ error:
+ static int
+ is_valid_fd(int fd)
+ {
+-    int dummy_fd;
+     if (fd < 0 || !_PyVerify_fd(fd))
+         return 0;
+-    dummy_fd = dup(fd);
+-    if (dummy_fd < 0)
+-        return 0;
+-    close(dummy_fd);
 +
-+    ZeroMemory(&osvi, sizeof(osvi));
-+    osvi.dwOSVersionInfoSize = sizeof(osvi);
-+    GetVersionEx(&osvi);
-+    bIsWindowsXP = (osvi.dwMajorVersion < 6);
-+#endif
-     /* Hack to avoid a nasty recursion issue when Python is invoked
-        in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
-     if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
-@@ -1084,7 +1092,11 @@
-      * and fileno() may point to an invalid file descriptor. For example
-      * GUI apps don't have valid standard streams by default.
-      */
-+#ifdef MS_WINDOWS
-+    if (!is_valid_fd(fd) || GetStdHandle(STD_INPUT_HANDLE) == NULL || bIsWindowsXP) {
++#if defined(MS_WINDOWS) && defined(HAVE_FSTAT)
++    /* dup (DuplicateHandle) doesn't say fd is a valid *file* handle.
++     * It could be a current thread pseudo-handle.
++     */
++    {
++        struct stat buf;
++        if (fstat(fd, &buf) < 0 && (errno == EBADF || errno == ENOENT))
++            return 0;
++    }
 +#else
-     if (!is_valid_fd(fd)) {
++    {
++        int dummy_fd;
++        dummy_fd = dup(fd);
++        if (dummy_fd < 0)
++            return 0;
++        close(dummy_fd);
++    }
 +#endif
-         std = Py_None;
-         Py_INCREF(std);
-     }
-@@ -1099,7 +1111,11 @@
++
+     return 1;
+ }
  
-     /* Set sys.stdout */
-     fd = fileno(stdout);
-+#ifdef MS_WINDOWS
-+    if (!is_valid_fd(fd) || GetStdHandle(STD_OUTPUT_HANDLE) == NULL || bIsWindowsXP) {
-+#else
-     if (!is_valid_fd(fd)) {
-+#endif
-         std = Py_None;
-         Py_INCREF(std);
-     }
-@@ -1115,7 +1131,11 @@
- #if 1 /* Disable this if you have trouble debugging bootstrap stuff */
-     /* Set sys.stderr, replaces the preliminary stderr */
-     fd = fileno(stderr);
-+#ifdef MS_WINDOWS
-+    if (!is_valid_fd(fd) || GetStdHandle(STD_ERROR_HANDLE) == NULL || bIsWindowsXP) {
-+#else
-     if (!is_valid_fd(fd)) {
-+#endif
-         std = Py_None;
-         Py_INCREF(std);
-     }


More information about the Libreoffice-commits mailing list