editeng/source/editeng/editobj2.hxx | 1 editeng/source/editeng/eerdll.cxx | 2 editeng/source/editeng/fieldupdater.cxx | 39 ++++++++++ include/editeng/fieldupdater.hxx | 17 ++++ sd/inc/drawdoc.hxx | 4 + sd/source/core/drawdoc2.cxx | 123 ++++++++++++++++++++++---------- 6 files changed, 148 insertions(+), 38 deletions(-)
New commits: commit c638ae429e500cee147b621ed30d9fed392edd0a Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Fri Oct 18 16:21:10 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Oct 28 18:43:21 2024 +0100 don't use iterateItemSurrogates for EE_FEATURE_FIELD Change-Id: I96cd1728e2358d4ea49275952726aae85e6f52a7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175726 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/editeng/source/editeng/editobj2.hxx b/editeng/source/editeng/editobj2.hxx index 4392022b77a3..f1bfa4e773ac 100644 --- a/editeng/source/editeng/editobj2.hxx +++ b/editeng/source/editeng/editobj2.hxx @@ -55,6 +55,7 @@ public: XEditAttribute(SfxItemPool&, const SfxPoolItem&, sal_Int32 nStart, sal_Int32 nEnd ); const SfxPoolItem* GetItem() const { return maItemHolder.getItem(); } + SfxPoolItemHolder& GetItemHolder() { return maItemHolder; } sal_Int32& GetStart() { return nStart; } sal_Int32& GetEnd() { return nEnd; } diff --git a/editeng/source/editeng/eerdll.cxx b/editeng/source/editeng/eerdll.cxx index a50641ee1b0c..9bc101646c7e 100644 --- a/editeng/source/editeng/eerdll.cxx +++ b/editeng/source/editeng/eerdll.cxx @@ -157,7 +157,7 @@ ItemInfoPackage& getItemInfoPackageEditEngine() { EE_FEATURE_TAB, new SfxVoidItem( EE_FEATURE_TAB ), 0, SFX_ITEMINFOFLAG_NONE }, { EE_FEATURE_LINEBR, new SfxVoidItem( EE_FEATURE_LINEBR ), 0, SFX_ITEMINFOFLAG_NONE }, { EE_FEATURE_NOTCONV, new SvxColorItem( COL_RED, EE_FEATURE_NOTCONV ), SID_ATTR_CHAR_CHARSETCOLOR, SFX_ITEMINFOFLAG_NONE }, - { EE_FEATURE_FIELD, new SvxFieldItem( SvxFieldData(), EE_FEATURE_FIELD ), SID_FIELD, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE } + { EE_FEATURE_FIELD, new SvxFieldItem( SvxFieldData(), EE_FEATURE_FIELD ), SID_FIELD, SFX_ITEMINFOFLAG_NONE } }}; virtual const ItemInfoStatic& getItemInfoStatic(size_t nIndex) const override { return maItemInfos[nIndex]; } diff --git a/editeng/source/editeng/fieldupdater.cxx b/editeng/source/editeng/fieldupdater.cxx index 05eca4575590..6d6fbfb28c3c 100644 --- a/editeng/source/editeng/fieldupdater.cxx +++ b/editeng/source/editeng/fieldupdater.cxx @@ -18,6 +18,22 @@ using namespace com::sun::star; namespace editeng { +SvxFieldItemUpdater::~SvxFieldItemUpdater() {} + +namespace { +class SvxFieldItemUpdaterImpl : public SvxFieldItemUpdater +{ + SfxPoolItemHolder& mrItemHolder; +public: + SvxFieldItemUpdaterImpl(SfxPoolItemHolder& rHolder) : mrItemHolder(rHolder) {} + + virtual void SetItem(const SvxFieldItem& rNewItem) + { + mrItemHolder = SfxPoolItemHolder(mrItemHolder.getPool(), &rNewItem, false); + } +}; +} + class FieldUpdaterImpl { EditTextObjectImpl& mrObj; @@ -51,6 +67,24 @@ public: } } } + + void UpdatePageRelativeURLs(const std::function<void(const SvxFieldItem & rFieldItem, SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback) + { + EditTextObjectImpl::ContentInfosType& rContents = mrObj.GetContents(); + for (std::unique_ptr<ContentInfo> & i : rContents) + { + ContentInfo& rContent = *i; + for (XEditAttribute & rAttr : rContent.GetCharAttribs()) + { + const SfxPoolItem* pItem = rAttr.GetItem(); + if (pItem->Which() != EE_FEATURE_FIELD) + // This is not a field item. + continue; + SvxFieldItemUpdaterImpl aUpdater(rAttr.GetItemHolder()); + rItemCallback(static_cast<const SvxFieldItem&>(*pItem), aUpdater); + } + } + } }; FieldUpdater::FieldUpdater(EditTextObject& rObj) : mpImpl(new FieldUpdaterImpl(rObj)) {} @@ -65,6 +99,11 @@ void FieldUpdater::updateTableFields(int nTab) mpImpl->updateTableFields(nTab); } +void FieldUpdater::UpdatePageRelativeURLs(const std::function<void(const SvxFieldItem & rFieldItem, SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback) +{ + mpImpl->UpdatePageRelativeURLs(rItemCallback); +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/editeng/fieldupdater.hxx b/include/editeng/fieldupdater.hxx index e15754ffdd0c..61d6570741e2 100644 --- a/include/editeng/fieldupdater.hxx +++ b/include/editeng/fieldupdater.hxx @@ -11,6 +11,8 @@ #define INCLUDED_EDITENG_FIELDUPDATER_HXX #include <editeng/editengdllapi.h> +#include <editeng/flditem.hxx> +#include <svl/itempool.hxx> #include <memory> class EditTextObject; @@ -18,6 +20,7 @@ class EditTextObject; namespace editeng { class FieldUpdaterImpl; +class SvxFieldItemUpdater; /** * Wrapper for EditTextObject to handle updating of fields without exposing @@ -38,6 +41,20 @@ public: * @param nTab new table ID */ void updateTableFields(int nTab); + + void UpdatePageRelativeURLs( + const std::function<void(const SvxFieldItem& rFieldItem, + SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback); +}; + +// helper for updating the items we find via UpdatePageRelativeURLs +class EDITENG_DLLPUBLIC SvxFieldItemUpdater +{ +public: + virtual ~SvxFieldItemUpdater(); + + // write-access when SvxFieldItem needs to be modified + virtual void SetItem(const SvxFieldItem&) = 0; }; } diff --git a/sd/inc/drawdoc.hxx b/sd/inc/drawdoc.hxx index 50f88cc93a3d..d4dad173b7fb 100644 --- a/sd/inc/drawdoc.hxx +++ b/sd/inc/drawdoc.hxx @@ -36,6 +36,7 @@ namespace com::sun::star::xml::dom { class XNode; } namespace com::sun::star::uno { class XInterface; } +namespace editeng { class SvxFieldItemUpdater; } namespace vcl { class Font; } namespace com::sun::star::presentation { class XPresentation2; } class SdOutliner; @@ -628,6 +629,9 @@ public: void dumpAsXml(xmlTextWriterPtr pWriter) const override; private: + + void UpdatePageRelativeURLsImpl(const std::function<void(const SvxFieldItem & rFieldItem, editeng::SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback); + /** This member stores the printer independent layout mode. Please refer to <member>SetPrinterIndependentLayout()</member> for its values. diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx index 8a3380cf9475..ed91f4034046 100644 --- a/sd/source/core/drawdoc2.cxx +++ b/sd/source/core/drawdoc2.cxx @@ -28,6 +28,8 @@ #include <svx/svdundo.hxx> #include <vcl/svapp.hxx> #include <editeng/eeitem.hxx> +#include <editeng/editobj.hxx> +#include <editeng/fieldupdater.hxx> #include <editeng/langitem.hxx> #include <svl/itempool.hxx> #include <editeng/flditem.hxx> @@ -260,29 +262,83 @@ void SdDrawDocument::UpdatePageObjectsInNotes(sal_uInt16 nStartPos) } } -void SdDrawDocument::UpdatePageRelativeURLs(std::u16string_view aOldName, std::u16string_view aNewName) +namespace { - if (aNewName.empty()) - return; +class SvxFieldItemUpdater_BaseProperties final : public editeng::SvxFieldItemUpdater +{ + sdr::properties::BaseProperties& mrProps; - SfxItemPool& rPool(GetPool()); +public: + SvxFieldItemUpdater_BaseProperties(sdr::properties::BaseProperties& rProps) + : mrProps(rProps) {} - rPool.iterateItemSurrogates(EE_FEATURE_FIELD, [&](SfxItemPool::SurrogateData& rData) + virtual void SetItem(const SvxFieldItem& rNew) override { - const SvxFieldItem* pFieldItem(dynamic_cast<const SvxFieldItem*>(&rData.getItem())); + mrProps.SetObjectItem(rNew); + } +}; +} - if (nullptr == pFieldItem) - return true; // continue callbacks +static void UpdatePageRelativeURLs(SdrObject& rObj, const std::function<void(const SvxFieldItem & rFieldItem, editeng::SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback) +{ + if (SdrObjList* pChildrenObjs = rObj.getChildrenOfSdrObject()) + { + for (const rtl::Reference<SdrObject>& pSubObj : *pChildrenObjs) + UpdatePageRelativeURLs(*pSubObj, rItemCallback); + } - const SvxURLField* pURLField(dynamic_cast<const SvxURLField*>(pFieldItem->GetField())); + // cannot call GetObjectItemSet on a group + if (rObj.GetObjIdentifier() != SdrObjKind::Group) + { + sdr::properties::BaseProperties& rProps = rObj.GetProperties(); + const SfxItemSet& rSet = rProps.GetObjectItemSet(); + if (const SvxFieldItem* pFieldItem = rSet.GetItemIfSet(EE_FEATURE_FIELD)) + { + SvxFieldItemUpdater_BaseProperties aItemUpdater(rProps); + rItemCallback(*pFieldItem, aItemUpdater); + } + } - if (nullptr == pURLField) - return true; // continue callbacks + SdrTextObj* pTxtObj = DynCastSdrTextObj(&rObj); + if (!pTxtObj) + return; + OutlinerParaObject* pOutlinerParagraphObject = pTxtObj->GetOutlinerParaObject(); + if (!pOutlinerParagraphObject) + return; + EditTextObject& aEdit = const_cast<EditTextObject&>(pOutlinerParagraphObject->GetTextObject()); + if (!aEdit.IsFieldObject()) + return; + const SvxFieldItem* pFieldItem = aEdit.GetField(); + if (!pFieldItem) + return; + aEdit.GetFieldUpdater().UpdatePageRelativeURLs(rItemCallback); +}; - OUString aURL(pURLField->GetURL()); +void SdDrawDocument::UpdatePageRelativeURLsImpl(const std::function<void(const SvxFieldItem & rFieldItem, editeng::SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback) +{ + for (sal_uInt16 nPage = 0, nPageCount = GetPageCount(); nPage < nPageCount; ++nPage) + { + SdrPage* pPage = GetPage(nPage); + for(size_t nObj = 0, nObjCount = pPage->GetObjCount(); nObj < nObjCount; ++nObj) + ::UpdatePageRelativeURLs(*pPage->GetObj(nObj), rItemCallback); + } +} + +void SdDrawDocument::UpdatePageRelativeURLs(std::u16string_view aOldName, std::u16string_view aNewName) +{ + if (aNewName.empty()) + return; + const OUString sNotes(SdResId(STR_NOTES)); + auto aItemCallback = [&sNotes, &aOldName, &aNewName](const SvxFieldItem & rFieldItem, editeng::SvxFieldItemUpdater& rFieldItemUpdater) -> void + { + const SvxFieldData* pFieldData = rFieldItem.GetField(); + if (pFieldData->GetClassId() != SvxURLField::CLASS_ID) + return; + const SvxURLField* pURLField(static_cast<const SvxURLField*>(pFieldData)); + OUString aURL(pURLField->GetURL()); if (aURL.isEmpty() || (aURL[0] != 35) || (aURL.indexOf(aOldName, 1) != 1)) - return true; // continue callbacks + return; bool bURLChange(false); @@ -294,7 +350,6 @@ void SdDrawDocument::UpdatePageRelativeURLs(std::u16string_view aOldName, std::u } else { - const OUString sNotes(SdResId(STR_NOTES)); if (aURL.getLength() == sal_Int32(aOldName.size()) + 2 + sNotes.getLength() && aURL.indexOf(sNotes, aOldName.size() + 2) == sal_Int32(aOldName.size() + 2)) { @@ -306,36 +361,30 @@ void SdDrawDocument::UpdatePageRelativeURLs(std::u16string_view aOldName, std::u if(bURLChange) { - SvxFieldItem* pNewFieldItem(pFieldItem->Clone(&rPool)); - const_cast<SvxURLField*>(static_cast<const SvxURLField*>(pNewFieldItem->GetField()))->SetURL(aURL); - rData.setItem(std::unique_ptr<SfxPoolItem>(pNewFieldItem)); + SvxFieldItem aNewFieldItem(rFieldItem); + const_cast<SvxURLField*>(static_cast<const SvxURLField*>(aNewFieldItem.GetField()))->SetURL(aURL); + rFieldItemUpdater.SetItem(aNewFieldItem); } + }; - return true; // continue callbacks - }); + UpdatePageRelativeURLsImpl(aItemCallback); } void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * pPage, sal_uInt16 nPos, sal_Int32 nIncrement) { bool bNotes = (pPage->GetPageKind() == PageKind::Notes); - SfxItemPool& rPool(GetPool()); - rPool.iterateItemSurrogates(EE_FEATURE_FIELD, [&](SfxItemPool::SurrogateData& rData) + auto aItemCallback = [this, nPos, bNotes, nIncrement](const SvxFieldItem & rFieldItem, editeng::SvxFieldItemUpdater& rFieldItemUpdater) -> void { - const SvxFieldItem* pFieldItem(static_cast<const SvxFieldItem*>(&rData.getItem())); - - if (nullptr == pFieldItem) - return true; // continue callbacks - - const SvxURLField* pURLField(dynamic_cast<const SvxURLField*>(pFieldItem->GetField())); + const SvxURLField* pURLField(dynamic_cast<const SvxURLField*>(rFieldItem.GetField())); if (nullptr == pURLField) - return true; // continue callbacks + return; OUString aURL(pURLField->GetURL()); if (aURL.isEmpty() || (aURL[0] != 35)) - return true; // continue callbacks + return; OUString aHashSlide; if (meDocType == DocumentType::Draw) @@ -344,7 +393,7 @@ void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * pPage, sal_uInt16 nPo aHashSlide = "#" + SdResId(STR_PAGE); if (!aURL.startsWith(aHashSlide)) - return true; // continue callbacks + return; OUString aURLCopy = aURL; const OUString sNotes(SdResId(STR_NOTES)); @@ -355,7 +404,7 @@ void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * pPage, sal_uInt16 nPo && aURLCopy.endsWith(sNotes) ); if (bNotesLink != bNotes) - return true; // no compatible link and page, continue callbacks + return; // no compatible link and page if (bNotes) aURLCopy = aURLCopy.replaceAt(aURLCopy.getLength() - sNotes.getLength(), sNotes.getLength(), u""); @@ -364,7 +413,7 @@ void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * pPage, sal_uInt16 nPo sal_uInt16 realPageNumber = (nPos + 1)/ 2; if ( number < realPageNumber ) - return true; // continue callbacks + return; // update link page number number += nIncrement; @@ -375,12 +424,12 @@ void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * pPage, sal_uInt16 nPo aURL += " " + sNotes; } - SvxFieldItem* pNewFieldItem(pFieldItem->Clone(&rPool)); - const_cast<SvxURLField*>(static_cast<const SvxURLField*>(pNewFieldItem->GetField()))->SetURL(aURL); - rData.setItem(std::unique_ptr<SfxPoolItem>(pNewFieldItem)); + SvxFieldItem aNewFieldItem(rFieldItem); + const_cast<SvxURLField*>(static_cast<const SvxURLField*>(aNewFieldItem.GetField()))->SetURL(aURL); + rFieldItemUpdater.SetItem(aNewFieldItem); + }; - return true; // continue callbacks - }); + UpdatePageRelativeURLsImpl(aItemCallback); } // Move page