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