diff --git a/docmodel/Library_docmodel.mk b/docmodel/Library_docmodel.mk index 8db7d0fa6f93..8a07e6532dad 100644 --- a/docmodel/Library_docmodel.mk +++ b/docmodel/Library_docmodel.mk @@ -14,6 +14,7 @@ $(eval $(call gb_Library_add_exception_objects,docmodel,\ docmodel/source/uno/UnoTheme \ docmodel/source/theme/ColorSet \ docmodel/source/theme/Theme \ + docmodel/source/theme/ThemeColorJSON \ )) $(eval $(call gb_Library_set_include,docmodel,\ @@ -22,7 +23,8 @@ $(eval $(call gb_Library_set_include,docmodel,\ )) $(eval $(call gb_Library_use_externals,docmodel,\ - libxml2 \ + libxml2 \ + boost_headers \ )) $(eval $(call gb_Library_add_defs,docmodel,\ diff --git a/docmodel/source/theme/ThemeColorJSON.cxx b/docmodel/source/theme/ThemeColorJSON.cxx new file mode 100644 index 000000000000..6b2293ca1f64 --- /dev/null +++ b/docmodel/source/theme/ThemeColorJSON.cxx @@ -0,0 +1,103 @@ +/* -*- 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/. + * + */ + +#include +#include +#include +#include +#include + +namespace model::theme +{ +bool convertFromJSON(OString const& rJsonString, model::ThemeColor& rThemeColor) +{ + model::ThemeColor aThemeColor; + std::stringstream aStream(rJsonString.getStr()); + boost::property_tree::ptree aRootTree; + try + { + boost::property_tree::read_json(aStream, aRootTree); + } + catch (const boost::property_tree::json_parser_error& /*exception*/) + { + return false; + } + + sal_Int32 nThemeType = aRootTree.get("ThemeIndex", -1); + aThemeColor.setType(model::convertToThemeColorType(nThemeType)); + boost::property_tree::ptree aTransformTree = aRootTree.get_child("Transformations"); + for (const auto& rEachTransformationNode : + boost::make_iterator_range(aTransformTree.equal_range(""))) + { + auto const& rTransformationTree = rEachTransformationNode.second; + std::string sType = rTransformationTree.get("Type", ""); + sal_Int16 nValue = rTransformationTree.get("Value", 0); + + auto eType = model::TransformationType::Undefined; + if (sType == "LumOff") + eType = model::TransformationType::LumOff; + else if (sType == "LumMod") + eType = model::TransformationType::LumMod; + else if (sType == "Tint") + eType = model::TransformationType::Tint; + else if (sType == "Shade") + eType = model::TransformationType::Shade; + + if (eType != model::TransformationType::Undefined) + aThemeColor.addTransformation({ eType, nValue }); + } + rThemeColor = aThemeColor; + return true; +} + +OString convertToJSON(model::ThemeColor const& rThemeColor) +{ + boost::property_tree::ptree aTree; + aTree.put("ThemeIndex", sal_Int16(rThemeColor.getType())); + + boost::property_tree::ptree aTransformationsList; + for (auto const& rTransformation : rThemeColor.getTransformations()) + { + std::string aType; + switch (rTransformation.meType) + { + case model::TransformationType::LumMod: + aType = "LumMod"; + break; + case model::TransformationType::LumOff: + aType = "LumOff"; + break; + case model::TransformationType::Tint: + aType = "Tint"; + break; + case model::TransformationType::Shade: + aType = "Shade"; + break; + default: + break; + } + if (!aType.empty()) + { + boost::property_tree::ptree aChild; + aChild.put("Type", aType); + aChild.put("Value", rTransformation.mnValue); + aTransformationsList.push_back(std::make_pair("", aChild)); + } + } + aTree.add_child("Transformations", aTransformationsList); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + + return OString(aStream.str().c_str()); +} + +} // end model::theme + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx index 5a53d6a8e14c..ece9a4a35237 100644 --- a/editeng/source/items/textitem.cxx +++ b/editeng/source/items/textitem.cxx @@ -78,6 +78,7 @@ #include #include #include +#include #include using namespace ::com::sun::star; @@ -1367,6 +1368,13 @@ SvxColorItem::SvxColorItem( const Color& rCol, const sal_uInt16 nId ) : { } +SvxColorItem::SvxColorItem(Color const& rColor, model::ThemeColor const& rThemeColor, const sal_uInt16 nId) + : SfxPoolItem(nId) + , mColor(rColor) + , maThemeColor(rThemeColor) +{ +} + SvxColorItem::~SvxColorItem() { } @@ -1436,12 +1444,18 @@ bool SvxColorItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const rVal <<= nValue; break; } - case MID_COLOR_THEME_REFERENCE: + case MID_COLOR_THEME_REFERENCE: { auto xThemeColor = model::theme::createXThemeColor(maThemeColor); rVal <<= xThemeColor; break; } + case MID_COLOR_THEME_REFERENCE_JSON: + { + rVal <<= OStringToOUString(model::theme::convertToJSON(maThemeColor), RTL_TEXTENCODING_UTF8); + break; + } + case MID_COLOR_RGB: default: { rVal <<= mColor; @@ -1528,6 +1542,23 @@ bool SvxColorItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) } } break; + + case MID_COLOR_THEME_REFERENCE_JSON: + { + OUString sThemeJson; + if (!(rVal >>= sThemeJson)) + return false; + + if (sThemeJson.isEmpty()) + { + return false; + } + OString aJSON = OUStringToOString(sThemeJson, RTL_TEXTENCODING_ASCII_US); + model::theme::convertFromJSON(aJSON, maThemeColor); + } + break; + + case MID_COLOR_RGB: default: { return rVal >>= mColor; diff --git a/include/docmodel/theme/ThemeColorJSON.hxx b/include/docmodel/theme/ThemeColorJSON.hxx new file mode 100644 index 000000000000..008850730e99 --- /dev/null +++ b/include/docmodel/theme/ThemeColorJSON.hxx @@ -0,0 +1,23 @@ +/* -*- 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/. + * + */ + +#pragma once + +#include +#include + +namespace model::theme +{ +DOCMODEL_DLLPUBLIC OString convertToJSON(model::ThemeColor const& rThemeColor); +DOCMODEL_DLLPUBLIC bool convertFromJSON(OString const& rJsonString, model::ThemeColor& rThemeColor); + +} // end of namespace model + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/editeng/colritem.hxx b/include/editeng/colritem.hxx index d4090eb9e7eb..fc55b6e04553 100644 --- a/include/editeng/colritem.hxx +++ b/include/editeng/colritem.hxx @@ -39,6 +39,7 @@ public: explicit SvxColorItem(const sal_uInt16 nId); SvxColorItem(const Color& aColor, const sal_uInt16 nId); + SvxColorItem(const Color& aColor, model::ThemeColor const& rThemeColor, const sal_uInt16 nId); virtual ~SvxColorItem() override; // "pure virtual Methods" from SfxPoolItem @@ -63,6 +64,11 @@ public: const model::ThemeColor& GetThemeColor() const { return maThemeColor; } + void setThemeColor(model::ThemeColor const& rThemeColor) + { + maThemeColor = rThemeColor; + } + void dumpAsXml(xmlTextWriterPtr pWriter) const override; }; diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h index 0b110cb52c5d..6003ce394ba0 100644 --- a/include/editeng/memberids.h +++ b/include/editeng/memberids.h @@ -189,6 +189,7 @@ #define MID_COLOR_LUM_MOD 6 #define MID_COLOR_LUM_OFF 7 #define MID_COLOR_THEME_REFERENCE 8 +#define MID_COLOR_THEME_REFERENCE_JSON 9 #endif diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc index 0c744f007348..d3da901a09ce 100644 --- a/include/svx/svxids.hrc +++ b/include/svx/svxids.hrc @@ -449,9 +449,10 @@ class XFillGradientItem; #define SID_ATTR_TEXTCOLUMNS_NUMBER ( SID_SVX_START + 340 ) #define SID_ATTR_TEXTCOLUMNS_SPACING ( SID_SVX_START + 341 ) -#define SID_ATTR_COLOR_THEME_INDEX TypedWhichId( SID_SVX_START + 342 ) -#define SID_ATTR_COLOR_LUM_MOD TypedWhichId( SID_SVX_START + 343 ) -#define SID_ATTR_COLOR_LUM_OFF TypedWhichId( SID_SVX_START + 344 ) +#define SID_ATTR_COLOR_THEME_REFERENCE TypedWhichId( SID_SVX_START + 342 ) +#define SID_ATTR_COLOR_THEME_INDEX TypedWhichId( SID_SVX_START + 343 ) +#define SID_ATTR_COLOR_LUM_MOD TypedWhichId( SID_SVX_START + 344 ) +#define SID_ATTR_COLOR_LUM_OFF TypedWhichId( SID_SVX_START + 345 ) #define SID_SB_CONNECTIONPOOLING ( SID_SVX_START + 348 ) #define SID_SB_DBREGISTEROPTIONS ( SID_SVX_START + 349 ) @@ -683,7 +684,6 @@ class XFillGradientItem; #define SID_PARAGRAPH_CHANGE_STATE ( SID_SVX_START + 754 ) #define SID_ATTR_SHADOW_BLUR ( SID_SVX_START + 755 ) - //FREE //FREE //FREE diff --git a/svx/sdi/svxitems.sdi b/svx/sdi/svxitems.sdi index 66eaf39b675b..a26c02c46ebb 100644 --- a/svx/sdi/svxitems.sdi +++ b/svx/sdi/svxitems.sdi @@ -169,7 +169,14 @@ item INT16 SvxParaVertAlignItem; item INT16 SvxCharReliefItem; item BOOL SvxBlinkItem; item BOOL SvxAutoKernItem; -item INT32 SvxColorItem; + +struct SvxColor +{ + INT32 Color MID_COLOR_RGB; + String ThemeReferenceJSON MID_COLOR_THEME_REFERENCE_JSON; +}; +item SvxColor SvxColorItem; + item BOOL SvxContourItem; item INT16 SvxFormatBreakItem; // enum item BOOL SvxFormatKeepItem; diff --git a/svx/source/tbxctrls/PaletteManager.cxx b/svx/source/tbxctrls/PaletteManager.cxx index f5cb5d221e37..314814e9dc7e 100644 --- a/svx/source/tbxctrls/PaletteManager.cxx +++ b/svx/source/tbxctrls/PaletteManager.cxx @@ -41,6 +41,11 @@ #include #include #include +#include +#include +#include +#include +#include #include @@ -420,6 +425,7 @@ void PaletteManager::PopupColorPicker(weld::Window* pParent, const OUString& aCo void PaletteManager::DispatchColorCommand(const OUString& aCommand, const svx::NamedThemedColor& rColor) { + using namespace css; using namespace css::uno; using namespace css::frame; using namespace css::beans; @@ -435,13 +441,22 @@ void PaletteManager::DispatchColorCommand(const OUString& aCommand, const svx::N INetURLObject aObj( aCommand ); std::vector aArgs{ - comphelper::makePropertyValue(aObj.GetURLPath(), sal_Int32(rColor.m_aColor)), + comphelper::makePropertyValue(aObj.GetURLPath()+ ".Color", sal_Int32(rColor.m_aColor)), }; + if (rColor.m_nThemeIndex != -1) { - aArgs.push_back(comphelper::makePropertyValue("ColorThemeIndex", rColor.m_nThemeIndex)); - aArgs.push_back(comphelper::makePropertyValue("ColorLumMod", rColor.m_nLumMod)); - aArgs.push_back(comphelper::makePropertyValue("ColorLumOff", rColor.m_nLumOff)); + model::ThemeColor aThemeColor; + aThemeColor.setType(model::convertToThemeColorType(rColor.m_nThemeIndex)); + if (rColor.m_nLumMod != 10000) + aThemeColor.addTransformation({model::TransformationType::LumMod, rColor.m_nLumMod}); + if (rColor.m_nLumMod != 0) + aThemeColor.addTransformation({model::TransformationType::LumOff, rColor.m_nLumOff}); + + uno::Any aAny; + aAny <<= OStringToOUString(model::theme::convertToJSON(aThemeColor), RTL_TEXTENCODING_UTF8); + + aArgs.push_back(comphelper::makePropertyValue(aObj.GetURLPath() + ".ThemeReferenceJSON", aAny)); } URL aTargetURL; diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 4df9f6f39999..b68d5cd83baa 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -1672,26 +1672,18 @@ void SwTextShell::Execute(SfxRequest &rReq) case SID_ATTR_CHAR_COLOR2: { - Color aSet; - bool bHasItem = false; - - if(pItem) - { - aSet = static_cast(pItem)->GetValue(); - bHasItem = true; - } - - if (bHasItem) + if (pItem) { + auto* pColorItem = static_cast(pItem); SwEditWin& rEditWin = GetView().GetEditWin(); - rEditWin.SetWaterCanTextColor(aSet); + rEditWin.SetWaterCanTextColor(pColorItem->GetValue()); SwApplyTemplate* pApply = rEditWin.GetApplyTemplate(); // If there is a selection, then set the color on it // otherwise, it'll be the color for the next text to be typed - if(!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_EXT) + if (!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_EXT) { - rWrtSh.SetAttrItem(SvxColorItem (aSet, RES_CHRATR_COLOR)); + rWrtSh.SetAttrItem(SvxColorItem(pColorItem->GetValue(), pColorItem->GetThemeColor(), RES_CHRATR_COLOR)); } rReq.Done();