summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/themes/genericunix/qgenericunixthemes.cpp')
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp325
1 files changed, 325 insertions, 0 deletions
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
new file mode 100644
index 0000000000..a9f05f6084
--- /dev/null
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgenericunixthemes_p.h"
+#include "../../services/genericunix/qgenericunixservices_p.h"
+
+#include <QtGui/QPalette>
+#include <QtGui/QGuiApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QFile>
+#include <QtCore/QDebug>
+#include <QtCore/QSettings>
+#include <QtCore/QVariant>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGenericX11ThemeQKdeTheme
+ \brief QGenericX11Theme is a generic theme implementation for X11.
+ \since 5.0
+ \internal
+ \ingroup qpa
+*/
+
+// Helper to return the icon theme paths from XDG.
+QStringList QGenericUnixTheme::xdgIconThemePaths()
+{
+ QStringList paths;
+ // Add home directory first in search path
+ const QFileInfo homeIconDir(QDir::homePath() + QStringLiteral("/.icons"));
+ if (homeIconDir.isDir())
+ paths.prepend(homeIconDir.absoluteFilePath());
+
+ QString xdgDirString = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
+ if (xdgDirString.isEmpty())
+ xdgDirString = QLatin1String("/usr/local/share/:/usr/share/");
+ foreach (const QString &xdgDir, xdgDirString.split(QLatin1Char(':'))) {
+ const QFileInfo xdgIconsDir(xdgDir + QStringLiteral("/icons"));
+ if (xdgIconsDir.isDir())
+ paths.append(xdgIconsDir.absoluteFilePath());
+ }
+ return paths;
+}
+
+QVariant QGenericUnixTheme::themeHint(ThemeHint hint) const
+{
+ switch (hint) {
+ case QPlatformTheme::SystemIconFallbackThemeName:
+ return QVariant(QString(QStringLiteral("hicolor")));
+ case QPlatformTheme::IconThemeSearchPaths:
+ return xdgIconThemePaths();
+ case QPlatformTheme::StyleNames: {
+ QStringList styleNames;
+ styleNames << QStringLiteral("Plastique") << QStringLiteral("Windows");
+ return QVariant(styleNames);
+ }
+ break;
+ default:
+ break;
+ }
+ return QPlatformTheme::themeHint(hint);
+}
+
+// Reads the color from the KDE configuration, and store it in the
+// palette with the given color role if found.
+static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role,
+ const QSettings &kdeSettings, const QString &key)
+{
+ const QVariant value = kdeSettings.value(key);
+ if (!value.isValid())
+ return false;
+ const QStringList values = value.toStringList();
+ if (values.size() != 3)
+ return false;
+ pal->setBrush(role, QColor(values.at(0).toInt(), values.at(1).toInt(), values.at(2).toInt()));
+ return true;
+}
+
+// Reads the KDE system palette
+static inline bool readKdeSystemPalette(const QSettings &kdeSettings, QPalette *pal)
+{
+ // Setup KDE palette
+ return kdeColor(pal, QPalette::Button, kdeSettings, QStringLiteral("Colors:Button/BackgroundNormal"))
+ || kdeColor(pal, QPalette::Window, kdeSettings, QStringLiteral("Colors:Window/BackgroundNormal"))
+ || kdeColor(pal, QPalette::Text, kdeSettings, QStringLiteral("Colors:View/ForegroundNormal"))
+ || kdeColor(pal, QPalette::WindowText, kdeSettings, QStringLiteral("Colors:Window/ForegroundNormal"))
+ || kdeColor(pal, QPalette::Base, kdeSettings, QStringLiteral("Colors:View/BackgroundNormal"))
+ || kdeColor(pal, QPalette::Highlight, kdeSettings, QStringLiteral("Colors:Selection/BackgroundNormal"))
+ || kdeColor(pal, QPalette::HighlightedText, kdeSettings, QStringLiteral("Colors:Selection/ForegroundNormal"))
+ || kdeColor(pal, QPalette::AlternateBase, kdeSettings, QStringLiteral("Colors:View/BackgroundAlternate"))
+ || kdeColor(pal, QPalette::ButtonText, kdeSettings, QStringLiteral("Colors:Button/ForegroundNormal"))
+ || kdeColor(pal, QPalette::Link, kdeSettings, QStringLiteral("Colors:View/ForegroundLink"))
+ || kdeColor(pal, QPalette::LinkVisited, kdeSettings, QStringLiteral("Colors:View/ForegroundVisited"));
+}
+
+/*!
+ \class QKdeTheme
+ \brief QKdeTheme is a theme implementation for the KDE desktop (version 4 or higher).
+ \since 5.0
+ \internal
+ \ingroup qpa
+*/
+
+QKdeTheme::QKdeTheme(const QString &kdeHome, int kdeVersion) :
+ m_kdeHome(kdeHome), m_kdeVersion(kdeVersion),
+ m_toolButtonStyle(Qt::ToolButtonTextBesideIcon), m_toolBarIconSize(0)
+{
+ qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+ refresh();
+}
+
+void QKdeTheme::clearPalettes()
+{
+ qDeleteAll(m_palettes, m_palettes + NPalettes);
+ qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+}
+
+void QKdeTheme::refresh()
+{
+ clearPalettes();
+
+ m_toolButtonStyle = Qt::ToolButtonTextBesideIcon;
+ m_toolBarIconSize = 0;
+ m_styleNames.clear();
+ m_styleNames << QStringLiteral("Oxygen") << QStringLiteral("plastique") << QStringLiteral("windows");
+ m_iconFallbackThemeName = m_iconThemeName = QStringLiteral("oxygen");
+
+ // Read settings file.
+ const QString settingsFile = globalSettingsFile();
+ if (!QFileInfo(settingsFile).isReadable())
+ return;
+
+ const QSettings kdeSettings(settingsFile, QSettings::IniFormat);
+
+ QPalette systemPalette;
+ if (readKdeSystemPalette(kdeSettings, &systemPalette))
+ m_palettes[SystemPalette] = new QPalette(systemPalette);
+ //## TODO tooltip color
+
+ const QVariant styleValue = kdeSettings.value(QStringLiteral("widgetStyle"));
+ if (styleValue.isValid()) {
+ const QString style = styleValue.toString();
+ if (style != m_styleNames.front())
+ m_styleNames.push_front(style);
+ }
+
+ const QVariant themeValue = kdeSettings.value(QStringLiteral("Icons/Theme"));
+ if (themeValue.isValid())
+ m_iconThemeName = themeValue.toString();
+
+ const QVariant toolBarIconSizeValue = kdeSettings.value(QStringLiteral("ToolbarIcons/Size"));
+ if (toolBarIconSizeValue.isValid())
+ m_toolBarIconSize = toolBarIconSizeValue.toInt();
+
+ const QVariant toolbarStyleValue = kdeSettings.value(QStringLiteral("ToolButtonStyle"));
+ if (toolbarStyleValue.isValid()) {
+ const QString toolBarStyle = toolbarStyleValue.toString();
+ if (toolBarStyle == QStringLiteral("TextBesideIcon"))
+ m_toolButtonStyle = Qt::ToolButtonTextBesideIcon;
+ else if (toolBarStyle == QStringLiteral("TextOnly"))
+ m_toolButtonStyle = Qt::ToolButtonTextOnly;
+ else if (toolBarStyle == QStringLiteral("TextUnderIcon"))
+ m_toolButtonStyle = Qt::ToolButtonTextUnderIcon;
+ }
+}
+
+QString QKdeTheme::globalSettingsFile() const
+{
+ return m_kdeHome + QStringLiteral("/share/config/kdeglobals");
+}
+
+static QStringList kdeIconThemeSearchPaths(const QString &kdeHome)
+{
+ QStringList candidates = QStringList(kdeHome);
+ const QString kdeDirs = QFile::decodeName(qgetenv("KDEDIRS"));
+ if (!kdeDirs.isEmpty())
+ candidates.append(kdeDirs.split(QLatin1Char(':')));
+
+ QStringList paths = QGenericUnixTheme::xdgIconThemePaths();
+ const QString iconPath = QStringLiteral("/share/icons");
+ foreach (const QString &candidate, candidates) {
+ const QFileInfo fi(candidate + iconPath);
+ if (fi.isDir())
+ paths.append(fi.absoluteFilePath());
+ }
+ return paths;
+}
+
+QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+{
+ switch (hint) {
+ case QPlatformTheme::ToolButtonStyle:
+ return QVariant(m_toolButtonStyle);
+ case QPlatformTheme::ToolBarIconSize:
+ return QVariant(m_toolBarIconSize);
+ case QPlatformTheme::SystemIconThemeName:
+ return QVariant(m_iconThemeName);
+ case QPlatformTheme::SystemIconFallbackThemeName:
+ return QVariant(m_iconFallbackThemeName);
+ case QPlatformTheme::IconThemeSearchPaths:
+ return QVariant(kdeIconThemeSearchPaths(m_kdeHome));
+ case QPlatformTheme::StyleNames:
+ return QVariant(m_styleNames);
+ default:
+ break;
+ }
+ return QPlatformTheme::themeHint(hint);
+}
+
+QPlatformTheme *QKdeTheme::createKdeTheme()
+{
+ // Check for version >= 4 and determine home folder from environment,
+ // defaulting to ~/.kde<version>, ~/.kde
+ const QByteArray kdeVersionBA = qgetenv("KDE_SESSION_VERSION");
+ const int kdeVersion = kdeVersionBA.toInt();
+ if (kdeVersion < 4)
+ return 0;
+ const QString kdeHomePathVar = QString::fromLocal8Bit(qgetenv("KDEHOME"));
+ if (!kdeHomePathVar.isEmpty())
+ return new QKdeTheme(kdeHomePathVar, kdeVersion);
+
+ const QString kdeVersionHomePath = QDir::homePath() + QStringLiteral("/.kde") + QLatin1String(kdeVersionBA);
+ if (QFileInfo(kdeVersionHomePath).isDir())
+ return new QKdeTheme(kdeVersionHomePath, kdeVersion);
+
+ const QString kdeHomePath = QDir::homePath() + QStringLiteral("/.kde");
+ if (QFileInfo(kdeHomePath).isDir())
+ return new QKdeTheme(kdeHomePath, kdeVersion);
+
+ qWarning("%s: Unable to determine KDEHOME", Q_FUNC_INFO);
+ return 0;
+}
+
+/*!
+ \class QGnomeTheme
+ \brief QGnomeTheme is a theme implementation for the Gnome desktop.
+ \since 5.0
+ \internal
+ \ingroup qpa
+*/
+
+QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+{
+ switch (hint) {
+ case QPlatformTheme::SystemIconThemeName:
+ case QPlatformTheme::SystemIconFallbackThemeName:
+ return QVariant(QString(QStringLiteral("gnome")));
+ case QPlatformTheme::IconThemeSearchPaths:
+ return QVariant(QGenericUnixTheme::xdgIconThemePaths());
+ case QPlatformTheme::StyleNames: {
+ QStringList styleNames;
+ styleNames << QStringLiteral("GTK+") << QStringLiteral("cleanlooks") << QStringLiteral("windows");
+ return QVariant(styleNames);
+ }
+ default:
+ break;
+ }
+ return QPlatformTheme::themeHint(hint);
+}
+
+/*!
+ \brief Creates a UNIX theme according to the detected desktop environment.
+*/
+
+QPlatformTheme *QGenericUnixTheme::createUnixTheme()
+{
+ QPlatformTheme *result = 0;
+ if (QGuiApplication::desktopSettingsAware()) {
+ switch (QGenericUnixServices::desktopEnvironment()) {
+ case QGenericUnixServices::DE_UNKNOWN:
+ break;
+ case QGenericUnixServices::DE_KDE:
+ result = QKdeTheme::createKdeTheme();
+ break;
+ case QGenericUnixServices::DE_GNOME:
+ result = new QGnomeTheme;
+ break;
+ }
+ }
+ if (!result)
+ result = new QGenericUnixTheme;
+ return result;
+}
+
+QT_END_NAMESPACE