1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sortedobjsimpl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <sortedobjsimpl.hxx>
36 #include <anchoredobject.hxx>
38 #include <svx/svdobj.hxx>
42 #include <fmtsrnd.hxx>
43 #include <fmtwrapinfluenceonobjpos.hxx>
44 #ifndef IDOCUMENTDRAWMODELACCESS_HXX_INCLUDED
45 #include <IDocumentDrawModelAccess.hxx>
48 using namespace ::com::sun::star
;
50 typedef std::vector
< SwAnchoredObject
* >::iterator tIter
;
51 typedef std::vector
< SwAnchoredObject
* >::const_iterator tConstIter
;
53 using namespace ::com::sun::star
;
56 SwSortedObjsImpl::SwSortedObjsImpl()
60 SwSortedObjsImpl::~SwSortedObjsImpl()
64 sal_uInt32
SwSortedObjsImpl::Count() const
66 return maSortedObjLst
.size();
69 SwAnchoredObject
* SwSortedObjsImpl::operator[]( sal_uInt32 _nIndex
)
71 SwAnchoredObject
* pAnchoredObj
= 0L;
73 if ( _nIndex
>= Count() )
75 ASSERT( false, "<SwSortedObjsImpl::operator[]> - index out of range" );
79 pAnchoredObj
= maSortedObjLst
[ _nIndex
];
87 bool operator()( const SwAnchoredObject
* _pListedAnchoredObj
,
88 const SwAnchoredObject
* _pNewAnchoredObj
)
90 // get attributes of listed object
91 const SwFrmFmt
& rFmtListed
= _pListedAnchoredObj
->GetFrmFmt();
92 const SwFmtAnchor
* pAnchorListed
= &(rFmtListed
.GetAnchor());
94 // get attributes of new object
95 const SwFrmFmt
& rFmtNew
= _pNewAnchoredObj
->GetFrmFmt();
96 const SwFmtAnchor
* pAnchorNew
= &(rFmtNew
.GetAnchor());
98 // check for to-page anchored objects
99 if ( pAnchorListed
->GetAnchorId() == FLY_PAGE
&&
100 pAnchorNew
->GetAnchorId() != FLY_PAGE
)
104 else if ( pAnchorListed
->GetAnchorId() != FLY_PAGE
&&
105 pAnchorNew
->GetAnchorId() == FLY_PAGE
)
109 else if ( pAnchorListed
->GetAnchorId() == FLY_PAGE
&&
110 pAnchorNew
->GetAnchorId() == FLY_PAGE
)
112 return pAnchorListed
->GetOrder() < pAnchorNew
->GetOrder();
115 // Both objects aren't anchored to page.
116 // Thus, check for to-fly anchored objects
117 if ( pAnchorListed
->GetAnchorId() == FLY_AT_FLY
&&
118 pAnchorNew
->GetAnchorId() != FLY_AT_FLY
)
122 else if ( pAnchorListed
->GetAnchorId() != FLY_AT_FLY
&&
123 pAnchorNew
->GetAnchorId() == FLY_AT_FLY
)
127 else if ( pAnchorListed
->GetAnchorId() == FLY_AT_FLY
&&
128 pAnchorNew
->GetAnchorId() == FLY_AT_FLY
)
130 return pAnchorListed
->GetOrder() < pAnchorNew
->GetOrder();
133 // Both objects aren't anchor to page or to fly
134 // Thus, compare content anchor nodes, if existing.
135 const SwPosition
* pCntntAnchorListed
= pAnchorListed
->GetCntntAnchor();
136 const SwPosition
* pCntntAnchorNew
= pAnchorNew
->GetCntntAnchor();
137 if ( pCntntAnchorListed
&& pCntntAnchorNew
&&
138 pCntntAnchorListed
->nNode
!= pCntntAnchorNew
->nNode
)
140 return pCntntAnchorListed
->nNode
< pCntntAnchorNew
->nNode
;
143 // objects anchored at the same content.
144 // --> OD 2006-11-29 #???# - objects have to be ordered by anchor node position
145 // Thus, compare content anchor node positions and anchor type,
146 // if not anchored at-paragraph
147 if ( pAnchorListed
->GetAnchorId() != FLY_AT_CNTNT
&&
148 pAnchorNew
->GetAnchorId() != FLY_AT_CNTNT
&&
149 pCntntAnchorListed
&& pCntntAnchorNew
)
151 if ( pCntntAnchorListed
->nContent
!= pCntntAnchorNew
->nContent
)
153 return pCntntAnchorListed
->nContent
< pCntntAnchorNew
->nContent
;
155 else if ( pAnchorListed
->GetAnchorId() == FLY_AUTO_CNTNT
&&
156 pAnchorNew
->GetAnchorId() == FLY_IN_CNTNT
)
160 else if ( pAnchorListed
->GetAnchorId() == FLY_IN_CNTNT
&&
161 pAnchorNew
->GetAnchorId() == FLY_AUTO_CNTNT
)
168 // objects anchored at the same content and at the same content anchor
169 // node position with the same anchor type
170 // Thus, compare its wrapping style including its layer
171 const IDocumentDrawModelAccess
* pIDDMA
= rFmtListed
.getIDocumentDrawModelAccess();
172 const SdrLayerID nHellId
= pIDDMA
->GetHellId();
173 const SdrLayerID nInvisibleHellId
= pIDDMA
->GetInvisibleHellId();
174 const bool bWrapThroughOrHellListed
=
175 rFmtListed
.GetSurround().GetSurround() == SURROUND_THROUGHT
||
176 _pListedAnchoredObj
->GetDrawObj()->GetLayer() == nHellId
||
177 _pListedAnchoredObj
->GetDrawObj()->GetLayer() == nInvisibleHellId
;
178 const bool bWrapThroughOrHellNew
=
179 rFmtNew
.GetSurround().GetSurround() == SURROUND_THROUGHT
||
180 _pNewAnchoredObj
->GetDrawObj()->GetLayer() == nHellId
||
181 _pNewAnchoredObj
->GetDrawObj()->GetLayer() == nInvisibleHellId
;
182 if ( bWrapThroughOrHellListed
!= bWrapThroughOrHellNew
)
184 if ( bWrapThroughOrHellListed
)
189 else if ( bWrapThroughOrHellListed
&& bWrapThroughOrHellNew
)
191 return pAnchorListed
->GetOrder() < pAnchorNew
->GetOrder();
194 // objects anchored at the same content with a set text wrapping
195 // Thus, compare wrap influences on object position
196 const SwFmtWrapInfluenceOnObjPos
* pWrapInfluenceOnObjPosListed
=
197 &(rFmtListed
.GetWrapInfluenceOnObjPos());
198 const SwFmtWrapInfluenceOnObjPos
* pWrapInfluenceOnObjPosNew
=
199 &(rFmtNew
.GetWrapInfluenceOnObjPos());
200 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
201 if ( pWrapInfluenceOnObjPosListed
->GetWrapInfluenceOnObjPos( true ) !=
202 pWrapInfluenceOnObjPosNew
->GetWrapInfluenceOnObjPos( true ) )
205 // --> OD 2004-10-18 #i35017# - constant name has changed
206 if ( pWrapInfluenceOnObjPosListed
->GetWrapInfluenceOnObjPos( true )
207 == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE
)
214 // objects anchored at the same content position/page/fly with same
216 // Thus, compare anchor order number
217 return pAnchorListed
->GetOrder() < pAnchorNew
->GetOrder();
221 bool SwSortedObjsImpl::Insert( SwAnchoredObject
& _rAnchoredObj
)
223 // --> OD 2005-08-18 #i51941#
224 if ( Contains( _rAnchoredObj
) )
226 // list already contains object
227 #if OSL_DEBUG_LEVEL > 1
229 "<SwSortedObjsImpl::Insert()> - already contains object" );
234 // find insert position
235 tIter aInsPosIter
= std::lower_bound( maSortedObjLst
.begin(),
236 maSortedObjLst
.end(),
237 &_rAnchoredObj
, ObjAnchorOrder() );
239 // insert object into list
240 maSortedObjLst
.insert( aInsPosIter
, &_rAnchoredObj
);
242 return Contains( _rAnchoredObj
);
245 bool SwSortedObjsImpl::Remove( SwAnchoredObject
& _rAnchoredObj
)
249 tIter aDelPosIter
= std::find( maSortedObjLst
.begin(),
250 maSortedObjLst
.end(),
253 if ( aDelPosIter
== maSortedObjLst
.end() )
257 #if OSL_DEBUG_LEVEL > 1
259 "<SwSortedObjsImpl::Remove()> - object not found" );
264 maSortedObjLst
.erase( aDelPosIter
);
270 bool SwSortedObjsImpl::Contains( const SwAnchoredObject
& _rAnchoredObj
) const
272 tConstIter aIter
= std::find( maSortedObjLst
.begin(), maSortedObjLst
.end(),
275 return aIter
!= maSortedObjLst
.end();
278 bool SwSortedObjsImpl::Update( SwAnchoredObject
& _rAnchoredObj
)
280 if ( !Contains( _rAnchoredObj
) )
282 // given anchored object not found in list
284 "<SwSortedObjsImpl::Update(..) - sorted list doesn't contain given anchored object" );
290 // given anchored object is the only one in the list.
294 Remove( _rAnchoredObj
);
295 Insert( _rAnchoredObj
);
297 return Contains( _rAnchoredObj
);
300 sal_uInt32
SwSortedObjsImpl::ListPosOf( const SwAnchoredObject
& _rAnchoredObj
) const
302 sal_uInt32 nRetLstPos
= Count();
304 tConstIter aIter
= std::find( maSortedObjLst
.begin(), maSortedObjLst
.end(),
307 if ( aIter
!= maSortedObjLst
.end() )
309 // --> OD 2005-08-18 #i51941#
310 // nRetLstPos = aIter - maSortedObjLst.begin();
311 std::vector
< SwAnchoredObject
* >::difference_type nPos
=
312 aIter
- maSortedObjLst
.begin();
313 nRetLstPos
= sal_uInt32( nPos
);