Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <sortedobjs.hxx>
30 : :
31 : : #include <algorithm>
32 : : #include <anchoredobject.hxx>
33 : : #include <fmtanchr.hxx>
34 : : #include <fmtsrnd.hxx>
35 : : #include <fmtwrapinfluenceonobjpos.hxx>
36 : : #include <frmfmt.hxx>
37 : : #include <pam.hxx>
38 : : #include <svx/svdobj.hxx>
39 : : #include <IDocumentDrawModelAccess.hxx>
40 : :
41 : :
42 : : using namespace ::com::sun::star;
43 : :
44 : :
45 : 1367 : SwSortedObjs::SwSortedObjs()
46 : : {
47 : 1367 : }
48 : :
49 : 1262 : SwSortedObjs::~SwSortedObjs()
50 : : {
51 : 1262 : }
52 : :
53 : 124316 : sal_uInt32 SwSortedObjs::Count() const
54 : : {
55 : 124316 : return maSortedObjLst.size();
56 : : }
57 : :
58 : 46755 : SwAnchoredObject* SwSortedObjs::operator[]( sal_uInt32 _nIndex ) const
59 : : {
60 : 46755 : SwAnchoredObject* pAnchoredObj = 0L;
61 : :
62 [ + - ]: 46755 : if ( _nIndex >= Count() )
63 : : {
64 : : OSL_FAIL( "<SwSortedObjs::operator[]> - index out of range" );
65 : : }
66 : : else
67 : : {
68 : 46755 : pAnchoredObj = maSortedObjLst[ _nIndex ];
69 : : }
70 : :
71 : 46755 : return pAnchoredObj;
72 : : }
73 : :
74 : : struct ObjAnchorOrder
75 : : {
76 : 628 : bool operator()( const SwAnchoredObject* _pListedAnchoredObj,
77 : : const SwAnchoredObject* _pNewAnchoredObj )
78 : : {
79 : : // get attributes of listed object
80 : 628 : const SwFrmFmt& rFmtListed = _pListedAnchoredObj->GetFrmFmt();
81 : 628 : const SwFmtAnchor* pAnchorListed = &(rFmtListed.GetAnchor());
82 : :
83 : : // get attributes of new object
84 : 628 : const SwFrmFmt& rFmtNew = _pNewAnchoredObj->GetFrmFmt();
85 : 628 : const SwFmtAnchor* pAnchorNew = &(rFmtNew.GetAnchor());
86 : :
87 : : // check for to-page anchored objects
88 [ + + ]: 680 : if ((pAnchorListed->GetAnchorId() == FLY_AT_PAGE) &&
[ + + + + ]
89 : 52 : (pAnchorNew ->GetAnchorId() != FLY_AT_PAGE))
90 : : {
91 : 24 : return true;
92 : : }
93 [ + + + + ]: 1180 : else if ((pAnchorListed->GetAnchorId() != FLY_AT_PAGE) &&
[ + + ]
94 : 576 : (pAnchorNew ->GetAnchorId() == FLY_AT_PAGE))
95 : : {
96 : 6 : return false;
97 : : }
98 [ + + + - ]: 626 : else if ((pAnchorListed->GetAnchorId() == FLY_AT_PAGE) &&
[ + + ]
99 : 28 : (pAnchorNew ->GetAnchorId() == FLY_AT_PAGE))
100 : : {
101 : 28 : return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
102 : : }
103 : :
104 : : // Both objects aren't anchored to page.
105 : : // Thus, check for to-fly anchored objects
106 [ - + # # ]: 570 : if ((pAnchorListed->GetAnchorId() == FLY_AT_FLY) &&
[ - + ]
107 : 0 : (pAnchorNew ->GetAnchorId() != FLY_AT_FLY))
108 : : {
109 : 0 : return true;
110 : : }
111 [ + - - + ]: 1140 : else if ((pAnchorListed->GetAnchorId() != FLY_AT_FLY) &&
[ - + ]
112 : 570 : (pAnchorNew ->GetAnchorId() == FLY_AT_FLY))
113 : : {
114 : 0 : return false;
115 : : }
116 [ - + # # ]: 570 : else if ((pAnchorListed->GetAnchorId() == FLY_AT_FLY) &&
[ - + ]
117 : 0 : (pAnchorNew ->GetAnchorId() == FLY_AT_FLY))
118 : : {
119 : 0 : return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
120 : : }
121 : :
122 : : // Both objects aren't anchor to page or to fly
123 : : // Thus, compare content anchor nodes, if existing.
124 : 570 : const SwPosition* pCntntAnchorListed = pAnchorListed->GetCntntAnchor();
125 : 570 : const SwPosition* pCntntAnchorNew = pAnchorNew->GetCntntAnchor();
126 [ + - + + ]: 1140 : if ( pCntntAnchorListed && pCntntAnchorNew &&
[ + + ][ + - ]
127 : 570 : pCntntAnchorListed->nNode != pCntntAnchorNew->nNode )
128 : : {
129 : 14 : return pCntntAnchorListed->nNode < pCntntAnchorNew->nNode;
130 : : }
131 : :
132 : : // objects anchored at the same content.
133 : : // --> OD 2006-11-29 #???# - objects have to be ordered by anchor node position
134 : : // Thus, compare content anchor node positions and anchor type,
135 : : // if not anchored at-paragraph
136 [ + + + + ]: 1030 : if ((pAnchorListed->GetAnchorId() != FLY_AT_PARA) &&
[ + - ][ + - ]
[ + + ]
137 : 474 : (pAnchorNew ->GetAnchorId() != FLY_AT_PARA) &&
138 : : pCntntAnchorListed && pCntntAnchorNew )
139 : : {
140 [ + + ]: 460 : if ( pCntntAnchorListed->nContent != pCntntAnchorNew->nContent )
141 : : {
142 : 418 : return pCntntAnchorListed->nContent < pCntntAnchorNew->nContent;
143 : : }
144 [ + + - + ]: 78 : else if ((pAnchorListed->GetAnchorId() == FLY_AT_CHAR) &&
[ - + ]
145 : 36 : (pAnchorNew ->GetAnchorId() == FLY_AS_CHAR))
146 : : {
147 : 0 : return true;
148 : : }
149 [ + + + - ]: 48 : else if ((pAnchorListed->GetAnchorId() == FLY_AS_CHAR) &&
[ + + ]
150 : 6 : (pAnchorNew ->GetAnchorId() == FLY_AT_CHAR))
151 : : {
152 : 6 : return false;
153 : : }
154 : : }
155 : :
156 : : // objects anchored at the same content and at the same content anchor
157 : : // node position with the same anchor type
158 : : // Thus, compare its wrapping style including its layer
159 : 132 : const IDocumentDrawModelAccess* pIDDMA = rFmtListed.getIDocumentDrawModelAccess();
160 : 132 : const SdrLayerID nHellId = pIDDMA->GetHellId();
161 : 132 : const SdrLayerID nInvisibleHellId = pIDDMA->GetInvisibleHellId();
162 : : const bool bWrapThroughOrHellListed =
163 : 132 : rFmtListed.GetSurround().GetSurround() == SURROUND_THROUGHT ||
164 : 126 : _pListedAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
165 [ + + ]: 258 : _pListedAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
[ + + + - ]
166 : : const bool bWrapThroughOrHellNew =
167 : 132 : rFmtNew.GetSurround().GetSurround() == SURROUND_THROUGHT ||
168 : 126 : _pNewAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
169 [ + + ]: 258 : _pNewAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
[ + + + - ]
170 [ + + ]: 132 : if ( bWrapThroughOrHellListed != bWrapThroughOrHellNew )
171 : : {
172 [ + + ]: 30 : if ( bWrapThroughOrHellListed )
173 : 24 : return false;
174 : : else
175 : 6 : return true;
176 : : }
177 [ + + ][ + - ]: 102 : else if ( bWrapThroughOrHellListed && bWrapThroughOrHellNew )
178 : : {
179 : 36 : return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
180 : : }
181 : :
182 : : // objects anchored at the same content with a set text wrapping
183 : : // Thus, compare wrap influences on object position
184 : : const SwFmtWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosListed =
185 : 66 : &(rFmtListed.GetWrapInfluenceOnObjPos());
186 : : const SwFmtWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosNew =
187 : 66 : &(rFmtNew.GetWrapInfluenceOnObjPos());
188 : : // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
189 [ - + ]: 132 : if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true ) !=
190 : 66 : pWrapInfluenceOnObjPosNew->GetWrapInfluenceOnObjPos( true ) )
191 : : {
192 : : // #i35017# - constant name has changed
193 [ # # ]: 0 : if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true )
194 : : == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE )
195 : 0 : return true;
196 : : else
197 : 0 : return false;
198 : : }
199 : :
200 : : // objects anchored at the same content position/page/fly with same
201 : : // wrap influence.
202 : : // Thus, compare anchor order number
203 : 628 : return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
204 : : }
205 : : };
206 : :
207 : 1422 : bool SwSortedObjs::Insert( SwAnchoredObject& _rAnchoredObj )
208 : : {
209 : : // #i51941#
210 [ + - ][ - + ]: 1422 : if ( Contains( _rAnchoredObj ) )
211 : : {
212 : : // list already contains object
213 : : OSL_FAIL( "<SwSortedObjs::Insert()> - already contains object" );
214 : 0 : return true;
215 : : }
216 : :
217 : : // find insert position
218 : : std::vector< SwAnchoredObject* >::iterator aInsPosIter =
219 : : std::lower_bound( maSortedObjLst.begin(), maSortedObjLst.end(),
220 [ + - ]: 1422 : &_rAnchoredObj, ObjAnchorOrder() );
221 : :
222 : : // insert object into list
223 [ + - ]: 1422 : maSortedObjLst.insert( aInsPosIter, &_rAnchoredObj );
224 : :
225 [ + - ]: 1422 : return Contains( _rAnchoredObj );
226 : : }
227 : :
228 : 1145 : bool SwSortedObjs::Remove( SwAnchoredObject& _rAnchoredObj )
229 : : {
230 : 1145 : bool bRet = true;
231 : :
232 : : std::vector< SwAnchoredObject* >::iterator aDelPosIter =
233 [ + - ]: 1145 : std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );
234 : :
235 [ + - ][ - + ]: 1145 : if ( aDelPosIter == maSortedObjLst.end() )
236 : : {
237 : : // object not found.
238 : 0 : bRet = false;
239 : : OSL_FAIL( "<SwSortedObjs::Remove()> - object not found" );
240 : : }
241 : : else
242 : : {
243 [ + - ]: 1145 : maSortedObjLst.erase( aDelPosIter );
244 : : }
245 : :
246 : 1145 : return bRet;
247 : : }
248 : :
249 : 2928 : bool SwSortedObjs::Contains( const SwAnchoredObject& _rAnchoredObj ) const
250 : : {
251 : : std::vector< SwAnchoredObject* >::const_iterator aIter =
252 [ + - ]: 2928 : std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );
253 : :
254 [ + - ]: 2928 : return aIter != maSortedObjLst.end();
255 : : }
256 : :
257 : 70 : bool SwSortedObjs::Update( SwAnchoredObject& _rAnchoredObj )
258 : : {
259 [ - + ]: 70 : if ( !Contains( _rAnchoredObj ) )
260 : : {
261 : : // given anchored object not found in list
262 : : OSL_FAIL( "<SwSortedObjs::Update(..) - sorted list doesn't contain given anchored object" );
263 : 0 : return false;
264 : : }
265 : :
266 [ + + ]: 70 : if ( Count() == 1 )
267 : : {
268 : : // given anchored object is the only one in the list.
269 : 56 : return true;
270 : : }
271 : :
272 : 14 : Remove( _rAnchoredObj );
273 : 14 : Insert( _rAnchoredObj );
274 : :
275 : 70 : return Contains( _rAnchoredObj );
276 : : }
277 : :
278 : 2009 : sal_uInt32 SwSortedObjs::ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const
279 : : {
280 : 2009 : sal_uInt32 nRetLstPos = Count();
281 : :
282 : : std::vector< SwAnchoredObject* >::const_iterator aIter =
283 [ + - ]: 2009 : std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );
284 : :
285 [ + - ][ + - ]: 2009 : if ( aIter != maSortedObjLst.end() )
286 : : {
287 : : // #i51941#
288 : : // nRetLstPos = aIter - maSortedObjLst.begin();
289 : : std::vector< SwAnchoredObject* >::difference_type nPos =
290 [ + - ]: 2009 : aIter - maSortedObjLst.begin();
291 : 2009 : nRetLstPos = sal_uInt32( nPos );
292 : : }
293 : :
294 : 2009 : return nRetLstPos;
295 : : }
296 : :
297 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|