/* -*- 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 <sal/config.h>
#include "ThemePanel.hxx"
#include <swtypes.hxx>
#include <cmdid.h>
#include <svl/intitem.hxx>
#include <svx/svxids.hrc>
#include <svx/dlgutil.hxx>
#include <svx/rulritem.hxx>
#include <sfx2/sidebar/ControlFactory.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/objsh.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/borderline.hxx>
#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;
sal_Int16 mnTintShade;
ColorVariable()
: mnIndex(-1)
, mnTintShade()
{}
ColorVariable(long nIndex, sal_Int16 nTintShade)
: mnIndex(nIndex)
, 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 const & rColorSet)
{
Color aColor;
if (maVariable.mnIndex > -1)
{
aColor = rColorSet.getColor(maVariable.mnIndex);
aColor.ApplyTintOrShade(maVariable.mnTintShade);
}
else
{
aColor = COL_BLACK;
}
return aColor;
}
};
class StyleSet
{
std::vector<StyleRedefinition> 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 const * pStyle, FontSet const & rFontSet)
{
bool bChanged = false;
if (pStyle->GetName() != "Default Style" && pFormat->GetAttrSet().GetItem(RES_CHRATR_FONT, false) == nullptr)
{
return;
}
SvxFontItem aFontItem(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 const & rColorSet, StyleRedefinition* pRedefinition)
{
Color aColor = pRedefinition->getColor(rColorSet);
SvxColorItem aColorItem(pCollection->GetColor());
aColorItem.SetValue(aColor);
pCollection->SetFormatAttr(aColorItem);
}
std::vector<FontSet> initFontSets()
{
std::vector<FontSet> 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<FontSet>& 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<FontSet> aFontSets = initFontSets();
FontSet aFontSet = getFontSet(sFontSetName, aFontSets);
svx::ColorSet aColorSet = rColorSets.getColorSet(sColorSetName);
pPool->SetSearchMask(SfxStyleFamily::Para);
pStyle = static_cast<SwDocStyleSheet*>(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<SwDocStyleSheet*>(pPool->Next());
}
pPool->SetSearchMask(SfxStyleFamily::Char);
pStyle = static_cast<SwDocStyleSheet*>(pPool->First());
while (pStyle)
{
SwCharFormat* pCharFormat = pStyle->GetCharFormat();
changeFont(static_cast<SwFormat*>(pCharFormat), pStyle, aFontSet);
pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
}
}
BitmapEx GenerateColorPreview(const svx::ColorSet& rColorSet)
{
ScopedVclPtrInstance<VirtualDevice> pVirtualDev(*Application::GetDefaultDevice());
float fScaleFactor = pVirtualDev->GetDPIScaleFactor();
long BORDER = 2 * fScaleFactor;
long SIZE = 12 * fScaleFactor;
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(tools::Rectangle(x, y1, x + SIZE, y1 + SIZE));
pVirtualDev->SetFillColor(rColorSet.getColor(i + 1));
pVirtualDev->DrawRect(tools::Rectangle(x, y2, x + SIZE, y2 + SIZE));
x += SIZE + BORDER;
}
return pVirtualDev->GetBitmapEx(Point(), aSize);
}
} // end anonymous namespace
namespace sw { namespace sidebar {
VclPtr<vcl::Window> ThemePanel::Create (vcl::Window* pParent,
const css::uno::Reference<css::frame::XFrame>& 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<ThemePanel>::Create(pParent, rxFrame);
}
ThemePanel::ThemePanel(vcl::Window* pParent,
const css::uno::Reference<css::frame::XFrame>& 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<FontSet> aFontSets = initFontSets();
for (FontSet & rFontSet : aFontSets)
{
mpListBoxFonts->InsertEntry(rFontSet.maName);
}
maColorSets.init();
const std::vector<svx::ColorSet>& 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<SwDocShell*>(SfxObjectShell::Current());
if (pDocSh)
{
OUString sEntryFonts = mpListBoxFonts->GetSelectedEntry();
sal_uInt32 nItemId = mpValueSetColors->GetSelectedItemId();
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: */
↑ V547 Expression 'bChanged' is always true.