mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 19:32:54 +00:00
525 lines
13 KiB
C++
525 lines
13 KiB
C++
/*
|
|
* Copyright (C) 2007, 2008, 2009, 2010 Ivan Cukic <ivan.cukic(at)kde.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser/Library General Public License version 2,
|
|
* or (at your option) any later version, as published by the Free
|
|
* Software Foundation
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser/Library General Public License for more details
|
|
*
|
|
* You should have received a copy of the GNU Lesser/Library General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "Global.h"
|
|
#include "Global_p.h"
|
|
|
|
#include <QMetaObject>
|
|
#include <QtCore/qmetaobject.h>
|
|
#include <QMutex>
|
|
|
|
#include <KGlobal>
|
|
#include <KStandardDirs>
|
|
#include <KDebug>
|
|
|
|
#include <Plasma/Theme>
|
|
|
|
namespace Lancelot
|
|
{
|
|
|
|
// Group
|
|
Group::ColorScheme::ColorScheme()
|
|
: normal(QColor()), disabled(QColor()), active(QColor())
|
|
{
|
|
}
|
|
|
|
GroupPrivate::GroupPrivate()
|
|
: name(QString()), backgroundSvg(NULL),
|
|
ownsBackgroundSvg(false), loaded(false)
|
|
// TODO : Add caching?
|
|
//cachedBackgroundNormal(NULL), cachedBackgroundActive(NULL), cachedBackgroundDisabled(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
GroupPrivate::~GroupPrivate()
|
|
{
|
|
if (ownsBackgroundSvg) {
|
|
delete backgroundSvg;
|
|
}
|
|
//delete d->cachedBackgroundNormal;
|
|
//delete d->cachedBackgroundActive;
|
|
//delete d->cachedBackgroundDisabled;
|
|
}
|
|
|
|
void GroupPrivate::setObjectProperty(QObject * object,
|
|
const QString & property, const QVariant & value)
|
|
{
|
|
object->setProperty(property.toAscii(), value);
|
|
}
|
|
|
|
// clearing all info
|
|
void GroupPrivate::reset()
|
|
{
|
|
loaded = false;
|
|
|
|
// kDebug() << name << "Persistent properties:"
|
|
// << persistentProperties << "of"
|
|
// << properties;
|
|
|
|
QMutableMapIterator < QString, QVariant > i(properties);
|
|
while (i.hasNext()) {
|
|
i.next();
|
|
if (!persistentProperties.contains(i.key())) {
|
|
// kDebug() << "reloading property:" << i.key();
|
|
i.remove();
|
|
}
|
|
}
|
|
|
|
if (ownsBackgroundSvg) {
|
|
delete backgroundSvg;
|
|
}
|
|
backgroundSvg = NULL;
|
|
|
|
foregroundColor = Group::ColorScheme();
|
|
backgroundColor = Group::ColorScheme();
|
|
|
|
}
|
|
|
|
void GroupPrivate::copyFrom(GroupPrivate * d)
|
|
{
|
|
if (this == d) return;
|
|
|
|
QMap < QString, QVariant > savedProperties;
|
|
|
|
foreach (const QString & key, persistentProperties) {
|
|
savedProperties[key] = properties[key];
|
|
}
|
|
|
|
properties = d->properties;
|
|
persistentProperties += d->persistentProperties;
|
|
|
|
QMapIterator < QString, QVariant > i( savedProperties );
|
|
while (i.hasNext()) {
|
|
i.next();
|
|
|
|
properties[i.key()] = i.value();
|
|
}
|
|
|
|
foregroundColor = d->foregroundColor;
|
|
backgroundColor = d->backgroundColor;
|
|
|
|
if (ownsBackgroundSvg) {
|
|
delete backgroundSvg;
|
|
}
|
|
backgroundSvg = d->backgroundSvg;
|
|
ownsBackgroundSvg = false;
|
|
}
|
|
|
|
KConfigGroup GroupPrivate::confGroupTheme()
|
|
{
|
|
return KConfigGroup(Global::self()->theme(), "Group-" + name);
|
|
}
|
|
|
|
Group::Group(QString name)
|
|
: d(new GroupPrivate())
|
|
{
|
|
d->name = name;
|
|
}
|
|
|
|
Group::~Group()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void Group::add(QObject * object)
|
|
{
|
|
if (!object) return;
|
|
|
|
if (d->objects.contains(object)) return;
|
|
d->objects << object;
|
|
|
|
QMapIterator < QString, QVariant > i(d->properties);
|
|
while (i.hasNext()) {
|
|
i.next();
|
|
d->setObjectProperty(object,
|
|
i.key(), i.value());
|
|
}
|
|
}
|
|
|
|
void Group::remove(QObject * object, bool setDefaultGroup)
|
|
{
|
|
if (Global::self()->defaultGroup() == this && setDefaultGroup) return;
|
|
|
|
if (!d->objects.contains(object)) return;
|
|
d->objects.remove(object);
|
|
}
|
|
|
|
bool Group::hasProperty(const QString & property) const
|
|
{
|
|
return d->properties.contains(property);
|
|
}
|
|
|
|
QVariant Group::property(const QString & property) const
|
|
{
|
|
return d->properties.value(property);
|
|
}
|
|
|
|
void Group::setProperty(const QString & property, const QVariant & value, bool persistent)
|
|
{
|
|
// kDebug() << property << value;
|
|
|
|
d->properties[property] = value;
|
|
|
|
if (persistent) {
|
|
d->persistentProperties << property;
|
|
}
|
|
|
|
foreach (QObject * child, d->objects) {
|
|
d->setObjectProperty(child, property, value);
|
|
}
|
|
}
|
|
|
|
void Group::clearProperty(const QString & property)
|
|
{
|
|
d->properties.remove(property);
|
|
}
|
|
|
|
QString Group::name() const
|
|
{
|
|
return d->name;
|
|
}
|
|
|
|
Plasma::FrameSvg * Group::backgroundSvg() const
|
|
{
|
|
return d->backgroundSvg;
|
|
}
|
|
|
|
const Group::ColorScheme * Group::backgroundColor() const
|
|
{
|
|
if (!hasProperty("WholeColorBackground") &&
|
|
!hasProperty("TextColorBackground")) {
|
|
return NULL;
|
|
}
|
|
return & d->backgroundColor;
|
|
}
|
|
|
|
const Group::ColorScheme * Group::foregroundColor() const
|
|
{
|
|
return & d->foregroundColor;
|
|
}
|
|
|
|
void Group::load(bool full)
|
|
{
|
|
if (d->loaded && !full) return;
|
|
|
|
// kDebug() << name();
|
|
|
|
d->reset();
|
|
d->loaded = true;
|
|
|
|
Group * group;
|
|
|
|
KConfigGroup confGroupTheme = d->confGroupTheme();
|
|
if (!confGroupTheme.exists()) {
|
|
group = Global::self()->defaultGroup();
|
|
if (group == this) return;
|
|
|
|
d->copyFrom(group->d);
|
|
return;
|
|
}
|
|
|
|
QString parentName = confGroupTheme.readEntry("parent", "Default");
|
|
if (Global::self()->groupExists(parentName)) {
|
|
group = Global::self()->group(confGroupTheme.readEntry("parent", "Default"));
|
|
if (group != this) {
|
|
group->load(false);
|
|
d->copyFrom(group->d);
|
|
}
|
|
}
|
|
|
|
// Load properties from theme configuration file
|
|
d->foregroundColor.normal = confGroupTheme.readEntry("foreground.color.normal", d->foregroundColor.normal);
|
|
d->foregroundColor.active = confGroupTheme.readEntry("foreground.color.active", d->foregroundColor.active);
|
|
d->foregroundColor.disabled = confGroupTheme.readEntry("foreground.color.disabled", d->foregroundColor.disabled);
|
|
|
|
QString type = confGroupTheme.readEntry("background.type", "none");
|
|
if (type == "color" || type == "color-compact") {
|
|
// kDebug() << "loading color background";
|
|
if (type == "color") {
|
|
setProperty("WholeColorBackground", 1, false);
|
|
} else {
|
|
setProperty("TextColorBackground", 1, false);
|
|
}
|
|
d->backgroundColor.normal = confGroupTheme.readEntry("background.color.normal", d->backgroundColor.normal);
|
|
d->backgroundColor.active = confGroupTheme.readEntry("background.color.active", d->backgroundColor.active);
|
|
d->backgroundColor.disabled = confGroupTheme.readEntry("background.color.disabled", d->backgroundColor.disabled);
|
|
} else if (type == "svg") {
|
|
// kDebug() << "loading svg background";
|
|
// we have already deleted the backgroundSvg
|
|
// if (d->ownsBackgroundSvg) {
|
|
// delete d->backgroundSvg;
|
|
// }
|
|
|
|
d->backgroundSvg = new Plasma::FrameSvg(NULL);
|
|
QString imagePath = Plasma::Theme::defaultTheme()->imagePath(
|
|
confGroupTheme.readEntry("background.svg"));
|
|
|
|
d->backgroundSvg->setImagePath(imagePath);
|
|
// kDebug() << "Background is: " <<
|
|
// d->backgroundSvg->imagePath();
|
|
d->backgroundSvg->setCacheAllRenderedFrames(true);
|
|
d->ownsBackgroundSvg = true;
|
|
|
|
if (!d->backgroundSvg->isValid()) {
|
|
// kDebug() << "Background is not valid: " <<
|
|
// d->backgroundSvg->imagePath();
|
|
delete d->backgroundSvg;
|
|
d->backgroundSvg = NULL;
|
|
d->ownsBackgroundSvg = false;
|
|
} else {
|
|
setProperty("SvgBackground", 1, false);
|
|
}
|
|
}
|
|
|
|
if (!confGroupTheme.readEntry(
|
|
"foreground.blurtextshadow", QString()).isEmpty()) {
|
|
setProperty("BlurTextShadow", 1, false);
|
|
}
|
|
}
|
|
|
|
bool Group::contains(QObject * object)
|
|
{
|
|
return d->objects.contains(object);
|
|
}
|
|
|
|
|
|
// Global
|
|
|
|
Global * Global::Private::instance = NULL;
|
|
|
|
Global * Global::self()
|
|
{
|
|
if (!Global::Private::instance) {
|
|
Global::Private::instance = new Global();
|
|
}
|
|
return Global::Private::instance;
|
|
}
|
|
|
|
Global::Private::Private()
|
|
: confMain(NULL),
|
|
confTheme(NULL)
|
|
{
|
|
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
|
|
this, SLOT(themeChanged()));
|
|
}
|
|
|
|
Global::Private::~Private()
|
|
{
|
|
}
|
|
|
|
void Global::Private::objectDeleted(QObject * object)
|
|
{
|
|
Group * group = Global::self()->groupForObject(object);
|
|
if (group) {
|
|
group->remove(object);
|
|
}
|
|
}
|
|
|
|
void Global::Private::createConfTheme()
|
|
{
|
|
QString app = KGlobal::mainComponent().componentName();
|
|
if (app == "lancelot") {
|
|
app = "";
|
|
} else {
|
|
app += '-';
|
|
}
|
|
|
|
delete confTheme;
|
|
QString search = "desktoptheme/" +
|
|
Plasma::Theme::defaultTheme()->themeName()
|
|
+ "/lancelot/" + app + "theme.config";
|
|
QString path = KStandardDirs::locate( "data", search );
|
|
// kDebug() << "path:" << search << "=" << path;
|
|
|
|
// if we didn't find the theme specific for this application
|
|
// we'll use the main theme file
|
|
if (path.isEmpty()) {
|
|
search = "desktoptheme/" +
|
|
Plasma::Theme::defaultTheme()->themeName()
|
|
+ "/lancelot/theme.config";
|
|
path = KStandardDirs::locate( "data", search );
|
|
// kDebug() << "path:" << search << "=" << path;
|
|
}
|
|
|
|
// if the above fails, we are loading the default theme's
|
|
// file
|
|
if (path.isEmpty()) {
|
|
search = "desktoptheme/default/lancelot/theme.config";
|
|
path = KStandardDirs::locate( "data", search );
|
|
// kDebug() << "path:" << search << "=" << path;
|
|
}
|
|
|
|
// this doesn't really do anything useful
|
|
// TODO: remove later
|
|
if (path.isEmpty()) {
|
|
path = "lancelotrc";
|
|
}
|
|
|
|
confTheme = new KConfig(path);
|
|
}
|
|
|
|
void Global::Private::themeChanged()
|
|
{
|
|
createConfTheme();
|
|
loadAllGroups(true);
|
|
}
|
|
|
|
void Global::Private::loadAllGroups(bool clearFirst)
|
|
{
|
|
if (clearFirst) {
|
|
foreach(Group * group, groups) {
|
|
group->d->reset();
|
|
}
|
|
}
|
|
|
|
foreach(Group * group, groups) {
|
|
group->load(true);
|
|
}
|
|
}
|
|
|
|
Global::Global()
|
|
: d(new Private())
|
|
{
|
|
d->confMain = new KConfig("lancelotrc");
|
|
|
|
Plasma::Theme::defaultTheme()->setUseGlobalSettings(true);
|
|
d->createConfTheme();
|
|
|
|
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
|
|
d, SLOT(themeChanged()));
|
|
}
|
|
|
|
Global::~Global()
|
|
{
|
|
foreach (Group * group, d->groups) {
|
|
delete group;
|
|
}
|
|
delete d->confMain;
|
|
delete d->confTheme;
|
|
|
|
delete d;
|
|
}
|
|
|
|
KConfig * Global::theme() const
|
|
{
|
|
return d->confTheme;
|
|
}
|
|
|
|
KConfig * Global::config()
|
|
{
|
|
return d->confMain;
|
|
}
|
|
|
|
bool Global::groupExists(const QString & name) const
|
|
{
|
|
QString groupName = name;
|
|
if (groupName.isEmpty()) {
|
|
groupName = "Default";
|
|
}
|
|
|
|
return (!d->groups.contains(groupName))
|
|
|| theme()->groupList().contains(
|
|
"Group-" + groupName);
|
|
}
|
|
|
|
Group * Global::group(const QString & name)
|
|
{
|
|
QString groupName = name;
|
|
if (groupName.isEmpty()) {
|
|
groupName = "Default";
|
|
}
|
|
|
|
if (!d->groups.contains(groupName)) {
|
|
Group * group = new Group(groupName);
|
|
d->groups.insert(groupName, group);
|
|
group->load();
|
|
}
|
|
|
|
return d->groups[groupName];
|
|
}
|
|
|
|
Group * Global::defaultGroup()
|
|
{
|
|
return group("Default");
|
|
}
|
|
|
|
Group * Global::groupForObject(QObject * object)
|
|
{
|
|
foreach (Group * group, d->groups) {
|
|
if (group->contains(object)) {
|
|
return group;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void Global::setGroupForObject(QObject * object, Group * group) {
|
|
Group * oldGroup = groupForObject(object);
|
|
if (oldGroup == group) {
|
|
return;
|
|
}
|
|
|
|
if (oldGroup) {
|
|
oldGroup->remove(object);
|
|
}
|
|
|
|
if (group) {
|
|
group->add(object);
|
|
connect(object, SIGNAL(destroyed(QObject*)),
|
|
d, SLOT(objectDeleted(QObject*)));
|
|
}
|
|
}
|
|
|
|
void Global::setImmutability(const Plasma::ImmutabilityType immutable)
|
|
{
|
|
if (d->immutability == immutable) {
|
|
return;
|
|
}
|
|
|
|
d->immutability = immutable;
|
|
emit immutabilityChanged(immutable);
|
|
}
|
|
|
|
Plasma::ImmutabilityType Global::immutability() const
|
|
{
|
|
return d->immutability;
|
|
}
|
|
|
|
bool Global::config(const QString & group, const QString & field, bool defaultValue) const
|
|
{
|
|
KConfigGroup config(Global::self()->config(), group);
|
|
return config.readEntry(field, defaultValue);
|
|
}
|
|
|
|
int Global::config(const QString & group, const QString & field, int defaultValue) const
|
|
{
|
|
KConfigGroup config(Global::self()->config(), group);
|
|
return config.readEntry(field, defaultValue);
|
|
}
|
|
|
|
QString Global::config(const QString & group, const QString & field, const QString & defaultValue) const
|
|
{
|
|
KConfigGroup config(Global::self()->config(), group);
|
|
return config.readEntry(field, defaultValue);
|
|
}
|
|
|
|
|
|
} // namespace Lancelot
|
|
|