download.lst | 4 external/zxcvbn-c/0001-There-is-no-std-basic_string-int.patch.1 | 72 - external/zxcvbn-c/0001-use-const-for-these-arrays.patch.1 | 42 external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk | 2 include/svx/svxbmpnumiconview.hxx | 73 + readlicense_oo/license/license.xml | 6 solenv/clang-format/excludelist | 2 svx/Library_svx.mk | 1 svx/source/dialog/svxbmpnumiconview.cxx | 539 ++++++++++ svx/source/tbxctrls/bulletsnumbering.cxx | 191 ++- svx/uiconfig/ui/numberingwindow.ui | 66 - sw/qa/extras/odfimport/data/tdf167774.odt |binary sw/qa/extras/odfimport/odfimport.cxx | 15 sw/source/core/attr/calbck.cxx | 2 sw/source/core/layout/flyincnt.cxx | 10 sw/source/core/layout/pagechg.cxx | 8 sw/source/core/ole/ndole.cxx | 68 - sw/source/core/txtnode/atrfld.cxx | 5 sw/source/core/txtnode/ndtxt.cxx | 63 - 19 files changed, 855 insertions(+), 314 deletions(-)
New commits: commit 844be84c6a7fd1816b23b4c559dc93bdbc3a630e Author: Parth Raiyani <parth.raiy...@collabora.com> AuthorDate: Fri Aug 22 12:56:38 2025 +0530 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Sep 1 14:59:52 2025 +0200 Switch to IconView in bullets numbering popup for improved UI handling - Replaced SvxNumValueSet with weld::IconView in the bullets numbering popup - Updated UI in numberingwindow.ui to include GtkIconView and GtkTreeStore - Refactors related logic to accommodate IconView, including preview generation, selection handling, and tooltip support Change-Id: I0b9b2fa5e9612488662548edc1fb78bf7eaa95e0 Signed-off-by: Parth Raiyani <parth.raiy...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189605 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/include/svx/svxbmpnumiconview.hxx b/include/svx/svxbmpnumiconview.hxx new file mode 100644 index 000000000000..853ad3ae29a1 --- /dev/null +++ b/include/svx/svxbmpnumiconview.hxx @@ -0,0 +1,73 @@ +/* -*- 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 <svx/numvset.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::text; +using namespace com::sun::star::container; +using namespace com::sun::star::style; + +class SVX_DLLPUBLIC SvxBmpNumIconView +{ +public: + static vcl::Font& GetDefaultBulletFont(); + + static void PopulateIconView( + weld::IconView* pIconView, + NumberingPageType ePageType, + Size previewSize, + const Sequence<Sequence<PropertyValue>>& rNumSettings = Sequence<Sequence<PropertyValue>>(), + const Sequence<Reference<XIndexAccess>>& rOutlineSettings = Sequence<Reference<XIndexAccess>>(), + Reference<XNumberingFormatter> const& xFormatter = nullptr, + const Locale& rLocale = Locale()); + + static VclPtr<VirtualDevice> CreatePreviewFromUserDraw( + NumberingPageType ePageType, + sal_Int32 nIndex, + Size previewSize, + const Sequence<Sequence<PropertyValue>>& rNumSettings = Sequence<Sequence<PropertyValue>>(), + const Sequence<Reference<XIndexAccess>>& rOutlineSettings = Sequence<Reference<XIndexAccess>>(), + Reference<XNumberingFormatter> const& xFormatter = nullptr, + const Locale& rLocale = Locale(), + const std::vector<std::pair<OUString, OUString>>& rCustomBullets = std::vector<std::pair<OUString, OUString>>()); + + static VclPtr<VirtualDevice> CreateCustomBulletPreview(const OUString& rBulletChar, const OUString& rFontName); + static OUString GetNumberingDescription(NumberingPageType ePageType, sal_Int32 nIndex); + + static void SetNumberingSettings( + weld::IconView* mxIconView, + Size previewSize, + const Sequence<Sequence<PropertyValue>>& aNum, + Reference<XNumberingFormatter> const& xFormat, + const Locale& rLocale, + std::vector<std::pair<OUString, OUString>> maCustomBullets = std::vector<std::pair<OUString, OUString>>()); + + static void SetOutlineNumberingSettings( + weld::IconView* mxIconView, + Size previewSize, + const Sequence<Reference<XIndexAccess>>& rOutline, + Reference<XNumberingFormatter> const& xFormat, + const Locale& rLocale, + std::vector<std::pair<OUString, OUString>> maCustomBullets = std::vector<std::pair<OUString, OUString>>()); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index f8c6642f9316..2a99f09fcc7c 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -5731,6 +5731,7 @@ include/svx/ParseContext.hxx include/svx/ShapeTypeHandler.hxx include/svx/SmartTagItem.hxx include/svx/SmartTagMgr.hxx +include/svx/svxbmpnumiconview.hxx include/svx/SvxColorChildWindow.hxx include/svx/SvxPresetListBox.hxx include/svx/algitem.hxx @@ -11318,6 +11319,7 @@ svx/source/dialog/searchcharmap.cxx svx/source/dialog/spacinglistbox.cxx svx/source/dialog/srchctrl.cxx svx/source/dialog/srchdlg.cxx +svx/source/dialog/svxbmpnumiconview.cxx svx/source/dialog/svxbmpnumvalueset.cxx svx/source/dialog/svxgraphicitem.cxx svx/source/dialog/svxruler.cxx diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk index 4dd372c5bda4..9ba2b77f6aaa 100644 --- a/svx/Library_svx.mk +++ b/svx/Library_svx.mk @@ -173,6 +173,7 @@ $(eval $(call gb_Library_add_exception_objects,svx,\ svx/source/dialog/srchdlg \ svx/source/dialog/strarray \ svx/source/dialog/svxbmpnumvalueset \ + svx/source/dialog/svxbmpnumiconview \ svx/source/dialog/svxgraphicitem \ svx/source/dialog/svxruler \ svx/source/dialog/swframeexample \ diff --git a/svx/source/dialog/svxbmpnumiconview.cxx b/svx/source/dialog/svxbmpnumiconview.cxx new file mode 100644 index 000000000000..84582570821c --- /dev/null +++ b/svx/source/dialog/svxbmpnumiconview.cxx @@ -0,0 +1,539 @@ +/* -*- 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 <com/sun/star/text/DefaultNumberingProvider.hpp> +#include <com/sun/star/text/XNumberingFormatter.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/graphic/XGraphic.hpp> + +#include <vcl/virdev.hxx> +#include <i18nlangtag/mslangid.hxx> +#include <editeng/svxenum.hxx> +#include <comphelper/diagnose_ex.hxx> +#include <svx/dialmgr.hxx> +#include <svx/strings.hrc> +#include <officecfg/Office/Common.hxx> + +#include <svx/svxbmpnumiconview.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::text; +using namespace com::sun::star::container; +using namespace com::sun::star::style; + +const TranslateId OUTLINE_DESCRIPTIONS[] = { + RID_SVXSTR_OUTLINENUM_DESCRIPTION_0, + RID_SVXSTR_OUTLINENUM_DESCRIPTION_1, + RID_SVXSTR_OUTLINENUM_DESCRIPTION_2, + RID_SVXSTR_OUTLINENUM_DESCRIPTION_3, + RID_SVXSTR_OUTLINENUM_DESCRIPTION_4, + RID_SVXSTR_OUTLINENUM_DESCRIPTION_5, + RID_SVXSTR_OUTLINENUM_DESCRIPTION_6, + RID_SVXSTR_OUTLINENUM_DESCRIPTION_7 +}; + +const TranslateId SINGLENUM_DESCRIPTIONS[] = { + RID_SVXSTR_SINGLENUM_DESCRIPTION_0, + RID_SVXSTR_SINGLENUM_DESCRIPTION_1, + RID_SVXSTR_SINGLENUM_DESCRIPTION_2, + RID_SVXSTR_SINGLENUM_DESCRIPTION_3, + RID_SVXSTR_SINGLENUM_DESCRIPTION_4, + RID_SVXSTR_SINGLENUM_DESCRIPTION_5, + RID_SVXSTR_SINGLENUM_DESCRIPTION_6, + RID_SVXSTR_SINGLENUM_DESCRIPTION_7 +}; + +vcl::Font& SvxBmpNumIconView::GetDefaultBulletFont() +{ + static vcl::Font aDefBulletFont = []() + { + static vcl::Font tmp(u"OpenSymbol"_ustr, u""_ustr, Size(0, 14)); + tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL ); + tmp.SetFamily( FAMILY_DONTKNOW ); + tmp.SetPitch( PITCH_DONTKNOW ); + tmp.SetWeight( WEIGHT_DONTKNOW ); + tmp.SetTransparent( true ); + return tmp; + }(); + return aDefBulletFont; +} + +void SvxBmpNumIconView::PopulateIconView( + weld::IconView* pIconView, + NumberingPageType ePageType, + Size previewSize, + const Sequence<Sequence<PropertyValue>>& rNumSettings, + const Sequence<Reference<XIndexAccess>>& rOutlineSettings, + Reference<XNumberingFormatter> const& xFormatter, + const Locale& rLocale) +{ + if (!pIconView) + return; + + pIconView->clear(); + + if (ePageType == NumberingPageType::BULLET) + { + Sequence<OUString> aBulletSymbols = + officecfg::Office::Common::BulletsNumbering::DefaultBullets::get(); + + for (sal_Int32 i = 0; i < std::min(aBulletSymbols.getLength(), sal_Int32(8)); ++i) + { + VclPtr<VirtualDevice> pVDev = CreatePreviewFromUserDraw(NumberingPageType::BULLET, i, previewSize, rNumSettings, rOutlineSettings, xFormatter, rLocale); + OUString sId = OUString::number(i); + OUString sText = GetNumberingDescription(ePageType, i); + pIconView->insert(-1, &sText, &sId, pVDev, nullptr); + } + } +} + +VclPtr<VirtualDevice> SvxBmpNumIconView::CreatePreviewFromUserDraw( + NumberingPageType ePageType, + sal_Int32 nIndex, + Size previewSize, + const Sequence<Sequence<PropertyValue>>& rNumSettings, + const Sequence<Reference<XIndexAccess>>& rOutlineSettings, + Reference<XNumberingFormatter> const& xFormatter, + const Locale& rLocale, + const std::vector<std::pair<OUString, OUString>>& rCustomBullets) +{ + static const sal_uInt16 aLinesArr[] = + { + 15, 10, + 20, 30, + 25, 50, + 30, 70, + 35, 90, // up to here line positions + 5, 10, // character positions + 10, 30, + 15, 50, + 20, 70, + 25, 90, + }; + + const Color aBackColor(COL_WHITE); + const Color aTextColor(COL_BLACK); + + VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create(); + pVDev->SetOutputSizePixel(previewSize); + + + tools::Long nRectWidth = previewSize.Width(); + tools::Long nRectHeight = previewSize.Height(); + Point aBLPos(0, 0); + + vcl::Font aFont(OutputDevice::GetDefaultFont( + DefaultFontType::UI_SANS, MsLangId::getConfiguredSystemLanguage(), GetDefaultFontFlags::OnlyOne)); + + Size aSize = aFont.GetFontSize(); + + vcl::Font aRuleFont( GetDefaultBulletFont() ); + Sequence<OUString> aBulletSymbols; + + if(ePageType == NumberingPageType::BULLET || ePageType == NumberingPageType::DOCBULLET) + { + if(ePageType == NumberingPageType::BULLET) + { + aBulletSymbols = officecfg::Office::Common::BulletsNumbering::DefaultBullets::get(); + Sequence< OUString > aBulletFonts = + officecfg::Office::Common::BulletsNumbering::DefaultBulletsFonts::get(); + if (nIndex < aBulletFonts.getLength()) + { + aRuleFont.SetFamilyName(aBulletFonts[nIndex]); + } + } + else // DOCBULLET + { + if (o3tl::make_unsigned(nIndex) < rCustomBullets.size()) + { + aRuleFont.SetFamilyName(rCustomBullets[nIndex].second); + } + } + aSize.setHeight(nRectHeight/6); + aRuleFont.SetFontSize(aSize); + aRuleFont.SetColor(aTextColor); + aRuleFont.SetFillColor(aBackColor); + aFont = aRuleFont; + } + else if(ePageType == NumberingPageType::OUTLINE) + { + aSize.setHeight( nRectHeight/8 ); + } + else // SINGLENUM + { + aSize.setHeight(nRectHeight/6); + } + + aFont.SetColor(aTextColor); + aFont.SetFillColor(aBackColor); + aFont.SetFontSize( aSize ); + pVDev->SetFont(aFont); + + pVDev->SetFillColor(aBackColor); + pVDev->SetLineColor(aTextColor); + pVDev->DrawRect(tools::Rectangle(Point(0,0), previewSize)); + + // Draw background lines for non-outline types + if(ePageType != NumberingPageType::OUTLINE) + { + pVDev->SetLineColor(COL_LIGHTGRAY); + Point aStart(aBLPos.X() + nRectWidth * 25 / 100, 0); + Point aEnd(aBLPos.X() + nRectWidth * 9 / 10, 0); + for(sal_uInt16 i = 11; i < 100; i += 33) + { + aStart.setY(aBLPos.Y() + nRectHeight * i / 100); + aEnd.setY(aStart.Y()); + pVDev->DrawLine(aStart, aEnd); + aStart.setY(aBLPos.Y() + nRectHeight * (i + 11) / 100); + aEnd.setY(aStart.Y()); + pVDev->DrawLine(aStart, aEnd); + } + } + + // Render content based on page type + if(ePageType == NumberingPageType::SINGLENUM || + ePageType == NumberingPageType::BULLET || + ePageType == NumberingPageType::DOCBULLET) + { + Point aStart(aBLPos.X() + nRectWidth / 9, 0); + for(sal_uInt16 i = 0; i < 3; i++) + { + sal_uInt16 nY = 11 + i * 33; + aStart.setY(aBLPos.Y() + nRectHeight * nY / 100); + OUString sText; + + if(ePageType == NumberingPageType::BULLET) + { + if (nIndex < aBulletSymbols.getLength()) + sText = aBulletSymbols[nIndex]; + aStart.AdjustY(-(pVDev->GetTextHeight()/2)); + aStart.setX(aBLPos.X() + 5); + } + else if(ePageType == NumberingPageType::DOCBULLET) + { + if (o3tl::make_unsigned(nIndex) < rCustomBullets.size()) + sText = rCustomBullets[nIndex].first; + aStart.AdjustY(-(pVDev->GetTextHeight()/2)); + aStart.setX(aBLPos.X() + 5); + } + else // SINGLENUM + { + if(xFormatter.is() && rNumSettings.getLength() > nIndex) + { + Sequence<PropertyValue> aLevel = rNumSettings.getConstArray()[nIndex]; + try + { + aLevel.realloc(aLevel.getLength() + 1); + PropertyValue& rValue = aLevel.getArray()[aLevel.getLength() - 1]; + rValue.Name = "Value"; + rValue.Value <<= static_cast<sal_Int32>(i + 1); + sText = xFormatter->makeNumberingString(aLevel, rLocale); + } + catch(Exception&) + { + sText = OUString::number(i + 1); + } + } + aStart.setX(aBLPos.X() + 2); + aStart.AdjustY(-(pVDev->GetTextHeight()/2)); + } + pVDev->DrawText(aStart, sText); + } + } + else if(ePageType == NumberingPageType::OUTLINE) + { + tools::Long nStartX = 0; + tools::Long nStartY = 0; + + if(xFormatter.is() && rOutlineSettings.getLength() > nIndex) + { + Reference<XIndexAccess> xLevel = rOutlineSettings.getConstArray()[nIndex]; + try + { + OUString sLevelTexts[5]; + OUString sFontNames[5]; + OUString sBulletChars[5]; + sal_Int16 aNumberingTypes[5]; + OUString sPrefixes[5]; + OUString sSuffixes[5]; + sal_Int16 aParentNumberings[5]; + + sal_Int32 nLevelCount = xLevel->getCount(); + if(nLevelCount > 5) + nLevelCount = 5; + + for(sal_Int32 i = 0; i < nLevelCount; i++) + { + tools::Long nTop = nStartY + nRectHeight * (aLinesArr[2 * i + 11])/100; + Point aLeft(nStartX + nRectWidth * (aLinesArr[2 * i + 10])/100, nTop); + + Any aLevelAny = xLevel->getByIndex(i); + Sequence<PropertyValue> aLevel; + aLevelAny >>= aLevel; + + aNumberingTypes[i] = 0; + aParentNumberings[i] = 0; + + for (const PropertyValue& rProp : aLevel) + { + if (rProp.Name == "NumberingType") + rProp.Value >>= aNumberingTypes[i]; + else if (rProp.Name == "BulletFontName") + rProp.Value >>= sFontNames[i]; + else if (rProp.Name == "BulletChar") + rProp.Value >>= sBulletChars[i]; + else if (rProp.Name == "Prefix") + rProp.Value >>= sPrefixes[i]; + else if (rProp.Name == "Suffix") + rProp.Value >>= sSuffixes[i]; + else if (rProp.Name == "ParentNumbering") + rProp.Value >>= aParentNumberings[i]; + } + + // Generate numbering text using formatter + Sequence<PropertyValue> aProperties(2); + PropertyValue* pProperties = aProperties.getArray(); + pProperties[0].Name = "NumberingType"; + pProperties[0].Value <<= aNumberingTypes[i]; + pProperties[1].Name = "Value"; + pProperties[1].Value <<= sal_Int32(1); + + try + { + sLevelTexts[i] = xFormatter->makeNumberingString(aProperties, rLocale); + } + catch(Exception&) + { + sLevelTexts[i] = "1"; + } + + aLeft.AdjustY(-(pVDev->GetTextHeight()/2)); + + // Draw prefix + if(!sPrefixes[i].isEmpty() && sPrefixes[i] != " ") + { + pVDev->SetFont(aFont); + pVDev->DrawText(aLeft, sPrefixes[i]); + aLeft.AdjustX(pVDev->GetTextWidth(sPrefixes[i])); + } + + // Draw parent numbering + if(aParentNumberings[i]) + { + sal_Int32 nStartLevel = std::min(static_cast<sal_Int32>(aParentNumberings[i]), i); + for(sal_Int32 nParentLevel = i - nStartLevel; nParentLevel < i; nParentLevel++) + { + OUString sTmp = sLevelTexts[nParentLevel] + "."; + + if(aNumberingTypes[nParentLevel] == SVX_NUM_CHAR_SPECIAL && !sBulletChars[nParentLevel].isEmpty()) + { + if(!sFontNames[nParentLevel].isEmpty()) + { + vcl::Font aBulletFont(sFontNames[nParentLevel], aSize); + aBulletFont.SetColor(aTextColor); + pVDev->SetFont(aBulletFont); + } + pVDev->DrawText(aLeft, sBulletChars[nParentLevel]); + aLeft.AdjustX(pVDev->GetTextWidth(sBulletChars[nParentLevel])); + } + else + { + pVDev->SetFont(aFont); + pVDev->DrawText(aLeft, sTmp); + aLeft.AdjustX(pVDev->GetTextWidth(sTmp)); + } + } + } + + // Draw current level + if(aNumberingTypes[i] == SVX_NUM_CHAR_SPECIAL && !sBulletChars[i].isEmpty()) + { + if(!sFontNames[i].isEmpty()) + { + vcl::Font aBulletFont(sFontNames[i], aSize); + aBulletFont.SetColor(aTextColor); + pVDev->SetFont(aBulletFont); + } + pVDev->DrawText(aLeft, sBulletChars[i]); + aLeft.AdjustX(pVDev->GetTextWidth(sBulletChars[i])); + } + else + { + pVDev->SetFont(aFont); + pVDev->DrawText(aLeft, sLevelTexts[i]); + aLeft.AdjustX(pVDev->GetTextWidth(sLevelTexts[i])); + } + + // Draw suffix + if(!sSuffixes[i].isEmpty() && !sSuffixes[i].startsWith(" ")) + { + pVDev->SetFont(aFont); + pVDev->DrawText(aLeft, sSuffixes[i]); + aLeft.AdjustX(pVDev->GetTextWidth(sSuffixes[i])); + } + + // Draw horizontal line + tools::Long nLineTop = nStartY + nRectHeight * aLinesArr[2 * i + 1]/100; + Point aLineLeft(aLeft.X(), nLineTop); + Point aLineRight(nStartX + nRectWidth * 90/100, nLineTop); + pVDev->SetLineColor(COL_LIGHTGRAY); + pVDev->DrawLine(aLineLeft, aLineRight); + } + + } + #ifdef DBG_UTIL + catch(Exception&) + { + static bool bAssert = false; + if(!bAssert) + { + TOOLS_WARN_EXCEPTION("svx.dialog", ""); + bAssert = true; + } + } +#else + catch(Exception&) + { + } +#endif + } + } + + return pVDev; +} + +VclPtr<VirtualDevice> SvxBmpNumIconView::CreateCustomBulletPreview(const OUString& rBulletChar, const OUString& rFontName) +{ + VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create(); + Size aSize(80, 100); + pVDev->SetOutputSizePixel(aSize); + + const Color aBackColor(COL_WHITE); + const Color aTextColor(COL_BLACK); + + pVDev->SetFillColor(aBackColor); + pVDev->SetLineColor(aTextColor); + pVDev->DrawRect(tools::Rectangle(Point(0,0), aSize)); + + // Add horizontal lines + pVDev->SetLineColor(COL_LIGHTGRAY); + Point aStart(aSize.Width() * 25 / 100, 0); + Point aEnd(aSize.Width() * 9 / 10, 0); + for (sal_uInt16 i = 11; i < 100; i += 33) + { + aStart.setY(aSize.Height() * i / 100); + aEnd.setY(aStart.Y()); + pVDev->DrawLine(aStart, aEnd); + aStart.setY(aSize.Height() * (i + 11) / 100); + aEnd.setY(aStart.Y()); + pVDev->DrawLine(aStart, aEnd); + } + + vcl::Font aRuleFont(rFontName, Size(0, aSize.Height()/6)); + aRuleFont.SetCharSet(RTL_TEXTENCODING_SYMBOL); + aRuleFont.SetColor(aTextColor); + aRuleFont.SetFillColor(aBackColor); + pVDev->SetFont(aRuleFont); + + for (sal_uInt16 i = 0; i < 3; i++) // Show 3 sample lines + { + sal_uInt16 nY = 11 + i * 33; + Point pStart(5, aSize.Height() * nY / 100); + pStart.AdjustY(-(pVDev->GetTextHeight()/2)); + pVDev->DrawText(pStart, rBulletChar); + } + + return pVDev; +} + +OUString SvxBmpNumIconView::GetNumberingDescription(NumberingPageType ePageType, sal_Int32 nIndex) +{ + if (nIndex < 0) + return OUString(); + + switch (ePageType) + { + case NumberingPageType::OUTLINE: { + constexpr auto size = std::size(OUTLINE_DESCRIPTIONS); + if (nIndex < static_cast<sal_Int32>(size)) + return SvxResId(OUTLINE_DESCRIPTIONS[nIndex]); + break; + } + case NumberingPageType::SINGLENUM: { + constexpr auto size = std::size(SINGLENUM_DESCRIPTIONS); + if (nIndex < static_cast<sal_Int32>(size)) + return SvxResId(SINGLENUM_DESCRIPTIONS[nIndex]); + break; + } + case NumberingPageType::BULLET: + return u"Bullet " + OUString::number(nIndex + 1); // convert and display 1-based index + default: + break; + } + + return OUString(); +} + +void SvxBmpNumIconView::SetNumberingSettings( + weld::IconView* mxIconView, + Size previewSize, + const Sequence<Sequence<PropertyValue>>& aNum, + Reference<XNumberingFormatter> const& xFormat, + const Locale& rLocale, + std::vector<std::pair<OUString, OUString>> maCustomBullets) +{ + mxIconView->clear(); + + for (sal_Int32 i = 0; i < aNum.getLength(); ++i) + { + VclPtr<VirtualDevice> pVDev = CreatePreviewFromUserDraw( + NumberingPageType::SINGLENUM, i, previewSize, aNum, Sequence<Reference<XIndexAccess>>(), + xFormat, rLocale, maCustomBullets); + + OUString sId = OUString::number(i); + OUString sText = GetNumberingDescription(NumberingPageType::SINGLENUM, i); + mxIconView->insert(-1, &sText, &sId, pVDev, nullptr); + } +} + +void SvxBmpNumIconView::SetOutlineNumberingSettings( + weld::IconView* mxIconView, + Size previewSize, + const Sequence<Reference<XIndexAccess>>& rOutline, + Reference<XNumberingFormatter> const& xFormat, + const Locale& rLocale, + std::vector<std::pair<OUString, OUString>> maCustomBullets) +{ + mxIconView->clear(); + + for (sal_Int32 i = 0; i < rOutline.getLength(); ++i) + { + VclPtr<VirtualDevice> pVDev = CreatePreviewFromUserDraw( + NumberingPageType::OUTLINE, i, previewSize, Sequence<Sequence<PropertyValue>>(), rOutline, + xFormat, rLocale, maCustomBullets); + + OUString sId = OUString::number(i); + OUString sText = GetNumberingDescription(NumberingPageType::OUTLINE, i); + mxIconView->insert(-1, &sText, &sId, pVDev, nullptr); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/tbxctrls/bulletsnumbering.cxx b/svx/source/tbxctrls/bulletsnumbering.cxx index 8e06d125ae4f..9e16d687a581 100644 --- a/svx/source/tbxctrls/bulletsnumbering.cxx +++ b/svx/source/tbxctrls/bulletsnumbering.cxx @@ -23,6 +23,18 @@ #include <vcl/toolbox.hxx> #include <vcl/settings.hxx> #include <vcl/svapp.hxx> +#include <vcl/virdev.hxx> +#include <i18nlangtag/mslangid.hxx> +#include <editeng/svxenum.hxx> +#include <comphelper/diagnose_ex.hxx> +#include <svx/svxbmpnumiconview.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::text; +using namespace com::sun::star::container; +using namespace com::sun::star::style; namespace { @@ -32,19 +44,23 @@ class NumberingPopup : public WeldToolbarPopup { NumberingPageType mePageType; NumberingToolBoxControl& mrController; - std::unique_ptr<SvxNumValueSet> mxValueSet; - std::unique_ptr<weld::CustomWeld> mxValueSetWin; - std::unique_ptr<SvxNumValueSet> mxValueSetDoc; - std::unique_ptr<weld::CustomWeld> mxValueSetWinDoc; + std::unique_ptr<weld::IconView> mxIconView; + std::unique_ptr<weld::IconView> mxIconViewDoc; std::unique_ptr<weld::Button> mxMoreButton; std::unique_ptr<weld::Label> mxBulletsLabel; std::unique_ptr<weld::Label> mxDocBulletsLabel; - DECL_LINK(VSSelectValueSetHdl, ValueSet*, void); - DECL_LINK(VSSelectValueSetDocHdl, ValueSet*, void); + DECL_LINK(ItemActivatedHdl, weld::IconView&, bool); + DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString); + + DECL_LINK(DocItemActivatedHdl, weld::IconView&, bool); DECL_LINK(VSButtonClickSetHdl, weld::Button&, void); virtual void GrabFocus() override; +private: + std::vector<std::pair<OUString, OUString>> maCustomBullets; + Size aPreviewSize; + public: NumberingPopup(NumberingToolBoxControl& rController, weld::Widget* pParent, NumberingPageType ePageType); @@ -56,16 +72,16 @@ class NumberingToolBoxControl : public svt::PopupWindowController NumberingPageType mePageType; public: - explicit NumberingToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + explicit NumberingToolBoxControl( const Reference< XComponentContext >& rxContext ); virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override; std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override; // XInitialization - virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override; // XServiceInfo virtual OUString SAL_CALL getImplementationName() override; - virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override; }; } @@ -75,59 +91,43 @@ NumberingPopup::NumberingPopup(NumberingToolBoxControl& rController, : WeldToolbarPopup(rController.getFrameInterface(), pParent, u"svx/ui/numberingwindow.ui"_ustr, u"NumberingWindow"_ustr) , mePageType(ePageType) , mrController(rController) - , mxValueSet(new SvxNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true))) - , mxValueSetWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *mxValueSet)) - , mxValueSetDoc(new SvxNumValueSet(m_xBuilder->weld_scrolled_window(u"valuesetwin_doc"_ustr, true))) - , mxValueSetWinDoc(new weld::CustomWeld(*m_xBuilder, u"valueset_doc"_ustr, *mxValueSetDoc)) + , mxIconView(m_xBuilder->weld_icon_view(u"numbering_window_iconview"_ustr)) + , mxIconViewDoc(m_xBuilder->weld_icon_view(u"numbering_window_iconview_doc"_ustr)) , mxMoreButton(m_xBuilder->weld_button(u"more"_ustr)) , mxBulletsLabel(m_xBuilder->weld_label(u"label_default"_ustr)) , mxDocBulletsLabel(m_xBuilder->weld_label(u"label_doc"_ustr)) + , aPreviewSize(80, 100) { - mxValueSet->SetStyle(WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NO_DIRECTSELECT); - mxValueSetDoc->SetStyle(WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NO_DIRECTSELECT); - mxValueSet->init(mePageType); - mxValueSetDoc->init(NumberingPageType::DOCBULLET); - mxValueSetWinDoc->hide(); + SvxBmpNumIconView::PopulateIconView(mxIconView.get(), mePageType, aPreviewSize); + SvxBmpNumIconView::PopulateIconView(mxIconViewDoc.get(), NumberingPageType::DOCBULLET, aPreviewSize); + + mxIconViewDoc->hide(); mxDocBulletsLabel->hide(); if ( mePageType != NumberingPageType::BULLET ) { mxBulletsLabel->hide(); - css::uno::Reference< css::text::XDefaultNumberingProvider > xDefNum = css::text::DefaultNumberingProvider::create( mrController.getContext() ); + Reference< XDefaultNumberingProvider > xDefNum = DefaultNumberingProvider::create( mrController.getContext() ); if ( xDefNum.is() ) { - css::lang::Locale aLocale = Application::GetSettings().GetLanguageTag().getLocale(); - css::uno::Reference< css::text::XNumberingFormatter > xFormat( xDefNum, css::uno::UNO_QUERY ); + Locale aLocale = Application::GetSettings().GetLanguageTag().getLocale(); + Reference< XNumberingFormatter > xFormat( xDefNum, UNO_QUERY ); if ( mePageType == NumberingPageType::SINGLENUM ) { - css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aNumberings( + Sequence< Sequence< PropertyValue > > aNumberings( xDefNum->getDefaultContinuousNumberingLevels( aLocale ) ); - mxValueSet->SetNumberingSettings( aNumberings, xFormat, aLocale ); + SvxBmpNumIconView::SetNumberingSettings( mxIconView.get(), aPreviewSize, aNumberings, xFormat, aLocale ); } else if ( mePageType == NumberingPageType::OUTLINE ) { - css::uno::Sequence< css::uno::Reference< css::container::XIndexAccess > > aOutline( + Sequence< Reference< XIndexAccess > > aOutline( xDefNum->getDefaultOutlineNumberings( aLocale ) ); - mxValueSet->SetOutlineNumberingSettings( aOutline, xFormat, aLocale ); + SvxBmpNumIconView::SetOutlineNumberingSettings( mxIconView.get(), aPreviewSize, aOutline, xFormat, aLocale ); } } } - weld::DrawingArea* pDrawingArea = mxValueSet->GetDrawingArea(); - weld::DrawingArea* pDrawingAreaDoc = mxValueSetDoc->GetDrawingArea(); - OutputDevice& rRefDevice = pDrawingArea->get_ref_device(); - Size aItemSize(rRefDevice.LogicToPixel(Size(30, 42), MapMode(MapUnit::MapAppFont))); - mxValueSet->SetExtraSpacing( 2 ); - mxValueSetDoc->SetExtraSpacing( 2 ); - Size aSize(mxValueSet->CalcWindowSizePixel(aItemSize)); - pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); - pDrawingAreaDoc->set_size_request(aSize.Width(), aSize.Height()); - mxValueSet->SetOutputSizePixel(aSize); - mxValueSetDoc->SetOutputSizePixel(aSize); - mxValueSet->SetColor(Application::GetSettings().GetStyleSettings().GetFieldColor()); - mxValueSetDoc->SetColor(Application::GetSettings().GetStyleSettings().GetFieldColor()); - if ( mePageType == NumberingPageType::BULLET ) { AddStatusListener( u".uno:CurrentBulletListType"_ustr ); @@ -142,17 +142,19 @@ NumberingPopup::NumberingPopup(NumberingToolBoxControl& rController, mxMoreButton->set_image(xImage); mxMoreButton->connect_clicked(LINK(this, NumberingPopup, VSButtonClickSetHdl)); - mxValueSet->SetSelectHdl(LINK(this, NumberingPopup, VSSelectValueSetHdl)); - mxValueSetDoc->SetSelectHdl(LINK(this, NumberingPopup, VSSelectValueSetDocHdl)); + mxIconView->connect_item_activated(LINK(this, NumberingPopup, ItemActivatedHdl)); + mxIconView->connect_query_tooltip(LINK(this, NumberingPopup, QueryTooltipHdl)); + + mxIconViewDoc->connect_item_activated(LINK(this, NumberingPopup, DocItemActivatedHdl)); } namespace { bool lcl_BulletIsDefault(std::u16string_view aSymbol, std::u16string_view aFont) { - css::uno::Sequence<OUString> aBulletSymbols + Sequence<OUString> aBulletSymbols = officecfg::Office::Common::BulletsNumbering::DefaultBullets::get(); - css::uno::Sequence<OUString> aBulletFonts + Sequence<OUString> aBulletFonts = officecfg::Office::Common::BulletsNumbering::DefaultBulletsFonts::get(); for (sal_Int32 i = 0; i < aBulletSymbols.getLength(); i++) { @@ -167,12 +169,12 @@ void NumberingPopup::statusChanged( const css::frame::FeatureStateEvent& rEvent { if (rEvent.FeatureURL.Complete == ".uno:DocumentBulletList") { - css::uno::Sequence<OUString> aSeq; + Sequence<OUString> aSeq; if (rEvent.State >>= aSeq) { std::vector<std::pair<OUString, OUString>> aList; - mxValueSetDoc->Clear(); - int i = 1; + mxIconViewDoc->clear(); + // The string contains the bullet as first character, and then the font name for (const OUString& sBulletFont : aSeq) { @@ -180,80 +182,113 @@ void NumberingPopup::statusChanged( const css::frame::FeatureStateEvent& rEvent OUString sFont(sBulletFont.copy(1, sBulletFont.getLength() - 1)); if (lcl_BulletIsDefault(sBullet, sFont)) continue; - mxValueSetDoc->InsertItem(i, sBullet, i); + + VclPtr<VirtualDevice> pVDev = SvxBmpNumIconView::CreateCustomBulletPreview(sBullet, sFont); + OUString sId = OUString::number(aList.size()); + mxIconViewDoc->insert(-1, nullptr, &sId, pVDev, nullptr); aList.emplace_back(sBullet, sFont); - i++; } + if (!aList.empty()) { - mxValueSetWinDoc->show(); mxDocBulletsLabel->show(); - mxValueSetDoc->SetCustomBullets(aList); + mxIconViewDoc->show(); + maCustomBullets = aList; } else { - mxValueSetWinDoc->hide(); mxDocBulletsLabel->hide(); + mxIconViewDoc->hide(); } } } else { - mxValueSet->SetNoSelection(); - sal_Int32 nSelItem; - if ( rEvent.State >>= nSelItem ) - mxValueSet->SelectItem( nSelItem ); + OUString sId = mxIconView->get_selected_id(); + sal_Int32 nSelItem = !sId.isEmpty() ? sId.toInt32() : -1; + if(nSelItem == -1) { + if ( rEvent.State >>= nSelItem ) + { + nSelItem--; // convert to 0-based index for iconview + if(nSelItem > -1 && nSelItem < mxIconView->n_children()) + mxIconView->select( nSelItem ); + } + } } } -IMPL_LINK_NOARG(NumberingPopup, VSSelectValueSetHdl, ValueSet*, void) +IMPL_LINK(NumberingPopup, ItemActivatedHdl, weld::IconView&, rIconView, bool) { - sal_uInt16 nSelItem = mxValueSet->GetSelectedItemId(); + OUString sId = rIconView.get_selected_id(); + if (sId.isEmpty()) + return false; + + sal_Int32 nId = sId.toInt32(); + if ( mePageType == NumberingPageType::BULLET ) { - auto aArgs( comphelper::InitPropertySequence( { { "BulletIndex", css::uno::Any( nSelItem ) } } ) ); + auto aArgs( comphelper::InitPropertySequence( { { "BulletIndex", Any( nId + 1 ) } } ) ); mrController.dispatchCommand( u".uno:SetBullet"_ustr, aArgs ); } else if ( mePageType == NumberingPageType::SINGLENUM ) { - auto aArgs( comphelper::InitPropertySequence( { { "SetNumber", css::uno::Any( nSelItem ) } } ) ); + auto aArgs( comphelper::InitPropertySequence( { { "SetNumber", Any( nId + 1 ) } } ) ); mrController.dispatchCommand( u".uno:SetNumber"_ustr, aArgs ); } else { - auto aArgs( comphelper::InitPropertySequence( { { "SetOutline", css::uno::Any( nSelItem ) } } ) ); + auto aArgs( comphelper::InitPropertySequence( { { "SetOutline", Any( nId + 1 ) } } ) ); mrController.dispatchCommand( u".uno:SetOutline"_ustr, aArgs ); } mrController.EndPopupMode(); + return true; } -IMPL_LINK_NOARG(NumberingPopup, VSSelectValueSetDocHdl, ValueSet*, void) +IMPL_LINK(NumberingPopup, DocItemActivatedHdl, weld::IconView&, rIconView, bool) { - sal_uInt16 nSelItem = mxValueSetDoc->GetSelectedItemId() - 1; - auto aCustomBullets = mxValueSetDoc->GetCustomBullets(); - OUString nChar(aCustomBullets[nSelItem].first); - OUString sFont(aCustomBullets[nSelItem].second); - auto aArgs(comphelper::InitPropertySequence( - { { "BulletChar", css::uno::Any(nChar) }, { "BulletFont", css::uno::Any(sFont) } })); - mrController.dispatchCommand(u".uno:SetBullet"_ustr, aArgs); - mrController.EndPopupMode(); + OUString sId = rIconView.get_selected_id(); + if (sId.isEmpty()) + return false; + + sal_Int32 nId = sId.toInt32(); + + if (nId >= 0 && nId < static_cast<sal_Int32>(maCustomBullets.size())) + { + OUString nChar(maCustomBullets[nId].first); + OUString sFont(maCustomBullets[nId].second); + auto aArgs(comphelper::InitPropertySequence( + { { "BulletChar", Any(nChar) }, { "BulletFont", Any(sFont) } })); + mrController.dispatchCommand(u".uno:SetBullet"_ustr, aArgs); + mrController.EndPopupMode(); + } + return true; +} + +IMPL_LINK(NumberingPopup, QueryTooltipHdl, const weld::TreeIter&, rIter, OUString) +{ + const OUString sId = mxIconView->get_id(rIter); + if (sId.isEmpty()) + return OUString(); + + sal_Int32 nIndex = sId.toInt32(); + return SvxBmpNumIconView::GetNumberingDescription(mePageType, nIndex); } void NumberingPopup::GrabFocus() { - mxValueSet->GrabFocus(); + mxIconView->grab_focus(); } IMPL_LINK_NOARG(NumberingPopup, VSButtonClickSetHdl, weld::Button&, void) { - auto aArgs( comphelper::InitPropertySequence( { { "Page", css::uno::Any( u"customize"_ustr ) } } ) ); + auto aArgs( comphelper::InitPropertySequence( { { "Page", Any( u"customize"_ustr ) } } ) ); mrController.dispatchCommand( u".uno:OutlineBullet"_ustr, aArgs ); mrController.EndPopupMode(); } -NumberingToolBoxControl::NumberingToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext ): - svt::PopupWindowController( rxContext, css::uno::Reference< css::frame::XFrame >(), OUString() ), +NumberingToolBoxControl::NumberingToolBoxControl( const Reference< XComponentContext >& rxContext ): + svt::PopupWindowController( rxContext, Reference< css::frame::XFrame >(), OUString() ), mePageType( NumberingPageType::SINGLENUM ) { } @@ -273,7 +308,7 @@ VclPtr<vcl::Window> NumberingToolBoxControl::createVclPopupWindow( vcl::Window* return mxInterimPopover; } -void SAL_CALL NumberingToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) +void SAL_CALL NumberingToolBoxControl::initialize( const Sequence< Any >& aArguments ) { svt::PopupWindowController::initialize( aArguments ); @@ -305,15 +340,15 @@ OUString SAL_CALL NumberingToolBoxControl::getImplementationName() return u"com.sun.star.comp.svx.NumberingToolBoxControl"_ustr; } -css::uno::Sequence< OUString > SAL_CALL NumberingToolBoxControl::getSupportedServiceNames() +Sequence< OUString > SAL_CALL NumberingToolBoxControl::getSupportedServiceNames() { return { u"com.sun.star.frame.ToolbarController"_ustr }; } -extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +extern "C" SAL_DLLPUBLIC_EXPORT XInterface * com_sun_star_comp_svx_NumberingToolBoxControl_get_implementation( - css::uno::XComponentContext *rxContext, - css::uno::Sequence<css::uno::Any> const & ) + XComponentContext *rxContext, + Sequence<Any> const & ) { return cppu::acquire( new NumberingToolBoxControl( rxContext ) ); } diff --git a/svx/uiconfig/ui/numberingwindow.ui b/svx/uiconfig/ui/numberingwindow.ui index c92acae81edc..42d1f46c4938 100644 --- a/svx/uiconfig/ui/numberingwindow.ui +++ b/svx/uiconfig/ui/numberingwindow.ui @@ -13,6 +13,22 @@ <property name="border-width">4</property> <property name="constrain-to">none</property> <child> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name pixbuf --> + <column type="GdkPixbuf"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkTreeStore" id="liststore2"> + <columns> + <!-- column-name pixbuf --> + <column type="GdkPixbuf"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> <object class="GtkBox" id="container"> <property name="visible">True</property> <property name="can-focus">False</property> @@ -24,7 +40,7 @@ <property name="can-focus">False</property> <property name="label" translatable="yes" context="numberingwindow|label_default">Bullet Library</property> <accessibility> - <relation type="label-for" target="valueset"/> + <relation type="label-for" target="numbering_window_iconview"/> </accessibility> </object> <packing> @@ -34,7 +50,7 @@ </packing> </child> <child> - <object class="GtkScrolledWindow" id="valuesetwin"> + <object class="GtkScrolledWindow"> <property name="visible">True</property> <property name="can-focus">True</property> <property name="hexpand">True</property> @@ -43,21 +59,20 @@ <property name="vscrollbar-policy">never</property> <property name="shadow-type">in</property> <child> - <object class="GtkViewport"> + <object class="GtkIconView" id="numbering_window_iconview"> <property name="visible">True</property> - <property name="can-focus">False</property> - <child> - <object class="GtkDrawingArea" id="valueset"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <accessibility> - <relation type="labelled-by" target="label_default"/> - </accessibility> - </object> - </child> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="model">liststore1</property> + <property name="pixbuf-column">0</property> + <property name="columns">4</property> + <property name="item-width">80</property> + <property name="selection-mode">single</property> + <property name="activate-on-single-click">True</property> + <accessibility> + <relation type="labelled-by" target="label_default"/> + </accessibility> </object> </child> </object> @@ -73,7 +88,7 @@ <property name="can-focus">False</property> <property name="label" translatable="yes" context="numberingwindow|label_doc">Document Bullets</property> <accessibility> - <relation type="label-for" target="valueset_doc"/> + <relation type="label-for" target="numbering_window_iconview_doc"/> </accessibility> </object> <packing> @@ -83,7 +98,7 @@ </packing> </child> <child> - <object class="GtkScrolledWindow" id="valuesetwin_doc"> + <object class="GtkScrolledWindow"> <property name="visible">True</property> <property name="can-focus">True</property> <property name="hexpand">True</property> @@ -92,23 +107,22 @@ <property name="vscrollbar-policy">never</property> <property name="shadow-type">in</property> <child> - <object class="GtkViewport"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <child> - <object class="GtkDrawingArea" id="valueset_doc"> + <object class="GtkIconView" id="numbering_window_iconview_doc"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="model">liststore2</property> + <property name="pixbuf-column">0</property> + <property name="columns">4</property> + <property name="item-width">80</property> + <property name="selection-mode">single</property> + <property name="activate-on-single-click">True</property> <accessibility> <relation type="labelled-by" target="label_doc"/> </accessibility> </object> </child> - </object> - </child> </object> <packing> <property name="expand">False</property> commit 560ccaf3c2083031577548c30fde309edf671a47 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Thu Aug 21 18:39:47 2025 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Sep 1 14:59:39 2025 +0200 tdf#167774: sw_odfimport: Add test Change-Id: I781bd1bbae10f2ccc0660b39e976d99c72c4fee0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190021 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit 3d411a417db35c40e990c2cab09f65198ec0371b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190031 diff --git a/sw/qa/extras/odfimport/data/tdf167774.odt b/sw/qa/extras/odfimport/data/tdf167774.odt new file mode 100644 index 000000000000..c0714c9cadcb Binary files /dev/null and b/sw/qa/extras/odfimport/data/tdf167774.odt differ diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx index a78a9fddf236..8dcbc2776b5d 100644 --- a/sw/qa/extras/odfimport/odfimport.cxx +++ b/sw/qa/extras/odfimport/odfimport.cxx @@ -1545,6 +1545,21 @@ CPPUNIT_TEST_FIXTURE(Test, testWindowsFileZone) #endif } +CPPUNIT_TEST_FIXTURE(Test, testTdf167774) +{ + createSwDoc("tdf167774.odt"); + + CPPUNIT_ASSERT_EQUAL(4, getParagraphs()); + + for (int i = 1; i <= 4; ++i) + { + // Without the fix in place, this test would have failed with + // - Expected: 9 + // - Actual : 10.8 + CPPUNIT_ASSERT_EQUAL(float(9), getProperty<float>(getParagraph(i), u"CharHeight"_ustr)); + } +} + CPPUNIT_TEST_FIXTURE(Test, testEmptyTrailingSpans) { createSwDoc("emptyParagraphLoosesFontHeight.fodt"); commit ea46f29b1398c5516dc6d70511fe053a96be73fc Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Thu Aug 21 14:23:05 2025 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Sep 1 14:59:30 2025 +0200 tdf#167774 Writer shows font of defined style with 10,8 pt instead of 9 pt regression from commit ca65ed8a37847b334868b8cbf05f1ba77665d5aa Author: Noel Grandin <noelgran...@gmail.com> Date: Tue Dec 24 12:28:29 2024 +0200 move RES_FMT_CHG to SfxHint The important fix is in SwModify::SwClientNotify. The other changes are small things I picked up when going over the original patch, which likely don't make much different, but better safe than sorry. Change-Id: I65c79b60740dc7f1b711522db8d8682c69d632e1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189998 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190020 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190023 diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx index e4a1f437cef7..6e6b9721f11b 100644 --- a/sw/source/core/attr/calbck.cxx +++ b/sw/source/core/attr/calbck.cxx @@ -289,7 +289,7 @@ sw::ClientIteratorBase* sw::ClientIteratorBase::s_pClientIters = nullptr; void SwModify::SwClientNotify(const SwModify&, const SfxHint& rHint) { - if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != SfxHintId::SwRemoveUnoObject && rHint.GetId() != SfxHintId::SwRemoveUnoObject) + if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != SfxHintId::SwRemoveUnoObject && rHint.GetId() != SfxHintId::SwFormatChange) return; DBG_TESTSOLARMUTEX(); diff --git a/sw/source/core/layout/flyincnt.cxx b/sw/source/core/layout/flyincnt.cxx index ed249c322bd0..2d7fb593a10f 100644 --- a/sw/source/core/layout/flyincnt.cxx +++ b/sw/source/core/layout/flyincnt.cxx @@ -102,9 +102,13 @@ void SwFlyInContentFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rH } if (rHint.GetId() == SfxHintId::SwFormatChange) { - SwFlyFrame::SwClientNotify(rMod, rHint); - if(GetAnchorFrame()) - AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, GetFormat()); + auto pFormatChangeHint = static_cast<const SwFormatChangeHint*>(&rHint); + if (pFormatChangeHint->m_pNewFormat) + { + SwFlyFrame::SwClientNotify(rMod, rHint); + if(GetAnchorFrame()) + AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, GetFormat()); + } return; } if (rHint.GetId() != SfxHintId::SwLegacyModify) diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index bc8de8ed1f9b..89774c299d8d 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -625,6 +625,14 @@ void SwPageFrame::UpdateAttr_( const SfxPoolItem *pOld, const SfxPoolItem *pNew, } else if (pNew) { + const SwFormatFrameSize &rSz = static_cast<const SwFormatFrameSize&>(*pNew); + + { + SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); + aFrm.Height( std::max( rSz.GetHeight(), tools::Long(MINLAY) ) ); + aFrm.Width ( std::max( rSz.GetWidth(), tools::Long(MINLAY) ) ); + } + if ( GetUpper() ) { static_cast<SwRootFrame*>(GetUpper())->CheckViewLayout( nullptr, nullptr ); diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx index 25b9c0287673..12d72a2cb47d 100644 --- a/sw/source/core/txtnode/atrfld.cxx +++ b/sw/source/core/txtnode/atrfld.cxx @@ -413,6 +413,11 @@ void SwFormatField::UpdateTextNode(const SfxHint& rHint) if (rHint.GetId() == SfxHintId::SwFormatChange) { auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint); + if (pChangeHint->m_pOldFormat == nullptr && pChangeHint->m_pNewFormat == nullptr) + { + ForceUpdateTextNode(); + return; + } if (!IsFieldInDoc()) return; diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index db1061a4d5e4..8f7a2e8dc26b 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -5691,46 +5691,43 @@ void SwTextNode::TriggerNodeUpdate(const sw::RemoveUnoObjectHint& rHint) void SwTextNode::TriggerNodeUpdate(const SwFormatChangeHint& rHint) { - assert(!rHint.m_pOldFormat || dynamic_cast<const SwTextFormatColl*>(rHint.m_pOldFormat)); - assert(!rHint.m_pNewFormat || dynamic_cast<const SwTextFormatColl*>(rHint.m_pNewFormat)); - const SwTextFormatColl* pTxtFmtColOld = static_cast<const SwTextFormatColl*>( - rHint.m_pOldFormat); - const SwTextFormatColl* pTxtFmtColNew = static_cast<const SwTextFormatColl*>( - rHint.m_pNewFormat); - { - sw::TextNodeNotificationSuppressor(*this); + sw::TextNodeNotificationSuppressor(*this); - // Override Modify so that deleting styles works properly (outline - // numbering!). - // Never call ChgTextCollUpdateNum for Nodes in Undo. - if( GetRegisteredIn() == rHint.m_pNewFormat - && GetNodes().IsDocNodes() ) + // Override Modify so that deleting styles works properly (outline + // numbering!). + // Never call ChgTextCollUpdateNum for Nodes in Undo. + if( rHint.m_pOldFormat + && rHint.m_pNewFormat + && GetRegisteredIn() == rHint.m_pNewFormat + && GetNodes().IsDocNodes() ) + { + assert(dynamic_cast<const SwTextFormatColl*>(rHint.m_pNewFormat)); + if (const SwTextFormatColl* pTxtFmtColOld = dynamic_cast<const SwTextFormatColl*>(rHint.m_pOldFormat)) { - if (pTxtFmtColOld) - { - ChgTextCollUpdateNum(pTxtFmtColOld, pTxtFmtColNew); - } + ChgTextCollUpdateNum( + pTxtFmtColOld, static_cast<const SwTextFormatColl*>(rHint.m_pNewFormat)); } + } - // reset fill information - if (maFillAttributes) - { - maFillAttributes.reset(); - } + // reset fill information + if (maFillAttributes && rHint.m_pNewFormat) + { + // ..on format change (e.g. style changed) + maFillAttributes.reset(); + } - if ( !mbInSetOrResetAttr ) - { - HandleModifyAtTextNodeFormatChange( *this ); - } + if ( !mbInSetOrResetAttr ) + { + HandleModifyAtTextNodeFormatChange( *this ); + } - SwContentNode::SwClientNotify(*this, rHint); + SwContentNode::SwClientNotify(*this, rHint); - SwDoc& rDoc = GetDoc(); - // #125329# - assure that text node is in document nodes array - if ( !rDoc.IsInDtor() && &rDoc.GetNodes() == &GetNodes() ) - { - rDoc.GetNodes().UpdateOutlineNode(*this); - } + SwDoc& rDoc = GetDoc(); + // #125329# - assure that text node is in document nodes array + if ( !rDoc.IsInDtor() && &rDoc.GetNodes() == &GetNodes() ) + { + rDoc.GetNodes().UpdateOutlineNode(*this); } } commit f01e0df54af1a533ab0b7ae3494ffa6507578e37 Author: Andras Timar <andras.ti...@collabora.com> AuthorDate: Sat Aug 30 15:17:44 2025 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Sep 1 14:59:06 2025 +0200 license: en-AU spelling dictionary has the same license as en-CA and en-US Change-Id: Ie100857a152f5b8484cb25898b6a97f9cb92bca7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190419 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/readlicense_oo/license/license.xml b/readlicense_oo/license/license.xml index b76431954634..9855f4970b0c 100644 --- a/readlicense_oo/license/license.xml +++ b/readlicense_oo/license/license.xml @@ -3095,11 +3095,7 @@ <h3>Spelling dictionary</h3> <p>The following software may be included in this product: English (Australia) spelling dictionary. Use of any of this software is governed by the terms of the license below:</p> - <p>Copyright (C) 2006 Cameron Roy</p> - <p>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General - Public License as published by the Free Software Foundation; either version 2 of the License, or (at your - option) any later version.</p> - <p><a href="#a__GPL_version_2">Jump to GPL version 2</a></p> + <p><a href="#a__See_English_Canada">See English (Canada)</a>.</p> <h2><a id="a__See_English_Canada" name="a__See_English_Canada">English (Canada)</a></h2> <h3>Spelling dictionary</h3> <p>The following software may be included in this product: English (Canada) spelling dictionary. Use of any of commit 78cfac9d7720d034f40ea14e44c574518034e4ac Author: Stephan Bergmann <stephan.bergm...@collabora.com> AuthorDate: Fri Aug 29 17:33:15 2025 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Sep 1 14:57:58 2025 +0200 Revert part of "register caches with ImplSVData"... ...and of "use a different memory allocation strategy for caches" This reverts the sw/source/core/ole/ndole.cxx part of commit 3fc2216aa394222e7f3f4f0f4f78c5f198c694f5 and of commit b8935ee3b43e515b4a2810bb51a8bf17b90b7446 for now, as it causes > ==489880==ERROR: AddressSanitizer: heap-use-after-free on address 0x7c4dc7e22210 at pc 0x7b6d336739b2 bp 0x7ffc09ed2d50 sp 0x7ffc09ed2d48 > READ of size 8 at 0x7c4dc7e22210 thread T0 (kitbroker_003) > #0 in __gnu_cxx::__normal_iterator<SwOLEObj* const*, std::__cxx1998::vector<SwOLEObj*, std::pmr::polymorphic_allocator<SwOLEObj*>>>::__normal_iterator(SwOLEObj* const* const&) at /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/stl_iterator.h:1059:20 > #1 in std::__cxx1998::vector<SwOLEObj*, std::pmr::polymorphic_allocator<SwOLEObj*>>::begin() const at /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/stl_vector.h:1009:16 > #2 in std::__cxx1998::vector<SwOLEObj*, std::pmr::polymorphic_allocator<SwOLEObj*>>::empty() const at /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/stl_vector.h:1224:16 > #3 in (anonymous namespace)::SwOLELRUCache::dropCaches() at core/sw/source/core/ole/ndole.cxx:98:29 > #4 in ImplSVData::dropCaches() at core/vcl/source/app/svdata.cxx:455:43 > #5 in vcl::lok::trimMemory(int) at core/vcl/source/app/svapp.cxx:1800:18 > #6 in lo_trimMemory(_LibreOfficeKit*, int) at core/desktop/source/lib/init.cxx:3403:5 > #7 in Document::trimAfterInactivity() at online/kit/Kit.cpp:1122:17 > #8 in KitSocketPoll::kitPoll(int) at online/kit/Kit.cpp:3045:20 > #9 in SvpSalInstance::ImplYield(bool, bool) at core/vcl/headless/svpinst.cxx:463:31 > #10 in SvpSalInstance::DoYield(bool, bool) at core/vcl/headless/svpinst.cxx:504:21 > #11 in ImplYield(bool, bool) at core/vcl/source/app/svapp.cxx:389:48 > #12 in Application::Yield() at core/vcl/source/app/svapp.cxx:492:5 > #13 in Application::Execute() at core/vcl/source/app/svapp.cxx:364:13 > #14 in desktop::Desktop::Main() at core/desktop/source/app/app.cxx:1680:13 > #15 in ImplSVMain() at core/vcl/source/app/svmain.cxx:228:35 > #16 in SVMain() at core/vcl/source/app/svmain.cxx:246:12 > #17 in soffice_main at core/desktop/source/app/sofficemain.cxx:121:12 > #18 in lo_runLoop(_LibreOfficeKit*, int (*)(void*, int), void (*)(void*), void*) at core/desktop/source/lib/init.cxx:7849:9 > #19 in lokit_main(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool, bool, bool, bool, bool, unsigned long) at online/kit/Kit.cpp:3928:16 > #20 in createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool)::$_0::operator()() const at online/kit/ForKit.cpp:553:13 > #21 in void std::__invoke_impl<void, createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool)::$_0&>(std::__invoke_other, createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool)::$_0&) at /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/invoke.h:63:14 > #22 in std::enable_if<is_invocable_r_v<void, createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool)::$_0&>, void>::type std::__invoke_r<void, createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool)::$_0&>(createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string< char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool)::$_0&) at /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/invoke.h:113:2 > #23 in std::_Function_handler<void (), createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool)::$_0>::_M_invoke(std::_Any_data const&) at /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/std_function.h:292:9 > #24 in std::function<void ()>::operator()() const at /usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/std_function.h:593:9 > #25 in forkKit(std::function<void ()> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::function<void (int)> const&) at online/kit/ForKit.cpp:496:9 > #26 in createLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool) at online/kit/ForKit.cpp:573:20 > #27 in forkLibreOfficeKit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool) at online/kit/ForKit.cpp:698:39 > #28 in forkit_main(int, char**) at online/kit/ForKit.cpp:1100:17 > #29 in __libc_start_call_main at <null> Change-Id: I8fdc88ca965e27c16b92df1c05e95eca23ab57b6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190379 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx index 6674cb1ab1a6..20cef31053a3 100644 --- a/sw/source/core/ole/ndole.cxx +++ b/sw/source/core/ole/ndole.cxx @@ -33,7 +33,6 @@ #include <sfx2/linkmgr.hxx> #include <unotools/configitem.hxx> #include <utility> -#include <vcl/dropcache.hxx> #include <vcl/outdev.hxx> #include <fmtanchr.hxx> #include <frmfmt.hxx> @@ -58,7 +57,7 @@ #include <svx/unopage.hxx> #include <comphelper/threadpool.hxx> #include <atomic> -#include <vector> +#include <deque> #include <libxml/xmlwriter.h> #include <osl/diagnose.h> #include <flyfrm.hxx> @@ -71,39 +70,14 @@ namespace { class SwOLELRUCache : private utl::ConfigItem - , public CacheOwner { private: -#if defined __cpp_lib_memory_resource - typedef std::pmr::vector<SwOLEObj*> vector_t; -#else - typedef std::vector<SwOLEObj*> vector_t; -#endif - vector_t m_OleObjects; + std::deque<SwOLEObj *> m_OleObjects; sal_Int32 m_nLRU_InitSize; static uno::Sequence< OUString > GetPropertyNames(); virtual void ImplCommit() override; - void tryShrinkCacheTo(sal_Int32 nVal); - - virtual OUString getCacheName() const override - { - return "SwOLELRUCache"; - } - - virtual bool dropCaches() override - { - tryShrinkCacheTo(0); - return m_OleObjects.empty(); - } - - virtual void dumpState(rtl::OStringBuffer& rState) override - { - rState.append(" SwOLELRUCache: "); - rState.append(static_cast<sal_Int32>(m_OleObjects.size())); - } - public: SwOLELRUCache(); @@ -1310,9 +1284,6 @@ void SwOLEObj::dumpAsXml(xmlTextWriterPtr pWriter) const SwOLELRUCache::SwOLELRUCache() : utl::ConfigItem(u"Office.Common/Cache"_ustr) -#if defined __cpp_lib_memory_resource - , m_OleObjects(&GetMemoryResource()) -#endif , m_nLRU_InitSize( 20 ) { EnableNotification( GetPropertyNames() ); @@ -1334,23 +1305,6 @@ void SwOLELRUCache::ImplCommit() { } -void SwOLELRUCache::tryShrinkCacheTo(sal_Int32 nVal) -{ - // size of cache has been changed - sal_Int32 nCount = m_OleObjects.size(); - sal_Int32 nPos = nCount; - - // try to remove the last entries until new maximum size is reached - while( nCount > nVal ) - { - SwOLEObj *const pObj = m_OleObjects[ --nPos ]; - if ( pObj->UnloadObject() ) - nCount--; - if ( !nPos ) - break; - } -} - void SwOLELRUCache::Load() { Sequence< OUString > aNames( GetPropertyNames() ); @@ -1362,11 +1316,25 @@ void SwOLELRUCache::Load() sal_Int32 nVal = 0; *pValues >>= nVal; + if (nVal < m_nLRU_InitSize) { std::shared_ptr<SwOLELRUCache> xKeepAlive(g_pOLELRU_Cache); // prevent delete this - tryShrinkCacheTo(nVal); + // size of cache has been changed + sal_Int32 nCount = m_OleObjects.size(); + sal_Int32 nPos = nCount; + + // try to remove the last entries until new maximum size is reached + while( nCount > nVal ) + { + SwOLEObj *const pObj = m_OleObjects[ --nPos ]; + if ( pObj->UnloadObject() ) + nCount--; + if ( !nPos ) + break; + } } + m_nLRU_InitSize = nVal; } @@ -1392,7 +1360,7 @@ void SwOLELRUCache::InsertObj( SwOLEObj& rObj ) if ( pObj->UnloadObject() ) nCount--; } - m_OleObjects.insert(m_OleObjects.begin(), &rObj); + m_OleObjects.push_front(&rObj); } void SwOLELRUCache::RemoveObj( SwOLEObj& rObj ) commit b674da4666d1e7fc987e9b7bba8be8868fbf4327 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Thu Aug 7 10:17:30 2025 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Sep 1 08:58:18 2025 +0200 zxcvbn-c: upgrade to 2.6 * 0001-There-is-no-std-basic_string-int.patch.1 and 0001-use-const-for-these-arrays.patch.1 are fixed uptream now Downloaded from https://github.com/tsyrogit/zxcvbn-c/archive/refs/tags/v2.5.tar.gz Change-Id: I80b2d5f2b9a6a6bb274f56098f72010291934b21 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189041 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> Tested-by: Jenkins diff --git a/download.lst b/download.lst index c1f06779da30..d8eda71c535e 100644 --- a/download.lst +++ b/download.lst @@ -748,8 +748,8 @@ ZMF_TARBALL := libzmf-0.0.2.tar.xz # three static lines # so that git cherry-pick # will not run into conflicts -ZXCVBN_C_SHA256SUM := 77d6c6ecb35952a8d8ce7f736b7a2bf466275c48210e309b73782d6b7e84dffd -ZXCVBN_C_TARBALL := zxcvbn-c-2.5.tar.gz +ZXCVBN_C_SHA256SUM := 11e39f6776f9c82c68b2acb94336e32697d4ab6cdb4ac16f9583ccbdd735113a +ZXCVBN_C_TARBALL := zxcvbn-c-2.6.tar.gz # three static lines # so that git cherry-pick # will not run into conflicts diff --git a/external/zxcvbn-c/0001-There-is-no-std-basic_string-int.patch.1 b/external/zxcvbn-c/0001-There-is-no-std-basic_string-int.patch.1 deleted file mode 100644 index a1fe25bba08e..000000000000 --- a/external/zxcvbn-c/0001-There-is-no-std-basic_string-int.patch.1 +++ /dev/null @@ -1,72 +0,0 @@ -From 92c6ea875231876ca264187326ce2d615d5ad543 Mon Sep 17 00:00:00 2001 -From: Stephan Bergmann <stephan.bergm...@allotropia.de> -Date: Tue, 6 Feb 2024 13:14:08 +0100 -Subject: There is no std::basic_string<int> - -...and at least LLVM 19 trunk libc++ complains about it now since -<c3668779c13596e223c26fbd49670d18cd638c40> "[libc++] Remove deprecated -char_traits base template (#72694)" with - -> In file included from dict-generate.cpp:25: -> In file included from ~/llvm/inst/bin/../include/c++/v1/iostream:43: -> In file included from ~/llvm/inst/bin/../include/c++/v1/ios:223: -> In file included from ~/llvm/inst/bin/../include/c++/v1/__locale:24: -> ~/llvm/inst/bin/../include/c++/v1/string:746:43: error: implicit instantiation of undefined template 'std::char_traits<int>' -> 746 | static_assert((is_same<_CharT, typename traits_type::char_type>::value), -> | ^ -> dict-generate.cpp:861:18: note: in instantiation of template class 'std::basic_string<int>' requested here -> 861 | StringOfInts Chld; -> | ^ -> ~/llvm/inst/bin/../include/c++/v1/__fwd/string.h:23:29: note: template is declared here -> 23 | struct _LIBCPP_TEMPLATE_VIS char_traits; -> | ^ - -etc., so use a std::vector<int> instead ---- - dict-generate.cpp | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/dict-generate.cpp b/dict-generate.cpp -index eebcca9..fcfaaea 100644 ---- a/dict-generate.cpp -+++ b/dict-generate.cpp -@@ -22,6 +22,7 @@ - * - **********************************************************************************/ - -+#include <algorithm> - #include <iostream> - #include <string> - #include <fstream> -@@ -387,7 +388,7 @@ typedef map<string, Entry> EntryMap_t; - typedef list<string> StringList_t; - typedef list<NodeSPtr> NodeList_t; - typedef set<StringInt> StringIntSet_t; --typedef basic_string<int> StringOfInts; -+typedef vector<int> StringOfInts; - typedef vector<unsigned int> UintVect; - typedef vector<uint64_t> Uint64Vect; - typedef vector<StringInt *> StrIntPtrVect_t; -@@ -864,15 +865,14 @@ void CreateArrays(NodeSPtr Root, StringIntSet_t & StrSet, StringOfInts & ChildAd - for(Itc = Root->ChildBegin(); Itc != Root->ChildEnd(); ++Itc) - { - int i = Itc->second->GetAddr(); -- Chld += i; -+ Chld.push_back(i); - } - // Find where in pointer array the child pointer string is -- StringOfInts::size_type x = ChildAddrs.find(Chld); -- if (x == StringOfInts::npos) -+ StringOfInts::size_type x = search(ChildAddrs.begin(), ChildAddrs.end(), Chld.begin(), Chld.end()) - ChildAddrs.begin(); -+ if (x == ChildAddrs.size()) - { - // Not found, add it -- x = ChildAddrs.length(); -- ChildAddrs += Chld; -+ ChildAddrs.insert(ChildAddrs.end(), Chld.begin(), Chld.end()); - } - // Val will contain the final node data - uint64_t Val = Its->i; --- -2.43.0 - diff --git a/external/zxcvbn-c/0001-use-const-for-these-arrays.patch.1 b/external/zxcvbn-c/0001-use-const-for-these-arrays.patch.1 deleted file mode 100644 index 77cd9876921d..000000000000 --- a/external/zxcvbn-c/0001-use-const-for-these-arrays.patch.1 +++ /dev/null @@ -1,42 +0,0 @@ -From fb847af696b873750adf2e61410d897d128f3dee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolan.mcnam...@collabora.com> -Date: Sat, 12 Jul 2025 21:21:48 +0100 -Subject: [PATCH] use const for these arrays - -so they don't appear in the .data section. With const WordEndBits -ends up in the .rodata section and Formats in the .data.rel.ro -section. ---- - dict-generate.cpp | 2 +- - zxcvbn.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dict-generate.cpp b/dict-generate.cpp -index 878b4aa..7041be7 100644 ---- a/dict-generate.cpp -+++ b/dict-generate.cpp -@@ -1246,7 +1246,7 @@ int OutputCode(ostream *Out, bool Cmnts, const string & CharSet, StringIntSet_t - unsigned int Len = ((NodeData.size() + 7) / 8); - OutputSize += Len; - x = 999; -- *Out << "static unsigned char WordEndBits[" << Len << "] = {"; -+ *Out << "static const unsigned char WordEndBits[" << Len << "] = {"; - Index = 0; - unsigned int v = 0; - unsigned int y = 0; -diff --git a/zxcvbn.c b/zxcvbn.c -index 95aa88f..f6d843b 100644 ---- a/zxcvbn.c -+++ b/zxcvbn.c -@@ -1228,7 +1228,7 @@ static void SpatialMatch(ZxcMatch_t **Result, const uint8_t *Passwd, int Start, - - /* The possible date formats ordered by length (d for day, m for month, */ - /* y for year, ? for separator) */ --static const char *Formats[] = -+static const char * const Formats[] = - { - "yyyy", - "d?m?yy", --- -2.49.0 - diff --git a/external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk b/external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk index a1167ae708e0..2c3633859df7 100644 --- a/external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk +++ b/external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk @@ -17,8 +17,6 @@ $(eval $(call gb_UnpackedTarball_set_tarball,zxcvbn-c,$(ZXCVBN_C_TARBALL))) # <https://github.com/tsyrogit/zxcvbn-c/pull/37> "use const for these arrays": $(eval $(call gb_UnpackedTarball_add_patches,zxcvbn-c,\ external/zxcvbn-c/zxcvbn-c-2.5-do-not-use-stdafx.patch \ - external/zxcvbn-c/0001-There-is-no-std-basic_string-int.patch.1 \ - external/zxcvbn-c/0001-use-const-for-these-arrays.patch.1 \ )) # vim: set noet sw=4 ts=4: