LibreOffice Module sw (master)  1
sortedobjs.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sortedobjs.hxx>
21 
22 #include <algorithm>
23 #include <anchoredobject.hxx>
24 #include <fmtanchr.hxx>
25 #include <fmtsrnd.hxx>
27 #include <frmfmt.hxx>
28 #include <pam.hxx>
29 #include <svx/svdobj.hxx>
31 
32 using namespace ::com::sun::star;
33 
35 {
36 }
37 
39 {
40 }
41 
42 size_t SwSortedObjs::size() const
43 {
44  return maSortedObjLst.size();
45 }
46 
48 {
49  SwAnchoredObject* pAnchoredObj = nullptr;
50 
51  if ( _nIndex >= size() )
52  {
53  OSL_FAIL( "<SwSortedObjs::operator[]> - index out of range" );
54  }
55  else
56  {
57  pAnchoredObj = maSortedObjLst[ _nIndex ];
58  }
59 
60  return pAnchoredObj;
61 }
62 
63 namespace
64 {
65  int GetAnchorWeight(RndStdIds eAnchor)
66  {
67  if (eAnchor == RndStdIds::FLY_AT_CHAR)
68  return 0;
69  if (eAnchor == RndStdIds::FLY_AS_CHAR)
70  return 1;
71  return 2;
72  }
73 }
74 
76 {
77  bool operator()( const SwAnchoredObject* _pListedAnchoredObj,
78  const SwAnchoredObject* _pNewAnchoredObj )
79  {
80  // get attributes of listed object
81  const SwFrameFormat& rFormatListed = _pListedAnchoredObj->GetFrameFormat();
82  const SwFormatAnchor* pAnchorListed = &(rFormatListed.GetAnchor());
83 
84  // get attributes of new object
85  const SwFrameFormat& rFormatNew = _pNewAnchoredObj->GetFrameFormat();
86  const SwFormatAnchor* pAnchorNew = &(rFormatNew.GetAnchor());
87 
88  // check for to-page anchored objects
89  if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_PAGE) &&
90  (pAnchorNew ->GetAnchorId() != RndStdIds::FLY_AT_PAGE))
91  {
92  return true;
93  }
94  else if ((pAnchorListed->GetAnchorId() != RndStdIds::FLY_AT_PAGE) &&
95  (pAnchorNew ->GetAnchorId() == RndStdIds::FLY_AT_PAGE))
96  {
97  return false;
98  }
99  else if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_PAGE) &&
100  (pAnchorNew ->GetAnchorId() == RndStdIds::FLY_AT_PAGE))
101  {
102  return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
103  }
104 
105  // Both objects aren't anchored to page.
106  // Thus, check for to-fly anchored objects
107  if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_FLY) &&
108  (pAnchorNew ->GetAnchorId() != RndStdIds::FLY_AT_FLY))
109  {
110  return true;
111  }
112  else if ((pAnchorListed->GetAnchorId() != RndStdIds::FLY_AT_FLY) &&
113  (pAnchorNew ->GetAnchorId() == RndStdIds::FLY_AT_FLY))
114  {
115  return false;
116  }
117  else if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_FLY) &&
118  (pAnchorNew ->GetAnchorId() == RndStdIds::FLY_AT_FLY))
119  {
120  return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
121  }
122 
123  // Both objects aren't anchor to page or to fly
124  // Thus, compare content anchor nodes, if existing.
125  const SwPosition* pContentAnchorListed = pAnchorListed->GetContentAnchor();
126  const SwPosition* pContentAnchorNew = pAnchorNew->GetContentAnchor();
127  if ( pContentAnchorListed && pContentAnchorNew &&
128  pContentAnchorListed->nNode != pContentAnchorNew->nNode )
129  {
130  return pContentAnchorListed->nNode < pContentAnchorNew->nNode;
131  }
132 
133  // objects anchored at the same content.
134  // --> OD 2006-11-29 #???# - objects have to be ordered by anchor node position
135  // Thus, compare content anchor node positions and anchor type,
136  // if not anchored at-paragraph
137  if (pContentAnchorListed && pContentAnchorNew)
138  {
139  sal_Int32 nListedIndex = pAnchorListed->GetAnchorId() != RndStdIds::FLY_AT_PARA ?
140  pContentAnchorListed->nContent.GetIndex() : 0;
141  sal_Int32 nNewIndex = pAnchorNew->GetAnchorId() != RndStdIds::FLY_AT_PARA ?
142  pContentAnchorNew->nContent.GetIndex() : 0;
143  if (nListedIndex != nNewIndex)
144  {
145  return nListedIndex < nNewIndex;
146  }
147  }
148 
149  int nAnchorListedWeight = GetAnchorWeight(pAnchorListed->GetAnchorId());
150  int nAnchorNewWeight = GetAnchorWeight(pAnchorNew->GetAnchorId());
151  if (nAnchorListedWeight != nAnchorNewWeight)
152  {
153  return nAnchorListedWeight < nAnchorNewWeight;
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  const IDocumentDrawModelAccess& rIDDMA = rFormatListed.getIDocumentDrawModelAccess();
160  const SdrLayerID nHellId = rIDDMA.GetHellId();
161  const SdrLayerID nInvisibleHellId = rIDDMA.GetInvisibleHellId();
162  const bool bWrapThroughOrHellListed =
163  rFormatListed.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH ||
164  _pListedAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
165  _pListedAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
166  const bool bWrapThroughOrHellNew =
167  rFormatNew.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH ||
168  _pNewAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
169  _pNewAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
170  if ( bWrapThroughOrHellListed != bWrapThroughOrHellNew )
171  {
172  return !bWrapThroughOrHellListed;
173  }
174  else if ( bWrapThroughOrHellListed && bWrapThroughOrHellNew )
175  {
176  return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
177  }
178 
179  // objects anchored at the same content with a set text wrapping
180  // Thus, compare wrap influences on object position
181  const SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosListed =
182  &(rFormatListed.GetWrapInfluenceOnObjPos());
183  const SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosNew =
184  &(rFormatNew.GetWrapInfluenceOnObjPos());
185  // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
186  if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true ) !=
187  pWrapInfluenceOnObjPosNew->GetWrapInfluenceOnObjPos( true ) )
188  {
189  // #i35017# - constant name has changed
190  return pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true )
191  == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE;
192  }
193 
194  // objects anchored at the same content position/page/fly with same
195  // wrap influence.
196  // Thus, compare anchor order number
197  return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
198  }
199 };
200 
202 {
203  return std::is_sorted(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder());
204 }
205 
207 {
208  // #i51941#
209  if ( Contains( _rAnchoredObj ) )
210  {
211  // list already contains object
212  OSL_FAIL( "<SwSortedObjs::Insert()> - already contains object" );
213  return true;
214  }
215 
216  // find insert position
217  std::vector< SwAnchoredObject* >::iterator aInsPosIter =
218  std::lower_bound( maSortedObjLst.begin(), maSortedObjLst.end(),
219  &_rAnchoredObj, ObjAnchorOrder() );
220 
221  // insert object into list
222  maSortedObjLst.insert( aInsPosIter, &_rAnchoredObj );
223 
224  return Contains( _rAnchoredObj );
225 }
226 
228 {
229  std::vector< SwAnchoredObject* >::iterator aDelPosIter =
230  std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );
231 
232  if ( aDelPosIter == maSortedObjLst.end() )
233  {
234  // object not found.
235  OSL_FAIL( "<SwSortedObjs::Remove()> - object not found" );
236  }
237  else
238  {
239  maSortedObjLst.erase( aDelPosIter );
240  }
241 }
242 
243 bool SwSortedObjs::Contains( const SwAnchoredObject& _rAnchoredObj ) const
244 {
245  std::vector< SwAnchoredObject* >::const_iterator aIter =
246  std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );
247 
248  return aIter != maSortedObjLst.end();
249 }
250 
252 {
253  if ( !Contains( _rAnchoredObj ) )
254  {
255  // given anchored object not found in list
256  OSL_FAIL( "<SwSortedObjs::Update(..) - sorted list doesn't contain given anchored object" );
257  return;
258  }
259 
260  if ( size() == 1 )
261  {
262  // given anchored object is the only one in the list.
263  return;
264  }
265 
266  Remove( _rAnchoredObj );
267  Insert( _rAnchoredObj );
268 }
269 
271 {
272  std::stable_sort(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder());
273 }
274 
275 size_t SwSortedObjs::ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const
276 {
277  std::vector< SwAnchoredObject* >::const_iterator aIter =
278  std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );
279 
280  if ( aIter != maSortedObjLst.end() )
281  {
282  // #i51941#
283  std::vector< SwAnchoredObject* >::difference_type nPos =
284  aIter - maSortedObjLst.begin();
285  return static_cast<size_t>( nPos );
286  }
287 
288  return size();
289 }
290 
291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void UpdateAll()
Definition: sortedobjs.cxx:270
Marks a position in the document model.
Definition: pam.hxx:35
SwNodeIndex nNode
Definition: pam.hxx:37
bool is_sorted() const
Definition: sortedobjs.cxx:201
void Update(SwAnchoredObject &_rAnchoredObj)
method to update the position of the given anchored object in the sorted list
Definition: sortedobjs.cxx:251
bool operator()(const SwAnchoredObject *_pListedAnchoredObj, const SwAnchoredObject *_pNewAnchoredObj)
Definition: sortedobjs.cxx:77
wrapper class for the positioning of Writer fly frames and drawing objects
SwIndex nContent
Definition: pam.hxx:38
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
SwAnchoredObject * operator[](size_t _nIndex) const
direct access to the entries
Definition: sortedobjs.cxx:47
virtual SdrLayerID GetInvisibleHellId() const =0
Style of a layout element.
Definition: frmfmt.hxx:57
const SdrObject * GetDrawObj() const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
void Remove(SwAnchoredObject &_rAnchoredObj)
Definition: sortedobjs.cxx:227
bool Insert(SwAnchoredObject &_rAnchoredObj)
Definition: sortedobjs.cxx:206
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
size_t size() const
Definition: sortedobjs.cxx:42
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
FlyAnchors.
Definition: fmtanchr.hxx:34
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
std::vector< SwAnchoredObject * > maSortedObjLst
Definition: sortedobjs.hxx:51
virtual SdrLayerID GetHellId() const =0
virtual SdrLayerID GetLayer() const
virtual SwFrameFormat & GetFrameFormat()=0
sal_uInt32 GetOrder() const
Definition: fmtanchr.hxx:69
sal_Int32 GetIndex() const
Definition: index.hxx:95
size_t ListPosOf(const SwAnchoredObject &_rAnchoredObj) const
Position of object <_rAnchoredObj> in sorted list.
Definition: sortedobjs.cxx:275
const SwFormatWrapInfluenceOnObjPos & GetWrapInfluenceOnObjPos(bool=true) const
bool Contains(const SwAnchoredObject &_rAnchoredObj) const
Definition: sortedobjs.cxx:243
RndStdIds
sal_Int16 GetWrapInfluenceOnObjPos(const bool _bIterativeAsOnceConcurrent=false) const
to control, if value has to be treated as
sal_Int32 nPos
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: format.cxx:758