Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/editeng/source/editeng/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 23 kB image not shown  

Quelle  editobj.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 <memory>

#include <o3tl/safeint.hxx>
#include <sal/log.hxx>

#include <editeng/macros.hxx>
#include <editeng/section.hxx>
#include "editobj2.hxx"
#include <editeng/editdata.hxx>
#include <editeng/editeng.hxx>
#include <editeng/flditem.hxx>

#include <svl/sharedstringpool.hxx>
#include <rtl/ustrbuf.hxx>

#include <libxml/xmlwriter.h>
#include <algorithm>
#include <cassert>

#if DEBUG_EDIT_ENGINE
#include <iostream>
using std::cout;
using std::endl;
#endif

using namespace com::sun::star;


XEditAttribute::XEditAttribute(SfxItemPool& rPool, const SfxPoolItem& rItem, sal_Int32 nS, sal_Int32 nE)
: maItemHolder(rPool, &rItem)
, nStart(nS)
, nEnd(nE)
{
}

bool XEditAttribute::IsFeature() const
{
    sal_uInt16 nWhich = GetItem()->Which();
    return  ((nWhich >= EE_FEATURE_START) && (nWhich <=  EE_FEATURE_END));
}

void XEditAttribute::SetItem(SfxItemPool& rPool, const SfxPoolItem& rItem)
{
    maItemHolder = SfxPoolItemHolder(rPool, &rItem);
}

XParaPortionList::XParaPortionList(OutputDevice* pRefDev, sal_uInt32 nPW,
            double fFontScaleX, double fFontScaleY,
            double fSpacingScaleX, double fSpacingScaleY)
    : pRefDevPtr(pRefDev)
    , mfFontScaleX(fFontScaleX)
    , mfFontScaleY(fFontScaleY)
    , mfSpacingScaleX(fSpacingScaleX)
    , mfSpacingScaleY(fSpacingScaleY)
    , nPaperWidth(nPW)
{
}

void XParaPortionList::push_back(XParaPortion* p)
{
    maList.push_back(std::unique_ptr<XParaPortion>(p));
}

const XParaPortion& XParaPortionList::operator [](size_t i) const
{
    return *maList[i];
}

ContentInfo::ContentInfo( SfxItemPool& rPool ) :
    eFamily(SfxStyleFamily::Para),
    aParaAttribs(SfxItemSet::makeFixedSfxItemSet<EE_PARA_START, EE_CHAR_END>(rPool))
{
}

// the real Copy constructor is nonsense, since I have to work with another Pool!
ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse ) :
    maText(rCopyFrom.maText),
    aStyle(rCopyFrom.aStyle),
    eFamily(rCopyFrom.eFamily),
    aParaAttribs(SfxItemSet::makeFixedSfxItemSet<EE_PARA_START, EE_CHAR_END>(rPoolToUse))
{
    // this should ensure that the Items end up in the correct Pool!
    aParaAttribs.Set( rCopyFrom.GetParaAttribs() );

    for (const XEditAttribute & rAttr : rCopyFrom.maCharAttribs)
    {
        maCharAttribs.emplace_back(rPoolToUse, *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd());
    }

    if ( rCopyFrom.GetWrongList() )
        mpWrongs.reset(rCopyFrom.GetWrongList()->Clone());
}

ContentInfo::~ContentInfo()
{
    maCharAttribs.clear();
}

void ContentInfo::NormalizeString( svl::SharedStringPool& rPool )
{
    maText = rPool.intern(OUString(maText.getData()));
}


OUString ContentInfo::GetText() const
{
    rtl_uString* p = const_cast<rtl_uString*>(maText.getData());
    return OUString(p);
}

sal_Int32 ContentInfo::GetTextLen() const
{
    const rtl_uString* p = maText.getData();
    return p->length;
}

void ContentInfo::SetText( const OUString& rStr )
{
    maText = svl::SharedString(rStr.pData, nullptr);
}

void ContentInfo::dumpAsXml(xmlTextWriterPtr pWriter) const
{
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ContentInfo"));
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("style"), BAD_CAST(aStyle.toUtf8().getStr()));
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("text"));
    OUString aText = GetText();
    // TODO share code with sax_fastparser::FastSaxSerializer::write().
    (void)xmlTextWriterWriteString(pWriter, BAD_CAST(aText.replaceAll("\x01""").toUtf8().getStr()));
    (void)xmlTextWriterEndElement(pWriter);
    aParaAttribs.dumpAsXml(pWriter);
    for (auto const& rCharAttribs : maCharAttribs)
    {
        (void)xmlTextWriterStartElement(pWriter, BAD_CAST("attribs"));
        (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("start"), "%" SAL_PRIdINT32, rCharAttribs.GetStart());
        (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("end"), "%" SAL_PRIdINT32, rCharAttribs.GetEnd());
        rCharAttribs.GetItem()->dumpAsXml(pWriter);
        (void)xmlTextWriterEndElement(pWriter);
    }
    (void)xmlTextWriterEndElement(pWriter);
}

const WrongList* ContentInfo::GetWrongList() const
{
    return mpWrongs.get();
}

void ContentInfo::SetWrongList( WrongList* p )
{
    mpWrongs.reset(p);
}

// #i102062#
bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
{
    if(GetWrongList() == rCompare.GetWrongList())
        return true;

    if(!GetWrongList() || !rCompare.GetWrongList())
        return false;

    return (*GetWrongList() == *rCompare.GetWrongList());
}

#if DEBUG_EDIT_ENGINE
void ContentInfo::Dump() const
{
    cout << "--" << endl;
    cout << "text: '" << OUString(const_cast<rtl_uString*>(maText.getData())) << "'" << endl;
    cout << "style: '" << aStyle << "'" << endl;

    for (auto const& attrib : aAttribs)
    {
        cout << "attribute: " << endl;
        cout << " span: [begin=" << attrib.GetStart() << ", end=" << attrib.GetEnd() << "]" << endl;
        cout << " feature: " << (attrib.IsFeature() ? "yes":"no") << endl;
    }
}
#endif

bool ContentInfo::Equals(const ContentInfo& rCompare, bool bComparePool) const
{
    return maText == rCompare.maText && aStyle == rCompare.aStyle && eFamily == rCompare.eFamily
           && aParaAttribs.Equals(rCompare.aParaAttribs, bComparePool)
           && maCharAttribs == rCompare.maCharAttribs;
}

EditTextObject::~EditTextObject() = default;

std::unique_ptr<EditTextObject> EditTextObjectImpl::Clone() const
{
    return std::make_unique<EditTextObjectImpl>(*this);
}

bool EditTextObject::Equals( const EditTextObject& rCompare ) const
{
    return toImpl(*this).Equals(toImpl(rCompare), false /*bComparePool*/);
}

void EditTextObjectImpl::dumpAsXml(xmlTextWriterPtr pWriter) const
{
    bool bOwns = false;
    if (!pWriter)
    {
        pWriter = xmlNewTextWriterFilename("editTextObject.xml", 0);
        xmlTextWriterSetIndent(pWriter,1);
        (void)xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
        (void)xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
        bOwns = true;
    }

    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("EditTextObject"));
    sal_Int32 nCount = GetParagraphCount();
    for (sal_Int32 i = 0; i < nCount; ++i)
    {
        maContents[i]->dumpAsXml(pWriter);
    }
    (void)xmlTextWriterEndElement(pWriter);

    if (bOwns)
    {
       (void)xmlTextWriterEndDocument(pWriter);
       xmlFreeTextWriter(pWriter);
    }
}

#if DEBUG_EDIT_ENGINE
void EditTextObjectImpl::Dump() const
{
    for (auto const& content : maContents)
        content.Dump();
}
#endif

static rtl::Reference<SfxItemPool> getEditEngineItemPool(SfxItemPool* pPool, MapUnit eDefaultMetric)
{
    // #i101239# ensure target is an EditEngineItemPool, so that at
    // pool destruction time of an alien pool, the pool is still alive.
    // When registering would happen at an alien pool which just uses an
    // EditEngineItemPool as some sub-pool, that pool could already
    // be decoupled and deleted which would lead to crashes.
    for (; pPool; pPool = pPool->GetSecondaryPool())
        if (dynamic_cast<EditEngineItemPool*>(pPool))
            return pPool;

    auto pRetval = EditEngine::CreatePool();
    pRetval->SetDefaultMetric(eDefaultMetric);
    return pRetval;
}

EditTextObjectImpl::EditTextObjectImpl(SfxItemPool* pP, MapUnit eDefaultMetric, bool bVertical,
    TextRotation eRotation, SvtScriptType eScriptType)
    : mpPool(getEditEngineItemPool(pP, eDefaultMetric))
    , meUserType(OutlinerMode::DontKnow)
    , meScriptType(eScriptType)
    , meRotation(eRotation)
    , meMetric(eDefaultMetric)
    , mbVertical(bVertical)
{
}

EditTextObjectImpl::EditTextObjectImpl( const EditTextObjectImpl& r )
    : mpPool(r.mpPool)
    , meUserType(r.meUserType)
    , meScriptType(r.meScriptType)
    , meRotation(r.meRotation)
    , meMetric(r.meMetric)
    , mbVertical(r.mbVertical)
{
    // Do not copy PortionInfo

    maContents.reserve(r.maContents.size());
    for (auto const& content : r.maContents)
        maContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*content, *mpPool)));
}

EditTextObjectImpl::~EditTextObjectImpl()
{
    ClearPortionInfo();

    // Remove contents before deleting the pool instance since each content
    // has to access the pool instance in its destructor.
    maContents.clear();
}


void EditTextObjectImpl::SetUserType( OutlinerMode n )
{
    meUserType = n;
}

void EditTextObjectImpl::NormalizeString( svl::SharedStringPool& rPool )
{
    for (auto const& content : maContents)
    {
        ContentInfo& rInfo = *content;
        rInfo.NormalizeString(rPool);
    }
}

std::vector<svl::SharedString> EditTextObjectImpl::GetSharedStrings() const
{
    std::vector<svl::SharedString> aSSs;
    aSSs.reserve(maContents.size());
    for (auto const& content : maContents)
    {
        const ContentInfo& rInfo = *content;
        aSSs.push_back(rInfo.GetSharedString());
    }
    return aSSs;
}

bool EditTextObjectImpl::IsEffectivelyVertical() const
{
    return (mbVertical && meRotation == TextRotation::NONE) ||
        (!mbVertical && meRotation != TextRotation::NONE);
}

bool EditTextObjectImpl::IsTopToBottom() const
{
    return (mbVertical && meRotation == TextRotation::NONE) ||
        (!mbVertical && meRotation == TextRotation::TOPTOBOTTOM);
}

void EditTextObjectImpl::SetVertical( bool bVert)
{
    if (bVert != mbVertical)
    {
        mbVertical = bVert;
        ClearPortionInfo();
    }
}

bool EditTextObjectImpl::GetVertical() const
{
    return mbVertical;
}

void EditTextObjectImpl::SetRotation(TextRotation nRotation)
{
    if (meRotation != nRotation)
    {
        meRotation = nRotation;
        ClearPortionInfo();
    }
}

TextRotation EditTextObjectImpl::GetRotation() const
{
    return meRotation;
}

XEditAttribute EditTextObjectImpl::CreateAttrib( const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd )
{
    return XEditAttribute(*mpPool, rItem, nStart, nEnd);
}

ContentInfo* EditTextObjectImpl::CreateAndInsertContent()
{
    maContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*mpPool)));
    return maContents.back().get();
}

sal_Int32 EditTextObjectImpl::GetParagraphCount() const
{
    size_t nSize = maContents.size();
    if (nSize > EE_PARA_MAX)
    {
        SAL_WARN( "editeng""EditTextObjectImpl::GetParagraphCount - overflow " << nSize);
        return EE_PARA_MAX;
    }
    return static_cast<sal_Int32>(nSize);
}

OUString EditTextObjectImpl::GetText(sal_Int32 nPara) const
{
    if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size())
        return OUString();

    return maContents[nPara]->GetText();
}

OUString EditTextObjectImpl::GetText(LineEnd eEnd) const
{
    const size_t nParas = maContents.size();
    if (nParas == 0)
        return OUString();

    const OUString aSep = EditDoc::GetSepStr(eEnd);

    OUStringBuffer aBuffer;

    for (size_t nPara = 0; nPara < nParas; ++nPara)
    {
        if (!aSep.isEmpty() && nPara > 0)
            aBuffer.append(aSep);
        aBuffer.append(maContents[nPara]->GetText());
    }

    return aBuffer.makeStringAndClear();
}

sal_Int32 EditTextObjectImpl::GetTextLen(sal_Int32 nPara ) const
{
    if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size())
        return 0;

    return maContents[nPara]->GetTextLen();
}

void EditTextObjectImpl::ClearPortionInfo()
{
    mpPortionInfo.reset();
}

bool EditTextObjectImpl::HasOnlineSpellErrors() const
{
    for (auto const& content : maContents)
    {
        if ( content->GetWrongList() && !content->GetWrongList()->empty() )
            return true;
    }
    return false;
}

void EditTextObjectImpl::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>&&nbsp;rLst ) const
{
    if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size())
        return;

    rLst.clear();
    const ContentInfo& rC = *maContents[nPara];
    for (const XEditAttribute & rAttr : rC.maCharAttribs)
    {
        EECharAttrib aEEAttr(rAttr.GetStart(), rAttr.GetEnd(), rAttr.GetItem());
        rLst.push_back(aEEAttr);
    }
}

bool EditTextObjectImpl::IsFieldObject() const
{
    return GetField() != nullptr;
}

const SvxFieldItem* EditTextObjectImpl::GetField() const
{
    if (maContents.size() == 1)
    {
        const ContentInfo& rC = *maContents[0];
        if (rC.GetText().getLength() == 1)
        {
            size_t nAttribs = rC.maCharAttribs.size();
            for (size_t nAttr = nAttribs; nAttr; )
            {
                const XEditAttribute& rX = rC.maCharAttribs[--nAttr];
                if (rX.GetItem()->Which() == EE_FEATURE_FIELD)
                    return static_cast<const SvxFieldItem*>(rX.GetItem());
            }
        }
    }
    return nullptr;
}

const SvxFieldData* EditTextObjectImpl::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const
{
    if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size())
        return nullptr;

    const ContentInfo& rC = *maContents[nPara];
    if (nPos >= rC.maCharAttribs.size())
        // URL position is out-of-bound.
        return nullptr;

    size_t nCurPos = 0;
    for (XEditAttribute const& rAttr : rC.maCharAttribs)
    {
        if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD)
            // Skip attributes that are not fields.
            continue;

        const SvxFieldItem* pField = static_cast<const SvxFieldItem*>(rAttr.GetItem());
        const SvxFieldData* pFldData = pField->GetField();
        if (nType != text::textfield::Type::UNSPECIFIED && nType != pFldData->GetClassId())
            // Field type doesn't match. Skip it.  UNSPECIFIED matches all field types.
            continue;

        if (nCurPos == nPos)
            // Found it!
            return pFldData;

        ++nCurPos;
    }

    return nullptr; // field not found.
}

bool EditTextObjectImpl::HasField( sal_Int32 nType ) const
{
    size_t nParagraphs = maContents.size();
    for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
    {
        const ContentInfo& rC = *maContents[nPara];
        size_t nAttrs = rC.maCharAttribs.size();
        for (size_t nAttr = 0; nAttr < nAttrs; ++nAttr)
        {
            const XEditAttribute& rAttr = rC.maCharAttribs[nAttr];
            if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD)
                continue;

            if (nType == text::textfield::Type::UNSPECIFIED)
                // Match any field type.
                return true;

            const SvxFieldData* pFldData = static_cast<const SvxFieldItem*>(rAttr.GetItem())->GetField();
            if (pFldData && pFldData->GetClassId() == nType)
                return true;
        }
    }
    return false;
}

const SfxItemSet& EditTextObjectImpl::GetParaAttribs(sal_Int32 nPara) const
{
    const ContentInfo& rC = *maContents[nPara];
    return rC.GetParaAttribs();
}

bool EditTextObjectImpl::RemoveCharAttribs( sal_uInt16 _nWhich )
{
    bool bChanged = false;

    for ( size_t nPara = maContents.size(); nPara; )
    {
        ContentInfo& rC = *maContents[--nPara];

        for (size_t nAttr = rC.maCharAttribs.size(); nAttr; )
        {
            XEditAttribute& rAttr = rC.maCharAttribs[--nAttr];
            if ( !_nWhich || (rAttr.GetItem()->Which() == _nWhich) )
            {
                rC.maCharAttribs.erase(rC.maCharAttribs.begin()+nAttr);
                bChanged = true;
            }
        }
    }

    if ( bChanged )
        ClearPortionInfo();

    return bChanged;
}

namespace {

class FindByParagraph
{
    sal_Int32 mnPara;
public:
    explicit FindByParagraph(sal_Int32 nPara) : mnPara(nPara) {}
    bool operator() (const editeng::Section& rAttr) const
    {
        return rAttr.mnParagraph == mnPara;
    }
};

class FindBySectionStart
{
    sal_Int32 mnPara;
    sal_Int32 mnStart;
public:
    FindBySectionStart(sal_Int32 nPara, sal_Int32 nStart) : mnPara(nPara), mnStart(nStart) {}
    bool operator() (const editeng::Section& rAttr) const
    {
        return rAttr.mnParagraph == mnPara && rAttr.mnStart == mnStart;
    }
};

}

void EditTextObjectImpl::GetAllSections( std::vector<editeng::Section>& rAttrs ) const
{
    std::vector<editeng::Section> aAttrs;
    aAttrs.reserve(maContents.size());
    std::vector<size_t> aBorders;

    for (size_t nPara = 0; nPara < maContents.size(); ++nPara)
    {
        aBorders.clear();
        const ContentInfo& rC = *maContents[nPara];
        aBorders.push_back(0);
        aBorders.push_back(rC.GetText().getLength());
        for (const XEditAttribute & rAttr : rC.maCharAttribs)
        {
            const SfxPoolItem* pItem = rAttr.GetItem();
            if (!pItem)
                continue;

            aBorders.push_back(rAttr.GetStart());
            aBorders.push_back(rAttr.GetEnd());
        }

        // Sort and remove duplicates for each paragraph.
        std::sort(aBorders.begin(), aBorders.end());
        auto itUniqueEnd = std::unique(aBorders.begin(), aBorders.end());
        aBorders.erase(itUniqueEnd, aBorders.end());

        // Create storage for each section.  Note that this creates storage even
        // for unformatted sections.  The entries are sorted first by paragraph,
        // then by section positions.  They don't overlap with each other.

        if (aBorders.size() == 1 && aBorders[0] == 0)
        {
            // Empty paragraph. Push an empty section.
            aAttrs.emplace_back(nPara, 0, 0);
            continue;
        }

        auto itBorder = aBorders.begin(), itBorderEnd = aBorders.end();
        size_t nPrev = *itBorder;
        size_t nCur;
        for (++itBorder; itBorder != itBorderEnd; ++itBorder, nPrev = nCur)
        {
            nCur = *itBorder;
            aAttrs.emplace_back(nPara, nPrev, nCur);
        }
    }

    if (aAttrs.empty())
        return;

    // Go through all formatted paragraphs, and store format items.
    std::vector<editeng::Section>::iterator itAttr = aAttrs.begin();
    for (sal_Int32 nPara = 0; nPara < static_cast<sal_Int32>(maContents.size()); ++nPara)
    {
        const ContentInfo& rC = *maContents[nPara];

        itAttr = std::find_if(itAttr, aAttrs.end(), FindByParagraph(nPara));
        if (itAttr == aAttrs.end())
        {
            // This should never happen. There is a logic error somewhere...
            assert(false);
            return;
        }

        for (const XEditAttribute & rXAttr : rC.maCharAttribs)
        {
            const SfxPoolItem* pItem = rXAttr.GetItem();
            if (!pItem)
                continue;

            sal_Int32 nStart = rXAttr.GetStart(), nEnd = rXAttr.GetEnd();

            // Find the container whose start position matches.
            std::vector<editeng::Section>::iterator itCurAttr = std::find_if(itAttr, aAttrs.end(), FindBySectionStart(nPara, nStart));
            if (itCurAttr == aAttrs.end())
            {
                // This should never happen. There is a logic error somewhere...
                assert(false);
                return;
            }

            for (; itCurAttr != aAttrs.end() && itCurAttr->mnParagraph == nPara && itCurAttr->mnEnd <= nEnd; ++itCurAttr)
            {
                editeng::Section& rSecAttr = *itCurAttr;
                // serious bug: will cause duplicate attributes to be exported
                if (std::none_of(rSecAttr.maAttributes.begin(), rSecAttr.maAttributes.end(),
                    [&pItem](SfxPoolItem const*const pIt)
                        { return pIt->Which() == pItem->Which(); }))
                {
                    rSecAttr.maAttributes.push_back(pItem);
                }
                else
                {
                    SAL_WARN("editeng""GetAllSections(): duplicate attribute suppressed");
                }
            }
        }
    }

    rAttrs.swap(aAttrs);
}

void EditTextObjectImpl::GetStyleSheet(sal_Int32 nPara, OUString& rName, SfxStyleFamily& rFamily) const
{
    if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size())
        return;

    const ContentInfo& rC = *maContents[nPara];
    rName = rC.GetStyle();
    rFamily = rC.GetFamily();
}

void EditTextObjectImpl::SetStyleSheet(sal_Int32 nPara, const OUString& rName, const SfxStyleFamily& rFamily)
{
    if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size())
        return;

    ContentInfo& rC = *maContents[nPara];
    rC.SetStyle(rName);
    rC.SetFamily(rFamily);
}

bool EditTextObjectImpl::ImpChangeStyleSheets(
                    std::u16string_view rOldName, SfxStyleFamily eOldFamily,
                    const OUString& rNewName, SfxStyleFamily eNewFamily )
{
    const size_t nParagraphs = maContents.size();
    bool bChanges = false;

    for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
    {
        ContentInfo& rC = *maContents[nPara];
        if ( rC.GetFamily() == eOldFamily )
        {
            if ( rC.GetStyle() == rOldName )
            {
                rC.SetStyle(rNewName);
                rC.SetFamily(eNewFamily);
                bChanges = true;
            }
        }
    }
    return bChanges;
}

bool EditTextObjectImpl::ChangeStyleSheets(
                    std::u16string_view rOldName, SfxStyleFamily eOldFamily,
                    const OUString& rNewName, SfxStyleFamily eNewFamily)
{
    bool bChanges = ImpChangeStyleSheets( rOldName, eOldFamily, rNewName, eNewFamily );
    if ( bChanges )
        ClearPortionInfo();

    return bChanges;
}

void EditTextObjectImpl::ChangeStyleSheetName( SfxStyleFamily eFamily,
                std::u16string_view rOldName, const OUString& rNewName )
{
    ImpChangeStyleSheets( rOldName, eFamily, rNewName, eFamily );
}

bool EditTextObjectImpl::operator==( const EditTextObject& rCompare ) const
{
    return Equals(toImpl(rCompare), true);
}

bool EditTextObjectImpl::Equals( const EditTextObjectImpl& rCompare, bool bComparePool ) const
{
    ifthis == &rCompare )
        return true;

    if(     ( bComparePool && mpPool != rCompare.mpPool ) ||
            ( meMetric != rCompare.meMetric ) ||
            ( meUserType!= rCompare.meUserType ) ||
            ( meScriptType != rCompare.meScriptType ) ||
            ( mbVertical != rCompare.mbVertical ) ||
            ( meRotation != rCompare.meRotation ) )
        return false;

    return std::equal(
        maContents.begin(), maContents.end(), rCompare.maContents.begin(), rCompare.maContents.end(),
        [bComparePool](const auto& c1, const auto& c2) { return c1->Equals(*c2, bComparePool); });
}

// #i102062#
bool EditTextObjectImpl::isWrongListEqual(const EditTextObject& rComp) const
{
    const EditTextObjectImpl& rCompare = toImpl(rComp);
    return std::equal(
        maContents.begin(), maContents.end(), rCompare.maContents.begin(), rCompare.maContents.end(),
        [](const auto& c1, const auto& c2) { return c1->isWrongListEqual(*c2); });
}

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

Messung V0.5
C=92 H=92 G=91

¤ Dauer der Verarbeitung: 0.7 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.