LibreOffice Module svx (master) 1
ColorSets.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 */
10
11#include <svx/ColorSets.hxx>
12
13#include <sstream>
14
15#include <libxml/xmlwriter.h>
16
17#include <com/sun/star/util/Color.hpp>
18#include <com/sun/star/text/XTextRange.hpp>
19#include <com/sun/star/container/XEnumerationAccess.hpp>
20#include <com/sun/star/container/XEnumeration.hpp>
21#include <com/sun/star/beans/XPropertySet.hpp>
22
25#include <sal/log.hxx>
26#include <svx/svdpage.hxx>
27#include <svx/svditer.hxx>
28#include <editeng/unoprnms.hxx>
29
30using namespace com::sun::star;
31
32namespace
33{
35void UpdateTextPortionColorSet(const uno::Reference<beans::XPropertySet>& xPortion,
36 const svx::ColorSet& rColorSet)
37{
38 sal_Int16 nCharColorTheme = -1;
39 xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_THEME) >>= nCharColorTheme;
40 if (nCharColorTheme < 0 || nCharColorTheme > 11)
41 {
42 return;
43 }
44
45 Color aColor = rColorSet.getColor(nCharColorTheme);
46 sal_Int32 nCharColorLumMod{};
47 xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_LUM_MOD) >>= nCharColorLumMod;
48 sal_Int32 nCharColorLumOff{};
49 xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_LUM_OFF) >>= nCharColorLumOff;
50 if (nCharColorLumMod != 10000 || nCharColorLumOff != 0)
51 {
52 aColor.ApplyLumModOff(nCharColorLumMod, nCharColorLumOff);
53 }
54
55 sal_Int32 nCharColorTintOrShade{};
56 xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_TINT_OR_SHADE) >>= nCharColorTintOrShade;
57 if (nCharColorTintOrShade != 0)
58 {
59 aColor.ApplyTintOrShade(nCharColorTintOrShade);
60 }
61
62 xPortion->setPropertyValue(UNO_NAME_EDIT_CHAR_COLOR,
63 uno::Any(static_cast<sal_Int32>(aColor)));
64}
65
66void UpdateFillColorSet(const uno::Reference<beans::XPropertySet>& xShape, const svx::ColorSet& rColorSet)
67{
68 if (!xShape->getPropertySetInfo()->hasPropertyByName(UNO_NAME_FILLCOLOR_THEME))
69 {
70 return;
71 }
72
73 sal_Int16 nFillColorTheme = -1;
74 xShape->getPropertyValue(UNO_NAME_FILLCOLOR_THEME) >>= nFillColorTheme;
75 if (nFillColorTheme < 0 || nFillColorTheme > 11)
76 {
77 return;
78 }
79
80 Color aColor = rColorSet.getColor(nFillColorTheme);
81 sal_Int32 nFillColorLumMod{};
82 xShape->getPropertyValue(UNO_NAME_FILLCOLOR_LUM_MOD) >>= nFillColorLumMod;
83 sal_Int32 nFillColorLumOff{};
84 xShape->getPropertyValue(UNO_NAME_FILLCOLOR_LUM_OFF) >>= nFillColorLumOff;
85 if (nFillColorLumMod != 10000 || nFillColorLumOff != 0)
86 {
87 aColor.ApplyLumModOff(nFillColorLumMod, nFillColorLumOff);
88 }
89
90 xShape->setPropertyValue(UNO_NAME_FILLCOLOR, uno::Any(static_cast<sal_Int32>(aColor)));
91}
92
93void UpdateSdrObject(svx::Theme* pTheme, SdrObject* pObject)
94{
95 svx::ColorSet* pColorSet = pTheme->GetColorSet();
96 if (!pColorSet)
97 {
98 return;
99 }
100
101 uno::Reference<drawing::XShape> xShape = pObject->getUnoShape();
102 uno::Reference<text::XTextRange> xShapeText(xShape, uno::UNO_QUERY);
103 if (xShapeText.is())
104 {
105 // E.g. group shapes have no text.
106 uno::Reference<container::XEnumerationAccess> xText(xShapeText->getText(), uno::UNO_QUERY);
107 uno::Reference<container::XEnumeration> xParagraphs = xText->createEnumeration();
108 while (xParagraphs->hasMoreElements())
109 {
110 uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY);
111 uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
112 while (xPortions->hasMoreElements())
113 {
114 uno::Reference<beans::XPropertySet> xPortion(xPortions->nextElement(), uno::UNO_QUERY);
115 UpdateTextPortionColorSet(xPortion, *pColorSet);
116 }
117 }
118 }
119
120 uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
121 UpdateFillColorSet(xShapeProps, *pColorSet);
122}
123}
124
125namespace svx
126{
127
128ColorSet::ColorSet(OUString const & aColorSetName)
129 : maColorSetName(aColorSetName)
130 , maColors(12)
131{}
132
134{}
135
137{
138 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ColorSet"));
139 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
140 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("maColorSetName"),
141 BAD_CAST(maColorSetName.toUtf8().getStr()));
142
143 for (const auto& rColor : maColors)
144 {
145 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("Color"));
146 std::stringstream ss;
147 ss << rColor;
148 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(ss.str().c_str()));
149 (void)xmlTextWriterEndElement(pWriter);
150 }
151
152 (void)xmlTextWriterEndElement(pWriter);
153}
154
156{}
157
159{
160 {
161 ColorSet aColorSet("Breeze");
162 aColorSet.add(0, 0xFCFCFC);
163 aColorSet.add(1, 0x232629);
164 aColorSet.add(2, 0xEFF0F1);
165 aColorSet.add(3, 0x31363B);
166 aColorSet.add(4, 0xDA4453);
167 aColorSet.add(5, 0xF47750);
168 aColorSet.add(6, 0xFDBC4B);
169 aColorSet.add(7, 0xC9CE3B);
170 aColorSet.add(8, 0x1CDC9A);
171 aColorSet.add(9, 0x2ECC71);
172 aColorSet.add(10, 0x1D99F3);
173 aColorSet.add(11, 0x3DAEE9);
174 maColorSets.push_back(aColorSet);
175 }
176 {
177 ColorSet aColorSet("Material Blue");
178 aColorSet.add(0, 0xFFFFFF);
179 aColorSet.add(1, 0x212121);
180 aColorSet.add(2, 0xECEFF1);
181 aColorSet.add(3, 0x37474F);
182 aColorSet.add(4, 0x7986CB);
183 aColorSet.add(5, 0x303F9F);
184 aColorSet.add(6, 0x64B5F6);
185 aColorSet.add(7, 0x1976D2);
186 aColorSet.add(8, 0x4FC3F7);
187 aColorSet.add(9, 0x0277BD);
188 aColorSet.add(10, 0x4DD0E1);
189 aColorSet.add(11, 0x0097A7);
190 maColorSets.push_back(aColorSet);
191 }
192 {
193 ColorSet aColorSet("Material Red");
194 aColorSet.add(0, 0xFFFFFF);
195 aColorSet.add(1, 0x212121);
196 aColorSet.add(2, 0xF5F5F5);
197 aColorSet.add(3, 0x424242);
198 aColorSet.add(4, 0xFF9800);
199 aColorSet.add(5, 0xFF6D00);
200 aColorSet.add(6, 0xFF5722);
201 aColorSet.add(7, 0xDD2C00);
202 aColorSet.add(8, 0xF44336);
203 aColorSet.add(9, 0xD50000);
204 aColorSet.add(10, 0xE91E63);
205 aColorSet.add(11, 0xC51162);
206 maColorSets.push_back(aColorSet);
207 }
208 {
209 ColorSet aColorSet("Material Green");
210 aColorSet.add(0, 0xFFFFFF);
211 aColorSet.add(1, 0x212121);
212 aColorSet.add(2, 0xF5F5F5);
213 aColorSet.add(3, 0x424242);
214 aColorSet.add(4, 0x009688);
215 aColorSet.add(5, 0x00bfa5);
216 aColorSet.add(6, 0x4caf50);
217 aColorSet.add(7, 0x00c853);
218 aColorSet.add(8, 0x8bc34a);
219 aColorSet.add(9, 0x64dd17);
220 aColorSet.add(10, 0xcddc39);
221 aColorSet.add(11, 0xaeea00);
222 maColorSets.push_back(aColorSet);
223 }
224}
225
226const ColorSet& ColorSets::getColorSet(std::u16string_view rName)
227{
228 for (const ColorSet & rColorSet : maColorSets)
229 {
230 if (rColorSet.getName() == rName)
231 return rColorSet;
232 }
233 return maColorSets[0];
234}
235
236Theme::Theme(const OUString& rName)
237 : maName(rName)
238{
239}
240
242
243void Theme::SetColorSet(std::unique_ptr<ColorSet> pColorSet) { mpColorSet = std::move(pColorSet); }
244
246
247void Theme::SetName(const OUString& rName) { maName = rName; }
248
249const OUString& Theme::GetName() const { return maName; }
250
252{
253 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("Theme"));
254 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
255 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("maName"),
256 BAD_CAST(maName.toUtf8().getStr()));
257
258 if (mpColorSet)
259 {
260 mpColorSet->dumpAsXml(pWriter);
261 }
262
263 (void)xmlTextWriterEndElement(pWriter);
264}
265
266void Theme::ToAny(css::uno::Any& rVal) const
267{
269 aMap["Name"] <<= maName;
270
271 if (mpColorSet)
272 {
273 std::vector<util::Color> aColorScheme;
274 for (size_t i = 0; i < 12; ++i)
275 {
276 aColorScheme.push_back(static_cast<sal_Int32>(mpColorSet->getColor(i)));
277 }
278
279 aMap["ColorSchemeName"] <<= mpColorSet->getName();
280 aMap["ColorScheme"] <<= comphelper::containerToSequence(aColorScheme);
281 }
282
283 rVal <<= aMap.getAsConstPropertyValueList();
284}
285
286std::unique_ptr<Theme> Theme::FromAny(const css::uno::Any& rVal)
287{
289 std::unique_ptr<Theme> pTheme;
290 ColorSet* pColorSet = nullptr;
291
292 auto it = aMap.find("Name");
293 if (it != aMap.end())
294 {
295 OUString aName;
296 it->second >>= aName;
297 pTheme = std::make_unique<Theme>(aName);
298 }
299
300 it = aMap.find("ColorSchemeName");
301 if (it != aMap.end() && pTheme)
302 {
303 OUString aName;
304 it->second >>= aName;
305 auto pSet = std::make_unique<ColorSet>(aName);
306 pTheme->SetColorSet(std::move(pSet));
307 pColorSet = pTheme->GetColorSet();
308 }
309
310 it = aMap.find("ColorScheme");
311 if (it != aMap.end() && pColorSet)
312 {
313 uno::Sequence<util::Color> aColors;
314 it->second >>= aColors;
315 for (size_t i = 0; i < aColors.size(); ++i)
316 {
317 if (i >= 12)
318 {
319 SAL_WARN("svx", "Theme::FromAny: too many colors in the color set");
320 break;
321 }
322
323 pColorSet->add(i, Color(ColorTransparency, aColors[i]));
324 }
325 }
326
327 return pTheme;
328}
329
331{
332 for (size_t nObject = 0; nObject < pPage->GetObjCount(); ++nObject)
333 {
334 SdrObject* pObject = pPage->GetObj(nObject);
335 UpdateSdrObject(this, pObject);
336 SdrObjList* pList = pObject->GetSubList();
337 if (pList)
338 {
340 while (aIter.IsMore())
341 {
342 UpdateSdrObject(this, aIter.Next());
343 }
344 }
345 }
346}
347
348std::vector<Color> Theme::GetColors() const
349{
350 if (!mpColorSet)
351 {
352 return {};
353 }
354
355 std::vector<Color> aColors;
356 for (size_t i = 0; i < 12; ++i)
357 {
358 aColors.push_back(mpColorSet->getColor(i));
359 }
360 return aColors;
361}
362
364{
365 if (!mpColorSet)
366 {
367 return {};
368 }
369
370 return mpColorSet->getColor(static_cast<size_t>(eType));
371}
372
373} // end of namespace svx
374
375/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString maName
void ApplyTintOrShade(sal_Int16 n100thPercent)
void ApplyLumModOff(sal_Int16 nMod, sal_Int16 nOff)
SdrObject * Next()
Definition: svditer.hxx:63
bool IsMore() const
Definition: svditer.hxx:62
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:805
size_t GetObjCount() const
Definition: svdpage.cxx:799
Abstract DrawObject.
Definition: svdobj.hxx:261
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:374
void add(sal_uInt32 nIndex, ::Color aColorData)
Definition: ColorSets.hxx:34
ColorSet(OUString const &aName)
Definition: ColorSets.cxx:128
const OUString & getName() const
Definition: ColorSets.hxx:39
const Color & getColor(sal_uInt32 nIndex) const
Definition: ColorSets.hxx:43
OUString maColorSetName
Definition: ColorSets.hxx:29
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: ColorSets.cxx:136
std::vector< Color > maColors
Definition: ColorSets.hxx:30
std::vector< ColorSet > maColorSets
Definition: ColorSets.hxx:53
const ColorSet & getColorSet(sal_uInt32 nIndex)
Definition: ColorSets.hxx:64
A named theme has a named color set.
Definition: ColorSets.hxx:91
std::vector< Color > GetColors() const
Definition: ColorSets.cxx:348
OUString maName
Definition: ColorSets.hxx:92
Theme(OUString const &rName)
Definition: ColorSets.cxx:236
static std::unique_ptr< Theme > FromAny(const css::uno::Any &rVal)
Definition: ColorSets.cxx:286
void UpdateSdrPage(const SdrPage *pPage)
Definition: ColorSets.cxx:330
void SetName(const OUString &rName)
Definition: ColorSets.cxx:247
void SetColorSet(std::unique_ptr< ColorSet > pColorSet)
Definition: ColorSets.cxx:243
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: ColorSets.cxx:251
Color GetColor(ThemeColorType eType) const
Definition: ColorSets.cxx:363
const OUString & GetName() const
Definition: ColorSets.cxx:249
std::unique_ptr< ColorSet > mpColorSet
Definition: ColorSets.hxx:93
void ToAny(css::uno::Any &rVal) const
Definition: ColorSets.cxx:266
ColorSet * GetColorSet()
Definition: ColorSets.cxx:245
ColorTransparency
EmbeddedObjectRef * pObject
struct _xmlTextWriter * xmlTextWriterPtr
DocumentType eType
OUString aName
#define SAL_WARN(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
int i
ThemeColorType
Offsets into the color list of a theme.
Definition: ColorSets.hxx:74
HashMap_OWString_Interface aMap