blob: e68097e983d1cf3de06b6437919ac63999bcb016 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include <sortedobjsimpl.hxx>
#include <algorithm>
#include <anchoredobject.hxx>
#include <frmfmt.hxx>
#include <svx/svdobj.hxx>
#include <pam.hxx>
#include <txtfrm.hxx>
#include <ndtxt.hxx>
#include <fmtsrnd.hxx>
#include <fmtwrapinfluenceonobjpos.hxx>
#include <IDocumentDrawModelAccess.hxx>
using namespace ::com::sun::star;
typedef std::vector< SwAnchoredObject* >::iterator tIter;
typedef std::vector< SwAnchoredObject* >::const_iterator tConstIter;
SwSortedObjsImpl::SwSortedObjsImpl()
{
}
SwSortedObjsImpl::~SwSortedObjsImpl()
{
}
sal_uInt32 SwSortedObjsImpl::Count() const
{
return maSortedObjLst.size();
}
SwAnchoredObject* SwSortedObjsImpl::operator[]( sal_uInt32 _nIndex )
{
SwAnchoredObject* pAnchoredObj = 0L;
if ( _nIndex >= Count() )
{
ASSERT( false, "<SwSortedObjsImpl::operator[]> - index out of range" );
}
else
{
pAnchoredObj = maSortedObjLst[ _nIndex ];
}
return pAnchoredObj;
}
struct ObjAnchorOrder
{
bool operator()( const SwAnchoredObject* _pListedAnchoredObj,
const SwAnchoredObject* _pNewAnchoredObj )
{
// get attributes of listed object
const SwFrmFmt& rFmtListed = _pListedAnchoredObj->GetFrmFmt();
const SwFmtAnchor* pAnchorListed = &(rFmtListed.GetAnchor());
// get attributes of new object
const SwFrmFmt& rFmtNew = _pNewAnchoredObj->GetFrmFmt();
const SwFmtAnchor* pAnchorNew = &(rFmtNew.GetAnchor());
// check for to-page anchored objects
if ((pAnchorListed->GetAnchorId() == FLY_AT_PAGE) &&
(pAnchorNew ->GetAnchorId() != FLY_AT_PAGE))
{
return true;
}
else if ((pAnchorListed->GetAnchorId() != FLY_AT_PAGE) &&
(pAnchorNew ->GetAnchorId() == FLY_AT_PAGE))
{
return false;
}
else if ((pAnchorListed->GetAnchorId() == FLY_AT_PAGE) &&
(pAnchorNew ->GetAnchorId() == FLY_AT_PAGE))
{
return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
}
// Both objects aren't anchored to page.
// Thus, check for to-fly anchored objects
if ((pAnchorListed->GetAnchorId() == FLY_AT_FLY) &&
(pAnchorNew ->GetAnchorId() != FLY_AT_FLY))
{
return true;
}
else if ((pAnchorListed->GetAnchorId() != FLY_AT_FLY) &&
(pAnchorNew ->GetAnchorId() == FLY_AT_FLY))
{
return false;
}
else if ((pAnchorListed->GetAnchorId() == FLY_AT_FLY) &&
(pAnchorNew ->GetAnchorId() == FLY_AT_FLY))
{
return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
}
// Both objects aren't anchor to page or to fly
// Thus, compare content anchor nodes, if existing.
const SwPosition* pCntntAnchorListed = pAnchorListed->GetCntntAnchor();
const SwPosition* pCntntAnchorNew = pAnchorNew->GetCntntAnchor();
if ( pCntntAnchorListed && pCntntAnchorNew &&
pCntntAnchorListed->nNode != pCntntAnchorNew->nNode )
{
return pCntntAnchorListed->nNode < pCntntAnchorNew->nNode;
}
// objects anchored at the same content.
// --> 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->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))
{
return false;
}
}
// <--
// 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
const IDocumentDrawModelAccess* pIDDMA = rFmtListed.getIDocumentDrawModelAccess();
const SdrLayerID nHellId = pIDDMA->GetHellId();
const SdrLayerID nInvisibleHellId = pIDDMA->GetInvisibleHellId();
const bool bWrapThroughOrHellListed =
rFmtListed.GetSurround().GetSurround() == SURROUND_THROUGHT ||
_pListedAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
_pListedAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
const bool bWrapThroughOrHellNew =
rFmtNew.GetSurround().GetSurround() == SURROUND_THROUGHT ||
_pNewAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
_pNewAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
if ( bWrapThroughOrHellListed != bWrapThroughOrHellNew )
{
if ( bWrapThroughOrHellListed )
return false;
else
return true;
}
else if ( bWrapThroughOrHellListed && bWrapThroughOrHellNew )
{
return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
}
// objects anchored at the same content with a set text wrapping
// Thus, compare wrap influences on object position
const SwFmtWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosListed =
&(rFmtListed.GetWrapInfluenceOnObjPos());
const SwFmtWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosNew =
&(rFmtNew.GetWrapInfluenceOnObjPos());
// --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true ) !=
pWrapInfluenceOnObjPosNew->GetWrapInfluenceOnObjPos( true ) )
// <--
{
// --> OD 2004-10-18 #i35017# - constant name has changed
if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true )
== text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE )
// <--
return true;
else
return false;
}
// objects anchored at the same content position/page/fly with same
// wrap influence.
// Thus, compare anchor order number
return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
}
};
bool SwSortedObjsImpl::Insert( SwAnchoredObject& _rAnchoredObj )
{
// --> OD 2005-08-18 #i51941#
if ( Contains( _rAnchoredObj ) )
{
// list already contains object
#if OSL_DEBUG_LEVEL > 1
ASSERT( false,
"<SwSortedObjsImpl::Insert()> - already contains object" );
#endif
return true;
}
// find insert position
tIter aInsPosIter = std::lower_bound( maSortedObjLst.begin(),
maSortedObjLst.end(),
&_rAnchoredObj, ObjAnchorOrder() );
// insert object into list
maSortedObjLst.insert( aInsPosIter, &_rAnchoredObj );
return Contains( _rAnchoredObj );
}
bool SwSortedObjsImpl::Remove( SwAnchoredObject& _rAnchoredObj )
{
bool bRet = true;
tIter aDelPosIter = std::find( maSortedObjLst.begin(),
maSortedObjLst.end(),
&_rAnchoredObj );
if ( aDelPosIter == maSortedObjLst.end() )
{
// object not found.
bRet = false;
#if OSL_DEBUG_LEVEL > 1
ASSERT( false,
"<SwSortedObjsImpl::Remove()> - object not found" );
#endif
}
else
{
maSortedObjLst.erase( aDelPosIter );
}
return bRet;
}
bool SwSortedObjsImpl::Contains( const SwAnchoredObject& _rAnchoredObj ) const
{
tConstIter aIter = std::find( maSortedObjLst.begin(), maSortedObjLst.end(),
&_rAnchoredObj );
return aIter != maSortedObjLst.end();
}
bool SwSortedObjsImpl::Update( SwAnchoredObject& _rAnchoredObj )
{
if ( !Contains( _rAnchoredObj ) )
{
// given anchored object not found in list
ASSERT( false,
"<SwSortedObjsImpl::Update(..) - sorted list doesn't contain given anchored object" );
return false;
}
if ( Count() == 1 )
{
// given anchored object is the only one in the list.
return true;
}
Remove( _rAnchoredObj );
Insert( _rAnchoredObj );
return Contains( _rAnchoredObj );
}
sal_uInt32 SwSortedObjsImpl::ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const
{
sal_uInt32 nRetLstPos = Count();
tConstIter aIter = std::find( maSortedObjLst.begin(), maSortedObjLst.end(),
&_rAnchoredObj );
if ( aIter != maSortedObjLst.end() )
{
// --> OD 2005-08-18 #i51941#
// nRetLstPos = aIter - maSortedObjLst.begin();
std::vector< SwAnchoredObject* >::difference_type nPos =
aIter - maSortedObjLst.begin();
nRetLstPos = sal_uInt32( nPos );
// <--
}
return nRetLstPos;
}