diff options
author | Caolán McNamara <caolanm@redhat.com> | 2015-02-11 10:51:13 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-02-11 12:00:03 +0000 |
commit | 0a6a151c4b7c78a363fb64598fbda39db4f42d07 (patch) | |
tree | 5ef9c8bea47a3c5326ba695144745ef2988cb349 | |
parent | 39611d60204cd18e278ea822cfe3ef7ea09e6389 (diff) |
Related: tdf#70062 keep drawing anchor objects sorted
take attachment from tdf#70062, ungroup the bottom pair,
anchor as char the left one, anchor as char the right one
asserts with debugging stl on unsorted container
Change-Id: I3ae763f6d61445f9118ee573a98c69d7a6ee6e4b
-rw-r--r-- | sw/source/core/doc/docfly.cxx | 7 | ||||
-rw-r--r-- | sw/source/core/inc/sortedobjs.hxx | 5 | ||||
-rw-r--r-- | sw/source/core/layout/fly.cxx | 8 | ||||
-rw-r--r-- | sw/source/core/layout/sortedobjs.cxx | 51 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 8 |
5 files changed, 62 insertions, 17 deletions
diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx index 5548ccdd1928..acd472d95644 100644 --- a/sw/source/core/doc/docfly.cxx +++ b/sw/source/core/doc/docfly.cxx @@ -737,7 +737,8 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList, _eAnchorType = eOldAnchorType; SwFmtAnchor aNewAnch( _eAnchorType ); - Rectangle aObjRect( pContact->GetAnchoredObj( pObj )->GetObjRect().SVRect() ); + SwAnchoredObject *pAnchoredObj = pContact->GetAnchoredObj(pObj); + Rectangle aObjRect(pAnchoredObj->GetObjRect().SVRect()); const Point aPt( aObjRect.TopLeft() ); switch ( _eAnchorType ) @@ -894,6 +895,10 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList, } } + // we have changed the anchoring attributes, and those are used to + // order the object in its sorted list, so update its position + pAnchoredObj->UpdateObjInSortedList(); + // #i54336# if (xOldAsCharAnchorPos) { diff --git a/sw/source/core/inc/sortedobjs.hxx b/sw/source/core/inc/sortedobjs.hxx index 9605360d97c7..a57ed1570f82 100644 --- a/sw/source/core/inc/sortedobjs.hxx +++ b/sw/source/core/inc/sortedobjs.hxx @@ -74,7 +74,8 @@ class SwSortedObjs @return boolean, indicating success of the update. */ - bool Update( SwAnchoredObject& _rAnchoredObj ); + bool Update(SwAnchoredObject& _rAnchoredObj); + void UpdateAll(); /** Position of object <_rAnchoredObj> in sorted list @@ -85,6 +86,8 @@ class SwSortedObjs Number of the list position of object <_rAnchoredObj> */ size_t ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const; + + bool is_sorted() const; }; #endif diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index b8b942b456b9..529d19459733 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -2069,6 +2069,8 @@ void SwFrm::RemoveFly( SwFlyFrm *pToRemove ) void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj ) { + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); + if ( !_rNewObj.ISA(SwAnchoredDrawObject) ) { OSL_FAIL( "SwFrm::AppendDrawObj(..) - anchored object of unexpected type -> object not appended" ); @@ -2078,10 +2080,12 @@ void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj ) if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) && _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this ) { + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); // perform disconnect from layout, if 'master' drawing object is appended // to a new frame. static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))-> DisconnectFromLayout( false ); + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); } if ( _rNewObj.GetAnchorFrm() != this ) @@ -2136,6 +2140,8 @@ void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj ) if( pLayout && pLayout->IsAnyShellAccessible() ) pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() ); } + + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); } void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ) @@ -2159,6 +2165,8 @@ void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ) DELETEZ( mpDrawObjs ); _rToRemoveObj.ChgAnchorFrm( 0 ); + + assert(!mpDrawObjs || mpDrawObjs->is_sorted()); } void SwFrm::InvalidateObjs( const bool _bInvaPosOnly, diff --git a/sw/source/core/layout/sortedobjs.cxx b/sw/source/core/layout/sortedobjs.cxx index 0fef218dc07f..5893a4823822 100644 --- a/sw/source/core/layout/sortedobjs.cxx +++ b/sw/source/core/layout/sortedobjs.cxx @@ -60,6 +60,18 @@ SwAnchoredObject* SwSortedObjs::operator[]( size_t _nIndex ) const return pAnchoredObj; } +namespace +{ + int GetAnchorWeight(RndStdIds eAnchor) + { + if (eAnchor == FLY_AT_CHAR) + return 0; + if (eAnchor == FLY_AS_CHAR) + return 1; + return 2; + } +} + struct ObjAnchorOrder { bool operator()( const SwAnchoredObject* _pListedAnchoredObj, @@ -122,26 +134,25 @@ struct ObjAnchorOrder // --> OD 2006-11-29 #???# - objects have to be ordered by anchor node position // Thus, compare content anchor node positions and anchor type, // if not anchored at-paragraph - if ((pAnchorListed->GetAnchorId() != FLY_AT_PARA) && - (pAnchorNew ->GetAnchorId() != FLY_AT_PARA) && - pCntntAnchorListed && pCntntAnchorNew ) + if (pCntntAnchorListed && pCntntAnchorNew) { - if ( pCntntAnchorListed->nContent != pCntntAnchorNew->nContent ) - { - return pCntntAnchorListed->nContent < pCntntAnchorNew->nContent; - } - else if ((pAnchorListed->GetAnchorId() == FLY_AT_CHAR) && - (pAnchorNew ->GetAnchorId() == FLY_AS_CHAR)) - { - return true; - } - else if ((pAnchorListed->GetAnchorId() == FLY_AS_CHAR) && - (pAnchorNew ->GetAnchorId() == FLY_AT_CHAR)) + sal_Int32 nListedIndex = pAnchorListed->GetAnchorId() != FLY_AT_PARA ? + pCntntAnchorListed->nContent.GetIndex() : 0; + sal_Int32 nNewIndex = pAnchorNew->GetAnchorId() != FLY_AT_PARA ? + pCntntAnchorNew->nContent.GetIndex() : 0; + if (nListedIndex != nNewIndex) { - return false; + return nListedIndex < nNewIndex; } } + int nAnchorListedWeight = GetAnchorWeight(pAnchorListed->GetAnchorId()); + int nAnchorNewWeight = GetAnchorWeight(pAnchorNew->GetAnchorId()); + if (nAnchorListedWeight != nAnchorNewWeight) + { + return nAnchorListedWeight < nAnchorNewWeight; + } + // objects anchored at the same content and at the same content anchor // node position with the same anchor type // Thus, compare its wrapping style including its layer @@ -193,6 +204,11 @@ struct ObjAnchorOrder } }; +bool SwSortedObjs::is_sorted() const +{ + return std::is_sorted(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder()); +} + bool SwSortedObjs::Insert( SwAnchoredObject& _rAnchoredObj ) { // #i51941# @@ -264,6 +280,11 @@ bool SwSortedObjs::Update( SwAnchoredObject& _rAnchoredObj ) return Contains( _rAnchoredObj ); } +void SwSortedObjs::UpdateAll() +{ + std::stable_sort(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder()); +} + size_t SwSortedObjs::ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const { std::vector< SwAnchoredObject* >::const_iterator aIter = diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 18da646c44c1..9b1b4a26a311 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -82,6 +82,7 @@ #include <SwNodeNum.hxx> #include <svl/intitem.hxx> #include <list.hxx> +#include <sortedobjs.hxx> #include <switerator.hxx> #include <attrhint.hxx> #include <boost/scoped_ptr.hpp> @@ -1178,6 +1179,13 @@ void SwTxtNode::Update( { getIDocumentMarkAccess()->assureSortedMarkContainers(); } + + //Any drawing objects anchored into this text node may be sorted by their + //anchor position which may have changed here, so resort them + SwCntntFrm* pCntntFrm = getLayoutFrm(GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()); + SwSortedObjs* pSortedObjs = pCntntFrm ? pCntntFrm->GetDrawObjs() : NULL; + if (pSortedObjs) + pSortedObjs->UpdateAll(); } void SwTxtNode::_ChgTxtCollUpdateNum( const SwTxtFmtColl *pOldColl, |