/* -*- 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 <docmodel/theme/Theme.hxx>
#include <docmodel/uno/UnoTheme.hxx>
#include <utility>
#include <libxml/xmlwriter.h>
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/sequence.hxx>
#include <sal/log.hxx>
#include <sal/types.h>
#include <o3tl/enumrange.hxx>
#include <o3tl/underlyingenumvalue.hxx>
#include <com/sun/star/util/Color.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/util/XTheme.hpp>
using namespace com::sun::star;
namespace model
{
Theme::Theme() =
default;
Theme::Theme(OUString
const& rName)
: maName(rName)
{
}
Theme::Theme(Theme
const& rTheme)
: maName(rTheme.maName)
, mpColorSet(
new ColorSet(*rTheme.getColorSet()))
, maFontScheme(rTheme.maFontScheme)
{
}
void Theme::SetName(
const OUString& rName) { maName = rName; }
const OUString& Theme::GetName()
const {
return maName; }
void Theme::dumpAsXml(xmlTextWriterPtr pWriter)
const
{
(
void)xmlTextWriterStartElement(pWriter, BAD_CAST(
"Theme"));
(
void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST(
"ptr"),
"%p",
this);
(
void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST(
"maName"),
BAD_CAST(maName.toUtf8().getStr()));
if (mpColorSet)
{
mpColorSet->dumpAsXml(pWriter);
}
(
void)xmlTextWriterEndElement(pWriter);
}
void Theme::ToAny(uno::Any& rVal)
const
{
comphelper::SequenceAsHashMap aMap;
aMap[u
"Name"_ustr] <<= maName;
if (mpColorSet)
{
std::vector<util::Color> aColorScheme;
for (
auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
{
if (eThemeColorType != model::ThemeColorType::Unknown)
{
Color aColor = mpColorSet->getColor(eThemeColorType);
aColorScheme.push_back(sal_Int32(aColor));
}
}
aMap[u
"ColorSchemeName"_ustr] <<= mpColorSet->getName();
aMap[u
"ColorScheme"_ustr] <<= comphelper::containerToSequence(aColorScheme);
}
rVal <<= aMap.getAsConstPropertyValueList();
}
static std::shared_ptr<model::ColorSet> makeColorSet(
const OUString& name,
const uno::Sequence<util::Color>& colors)
{
auto colorset = std::make_shared<model::ColorSet>(name);
for (
auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
{
const size_t nIndex(o3tl::to_underlying(eThemeColorType));
if (nIndex >= colors.size())
break;
const Color aColor(ColorTransparency, colors[nIndex]);
colorset->add(eThemeColorType, aColor);
}
return colorset;
}
std::shared_ptr<Theme> Theme::FromAny(
const uno::Any& rVal)
{
if (css::uno::Reference<css::util::XTheme> xTheme; rVal >>= xTheme)
{
if (!xTheme)
return {};
if (
auto* pUnoTheme =
dynamic_cast<UnoTheme*>(xTheme.get()))
return pUnoTheme->getTheme();
auto pTheme = std::make_shared<Theme>(xTheme->getName());
if (
auto aColors = xTheme->getColorSet(); aColors.hasElements())
pTheme->setColorSet(makeColorSet(xTheme->getName(), aColors));
// Reuse theme name
return pTheme;
}
comphelper::SequenceAsHashMap aMap(rVal);
OUString aThemeName;
if (
auto it = aMap.find(u
"Name"_ustr); it != aMap.end())
it->second >>= aThemeName;
else
return {};
auto pTheme = std::make_shared<Theme>(aThemeName);
if (
auto it = aMap.find(u
"ColorSchemeName"_ustr); it != aMap.end())
{
OUString aColorSchemeName;
it->second >>= aColorSchemeName;
pTheme->setColorSet(makeColorSet(
aColorSchemeName,
aMap.getUnpackedValueOrDefault(u
"ColorScheme"_ustr, uno::Sequence<util::Color>{})))
;
}
return pTheme;
}
std::vector<Color> Theme::GetColors() const
{
if (!mpColorSet)
return {};
std::vector<Color> aColors;
for (auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
{
if (eThemeColorType != model::ThemeColorType::Unknown)
aColors.push_back(mpColorSet->getColor(eThemeColorType));
}
return aColors;
}
Color Theme::GetColor(model::ThemeColorType eType) const
{
if (!mpColorSet)
return {};
return mpColorSet->getColor(eType);
}
} // end of namespace model
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */