/* -*- 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 #include "ThemePanel.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "charatr.hxx" #include "charfmt.hxx" #include "docstyle.hxx" #include "fmtcol.hxx" #include "format.hxx" namespace { class FontSet { public: OUString maName; OUString msMonoFont; OUString msHeadingFont; OUString msBaseFont; }; class ColorVariable { public: long mnIndex; Color maColor; sal_Int16 mnTintShade; ColorVariable() : mnIndex(-1) , maColor() , mnTintShade() {} ColorVariable(long nIndex, sal_Int16 nTintShade) : mnIndex(nIndex) , maColor() , mnTintShade(nTintShade) {} }; class StyleRedefinition { ColorVariable maVariable; public: OUString maElementName; public: explicit StyleRedefinition(const OUString& aElementName) : maElementName(aElementName) {} void setColorVariable(ColorVariable aVariable) { maVariable = aVariable; } Color getColor(svx::ColorSet& rColorSet) { Color aColor; if (maVariable.mnIndex > -1) { aColor = rColorSet.getColor(maVariable.mnIndex); aColor.ApplyTintOrShade(maVariable.mnTintShade); } else { aColor.SetColor(maVariable.maColor.GetColor()); } return aColor; } }; class StyleSet { std::vector maStyles; public: explicit StyleSet() : maStyles() {} void add(StyleRedefinition const & aRedefinition) { maStyles.push_back(aRedefinition); } StyleRedefinition* get(const OUString& aString) { for (StyleRedefinition & rStyle : maStyles) { if (rStyle.maElementName == aString) { return &rStyle; } } return nullptr; } }; StyleSet setupThemes() { StyleSet aSet; { StyleRedefinition aRedefinition("Heading 1"); aRedefinition.setColorVariable(ColorVariable(10, -1000)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 2"); aRedefinition.setColorVariable(ColorVariable(7, -500)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 3"); aRedefinition.setColorVariable(ColorVariable(5, 0)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 4"); aRedefinition.setColorVariable(ColorVariable(6, -1000)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 5"); aRedefinition.setColorVariable(ColorVariable(4, -1500)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 6"); aRedefinition.setColorVariable(ColorVariable(3, -2500)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 7"); aRedefinition.setColorVariable(ColorVariable(3, -2500)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 8"); aRedefinition.setColorVariable(ColorVariable(2, 0)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 9"); aRedefinition.setColorVariable(ColorVariable(2, 0)); aSet.add(aRedefinition); } { StyleRedefinition aRedefinition("Heading 10"); aRedefinition.setColorVariable(ColorVariable(0, 0)); aSet.add(aRedefinition); } return aSet; } void changeFont(SwFormat* pFormat, SwDocStyleSheet* pStyle, FontSet& rFontSet) { bool bChanged = false; if (pStyle->GetName() != "Default Style" && pFormat->GetAttrSet().GetItem(RES_CHRATR_FONT, false) == nullptr) { return; } SvxFontItem aFontItem(static_cast(pFormat->GetFont(false))); FontPitch ePitch = aFontItem.GetPitch(); if (ePitch == PITCH_FIXED) { aFontItem.SetFamilyName(rFontSet.msMonoFont); bChanged = true; } else { if (pStyle->GetName() == "Heading") { aFontItem.SetFamilyName(rFontSet.msHeadingFont); bChanged = true; } else { aFontItem.SetFamilyName(rFontSet.msBaseFont); bChanged = true; } } if (bChanged) { pFormat->SetFormatAttr(aFontItem); } } /*void changeBorder(SwTextFormatColl* pCollection, SwDocStyleSheet* pStyle, StyleSet& rStyleSet) { if (pStyle->GetName() == "Heading") { SvxBoxItem aBoxItem(pCollection->GetBox()); editeng::SvxBorderLine aBorderLine; aBorderLine.SetWidth(40); //20 = 1pt aBorderLine.SetColor(rColorSet.mBaseColors[0]); aBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM); pCollection->SetFormatAttr(aBoxItem); } }*/ void changeColor(SwTextFormatColl* pCollection, svx::ColorSet& rColorSet, StyleRedefinition* pRedefinition) { Color aColor = pRedefinition->getColor(rColorSet); SvxColorItem aColorItem(pCollection->GetColor()); aColorItem.SetValue(aColor); pCollection->SetFormatAttr(aColorItem); } std::vector initFontSets() { std::vector aFontSets; { FontSet aFontSet; aFontSet.maName = "Liberation Family"; aFontSet.msHeadingFont = "Liberation Sans"; aFontSet.msBaseFont = "Liberation Serif"; aFontSet.msMonoFont = "Liberation Mono"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "DejaVu Family"; aFontSet.msHeadingFont = "DejaVu Sans"; aFontSet.msBaseFont = "DejaVu Serif"; aFontSet.msMonoFont = "DejaVu Sans Mono"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "Croscore Modern"; aFontSet.msHeadingFont = "Caladea"; aFontSet.msBaseFont = "Carlito"; aFontSet.msMonoFont = "Liberation Mono"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "Carlito"; aFontSet.msHeadingFont = "Carlito"; aFontSet.msBaseFont = "Carlito"; aFontSet.msMonoFont = "Liberation Mono"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "Source Sans Family"; aFontSet.msHeadingFont = "Source Sans Pro"; aFontSet.msBaseFont = "Source Sans Pro"; aFontSet.msMonoFont = "Source Code Pro"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "Source Sans Family 2"; aFontSet.msHeadingFont = "Source Sans Pro"; aFontSet.msBaseFont = "Source Sans Pro Light"; aFontSet.msMonoFont = "Source Code Pro"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "Libertine Family"; aFontSet.msHeadingFont = "Linux Biolinum G"; aFontSet.msBaseFont = "Linux Libertine G"; aFontSet.msMonoFont = "Liberation Mono"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "Open Sans"; aFontSet.msHeadingFont = "Open Sans"; aFontSet.msBaseFont = "Open Sans"; aFontSet.msMonoFont = "Droid Sans Mono"; aFontSets.push_back(aFontSet); } { FontSet aFontSet; aFontSet.maName = "Droid Sans"; aFontSet.msHeadingFont = "Droid Sans"; aFontSet.msBaseFont = "Droid Sans"; aFontSet.msMonoFont = "Droid Sans Mono"; aFontSets.push_back(aFontSet); } return aFontSets; } FontSet getFontSet(const OUString& rFontVariant, std::vector& aFontSets) { for (FontSet & rFontSet : aFontSets) { if (rFontSet.maName == rFontVariant) return rFontSet; } return aFontSets[0]; } void applyTheme(SfxStyleSheetBasePool* pPool, const OUString& sFontSetName, const OUString& sColorSetName, StyleSet& rStyleSet, svx::ColorSets& rColorSets) { SwDocStyleSheet* pStyle; std::vector aFontSets = initFontSets(); FontSet aFontSet = getFontSet(sFontSetName, aFontSets); svx::ColorSet aColorSet = rColorSets.getColorSet(sColorSetName); pPool->SetSearchMask(SfxStyleFamily::Para); pStyle = static_cast(pPool->First()); while (pStyle) { SwTextFormatColl* pCollection = pStyle->GetCollection(); changeFont(pCollection, pStyle, aFontSet); StyleRedefinition* pRedefinition = rStyleSet.get(pStyle->GetName()); if (pRedefinition) { changeColor(pCollection, aColorSet, pRedefinition); } pStyle = static_cast(pPool->Next()); } pPool->SetSearchMask(SfxStyleFamily::Char); pStyle = static_cast(pPool->First()); while (pStyle) { SwCharFormat* pCharFormat = pStyle->GetCharFormat(); changeFont(static_cast(pCharFormat), pStyle, aFontSet); pStyle = static_cast(pPool->Next()); } } BitmapEx GenerateColorPreview(const svx::ColorSet& rColorSet) { ScopedVclPtrInstance pVirtualDev(*Application::GetDefaultDevice()); sal_Int32 nScaleFactor = pVirtualDev->GetDPIScaleFactor(); long BORDER = 2 * nScaleFactor; long SIZE = 12 * nScaleFactor; Size aSize(BORDER * 7 + SIZE * 6, BORDER * 3 + SIZE * 2); pVirtualDev->SetOutputSizePixel(aSize); long x = BORDER; long y1 = BORDER; long y2 = y1 + SIZE + BORDER; pVirtualDev->SetLineColor(COL_LIGHTGRAY); for (sal_uInt32 i = 0; i < 12; i += 2) { pVirtualDev->SetFillColor(rColorSet.getColor(i)); pVirtualDev->DrawRect(Rectangle(x, y1, x + SIZE, y1 + SIZE)); pVirtualDev->SetFillColor(rColorSet.getColor(i + 1)); pVirtualDev->DrawRect(Rectangle(x, y2, x + SIZE, y2 + SIZE)); x += SIZE + BORDER; } return pVirtualDev->GetBitmapEx(Point(), aSize); } } // end anonymous namespace namespace sw { namespace sidebar { VclPtr ThemePanel::Create (vcl::Window* pParent, const css::uno::Reference& rxFrame) { if (pParent == nullptr) throw css::lang::IllegalArgumentException("no parent Window given to PagePropertyPanel::Create", nullptr, 0); if (!rxFrame.is()) throw css::lang::IllegalArgumentException("no XFrame given to PagePropertyPanel::Create", nullptr, 1); return VclPtr::Create(pParent, rxFrame); } ThemePanel::ThemePanel(vcl::Window* pParent, const css::uno::Reference& rxFrame) : PanelLayout(pParent, "ThemePanel", "modules/swriter/ui/sidebartheme.ui", rxFrame) , maColorSets() { get(mpListBoxFonts, "listbox_fonts"); get(mpValueSetColors, "valueset_colors"); get(mpApplyButton, "apply"); mpValueSetColors->SetColCount(2); mpValueSetColors->SetLineCount(4); mpApplyButton->SetClickHdl(LINK(this, ThemePanel, ClickHdl)); mpListBoxFonts->SetDoubleClickHdl(LINK(this, ThemePanel, DoubleClickHdl)); mpValueSetColors->SetDoubleClickHdl(LINK(this, ThemePanel, DoubleClickValueSetHdl)); std::vector aFontSets = initFontSets(); for (FontSet & rFontSet : aFontSets) { mpListBoxFonts->InsertEntry(rFontSet.maName); } maColorSets.init(); const std::vector& aColorSets = maColorSets.getColorSets(); for (size_t i = 0; i < aColorSets.size(); ++i) { const svx::ColorSet& rColorSet = aColorSets[i]; const OUString& aName = rColorSet.getName(); BitmapEx aPreview = GenerateColorPreview(rColorSet); mpValueSetColors->InsertItem(i, Image(aPreview), aName); } } ThemePanel::~ThemePanel() { disposeOnce(); } void ThemePanel::dispose() { mpListBoxFonts.clear(); mpValueSetColors.clear(); mpApplyButton.clear(); PanelLayout::dispose(); } IMPL_LINK_NOARG(ThemePanel, ClickHdl, Button*, void) { DoubleClickHdl(); } IMPL_LINK_NOARG(ThemePanel, DoubleClickValueSetHdl, ValueSet*, void) { DoubleClickHdl(); } IMPL_LINK_NOARG(ThemePanel, DoubleClickHdl, ListBox&, void) { DoubleClickHdl(); } void ThemePanel::DoubleClickHdl() { SwDocShell* pDocSh = static_cast(SfxObjectShell::Current()); if (pDocSh) { OUString sEntryFonts = mpListBoxFonts->GetSelectEntry(); sal_uInt32 nItemId = mpValueSetColors->GetSelectItemId(); OUString sEntryColors = maColorSets.getColorSet(nItemId).getName(); StyleSet aStyleSet = setupThemes(); applyTheme(pDocSh->GetStyleSheetPool(), sEntryFonts, sEntryColors, aStyleSet, maColorSets); } } void ThemePanel::NotifyItemUpdate(const sal_uInt16 /*nSId*/, const SfxItemState /*eState*/, const SfxPoolItem* /*pState*/, const bool /*bIsEnabled*/) { } }} // end of namespace ::sw::sidebar /* vim:set shiftwidth=4 softtabstop=4 expandtab: */