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


Quelle  IndexedStyleSheets.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/.
 */



#include <svl/IndexedStyleSheets.hxx>
#include <svl/style.hxx>

#include <stdexcept>
#include <algorithm>
#include <utility>


namespace {
size_t family_to_index(SfxStyleFamily family)
{
    switch (family) {
    case SfxStyleFamily::Char:
        return 0;
    case SfxStyleFamily::Para:
        return 1;
    case SfxStyleFamily::Frame:
        return 2;
    case SfxStyleFamily::Page:
        return 3;
    case SfxStyleFamily::Pseudo:
        return 4;
    case SfxStyleFamily::Table:
        return 5;
    defaultbreak;
    }
    assert(false); // only for compiler warning. all cases are handled in the switch
    return 0;
}
}

namespace svl {

IndexedStyleSheets::IndexedStyleSheets()
{
}

void IndexedStyleSheets::Register(SfxStyleSheetBase& style, sal_Int32 pos)
{
    mPositionsByName.insert(std::make_pair(style.GetName(), pos));
    size_t position = family_to_index(style.GetFamily());
    mStyleSheetsByFamily.at(position).push_back(&style);
}

void
IndexedStyleSheets::Reindex()
{
    mPositionsByName.clear();
    for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
        mStyleSheetsByFamily[i].clear();
    }

    sal_Int32 i = 0;
    for (const auto& rxStyleSheet : mStyleSheets) {
        SfxStyleSheetBase* p = rxStyleSheet.get();
        Register(*p, i);
        ++i;
    }
}

void
IndexedStyleSheets::ReindexOnNameChange(const SfxStyleSheetBase& style, const OUString& rOldName, const OUString& rNewName)
{
    std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(rOldName);
    for (MapType::const_iterator it = range.first; it != range.second; ++it)
    {
        if (mStyleSheets[it->second].get() == &style)
        {
            unsigned nPos = it->second;
            mPositionsByName.erase(it);
            mPositionsByName.insert(std::make_pair(rNewName, nPos));
            break;
        }
    }
}

void
IndexedStyleSheets::AddStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
{
    if (!HasStyleSheet(style)) {
        mStyleSheets.push_back(style);
        // since we just added an element to the vector, we can safely do -1 as it will always be >= 1
        Register(*style, mStyleSheets.size()-1);
    }
}

bool
IndexedStyleSheets::RemoveStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
{
    std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
    for (MapType::const_iterator it = range.first; it != range.second; ++it)
    {
        sal_Int32 pos = it->second;
        if (mStyleSheets.at(pos) == style)
        {
            mStyleSheets.erase(mStyleSheets.begin() + pos);
            Reindex();
            return true;
        }
    }
    return false;
}

std::vector<sal_Int32> IndexedStyleSheets::FindPositionsByName(const OUString& name) const
{
    std::vector<sal_Int32> r;
    std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(name);
    for (MapType::const_iterator it = range.first; it != range.second; ++it) {
        r.push_back(it->second);
    }
    return r;
}

std::vector<sal_Int32> IndexedStyleSheets::FindPositionsByNameAndPredicate(const OUString& name,
        StyleSheetPredicate& predicate, SearchBehavior behavior) const
{
    std::vector<sal_Int32> r;
    auto range = mPositionsByName.equal_range(name);
    for (auto it = range.first; it != range.second; ++it) {
        sal_Int32 pos = it->second;
        SfxStyleSheetBase *ssheet = mStyleSheets.at(pos).get();
        if (predicate.Check(*ssheet)) {
            r.push_back(pos);
            if (behavior == SearchBehavior::ReturnFirst) {
                break;
            }
        }
    }
    return r;
}


sal_Int32
IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
{
    return std::count_if(mStyleSheets.begin(), mStyleSheets.end(),
        [&predicate](const rtl::Reference<SfxStyleSheetBase>& rxStyleSheet) {
            const SfxStyleSheetBase *ssheet = rxStyleSheet.get();
            return predicate.Check(*ssheet);
        });
}

std::pair<SfxStyleSheetBase*, sal_Int32>
IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
        sal_Int32 n,
        StyleSheetPredicate& predicate,
        sal_Int32 startAt)
{
    SfxStyleSheetBase* retval = nullptr;
    sal_Int32 matching = 0;
    VectorType::const_iterator it = mStyleSheets.begin()+startAt;
    for (; it != mStyleSheets.end(); ++it) {
        SfxStyleSheetBase *ssheet = it->get();
        if (predicate.Check(*ssheet)) {
            if (matching == n) {
                retval = it->get();
                break;
            }
            ++matching;
        }
    }
    return { retval, std::distance(mStyleSheets.cbegin(), it) };
}

sal_Int32 IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase& style) const
{
    VectorType::const_iterator it = std::find(mStyleSheets.begin(), mStyleSheets.end(), &style);
    if (it == mStyleSheets.end()) {
        throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
    }
    return std::distance(mStyleSheets.begin(), it);
}

void
IndexedStyleSheets::Clear(StyleSheetDisposer& disposer)
{
    for (auto& rxStyleSheet : mStyleSheets) {
        disposer.Dispose(rxStyleSheet);

        // tdf#161729 clear style sheets in same order as they were added
        // std::vector::clear() appears to delete elements in the
        // reverse order added. In the case of tdf#161729, a style
        // sheet's SfxItemSet can have a parent SfxItemSet and that
        // parent is the SfxItemSet for a style sheet added later.
        // Deleting from the end of the vector deletes a style sheet
        // and its SfxItemSet. If the now deleted SfxItemSet is a
        // parent SfxItemSet of a style sheet that was added earlier,
        // the style sheet added earlier will now have an SfxItemSet
        // with its parent set to an already deleted pointer. And so
        // a crash will occur when that earlier style sheet is deleted.
        rxStyleSheet.clear();
    }
    mStyleSheets.clear();
    mPositionsByName.clear();
}

IndexedStyleSheets::~IndexedStyleSheets()
{
}

bool
IndexedStyleSheets::HasStyleSheet(const rtl::Reference< SfxStyleSheetBase >& styleconst
{
    std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
    for (MapType::const_iterator it = range.first; it != range.second; ++it)
    {
        if (mStyleSheets.at(it->second) == style)
            return true;
    }
    return false;
}

SfxStyleSheetBase*
IndexedStyleSheets::GetStyleSheetByPosition(sal_Int32 pos)
{
    if( pos < static_cast<sal_Int32>(mStyleSheets.size()) )
        return mStyleSheets.at(pos).get();
    return nullptr;
}

void
IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
{
    for (const auto& rxStyleSheet : mStyleSheets) {
        callback.DoIt(*rxStyleSheet);
    }
}

std::vector<sal_Int32>
IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
{
    std::vector<sal_Int32> r;
    for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
        if (predicate.Check(**it)) {
            r.push_back(std::distance(mStyleSheets.begin(), it));
        }
    }
    return r;
}

const std::vector<SfxStyleSheetBase*>&
IndexedStyleSheets::GetStyleSheetsByFamily(SfxStyleFamily e) const
{
    size_t position = family_to_index(e);
    return mStyleSheetsByFamily.at(position);
}

/* namespace svl */

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

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

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© 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