diff options
Diffstat (limited to 'editeng/source/editeng/editobj.cxx')
-rw-r--r-- | editeng/source/editeng/editobj.cxx | 673 |
1 files changed, 177 insertions, 496 deletions
diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx index fb872ca870eb..9b17e434e53d 100644 --- a/editeng/source/editeng/editobj.cxx +++ b/editeng/source/editeng/editobj.cxx @@ -22,12 +22,10 @@ #include <o3tl/safeint.hxx> #include <sal/log.hxx> -#include <editeng/fieldupdater.hxx> #include <editeng/macros.hxx> #include <editeng/section.hxx> #include "editobj2.hxx" #include <editeng/editdata.hxx> -#include <editattr.hxx> #include <editeng/editeng.hxx> #include <editeng/flditem.hxx> @@ -46,43 +44,32 @@ using std::endl; using namespace com::sun::star; -static std::unique_ptr<XEditAttribute> MakeXEditAttribute( SfxItemPool& rPool, const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd ) +XEditAttribute::XEditAttribute(SfxItemPool& rPool, const SfxPoolItem& rItem, sal_Int32 nS, sal_Int32 nE) +: maItemHolder(rPool, &rItem) +, nStart(nS) +, nEnd(nE) { - // Create the new attribute in the pool - const SfxPoolItem& rNew = rPool.Put( rItem ); - - std::unique_ptr<XEditAttribute> pNew(new XEditAttribute( rNew, nStart, nEnd )); - return pNew; -} - -XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr, sal_Int32 nS, sal_Int32 nE ) - : pItem(&rAttr) - , nStart(nS) - , nEnd(nE) -{ -} - -XEditAttribute::~XEditAttribute() -{ - pItem = nullptr; // belongs to the Pool. } bool XEditAttribute::IsFeature() const { - sal_uInt16 nWhich = pItem->Which(); + sal_uInt16 nWhich = GetItem()->Which(); return ((nWhich >= EE_FEATURE_START) && (nWhich <= EE_FEATURE_END)); } -void XEditAttribute::SetItem(const SfxPoolItem& rNew) +void XEditAttribute::SetItem(SfxItemPool& rPool, const SfxPoolItem& rItem) { - pItem = &rNew; + maItemHolder = SfxPoolItemHolder(rPool, &rItem); } -XParaPortionList::XParaPortionList( - OutputDevice* pRefDev, sal_uInt32 nPW, sal_uInt16 _nStretchX, sal_uInt16 _nStretchY) +XParaPortionList::XParaPortionList(OutputDevice* pRefDev, sal_uInt32 nPW, + double fFontScaleX, double fFontScaleY, + double fSpacingScaleX, double fSpacingScaleY) : pRefDevPtr(pRefDev) - , nStretchX(_nStretchX) - , nStretchY(_nStretchY) + , mfFontScaleX(fFontScaleX) + , mfFontScaleY(fFontScaleY) + , mfSpacingScaleX(fSpacingScaleX) + , mfSpacingScaleY(fSpacingScaleY) , nPaperWidth(nPW) { } @@ -99,7 +86,7 @@ const XParaPortion& XParaPortionList::operator [](size_t i) const ContentInfo::ContentInfo( SfxItemPool& rPool ) : eFamily(SfxStyleFamily::Para), - aParaAttribs(rPool, svl::Items<EE_PARA_START, EE_CHAR_END>{}) + aParaAttribs(rPool) { } @@ -108,17 +95,14 @@ ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse maText(rCopyFrom.maText), aStyle(rCopyFrom.aStyle), eFamily(rCopyFrom.eFamily), - aParaAttribs(rPoolToUse, svl::Items<EE_PARA_START, EE_CHAR_END>{}) + aParaAttribs(rPoolToUse) { // this should ensure that the Items end up in the correct Pool! aParaAttribs.Set( rCopyFrom.GetParaAttribs() ); - for (const auto & aAttrib : rCopyFrom.maCharAttribs) + for (const XEditAttribute & rAttr : rCopyFrom.maCharAttribs) { - const XEditAttribute& rAttr = *aAttrib; - std::unique_ptr<XEditAttribute> pMyAttr = MakeXEditAttribute( - rPoolToUse, *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd()); - maCharAttribs.push_back(std::move(pMyAttr)); + maCharAttribs.emplace_back(rPoolToUse, *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd()); } if ( rCopyFrom.GetWrongList() ) @@ -127,8 +111,6 @@ ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse ContentInfo::~ContentInfo() { - for (auto const& charAttrib : maCharAttribs) - aParaAttribs.GetPool()->Remove(*charAttrib->GetItem()); maCharAttribs.clear(); } @@ -144,6 +126,12 @@ OUString ContentInfo::GetText() const 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); @@ -151,21 +139,23 @@ void ContentInfo::SetText( const OUString& rStr ) void ContentInfo::dumpAsXml(xmlTextWriterPtr pWriter) const { - xmlTextWriterStartElement(pWriter, BAD_CAST("ContentInfo")); - xmlTextWriterWriteAttribute(pWriter, BAD_CAST("style"), BAD_CAST(aStyle.toUtf8().getStr())); - xmlTextWriterStartElement(pWriter, BAD_CAST("text")); - xmlTextWriterWriteString(pWriter, BAD_CAST(GetText().toUtf8().getStr())); - xmlTextWriterEndElement(pWriter); + (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 (size_t i=0; i<maCharAttribs.size(); ++i) + for (auto const& rCharAttribs : maCharAttribs) { - xmlTextWriterStartElement(pWriter, BAD_CAST("attribs")); - xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("start"), "%" SAL_PRIdINT32, maCharAttribs[i]->GetStart()); - xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("end"), "%" SAL_PRIdINT32, maCharAttribs[i]->GetEnd()); - maCharAttribs[i]->GetItem()->dumpAsXml(pWriter); - xmlTextWriterEndElement(pWriter); + (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); } - xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterEndElement(pWriter); } const WrongList* ContentInfo::GetWrongList() const @@ -210,386 +200,116 @@ bool ContentInfo::Equals(const ContentInfo& rCompare, bool bComparePool) const { return maText == rCompare.maText && aStyle == rCompare.aStyle && eFamily == rCompare.eFamily && aParaAttribs.Equals(rCompare.aParaAttribs, bComparePool) - && std::equal(maCharAttribs.cbegin(), maCharAttribs.cend(), - rCompare.maCharAttribs.cbegin(), rCompare.maCharAttribs.cend(), - [](const std::unique_ptr<XEditAttribute>& pAttribute1, - const std::unique_ptr<XEditAttribute>& pAttribute2) -> bool { - return *pAttribute1 == *pAttribute2; - }); -} - -EditTextObject::EditTextObject( SfxItemPool* pPool ) : - mpImpl(new EditTextObjectImpl(this, pPool)) -{ -} - -EditTextObject::EditTextObject( const EditTextObject& r ) : - SfxItemPoolUser(), - mpImpl(new EditTextObjectImpl(this, *r.mpImpl)) -{ -} - -EditTextObject::~EditTextObject() -{ -} - -sal_Int32 EditTextObject::GetParagraphCount() const -{ - return mpImpl->GetParagraphCount(); -} - -OUString EditTextObject::GetText(sal_Int32 nPara) const -{ - return mpImpl->GetText(nPara); -} - -void EditTextObject::ClearPortionInfo() -{ - mpImpl->ClearPortionInfo(); -} - -bool EditTextObject::HasOnlineSpellErrors() const -{ - return mpImpl->HasOnlineSpellErrors(); -} - -void EditTextObject::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const -{ - mpImpl->GetCharAttribs(nPara, rLst); -} - -bool EditTextObject::IsFieldObject() const -{ - return mpImpl->IsFieldObject(); -} - -const SvxFieldItem* EditTextObject::GetField() const -{ - return mpImpl->GetField(); -} - -const SvxFieldData* EditTextObject::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const -{ - return mpImpl->GetFieldData(nPara, nPos, nType); -} - -bool EditTextObject::HasField( sal_Int32 nType ) const -{ - return mpImpl->HasField(nType); -} - -const SfxItemSet& EditTextObject::GetParaAttribs(sal_Int32 nPara) const -{ - return mpImpl->GetParaAttribs(nPara); + && maCharAttribs == rCompare.maCharAttribs; } -bool EditTextObject::RemoveCharAttribs( sal_uInt16 nWhich ) -{ - return mpImpl->RemoveCharAttribs(nWhich); -} +EditTextObject::~EditTextObject() = default; -void EditTextObject::GetAllSections( std::vector<editeng::Section>& rAttrs ) const +std::unique_ptr<EditTextObject> EditTextObjectImpl::Clone() const { - mpImpl->GetAllSections(rAttrs); -} - -void EditTextObject::GetStyleSheet(sal_Int32 nPara, OUString& rName, SfxStyleFamily& eFamily) const -{ - mpImpl->GetStyleSheet(nPara, rName, eFamily); -} - -void EditTextObject::SetStyleSheet(sal_Int32 nPara, const OUString& rName, const SfxStyleFamily& eFamily) -{ - mpImpl->SetStyleSheet(nPara, rName, eFamily); -} - -bool EditTextObject::ChangeStyleSheets( - std::u16string_view rOldName, SfxStyleFamily eOldFamily, const OUString& rNewName, SfxStyleFamily eNewFamily) -{ - return mpImpl->ChangeStyleSheets(rOldName, eOldFamily, rNewName, eNewFamily); -} - -void EditTextObject::ChangeStyleSheetName( - SfxStyleFamily eFamily, std::u16string_view rOldName, const OUString& rNewName) -{ - mpImpl->ChangeStyleSheetName(eFamily, rOldName, rNewName); -} - -editeng::FieldUpdater EditTextObject::GetFieldUpdater() const -{ - return mpImpl->GetFieldUpdater(); -} - -void EditTextObject::NormalizeString( svl::SharedStringPool& rPool ) -{ - mpImpl->NormalizeString(rPool); -} - -std::vector<svl::SharedString> EditTextObject::GetSharedStrings() const -{ - return mpImpl->GetSharedStrings(); -} - -const SfxItemPool* EditTextObject::GetPool() const -{ - return mpImpl->GetPool(); -} - -OutlinerMode EditTextObject::GetUserType() const -{ - return mpImpl->GetUserType(); -} - -void EditTextObject::SetUserType( OutlinerMode n ) -{ - mpImpl->SetUserType(n); -} - -bool EditTextObject::IsVertical() const -{ - return mpImpl->IsVertical(); -} - -bool EditTextObject::GetDirectVertical() const -{ - return mpImpl->GetDirectVertical(); -} - -bool EditTextObject::IsTopToBottom() const -{ - return mpImpl->IsTopToBottom(); -} - -void EditTextObject::SetVertical( bool bVertical ) -{ - return mpImpl->SetVertical(bVertical); -} - -void EditTextObject::SetRotation( TextRotation nRotation ) -{ - mpImpl->SetRotation(nRotation); -} - -TextRotation EditTextObject::GetRotation() const -{ - return mpImpl->GetRotation(); -} - -SvtScriptType EditTextObject::GetScriptType() const -{ - return mpImpl->GetScriptType(); -} - - -std::unique_ptr<EditTextObject> EditTextObject::Clone() const -{ - return std::unique_ptr<EditTextObject>(new EditTextObject(*this)); -} - -bool EditTextObject::operator==( const EditTextObject& rCompare ) const -{ - return mpImpl->operator==(*rCompare.mpImpl); + return std::make_unique<EditTextObjectImpl>(*this); } bool EditTextObject::Equals( const EditTextObject& rCompare ) const { - return mpImpl->Equals(*rCompare.mpImpl, false/*bComparePool*/); + return toImpl(*this).Equals(toImpl(rCompare), false /*bComparePool*/); } -// #i102062# -bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const -{ - return mpImpl->isWrongListEqual(*rCompare.mpImpl); -} - -void EditTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool) -{ - mpImpl->ObjectInDestruction(rSfxItemPool); -} - -#if DEBUG_EDIT_ENGINE -void EditTextObject::Dump() const -{ - mpImpl->Dump(); -} -#endif - -void EditTextObject::dumpAsXml(xmlTextWriterPtr pWriter) const +void EditTextObjectImpl::dumpAsXml(xmlTextWriterPtr pWriter) const { bool bOwns = false; if (!pWriter) { pWriter = xmlNewTextWriterFilename("editTextObject.xml", 0); xmlTextWriterSetIndent(pWriter,1); - xmlTextWriterSetIndentString(pWriter, BAD_CAST(" ")); - xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr); + (void)xmlTextWriterSetIndentString(pWriter, BAD_CAST(" ")); + (void)xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr); bOwns = true; } - xmlTextWriterStartElement(pWriter, BAD_CAST("EditTextObject")); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("EditTextObject")); sal_Int32 nCount = GetParagraphCount(); for (sal_Int32 i = 0; i < nCount; ++i) { - mpImpl->aContents[i]->dumpAsXml(pWriter); + maContents[i]->dumpAsXml(pWriter); } - xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterEndElement(pWriter); if (bOwns) { - xmlTextWriterEndDocument(pWriter); + (void)xmlTextWriterEndDocument(pWriter); xmlFreeTextWriter(pWriter); } } -// from SfxItemPoolUser -void EditTextObjectImpl::ObjectInDestruction(const SfxItemPool& rSfxItemPool) -{ - if(bOwnerOfPool || pPool != &rSfxItemPool) - return; - - // The pool we are based on gets destructed; get owner of pool by creating own one. - // No need to call RemoveSfxItemPoolUser(), this is done from the pool's destructor - // Base new pool on EditEnginePool; it would also be possible to clone the used - // pool if needed, but only text attributes should be used. - SfxItemPool* pNewPool = EditEngine::CreatePool(); - - pNewPool->SetDefaultMetric(pPool->GetMetric(DEF_METRIC)); - - ContentInfosType aReplaced; - aReplaced.reserve(aContents.size()); - for (auto const& content : aContents) - aReplaced.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*content, *pNewPool))); - aReplaced.swap(aContents); - - // set local variables - pPool = pNewPool; - bOwnerOfPool = true; -} - #if DEBUG_EDIT_ENGINE void EditTextObjectImpl::Dump() const { - for (auto const& content : aContents) + for (auto const& content : maContents) content.Dump(); } #endif -static EditEngineItemPool* getEditEngineItemPool(SfxItemPool* pPool) -{ - EditEngineItemPool* pRetval = dynamic_cast< EditEngineItemPool* >(pPool); - - while(!pRetval && pPool && pPool->GetSecondaryPool()) - { - pPool = pPool->GetSecondaryPool(); - - if(pPool) - { - pRetval = dynamic_cast< EditEngineItemPool* >(pPool); - } - } - - return pRetval; -} - -EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, SfxItemPool* pP ) - : mpFront(pFront) - , nMetric(0xFFFF) - , nUserType(OutlinerMode::DontKnow) - , nScriptType(SvtScriptType::NONE) - , bVertical(false) - , mnRotation(TextRotation::NONE) +static rtl::Reference<SfxItemPool> getEditEngineItemPool(SfxItemPool* pPool, MapUnit eDefaultMetric) { - // #i101239# ensure target is an EditEngineItemPool, else - // fallback to pool ownership. This is needed to ensure that at + // #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. - pPool = getEditEngineItemPool(pP); + for (; pPool; pPool = pPool->GetSecondaryPool()) + if (dynamic_cast<EditEngineItemPool*>(pPool)) + return pPool; - if ( pPool ) - { - bOwnerOfPool = false; - } - else - { - pPool = EditEngine::CreatePool(); - bOwnerOfPool = true; - } + auto pRetval = EditEngine::CreatePool(); + pRetval->SetDefaultMetric(eDefaultMetric); + return pRetval; +} - if(!bOwnerOfPool && pPool) - { - // it is sure now that the pool is an EditEngineItemPool - pPool->AddSfxItemPoolUser(*mpFront); - } +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( EditTextObject* pFront, const EditTextObjectImpl& r ) - : mpFront(pFront) - , nMetric(r.nMetric) - , nUserType(r.nUserType) - , nScriptType(r.nScriptType) - , bVertical(r.bVertical) - , mnRotation(r.mnRotation) +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 - if ( !r.bOwnerOfPool ) - { - // reuse alien pool; this must be an EditEngineItemPool - // since there is no other way to construct a BinTextObject - // than it's regular constructor where that is ensured - pPool = r.pPool; - bOwnerOfPool = false; - } - else - { - pPool = EditEngine::CreatePool(); - bOwnerOfPool = true; - - } - - if (!bOwnerOfPool) - { - // it is sure now that the pool is an EditEngineItemPool - pPool->AddSfxItemPoolUser(*mpFront); - } - - if (bOwnerOfPool && r.pPool) - pPool->SetDefaultMetric( r.pPool->GetMetric( DEF_METRIC ) ); - - aContents.reserve(r.aContents.size()); - for (auto const& content : r.aContents) - aContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*content, *pPool))); + maContents.reserve(r.maContents.size()); + for (auto const& content : r.maContents) + maContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*content, *mpPool))); } EditTextObjectImpl::~EditTextObjectImpl() { - if(!bOwnerOfPool && pPool) - { - pPool->RemoveSfxItemPoolUser(*mpFront); - } - ClearPortionInfo(); // Remove contents before deleting the pool instance since each content // has to access the pool instance in its destructor. - aContents.clear(); - if ( bOwnerOfPool ) - { - SfxItemPool::Free(pPool); - } + maContents.clear(); } void EditTextObjectImpl::SetUserType( OutlinerMode n ) { - nUserType = n; + meUserType = n; } void EditTextObjectImpl::NormalizeString( svl::SharedStringPool& rPool ) { - for (auto const& content : aContents) + for (auto const& content : maContents) { ContentInfo& rInfo = *content; rInfo.NormalizeString(rPool); @@ -599,8 +319,8 @@ void EditTextObjectImpl::NormalizeString( svl::SharedStringPool& rPool ) std::vector<svl::SharedString> EditTextObjectImpl::GetSharedStrings() const { std::vector<svl::SharedString> aSSs; - aSSs.reserve(aContents.size()); - for (auto const& content : aContents) + aSSs.reserve(maContents.size()); + for (auto const& content : maContents) { const ContentInfo& rInfo = *content; aSSs.push_back(rInfo.GetSharedString()); @@ -608,72 +328,60 @@ std::vector<svl::SharedString> EditTextObjectImpl::GetSharedStrings() const return aSSs; } -bool EditTextObjectImpl::IsVertical() const +bool EditTextObjectImpl::IsEffectivelyVertical() const { - return (bVertical && mnRotation == TextRotation::NONE) || - (!bVertical && mnRotation != TextRotation::NONE); + return (mbVertical && meRotation == TextRotation::NONE) || + (!mbVertical && meRotation != TextRotation::NONE); } bool EditTextObjectImpl::IsTopToBottom() const { - return (bVertical && mnRotation == TextRotation::NONE) || - (!bVertical && mnRotation == TextRotation::TOPTOBOTTOM); + return (mbVertical && meRotation == TextRotation::NONE) || + (!mbVertical && meRotation == TextRotation::TOPTOBOTTOM); } void EditTextObjectImpl::SetVertical( bool bVert) { - if (bVert != bVertical) + if (bVert != mbVertical) { - bVertical = bVert; + mbVertical = bVert; ClearPortionInfo(); } } -bool EditTextObjectImpl::GetDirectVertical() const +bool EditTextObjectImpl::GetVertical() const { - return bVertical; + return mbVertical; } void EditTextObjectImpl::SetRotation(TextRotation nRotation) { - if (mnRotation != nRotation) + if (meRotation != nRotation) { - mnRotation = nRotation; + meRotation = nRotation; ClearPortionInfo(); } } TextRotation EditTextObjectImpl::GetRotation() const { - return mnRotation; -} - - -void EditTextObjectImpl::SetScriptType( SvtScriptType nType ) -{ - nScriptType = nType; -} - -std::unique_ptr<XEditAttribute> EditTextObjectImpl::CreateAttrib( const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd ) -{ - return MakeXEditAttribute( *pPool, rItem, nStart, nEnd ); + return meRotation; } -void EditTextObjectImpl::DestroyAttrib( std::unique_ptr<XEditAttribute> pAttr ) +XEditAttribute EditTextObjectImpl::CreateAttrib( const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd ) { - pPool->Remove( *pAttr->GetItem() ); + return XEditAttribute(*mpPool, rItem, nStart, nEnd); } - ContentInfo* EditTextObjectImpl::CreateAndInsertContent() { - aContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*pPool))); - return aContents.back().get(); + maContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*mpPool))); + return maContents.back().get(); } sal_Int32 EditTextObjectImpl::GetParagraphCount() const { - size_t nSize = aContents.size(); + size_t nSize = maContents.size(); if (nSize > EE_PARA_MAX_COUNT) { SAL_WARN( "editeng", "EditTextObjectImpl::GetParagraphCount - overflow " << nSize); @@ -684,20 +392,28 @@ sal_Int32 EditTextObjectImpl::GetParagraphCount() const OUString EditTextObjectImpl::GetText(sal_Int32 nPara) const { - if (nPara < 0 || o3tl::make_unsigned(nPara) >= aContents.size()) + if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size()) return OUString(); - return aContents[nPara]->GetText(); + return maContents[nPara]->GetText(); +} + +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() { - pPortionInfo.reset(); + mpPortionInfo.reset(); } bool EditTextObjectImpl::HasOnlineSpellErrors() const { - for (auto const& content : aContents) + for (auto const& content : maContents) { if ( content->GetWrongList() && !content->GetWrongList()->empty() ) return true; @@ -707,18 +423,14 @@ bool EditTextObjectImpl::HasOnlineSpellErrors() const void EditTextObjectImpl::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const { - if (nPara < 0 || o3tl::make_unsigned(nPara) >= aContents.size()) + if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size()) return; rLst.clear(); - const ContentInfo& rC = *aContents[nPara]; - for (const auto & aAttrib : rC.maCharAttribs) + const ContentInfo& rC = *maContents[nPara]; + for (const XEditAttribute & rAttr : rC.maCharAttribs) { - const XEditAttribute& rAttr = *aAttrib; - EECharAttrib aEEAttr; - aEEAttr.pAttr = rAttr.GetItem(); - aEEAttr.nStart = rAttr.GetStart(); - aEEAttr.nEnd = rAttr.GetEnd(); + EECharAttrib aEEAttr(rAttr.GetStart(), rAttr.GetEnd(), rAttr.GetItem()); rLst.push_back(aEEAttr); } } @@ -730,15 +442,15 @@ bool EditTextObjectImpl::IsFieldObject() const const SvxFieldItem* EditTextObjectImpl::GetField() const { - if (aContents.size() == 1) + if (maContents.size() == 1) { - const ContentInfo& rC = *aContents[0]; + 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]; + const XEditAttribute& rX = rC.maCharAttribs[--nAttr]; if (rX.GetItem()->Which() == EE_FEATURE_FIELD) return static_cast<const SvxFieldItem*>(rX.GetItem()); } @@ -749,18 +461,17 @@ const SvxFieldItem* EditTextObjectImpl::GetField() const const SvxFieldData* EditTextObjectImpl::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const { - if (nPara < 0 || o3tl::make_unsigned(nPara) >= aContents.size()) + if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size()) return nullptr; - const ContentInfo& rC = *aContents[nPara]; + const ContentInfo& rC = *maContents[nPara]; if (nPos >= rC.maCharAttribs.size()) // URL position is out-of-bound. return nullptr; size_t nCurPos = 0; - for (auto const& charAttrib : rC.maCharAttribs) + for (XEditAttribute const& rAttr : rC.maCharAttribs) { - const XEditAttribute& rAttr = *charAttrib; if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD) // Skip attributes that are not fields. continue; @@ -783,14 +494,14 @@ const SvxFieldData* EditTextObjectImpl::GetFieldData(sal_Int32 nPara, size_t nPo bool EditTextObjectImpl::HasField( sal_Int32 nType ) const { - size_t nParagraphs = aContents.size(); + size_t nParagraphs = maContents.size(); for (size_t nPara = 0; nPara < nParagraphs; ++nPara) { - const ContentInfo& rC = *aContents[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]; + const XEditAttribute& rAttr = rC.maCharAttribs[nAttr]; if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD) continue; @@ -808,7 +519,7 @@ bool EditTextObjectImpl::HasField( sal_Int32 nType ) const const SfxItemSet& EditTextObjectImpl::GetParaAttribs(sal_Int32 nPara) const { - const ContentInfo& rC = *aContents[nPara]; + const ContentInfo& rC = *maContents[nPara]; return rC.GetParaAttribs(); } @@ -816,16 +527,15 @@ bool EditTextObjectImpl::RemoveCharAttribs( sal_uInt16 _nWhich ) { bool bChanged = false; - for ( size_t nPara = aContents.size(); nPara; ) + for ( size_t nPara = maContents.size(); nPara; ) { - ContentInfo& rC = *aContents[--nPara]; + ContentInfo& rC = *maContents[--nPara]; for (size_t nAttr = rC.maCharAttribs.size(); nAttr; ) { - XEditAttribute& rAttr = *rC.maCharAttribs[--nAttr]; + XEditAttribute& rAttr = rC.maCharAttribs[--nAttr]; if ( !_nWhich || (rAttr.GetItem()->Which() == _nWhich) ) { - pPool->Remove(*rAttr.GetItem()); rC.maCharAttribs.erase(rC.maCharAttribs.begin()+nAttr); bChanged = true; } @@ -867,60 +577,50 @@ public: void EditTextObjectImpl::GetAllSections( std::vector<editeng::Section>& rAttrs ) const { - std::vector<std::vector<size_t>> aParaBorders(aContents.size()); + std::vector<editeng::Section> aAttrs; + aAttrs.reserve(maContents.size()); + std::vector<size_t> aBorders; - // First pass: determine section borders for each paragraph. - for (size_t nPara = 0; nPara < aContents.size(); ++nPara) + for (size_t nPara = 0; nPara < maContents.size(); ++nPara) { - const ContentInfo& rC = *aContents[nPara]; - std::vector<size_t>& rBorders = aParaBorders[nPara]; - rBorders.push_back(0); - rBorders.push_back(rC.GetText().getLength()); - for (const auto & aAttrib : rC.maCharAttribs) + aBorders.clear(); + const ContentInfo& rC = *maContents[nPara]; + aBorders.push_back(0); + aBorders.push_back(rC.GetText().getLength()); + for (const XEditAttribute & rAttr : rC.maCharAttribs) { - const XEditAttribute& rAttr = *aAttrib; const SfxPoolItem* pItem = rAttr.GetItem(); if (!pItem) continue; - rBorders.push_back(rAttr.GetStart()); - rBorders.push_back(rAttr.GetEnd()); + aBorders.push_back(rAttr.GetStart()); + aBorders.push_back(rAttr.GetEnd()); } - } - // Sort and remove duplicates for each paragraph. - for (auto & paraBorders : aParaBorders) - { - std::sort(paraBorders.begin(), paraBorders.end()); - auto itUniqueEnd = std::unique(paraBorders.begin(), paraBorders.end()); - paraBorders.erase(itUniqueEnd, paraBorders.end()); - } + // 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()); - std::vector<editeng::Section> aAttrs; + // 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. - // 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. - size_t nPara1 = 0; - for (auto const& paraBorders : aParaBorders) - { - if (paraBorders.size() == 1 && paraBorders[0] == 0) + if (aBorders.size() == 1 && aBorders[0] == 0) { // Empty paragraph. Push an empty section. - aAttrs.emplace_back(nPara1, 0, 0); - ++nPara1; + aAttrs.emplace_back(nPara, 0, 0); continue; } - auto itBorder = paraBorders.begin(), itBorderEnd = paraBorders.end(); + 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(nPara1, nPrev, nCur); + aAttrs.emplace_back(nPara, nPrev, nCur); } - ++nPara1; } if (aAttrs.empty()) @@ -928,9 +628,9 @@ void EditTextObjectImpl::GetAllSections( std::vector<editeng::Section>& rAttrs ) // 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>(aContents.size()); ++nPara) + for (sal_Int32 nPara = 0; nPara < static_cast<sal_Int32>(maContents.size()); ++nPara) { - const ContentInfo& rC = *aContents[nPara]; + const ContentInfo& rC = *maContents[nPara]; itAttr = std::find_if(itAttr, aAttrs.end(), FindByParagraph(nPara)); if (itAttr == aAttrs.end()) @@ -940,9 +640,8 @@ void EditTextObjectImpl::GetAllSections( std::vector<editeng::Section>& rAttrs ) return; } - for (const auto & aAttrib : rC.maCharAttribs) + for (const XEditAttribute & rXAttr : rC.maCharAttribs) { - const XEditAttribute& rXAttr = *aAttrib; const SfxPoolItem* pItem = rXAttr.GetItem(); if (!pItem) continue; @@ -981,20 +680,20 @@ void EditTextObjectImpl::GetAllSections( std::vector<editeng::Section>& rAttrs ) void EditTextObjectImpl::GetStyleSheet(sal_Int32 nPara, OUString& rName, SfxStyleFamily& rFamily) const { - if (nPara < 0 || o3tl::make_unsigned(nPara) >= aContents.size()) + if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size()) return; - const ContentInfo& rC = *aContents[nPara]; + 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) >= aContents.size()) + if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size()) return; - ContentInfo& rC = *aContents[nPara]; + ContentInfo& rC = *maContents[nPara]; rC.SetStyle(rName); rC.SetFamily(rFamily); } @@ -1003,12 +702,12 @@ bool EditTextObjectImpl::ImpChangeStyleSheets( std::u16string_view rOldName, SfxStyleFamily eOldFamily, const OUString& rNewName, SfxStyleFamily eNewFamily ) { - const size_t nParagraphs = aContents.size(); + const size_t nParagraphs = maContents.size(); bool bChanges = false; for (size_t nPara = 0; nPara < nParagraphs; ++nPara) { - ContentInfo& rC = *aContents[nPara]; + ContentInfo& rC = *maContents[nPara]; if ( rC.GetFamily() == eOldFamily ) { if ( rC.GetStyle() == rOldName ) @@ -1039,9 +738,9 @@ void EditTextObjectImpl::ChangeStyleSheetName( SfxStyleFamily eFamily, ImpChangeStyleSheets( rOldName, eFamily, rNewName, eFamily ); } -bool EditTextObjectImpl::operator==( const EditTextObjectImpl& rCompare ) const +bool EditTextObjectImpl::operator==( const EditTextObject& rCompare ) const { - return Equals( rCompare, true); + return Equals(toImpl(rCompare), true); } bool EditTextObjectImpl::Equals( const EditTextObjectImpl& rCompare, bool bComparePool ) const @@ -1049,44 +748,26 @@ bool EditTextObjectImpl::Equals( const EditTextObjectImpl& rCompare, bool bCompa if( this == &rCompare ) return true; - if( ( aContents.size() != rCompare.aContents.size() ) || - ( bComparePool && pPool != rCompare.pPool ) || - ( nMetric != rCompare.nMetric ) || - ( nUserType!= rCompare.nUserType ) || - ( nScriptType != rCompare.nScriptType ) || - ( bVertical != rCompare.bVertical ) || - ( mnRotation != rCompare.mnRotation ) ) + if( ( bComparePool && mpPool != rCompare.mpPool ) || + ( meMetric != rCompare.meMetric ) || + ( meUserType!= rCompare.meUserType ) || + ( meScriptType != rCompare.meScriptType ) || + ( mbVertical != rCompare.mbVertical ) || + ( meRotation != rCompare.meRotation ) ) return false; - for (size_t i = 0, n = aContents.size(); i < n; ++i) - { - if (!(aContents[i]->Equals( *(rCompare.aContents[i]), bComparePool))) - return false; - } - - return true; + 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 EditTextObjectImpl& rCompare) const +bool EditTextObjectImpl::isWrongListEqual(const EditTextObject& rComp) const { - if (aContents.size() != rCompare.aContents.size()) - { - return false; - } - - for (size_t i = 0, n = aContents.size(); i < n; ++i) - { - const ContentInfo& rCandA = *aContents[i]; - const ContentInfo& rCandB = *rCompare.aContents[i]; - - if(!rCandA.isWrongListEqual(rCandB)) - { - return false; - } - } - - return true; + 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: */ |