1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
11 #include <sal/config.h>
13 #include "ThemePanel.hxx"
15 #include <sfx2/objsh.hxx>
17 #include <com/sun/star/lang/IllegalArgumentException.hpp>
19 #include <editeng/fontitem.hxx>
20 #include <vcl/bitmapex.hxx>
21 #include <vcl/image.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/virdev.hxx>
24 #include <charatr.hxx>
25 #include <charfmt.hxx>
27 #include <docstyle.hxx>
39 OUString msHeadingFont
;
47 sal_Int16 mnTintShade
;
54 ColorVariable(tools::Long nIndex
, sal_Int16 nTintShade
)
56 , mnTintShade(nTintShade
)
60 class StyleRedefinition
62 ColorVariable maVariable
;
65 OUString maElementName
;
68 explicit StyleRedefinition(const OUString
& aElementName
)
69 : maElementName(aElementName
)
72 void setColorVariable(ColorVariable aVariable
)
74 maVariable
= aVariable
;
77 Color
getColor(svx::ColorSet
const & rColorSet
)
80 if (maVariable
.mnIndex
> -1)
82 aColor
= rColorSet
.getColor(maVariable
.mnIndex
);
83 aColor
.ApplyTintOrShade(maVariable
.mnTintShade
);
95 std::vector
<StyleRedefinition
> maStyles
;
102 void add(StyleRedefinition
const & aRedefinition
)
104 maStyles
.push_back(aRedefinition
);
107 StyleRedefinition
* get(const OUString
& aString
)
109 for (StyleRedefinition
& rStyle
: maStyles
)
111 if (rStyle
.maElementName
== aString
)
120 StyleSet
setupThemes()
125 StyleRedefinition
aRedefinition("Heading 1");
126 aRedefinition
.setColorVariable(ColorVariable(10, -1000));
127 aSet
.add(aRedefinition
);
131 StyleRedefinition
aRedefinition("Heading 2");
132 aRedefinition
.setColorVariable(ColorVariable(7, -500));
133 aSet
.add(aRedefinition
);
137 StyleRedefinition
aRedefinition("Heading 3");
138 aRedefinition
.setColorVariable(ColorVariable(5, 0));
139 aSet
.add(aRedefinition
);
143 StyleRedefinition
aRedefinition("Heading 4");
144 aRedefinition
.setColorVariable(ColorVariable(6, -1000));
145 aSet
.add(aRedefinition
);
149 StyleRedefinition
aRedefinition("Heading 5");
150 aRedefinition
.setColorVariable(ColorVariable(4, -1500));
151 aSet
.add(aRedefinition
);
155 StyleRedefinition
aRedefinition("Heading 6");
156 aRedefinition
.setColorVariable(ColorVariable(3, -2500));
157 aSet
.add(aRedefinition
);
161 StyleRedefinition
aRedefinition("Heading 7");
162 aRedefinition
.setColorVariable(ColorVariable(3, -2500));
163 aSet
.add(aRedefinition
);
167 StyleRedefinition
aRedefinition("Heading 8");
168 aRedefinition
.setColorVariable(ColorVariable(2, 0));
169 aSet
.add(aRedefinition
);
173 StyleRedefinition
aRedefinition("Heading 9");
174 aRedefinition
.setColorVariable(ColorVariable(2, 0));
175 aSet
.add(aRedefinition
);
179 StyleRedefinition
aRedefinition("Heading 10");
180 aRedefinition
.setColorVariable(ColorVariable(0, 0));
181 aSet
.add(aRedefinition
);
187 void changeFont(SwFormat
* pFormat
, SwDocStyleSheet
const * pStyle
, FontSet
const & rFontSet
)
189 if (pStyle
->GetName() != "Default Style" && pFormat
->GetAttrSet().GetItem(RES_CHRATR_FONT
, false) == nullptr)
194 SvxFontItem
aFontItem(pFormat
->GetFont(false));
196 FontPitch ePitch
= aFontItem
.GetPitch();
198 if (ePitch
== PITCH_FIXED
)
200 aFontItem
.SetFamilyName(rFontSet
.msMonoFont
);
204 if (pStyle
->GetName() == "Heading")
206 aFontItem
.SetFamilyName(rFontSet
.msHeadingFont
);
210 aFontItem
.SetFamilyName(rFontSet
.msBaseFont
);
214 pFormat
->SetFormatAttr(aFontItem
);
217 /*void changeBorder(SwTextFormatColl* pCollection, SwDocStyleSheet* pStyle, StyleSet& rStyleSet)
219 if (pStyle->GetName() == "Heading")
221 SvxBoxItem aBoxItem(pCollection->GetBox());
222 editeng::SvxBorderLine aBorderLine;
223 aBorderLine.SetWidth(40); //20 = 1pt
224 aBorderLine.SetColor(rColorSet.mBaseColors[0]);
225 aBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
227 pCollection->SetFormatAttr(aBoxItem);
231 void changeColor(SwTextFormatColl
* pCollection
, svx::ColorSet
const & rColorSet
, StyleRedefinition
* pRedefinition
)
233 Color aColor
= pRedefinition
->getColor(rColorSet
);
235 SvxColorItem
aColorItem(pCollection
->GetColor());
236 aColorItem
.SetValue(aColor
);
237 pCollection
->SetFormatAttr(aColorItem
);
240 std::vector
<FontSet
> initFontSets()
242 std::vector
<FontSet
> aFontSets
;
245 aFontSet
.maName
= "Liberation Family";
246 aFontSet
.msHeadingFont
= "Liberation Sans";
247 aFontSet
.msBaseFont
= "Liberation Serif";
248 aFontSet
.msMonoFont
= "Liberation Mono";
249 aFontSets
.push_back(aFontSet
);
253 aFontSet
.maName
= "DejaVu Family";
254 aFontSet
.msHeadingFont
= "DejaVu Sans";
255 aFontSet
.msBaseFont
= "DejaVu Serif";
256 aFontSet
.msMonoFont
= "DejaVu Sans Mono";
257 aFontSets
.push_back(aFontSet
);
261 aFontSet
.maName
= "Croscore Modern";
262 aFontSet
.msHeadingFont
= "Caladea";
263 aFontSet
.msBaseFont
= "Carlito";
264 aFontSet
.msMonoFont
= "Liberation Mono";
265 aFontSets
.push_back(aFontSet
);
269 aFontSet
.maName
= "Carlito";
270 aFontSet
.msHeadingFont
= "Carlito";
271 aFontSet
.msBaseFont
= "Carlito";
272 aFontSet
.msMonoFont
= "Liberation Mono";
273 aFontSets
.push_back(aFontSet
);
277 aFontSet
.maName
= "Source Sans Family";
278 aFontSet
.msHeadingFont
= "Source Sans Pro";
279 aFontSet
.msBaseFont
= "Source Sans Pro";
280 aFontSet
.msMonoFont
= "Source Code Pro";
281 aFontSets
.push_back(aFontSet
);
285 aFontSet
.maName
= "Source Sans Family 2";
286 aFontSet
.msHeadingFont
= "Source Sans Pro";
287 aFontSet
.msBaseFont
= "Source Sans Pro Light";
288 aFontSet
.msMonoFont
= "Source Code Pro";
289 aFontSets
.push_back(aFontSet
);
293 aFontSet
.maName
= "Libertine Family";
294 aFontSet
.msHeadingFont
= "Linux Biolinum G";
295 aFontSet
.msBaseFont
= "Linux Libertine G";
296 aFontSet
.msMonoFont
= "Liberation Mono";
297 aFontSets
.push_back(aFontSet
);
301 aFontSet
.maName
= "Open Sans";
302 aFontSet
.msHeadingFont
= "Open Sans";
303 aFontSet
.msBaseFont
= "Open Sans";
304 aFontSet
.msMonoFont
= "Droid Sans Mono";
305 aFontSets
.push_back(aFontSet
);
309 aFontSet
.maName
= "Droid Sans";
310 aFontSet
.msHeadingFont
= "Droid Sans";
311 aFontSet
.msBaseFont
= "Droid Sans";
312 aFontSet
.msMonoFont
= "Droid Sans Mono";
313 aFontSets
.push_back(aFontSet
);
318 FontSet
getFontSet(const OUString
& rFontVariant
, std::vector
<FontSet
>& aFontSets
)
320 for (const FontSet
& rFontSet
: aFontSets
)
322 if (rFontSet
.maName
== rFontVariant
)
328 void applyTheme(SfxStyleSheetBasePool
* pPool
, const OUString
& sFontSetName
, const OUString
& sColorSetName
,
329 StyleSet
& rStyleSet
, svx::ColorSets
& rColorSets
)
331 SwDocStyleSheet
* pStyle
;
333 std::vector
<FontSet
> aFontSets
= initFontSets();
334 FontSet aFontSet
= getFontSet(sFontSetName
, aFontSets
);
336 svx::ColorSet aColorSet
= rColorSets
.getColorSet(sColorSetName
);
338 pStyle
= static_cast<SwDocStyleSheet
*>(pPool
->First(SfxStyleFamily::Para
));
341 SwTextFormatColl
* pCollection
= pStyle
->GetCollection();
343 changeFont(pCollection
, pStyle
, aFontSet
);
345 StyleRedefinition
* pRedefinition
= rStyleSet
.get(pStyle
->GetName());
349 changeColor(pCollection
, aColorSet
, pRedefinition
);
352 pStyle
= static_cast<SwDocStyleSheet
*>(pPool
->Next());
355 pStyle
= static_cast<SwDocStyleSheet
*>(pPool
->First(SfxStyleFamily::Char
));
358 SwCharFormat
* pCharFormat
= pStyle
->GetCharFormat();
360 changeFont(static_cast<SwFormat
*>(pCharFormat
), pStyle
, aFontSet
);
362 pStyle
= static_cast<SwDocStyleSheet
*>(pPool
->Next());
366 BitmapEx
GenerateColorPreview(const svx::ColorSet
& rColorSet
)
368 ScopedVclPtrInstance
<VirtualDevice
> pVirtualDev(*Application::GetDefaultDevice());
369 float fScaleFactor
= pVirtualDev
->GetDPIScaleFactor();
370 tools::Long BORDER
= 2 * fScaleFactor
;
371 tools::Long SIZE
= 12 * fScaleFactor
;
373 Size
aSize(BORDER
* 7 + SIZE
* 6, BORDER
* 3 + SIZE
* 2);
374 pVirtualDev
->SetOutputSizePixel(aSize
);
376 tools::Long x
= BORDER
;
377 tools::Long y1
= BORDER
;
378 tools::Long y2
= y1
+ SIZE
+ BORDER
;
380 pVirtualDev
->SetLineColor(COL_LIGHTGRAY
);
382 for (sal_uInt32 i
= 0; i
< 12; i
+= 2)
384 pVirtualDev
->SetFillColor(rColorSet
.getColor(i
));
385 pVirtualDev
->DrawRect(tools::Rectangle(x
, y1
, x
+ SIZE
, y1
+ SIZE
));
387 pVirtualDev
->SetFillColor(rColorSet
.getColor(i
+ 1));
388 pVirtualDev
->DrawRect(tools::Rectangle(x
, y2
, x
+ SIZE
, y2
+ SIZE
));
393 return pVirtualDev
->GetBitmapEx(Point(), aSize
);
396 } // end anonymous namespace
398 namespace sw::sidebar
{
400 VclPtr
<vcl::Window
> ThemePanel::Create (vcl::Window
* pParent
,
401 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
)
403 if (pParent
== nullptr)
404 throw css::lang::IllegalArgumentException("no parent Window given to PagePropertyPanel::Create", nullptr, 0);
406 throw css::lang::IllegalArgumentException("no XFrame given to PagePropertyPanel::Create", nullptr, 1);
408 return VclPtr
<ThemePanel
>::Create(pParent
, rxFrame
);
411 ThemePanel::ThemePanel(vcl::Window
* pParent
,
412 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
)
413 : PanelLayout(pParent
, "ThemePanel", "modules/swriter/ui/sidebartheme.ui", rxFrame
)
414 , mxListBoxFonts(m_xBuilder
->weld_tree_view("listbox_fonts"))
415 , mxValueSetColors(new ValueSet(nullptr))
416 , mxValueSetColorsWin(new weld::CustomWeld(*m_xBuilder
, "valueset_colors", *mxValueSetColors
))
417 , mxApplyButton(m_xBuilder
->weld_button("apply"))
420 mxValueSetColors
->SetColCount(2);
421 mxValueSetColors
->SetLineCount(3);
423 mxApplyButton
->connect_clicked(LINK(this, ThemePanel
, ClickHdl
));
424 mxListBoxFonts
->connect_row_activated(LINK(this, ThemePanel
, DoubleClickHdl
));
425 mxValueSetColors
->SetDoubleClickHdl(LINK(this, ThemePanel
, DoubleClickValueSetHdl
));
427 std::vector
<FontSet
> aFontSets
= initFontSets();
428 for (const FontSet
& rFontSet
: aFontSets
)
429 mxListBoxFonts
->append_text(rFontSet
.maName
);
430 mxListBoxFonts
->set_size_request(-1, mxListBoxFonts
->get_height_rows(aFontSets
.size()));
434 const std::vector
<svx::ColorSet
>& aColorSets
= maColorSets
.getColorSets();
435 for (size_t i
= 0; i
< aColorSets
.size(); ++i
)
437 const svx::ColorSet
& rColorSet
= aColorSets
[i
];
439 const OUString
& aName
= rColorSet
.getName();
440 BitmapEx aPreview
= GenerateColorPreview(rColorSet
);
442 sal_uInt16 nId
= i
+ 1;
443 mxValueSetColors
->InsertItem(nId
, Image(aPreview
), aName
);
446 mxValueSetColors
->SetOptimalSize();
448 if (!aColorSets
.empty())
449 mxValueSetColors
->SelectItem(1); // ItemId 1, position 0
451 m_pInitialFocusWidget
= mxListBoxFonts
.get();
454 ThemePanel::~ThemePanel()
459 void ThemePanel::dispose()
461 mxListBoxFonts
.reset();
462 mxValueSetColorsWin
.reset();
463 mxValueSetColors
.reset();
464 mxApplyButton
.reset();
466 PanelLayout::dispose();
469 IMPL_LINK_NOARG(ThemePanel
, ClickHdl
, weld::Button
&, void)
474 IMPL_LINK_NOARG(ThemePanel
, DoubleClickValueSetHdl
, ValueSet
*, void)
479 IMPL_LINK_NOARG(ThemePanel
, DoubleClickHdl
, weld::TreeView
&, bool)
485 void ThemePanel::DoubleClickHdl()
487 SwDocShell
* pDocSh
= static_cast<SwDocShell
*>(SfxObjectShell::Current());
491 sal_uInt32 nItemId
= mxValueSetColors
->GetSelectedItemId();
494 OUString sEntryFonts
= mxListBoxFonts
->get_selected_text();
495 sal_uInt32 nIndex
= nItemId
- 1;
496 OUString sEntryColors
= maColorSets
.getColorSet(nIndex
).getName();
498 StyleSet aStyleSet
= setupThemes();
500 applyTheme(pDocSh
->GetStyleSheetPool(), sEntryFonts
, sEntryColors
, aStyleSet
, maColorSets
);
503 void ThemePanel::NotifyItemUpdate(const sal_uInt16
/*nSId*/,
504 const SfxItemState
/*eState*/,
505 const SfxPoolItem
* /*pState*/)
509 } // end of namespace ::sw::sidebar
511 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */