diff options
Diffstat (limited to 'svx/source/theme')
-rw-r--r-- | svx/source/theme/ThemeColorChangerCommon.cxx | 177 | ||||
-rw-r--r-- | svx/source/theme/ThemeColorPaletteManager.cxx | 173 |
2 files changed, 350 insertions, 0 deletions
diff --git a/svx/source/theme/ThemeColorChangerCommon.cxx b/svx/source/theme/ThemeColorChangerCommon.cxx new file mode 100644 index 0000000000..82f915fef9 --- /dev/null +++ b/svx/source/theme/ThemeColorChangerCommon.cxx @@ -0,0 +1,177 @@ +/* -*- 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 <svx/theme/ThemeColorChangerCommon.hxx> + +#include <sal/config.h> +#include <editeng/colritem.hxx> +#include <editeng/unoprnms.hxx> +#include <docmodel/uno/UnoComplexColor.hxx> +#include <docmodel/theme/ColorSet.hxx> + +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/util/XComplexColor.hpp> + +#include <svx/xlnclit.hxx> +#include <svx/xflclit.hxx> +#include <svx/xdef.hxx> +#include <editeng/eeitem.hxx> +#include <svx/svdundo.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdotext.hxx> + +#include <editeng/editeng.hxx> +#include <editeng/section.hxx> + +using namespace css; + +namespace svx::theme +{ +namespace +{ +const SvxColorItem* getColorItem(const editeng::Section& rSection) +{ + auto iterator = std::find_if( + rSection.maAttributes.begin(), rSection.maAttributes.end(), + [](const SfxPoolItem* pPoolItem) { return pPoolItem->Which() == EE_CHAR_COLOR; }); + + if (iterator != rSection.maAttributes.end()) + return static_cast<const SvxColorItem*>(*iterator); + return nullptr; +} + +bool updateEditEngTextSections(model::ColorSet const& rColorSet, SdrObject* pObject, SdrView& rView) +{ + SdrTextObj* pTextObject = DynCastSdrTextObj(pObject); + + if (!pTextObject) + return false; + + rView.SdrBeginTextEdit(pTextObject); + + auto* pOutlinerView = rView.GetTextEditOutlinerView(); + if (!pOutlinerView) + return false; + + auto* pEditEngine = pOutlinerView->GetEditView().GetEditEngine(); + if (!pEditEngine) + return false; + + OutlinerParaObject* pOutlinerParagraphObject = pTextObject->GetOutlinerParaObject(); + if (pOutlinerParagraphObject) + { + const EditTextObject& rEditText = pOutlinerParagraphObject->GetTextObject(); + std::vector<editeng::Section> aSections; + rEditText.GetAllSections(aSections); + + for (editeng::Section const& rSection : aSections) + { + const SvxColorItem* pItem = getColorItem(rSection); + if (!pItem) + continue; + + model::ComplexColor const& rComplexColor = pItem->getComplexColor(); + if (rComplexColor.isValidThemeType()) + { + SfxItemSet aSet(pEditEngine->GetAttribs(rSection.mnParagraph, rSection.mnStart, + rSection.mnEnd, + GetAttribsFlags::CHARATTRIBS)); + Color aNewColor = rColorSet.resolveColor(rComplexColor); + std::unique_ptr<SvxColorItem> pNewItem(pItem->Clone()); + pNewItem->setColor(aNewColor); + aSet.Put(*pNewItem); + + ESelection aSelection(rSection.mnParagraph, rSection.mnStart, rSection.mnParagraph, + rSection.mnEnd); + pEditEngine->QuickSetAttribs(aSet, aSelection); + } + } + } + + rView.SdrEndTextEdit(); + + return true; +} + +bool updateObjectAttributes(model::ColorSet const& rColorSet, SdrObject& rObject, + SfxUndoManager* pUndoManager) +{ + bool bChanged = false; + + auto aItemSet = rObject.GetMergedItemSet(); + + if (const XFillColorItem* pItem = aItemSet.GetItemIfSet(XATTR_FILLCOLOR, false)) + { + model::ComplexColor const& rComplexColor = pItem->getComplexColor(); + if (rComplexColor.isValidThemeType()) + { + Color aNewColor = rColorSet.resolveColor(rComplexColor); + std::unique_ptr<XFillColorItem> pNewItem(pItem->Clone()); + pNewItem->SetColorValue(aNewColor); + aItemSet.Put(*pNewItem); + bChanged = true; + } + } + if (const XLineColorItem* pItem = aItemSet.GetItemIfSet(XATTR_LINECOLOR, false)) + { + model::ComplexColor const& rComplexColor = pItem->getComplexColor(); + if (rComplexColor.isValidThemeType()) + { + Color aNewColor = rColorSet.resolveColor(rComplexColor); + std::unique_ptr<XLineColorItem> pNewItem(pItem->Clone()); + pNewItem->SetColorValue(aNewColor); + aItemSet.Put(*pNewItem); + bChanged = true; + } + } + if (const SvxColorItem* pItem = aItemSet.GetItemIfSet(EE_CHAR_COLOR, false)) + { + model::ComplexColor const& rComplexColor = pItem->getComplexColor(); + if (rComplexColor.isValidThemeType()) + { + Color aNewColor = rColorSet.resolveColor(rComplexColor); + std::unique_ptr<SvxColorItem> pNewItem(pItem->Clone()); + pNewItem->setColor(aNewColor); + aItemSet.Put(*pNewItem); + bChanged = true; + } + } + if (bChanged) + { + const bool bUndo = pUndoManager && pUndoManager->IsInListAction(); + if (bUndo) + { + pUndoManager->AddUndoAction( + rObject.getSdrModelFromSdrObject().GetSdrUndoFactory().CreateUndoAttrObject( + rObject)); + } + rObject.SetMergedItemSetAndBroadcast(aItemSet); + } + return bChanged; +} + +} // end anonymous namespace + +/// Updates properties of the SdrObject +void updateSdrObject(model::ColorSet const& rColorSet, SdrObject* pObject, SdrView* pView, + SfxUndoManager* pUndoManager) +{ + if (!pObject) + return; + updateObjectAttributes(rColorSet, *pObject, pUndoManager); + if (pView) + updateEditEngTextSections(rColorSet, pObject, *pView); +} + +} // end svx::theme namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/theme/ThemeColorPaletteManager.cxx b/svx/source/theme/ThemeColorPaletteManager.cxx new file mode 100644 index 0000000000..0e4f208996 --- /dev/null +++ b/svx/source/theme/ThemeColorPaletteManager.cxx @@ -0,0 +1,173 @@ +/* -*- 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 <svx/theme/ThemeColorPaletteManager.hxx> + +#include <basegfx/color/bcolortools.hxx> +#include <tools/color.hxx> +#include <unotools/resmgr.hxx> +#include <svx/dialmgr.hxx> +#include <svx/strings.hrc> +#include <docmodel/theme/ColorSet.hxx> +#include <docmodel/color/ComplexColorJSON.hxx> +#include <boost/property_tree/json_parser.hpp> + +#include <array> + +namespace +{ +constexpr const std::array<const std::array<sal_Int16, 6>, 5> g_aLumMods = { + std::array<sal_Int16, 6>{ 10'000, 5'000, 6'500, 7'500, 8'500, 9'500 }, + std::array<sal_Int16, 6>{ 10'000, 1'000, 2'500, 5'000, 7'500, 9'000 }, + std::array<sal_Int16, 6>{ 10'000, 2'000, 4'000, 6'000, 7'500, 5'000 }, + std::array<sal_Int16, 6>{ 10'000, 9'000, 7'500, 5'000, 2'500, 1'000 }, + std::array<sal_Int16, 6>{ 10'000, 9'500, 8'500, 7'500, 6'500, 5'000 }, +}; + +constexpr const std::array<const std::array<sal_Int16, 6>, 5> g_aLumOffs = { + std::array<sal_Int16, 6>{ 0, 5'000, 3'500, 2'500, 1'500, 0'500 }, + std::array<sal_Int16, 6>{ 0, 9'000, 7'500, 5'000, 2'500, 1'000 }, + std::array<sal_Int16, 6>{ 0, 8'000, 6'000, 4'000, 0, 0 }, + std::array<sal_Int16, 6>{ 0, 0, 0, 0, 0, 0 }, + std::array<sal_Int16, 6>{ 0, 0, 0, 0, 0, 0 }, +}; + +} // end anonymous namespace + +namespace svx +{ +ThemeColorPaletteManager::ThemeColorPaletteManager( + std::shared_ptr<model::ColorSet> const& pColorSet) + : m_pColorSet(pColorSet) +{ +} + +svx::ThemePaletteCollection ThemeColorPaletteManager::generate() +{ + svx::ThemePaletteCollection aThemePaletteCollection; + + const std::array<OUString, 12> aColorNames = { + SvxResId(RID_SVXSTR_THEME_COLOR1), SvxResId(RID_SVXSTR_THEME_COLOR2), + SvxResId(RID_SVXSTR_THEME_COLOR3), SvxResId(RID_SVXSTR_THEME_COLOR4), + SvxResId(RID_SVXSTR_THEME_COLOR5), SvxResId(RID_SVXSTR_THEME_COLOR6), + SvxResId(RID_SVXSTR_THEME_COLOR7), SvxResId(RID_SVXSTR_THEME_COLOR8), + SvxResId(RID_SVXSTR_THEME_COLOR9), SvxResId(RID_SVXSTR_THEME_COLOR10), + SvxResId(RID_SVXSTR_THEME_COLOR11), SvxResId(RID_SVXSTR_THEME_COLOR12), + }; + + for (size_t nColor = 0; nColor < aColorNames.size(); ++nColor) + { + auto eThemeType = model::convertToThemeColorType(nColor); + if (eThemeType == model::ThemeColorType::Unknown) + continue; + + auto& aThemeColorData = aThemePaletteCollection.maColors[nColor]; + aThemeColorData.meThemeColorType = eThemeType; + + Color aThemeColor = m_pColorSet->getColor(eThemeType); + aThemeColorData.maBaseColor = aThemeColor; + + basegfx::BColor aHSLColor = basegfx::utils::rgb2hsl(aThemeColor.getBColor()); + double aLuminanceValue = aHSLColor.getBlue() * 255.0; + + for (size_t nEffect : { 0, 1, 2, 3, 4, 5 }) + { + auto& rEffect = aThemeColorData.maEffects[nEffect]; + size_t nIndex = 0; + + if (aLuminanceValue < 0.5) + nIndex = 0; // Black + else if (aLuminanceValue > 254.5) + nIndex = 4; // White + else if (aLuminanceValue < 50.5) + nIndex = 1; // Low + else if (aLuminanceValue > 203.5) + nIndex = 3; // High + else + nIndex = 2; // Middle + + rEffect.mnLumOff = g_aLumOffs[nIndex][nEffect]; + rEffect.mnLumMod = g_aLumMods[nIndex][nEffect]; + + rEffect.maColor = aThemeColor; + rEffect.maColor.ApplyLumModOff(rEffect.mnLumMod, rEffect.mnLumOff); + + OUString aColorName; + sal_Int16 nPercent = rEffect.getPercentage(); + + OUString aTemplate; + if (nPercent > 0) + { + aTemplate = SvxResId(RID_SVXSTR_THEME_EFFECT_LIGHTER); + } + else if (nPercent < 0) + { + aTemplate = SvxResId(RID_SVXSTR_THEME_EFFECT_DARKER); + } + + if (!aTemplate.isEmpty()) + { + aColorName = aTemplate.replaceAll("$THEME_NAME", aColorNames[nColor]); + aColorName + = aColorName.replaceAll("$PERCENTAGE", OUString::number(std::abs(nPercent))); + } + else + { + aColorName = aColorNames[nColor]; + } + rEffect.maColorName = aColorName; + } + } + return aThemePaletteCollection; +} + +OString ThemeColorPaletteManager::generateJSON() +{ + svx::ThemePaletteCollection aThemePaletteCollection = generate(); + + boost::property_tree::ptree aTree; + boost::property_tree::ptree aColorListTree; + + for (size_t nEffect = 0; nEffect < 6; ++nEffect) + { + boost::property_tree::ptree aColorRowTree; + for (size_t nIndex = 0; nIndex < 12; ++nIndex) + { + auto const& rColorData = aThemePaletteCollection.maColors[nIndex]; + auto const& rEffectData = rColorData.maEffects[nEffect]; + + boost::property_tree::ptree aColorTree; + aColorTree.put("Value", rEffectData.maColor.AsRGBHexString().toUtf8()); + aColorTree.put("Name", rEffectData.maColorName.toUtf8()); + + model::ComplexColor aComplexColor; + aComplexColor.setThemeColor(rColorData.meThemeColorType); + aComplexColor.addTransformation( + { model::TransformationType::LumMod, rEffectData.mnLumMod }); + aComplexColor.addTransformation( + { model::TransformationType::LumOff, rEffectData.mnLumOff }); + boost::property_tree::ptree aDataTree; + model::color::convertToJSONTree(aDataTree, aComplexColor); + aColorTree.add_child("Data", aDataTree); + aColorRowTree.push_back(std::make_pair("", aColorTree)); + } + aColorListTree.push_back(std::make_pair("", aColorRowTree)); + } + + aTree.add_child("ThemeColors", aColorListTree); + + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + + return OString(aStream.str()); +} + +} // end svx namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |