summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-02-11 10:51:13 +0000
committerCaolán McNamara <caolanm@redhat.com>2015-02-11 12:00:03 +0000
commit0a6a151c4b7c78a363fb64598fbda39db4f42d07 (patch)
tree5ef9c8bea47a3c5326ba695144745ef2988cb349 /sw
parent39611d60204cd18e278ea822cfe3ef7ea09e6389 (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
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/doc/docfly.cxx7
-rw-r--r--sw/source/core/inc/sortedobjs.hxx5
-rw-r--r--sw/source/core/layout/fly.cxx8
-rw-r--r--sw/source/core/layout/sortedobjs.cxx51
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx8
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,