merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / layout / sortedobjsimpl.cxx
blobbd4e128dc4d6e50a9b8a539f32a93d8ec588b632
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sortedobjsimpl.cxx,v $
10 * $Revision: 1.13 $
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>
35 #include <algorithm>
36 #include <anchoredobject.hxx>
37 #include <frmfmt.hxx>
38 #include <svx/svdobj.hxx>
39 #include <pam.hxx>
40 #include <txtfrm.hxx>
41 #include <ndtxt.hxx>
42 #include <fmtsrnd.hxx>
43 #include <fmtwrapinfluenceonobjpos.hxx>
44 #ifndef IDOCUMENTDRAWMODELACCESS_HXX_INCLUDED
45 #include <IDocumentDrawModelAccess.hxx>
46 #endif
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" );
77 else
79 pAnchoredObj = maSortedObjLst[ _nIndex ];
82 return pAnchoredObj;
85 struct ObjAnchorOrder
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 )
102 return true;
104 else if ( pAnchorListed->GetAnchorId() != FLY_PAGE &&
105 pAnchorNew->GetAnchorId() == FLY_PAGE )
107 return false;
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 )
120 return true;
122 else if ( pAnchorListed->GetAnchorId() != FLY_AT_FLY &&
123 pAnchorNew->GetAnchorId() == FLY_AT_FLY )
125 return false;
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 )
158 return true;
160 else if ( pAnchorListed->GetAnchorId() == FLY_IN_CNTNT &&
161 pAnchorNew->GetAnchorId() == FLY_AUTO_CNTNT )
163 return false;
166 // <--
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 )
185 return false;
186 else
187 return true;
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 ) )
203 // <--
205 // --> OD 2004-10-18 #i35017# - constant name has changed
206 if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true )
207 == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE )
208 // <--
209 return true;
210 else
211 return false;
214 // objects anchored at the same content position/page/fly with same
215 // wrap influence.
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
228 ASSERT( false,
229 "<SwSortedObjsImpl::Insert()> - already contains object" );
230 #endif
231 return true;
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 )
247 bool bRet = true;
249 tIter aDelPosIter = std::find( maSortedObjLst.begin(),
250 maSortedObjLst.end(),
251 &_rAnchoredObj );
253 if ( aDelPosIter == maSortedObjLst.end() )
255 // object not found.
256 bRet = false;
257 #if OSL_DEBUG_LEVEL > 1
258 ASSERT( false,
259 "<SwSortedObjsImpl::Remove()> - object not found" );
260 #endif
262 else
264 maSortedObjLst.erase( aDelPosIter );
267 return bRet;
270 bool SwSortedObjsImpl::Contains( const SwAnchoredObject& _rAnchoredObj ) const
272 tConstIter aIter = std::find( maSortedObjLst.begin(), maSortedObjLst.end(),
273 &_rAnchoredObj );
275 return aIter != maSortedObjLst.end();
278 bool SwSortedObjsImpl::Update( SwAnchoredObject& _rAnchoredObj )
280 if ( !Contains( _rAnchoredObj ) )
282 // given anchored object not found in list
283 ASSERT( false,
284 "<SwSortedObjsImpl::Update(..) - sorted list doesn't contain given anchored object" );
285 return false;
288 if ( Count() == 1 )
290 // given anchored object is the only one in the list.
291 return true;
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(),
305 &_rAnchoredObj );
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 );
314 // <--
317 return nRetLstPos;