Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  sortedobjs.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */


#include <sortedobjs.hxx>

#include <algorithm>
#include <anchoredobject.hxx>
#include <fmtanchr.hxx>
#include <fmtsrnd.hxx>
#include <fmtwrapinfluenceonobjpos.hxx>
#include <frmfmt.hxx>
#include <pam.hxx>
#include <svx/svdobj.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <osl/diagnose.h>

using namespace ::com::sun::star;

SwSortedObjs::SwSortedObjs()
{
}

SwSortedObjs::~SwSortedObjs()
{
}

size_t SwSortedObjs::size() const
{
    return maSortedObjLst.size();
}

SwAnchoredObject* SwSortedObjs::operator[]( size_t _nIndex ) const
{
    SwAnchoredObject* pAnchoredObj = nullptr;

    if ( _nIndex >= size() )
    {
        OSL_FAIL( " - index out of range" );
    }
    else
    {
        pAnchoredObj = maSortedObjLst[ _nIndex ];
    }

    return pAnchoredObj;
}

namespace
{
    int GetAnchorWeight(RndStdIds eAnchor)
    {
        if (eAnchor == RndStdIds::FLY_AT_CHAR)
            return 0;
        if (eAnchor == RndStdIds::FLY_AS_CHAR)
            return 1;
        return 2;
    }

struct ObjAnchorOrder
{
    bool operator()( const SwAnchoredObject* _pListedAnchoredObj,
                     const SwAnchoredObject* _pNewAnchoredObj )
    {
        // get attributes of listed object
        const SwFrameFormat* pFormatListed = _pListedAnchoredObj->GetFrameFormat();
        if (!pFormatListed)
            return false;
        const SwFormatAnchor* pAnchorListed = &(pFormatListed->GetAnchor());

        // get attributes of new object
        const SwFrameFormat* pFormatNew = _pNewAnchoredObj->GetFrameFormat();
        if (!pFormatNew)
            return false;
        const SwFormatAnchor* pAnchorNew = &(pFormatNew->GetAnchor());

        // check for to-page anchored objects
        if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_PAGE) &&
            (pAnchorNew   ->GetAnchorId() != RndStdIds::FLY_AT_PAGE))
        {
            return true;
        }
        else if ((pAnchorListed->GetAnchorId() != RndStdIds::FLY_AT_PAGE) &&
                 (pAnchorNew   ->GetAnchorId() == RndStdIds::FLY_AT_PAGE))
        {
            return false;
        }
        else if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_PAGE) &&
                 (pAnchorNew   ->GetAnchorId() == RndStdIds::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() == RndStdIds::FLY_AT_FLY) &&
            (pAnchorNew   ->GetAnchorId() != RndStdIds::FLY_AT_FLY))
        {
            return true;
        }
        else if ((pAnchorListed->GetAnchorId() != RndStdIds::FLY_AT_FLY) &&
                 (pAnchorNew   ->GetAnchorId() == RndStdIds::FLY_AT_FLY))
        {
            return false;
        }
        else if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_FLY) &&
                 (pAnchorNew   ->GetAnchorId() == RndStdIds::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 SwNode* pContentAnchorListed = pAnchorListed->GetAnchorNode();
        const SwNode* pContentAnchorNew = pAnchorNew->GetAnchorNode();
        if ( pContentAnchorListed && pContentAnchorNew &&
             *pContentAnchorListed != *pContentAnchorNew )
        {
            return *pContentAnchorListed < *pContentAnchorNew;
        }

        // 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 (pContentAnchorListed && pContentAnchorNew)
        {
            sal_Int32 nListedIndex = pAnchorListed->GetAnchorId() != RndStdIds::FLY_AT_PARA ?
                pAnchorListed->GetAnchorContentOffset() : 0;
            sal_Int32 nNewIndex = pAnchorNew->GetAnchorId() != RndStdIds::FLY_AT_PARA ?
                pAnchorNew->GetAnchorContentOffset() : 0;
            if (nListedIndex != nNewIndex)
            {
                return nListedIndex < nNewIndex;
            }
        }

        int nAnchorListedWeight = GetAnchorWeight(pAnchorListed->GetAnchorId());
        int nAnchorNewWeight = GetAnchorWeight(pAnchorNew->GetAnchorId());
        if (nAnchorListedWeight != nAnchorNewWeight)
        {
            return nAnchorListedWeight < nAnchorNewWeight;
        }

        // 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& rIDDMA = pFormatListed->getIDocumentDrawModelAccess();
        const SdrLayerID nHellId = rIDDMA.GetHellId();
        const SdrLayerID nInvisibleHellId = rIDDMA.GetInvisibleHellId();
        const bool bWrapThroughOrHellListed =
                    pFormatListed->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH ||
                    _pListedAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
                    _pListedAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
        const bool bWrapThroughOrHellNew =
                    pFormatNew->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH ||
                    _pNewAnchoredObj->GetDrawObj()->GetLayer() == nHellId ||
                    _pNewAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId;
        if ( bWrapThroughOrHellListed != bWrapThroughOrHellNew )
        {
            return !bWrapThroughOrHellListed;
        }
        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 SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosListed =
                                        &(pFormatListed->GetWrapInfluenceOnObjPos());
        const SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosNew =
                                        &(pFormatNew->GetWrapInfluenceOnObjPos());
        // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
        if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true ) !=
                pWrapInfluenceOnObjPosNew->GetWrapInfluenceOnObjPos( true ) )
        {
            // #i35017# - constant name has changed
            return pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true )
                            == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE;
        }

        // objects anchored at the same content position/page/fly with same
        // wrap influence.
        // Thus, compare anchor order number
        return pAnchorListed->GetOrder() < pAnchorNew->GetOrder();
    }
};

}

bool SwSortedObjs::is_sorted() const
{
    return std::is_sorted(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder());
}

bool SwSortedObjs::Insert( SwAnchoredObject& _rAnchoredObj )
{
    if (!is_sorted())
    {
        SAL_WARN("sw.core""SwSortedObjs::Insert: object list is not sorted");
        UpdateAll();
    }

    // #i51941#
    if ( Contains( _rAnchoredObj ) )
    {
        // list already contains object
        OSL_FAIL( " - already contains object" );
        return true;
    }

    // find insert position
    std::vector< SwAnchoredObject* >::iterator aInsPosIter =
        std::lower_bound( maSortedObjLst.begin(), maSortedObjLst.end(),
                          &_rAnchoredObj, ObjAnchorOrder() );

    // insert object into list
    maSortedObjLst.insert( aInsPosIter, &_rAnchoredObj );

    return Contains( _rAnchoredObj );
}

void SwSortedObjs::Remove( SwAnchoredObject& _rAnchoredObj )
{
    std::vector< SwAnchoredObject* >::iterator aDelPosIter =
        std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );

    if ( aDelPosIter == maSortedObjLst.end() )
    {
        // object not found.
        OSL_FAIL( " - object not found" );
    }
    else
    {
        maSortedObjLst.erase( aDelPosIter );
    }
}

bool SwSortedObjs::Contains( const SwAnchoredObject& _rAnchoredObj ) const
{
    std::vector< SwAnchoredObject* >::const_iterator aIter =
        std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );

    return aIter != maSortedObjLst.end();
}

void SwSortedObjs::Update( const SwAnchoredObject& _rAnchoredObj )
{
    if ( !Contains( _rAnchoredObj ) )
    {
        // given anchored object not found in list
        OSL_FAIL( " );
        return;
    }

    if ( size() == 1 )
    {
        // given anchored object is the only one in the list.
        return;
    }

    if (is_sorted())
        return;

    UpdateAll();
}

void SwSortedObjs::UpdateAll()
{
    std::stable_sort(maSortedObjLst.begin(), maSortedObjLst.end(), ObjAnchorOrder());
}

size_t SwSortedObjs::ListPosOf( const SwAnchoredObject& _rAnchoredObj ) const
{
    std::vector< SwAnchoredObject* >::const_iterator aIter =
        std::find( maSortedObjLst.begin(), maSortedObjLst.end(), &_rAnchoredObj );

    if ( aIter != maSortedObjLst.end() )
    {
        // #i51941#
        std::vector< SwAnchoredObject* >::difference_type nPos =
                                                aIter - maSortedObjLst.begin();
        return static_cast<size_t>( nPos );
    }

    return size();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge