themePrivate instances are kept in statics

as a static pointer with refcount if "global" and internal refcounted hash if created with name
This commit is contained in:
Marco Martin 2013-03-11 22:26:15 +01:00
parent 3edbe10c8c
commit 0ca0934370
3 changed files with 111 additions and 23 deletions

View File

@ -24,6 +24,7 @@
#include <QFile>
#include <QFileInfo>
#include <kdirwatch.h>
#include <kglobalsettings.h>
#include <kwindoweffects.h>
@ -39,23 +40,49 @@ const char *ThemePrivate::systemColorsTheme = "internal-system-colors";
EffectWatcher *ThemePrivate::s_blurEffectWatcher = 0;
#endif
ThemePrivate::ThemePrivate(Theme *theme)
: colorScheme(QPalette::Active, KColorScheme::Window, KSharedConfigPtr(0)),
buttonColorScheme(QPalette::Active, KColorScheme::Button, KSharedConfigPtr(0)),
viewColorScheme(QPalette::Active, KColorScheme::View, KSharedConfigPtr(0)),
defaultWallpaperTheme(DEFAULT_WALLPAPER_THEME),
defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
pixmapCache(0),
cacheSize(0),
cachesToDiscard(NoCache),
locolor(false),
compositingActive(KWindowSystem::self()->compositingActive()),
blurActive(false),
isDefault(false),
useGlobal(true),
hasWallpapers(false)
ThemePrivate *ThemePrivate::globalTheme = 0;
int ThemePrivate::globalThemeRefCount = 0;
QHash<QString, ThemePrivate *> ThemePrivate::themes = QHash<QString, ThemePrivate*>();
QHash<QString, int> ThemePrivate::themesRefCount = QHash<QString, int>();
class ThemePrivateSingleton
{
public:
ThemePrivateSingleton()
{
self.isDefault = true;
//FIXME: if/when kconfig gets change notification, this will be unnecessary
KDirWatch::self()->addFile(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + ThemePrivate::themeRcFile);
QObject::connect(KDirWatch::self(), SIGNAL(created(QString)), &self, SLOT(settingsFileChanged(QString)));
QObject::connect(KDirWatch::self(), SIGNAL(dirty(QString)), &self, SLOT(settingsFileChanged(QString)));
}
ThemePrivate self;
};
Q_GLOBAL_STATIC(ThemePrivateSingleton, themePrivateSelf)
ThemePrivate::ThemePrivate(QObject *parent)
: QObject(parent),
colorScheme(QPalette::Active, KColorScheme::Window, KSharedConfigPtr(0)),
buttonColorScheme(QPalette::Active, KColorScheme::Button, KSharedConfigPtr(0)),
viewColorScheme(QPalette::Active, KColorScheme::View, KSharedConfigPtr(0)),
defaultWallpaperTheme(DEFAULT_WALLPAPER_THEME),
defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
pixmapCache(0),
cacheSize(0),
cachesToDiscard(NoCache),
locolor(false),
compositingActive(KWindowSystem::self()->compositingActive()),
blurActive(false),
isDefault(false),
useGlobal(true),
hasWallpapers(false)
{
ThemeConfig config;
cacheTheme = config.cacheTheme();
@ -87,6 +114,11 @@ ThemePrivate::~ThemePrivate()
delete pixmapCache;
}
ThemePrivate *ThemePrivate::self()
{
return &themePrivateSelf()->self;
}
KConfigGroup &ThemePrivate::config()
{
if (!cfg.isValid()) {

View File

@ -65,9 +65,11 @@ class ThemePrivate : public QObject
Q_OBJECT
public:
ThemePrivate(Theme *theme);
ThemePrivate(QObject *parent = 0);
~ThemePrivate();
static ThemePrivate *self();
KConfigGroup &config();
QString findInTheme(const QString &image, const QString &theme, bool cache = true);
@ -100,7 +102,10 @@ public:
#if HAVE_X11
static EffectWatcher *s_blurEffectWatcher;
#endif
static QHash<QString, ThemePrivate *>dAssociations;
static ThemePrivate *globalTheme;
static int globalThemeRefCount;
static QHash<QString, ThemePrivate *> themes;
static QHash<QString, int> themesRefCount;
QString themeName;
KPluginInfo pluginInfo;

View File

@ -74,8 +74,15 @@ Theme *Theme::defaultTheme()
Theme::Theme(QObject *parent)
: QObject(parent),
d(new ThemePrivate(this))
d(ThemePrivate::self())
{
if (!ThemePrivate::globalTheme) {
ThemePrivate::globalTheme = new ThemePrivate;
++ThemePrivate::globalThemeRefCount;
}
d = ThemePrivate::globalTheme;
d->settingsChanged();
if (QCoreApplication::instance()) {
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
@ -85,13 +92,20 @@ Theme::Theme(QObject *parent)
}
Theme::Theme(const QString &themeName, QObject *parent)
: QObject(parent),
d(new ThemePrivate(this))
: QObject(parent)
{
if (!ThemePrivate::themes.contains(themeName)) {
ThemePrivate::themes[themeName] = new ThemePrivate;
ThemePrivate::themesRefCount[themeName] = 0;
}
++ThemePrivate::themesRefCount[themeName];
d = ThemePrivate::themes[themeName];
// turn off caching so we don't accidently trigger unnecessary disk activity at this point
bool useCache = d->cacheTheme;
d->cacheTheme = false;
setThemeName(themeName);
d->setThemeName(themeName, true);
d->cacheTheme = useCache;
if (QCoreApplication::instance()) {
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
@ -111,11 +125,48 @@ Theme::~Theme()
}
d->onAppExitCleanup();
if (d == ThemePrivate::globalTheme) {
--ThemePrivate::globalThemeRefCount;
if (ThemePrivate::globalThemeRefCount == 0) {
delete ThemePrivate::globalTheme;
}
} else {
--ThemePrivate::themesRefCount[d->themeName];
if (ThemePrivate::themesRefCount[d->themeName] == 0) {
ThemePrivate *themePrivate = ThemePrivate::themes[d->themeName];
ThemePrivate::themes.remove(d->themeName);
ThemePrivate::themesRefCount.remove(d->themeName);
delete themePrivate;
}
}
delete d;
}
void Theme::setThemeName(const QString &themeName)
{
if (d->themeName == themeName) {
return;
}
if (d != ThemePrivate::globalTheme) {
--ThemePrivate::themesRefCount[d->themeName];
if (ThemePrivate::themesRefCount[d->themeName] == 0) {
ThemePrivate *themePrivate = ThemePrivate::themes[d->themeName];
ThemePrivate::themes.remove(d->themeName);
ThemePrivate::themesRefCount.remove(d->themeName);
delete themePrivate;
}
}
if (!ThemePrivate::themes.contains(themeName)) {
ThemePrivate::themes[themeName] = new ThemePrivate;
ThemePrivate::themesRefCount[themeName] = 0;
}
++ThemePrivate::themesRefCount[themeName];
d = ThemePrivate::themes[themeName];
d->setThemeName(themeName, true);
}