Rebased ref, commits from common ancestor: commit 6546856703cf1cec4493e8c357fa89fa7f53f8ca Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Fri Apr 2 00:21:34 2021 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@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.vajng...@collabora.co.uk> AuthorDate: Wed Sep 23 13:38:38 2015 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@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.vajng...@collabora.co.uk> AuthorDate: Wed Sep 23 13:37:43 2015 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@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.vajng...@collabora.co.uk> AuthorDate: Wed Sep 23 13:35:56 2015 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@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.vajng...@collabora.co.uk> AuthorDate: Sun Sep 20 19:27:09 2015 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@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.vajng...@collabora.co.uk> AuthorDate: Sun Sep 20 19:20:59 2015 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@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.vajng...@collabora.co.uk> AuthorDate: Thu Sep 24 12:32:14 2015 +0200 Commit: Tomaž Vajngerl <qui...@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 <qui...@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.mo...@protonmail.com> AuthorDate: Tue Jun 29 20:31:30 2021 +0200 Commit: Mike Kaganski <mike.kagan...@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.kagan...@collabora.com> Reviewed-by: Mike Kaganski <mike.kagan...@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 <glo...@fbihome.de> AuthorDate: Tue Jun 29 16:13:42 2021 +0000 Commit: Jan-Marek Glogowski <glo...@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 <glo...@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 <caol...@redhat.com> AuthorDate: Wed Jun 30 15:58:57 2021 +0100 Commit: Caolán McNamara <caol...@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 <caol...@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 <caol...@redhat.com> AuthorDate: Wed Jun 30 14:28:21 2021 +0100 Commit: Caolán McNamara <caol...@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 <caol...@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 <caol...@redhat.com> AuthorDate: Tue Jun 29 21:27:18 2021 +0100 Commit: Caolán McNamara <caol...@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 <caol...@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.lu...@collabora.com> AuthorDate: Tue Jun 15 15:24:15 2021 +0200 Commit: Noel Grandin <noel.gran...@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.gran...@collabora.co.uk> Reviewed-by: Luboš Luňák <l.lu...@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 <vmik...@collabora.com> AuthorDate: Wed Jun 30 16:22:42 2021 +0200 Commit: Miklos Vajna <vmik...@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 <vmik...@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.st...@allotropia.de> AuthorDate: Wed Jun 30 13:26:59 2021 +0200 Commit: Michael Stahl <michael.st...@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.st...@allotropia.de> Reviewed-by: Michael Stahl <michael.st...@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.gran...@collabora.co.uk> AuthorDate: Wed Jun 30 15:10:44 2021 +0200 Commit: Noel Grandin <noel.gran...@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.gran...@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.gran...@collabora.co.uk> AuthorDate: Wed Jun 23 08:51:05 2021 +0200 Commit: Noel Grandin <noel.gran...@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.gran...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits