Line data Source code
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 <sal/config.h>
12 :
13 : #include "ThemePanel.hxx"
14 :
15 : #include <swtypes.hxx>
16 : #include <cmdid.h>
17 :
18 : #include <tools/helpers.hxx>
19 :
20 : #include <svl/intitem.hxx>
21 : #include <svx/svxids.hrc>
22 : #include <svx/dlgutil.hxx>
23 : #include <svx/rulritem.hxx>
24 :
25 : #include <sfx2/sidebar/ControlFactory.hxx>
26 : #include <sfx2/dispatch.hxx>
27 : #include <sfx2/bindings.hxx>
28 : #include <sfx2/viewsh.hxx>
29 : #include <sfx2/objsh.hxx>
30 :
31 : #include <com/sun/star/frame/XController.hpp>
32 : #include <com/sun/star/frame/XModel.hpp>
33 : #include <com/sun/star/frame/DocumentTemplates.hpp>
34 : #include <com/sun/star/frame/XDocumentTemplates.hpp>
35 : #include <com/sun/star/document/XUndoManagerSupplier.hpp>
36 :
37 : #include <editeng/fontitem.hxx>
38 : #include <editeng/boxitem.hxx>
39 : #include <editeng/borderline.hxx>
40 : #include "charatr.hxx"
41 : #include "charfmt.hxx"
42 : #include "docstyle.hxx"
43 : #include "fmtcol.hxx"
44 : #include "format.hxx"
45 :
46 : namespace
47 : {
48 :
49 0 : class FontSet
50 : {
51 : public:
52 : OUString maName;
53 : OUString msMonoFont;
54 : OUString msHeadingFont;
55 : OUString msBaseFont;
56 : };
57 :
58 0 : class ColorSet
59 : {
60 : public:
61 : OUString maName;
62 : Color maColors[10];
63 : };
64 :
65 : class ColorVariable
66 : {
67 : public:
68 : long mnIndex;
69 : Color maColor;
70 : sal_Int16 mnTintShade;
71 :
72 0 : ColorVariable()
73 : : mnIndex(-1)
74 : , maColor()
75 0 : , mnTintShade()
76 0 : {}
77 :
78 0 : ColorVariable(long nIndex, sal_Int16 nTintShade = 0)
79 : : mnIndex(nIndex)
80 : , maColor()
81 0 : , mnTintShade(nTintShade)
82 0 : {}
83 : };
84 :
85 0 : class StyleRedefinition
86 : {
87 : ColorVariable maVariable;
88 :
89 : public:
90 : OUString maElementName;
91 :
92 : public:
93 0 : explicit StyleRedefinition(const OUString& aElementName)
94 0 : : maElementName(aElementName)
95 0 : {}
96 :
97 0 : void setColorVariable(ColorVariable aVariable)
98 : {
99 0 : maVariable = aVariable;
100 0 : }
101 :
102 0 : Color getColor(ColorSet& rColorSet)
103 : {
104 0 : Color aColor;
105 0 : if (maVariable.mnIndex > -1)
106 : {
107 0 : aColor.SetColor(rColorSet.maColors[maVariable.mnIndex].GetColor());
108 0 : if (maVariable.mnTintShade < 0)
109 : {
110 0 : double fFactor = std::abs(maVariable.mnTintShade) / 10000.0;
111 0 : aColor.SetRed(MinMax(aColor.GetRed() + (fFactor * (255.0 - aColor.GetRed())), 0, 255));
112 0 : aColor.SetGreen(MinMax(aColor.GetGreen() + (fFactor * (255.0 - aColor.GetGreen())), 0, 255));
113 0 : aColor.SetBlue(MinMax(aColor.GetBlue() + (fFactor * (255.0 - aColor.GetBlue())), 0, 255));
114 : }
115 0 : else if (maVariable.mnTintShade > 0)
116 : {
117 0 : double fFactor = 1.0 - std::abs(maVariable.mnTintShade) / 10000.0;
118 0 : aColor.SetRed(MinMax(aColor.GetRed() * fFactor, 0, 255));
119 0 : aColor.SetGreen(MinMax(aColor.GetGreen() * fFactor, 0, 255));
120 0 : aColor.SetBlue(MinMax(aColor.GetBlue() * fFactor, 0, 255));
121 : }
122 : }
123 : else
124 : {
125 0 : aColor.SetColor(maVariable.maColor.GetColor());
126 : }
127 0 : return aColor;
128 : }
129 : };
130 :
131 0 : class StyleSet
132 : {
133 : OUString maName;
134 : std::vector<StyleRedefinition> maStyles;
135 :
136 : public:
137 0 : explicit StyleSet(const OUString& aName)
138 : : maName(aName)
139 0 : , maStyles()
140 0 : {}
141 :
142 0 : void add(StyleRedefinition aRedefinition)
143 : {
144 0 : maStyles.push_back(aRedefinition);
145 0 : }
146 :
147 0 : StyleRedefinition* get(const OUString& aString)
148 : {
149 0 : for (size_t i = 0; i < maStyles.size(); i++)
150 : {
151 0 : if (maStyles[i].maElementName == aString)
152 : {
153 0 : return &maStyles[i];
154 : }
155 : }
156 0 : return nullptr;
157 : }
158 : };
159 :
160 0 : StyleSet setupThemes()
161 : {
162 0 : StyleSet aSet("Default");
163 :
164 : {
165 0 : StyleRedefinition aRedefinition("Heading 1");
166 0 : aRedefinition.setColorVariable(ColorVariable(0, 4000));
167 0 : aSet.add(aRedefinition);
168 : }
169 :
170 : {
171 0 : StyleRedefinition aRedefinition("Heading 2");
172 0 : aRedefinition.setColorVariable(ColorVariable(0, 2500));
173 0 : aSet.add(aRedefinition);
174 : }
175 :
176 : {
177 0 : StyleRedefinition aRedefinition("Heading 3");
178 0 : aRedefinition.setColorVariable(ColorVariable(0, 1000));
179 0 : aSet.add(aRedefinition);
180 : }
181 :
182 : {
183 0 : StyleRedefinition aRedefinition("Heading 4");
184 0 : aRedefinition.setColorVariable(ColorVariable(0));
185 0 : aSet.add(aRedefinition);
186 : }
187 :
188 : {
189 0 : StyleRedefinition aRedefinition("Heading 5");
190 0 : aRedefinition.setColorVariable(ColorVariable(0, -500));
191 0 : aSet.add(aRedefinition);
192 : }
193 :
194 : {
195 0 : StyleRedefinition aRedefinition("Heading 6");
196 0 : aRedefinition.setColorVariable(ColorVariable(0, -1000));
197 0 : aSet.add(aRedefinition);
198 : }
199 :
200 : {
201 0 : StyleRedefinition aRedefinition("Heading 7");
202 0 : aRedefinition.setColorVariable(ColorVariable(0, -1500));
203 0 : aSet.add(aRedefinition);
204 : }
205 :
206 : {
207 0 : StyleRedefinition aRedefinition("Heading 8");
208 0 : aRedefinition.setColorVariable(ColorVariable(0, -2000));
209 0 : aSet.add(aRedefinition);
210 : }
211 :
212 : {
213 0 : StyleRedefinition aRedefinition("Heading 9");
214 0 : aRedefinition.setColorVariable(ColorVariable(0, -2500));
215 0 : aSet.add(aRedefinition);
216 : }
217 :
218 : {
219 0 : StyleRedefinition aRedefinition("Heading 10");
220 0 : aRedefinition.setColorVariable(ColorVariable(0, -3000));
221 0 : aSet.add(aRedefinition);
222 : }
223 :
224 0 : return aSet;
225 : }
226 :
227 0 : void changeFont(SwFormat* pFormat, SwDocStyleSheet* pStyle, FontSet& rFontSet)
228 : {
229 0 : bool bChanged = false;
230 :
231 0 : if (pStyle->GetName() != "Default Style" && pFormat->GetAttrSet().GetItem(RES_CHRATR_FONT, false) == nullptr)
232 : {
233 0 : return;
234 : }
235 :
236 0 : SvxFontItem aFontItem(static_cast<const SvxFontItem&>(pFormat->GetFont(false)));
237 :
238 0 : FontPitch ePitch = aFontItem.GetPitch();
239 :
240 0 : if (ePitch == PITCH_FIXED)
241 : {
242 0 : aFontItem.SetFamilyName(rFontSet.msMonoFont);
243 0 : bChanged = true;
244 : }
245 : else
246 : {
247 0 : if (pStyle->GetName() == "Heading")
248 : {
249 0 : aFontItem.SetFamilyName(rFontSet.msHeadingFont);
250 0 : bChanged = true;
251 : }
252 : else
253 : {
254 0 : aFontItem.SetFamilyName(rFontSet.msBaseFont);
255 0 : bChanged = true;
256 : }
257 : }
258 :
259 0 : if (bChanged)
260 : {
261 0 : pFormat->SetFormatAttr(aFontItem);
262 0 : }
263 : }
264 :
265 : /*void changeBorder(SwTextFormatColl* pCollection, SwDocStyleSheet* pStyle, StyleSet& rStyleSet)
266 : {
267 : if (pStyle->GetName() == "Heading")
268 : {
269 : SvxBoxItem aBoxItem(pCollection->GetBox());
270 : editeng::SvxBorderLine aBorderLine;
271 : aBorderLine.SetWidth(40); //20 = 1pt
272 : aBorderLine.SetColor(rColorSet.mBaseColors[0]);
273 : aBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
274 :
275 : pCollection->SetFormatAttr(aBoxItem);
276 : }
277 : }*/
278 :
279 0 : void changeColor(SwTextFormatColl* pCollection, ColorSet& rColorSet, StyleRedefinition* pRedefinition)
280 : {
281 0 : Color aColor = pRedefinition->getColor(rColorSet);
282 :
283 0 : SvxColorItem aColorItem(pCollection->GetColor());
284 0 : aColorItem.SetValue(aColor);
285 0 : pCollection->SetFormatAttr(aColorItem);
286 0 : }
287 :
288 0 : std::vector<FontSet> initFontSets()
289 : {
290 0 : std::vector<FontSet> aFontSets;
291 : {
292 0 : FontSet aFontSet;
293 0 : aFontSet.maName = "Liberation Family";
294 0 : aFontSet.msHeadingFont = "Liberation Sans";
295 0 : aFontSet.msBaseFont = "Liberation Serif";
296 0 : aFontSet.msMonoFont = "Liberation Mono";
297 0 : aFontSets.push_back(aFontSet);
298 : }
299 : {
300 0 : FontSet aFontSet;
301 0 : aFontSet.maName = "DejaVu Family";
302 0 : aFontSet.msHeadingFont = "DejaVu Sans";
303 0 : aFontSet.msBaseFont = "DejaVu Serif";
304 0 : aFontSet.msMonoFont = "DejaVu Sans Mono";
305 0 : aFontSets.push_back(aFontSet);
306 : }
307 : {
308 0 : FontSet aFontSet;
309 0 : aFontSet.maName = "Croscore Modern";
310 0 : aFontSet.msHeadingFont = "Caladea";
311 0 : aFontSet.msBaseFont = "Carlito";
312 0 : aFontSet.msMonoFont = "Liberation Mono";
313 0 : aFontSets.push_back(aFontSet);
314 : }
315 : {
316 0 : FontSet aFontSet;
317 0 : aFontSet.maName = "Carlito";
318 0 : aFontSet.msHeadingFont = "Carlito";
319 0 : aFontSet.msBaseFont = "Carlito";
320 0 : aFontSet.msMonoFont = "Liberation Mono";
321 0 : aFontSets.push_back(aFontSet);
322 : }
323 : {
324 0 : FontSet aFontSet;
325 0 : aFontSet.maName = "Source Sans Family";
326 0 : aFontSet.msHeadingFont = "Source Sans Pro";
327 0 : aFontSet.msBaseFont = "Source Sans Pro";
328 0 : aFontSet.msMonoFont = "Source Code Pro";
329 0 : aFontSets.push_back(aFontSet);
330 : }
331 : {
332 0 : FontSet aFontSet;
333 0 : aFontSet.maName = "Source Sans Family 2";
334 0 : aFontSet.msHeadingFont = "Source Sans Pro";
335 0 : aFontSet.msBaseFont = "Source Sans Pro Light";
336 0 : aFontSet.msMonoFont = "Source Code Pro";
337 0 : aFontSets.push_back(aFontSet);
338 : }
339 : {
340 0 : FontSet aFontSet;
341 0 : aFontSet.maName = "Libertine Family";
342 0 : aFontSet.msHeadingFont = "Linux Biolinum G";
343 0 : aFontSet.msBaseFont = "Linux Libertine G";
344 0 : aFontSet.msMonoFont = "Liberation Mono";
345 0 : aFontSets.push_back(aFontSet);
346 : }
347 : {
348 0 : FontSet aFontSet;
349 0 : aFontSet.maName = "Open Sans";
350 0 : aFontSet.msHeadingFont = "Open Sans";
351 0 : aFontSet.msBaseFont = "Open Sans";
352 0 : aFontSet.msMonoFont = "Droid Sans Mono";
353 0 : aFontSets.push_back(aFontSet);
354 : }
355 : {
356 0 : FontSet aFontSet;
357 0 : aFontSet.maName = "Droid Sans";
358 0 : aFontSet.msHeadingFont = "Droid Sans";
359 0 : aFontSet.msBaseFont = "Droid Sans";
360 0 : aFontSet.msMonoFont = "Droid Sans Mono";
361 0 : aFontSets.push_back(aFontSet);
362 : }
363 0 : return aFontSets;
364 : }
365 :
366 0 : FontSet getFontSet(const OUString& rFontVariant, std::vector<FontSet>& aFontSets)
367 : {
368 0 : for (size_t i = 0; i < aFontSets.size(); ++i)
369 : {
370 0 : if (aFontSets[i].maName == rFontVariant)
371 0 : return aFontSets[i];
372 : }
373 0 : return aFontSets[0];
374 : }
375 :
376 0 : std::vector<ColorSet> initColorSets()
377 : {
378 0 : std::vector<ColorSet> aColorSets;
379 : {
380 0 : ColorSet aColorSet;
381 0 : aColorSet.maName = "Default";
382 0 : aColorSet.maColors[0] = Color(0x00, 0x00, 0x00);
383 0 : aColorSets.push_back(aColorSet);
384 : }
385 : {
386 0 : ColorSet aColorSet;
387 0 : aColorSet.maName = "Red";
388 0 : aColorSet.maColors[0] = Color(0xa4, 0x00, 0x00);
389 0 : aColorSets.push_back(aColorSet);
390 : }
391 : {
392 0 : ColorSet aColorSet;
393 0 : aColorSet.maName = "Green";
394 0 : aColorSet.maColors[0] = Color(0x00, 0xa4, 0x00);
395 0 : aColorSets.push_back(aColorSet);
396 : }
397 : {
398 0 : ColorSet aColorSet;
399 0 : aColorSet.maName = "Blue";
400 0 : aColorSet.maColors[0] = Color(0x00, 0x00, 0xa4);
401 0 : aColorSets.push_back(aColorSet);
402 : }
403 : {
404 0 : ColorSet aColorSet;
405 0 : aColorSet.maName = "Sky";
406 0 : aColorSet.maColors[0] = Color(0x72, 0x9f, 0xcf);
407 0 : aColorSets.push_back(aColorSet);
408 : }
409 :
410 0 : return aColorSets;
411 : }
412 :
413 0 : ColorSet getColorSet(const OUString& rColorVariant, std::vector<ColorSet>& aColorSets)
414 : {
415 0 : for (size_t i = 0; i < aColorSets.size(); ++i)
416 : {
417 0 : if (aColorSets[i].maName == rColorVariant)
418 0 : return aColorSets[i];
419 : }
420 0 : return aColorSets[0];
421 : }
422 :
423 0 : void applyTheme(SfxStyleSheetBasePool* pPool, const OUString& sFontSetName, const OUString& sColorSetName, StyleSet& rStyleSet)
424 : {
425 : SwDocStyleSheet* pStyle;
426 :
427 0 : std::vector<FontSet> aFontSets = initFontSets();
428 0 : FontSet aFontSet = getFontSet(sFontSetName, aFontSets);
429 :
430 0 : std::vector<ColorSet> aColorSets = initColorSets();
431 0 : ColorSet aColorSet = getColorSet(sColorSetName, aColorSets);
432 :
433 0 : pPool->SetSearchMask(SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL);
434 0 : pStyle = static_cast<SwDocStyleSheet*>(pPool->First());
435 :
436 0 : while (pStyle)
437 : {
438 0 : SwTextFormatColl* pCollection = pStyle->GetCollection();
439 :
440 0 : changeFont(pCollection, pStyle, aFontSet);
441 :
442 0 : StyleRedefinition* pRedefinition = rStyleSet.get(pStyle->GetName());
443 :
444 0 : if (pRedefinition)
445 : {
446 0 : changeColor(pCollection, aColorSet, pRedefinition);
447 : }
448 :
449 0 : pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
450 : }
451 :
452 0 : pPool->SetSearchMask(SFX_STYLE_FAMILY_CHAR, SFXSTYLEBIT_ALL);
453 0 : pStyle = static_cast<SwDocStyleSheet*>(pPool->First());
454 :
455 0 : while (pStyle)
456 : {
457 0 : SwCharFormat* pCharFormat = pStyle->GetCharFormat();
458 :
459 0 : changeFont(static_cast<SwFormat*>(pCharFormat), pStyle, aFontSet);
460 :
461 0 : pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
462 0 : }
463 0 : }
464 :
465 : } // end anonymous namespace
466 :
467 : namespace sw { namespace sidebar {
468 :
469 0 : VclPtr<vcl::Window> ThemePanel::Create (vcl::Window* pParent,
470 : const css::uno::Reference<css::frame::XFrame>& rxFrame,
471 : SfxBindings* pBindings)
472 : {
473 0 : if (pParent == NULL)
474 0 : throw css::lang::IllegalArgumentException("no parent Window given to PagePropertyPanel::Create", NULL, 0);
475 0 : if (!rxFrame.is())
476 0 : throw css::lang::IllegalArgumentException("no XFrame given to PagePropertyPanel::Create", NULL, 1);
477 0 : if (pBindings == NULL)
478 0 : throw css::lang::IllegalArgumentException("no SfxBindings given to PagePropertyPanel::Create", NULL, 2);
479 :
480 0 : return VclPtr<ThemePanel>::Create(pParent, rxFrame, pBindings);
481 : }
482 :
483 0 : ThemePanel::ThemePanel(vcl::Window* pParent,
484 : const css::uno::Reference<css::frame::XFrame>& rxFrame,
485 : SfxBindings* pBindings)
486 : : PanelLayout(pParent, "ThemePanel", "modules/swriter/ui/sidebartheme.ui", rxFrame)
487 0 : , mpBindings(pBindings)
488 : {
489 0 : get(mpListBoxFonts, "listbox_fonts");
490 0 : get(mpListBoxColors, "listbox_colors");
491 0 : get(mpApplyButton, "apply");
492 :
493 0 : mpApplyButton->SetClickHdl(LINK(this, ThemePanel, ClickHdl));
494 0 : mpListBoxFonts->SetDoubleClickHdl(LINK(this, ThemePanel, ClickHdl));
495 0 : mpListBoxColors->SetDoubleClickHdl(LINK(this, ThemePanel, ClickHdl));
496 :
497 0 : std::vector<FontSet> aFontSets = initFontSets();
498 0 : for (size_t i = 0; i < aFontSets.size(); ++i)
499 : {
500 0 : mpListBoxFonts->InsertEntry(aFontSets[i].maName);
501 : }
502 :
503 0 : std::vector<ColorSet> aColorSets = initColorSets();
504 0 : for (size_t i = 0; i < aColorSets.size(); ++i)
505 : {
506 0 : mpListBoxColors->InsertEntry(aColorSets[i].maName);
507 0 : }
508 0 : }
509 :
510 0 : ThemePanel::~ThemePanel()
511 : {
512 0 : disposeOnce();
513 0 : }
514 :
515 0 : void ThemePanel::dispose()
516 : {
517 0 : mpListBoxFonts.clear();
518 0 : mpListBoxColors.clear();
519 0 : mpApplyButton.clear();
520 :
521 0 : PanelLayout::dispose();
522 0 : }
523 :
524 0 : IMPL_LINK_NOARG(ThemePanel, ClickHdl)
525 : {
526 0 : SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
527 0 : if (pDocSh)
528 : {
529 0 : OUString sEntryFonts = mpListBoxFonts->GetSelectEntry();
530 0 : OUString sEntryColors = mpListBoxColors->GetSelectEntry();
531 :
532 0 : StyleSet aStyleSet = setupThemes();
533 :
534 0 : applyTheme(pDocSh->GetStyleSheetPool(), sEntryFonts, sEntryColors, aStyleSet);
535 : }
536 0 : return 1;
537 : }
538 :
539 0 : void ThemePanel::NotifyItemUpdate(const sal_uInt16 /*nSId*/,
540 : const SfxItemState /*eState*/,
541 : const SfxPoolItem* /*pState*/,
542 : const bool /*bIsEnabled*/)
543 : {
544 0 : }
545 :
546 177 : }} // end of namespace ::sw::sidebar
547 :
548 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|