summaryrefslogtreecommitdiffstats
path: root/svx/source/theme
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/theme')
-rw-r--r--svx/source/theme/ThemeColorChangerCommon.cxx177
-rw-r--r--svx/source/theme/ThemeColorPaletteManager.cxx173
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: */