[Libreoffice-commits] core.git: Branch 'feature/themesupport2' - 504 commits - accessibility/inc accessibility/source avmedia/source basctl/source basegfx/CppunitTest_basegfx.mk basegfx/source basegfx/test basic/qa basic/source bin/find-unneeded-includes bin/symbolstore.py bin/ui-rules-enforcer.py canvas/source chart2/qa chart2/source chart2/uiconfig codemaker/source comphelper/qa comphelper/source compilerplugins/clang config_host/config_features.h.in configure.ac connectivity/source cppu/source cui/Library_cui.mk cui/qa cui/source cui/uiconfig cui/UIConfig_cui.mk dbaccess/source desktop/inc desktop/Library_deployment.mk desktop/source desktop/unx dictionaries distro-configs/LibreOfficeOssFuzz.conf download.lst drawinglayer/inc drawinglayer/Library_drawinglayer.mk drawinglayer/source editeng/source embedserv/source emfio/qa emfio/source extensions/source external/breakpad external/clucene external/harfbuzz external/poppler external/python3 filter/Configuration_filter.mk filter/source forms/sourc e formula/inc formula/source fpicker/inc fpicker/source framework/inc framework/qa framework/source helpcompiler/Module_helpcompiler.mk helpcontent2 hwpfilter/source i18npool/source i18nutil/source idlc/source idl/source include/avmedia include/basegfx include/basic include/com include/comphelper include/connectivity include/desktop include/drawinglayer include/editeng include/filter include/formula include/o3tl include/oox include/registry include/sfx2 include/sot include/svl include/svtools include/svx include/toolkit include/tools include/unotools include/vbahelper include/vcl include/xmloff jvmfwk/plugins l10ntools/source leak-suppress.txt lotuswordpro/source Makefile.fetch Makefile.in nlpsolver/src nlpsolver/ThirdParty odk/examples offapi/com offapi/UnoApi_offapi.mk oox/inc oox/Library_oox.mk oox/source oox/util package/inc package/source postprocess/Rdb_services.mk readlicense_oo/license README.help.md reportdesign/inc reportdesign/source RepositoryExternal.mk Repository.mk Re positoryModule_build.mk RepositoryModule_host.mk sal/osl sal/qa sal/rtl scaddins/source sccomp/source sc/CppunitTest_sc_bugfix_test.mk schema/libreoffice sc/inc sc/Module_sc.mk scp2/source sc/qa scripting/source sc/source sc/uiconfig sc/UITest_csv_dialog.mk sdext/Executable_xpdfimport.mk sdext/source sd/inc sd/qa sd/source sd/uiconfig sfx2/classification sfx2/inc sfx2/Package_classification.mk sfx2/qa sfx2/sdi sfx2/source shell/source slideshow/source solenv/bin solenv/clang-format solenv/CompilerTest_compilerplugins_clang.mk solenv/flatpak-manifest.in solenv/gbuild solenv/gdb soltools/cpp soltools/mkdepend starmath/inc starmath/source stoc/source svgio/qa svgio/source svl/source svtools/source svx/CppunitTest_svx_removewhichrange.mk svx/inc svx/Module_svx.mk svx/qa svx/sdi svx/source svx/uiconfig sw/CppunitTest_sw_indexingexport.mk sw/inc sw/Library_sw.mk sw/qa sw/source sw/uiconfig sw/util sysui/desktop toolkit/inc toolkit/source tools/CppunitTest_tools_test.mk tools/qa tools/sour ce translations ucb/source uitest/demo_ui uitest/impress_tests uitest/math_tests uitest/test_main.py uitest/uitest unotools/qa unotools/source ure/source vbahelper/source vcl/backendtest vcl/CppunitTest_vcl_svm_test.mk vcl/headless vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_gtk3_kde5.mk vcl/Library_vclplug_gtk3.mk vcl/Library_vclplug_gtk4.mk vcl/osx vcl/qa vcl/source vcl/unx vcl/win winaccessibility/source wizards/Package_scriptforge.mk wizards/source writerfilter/inc writerfilter/qa writerfilter/source writerperfect/inc writerperfect/qa writerperfect/source xmlhelp/README.md xmlhelp/source xmloff/inc xmloff/source xmlsecurity/inc xmlsecurity/source

Jan Holesovsky (via logerrit) logerrit at kemper.freedesktop.org
Thu Jul 1 00:55:54 UTC 2021


Rebased ref, commits from common ancestor:
commit 6546856703cf1cec4493e8c357fa89fa7f53f8ca
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Apr 2 00:21:34 2021 +0200
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Thu Jul 1 09:53:47 2021 +0900

    Unit test (with the content disabled so far) for the theming.
    
    Change-Id: Ie9e003df38e1bc766fb5323936138d3e0e664321

diff --git a/sw/qa/extras/ooxmlexport/data/themeOrange.docx b/sw/qa/extras/ooxmlexport/data/themeOrange.docx
new file mode 100644
index 000000000000..e350c2676d41
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/themeOrange.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index bafe3b511730..f29b156d171e 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -587,6 +587,12 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(Test_ShadowDirection, "tdf142361ShadowDirect
                 "rotWithShape", "0");
 }
 
+DECLARE_OOXMLEXPORT_TEST(testThemeOrange, "themeOrange.docx")
+{
+    // Assert that the theme color of the 1st paragraph is "accent1"
+    //CPPUNIT_ASSERT_EQUAL(getProperty<sal_Int16>(getParagraph(1), "CharColorTheme"), static_cast<sal_Int16>(4));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit f02d56dca274961ad9ecc6b1eaeb2acc4dea25b3
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Sep 23 13:38:38 2015 +0200
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Thu Jul 1 09:53:30 2021 +0900

    adjust the conversion from theme color type to the color set index
    
    Change-Id: I8c54c8935de8acc3e2b302e10327aa2488f9ac85

diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx b/writerfilter/source/dmapper/TDefTableHandler.cxx
index 42ab0d61bd83..4bc8faf7e3d5 100644
--- a/writerfilter/source/dmapper/TDefTableHandler.cxx
+++ b/writerfilter/source/dmapper/TDefTableHandler.cxx
@@ -298,15 +298,15 @@ sal_Int16 TDefTableHandler::getThemeColorTypeIndex(sal_Int32 nType)
         case NS_ooxml::LN_Value_St_ThemeColor_followedHyperlink:
                 return 11;
         case NS_ooxml::LN_Value_St_ThemeColor_none:
-                return 12;
+                return -1;
         case NS_ooxml::LN_Value_St_ThemeColor_background1:
-                return 13;
+                return 0;
         case NS_ooxml::LN_Value_St_ThemeColor_text1:
-                return 14;
+                return 1;
         case NS_ooxml::LN_Value_St_ThemeColor_background2:
-                return 15;
+                return 2;
         case NS_ooxml::LN_Value_St_ThemeColor_text2:
-                return 16;
+                return 3;
         default:
                 break;
     }
commit d480eea0e754d0849ff59b391bd37abf043d47cc
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Sep 23 13:37:43 2015 +0200
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Thu Jul 1 09:53:29 2021 +0900

    convert tint value from ooxml to the value we support
    
    Change-Id: I5a79ca434be16f9dccc5aa6118a7efbf4544f0b1

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index a28e3dae2838..8ba4881c4e13 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -999,7 +999,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         case NS_ooxml::LN_CT_Color_themeTint:
             if (m_pImpl->GetTopContext())
             {
-                m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR_TINT_OR_SHADE, uno::makeAny(sal_Int16(nIntValue * 10000 / 256)));
+                m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR_TINT_OR_SHADE, uno::makeAny(sal_Int16((256 - nIntValue) * 10000 / 256)));
             }
             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", OUString::number(nIntValue, 16));
         break;
commit 4e553ab0e53feb30e17048da065921ad9cb78054
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Sep 23 13:35:56 2015 +0200
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Thu Jul 1 09:53:29 2021 +0900

    check that the color index is valid
    
    Change-Id: Id5c7c83f50e1611af12f3b25e6c9a335a8353ba0

diff --git a/sw/source/uibase/sidebar/ThemePanel.cxx b/sw/source/uibase/sidebar/ThemePanel.cxx
index 9117f20a7013..ce42983879ce 100644
--- a/sw/source/uibase/sidebar/ThemePanel.cxx
+++ b/sw/source/uibase/sidebar/ThemePanel.cxx
@@ -232,9 +232,9 @@ void changeFont(SwFormat* pFormat, SwDocStyleSheet const * pStyle, FontSet const
 void changeColor(SwTextFormatColl* pCollection, svx::ColorSet const& rColorSet, StyleRedefinition* /*pRedefinition*/)
 {
     SvxColorItem aColorItem(pCollection->GetColor());
-    if (aColorItem.GetThemeIndex() >= 0)
+    sal_Int16 nIndex = aColorItem.GetThemeIndex();
+    if (nIndex >= 0 && nIndex < 12)
     {
-        sal_Int16 nIndex = aColorItem.GetThemeIndex();
         Color aColor = Color(rColorSet.getColor(nIndex));
         aColor.ApplyTintOrShade(aColorItem.GetTintOrShade());
         aColorItem.SetValue(aColor);
commit 16a0a2089e8572a35a36a7e649703893ecd06299
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Sep 20 19:27:09 2015 +0200
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Thu Jul 1 09:53:29 2021 +0900

    Support reading back theme color from an ooxml document
    
    ooxml supports theme colors and tint/shade value that additionally
    changed the theme color. Read back which theme color + tint/shade
    value was applied in the resulting color and add this attributes
    as properties to be used by writer.
    In sidebar theme panel the changing the theme colors now doesn't
    takes this into account and changes the colors correctly.
    
    Change-Id: I6703e86b1fc6b2ba07f3023ec48e619aec961ff1

diff --git a/include/editeng/unoprnms.hxx b/include/editeng/unoprnms.hxx
index 011e504ae7f4..c637521dcf2d 100644
--- a/include/editeng/unoprnms.hxx
+++ b/include/editeng/unoprnms.hxx
@@ -22,6 +22,8 @@
 
 
 #define UNO_NAME_CHAR_COLOR                     "CharColor"
+#define UNO_NAME_CHAR_COLOR_THEME               "CharColorTheme"
+#define UNO_NAME_CHAR_COLOR_TINT_OR_SHADE       "CharColorTintOrShade"
 #define UNO_NAME_CHAR_HEIGHT                    "CharHeight"
 #define UNO_NAME_CHAR_POSTURE                   "CharPosture"
 #define UNO_NAME_CHAR_SHADOWED                  "CharShadowed"
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index 3580a8f416a2..26913359031e 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -1506,7 +1506,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s
                     // SvxAdjustItem
                     { u"" UNO_NAME_PARA_ADJUST,            RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(),PropertyAttribute::MAYBEVOID,  MID_PARA_ADJUST                      },
                     // SvxColorItem
-                    { u"" UNO_NAME_CHAR_COLOR,             RES_CHRATR_COLOR,  cppu::UnoType<sal_Int32>::get(),               PROPERTY_NONE,  0                                    },
+                    { u"" UNO_NAME_CHAR_COLOR,             RES_CHRATR_COLOR,  cppu::UnoType<sal_Int32>::get(),               PROPERTY_NONE,  MID_COLOR_RGB                        },
                     // SvxShadowedItem
                     { u"" UNO_NAME_CHAR_SHADOWED,          RES_CHRATR_SHADOWED,    cppu::UnoType<bool>::get(),               PROPERTY_NONE,  0                                    },
                     // SvxContouredItem
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
index 263a712010c0..f873500432e7 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -121,8 +121,10 @@
         { u"" UNO_NAME_CHAR_HIGHLIGHT,                      RES_CHRATR_HIGHLIGHT,          cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR                         }, \
         { u"" UNO_NAME_PARA_BACK_COLOR,                     RES_BACKGROUND,                cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, MID_BACK_COLOR                         }, \
         { u"" UNO_NAME_CHAR_CASE_MAP,                       RES_CHRATR_CASEMAP,            cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, 0                                      }, \
-        { u"" UNO_NAME_CHAR_COLOR,                          RES_CHRATR_COLOR,              cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, 0                                      }, \
+        { u"" UNO_NAME_CHAR_COLOR,                          RES_CHRATR_COLOR,              cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, MID_COLOR_RGB }, \
         { u"" UNO_NAME_CHAR_TRANSPARENCE,                   RES_CHRATR_COLOR,              cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_COLOR_ALPHA }, \
+        { u"" UNO_NAME_CHAR_COLOR_THEME,                    RES_CHRATR_COLOR,              cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_COLOR_THEME_INDEX }, \
+        { u"" UNO_NAME_CHAR_COLOR_TINT_OR_SHADE,            RES_CHRATR_COLOR,              cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_COLOR_TINT_OR_SHADE }, \
         { u"" UNO_NAME_CHAR_STRIKEOUT,                      RES_CHRATR_CROSSEDOUT,         cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_CROSS_OUT                          }, \
         { u"" UNO_NAME_CHAR_CROSSED_OUT,                    RES_CHRATR_CROSSEDOUT,         cppu::UnoType<bool>::get(),       PropertyAttribute::MAYBEVOID, MID_CROSSED_OUT                        }, \
         { u"" UNO_NAME_CHAR_ESCAPEMENT,                     RES_CHRATR_ESCAPEMENT,         cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_ESC                                }, \
@@ -363,8 +365,10 @@
                     { u"" UNO_NAME_PARA_GRAPHIC_FILTER, RES_BACKGROUND,       cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER    },\
                     { u"" UNO_NAME_PARA_GRAPHIC_LOCATION, RES_BACKGROUND,         cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION}, \
                     { u"" UNO_NAME_CHAR_CASE_MAP, RES_CHRATR_CASEMAP,     cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, 0},\
-                    { u"" UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, 0},\
+                    { u"" UNO_NAME_CHAR_COLOR,        RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, MID_COLOR_RGB }, \
                     { u"" UNO_NAME_CHAR_TRANSPARENCE, RES_CHRATR_COLOR,      cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, MID_COLOR_ALPHA},\
+                    { u"" UNO_NAME_CHAR_COLOR_THEME,  RES_CHRATR_COLOR,      cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, MID_COLOR_THEME_INDEX }, \
+                    { u"" UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(),         PROPERTY_NONE, MID_COLOR_TINT_OR_SHADE }, \
                     { u"" UNO_NAME_CHAR_STRIKEOUT, RES_CHRATR_CROSSEDOUT,  cppu::UnoType<sal_Int16>::get(),                  PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},\
                     { u"" UNO_NAME_CHAR_CROSSED_OUT, RES_CHRATR_CROSSEDOUT,  cppu::UnoType<bool>::get()  ,        PROPERTY_NONE, 0},\
                     { u"" UNO_NAME_CHAR_ESCAPEMENT, RES_CHRATR_ESCAPEMENT,  cppu::UnoType<sal_Int16>::get(),             PROPERTY_NONE, MID_ESC          },\
@@ -468,8 +472,10 @@
 
 #define COMMON_ACCESSIBILITY_TEXT_ATTRIBUTE \
                     { u"" UNO_NAME_CHAR_BACK_COLOR, RES_CHRATR_BACKGROUND,    cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE ,MID_BACK_COLOR        }, \
-                    { u"" UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, 0},  \
+                    { u"" UNO_NAME_CHAR_COLOR,        RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, MID_COLOR_RGB },  \
                     { u"" UNO_NAME_CHAR_TRANSPARENCE, RES_CHRATR_COLOR,      cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, MID_COLOR_ALPHA },  \
+                    { u"" UNO_NAME_CHAR_COLOR_THEME,  RES_CHRATR_COLOR,      cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, MID_COLOR_THEME_INDEX }, \
+                    { u"" UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(),         PROPERTY_NONE, MID_COLOR_TINT_OR_SHADE }, \
                     { u"" UNO_NAME_CHAR_CONTOURED, RES_CHRATR_CONTOUR,    cppu::UnoType<bool>::get()  ,       PROPERTY_NONE, 0},  \
                     { u"" UNO_NAME_CHAR_EMPHASIS, RES_CHRATR_EMPHASIS_MARK,           cppu::UnoType<sal_Int16>::get(),   PROPERTY_NONE, MID_EMPHASIS},   \
                     { u"" UNO_NAME_CHAR_ESCAPEMENT, RES_CHRATR_ESCAPEMENT,  cppu::UnoType<sal_Int16>::get(),             PROPERTY_NONE, MID_ESC          },  \
diff --git a/sw/source/uibase/sidebar/ThemePanel.cxx b/sw/source/uibase/sidebar/ThemePanel.cxx
index 68c24eb08571..9117f20a7013 100644
--- a/sw/source/uibase/sidebar/ThemePanel.cxx
+++ b/sw/source/uibase/sidebar/ThemePanel.cxx
@@ -229,13 +229,17 @@ void changeFont(SwFormat* pFormat, SwDocStyleSheet const * pStyle, FontSet const
     }
 }*/
 
-void changeColor(SwTextFormatColl* pCollection, svx::ColorSet const & rColorSet, StyleRedefinition* pRedefinition)
+void changeColor(SwTextFormatColl* pCollection, svx::ColorSet const& rColorSet, StyleRedefinition* /*pRedefinition*/)
 {
-    Color aColor = pRedefinition->getColor(rColorSet);
-
     SvxColorItem aColorItem(pCollection->GetColor());
-    aColorItem.SetValue(aColor);
-    pCollection->SetFormatAttr(aColorItem);
+    if (aColorItem.GetThemeIndex() >= 0)
+    {
+        sal_Int16 nIndex = aColorItem.GetThemeIndex();
+        Color aColor = Color(rColorSet.getColor(nIndex));
+        aColor.ApplyTintOrShade(aColorItem.GetTintOrShade());
+        aColorItem.SetValue(aColor);
+        pCollection->SetFormatAttr(aColorItem);
+    }
 }
 
 std::vector<FontSet> initFontSets()
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 39b118e108f0..a28e3dae2838 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -989,12 +989,25 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             // footnote or endnote reference id - not needed
         break;
         case NS_ooxml::LN_CT_Color_themeColor:
+            if (m_pImpl->GetTopContext())
+            {
+                sal_Int16 nIndex = TDefTableHandler::getThemeColorTypeIndex(nIntValue);
+                m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR_THEME_INDEX, uno::makeAny(nIndex));
+            }
             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", TDefTableHandler::getThemeColorTypeString(nIntValue));
         break;
         case NS_ooxml::LN_CT_Color_themeTint:
+            if (m_pImpl->GetTopContext())
+            {
+                m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR_TINT_OR_SHADE, uno::makeAny(sal_Int16(nIntValue * 10000 / 256)));
+            }
             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", OUString::number(nIntValue, 16));
         break;
         case NS_ooxml::LN_CT_Color_themeShade:
+            if (m_pImpl->GetTopContext())
+            {
+                m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR_TINT_OR_SHADE, uno::makeAny(sal_Int16((nIntValue - 256) * 10000 / 256)));
+            }
             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeShade", OUString::number(nIntValue, 16));
         break;
         case NS_ooxml::LN_CT_DocGrid_linePitch:
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index 0100313bdf45..08b695a6007d 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -32,6 +32,8 @@ OUString getPropertyName( PropertyIds eId )
         case PROP_CHAR_SHADOWED:   sName = "CharShadowed"; break;
         case PROP_CHAR_CASE_MAP:   sName = "CharCaseMap"; break;
         case PROP_CHAR_COLOR:      sName = "CharColor"; break;
+        case PROP_CHAR_COLOR_THEME_INDEX: sName = "CharColorTheme"; break;
+        case PROP_CHAR_COLOR_TINT_OR_SHADE: sName = "CharColorTintOrShade"; break;
         case PROP_CHAR_RELIEF:     sName = "CharRelief"; break;
         case PROP_CHAR_UNDERLINE:  sName = "CharUnderline"; break;
         case PROP_CHAR_UNDERLINE_COLOR:  sName = "CharUnderlineColor"; break;
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index a6afe0c5313f..09ec7954c8df 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -54,6 +54,8 @@ enum PropertyIds
         ,PROP_CHAR_CASE_MAP
         ,PROP_CHAR_CHAR_KERNING
         ,PROP_CHAR_COLOR
+        ,PROP_CHAR_COLOR_THEME_INDEX
+        ,PROP_CHAR_COLOR_TINT_OR_SHADE
         ,PROP_CHAR_COMBINE_IS_ON
         ,PROP_CHAR_COMBINE_PREFIX
         ,PROP_CHAR_COMBINE_SUFFIX
diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx b/writerfilter/source/dmapper/TDefTableHandler.cxx
index 9d7059feece6..42ab0d61bd83 100644
--- a/writerfilter/source/dmapper/TDefTableHandler.cxx
+++ b/writerfilter/source/dmapper/TDefTableHandler.cxx
@@ -269,6 +269,50 @@ OUString TDefTableHandler::getThemeColorTypeString(sal_Int32 nType)
     return OUString();
 }
 
+sal_Int16 TDefTableHandler::getThemeColorTypeIndex(sal_Int32 nType)
+{
+    switch (nType)
+    {
+        case NS_ooxml::LN_Value_St_ThemeColor_dark1:
+                return 0;
+        case NS_ooxml::LN_Value_St_ThemeColor_light1:
+                return 1;
+        case NS_ooxml::LN_Value_St_ThemeColor_dark2:
+                return 2;
+        case NS_ooxml::LN_Value_St_ThemeColor_light2:
+                return 3;
+        case NS_ooxml::LN_Value_St_ThemeColor_accent1:
+                return 4;
+        case NS_ooxml::LN_Value_St_ThemeColor_accent2:
+                return 5;
+        case NS_ooxml::LN_Value_St_ThemeColor_accent3:
+                return 6;
+        case NS_ooxml::LN_Value_St_ThemeColor_accent4:
+                return 7;
+        case NS_ooxml::LN_Value_St_ThemeColor_accent5:
+                return 8;
+        case NS_ooxml::LN_Value_St_ThemeColor_accent6:
+                return 9;
+        case NS_ooxml::LN_Value_St_ThemeColor_hyperlink:
+                return 10;
+        case NS_ooxml::LN_Value_St_ThemeColor_followedHyperlink:
+                return 11;
+        case NS_ooxml::LN_Value_St_ThemeColor_none:
+                return 12;
+        case NS_ooxml::LN_Value_St_ThemeColor_background1:
+                return 13;
+        case NS_ooxml::LN_Value_St_ThemeColor_text1:
+                return 14;
+        case NS_ooxml::LN_Value_St_ThemeColor_background2:
+                return 15;
+        case NS_ooxml::LN_Value_St_ThemeColor_text2:
+                return 16;
+        default:
+                break;
+    }
+    return -1;
+}
+
 void TDefTableHandler::lcl_attribute(Id rName, Value & rVal)
 {
     sal_Int32 nIntValue = rVal.getInt();
diff --git a/writerfilter/source/dmapper/TDefTableHandler.hxx b/writerfilter/source/dmapper/TDefTableHandler.hxx
index 17e6f2ed4fab..f9ae47eb5390 100644
--- a/writerfilter/source/dmapper/TDefTableHandler.hxx
+++ b/writerfilter/source/dmapper/TDefTableHandler.hxx
@@ -66,6 +66,7 @@ public:
     css::beans::PropertyValue getInteropGrabBag(const OUString& aName = OUString());
     static OUString getBorderTypeString(sal_Int32 nType);
     static OUString getThemeColorTypeString(sal_Int32 nType);
+    static sal_Int16 getThemeColorTypeIndex(sal_Int32 nType);
 };
 }
 
commit ccdbf815e00dbe2ba21f7e86b6743df100b7401f
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Sep 20 19:20:59 2015 +0200
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Thu Jul 1 09:53:28 2021 +0900

    Theme color and tint/shade attribute for SvxColorItem
    
    To support theme colors the SvxColorItem must be extended with
    an optional attribute theme index to define the index to which
    theme color current color belongs and an optional tint/shade
    attribute define how much the color ha been additionally tinted
    or shaded.
    
    Change-Id: I87b7788ead25f956eeec835ba80df5e913790697

diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx
index 53f5328890b2..ac87db3a2573 100644
--- a/editeng/source/items/textitem.cxx
+++ b/editeng/source/items/textitem.cxx
@@ -1311,14 +1311,18 @@ bool SvxContourItem::GetPresentation
 
 // class SvxColorItem ----------------------------------------------------
 SvxColorItem::SvxColorItem( const sal_uInt16 nId ) :
-    SfxPoolItem( nId ),
-    mColor( COL_BLACK )
+    SfxPoolItem(nId),
+    mColor( COL_BLACK ),
+    maThemeIndex(-1),
+    maTintShade(0)
 {
 }
 
 SvxColorItem::SvxColorItem( const Color& rCol, const sal_uInt16 nId ) :
     SfxPoolItem( nId ),
-    mColor( rCol )
+    mColor( rCol ),
+    maThemeIndex(-1),
+    maTintShade(0)
 {
 }
 
@@ -1329,8 +1333,11 @@ SvxColorItem::~SvxColorItem()
 bool SvxColorItem::operator==( const SfxPoolItem& rAttr ) const
 {
     assert(SfxPoolItem::operator==(rAttr));
+    const SvxColorItem& rColorItem = static_cast<const SvxColorItem&>(rAttr);
 
-    return  mColor == static_cast<const SvxColorItem&>( rAttr ).mColor;
+    return mColor == rColorItem.mColor &&
+           maThemeIndex == rColorItem.maThemeIndex &&
+           maTintShade == rColorItem.maTintShade;
 }
 
 bool SvxColorItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
@@ -1349,6 +1356,16 @@ bool SvxColorItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
             rVal <<= mColor.GetAlpha() == 0;
             break;
         }
+        case MID_COLOR_THEME_INDEX:
+        {
+            rVal <<= maThemeIndex;
+            break;
+        }
+        case MID_COLOR_TINT_OR_SHADE:
+        {
+            rVal <<= maTintShade;
+            break;
+        }
         default:
         {
             rVal <<= mColor;
@@ -1379,11 +1396,29 @@ bool SvxColorItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
             mColor.SetAlpha( Any2Bool( rVal ) ? 0 : 255 );
             return true;
         }
+        case MID_COLOR_THEME_INDEX:
+        {
+            sal_Int16 nIndex = -1;
+            if (!(rVal >>= nIndex))
+                return false;
+            maThemeIndex = nIndex;
+        }
+        break;
+        case MID_COLOR_TINT_OR_SHADE:
+        {
+            sal_Int16 nTintShade = -1;
+            if (!(rVal >>= nTintShade))
+                return false;
+            maTintShade = nTintShade;
+        }
+        break;
         default:
         {
             return rVal >>= mColor;
         }
+        break;
     }
+    return true;
 }
 
 SvxColorItem* SvxColorItem::Clone( SfxItemPool * ) const
diff --git a/include/editeng/colritem.hxx b/include/editeng/colritem.hxx
index afb1d9d15c18..ce51be7f3e30 100644
--- a/include/editeng/colritem.hxx
+++ b/include/editeng/colritem.hxx
@@ -31,6 +31,8 @@ class EDITENG_DLLPUBLIC SvxColorItem final : public SfxPoolItem
 {
 private:
     Color mColor;
+    sal_Int16 maThemeIndex;
+    sal_Int16 maTintShade;
 
 public:
     static SfxPoolItem* CreateDefault();
@@ -57,6 +59,26 @@ public:
     }
     void SetValue(const Color& rNewColor);
 
+    sal_Int16 GetThemeIndex() const
+    {
+        return maThemeIndex;
+    }
+
+    void SetThemeIndex(sal_Int16 nIndex)
+    {
+        maThemeIndex = nIndex;
+    }
+
+    sal_Int16 GetTintOrShade() const
+    {
+        return maTintShade;
+    }
+
+    void SetTintOrShade(sal_Int16 nTintOrShade)
+    {
+        maTintShade = nTintOrShade;
+    }
+
     void dumpAsXml(xmlTextWriterPtr pWriter) const override;
 };
 
diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h
index 8a6c9d0e7769..c6d781da568a 100644
--- a/include/editeng/memberids.h
+++ b/include/editeng/memberids.h
@@ -178,8 +178,12 @@
 #define MID_SHADOW_TRANSPARENCE 1
 
 // SvxColorItem
-#define MID_COLOR_RGB 0
-#define MID_COLOR_ALPHA 1
+#define MID_COLOR_RGB           0
+#define MID_COLOR_ALPHA         1
+//#define MID_GRAPHIC_TRANSPARENT 3 // used, but already defined above
+#define MID_COLOR_THEME_INDEX   4
+#define MID_COLOR_TINT_OR_SHADE 5
+
 
 #endif
 
diff --git a/offapi/com/sun/star/style/CharacterProperties.idl b/offapi/com/sun/star/style/CharacterProperties.idl
index 2f8a87448a33..b9fb1e7a1ca9 100644
--- a/offapi/com/sun/star/style/CharacterProperties.idl
+++ b/offapi/com/sun/star/style/CharacterProperties.idl
@@ -468,6 +468,18 @@ published service CharacterProperties
     */
     [optional, property] short CharTransparence;
 
+    /** If available, keeps the color theme index, so that the character can
+     *  be re-colored easily based on a theme.
+     *
+     *  @since LibreOffice 7.2
+     **/
+    [optional, property] short CharColorTheme;
+
+    /** Tint or shade of the character color.
+     *
+     *  @since LibreOffice 7.2
+     **/
+    [optional, property] short CharColorTintOrShade;
 };
 
 }; }; }; };
diff --git a/svx/sdi/svxitems.sdi b/svx/sdi/svxitems.sdi
index 549ffc3f3227..321d84019568 100644
--- a/svx/sdi/svxitems.sdi
+++ b/svx/sdi/svxitems.sdi
@@ -164,12 +164,19 @@ enum SvxShadowLocation
 };
 item SvxShadowLocation      SvxShadowLocationItem;
 
+struct SvxColor
+{
+    INT32 ColorValue       MID_COLOR_RGB;
+    INT16 ThemeIndex       MID_COLOR_THEME_INDEX;
+    INT16 ThemeTintOrShade MID_COLOR_TINT_OR_SHADE;
+};
+item SvxColor SvxColorItem;
+
 item INT16                  SvxCharScaleWidthItem;
 item INT16                  SvxParaVertAlignItem;
 item INT16                  SvxCharReliefItem;
 item BOOL                   SvxBlinkItem;
 item BOOL                   SvxAutoKernItem;
-item INT32                  SvxColorItem;
 item BOOL                   SvxContourItem;
 item INT16                  SvxFormatBreakItem;  // enum
 item BOOL                   SvxFormatKeepItem;
commit 4f42bcc9dc825cf50a40a00bb992137b6b8906b6
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Sep 24 12:32:14 2015 +0200
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Thu Jul 1 02:50:48 2021 +0200

    Improve preview of theme color sets - add color set name
    
    Change-Id: I1f7b3668ba9dfbab1da283741e99754de2d6be47
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118151
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/sw/source/uibase/sidebar/ThemePanel.cxx b/sw/source/uibase/sidebar/ThemePanel.cxx
index 3ff74fcdb016..68c24eb08571 100644
--- a/sw/source/uibase/sidebar/ThemePanel.cxx
+++ b/sw/source/uibase/sidebar/ThemePanel.cxx
@@ -19,6 +19,7 @@
 #include <editeng/fontitem.hxx>
 #include <vcl/bitmapex.hxx>
 #include <vcl/image.hxx>
+#include <vcl/settings.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/virdev.hxx>
 #include <charatr.hxx>
@@ -367,17 +368,39 @@ BitmapEx GenerateColorPreview(const svx::ColorSet& rColorSet)
 {
     ScopedVclPtrInstance<VirtualDevice> pVirtualDev(*Application::GetDefaultDevice());
     float fScaleFactor = pVirtualDev->GetDPIScaleFactor();
-    tools::Long BORDER = 2 * fScaleFactor;
-    tools::Long SIZE = 12 * fScaleFactor;
+    tools::Long BORDER = 3 * fScaleFactor;
+    tools::Long SIZE = 14 * fScaleFactor;
+    tools::Long LABEL_HEIGHT = 16 * fScaleFactor;
+    tools::Long LABEL_TEXT_HEIGHT = 14 * fScaleFactor;
 
-    Size aSize(BORDER * 7 + SIZE * 6, BORDER * 3 + SIZE * 2);
+    Size aSize(BORDER * 7 + SIZE * 6 + BORDER * 2, BORDER * 3 + SIZE * 2 + LABEL_HEIGHT);
     pVirtualDev->SetOutputSizePixel(aSize);
+    pVirtualDev->SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetFaceColor()));
+    pVirtualDev->Erase();
 
     tools::Long x = BORDER;
-    tools::Long y1 = BORDER;
+    tools::Long y1 = BORDER + LABEL_HEIGHT;
     tools::Long y2 = y1 + SIZE + BORDER;
 
     pVirtualDev->SetLineColor(COL_LIGHTGRAY);
+    pVirtualDev->SetFillColor(COL_LIGHTGRAY);
+    tools::Rectangle aNameRect(Point(0, 0), Size(aSize.Width(), LABEL_HEIGHT));
+    pVirtualDev->DrawRect(aNameRect);
+
+    vcl::Font aFont;
+    OUString aName = rColorSet.getName();
+    aFont.SetFontHeight(LABEL_TEXT_HEIGHT);
+    pVirtualDev->SetFont(aFont);
+
+    Size aTextSize(pVirtualDev->GetTextWidth(aName), pVirtualDev->GetTextHeight());
+
+    Point aPoint((aNameRect.GetWidth()  / 2.0) - (aTextSize.Width()  / 2.0),
+                 (aNameRect.GetHeight() / 2.0) - (aTextSize.Height() / 2.0));
+
+    pVirtualDev->DrawText(aPoint, aName);
+
+    pVirtualDev->SetLineColor(COL_LIGHTGRAY);
+    pVirtualDev->SetFillColor();
 
     for (sal_uInt32 i = 0; i < 12; i += 2)
     {
@@ -388,6 +411,8 @@ BitmapEx GenerateColorPreview(const svx::ColorSet& rColorSet)
         pVirtualDev->DrawRect(tools::Rectangle(x, y2, x + SIZE, y2 + SIZE));
 
         x += SIZE + BORDER;
+        if (i == 2 || i == 8)
+            x += BORDER;
     }
 
     return pVirtualDev->GetBitmapEx(Point(), aSize);
@@ -415,6 +440,7 @@ ThemePanel::ThemePanel(weld::Widget* pParent)
 {
     mxValueSetColors->SetColCount(2);
     mxValueSetColors->SetLineCount(3);
+    mxValueSetColors->SetColor(Application::GetSettings().GetStyleSettings().GetFaceColor());
 
     mxApplyButton->connect_clicked(LINK(this, ThemePanel, ClickHdl));
     mxListBoxFonts->connect_row_activated(LINK(this, ThemePanel, DoubleClickHdl));
commit 3964e0854507b2696ae0fbe48a4fb005c779947e
Author:     BaiXiaochun <bai.xiaochun.mofan at protonmail.com>
AuthorDate: Tue Jun 29 20:31:30 2021 +0200
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Thu Jul 1 00:39:17 2021 +0200

    Purge out rtl::math::setInf
    
    Change-Id: I71af8273c672a4cbcbfefafffd0003ab266dcce6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118132
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/basic/qa/cppunit/test_scanner.cxx b/basic/qa/cppunit/test_scanner.cxx
index 5663c44d027e..6459ab45f6b1 100644
--- a/basic/qa/cppunit/test_scanner.cxx
+++ b/basic/qa/cppunit/test_scanner.cxx
@@ -13,7 +13,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 #include <cppunit/plugin/TestPlugIn.h>
 
-#include <rtl/math.hxx>
+#include <limits>
 
 #include <scanner.hxx>
 
@@ -654,11 +654,9 @@ void ScannerTest::testNumbers()
     // the buffer is artificially constrained by the scanner.
     CPPUNIT_ASSERT_EQUAL(1u, static_cast<unsigned int>(errors)); // HACK
 
-    double fInf = 0.0;
-    rtl::math::setInf(&fInf, false);
     symbols = getSymbols("10e308", errors);
     CPPUNIT_ASSERT_EQUAL(size_t(2), symbols.size());
-    CPPUNIT_ASSERT_EQUAL(fInf, symbols[0].number);
+    CPPUNIT_ASSERT_EQUAL(std::numeric_limits<double>::infinity(), symbols[0].number);
     CPPUNIT_ASSERT_EQUAL(SbxDOUBLE, symbols[0].type);
     CPPUNIT_ASSERT_EQUAL(cr, symbols[1].text);
     CPPUNIT_ASSERT_EQUAL(1u, static_cast<unsigned int>(errors)); // math error, overflow
diff --git a/chart2/source/view/axes/MinimumAndMaximumSupplier.cxx b/chart2/source/view/axes/MinimumAndMaximumSupplier.cxx
index 422d08e64029..eaf5c4347379 100644
--- a/chart2/source/view/axes/MinimumAndMaximumSupplier.cxx
+++ b/chart2/source/view/axes/MinimumAndMaximumSupplier.cxx
@@ -21,8 +21,7 @@
 
 #include <com/sun/star/chart/TimeUnit.hpp>
 
-#include <rtl/math.hxx>
-
+#include <cmath>
 #include <limits>
 
 namespace chart
@@ -49,8 +48,7 @@ bool MergedMinimumAndMaximumSupplier::hasMinimumAndMaximumSupplier( MinimumAndMa
 
 double MergedMinimumAndMaximumSupplier::getMinimumX()
 {
-    double fGlobalExtremum;
-    ::rtl::math::setInf(&fGlobalExtremum, false);
+    double fGlobalExtremum = std::numeric_limits<double>::infinity();
     for (auto const& elem : m_aMinimumAndMaximumSupplierList)
     {
         double fLocalExtremum = elem->getMinimumX();
@@ -64,8 +62,7 @@ double MergedMinimumAndMaximumSupplier::getMinimumX()
 
 double MergedMinimumAndMaximumSupplier::getMaximumX()
 {
-    double fGlobalExtremum;
-    ::rtl::math::setInf(&fGlobalExtremum, true);
+    double fGlobalExtremum = -std::numeric_limits<double>::infinity();
     for (auto const& elem : m_aMinimumAndMaximumSupplierList)
     {
         double fLocalExtremum = elem->getMaximumX();
@@ -79,8 +76,7 @@ double MergedMinimumAndMaximumSupplier::getMaximumX()
 
 double MergedMinimumAndMaximumSupplier::getMinimumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex )
 {
-    double fGlobalExtremum;
-    ::rtl::math::setInf(&fGlobalExtremum, false);
+    double fGlobalExtremum = std::numeric_limits<double>::infinity();
     for (auto const& elem : m_aMinimumAndMaximumSupplierList)
     {
         double fLocalExtremum = elem->getMinimumYInRange( fMinimumX, fMaximumX, nAxisIndex );
@@ -94,8 +90,7 @@ double MergedMinimumAndMaximumSupplier::getMinimumYInRange( double fMinimumX, do
 
 double MergedMinimumAndMaximumSupplier::getMaximumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex )
 {
-    double fGlobalExtremum;
-    ::rtl::math::setInf(&fGlobalExtremum, true);
+    double fGlobalExtremum = -std::numeric_limits<double>::infinity();
     for (auto const& elem : m_aMinimumAndMaximumSupplierList)
     {
         double fLocalExtremum = elem->getMaximumYInRange( fMinimumX, fMaximumX, nAxisIndex );
@@ -109,8 +104,7 @@ double MergedMinimumAndMaximumSupplier::getMaximumYInRange( double fMinimumX, do
 
 double MergedMinimumAndMaximumSupplier::getMinimumZ()
 {
-    double fGlobalExtremum;
-    ::rtl::math::setInf(&fGlobalExtremum, false);
+    double fGlobalExtremum = std::numeric_limits<double>::infinity();
     for (auto const& elem : m_aMinimumAndMaximumSupplierList)
     {
         double fLocalExtremum = elem->getMinimumZ();
@@ -124,8 +118,7 @@ double MergedMinimumAndMaximumSupplier::getMinimumZ()
 
 double MergedMinimumAndMaximumSupplier::getMaximumZ()
 {
-    double fGlobalExtremum;
-    ::rtl::math::setInf(&fGlobalExtremum, true);
+    double fGlobalExtremum = -std::numeric_limits<double>::infinity();
     for (auto const& elem : m_aMinimumAndMaximumSupplierList)
     {
         double fLocalExtremum = elem->getMaximumZ();
diff --git a/chart2/source/view/axes/VCoordinateSystem.cxx b/chart2/source/view/axes/VCoordinateSystem.cxx
index 1c900b392233..c9364b63a76a 100644
--- a/chart2/source/view/axes/VCoordinateSystem.cxx
+++ b/chart2/source/view/axes/VCoordinateSystem.cxx
@@ -34,8 +34,9 @@
 #include <com/sun/star/chart2/XCoordinateSystem.hpp>
 #include <comphelper/sequence.hxx>
 #include <tools/diagnose_ex.h>
+
 #include <algorithm>
-#include <rtl/math.hxx>
+#include <limits>
 
 namespace chart
 {
@@ -354,10 +355,8 @@ void VCoordinateSystem::prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAuto
         m_aMergedMinMaxSupplier.setTimeResolutionOnXAxis( nTimeResolution, rScaleAutomatism.getNullDate() );
     }
 
-    double fMin = 0.0;
-    double fMax = 0.0;
-    ::rtl::math::setInf(&fMin, false);
-    ::rtl::math::setInf(&fMax, true);
+    double fMin = std::numeric_limits<double>::infinity();
+    double fMax = -std::numeric_limits<double>::infinity();
     if( nDimIndex == 0 )
     {
         // x dimension
diff --git a/chart2/source/view/charttypes/Splines.cxx b/chart2/source/view/charttypes/Splines.cxx
index 338179b2827c..521b559776ee 100644
--- a/chart2/source/view/charttypes/Splines.cxx
+++ b/chart2/source/view/charttypes/Splines.cxx
@@ -18,13 +18,14 @@
  */
 
 #include "Splines.hxx"
-#include <rtl/math.hxx>
 #include <osl/diagnose.h>
 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
 
 #include <vector>
 #include <algorithm>
 #include <memory>
+#include <cmath>
+#include <limits>
 
 namespace chart
 {
@@ -120,9 +121,8 @@ lcl_SplineCalculation::lcl_SplineCalculation(
           m_fYpN( fYnFirstDerivation ),
           m_nKLow( 0 ),
           m_nKHigh( rSortedPoints.size() - 1 ),
-          m_fLastInterpolatedValue(0.0)
+          m_fLastInterpolatedValue(std::numeric_limits<double>::infinity())
 {
-    ::rtl::math::setInf( &m_fLastInterpolatedValue, false );
     Calculate();
 }
 
@@ -133,9 +133,8 @@ lcl_SplineCalculation::lcl_SplineCalculation(
           m_fYpN( 0.0 ),  /*dummy*/
           m_nKLow( 0 ),
           m_nKHigh( rSortedPoints.size() - 1 ),
-          m_fLastInterpolatedValue(0.0)
+          m_fLastInterpolatedValue(std::numeric_limits<double>::infinity())
 {
-    ::rtl::math::setInf( &m_fLastInterpolatedValue, false );
     CalculatePeriodic();
 }
 
@@ -600,10 +599,8 @@ void SplineCalculater::CalculateCubicSplines(
         }
         else // generate the kind "natural spline"
         {
-            double fInfty;
-            ::rtl::math::setInf( &fInfty, false );
-            double fXDerivation = fInfty;
-            double fYDerivation = fInfty;
+            double fXDerivation = std::numeric_limits<double>::infinity();
+            double fYDerivation = std::numeric_limits<double>::infinity();
             aSplineX.reset(new lcl_SplineCalculation( aInputX, fXDerivation, fXDerivation ));
             aSplineY.reset(new lcl_SplineCalculation( aInputY, fYDerivation, fYDerivation ));
         }
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index f69bb8a10dd7..ee89ab640134 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -851,8 +851,7 @@ double lcl_getErrorBarLogicLength(
                                              ? OUString("PositiveError")
                                              : OUString("NegativeError") ) >>= fPercent )
                 {
-                    double fMaxValue;
-                    ::rtl::math::setInf(&fMaxValue, true);
+                    double fMaxValue = -std::numeric_limits<double>::infinity();
                     for(double d : rData)
                     {
                         if(fMaxValue < d)
@@ -1706,9 +1705,8 @@ double VSeriesPlotter::getMinimumYInRange( double fMinimumX, double fMaximumX, s
         return fMinY;
     }
 
-    double fMinimum, fMaximum;
-    ::rtl::math::setInf(&fMinimum, false);
-    ::rtl::math::setInf(&fMaximum, true);
+    double fMinimum = std::numeric_limits<double>::infinity();
+    double fMaximum = -std::numeric_limits<double>::infinity();
     for(std::vector<VDataSeriesGroup> & rXSlots : m_aZSlots)
     {
         for(VDataSeriesGroup & rXSlot : rXSlots)
@@ -1739,9 +1737,8 @@ double VSeriesPlotter::getMaximumYInRange( double fMinimumX, double fMaximumX, s
         return fMaxY;
     }
 
-    double fMinimum, fMaximum;
-    ::rtl::math::setInf(&fMinimum, false);
-    ::rtl::math::setInf(&fMaximum, true);
+    double fMinimum = std::numeric_limits<double>::infinity();
+    double fMaximum = -std::numeric_limits<double>::infinity();
     for( std::vector< VDataSeriesGroup > & rXSlots : m_aZSlots)
     {
         for(VDataSeriesGroup & rXSlot : rXSlots)
@@ -1817,8 +1814,8 @@ bool VSeriesPlotter::isSeparateStackingForDifferentSigns( sal_Int32 nDimensionIn
 
 void VSeriesPlotter::getMinimumAndMaximumX( double& rfMinimum, double& rfMaximum ) const
 {
-    ::rtl::math::setInf(&rfMinimum, false);
-    ::rtl::math::setInf(&rfMaximum, true);
+    rfMinimum = std::numeric_limits<double>::infinity();
+    rfMaximum = -std::numeric_limits<double>::infinity();
 
     for (auto const& ZSlot : m_aZSlots)
     {
@@ -1840,8 +1837,8 @@ void VSeriesPlotter::getMinimumAndMaximumX( double& rfMinimum, double& rfMaximum
 
 void VSeriesPlotter::getMinimumAndMaximumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const
 {
-    ::rtl::math::setInf(&rfMinY, false);
-    ::rtl::math::setInf(&rfMaxY, true);
+    rfMinY = std::numeric_limits<double>::infinity();
+    rfMaxY = -std::numeric_limits<double>::infinity();
 
     for (auto const& ZSlot : m_aZSlots)
     {
@@ -1926,8 +1923,8 @@ sal_Int32 VDataSeriesGroup::getAttachedAxisIndexForFirstSeries() const
 void VDataSeriesGroup::getMinimumAndMaximumX( double& rfMinimum, double& rfMaximum ) const
 {
 
-    ::rtl::math::setInf(&rfMinimum, false);
-    ::rtl::math::setInf(&rfMaximum, true);
+    rfMinimum = std::numeric_limits<double>::infinity();
+    rfMaximum = -std::numeric_limits<double>::infinity();
 
     for (std::unique_ptr<VDataSeries> const & pSeries : m_aSeriesVector)
     {
@@ -2131,8 +2128,8 @@ void VDataSeriesGroup::calculateYMinAndMaxForCategory( sal_Int32 nCategoryIndex
     assert(nCategoryIndex >= 0);
     assert(nCategoryIndex < getPointCount());
 
-    ::rtl::math::setInf(&rfMinimumY, false);
-    ::rtl::math::setInf(&rfMaximumY, true);
+    rfMinimumY = std::numeric_limits<double>::infinity();
+    rfMaximumY = -std::numeric_limits<double>::infinity();
 
     if(m_aSeriesVector.empty())
         return;
@@ -2218,8 +2215,8 @@ void VDataSeriesGroup::calculateYMinAndMaxForCategoryRange(
         , double& rfMinimumY, double& rfMaximumY, sal_Int32 nAxisIndex )
 {
     //@todo maybe cache these values
-    ::rtl::math::setInf(&rfMinimumY, false);
-    ::rtl::math::setInf(&rfMaximumY, true);
+    rfMinimumY = std::numeric_limits<double>::infinity();
+    rfMaximumY = -std::numeric_limits<double>::infinity();
 
     //iterate through the given categories
     if(nStartCategoryIndex<0)
diff --git a/chart2/source/view/main/VDataSeries.cxx b/chart2/source/view/main/VDataSeries.cxx
index 87abdb2810c8..1135174c24d3 100644
--- a/chart2/source/view/main/VDataSeries.cxx
+++ b/chart2/source/view/main/VDataSeries.cxx
@@ -34,7 +34,6 @@
 #include <com/sun/star/chart2/XRegressionCurveCalculator.hpp>
 #include <com/sun/star/chart2/RelativePosition.hpp>
 
-#include <rtl/math.hxx>
 #include <osl/diagnose.h>
 #include <tools/color.hxx>
 #include <tools/diagnose_ex.h>
@@ -657,8 +656,7 @@ bool VDataSeries::isLabelCustomPos(sal_Int32 nPointIndex) const
 
 double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index ) const
 {
-    double fMin=0.0;
-    ::rtl::math::setInf(&fMin, false);
+    double fMin = std::numeric_limits<double>::infinity();
 
     if( !m_aValues_Y.is() &&
         (m_aValues_Y_Min.is() || m_aValues_Y_Max.is()
@@ -693,8 +691,7 @@ double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index ) const
 
 double VDataSeries::getMaximumofAllDifferentYValues( sal_Int32 index ) const
 {
-    double fMax=0.0;
-    ::rtl::math::setInf(&fMax, true);
+    double fMax = -std::numeric_limits<double>::infinity();
 
     if( !m_aValues_Y.is() &&
         (m_aValues_Y_Min.is() || m_aValues_Y_Max.is()
diff --git a/sc/inc/math.hxx b/sc/inc/math.hxx
index 459b82e74bcd..a1afff90a0a7 100644
--- a/sc/inc/math.hxx
+++ b/sc/inc/math.hxx
@@ -52,16 +52,10 @@ inline double divide( const double& fNumerator, const double& fDenominator )
 {
     if (fDenominator == 0.0)
     {
-        double fVal;
         if (std::isfinite( fNumerator) && fNumerator != 0.0)
-        {
-            rtl::math::setInf( &fVal, std::signbit( fNumerator));
-        }
-        else
-        {
-            rtl::math::setNan( &fVal);
-        }
-        return fVal;
+            return std::signbit(fNumerator) ? -std::numeric_limits<double>::infinity()
+                                            :  std::numeric_limits<double>::infinity();
+        return std::numeric_limits<double>::quiet_NaN();
     }
     return fNumerator / fDenominator;
 }
diff --git a/sc/source/core/data/dpitemdata.cxx b/sc/source/core/data/dpitemdata.cxx
index f6d2e9812f9e..da3293d7c2be 100644
--- a/sc/source/core/data/dpitemdata.cxx
+++ b/sc/source/core/data/dpitemdata.cxx
@@ -167,14 +167,14 @@ void ScDPItemData::SetRangeStart(double fVal)
 void ScDPItemData::SetRangeFirst()
 {
     DisposeString();
-    rtl::math::setInf(&mfValue, true);
+    mfValue = -std::numeric_limits<double>::infinity();
     meType = RangeStart;
 }
 
 void ScDPItemData::SetRangeLast()
 {
     DisposeString();
-    rtl::math::setInf(&mfValue, false);
+    mfValue = std::numeric_limits<double>::infinity();
     meType = RangeStart;
 }
 
diff --git a/sc/source/core/data/dputil.cxx b/sc/source/core/data/dputil.cxx
index 6fabf2e286dd..62d61a733055 100644
--- a/sc/source/core/data/dputil.cxx
+++ b/sc/source/core/data/dputil.cxx
@@ -153,16 +153,10 @@ OUString ScDPUtil::getDateGroupName(
 double ScDPUtil::getNumGroupStartValue(double fValue, const ScDPNumGroupInfo& rInfo)
 {
     if (fValue < rInfo.mfStart && !rtl::math::approxEqual(fValue, rInfo.mfStart))
-    {
-        rtl::math::setInf(&fValue, true);
-        return fValue;
-    }
+        return -std::numeric_limits<double>::infinity();
 
     if (fValue > rInfo.mfEnd && !rtl::math::approxEqual(fValue, rInfo.mfEnd))
-    {
-        rtl::math::setInf(&fValue, false);
-        return fValue;
-    }
+        return std::numeric_limits<double>::infinity();
 
     double fDiff = fValue - rInfo.mfStart;
     double fDiv = rtl::math::approxFloor( fDiff / rInfo.mfStep );
commit 54d7fc9ea9d56ec16ec4f641a3dbf01f64233297
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Tue Jun 29 16:13:42 2021 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Wed Jun 30 22:34:41 2021 +0200

    svp: add ostream<< for SvpSalFrame
    
    ... and also store the window title.
    
    Change-Id: I20d8b30f6e8e5c48740fe569d9689a117db11e6d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118129
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx
index ab82a90a4faa..c7a1d8f50845 100644
--- a/vcl/headless/svpframe.cxx
+++ b/vcl/headless/svpframe.cxx
@@ -187,8 +187,9 @@ void SvpSalFrame::PostPaint() const
     }
 }
 
-void SvpSalFrame::SetTitle( const OUString& )
+void SvpSalFrame::SetTitle(const OUString& sTitle)
 {
+    m_sTitle = sTitle;
 }
 
 void SvpSalFrame::SetIcon( sal_uInt16 )
diff --git a/vcl/inc/headless/svpframe.hxx b/vcl/inc/headless/svpframe.hxx
index 145ccf5b3655..4c6dd98e2ca9 100644
--- a/vcl/inc/headless/svpframe.hxx
+++ b/vcl/inc/headless/svpframe.hxx
@@ -54,6 +54,8 @@ class SvpSalFrame : public SalFrame
     std::vector< SvpSalGraphics* >      m_aGraphics;
 
     static SvpSalFrame*       s_pFocusFrame;
+    OUString m_sTitle;
+
 public:
     SvpSalFrame( SvpSalInstance* pInstance,
                  SalFrame* pParent,
@@ -64,6 +66,11 @@ public:
     void LoseFocus();
     void PostPaint() const;
 
+    OUString title() const { return m_sTitle; }
+    SalFrameStyleFlags style() const { return m_nStyle; }
+    bool isVisible() const { return m_bVisible; }
+    bool hasFocus() const { return s_pFocusFrame == this; }
+
     // SalFrame
     virtual SalGraphics*        AcquireGraphics() override;
     virtual void                ReleaseGraphics( SalGraphics* pGraphics ) override;
@@ -120,6 +127,19 @@ private:
     basegfx::B2IVector GetSurfaceFrameSize() const;
 };
 
+template <typename charT, typename traits>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
+                                                     const SvpSalFrame& frame)
+{
+    stream << &frame << " (vis " << frame.isVisible() <<  " focus " << frame.hasFocus();
+    stream << " style " << std::hex << std::setfill('0') << std::setw(8) << static_cast<sal_uInt32>(frame.style());
+    OUString sTitle = frame.title();
+    if (!sTitle.isEmpty())
+        stream << " '" << sTitle << "'";
+    stream << ")";
+    return stream;
+}
+
 #endif // INCLUDED_VCL_INC_HEADLESS_SVPFRAME_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit ce9e6972148c657994beb74f671e51bec5be6689
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Jun 30 15:58:57 2021 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Jun 30 21:48:05 2021 +0200

    tdf#70633 unset Alt if detected as AltGr in both KeyInput branches
    
    we are unsetting Alt if the modifier is AltGr in one SalEvent::KeyInput
    case but not in another. If I replicate the unset of Alt if AlrGr in
    the other place then both UTF-16 parts of the codepoint get accepted
    and the described input case works
    
    Change-Id: Ifa8a5afbb1853ef3d5f388fd5e7bd3bbc048e260
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118170
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 8e4abcdbd66e..45361d8baef0 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -3353,6 +3353,16 @@ bool WinSalFrame::MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangT
     return bRet;
 }
 
+static void UnsetAltIfAltGr(SalKeyEvent& rKeyEvt, sal_uInt16 nModCode)
+{
+    if ((nModCode & (KEY_MOD1 | KEY_MOD2)) == (KEY_MOD1 | KEY_MOD2) &&
+        rKeyEvt.mnCharCode)
+    {
+        // this is actually AltGr and should not be handled as Alt
+        rKeyEvt.mnCode &= ~(KEY_MOD1 | KEY_MOD2);
+    }
+}
+
 static bool ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
                               WPARAM wParam, LPARAM lParam, LRESULT& rResult )
 {
@@ -3441,8 +3451,12 @@ static bool ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
         aKeyEvt.mnCode     |= nModCode;
         aKeyEvt.mnCharCode  = ImplGetCharCode( pFrame, wParam );
         aKeyEvt.mnRepeat    = nRepeat;
+
+        UnsetAltIfAltGr(aKeyEvt, nModCode);
+
         nLastChar = 0;
         nLastVKChar = 0;
+
         bool nRet = pFrame->CallCallback( SalEvent::KeyInput, &aKeyEvt );
         pFrame->CallCallback( SalEvent::KeyUp, &aKeyEvt );
         return nRet;
@@ -3593,12 +3607,7 @@ static bool ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
                 aKeyEvt.mnCode     |= nModCode;
                 aKeyEvt.mnRepeat    = nRepeat;
 
-                if ((nModCode & (KEY_MOD1 | KEY_MOD2)) == (KEY_MOD1 | KEY_MOD2) &&
-                    aKeyEvt.mnCharCode)
-                {
-                    // this is actually AltGr and should not be handled as Alt
-                    aKeyEvt.mnCode &= ~(KEY_MOD1 | KEY_MOD2);
-                }
+                UnsetAltIfAltGr(aKeyEvt, nModCode);
 
                 bIgnoreCharMsg = bCharPeek;
                 bool nRet = pFrame->CallCallback( nEvent, &aKeyEvt );
commit 86372bf5f62aea48cb3b68d30e81597a0dac9cc2
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Jun 30 14:28:21 2021 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Jun 30 21:46:02 2021 +0200

    tdf#143113 fix crash in dnd
    
    Change-Id: Ifab741494e4cc6e51ca4cd89b57c3600d80dca44
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118163
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index a293662791ae..5fb0b67b2b8f 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -176,7 +176,7 @@ public:
     gboolean signalDragDrop(GtkDropTargetAsync *context, GdkDrop *drop, double x, double y);
 #endif
 
-    void signalDragLeave();
+    void signalDragLeave(GtkWidget* pWidget);
 
 #if !GTK_CHECK_VERSION(4, 0, 0)
     void signalDragDropReceived(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, GtkSelectionData* data, guint ttype, guint time);
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index 2b133e0868e3..b3647b6a8296 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -4643,10 +4643,12 @@ GdkDragAction GtkInstDropTarget::signalDragMotion(GtkDropTargetAsync *context, G
 {
     if (!m_bInDrag)
     {
-        GtkWidget* pHighlightWidget = GTK_WIDGET(m_pFrame->getFixedContainer());
 #if !GTK_CHECK_VERSION(4,0,0)
+        GtkWidget* pHighlightWidget = m_pFrame ? GTK_WIDGET(m_pFrame->getFixedContainer()) : pWidget;
         gtk_drag_highlight(pHighlightWidget);
 #else
+        GtkWidget* pHighlightWidget = m_pFrame ? GTK_WIDGET(m_pFrame->getFixedContainer()) :
+                gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(context));
         gtk_widget_set_state_flags(pHighlightWidget, GTK_STATE_FLAG_DROP_ACTIVE, false);
 #endif
     }
@@ -4744,20 +4746,20 @@ GdkDragAction GtkInstDropTarget::signalDragMotion(GtkDropTargetAsync *context, G
 }
 
 #if GTK_CHECK_VERSION(4,0,0)
-void GtkSalFrame::signalDragLeave(GtkDropTargetAsync* /*dest*/, GdkDrop* /*drop*/, gpointer frame)
+void GtkSalFrame::signalDragLeave(GtkDropTargetAsync* pDest, GdkDrop* /*drop*/, gpointer frame)
 {
     GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
     if (!pThis->m_pDropTarget)
         return;
-    pThis->m_pDropTarget->signalDragLeave();
+    pThis->m_pDropTarget->signalDragLeave(gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(pDest)));
 }
 #else
-void GtkSalFrame::signalDragLeave(GtkWidget*, GdkDragContext* /*context*/, guint /*time*/, gpointer frame)
+void GtkSalFrame::signalDragLeave(GtkWidget* pWidget, GdkDragContext* /*context*/, guint /*time*/, gpointer frame)
 {
     GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
     if (!pThis->m_pDropTarget)
         return;
-    pThis->m_pDropTarget->signalDragLeave();
+    pThis->m_pDropTarget->signalDragLeave(pWidget);
 }
 #endif
 
@@ -4770,11 +4772,11 @@ static gboolean lcl_deferred_dragExit(gpointer user_data)
     return false;
 }
 
-void GtkInstDropTarget::signalDragLeave()
+void GtkInstDropTarget::signalDragLeave(GtkWidget *pWidget)
 {
     m_bInDrag = false;
 
-    GtkWidget* pHighlightWidget = GTK_WIDGET(m_pFrame->getFixedContainer());
+    GtkWidget* pHighlightWidget = m_pFrame ? GTK_WIDGET(m_pFrame->getFixedContainer()) : pWidget;
 #if !GTK_CHECK_VERSION(4,0,0)
     gtk_drag_unhighlight(pHighlightWidget);
 #else
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 0a0cb24724d7..80e2fc7983a5 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -3077,10 +3077,10 @@ private:
     }
 
 #if !GTK_CHECK_VERSION(4, 0, 0)
-    static void signalDragLeave(GtkWidget*, GdkDragContext*, guint /*time*/, gpointer widget)
+    static void signalDragLeave(GtkWidget* pWidget, GdkDragContext*, guint /*time*/, gpointer widget)
     {
         GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
-        pThis->m_xDropTarget->signalDragLeave();
+        pThis->m_xDropTarget->signalDragLeave(pWidget);
         if (pThis->m_bDraggedOver)
         {
             pThis->m_bDraggedOver = false;
commit 5e865370530a71eb966d2fbfc2fdfffc34d2e1b9
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jun 29 21:27:18 2021 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Jun 30 21:45:35 2021 +0200

    ofz#35504 clamp input values in cgm filter
    
    Change-Id: I96712b8dc8f8eaad3fb8fa6710d0f07fff61b592
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118137
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/filter/source/graphicfilter/icgm/class4.cxx b/filter/source/graphicfilter/icgm/class4.cxx
index 0a498426b3bc..697a466793bc 100644
--- a/filter/source/graphicfilter/icgm/class4.cxx
+++ b/filter/source/graphicfilter/icgm/class4.cxx
@@ -109,7 +109,12 @@ bool CGM::ImplGetEllipse( FloatPoint& rCenter, FloatPoint& rRadius, double& rAng
 
 static bool useless(double value)
 {
-    return std::isnan(value) || std::isinf(value);
+    if (!std::isfinite(value))
+        return true;
+    int exp;
+    std::frexp(value, &exp);
+    const int maxbits = sizeof(tools::Long) * 8;
+    return exp > maxbits;
 }
 
 void CGM::ImplDoClass4()
diff --git a/sd/qa/unit/data/cgm/fail/ofz35504-ubsan-1.cgm b/sd/qa/unit/data/cgm/fail/ofz35504-ubsan-1.cgm
new file mode 100644
index 000000000000..07aa3db00776
Binary files /dev/null and b/sd/qa/unit/data/cgm/fail/ofz35504-ubsan-1.cgm differ
commit 8ed2142789b3db66c5ab28087040dee7c0ca6341
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Jun 15 15:24:15 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Wed Jun 30 20:56:39 2021 +0200

    fix a size warning
    
    d7855213ae60d79f converted this incorrectly, the code right above
    may set the size as (0,0), and before the commit the invalid size
    was only negative.
    
    Change-Id: I198d025f5c02780ae509f97782bc41ac77fa3407
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117376
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/svx/source/sidebar/nbdtmg.cxx b/svx/source/sidebar/nbdtmg.cxx
index 76d1004e61dc..3c744fbf97b4 100644
--- a/svx/source/sidebar/nbdtmg.cxx
+++ b/svx/source/sidebar/nbdtmg.cxx
@@ -852,7 +852,7 @@ void OutlineTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt1
                     const Graphic* pGrf = pLevelSettings->pBrushItem->GetGraphic();
                     Size aSize = pLevelSettings->aSize;
                     sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
-                    if (!isResetSize  && aFmt.GetGraphicSize()!=Size(0,0))\
+                    if (!isResetSize  && aFmt.GetGraphicSize()!=Size(0,0))
                         aSize = aFmt.GetGraphicSize();
                     else if (aSize.IsEmpty() && pGrf)
                         aSize = SvxNumberFormat::GetGraphicSizeMM100( pGrf );
diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx
index 472f406c28c6..bc065a7d64c0 100644
--- a/sw/source/filter/html/htmlflywriter.cxx
+++ b/sw/source/filter/html/htmlflywriter.cxx
@@ -685,7 +685,7 @@ OString SwHTMLWriter::OutFrameFormatOptions( const SwFrameFormat &rFrameFormat,
                       (nPercentHeight ? 0
                                   : pFSItem->GetHeight()-aTwipSpc.Height()) );
 
-        OSL_ENSURE( !aTwipSz.IsEmpty(), "Frame size minus spacing  < 0!!!???" );
+        OSL_ENSURE( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0, "Frame size minus spacing  < 0!!!???" );
         if( aTwipSz.Width() < 0 )
             aTwipSz.setWidth( 0 );
         if( aTwipSz.Height() < 0 )
@@ -964,7 +964,7 @@ void SwHTMLWriter::writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameForma
                       (nPercentHeight ? 0
                                   : pFSItem->GetHeight()-aTwipSpc.Height()) );
 
-        OSL_ENSURE( !aTwipSz.IsEmpty(), "Frame size minus spacing < 0!!!???" );
+        OSL_ENSURE( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0, "Frame size minus spacing < 0!!!???" );
         if( aTwipSz.Width() < 0 )
             aTwipSz.setWidth( 0 );
         if( aTwipSz.Height() < 0 )
commit 94678a7b9c6b7e577c15adacc885e03551bcf17b
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Jun 30 16:22:42 2021 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jun 30 20:33:39 2021 +0200

    XLSX export: improve handling of checkbox (form controls)
    
    This builds on top of commit fd238380ae7820f12ac1f7c52d0f7180a93f3ba3
    (tdf#106181 XLSX export: output form controls, 2020-05-13) and adds the
    missing VML version which seems to be mandated by Excel 2019.
    
    It is not perfect (e.g. there is still an unwanted border around the
    checkbox), but the checkbox has a correct position and its label is
    readable, while it was just lost previously.
    
    Change-Id: I08198d068a0eb85061d138719cfc60d73c46398e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118168
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sc/qa/unit/data/xlsx/checkbox-form-control.xlsx b/sc/qa/unit/data/xlsx/checkbox-form-control.xlsx
new file mode 100644
index 000000000000..ad761a573aae
Binary files /dev/null and b/sc/qa/unit/data/xlsx/checkbox-form-control.xlsx differ
diff --git a/sc/qa/unit/subsequent_export-test2.cxx b/sc/qa/unit/subsequent_export-test2.cxx
index 1c088c813f21..eb6db21167d3 100644
--- a/sc/qa/unit/subsequent_export-test2.cxx
+++ b/sc/qa/unit/subsequent_export-test2.cxx
@@ -187,6 +187,7 @@ public:
     void testTdf139258_rotated_image();
     void testTdf126541_SheetVisibilityImportXlsx();
     void testTdf140431();
+    void testCheckboxFormControlXlsxExport();
 
     CPPUNIT_TEST_SUITE(ScExportTest2);
 
@@ -282,6 +283,7 @@ public:
     CPPUNIT_TEST(testTdf139258_rotated_image);
     CPPUNIT_TEST(testTdf126541_SheetVisibilityImportXlsx);
     CPPUNIT_TEST(testTdf140431);
+    CPPUNIT_TEST(testCheckboxFormControlXlsxExport);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2301,6 +2303,24 @@ void ScExportTest2::testTdf140431()
     xDocSh->DoClose();
 }
 
+void ScExportTest2::testCheckboxFormControlXlsxExport()
+{
+    // Given a document that has a checkbox form control:
+    ScDocShellRef xShell = loadDoc(u"checkbox-form-control.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xShell.is());
+
+    // When exporting to XLSX:
+    std::shared_ptr<utl::TempFile> pXPathFile
+        = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
+
+    // Then make sure its VML markup is written and it has a correct position + size:
+    xmlDocUniquePtr pDoc
+        = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/vmlDrawing1.vml");
+    // Without the fix in place, this test would have failed as there was no such stream.
+    CPPUNIT_ASSERT(pDoc);
+    assertXPathContent(pDoc, "/xml/v:shape/xx:ClientData/xx:Anchor", "1, 22, 3, 3, 3, 30, 6, 1");
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest2);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
index 1bc1a753acad..2f1253c0a16e 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -70,6 +70,7 @@
 #include <oox/export/chartexport.hxx>
 #include <oox/export/utils.hxx>
 #include <oox/token/namespaces.hxx>
+#include <oox/export/vmlexport.hxx>
 #include <memory>
 
 using namespace com::sun::star;
@@ -651,7 +652,8 @@ XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager& rRoot, Reference<
     mbScrollHor( false ),
     mbPrint( false ),
     mbVisible( false ),
-    mnShapeId( 0 )
+    mnShapeId( 0 ),
+    mrRoot(rRoot)
 {
     namespace FormCompType = css::form::FormComponentType;
     namespace AwtVisualEffect = css::awt::VisualEffect;
@@ -1084,6 +1086,100 @@ void XclExpTbxControlObj::setShapeId(sal_Int32 aShapeId)
     mnShapeId = aShapeId;
 }
 
+namespace
+{
+/// Handles the VML export of form controls (e.g. checkboxes).
+class VmlFormControlExporter : public oox::vml::VMLExport
+{
+    sal_uInt16 m_nObjType;
+    tools::Rectangle m_aAreaFrom;
+    tools::Rectangle m_aAreaTo;
+    OUString m_aLabel;
+
+public:
+    VmlFormControlExporter(const sax_fastparser::FSHelperPtr& p, sal_uInt16 nObjType,
+                           const tools::Rectangle& rAreaFrom, const tools::Rectangle& rAreaTo,
+                           const OUString& rLabel);
+
+protected:
+    using VMLExport::StartShape;
+    sal_Int32 StartShape() override;
+    using VMLExport::EndShape;
+    void EndShape(sal_Int32 nShapeElement) override;
+};
+
+VmlFormControlExporter::VmlFormControlExporter(const sax_fastparser::FSHelperPtr& p,
+                                               sal_uInt16 nObjType,
+                                               const tools::Rectangle& rAreaFrom,
+                                               const tools::Rectangle& rAreaTo,
+                                               const OUString& rLabel)
+    : VMLExport(p)
+    , m_nObjType(nObjType)
+    , m_aAreaFrom(rAreaFrom)
+    , m_aAreaTo(rAreaTo)
+    , m_aLabel(rLabel)
+{
+}
+
+sal_Int32 VmlFormControlExporter::StartShape()
+{
+    // Host control.
+    AddShapeAttribute(XML_type, "#_x0000_t201");
+    return VMLExport::StartShape();
+}
+
+void VmlFormControlExporter::EndShape(sal_Int32 nShapeElement)
+{
+    sax_fastparser::FSHelperPtr pVmlDrawing = GetFS();
+
+    pVmlDrawing->startElement(FSNS(XML_v, XML_textbox));
+    pVmlDrawing->startElement(XML_div);
+    pVmlDrawing->write(m_aLabel);
+    pVmlDrawing->endElement(XML_div);
+    pVmlDrawing->endElement(FSNS(XML_v, XML_textbox));
+
+    OString aObjectType;
+    switch (m_nObjType)
+    {
+        case EXC_OBJTYPE_CHECKBOX:
+            aObjectType = "Checkbox";
+            break;
+    }
+    pVmlDrawing->startElement(FSNS(XML_x, XML_ClientData), XML_ObjectType, aObjectType);
+    OString aAnchor = OString::number(m_aAreaFrom.Left());
+    aAnchor += ", " + OString::number(m_aAreaFrom.Top());
+    aAnchor += ", " + OString::number(m_aAreaFrom.Right());
+    aAnchor += ", " + OString::number(m_aAreaFrom.Bottom());
+    aAnchor += ", " + OString::number(m_aAreaTo.Left());
+    aAnchor += ", " + OString::number(m_aAreaTo.Top());
+    aAnchor += ", " + OString::number(m_aAreaTo.Right());
+    aAnchor += ", " + OString::number(m_aAreaTo.Bottom());
+    XclXmlUtils::WriteElement(pVmlDrawing, FSNS(XML_x, XML_Anchor), aAnchor);
+
+    // XclExpOcxControlObj::WriteSubRecs() has the same fixed value.
+    XclXmlUtils::WriteElement(pVmlDrawing, FSNS(XML_x, XML_TextVAlign), "Center");
+
+    pVmlDrawing->endElement(FSNS(XML_x, XML_ClientData));
+    VMLExport::EndShape(nShapeElement);
+}
+
+}
+
+/// Save into xl/drawings/vmlDrawing1.vml.
+void XclExpTbxControlObj::SaveVml(XclExpXmlStream& rStrm)
+{
+    SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape);
+    tools::Rectangle aAreaFrom;
+    tools::Rectangle aAreaTo;
+    // Unlike XclExpTbxControlObj::SaveXml(), this is not calculated in EMUs.
+    lcl_GetFromTo(mrRoot, pObj->GetLogicRect(), GetTab(), aAreaFrom, aAreaTo);
+    VmlFormControlExporter aFormControlExporter(rStrm.GetCurrentStream(), GetObjType(), aAreaFrom,
+                                                aAreaTo, msLabel);
+    aFormControlExporter.AddSdrObject(*pObj, /*bIsFollowingTextFlow=*/false, /*eHOri=*/-1,
+                                      /*eVOri=*/-1, /*eHRel=*/-1, /*eVRel=*/-1,
+                                      /*pWrapAttrList=*/nullptr, /*bOOxmlExport=*/true);
+}
+
 // save into xl\drawings\drawing1.xml
 void XclExpTbxControlObj::SaveXml( XclExpXmlStream& rStrm )
 {
diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx
index b6ff9e562f15..f775571cac53 100644
--- a/sc/source/filter/inc/xeescher.hxx
+++ b/sc/source/filter/inc/xeescher.hxx
@@ -258,6 +258,8 @@ public:
 
     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
 
+    void SaveVml(XclExpXmlStream& rStrm);
+
     OUString SaveControlPropertiesXml(XclExpXmlStream& rStrm) const;
     void SaveSheetXml(XclExpXmlStream& rStrm, const OUString& aIdFormControlPr) const;
 
@@ -295,6 +297,7 @@ private:
     sal_Int32           mnShapeId;
     tools::Rectangle    maAreaFrom;
     tools::Rectangle    maAreaTo;
+    XclExpObjectManager& mrRoot;
 };
 
 //#endif
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
index 4cde52e362f1..56a4dd956f0e 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -178,7 +178,7 @@ bool IsVmlObject( const XclObj *rObj )
 sal_Int32 GetVmlObjectCount( XclExpObjList& rList )
 {
     return static_cast<sal_Int32>(std::count_if(rList.begin(), rList.end(),
-        [](const std::unique_ptr<XclObj>& rxObj) { return IsVmlObject( rxObj.get() ); }));
+        [](const std::unique_ptr<XclObj>& rxObj) { return IsVmlObject( rxObj.get() ) || IsFormControlObject( rxObj.get() ); }));
 }
 
 bool IsValidObject( const XclObj& rObj )
@@ -333,6 +333,7 @@ void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm )
     rStrm.GetCurrentStream()->singleElement(XML_legacyDrawing, FSNS(XML_r, XML_id), sId.toUtf8());
 
     rStrm.PushStream( pVmlDrawing );
+    pVmlDrawing->write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
     pVmlDrawing->startElement( XML_xml,
             FSNS(XML_xmlns, XML_v),   rStrm.getNamespaceURL(OOX_NS(vml)).toUtf8(),
             FSNS(XML_xmlns, XML_o),   rStrm.getNamespaceURL(OOX_NS(vmlOffice)).toUtf8(),
@@ -341,6 +342,15 @@ void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm )
 
     for ( const auto& rxObj : rList )
     {
+        if (IsFormControlObject(rxObj.get()))
+        {
+            auto pFormControlObject = dynamic_cast<XclExpTbxControlObj*>(rxObj.get());
+            if (pFormControlObject)
+            {
+                pFormControlObject->SaveVml(rStrm);
+            }
+        }
+
         if( !IsVmlObject( rxObj.get() ) )
             continue;
         rxObj->SaveXml( rStrm );
commit 7cbd6d768d282077053c354254315f3dc89bf254
Author:     Michael Stahl <michael.stahl at allotropia.de>
AuthorDate: Wed Jun 30 13:26:59 2021 +0200
Commit:     Michael Stahl <michael.stahl at allotropia.de>
CommitDate: Wed Jun 30 18:40:27 2021 +0200

    sfx2: try to fix lifecycle of SfxOfficeDispatch
    
    This can be created either from the global SfxApplication, or from a
    SfxViewFrame.
    
    Particularly in the latter case, the SfxDispatcher and SfxBindings
    members are owned by SfxViewFrame, so in case that is destroyed, the
    SfxOfficeDispatch must clear its pointers.
    
    It looks like the member pointers are checked before access already
    everywhere, so just listen at the SfxViewFrame.
    
    Change-Id: If08825734e94dd54e32cb77546684fd583c336ec
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118162
    Tested-by: Michael Stahl <michael.stahl at allotropia.de>
    Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>

diff --git a/framework/qa/cppunit/data/empty.fodp b/framework/qa/cppunit/data/empty.fodp
new file mode 100644
index 000000000000..3c2a4cf2cda5
--- /dev/null
+++ b/framework/qa/cppunit/data/empty.fodp
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.presentation"><office:body><office:presentation><draw:page/></office:presentation></office:body></office:document>
diff --git a/framework/qa/cppunit/dispatchtest.cxx b/framework/qa/cppunit/dispatchtest.cxx
index 586c4af3b9b0..2f21a71b005e 100644
--- a/framework/qa/cppunit/dispatchtest.cxx
+++ b/framework/qa/cppunit/dispatchtest.cxx
@@ -15,6 +15,7 @@
 #include <com/sun/star/frame/DispatchHelper.hpp>
 #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
 #include <com/sun/star/frame/XInterceptorInfo.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
 
 #include <comphelper/processfactory.hxx>
 #include <rtl/ref.hxx>
@@ -199,6 +200,37 @@ CPPUNIT_TEST_FIXTURE(DispatchTest, testInterception)
     // This was 1: MyInterceptor::queryDispatch() was called for .uno:Italic.
     CPPUNIT_ASSERT_EQUAL(0, pInterceptor->getUnexpected());
 }
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/framework/qa/cppunit/data/";
+
+CPPUNIT_TEST_FIXTURE(DispatchTest, testSfxOfficeDispatchDispose)
+{
+    // this test doesn't work with a new document because of aURL.Main check in SfxBaseController::dispatch()
+    mxComponent = loadFromDesktop(m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.fodp",
+                                  "com.sun.star.presentation.PresentationDocument");
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xModel.is());
+    uno::Reference<frame::XController> xController(xModel->getCurrentController());
+    CPPUNIT_ASSERT(xController.is());
+    uno::Reference<frame::XDispatchProvider> xFrame(xController->getFrame(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xFrame.is());
+
+    uno::Reference<util::XURLTransformer> xParser(util::URLTransformer::create(mxComponentContext));
+    util::URL url;
+    url.Complete = xModel->getURL() + "#dummy";
+    xParser->parseStrict(url);
+
+    uno::Reference<frame::XDispatch> xDisp(xFrame->queryDispatch(url, "", 0));
+    CPPUNIT_ASSERT(xDisp.is());
+
+    mxComponent->dispose();
+
+    util::URL urlSlot;
+    urlSlot.Complete = "slot:5598";
+    xParser->parseStrict(urlSlot);
+    // crashed with UAF
+    xDisp->dispatch(urlSlot, {});
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sfx2/inc/unoctitm.hxx b/sfx2/inc/unoctitm.hxx
index 805ff22b3124..9e6bc19da488 100644
--- a/sfx2/inc/unoctitm.hxx
+++ b/sfx2/inc/unoctitm.hxx
@@ -25,6 +25,7 @@
 #include <cppuhelper/interfacecontainer.hxx>
 #include <cppuhelper/weakref.hxx>
 
+#include <svl/lstner.hxx>
 #include <sfx2/ctrlitem.hxx>
 #include <osl/mutex.hxx>
 
@@ -101,7 +102,9 @@ public:
     SfxDispatcher*          GetDispatcher_Impl();
 };
 
-class SfxDispatchController_Impl final : public SfxControllerItem
+class SfxDispatchController_Impl final
+    : public SfxControllerItem
+    , public SfxListener
 {
     css::util::URL              aDispatchURL;
     SfxDispatcher*              pDispatcher;
@@ -126,6 +129,8 @@ public:
                                                     const css::util::URL& rURL );
                         virtual ~SfxDispatchController_Impl() override;
 
+    virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
+
     static OUString getSlaveCommand( const css::util::URL& rURL );
 
     void                StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState, SfxSlotServer const * pServ );
diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
index 50034333bcd5..58bdc6179008 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -323,6 +323,27 @@ SfxDispatchController_Impl::SfxDispatchController_Impl(
         BindInternal_Impl( nSlot, pBindings );
         pBindings->LEAVEREGISTRATIONS();
     }
+    assert(pDispatcher);
+    assert(SfxApplication::Get()->GetAppDispatcher_Impl() == pDispatcher
+        || pDispatcher->GetFrame() != nullptr);
+    if (pDispatcher->GetFrame())
+    {
+        StartListening(*pDispatcher->GetFrame());
+    }
+    else
+    {
+        StartListening(*SfxApplication::Get());
+    }
+}
+
+void SfxDispatchController_Impl::Notify(SfxBroadcaster& rBC, SfxHint const& rHint)
+{
+    if (rHint.GetId() == SfxHintId::Dying)
+    {   // both pBindings and pDispatcher are dead if SfxViewFrame is dead
+        pBindings = nullptr;
+        pDispatcher = nullptr;
+        EndListening(rBC);
+    }
 }
 
 SfxDispatchController_Impl::~SfxDispatchController_Impl()
commit 738f7a8cb971a884f74766da0cbf7e59ef8b90e7
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Wed Jun 30 15:10:44 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Wed Jun 30 18:03:06 2021 +0200

    reduce cost of allocating and copying SvxNumRule
    
    by using std::move to avoid copying unnecessarily
    
    Change-Id: I940b57c9a05c8d75b9a16291fc4f05756fdeea12
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118164
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/editeng/source/items/numitem.cxx b/editeng/source/items/numitem.cxx
index 54bec9d892ea..41ee6e4cf952 100644
--- a/editeng/source/items/numitem.cxx
+++ b/editeng/source/items/numitem.cxx
@@ -1013,12 +1013,24 @@ SvxNumBulletItem::SvxNumBulletItem(SvxNumRule const & rRule) :
 {
 }
 
+SvxNumBulletItem::SvxNumBulletItem(SvxNumRule && rRule) :
+    SfxPoolItem(SID_ATTR_NUMBERING_RULE),
+    maNumRule(std::move(rRule))
+{
+}
+
 SvxNumBulletItem::SvxNumBulletItem(SvxNumRule const & rRule, sal_uInt16 _nWhich ) :
     SfxPoolItem(_nWhich),
     maNumRule(rRule)
 {
 }
 
+SvxNumBulletItem::SvxNumBulletItem(SvxNumRule && rRule, sal_uInt16 _nWhich ) :
+    SfxPoolItem(_nWhich),
+    maNumRule(std::move(rRule))
+{
+}
+
 SvxNumBulletItem::SvxNumBulletItem(const SvxNumBulletItem& rCopy) :
     SfxPoolItem(rCopy),
     maNumRule(rCopy.maNumRule)
diff --git a/editeng/source/outliner/outlvw.cxx b/editeng/source/outliner/outlvw.cxx
index aabe51c9efd8..6cd2f6d7515e 100644
--- a/editeng/source/outliner/outlvw.cxx
+++ b/editeng/source/outliner/outlvw.cxx
@@ -878,7 +878,7 @@ void OutlinerView::ToggleBullets()
                     {
                         SfxItemSet aAttrs( pOwner->GetParaAttribs( nPara ) );
                         SvxNumRule aNewNumRule( *pDefaultBulletNumRule );
-                        aAttrs.Put( SvxNumBulletItem( aNewNumRule, EE_PARA_NUMBULLET ) );
+                        aAttrs.Put( SvxNumBulletItem( std::move(aNewNumRule), EE_PARA_NUMBULLET ) );
                         pOwner->SetParaAttribs( nPara, aAttrs );
                     }
                 }
@@ -1050,7 +1050,7 @@ void OutlinerView::ApplyBulletsNumbering(
                         }
                     }
 
-                    aAttrs.Put(SvxNumBulletItem(aNewRule, EE_PARA_NUMBULLET));
+                    aAttrs.Put(SvxNumBulletItem(std::move(aNewRule), EE_PARA_NUMBULLET));
                 }
             }
             pOwner->SetParaAttribs(nPara, aAttrs);
diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx
index 1b5a30110a94..f7ef3675a03d 100644
--- a/filter/source/msfilter/svdfppt.cxx
+++ b/filter/source/msfilter/svdfppt.cxx
@@ -4411,7 +4411,7 @@ PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, Sd
                     aRule.SetLevel( nDepth, aNumberFormat );
             }
         }
-        mpNumBulletItem[ i ] = std::make_unique<SvxNumBulletItem>( aRule, EE_PARA_NUMBULLET );
+        mpNumBulletItem[ i ] = std::make_unique<SvxNumBulletItem>( std::move(aRule), EE_PARA_NUMBULLET );
     }
 }
 
diff --git a/include/editeng/numitem.hxx b/include/editeng/numitem.hxx
index 2e2e660267e8..bbcbecdf4c79 100644
--- a/include/editeng/numitem.hxx
+++ b/include/editeng/numitem.hxx
@@ -308,7 +308,9 @@ class EDITENG_DLLPUBLIC SvxNumBulletItem final : public SfxPoolItem
     SvxNumRule maNumRule;
 public:
     explicit SvxNumBulletItem(SvxNumRule const & rRule);
+    explicit SvxNumBulletItem(SvxNumRule && rRule);
     SvxNumBulletItem(SvxNumRule const & rRule, sal_uInt16 nWhich );
+    SvxNumBulletItem(SvxNumRule && rRule, sal_uInt16 nWhich );
     SvxNumBulletItem(const SvxNumBulletItem& rCopy);
     virtual ~SvxNumBulletItem() override;
 
diff --git a/sd/source/core/drawdoc4.cxx b/sd/source/core/drawdoc4.cxx
index e3d7080f953b..e078afc58b54 100644
--- a/sd/source/core/drawdoc4.cxx
+++ b/sd/source/core/drawdoc4.cxx
@@ -1268,7 +1268,7 @@ void SdDrawDocument::SetTextDefaults() const
         aNumRule.SetLevel( i, aNumberFormat );
     }
 
-    SvxNumBulletItem aNumBulletItem( aNumRule, EE_PARA_NUMBULLET );
+    SvxNumBulletItem aNumBulletItem( std::move(aNumRule), EE_PARA_NUMBULLET );
     m_pItemPool->SetPoolDefaultItem( aNumBulletItem );
 }
 
diff --git a/sd/source/core/stlpool.cxx b/sd/source/core/stlpool.cxx
index d6256bd6f9ae..d15aaf632b04 100644
--- a/sd/source/core/stlpool.cxx
+++ b/sd/source/core/stlpool.cxx
@@ -1095,7 +1095,7 @@ void SdStyleSheetPool::PutNumBulletItem( SfxStyleSheetBase* pSheet,
                 aNumRule.SetLevel( i, aNumberFormat );
             }
 
-            rSet.Put( SvxNumBulletItem( aNumRule, EE_PARA_NUMBULLET ) );
+            rSet.Put( SvxNumBulletItem( std::move(aNumRule), EE_PARA_NUMBULLET ) );
             static_cast<SfxStyleSheet*>(pSheet)->Broadcast(SfxHint( SfxHintId::DataChanged ) );
         }
         break;
@@ -1127,7 +1127,7 @@ void SdStyleSheetPool::PutNumBulletItem( SfxStyleSheetBase* pSheet,
                     aNumRule.SetLevel(i, aFrmt);
                 }
 
-                rSet.Put( SvxNumBulletItem( aNumRule, EE_PARA_NUMBULLET ) );
+                rSet.Put( SvxNumBulletItem( std::move(aNumRule), EE_PARA_NUMBULLET ) );
                 static_cast<SfxStyleSheet*>(pSheet)->Broadcast(SfxHint( SfxHintId::DataChanged ) );
             }
         }
@@ -1151,7 +1151,7 @@ void SdStyleSheetPool::PutNumBulletItem( SfxStyleSheetBase* pSheet,
                 aNumRule.SetLevel( i, aNumberFormat );
             }
 
-            rSet.Put( SvxNumBulletItem( aNumRule, EE_PARA_NUMBULLET ) );
+            rSet.Put( SvxNumBulletItem( std::move(aNumRule), EE_PARA_NUMBULLET ) );
             static_cast<SfxStyleSheet*>(pSheet)->Broadcast(SfxHint( SfxHintId::DataChanged ) );
         }
         break;
diff --git a/sd/source/ui/dlg/dlgolbul.cxx b/sd/source/ui/dlg/dlgolbul.cxx
index e82768d7dfa4..c30b31ad3ba7 100644
--- a/sd/source/ui/dlg/dlgolbul.cxx
+++ b/sd/source/ui/dlg/dlgolbul.cxx
@@ -108,7 +108,7 @@ OutlineBulletDlg::OutlineBulletDlg(weld::Window* pParent, const SfxItemSet* pAtt
         SvxNumRule aNewRule( rRule );
         aNewRule.SetFeatureFlag( SvxNumRuleFlags::NO_NUMBERS );
 
-        SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET );
+        SvxNumBulletItem aNewItem( std::move(aNewRule), EE_PARA_NUMBULLET );
         m_aInputSet.Put(aNewItem);
     }
 
diff --git a/sd/source/ui/func/fuolbull.cxx b/sd/source/ui/func/fuolbull.cxx
index 13db35c73079..5d1cf1dec398 100644
--- a/sd/source/ui/func/fuolbull.cxx
+++ b/sd/source/ui/func/fuolbull.cxx
@@ -327,7 +327,7 @@ const SfxPoolItem* FuBulletAndPosition::GetNumBulletItem(SfxItemSet& aNewAttr, s
                 SvxNumRule aNewRule( rLclRule );
                 aNewRule.SetFeatureFlag( SvxNumRuleFlags::NO_NUMBERS );
 
-                SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET );
+                SvxNumBulletItem aNewItem( std::move(aNewRule), EE_PARA_NUMBULLET );
                 aNewAttr.Put(aNewItem);
             }
 
diff --git a/sd/source/ui/view/drtxtob1.cxx b/sd/source/ui/view/drtxtob1.cxx
index 09f37d6a2872..8c636345fc5b 100644
--- a/sd/source/ui/view/drtxtob1.cxx
+++ b/sd/source/ui/view/drtxtob1.cxx
@@ -488,7 +488,7 @@ void TextObjectBar::Execute( SfxRequest &rReq )
                                 aNewRule.SetLevel(nLevel, aFmt);
                             }
 
-                            pFirstStyleSheet->GetItemSet().Put(SvxNumBulletItem(aNewRule, EE_PARA_NUMBULLET));
+                            pFirstStyleSheet->GetItemSet().Put(SvxNumBulletItem(std::move(aNewRule), EE_PARA_NUMBULLET));
 
                             SdStyleSheet::BroadcastSdStyleSheetChange(pFirstStyleSheet, PresentationObjects::Outline_1, pSSPool);
                         }
diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx
index 5a68e30abab9..dae22d8dfde8 100644
--- a/sd/source/ui/view/drviews2.cxx
+++ b/sd/source/ui/view/drviews2.cxx
@@ -446,7 +446,7 @@ private:
                         aItemSet.Put(SvxWeightItem(WEIGHT_NORMAL, EE_CHAR_WEIGHT));
 
                     SvxNumRule aDefaultNumRule(SvxNumRuleFlags::NONE, 0, false);
-                    aItemSet.Put(SvxNumBulletItem(aDefaultNumRule, EE_PARA_NUMBULLET));
+                    aItemSet.Put(SvxNumBulletItem(std::move(aDefaultNumRule), EE_PARA_NUMBULLET));
 
                     pOutliner->SetParaAttribs(nParagraph, aItemSet);
                 }
diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx
index 7f481d9677bc..ac7a5d3489ac 100644
--- a/sd/source/ui/view/viewshel.cxx
+++ b/sd/source/ui/view/viewshel.cxx
@@ -857,7 +857,7 @@ const SfxPoolItem* ViewShell::GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt16&
                 SvxNumRule aNewRule( rRule );
                 aNewRule.SetFeatureFlag( SvxNumRuleFlags::NO_NUMBERS );
 
-                SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET );
+                SvxNumBulletItem aNewItem( std::move(aNewRule), EE_PARA_NUMBULLET );
                 aNewAttr.Put(aNewItem);
             }
 
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index 2a0427e0f30f..b10570b348a2 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -1357,7 +1357,7 @@ SfxItemSet&   SwDocStyleSheet::GetItemSet()
             {
                 OSL_ENSURE(m_pNumRule, "No NumRule");
                 SvxNumRule aRule = m_pNumRule->MakeSvxNumRule();
-                m_aCoreSet.Put(SvxNumBulletItem(aRule));
+                m_aCoreSet.Put(SvxNumBulletItem(std::move(aRule)));
             }
             break;
 
diff --git a/sw/source/uibase/shells/txtnum.cxx b/sw/source/uibase/shells/txtnum.cxx
index e1890bbd6f34..6f2885397325 100644
--- a/sw/source/uibase/shells/txtnum.cxx
+++ b/sw/source/uibase/shells/txtnum.cxx
@@ -183,7 +183,7 @@ void SwTextShell::ExecEnterNum(SfxRequest &rReq)
                 }
                 aSvxRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false);
             }
-            aSet.Put( SvxNumBulletItem( aSvxRule ) );
+            aSet.Put( SvxNumBulletItem( std::move(aSvxRule) ) );
         }
 
         aSet.Put( SfxBoolItem( SID_PARAM_NUM_PRESET,false ));
commit cf15c4dad74e31a035c0d1ca899dfbef4da90ad2
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Wed Jun 23 08:51:05 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Wed Jun 30 17:53:36 2021 +0200

    tdf#135316 optimise SwCharFormats::FindFormatByName
    
    reduces load time by 10%
    
    Change-Id: Ic5c90588825592245d09f8ebe03b13e34676496a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117699
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sw/inc/charformats.hxx b/sw/inc/charformats.hxx
new file mode 100644
index 000000000000..f72958298ea8
--- /dev/null
+++ b/sw/inc/charformats.hxx
@@ -0,0 +1,114 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include "docary.hxx"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/composite_key.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/mem_fun.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+
+// Like o3tl::find_partialorder_ptrequals
+// We don't allow duplicated object entries!
+struct char_formats_name_key
+    : boost::multi_index::composite_key<
+          SwCharFormat*,
+          boost::multi_index::const_mem_fun<SwFormat, const OUString&, &SwFormat::GetName>,
+          boost::multi_index::identity<SwCharFormat*> // the actual object pointer
+          >
+{
+};
+
+typedef boost::multi_index_container<
+    SwCharFormat*,
+    boost::multi_index::indexed_by<boost::multi_index::random_access<>,
+                                   boost::multi_index::ordered_unique<char_formats_name_key>>>
+    SwCharFormatsBase;
+
+class SW_DLLPUBLIC SwCharFormats final : public SwFormatsBase
+{
+    // function updating ByName index via modify
+    friend void SwFormat::SetName(const OUString&, bool);
+
+public:
+    typedef SwCharFormatsBase::nth_index<0>::type ByPos;
+    typedef SwCharFormatsBase::nth_index<1>::type ByName;
+    typedef ByPos::iterator iterator;
+
+private:
+    SwCharFormatsBase m_Array;
+    ByPos& m_PosIndex;
+    ByName& m_NameIndex;
+
+public:
+    typedef ByPos::const_iterator const_iterator;
+    typedef SwCharFormatsBase::size_type size_type;
+    typedef SwCharFormatsBase::value_type value_type;
+
+    SwCharFormats();
+    // frees all SwCharFormat!
+    virtual ~SwCharFormats() override;
+
+    bool empty() const { return m_Array.empty(); }
+    size_t size() const { return m_Array.size(); }
+
+    // Only fails, if you try to insert the same object twice
+    void insert(SwCharFormat* x);
+
+    // This will try to remove the exact object!
+    void erase(const_iterator const& position);
+
+    // Get the iterator of the exact object (includes pointer!),
+    // e.g for position with std::distance.
+    // There is also ContainsFormat, if you don't need the position.
+    const_iterator find(const SwCharFormat* x) const;
+    size_t GetPos(const SwCharFormat* p) const;
+
+    // search for formats by name
+    ByName::const_iterator findByName(const OUString& name) const;
+    // So we can actually check for end()
+    ByName::const_iterator byNameEnd() const { return m_NameIndex.end(); }
+
+    SwCharFormat* operator[](size_t index_) const { return m_PosIndex.operator[](index_); }
+    const_iterator begin() const { return m_PosIndex.begin(); }
+    const_iterator end() const { return m_PosIndex.end(); }
+
+    void dumpAsXml(xmlTextWriterPtr pWriter) const;
+
+    virtual size_t GetFormatCount() const override { return m_Array.size(); }
+    virtual SwCharFormat* GetFormat(size_t idx) const override { return operator[](idx); }
+
+    /// fast check if given format is contained here
+    /// @precond pFormat must not have been deleted
+    bool ContainsFormat(SwCharFormat* pFormat) const;
+    /// not so fast check that given format is still alive (i.e. contained here)
+    bool IsAlive(SwCharFormat const*) const;
+
+    void DeleteAndDestroyAll(bool keepDefault = false);
+
+    // Override return type to reduce casting
+    virtual SwCharFormat* FindFormatByName(const OUString& rName) const override;
+
+    /** Need to call this when the format name changes */
+    void SetFormatNameAndReindex(SwCharFormat* v, const OUString& sNewName);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index f72c2b89cb0d..d5c3a210af42 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -37,6 +37,7 @@
 #include "frmfmt.hxx"
 #include "charfmt.hxx"
 #include "docary.hxx"
+#include "charformats.hxx"
 #include "pagedesc.hxx"
 #include "tblenum.hxx"
 #include "ndarr.hxx"
diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index 49d1a7c368a7..43939b1d84d1 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -187,12 +187,6 @@ public:
     SwFrameFormatsV() : SwFormatsModifyBase( DestructorPolicy::KeepElements ) {}
 };
 
-class SwCharFormats final : public SwFormatsModifyBase<SwCharFormat*>
-{
-public:
-    void dumpAsXml(xmlTextWriterPtr pWriter) const;
-};
-
 class SwTextFormatColls final : public SwFormatsModifyBase<SwTextFormatColl*>
 {
 public:
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index f6ccbb799b92..7f07cf62e99c 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -845,7 +845,7 @@ SwCharFormat *SwDoc::MakeCharFormat( const OUString &rFormatName,
                                bool bBroadcast )
 {
     SwCharFormat *pFormat = new SwCharFormat( GetAttrPool(), rFormatName, pDerivedFrom );
-    mpCharFormatTable->push_back( pFormat );
+    mpCharFormatTable->insert( pFormat );
     pFormat->SetAuto(false);
     getIDocumentState().SetModified();
 
@@ -1926,7 +1926,11 @@ void SwDoc::RenameFormat(SwFormat & rFormat, const OUString & sNewName,
         }
     }
 
-    rFormat.SetName(sNewName);
+    // name change means the o3tl::sorted_array is not property sorted
+    if (rFormat.Which() == RES_CHRFMT)
+        mpCharFormatTable->SetFormatNameAndReindex(static_cast<SwCharFormat*>(&rFormat), sNewName);
+    else
+        rFormat.SetName(sNewName);
 
     if (bBroadcast)
         BroadcastStyleOperation(sNewName, eFamily, SfxHintId::StyleSheetModified);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index ae2f24a92a8a..b1ed62e0bccc 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -113,6 +113,8 @@
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::document;
 
+constexpr OUStringLiteral DEFAULT_CHAR_FORMAT_NAME = u"Character style";
+
 /*
  * global functions...
  */
@@ -223,7 +225,7 @@ SwDoc::SwDoc()
     mpDfltFrameFormat( new SwFrameFormat( GetAttrPool(), "Frameformat", nullptr ) ),
     mpEmptyPageFormat( new SwFrameFormat( GetAttrPool(), "Empty Page", mpDfltFrameFormat.get() ) ),
     mpColumnContFormat( new SwFrameFormat( GetAttrPool(), "Columncontainer", mpDfltFrameFormat.get() ) ),
-    mpDfltCharFormat( new SwCharFormat( GetAttrPool(), "Character style", nullptr ) ),
+    mpDfltCharFormat( new SwCharFormat( GetAttrPool(), DEFAULT_CHAR_FORMAT_NAME, nullptr ) ),
     mpDfltTextFormatColl( new SwTextFormatColl( GetAttrPool(), "Paragraph style" ) ),
     mpDfltGrfFormatColl( new SwGrfFormatColl( GetAttrPool(), "Graphikformatvorlage" ) ),
     mpFrameFormatTable( new SwFrameFormats() ),
@@ -296,7 +298,7 @@ SwDoc::SwDoc()
      */
     /* Formats */
     mpFrameFormatTable->push_back(mpDfltFrameFormat.get());
-    mpCharFormatTable->push_back(mpDfltCharFormat.get());
+    mpCharFormatTable->insert(mpDfltCharFormat.get());
 
     /* FormatColls */
     // TXT
@@ -531,7 +533,6 @@ SwDoc::~SwDoc()
      * now.
      */
     mpFrameFormatTable->erase( mpFrameFormatTable->begin() );
-    mpCharFormatTable->erase( mpCharFormatTable->begin() );
 
 #if HAVE_FEATURE_DBCONNECTIVITY
     // On load, SwDBManager::setEmbeddedName() may register a data source.
@@ -728,7 +729,7 @@ void SwDoc::ClearDoc()
         mpTextFormatCollTable->DeleteAndDestroy(2, mpTextFormatCollTable->size());
     mpTextFormatCollTable->DeleteAndDestroy(1, mpTextFormatCollTable->size());
     mpGrfFormatCollTable->DeleteAndDestroy(1, mpGrfFormatCollTable->size());
-    mpCharFormatTable->DeleteAndDestroy(1, mpCharFormatTable->size());
+    mpCharFormatTable->DeleteAndDestroyAll(/*keepDefault*/true);
 
     if( getIDocumentLayoutAccess().GetCurrentViewShell() )
     {
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index 9bd2f27283b9..045d58f63fde 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -872,7 +872,7 @@ SwNumRule& SwNumRule::CopyNumRule( SwDoc& rDoc, const SwNumRule& rNumRule )
     {
         Set( n, rNumRule.maFormats[ n ].get() );
         if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() &&
-            !rDoc.GetCharFormats()->IsAlive(maFormats[n]->GetCharFormat()))
+            !rDoc.GetCharFormats()->ContainsFormat(maFormats[n]->GetCharFormat()))
         {
             // If we copy across different Documents, then copy the
             // corresponding CharFormat into the new Document.
diff --git a/sw/source/core/txtnode/chrfmt.cxx b/sw/source/core/txtnode/chrfmt.cxx
index 04301067ec23..3ee46ee3e8e8 100644
--- a/sw/source/core/txtnode/chrfmt.cxx
+++ b/sw/source/core/txtnode/chrfmt.cxx
@@ -20,7 +20,7 @@
 #include <libxml/xmlwriter.h>
 
 #include <charfmt.hxx>
-#include <docary.hxx>
+#include <charformats.hxx>
 
 void SwCharFormat::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
@@ -39,4 +39,79 @@ void SwCharFormats::dumpAsXml(xmlTextWriterPtr pWriter) const
     (void)xmlTextWriterEndElement(pWriter);
 }
 
+SwCharFormats::SwCharFormats()
+    : m_PosIndex(m_Array.get<0>())
+    , m_NameIndex(m_Array.get<1>())
+{
+}
+
+SwCharFormats::~SwCharFormats()
+{
+    // default char format is owned by SwDoc
+    DeleteAndDestroyAll(true);
+}
+
+SwCharFormats::const_iterator SwCharFormats::find(const SwCharFormat* x) const
+{
+    ByName::iterator it
+        = m_NameIndex.find(boost::make_tuple(x->GetName(), const_cast<SwCharFormat*>(x)));
+    return m_Array.project<0>(it);
+}
+
+SwCharFormats::ByName::const_iterator SwCharFormats::findByName(const OUString& name) const
+{
+    return m_NameIndex.find(boost::make_tuple(name));
+}
+
+SwCharFormat* SwCharFormats::FindFormatByName(const OUString& rName) const
+{
+    auto it = findByName(rName);
+    if (it != m_NameIndex.end())
+        return *it;
+    return nullptr;
+}
+
+void SwCharFormats::DeleteAndDestroyAll(bool keepDefault)
+{
+    if (empty())
+        return;
+    const int _offset = keepDefault ? 1 : 0;
+    for (const_iterator it = begin() + _offset; it != end(); ++it)
+    {
+        assert(!(*it)->HasName(u"Character style"));
+        delete *it;
+    }
+    if (_offset)
+        m_PosIndex.erase(begin() + _offset, end());
+    else
+        m_Array.clear();
+}
+
+void SwCharFormats::insert(SwCharFormat* x)
+{
+    assert(!ContainsFormat(x));
+    m_PosIndex.push_back(x);
+}
+
+void SwCharFormats::erase(const_iterator const& position) { m_PosIndex.erase(position); }
+
+bool SwCharFormats::ContainsFormat(SwCharFormat* x) const { return find(x) != end(); }
+
+bool SwCharFormats::IsAlive(SwCharFormat const* const p) const { return find(p) != end(); }
+
+/** Need to call this when the format name changes */
+void SwCharFormats::SetFormatNameAndReindex(SwCharFormat* v, const OUString& sNewName)
+{
+    auto it = find(v);
+    erase(it);
+    v->SetName(sNewName);
+    insert(v);
+}
+
+size_t SwCharFormats::GetPos(const SwCharFormat* p) const
+{
+    auto it = find(p);
+    return it == end() ? SIZE_MAX : it - begin();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
index 402f1486654b..cf308182c60b 100644
--- a/sw/source/core/undo/rolbck.cxx
+++ b/sw/source/core/undo/rolbck.cxx
@@ -254,7 +254,7 @@ void SwHistorySetText::SetInDoc( SwDoc* pDoc, bool )
     if ( RES_TXTATR_CHARFMT == m_pAttr->Which() )
     {
         // ask the Doc if the CharFormat still exists
-        if (!pDoc->GetCharFormats()->IsAlive(static_cast<SwFormatCharFormat&>(*m_pAttr).GetCharFormat()))
+        if (!pDoc->GetCharFormats()->ContainsFormat(static_cast<SwFormatCharFormat&>(*m_pAttr).GetCharFormat()))
             return; // do not set, format does not exist
     }
 
diff --git a/sw/source/core/unocore/unosett.cxx b/sw/source/core/unocore/unosett.cxx
index 186b0e98116e..101a70f10ada 100644
--- a/sw/source/core/unocore/unosett.cxx
+++ b/sw/source/core/unocore/unosett.cxx
@@ -1589,21 +1589,10 @@ void SwXNumberingRules::SetPropertiesToNumFormat(
             }
             else if (pLocalDoc)
             {
-                const SwCharFormats* pFormats = pLocalDoc->GetCharFormats();
-                const size_t nChCount = pFormats->size();
-
                 SwCharFormat* pCharFormat = nullptr;
                 if (!sCharFormatName.isEmpty())
                 {
-                    for(size_t j = 0; j< nChCount; ++j)
-                    {
-                        SwCharFormat* pTmp = (*pFormats)[j];
-                        if(pTmp->GetName() == sCharFormatName)
-                        {
-                            pCharFormat = pTmp;
-                            break;
-                        }
-                    }
+                    pCharFormat = pLocalDoc->FindCharFormatByName(sCharFormatName);
                     if(!pCharFormat)
                     {
 
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
index a6a14abef2dc..86d9381b8573 100644
--- a/sw/source/core/unocore/unostyle.cxx
+++ b/sw/source/core/unocore/unostyle.cxx

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list