summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Bache-Wiig <jbache@trolltech.com>2009-08-10 15:15:03 (GMT)
committerJens Bache-Wiig <jbache@trolltech.com>2009-08-10 15:39:20 (GMT)
commit13a31fe82845f8b1f4d86919080d3b2a87c4d061 (patch)
tree6ec3b5c3bc0811abca5fc84d1aa094be30d4e8c4
parent35ef002453cbe9841e23a7d33064a51dbe99fb06 (diff)
downloadQt-13a31fe82845f8b1f4d86919080d3b2a87c4d061.zip
Qt-13a31fe82845f8b1f4d86919080d3b2a87c4d061.tar.gz
Qt-13a31fe82845f8b1f4d86919080d3b2a87c4d061.tar.bz2
Introducing icon theme support
Added some static functions to QIcon to support desktop themes based on the freedesktop spec. It is not intended to replace KIcon and the intention is to use it when available to share icon cache between applications. Applications currently using icon themes are Assistant, Designer and the textedit demo. Reviewed-by: ogoffart
-rw-r--r--demos/textedit/textedit.cpp65
-rw-r--r--doc/src/snippets/code/src_gui_image_qicon.cpp9
-rw-r--r--src/gui/gui.pro1
-rw-r--r--src/gui/image/image.pri3
-rw-r--r--src/gui/image/qicon.cpp226
-rw-r--r--src/gui/image/qicon.h10
-rw-r--r--src/gui/image/qicon_p.h138
-rw-r--r--src/gui/image/qiconloader.cpp599
-rw-r--r--src/gui/image/qiconloader_p.h185
-rw-r--r--src/gui/kernel/qapplication_x11.cpp4
-rw-r--r--src/gui/styles/gtksymbols.cpp8
-rw-r--r--src/gui/styles/gtksymbols_p.h1
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp563
-rw-r--r--src/gui/styles/qcleanlooksstyle_p.h2
-rw-r--r--src/gui/styles/qcommonstyle.cpp770
-rw-r--r--src/gui/styles/qcommonstyle_p.h13
-rw-r--r--src/gui/styles/qgtkstyle.cpp96
-rw-r--r--src/gui/styles/qgtkstyle.h4
-rw-r--r--tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.pngbin0 -> 897 bytes
-rw-r--r--tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.pngbin0 -> 1411 bytes
-rw-r--r--tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.pngbin0 -> 2399 bytes
-rw-r--r--tests/auto/qicon/icons/testtheme/index.theme492
-rw-r--r--tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg425
-rw-r--r--tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.pngbin0 -> 796 bytes
-rw-r--r--tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.pngbin0 -> 897 bytes
-rw-r--r--tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.pngbin0 -> 924 bytes
-rw-r--r--tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.pngbin0 -> 1411 bytes
-rw-r--r--tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.pngbin0 -> 1897 bytes
-rw-r--r--tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.pngbin0 -> 2399 bytes
-rw-r--r--tests/auto/qicon/icons/themeparent/index.theme492
-rw-r--r--tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg389
-rw-r--r--tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg425
-rw-r--r--tests/auto/qicon/tst_qicon.cpp67
-rw-r--r--tools/assistant/compat/mainwindow.cpp10
-rw-r--r--tools/assistant/tools/assistant/mainwindow.cpp13
-rw-r--r--tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp5
-rw-r--r--tools/designer/src/components/formeditor/formwindowmanager.cpp22
-rw-r--r--tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp3
-rw-r--r--tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp4
-rw-r--r--tools/designer/src/designer/qdesigner_actions.cpp7
-rw-r--r--tools/designer/src/lib/shared/actioneditor.cpp18
-rw-r--r--tools/designer/src/lib/shared/qtresourceview.cpp10
42 files changed, 3784 insertions, 1295 deletions
diff --git a/demos/textedit/textedit.cpp b/demos/textedit/textedit.cpp
index d1e12bb..31b419a 100644
--- a/demos/textedit/textedit.cpp
+++ b/demos/textedit/textedit.cpp
@@ -158,14 +158,16 @@ void TextEdit::setupFileActions()
QAction *a;
- a = new QAction(QIcon(rsrcPath + "/filenew.png"), tr("&New"), this);
+ QIcon newIcon = QIcon::fromTheme("document-new", QIcon(rsrcPath + "/filenew.png"));
+ a = new QAction( newIcon, tr("&New"), this);
a->setPriority(QAction::LowPriority);
a->setShortcut(QKeySequence::New);
connect(a, SIGNAL(triggered()), this, SLOT(fileNew()));
tb->addAction(a);
menu->addAction(a);
- a = new QAction(QIcon(rsrcPath + "/fileopen.png"), tr("&Open..."), this);
+ a = new QAction(QIcon::fromTheme("document-open", QIcon(rsrcPath + "/fileopen.png")),
+ tr("&Open..."), this);
a->setShortcut(QKeySequence::Open);
connect(a, SIGNAL(triggered()), this, SLOT(fileOpen()));
tb->addAction(a);
@@ -173,7 +175,8 @@ void TextEdit::setupFileActions()
menu->addSeparator();
- actionSave = a = new QAction(QIcon(rsrcPath + "/filesave.png"), tr("&Save"), this);
+ actionSave = a = new QAction(QIcon::fromTheme("document-save", QIcon(rsrcPath + "/filesave.png")),
+ tr("&Save"), this);
a->setShortcut(QKeySequence::Save);
connect(a, SIGNAL(triggered()), this, SLOT(fileSave()));
a->setEnabled(false);
@@ -187,17 +190,21 @@ void TextEdit::setupFileActions()
menu->addSeparator();
#ifndef QT_NO_PRINTER
- a = new QAction(QIcon(rsrcPath + "/fileprint.png"), tr("&Print..."), this);
+ a = new QAction(QIcon::fromTheme("document-print", QIcon(rsrcPath + "/fileprint.png")),
+ tr("&Print..."), this);
+ a->setPriority(QAction::LowPriority);
a->setShortcut(QKeySequence::Print);
connect(a, SIGNAL(triggered()), this, SLOT(filePrint()));
tb->addAction(a);
menu->addAction(a);
- a = new QAction(QIcon(rsrcPath + "/fileprint.png"), tr("Print Preview..."), this);
+ a = new QAction(QIcon::fromTheme("fileprint", QIcon(rsrcPath + "/fileprint.png")),
+ tr("Print Preview..."), this);
connect(a, SIGNAL(triggered()), this, SLOT(filePrintPreview()));
menu->addAction(a);
- a = new QAction(QIcon(rsrcPath + "/exportpdf.png"), tr("&Export PDF..."), this);
+ a = new QAction(QIcon::fromTheme("exportpdf", QIcon(rsrcPath + "/exportpdf.png")),
+ tr("&Export PDF..."), this);
a->setPriority(QAction::LowPriority);
a->setShortcut(Qt::CTRL + Qt::Key_D);
connect(a, SIGNAL(triggered()), this, SLOT(filePrintPdf()));
@@ -218,32 +225,36 @@ void TextEdit::setupEditActions()
QToolBar *tb = new QToolBar(this);
tb->setWindowTitle(tr("Edit Actions"));
addToolBar(tb);
-
QMenu *menu = new QMenu(tr("&Edit"), this);
menuBar()->addMenu(menu);
QAction *a;
- a = actionUndo = new QAction(QIcon(rsrcPath + "/editundo.png"), tr("&Undo"), this);
+ a = actionUndo = new QAction(QIcon::fromTheme("edit-undo", QIcon(rsrcPath + "/editundo.png")),
+ tr("&Undo"), this);
a->setShortcut(QKeySequence::Undo);
tb->addAction(a);
menu->addAction(a);
- a = actionRedo = new QAction(QIcon(rsrcPath + "/editredo.png"), tr("&Redo"), this);
+ a = actionRedo = new QAction(QIcon::fromTheme("edit-redo", QIcon(rsrcPath + "/editredo.png")),
+ tr("&Redo"), this);
a->setPriority(QAction::LowPriority);
a->setShortcut(QKeySequence::Redo);
tb->addAction(a);
menu->addAction(a);
menu->addSeparator();
- a = actionCut = new QAction(QIcon(rsrcPath + "/editcut.png"), tr("Cu&t"), this);
+ a = actionCut = new QAction(QIcon::fromTheme("edit-cut", QIcon(rsrcPath + "/editcut.png")),
+ tr("Cu&t"), this);
a->setPriority(QAction::LowPriority);
a->setShortcut(QKeySequence::Cut);
tb->addAction(a);
menu->addAction(a);
- a = actionCopy = new QAction(QIcon(rsrcPath + "/editcopy.png"), tr("&Copy"), this);
+ a = actionCopy = new QAction(QIcon::fromTheme("edit-copy", QIcon(rsrcPath + "/editcopy.png")),
+ tr("&Copy"), this);
a->setPriority(QAction::LowPriority);
a->setShortcut(QKeySequence::Copy);
tb->addAction(a);
menu->addAction(a);
- a = actionPaste = new QAction(QIcon(rsrcPath + "/editpaste.png"), tr("&Paste"), this);
+ a = actionPaste = new QAction(QIcon::fromTheme("edit-paste", QIcon(rsrcPath + "/editpaste.png")),
+ tr("&Paste"), this);
a->setPriority(QAction::LowPriority);
a->setShortcut(QKeySequence::Paste);
tb->addAction(a);
@@ -260,10 +271,11 @@ void TextEdit::setupTextActions()
QMenu *menu = new QMenu(tr("F&ormat"), this);
menuBar()->addMenu(menu);
- actionTextBold = new QAction(QIcon(rsrcPath + "/textbold.png"), tr("&Bold"), this);
- actionTextBold->setPriority(QAction::LowPriority);
+ actionTextBold = new QAction(QIcon::fromTheme("format-text-bold", QIcon(rsrcPath + "/textbold.png")),
+ tr("&Bold"), this);
actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B);
- QFont bold;
+ actionTextBold->setPriority(QAction::LowPriority);
+ QFont bold;
bold.setBold(true);
actionTextBold->setFont(bold);
connect(actionTextBold, SIGNAL(triggered()), this, SLOT(textBold()));
@@ -271,7 +283,8 @@ void TextEdit::setupTextActions()
menu->addAction(actionTextBold);
actionTextBold->setCheckable(true);
- actionTextItalic = new QAction(QIcon(rsrcPath + "/textitalic.png"), tr("&Italic"), this);
+ actionTextItalic = new QAction(QIcon::fromTheme("format-text-italic", QIcon(rsrcPath + "/textitalic.png")),
+ tr("&Italic"), this);
actionTextItalic->setPriority(QAction::LowPriority);
actionTextItalic->setShortcut(Qt::CTRL + Qt::Key_I);
QFont italic;
@@ -282,9 +295,10 @@ void TextEdit::setupTextActions()
menu->addAction(actionTextItalic);
actionTextItalic->setCheckable(true);
- actionTextUnderline = new QAction(QIcon(rsrcPath + "/textunder.png"), tr("&Underline"), this);
- actionTextUnderline->setPriority(QAction::LowPriority);
+ actionTextUnderline = new QAction(QIcon::fromTheme("format-text-underline", QIcon(rsrcPath + "/textunder.png")),
+ tr("&Underline"), this);
actionTextUnderline->setShortcut(Qt::CTRL + Qt::Key_U);
+ actionTextUnderline->setPriority(QAction::LowPriority);
QFont underline;
underline.setUnderline(true);
actionTextUnderline->setFont(underline);
@@ -300,15 +314,16 @@ void TextEdit::setupTextActions()
// Make sure the alignLeft is always left of the alignRight
if (QApplication::isLeftToRight()) {
- actionAlignLeft = new QAction(QIcon(rsrcPath + "/textleft.png"), tr("&Left"), grp);
- actionAlignCenter = new QAction(QIcon(rsrcPath + "/textcenter.png"), tr("C&enter"), grp);
- actionAlignRight = new QAction(QIcon(rsrcPath + "/textright.png"), tr("&Right"), grp);
+ actionAlignLeft = new QAction(QIcon::fromTheme("format-justify-left", QIcon(rsrcPath + "/textleft.png")),
+ tr("&Left"), grp);
+ actionAlignCenter = new QAction(QIcon::fromTheme("format-justify-center", QIcon(rsrcPath + "/textcenter.png")), tr("C&enter"), grp);
+ actionAlignRight = new QAction(QIcon::fromTheme("format-justify-right", QIcon(rsrcPath + "/textright.png")), tr("&Right"), grp);
} else {
- actionAlignRight = new QAction(QIcon(rsrcPath + "/textright.png"), tr("&Right"), grp);
- actionAlignCenter = new QAction(QIcon(rsrcPath + "/textcenter.png"), tr("C&enter"), grp);
- actionAlignLeft = new QAction(QIcon(rsrcPath + "/textleft.png"), tr("&Left"), grp);
+ actionAlignRight = new QAction(QIcon::fromTheme("format-justify-right", QIcon(rsrcPath + "/textright.png")), tr("&Right"), grp);
+ actionAlignCenter = new QAction(QIcon::fromTheme("format-justify-center", QIcon(rsrcPath + "/textcenter.png")), tr("C&enter"), grp);
+ actionAlignLeft = new QAction(QIcon::fromTheme("format-justify-left", QIcon(rsrcPath + "/textleft.png")), tr("&Left"), grp);
}
- actionAlignJustify = new QAction(QIcon(rsrcPath + "/textjustify.png"), tr("&Justify"), grp);
+ actionAlignJustify = new QAction(QIcon::fromTheme("format-justify-fill", QIcon(rsrcPath + "/textjustify.png")), tr("&Justify"), grp);
actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L);
actionAlignLeft->setCheckable(true);
diff --git a/doc/src/snippets/code/src_gui_image_qicon.cpp b/doc/src/snippets/code/src_gui_image_qicon.cpp
index 2b7c893..455fd84 100644
--- a/doc/src/snippets/code/src_gui_image_qicon.cpp
+++ b/doc/src/snippets/code/src_gui_image_qicon.cpp
@@ -20,3 +20,12 @@ void MyWidget::drawIcon(QPainter *painter, QPoint pos)
painter->drawPixmap(pos, pixmap);
}
//! [2]
+
+//! [3]
+ QIcon undoicon = QIcon::fromTheme("edit-undo");
+//! [3]
+
+//! [4]
+ QIcon undoicon = QIcon::fromTheme("edit-undo", QIcon(":/undo.png"));
+//! [4]
+
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index b77bfdc..a49d680 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -46,4 +46,3 @@ contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri)
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist
DEFINES += Q_INTERNAL_QAPP_SRC
-
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index b9c36dc..baf2125 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -6,6 +6,8 @@
HEADERS += \
image/qbitmap.h \
image/qicon.h \
+ image/qicon_p.h \
+ image/qiconloader_p.h \
image/qiconengine.h \
image/qiconengineplugin.h \
image/qimage.h \
@@ -32,6 +34,7 @@ HEADERS += \
SOURCES += \
image/qbitmap.cpp \
image/qicon.cpp \
+ image/qiconloader.cpp \
image/qimage.cpp \
image/qimageiohandler.cpp \
image/qimagereader.cpp \
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index fa407c7..7a43514 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -40,9 +40,11 @@
****************************************************************************/
#include "qicon.h"
+#include "qicon_p.h"
#include "qiconengine.h"
#include "qiconengineplugin.h"
#include "private/qfactoryloader_p.h"
+#include "private/qiconloader_p.h"
#include "qapplication.h"
#include "qstyleoption.h"
#include "qpainter.h"
@@ -50,6 +52,7 @@
#include "qstyle.h"
#include "qpixmapcache.h"
#include "qvariant.h"
+#include "qcache.h"
#include "qdebug.h"
#ifdef Q_WS_MAC
@@ -57,6 +60,11 @@
#include <private/qt_cocoa_helpers_mac_p.h>
#endif
+#ifdef Q_WS_X11
+#include "private/qt_x11_p.h"
+#include "private/qkde_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -94,73 +102,14 @@ QT_BEGIN_NAMESPACE
static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
-class QIconPrivate
-{
-public:
- QIconPrivate(): engine(0), ref(1), serialNum(serialNumCounter.fetchAndAddRelaxed(1)), detach_no(0), engine_version(2), v1RefCount(0) {}
-
- ~QIconPrivate() {
- if (engine_version == 1) {
- if (!v1RefCount->deref()) {
- delete engine;
- delete v1RefCount;
- }
- } else if (engine_version == 2) {
- delete engine;
- }
- }
-
- QIconEngine *engine;
-
- QAtomicInt ref;
- int serialNum;
- int detach_no;
- int engine_version;
-
- QAtomicInt *v1RefCount;
-};
-
-
-struct QPixmapIconEngineEntry
+QIconPrivate::QIconPrivate()
+ : engine(0), ref(1),
+ serialNum(serialNumCounter.fetchAndAddRelaxed(1)),
+ detach_no(0),
+ engine_version(2),
+ v1RefCount(0)
{
- QPixmapIconEngineEntry():mode(QIcon::Normal), state(QIcon::Off){}
- QPixmapIconEngineEntry(const QPixmap &pm, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
- :pixmap(pm), size(pm.size()), mode(m), state(s){}
- QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
- :fileName(file), size(sz), mode(m), state(s){}
- QPixmap pixmap;
- QString fileName;
- QSize size;
- QIcon::Mode mode;
- QIcon::State state;
- bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); }
-};
-
-class QPixmapIconEngine : public QIconEngineV2 {
-public:
- QPixmapIconEngine();
- QPixmapIconEngine(const QPixmapIconEngine &);
- ~QPixmapIconEngine();
- void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly);
- QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
- void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state);
- void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state);
-
- // v2 functions
- QString key() const;
- QIconEngineV2 *clone() const;
- bool read(QDataStream &in);
- bool write(QDataStream &out) const;
- void virtual_hook(int id, void *data);
-
-private:
- QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QVector<QPixmapIconEngineEntry> pixmaps;
-
- friend QDataStream &operator<<(QDataStream &s, const QIcon &icon);
-};
+}
QPixmapIconEngine::QPixmapIconEngine()
{
@@ -918,6 +867,146 @@ QList<QSize> QIcon::availableSizes(Mode mode, State state) const
return engine->availableSizes(mode, state);
}
+/*!
+ \since 4.6
+
+ Sets the search paths for icon themes.
+ \sa themeSearchPaths(), fromTheme()
+*/
+void QIcon::setThemeSearchPaths(const QStringList &paths)
+{
+ QIconLoader::instance()->setThemeSearchPath(paths);
+}
+
+/*!
+ \since 4.6
+
+ Returns the search paths for icon themes.
+
+ The default value will depend on the platform:
+
+ On X11, the search path will use the XDG_DATA_DIRS environment
+ variable if available.
+
+ On Windows the search path defaults to [Application Directory]/icons
+
+ On Mac the default search path will search in the
+ [Contents/Resources/icons] part of the application bundle.
+
+ \sa setThemeSearchPaths(), fromName()
+*/
+QStringList QIcon::themeSearchPaths()
+{
+ return QIconLoader::instance()->themeSearchPaths();
+}
+
+/*!
+ \since 4.6
+
+ Sets the current icon theme.
+
+ The name should correspond to a directory name in the
+ current \ themeSearchPath() containing an index.theme
+ file describing it's contents..
+
+*/
+void QIcon::setThemeName(const QString &path)
+{
+ QIconLoader::instance()->setThemeName(path);
+}
+
+/*!
+ \since 4.6
+
+ Returns the name of the current icon theme.
+
+ On X11, the current icon theme depends on your desktop
+ settings. On other platforms it is not set by default.
+
+ \sa themeSearchPaths(), themeIcon(), fromTheme(), hasThemeIcon()
+*/
+QString QIcon::themeName()
+{
+ return QIconLoader::instance()->themeName();
+}
+
+/*!
+ \since 4.6
+
+ Returns the QIcon corresponding to \a name in the current
+ icon theme. If no such icon is found in the current theme
+ \a fallback is return instead.
+
+ To use an icon theme on Windows or Mac, you will need to
+ bundle a compliant theme with your application and make sure
+ it is located in your themeSarchPaths.
+
+ The lastest version of the freedesktop icon specification and naming
+ spesification can be obtained here:
+ http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
+ http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
+
+ To fetch an icon from the current icon theme:
+
+ \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 3
+
+ Or if you want to provide a guaranteed fallback for platforms that
+ do not support theme icons, you can use the second argument:
+
+ \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 4
+
+ \note By default, only X11 will support themed icons. In order to
+ use themed icons on Mac and Windows, you will have to bundle a
+ compliant theme in one of your themeSearchPaths() and set the
+ appropriate themeName().
+
+ \sa themeName(), themeSearchPaths()
+*/
+QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
+{
+
+ static QCache <QString, QIcon> iconCache;
+
+ QIcon icon;
+
+#ifdef Q_WS_X11
+ if (X11->desktopEnvironment == DE_KDE) {
+ icon = QKde::kdeIcon(name);
+ if (!icon.isNull())
+ return icon;
+ }
+#endif
+
+ if (iconCache.contains(name)) {
+ icon = *iconCache.object(name);
+ } else {
+ QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name));
+ iconCache.insert(name, cachedIcon);
+ icon = *cachedIcon;
+ }
+
+ if (icon.availableSizes().isEmpty())
+ return fallback;
+
+ return icon;
+}
+
+/*!
+ \since 4.6
+
+ Returns true if there is an icon available for a \a name in the current
+ icon theme, otherwise returns false.
+
+ \sa themeSearchPaths(), fromTheme()
+*/
+bool QIcon::hasThemeIcon(const QString &name)
+{
+ QIcon icon = fromTheme(name);
+
+ return !icon.isNull();
+}
+
+
/*****************************************************************************
QIcon stream functions
*****************************************************************************/
@@ -989,6 +1078,11 @@ QDataStream &operator>>(QDataStream &s, QIcon &icon)
QIconEngineV2 *engine = new QPixmapIconEngine;
icon.d->engine = engine;
engine->read(s);
+ } else if (key == QLatin1String("QIconLoaderEngine")) {
+ icon.d = new QIconPrivate;
+ QIconEngineV2 *engine = new QIconLoaderEngine();
+ icon.d->engine = engine;
+ engine->read(s);
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
} else if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(key))) {
if (QIconEngineV2 *engine= factory->create()) {
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index c318e14..2a71717 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -97,6 +97,16 @@ public:
QList<QSize> availableSizes(Mode mode = Normal, State state = Off) const;
+ static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon());
+ static bool hasThemeIcon(const QString &name);
+
+ static QStringList themeSearchPaths();
+ static void setThemeSearchPaths(const QStringList &searchpath);
+
+ static QString themeName();
+ static void setThemeName(const QString &path);
+
+
#ifdef QT3_SUPPORT
enum Size { Small, Large, Automatic = Small };
static QT3_SUPPORT void setPixmapSize(Size which, const QSize &size);
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
new file mode 100644
index 0000000..ccac4c3
--- /dev/null
+++ b/src/gui/image/qicon_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QICON_P_H
+#define QICON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qlist.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qicon.h>
+#include <QtGui/qiconengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIconPrivate
+{
+public:
+ QIconPrivate();
+
+ ~QIconPrivate() {
+ if (engine_version == 1) {
+ if (!v1RefCount->deref()) {
+ delete engine;
+ delete v1RefCount;
+ }
+ } else if (engine_version == 2) {
+ delete engine;
+ }
+ }
+
+ QIconEngine *engine;
+
+ QAtomicInt ref;
+ int serialNum;
+ int detach_no;
+ int engine_version;
+
+ QAtomicInt *v1RefCount;
+};
+
+
+struct QPixmapIconEngineEntry
+{
+ QPixmapIconEngineEntry():mode(QIcon::Normal), state(QIcon::Off){}
+ QPixmapIconEngineEntry(const QPixmap &pm, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
+ :pixmap(pm), size(pm.size()), mode(m), state(s){}
+ QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
+ :fileName(file), size(sz), mode(m), state(s){}
+ QPixmap pixmap;
+ QString fileName;
+ QSize size;
+ QIcon::Mode mode;
+ QIcon::State state;
+ bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); }
+};
+
+
+
+class QPixmapIconEngine : public QIconEngineV2 {
+public:
+ QPixmapIconEngine();
+ QPixmapIconEngine(const QPixmapIconEngine &);
+ ~QPixmapIconEngine();
+ void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly);
+ QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state);
+ void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state);
+
+ // v2 functions
+ QString key() const;
+ QIconEngineV2 *clone() const;
+ bool read(QDataStream &in);
+ bool write(QDataStream &out) const;
+ void virtual_hook(int id, void *data);
+
+private:
+ QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QVector<QPixmapIconEngineEntry> pixmaps;
+
+ friend QDataStream &operator<<(QDataStream &s, const QIcon &icon);
+ friend class QIconThemeEngine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QICON_P_H
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
new file mode 100644
index 0000000..6bf8d3b
--- /dev/null
+++ b/src/gui/image/qiconloader.cpp
@@ -0,0 +1,599 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qiconloader_p.h>
+
+#include <private/qapplication_p.h>
+#include <private/qicon_p.h>
+#include <private/qkde_p.h>
+
+#include <QtGui/QIconEnginePlugin>
+#include <QtGui/QPixmapCache>
+#include <QtGui/QIconEngine>
+#include <QtGui/QStyleOption>
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtCore/QDir>
+#include <QtCore/QSettings>
+
+#ifdef Q_WS_MAC
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+#ifdef Q_WS_X11
+#include <private/qt_x11_p.h>
+#include <private/gtksymbols_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance)
+
+static QString systemThemeName()
+{
+ QString result;
+#ifdef Q_WS_X11
+ if (X11->desktopEnvironment == DE_GNOME) {
+ result = QGtk::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"),
+ QLatin1String("gnome"));
+ } else if (X11->desktopEnvironment == DE_KDE) {
+ QString kdeDefault = X11->desktopVersion >= 4 ?
+ QString::fromLatin1("oxygen") :
+ QString::fromLatin1("crystalsvg");
+
+ QSettings settings(QKde::kdeHome() +
+ QLatin1String("/share/config/kdeglobals"),
+ QSettings::IniFormat);
+
+ settings.beginGroup(QLatin1String("Icons"));
+
+ result = settings.value(QLatin1String("Theme"), kdeDefault).toString();
+ }
+#endif
+ return result;
+}
+
+static QString fallbackTheme()
+{
+ QString defaultTheme = systemThemeName();
+ if (defaultTheme.isEmpty())
+ defaultTheme = QLatin1String("hicolor");
+ return defaultTheme;
+}
+
+QIconLoader::QIconLoader() :
+ m_themeKey(1), m_supportsSvg(false)
+{
+ m_systemTheme = systemThemeName();
+
+ QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid,
+ QLatin1String("/iconengines"),
+ Qt::CaseInsensitive);
+ if (iconFactoryLoader.keys().contains(QLatin1String("svg")))
+ m_supportsSvg = true;
+}
+
+QIconLoader *QIconLoader::instance()
+{
+ return iconLoaderInstance();
+}
+
+// Queries the system theme and invalidates existing
+// icons if the theme has changed.
+void QIconLoader::updateSystemTheme()
+{
+ // Only change if this is not explicitly set by the user
+ if (m_userTheme.isEmpty()) {
+ QString theme = systemThemeName();
+ if (theme != m_systemTheme) {
+ m_systemTheme = theme;
+ invalidateKey();
+ }
+ }
+}
+
+void QIconLoader::setThemeName(const QString &themeName)
+{
+ m_userTheme = themeName;
+ invalidateKey();
+}
+
+void QIconLoader::setThemeSearchPath(const QStringList &searchPaths)
+{
+ m_iconDirs = searchPaths;
+ themeList.clear();
+ invalidateKey();
+}
+
+QStringList QIconLoader::themeSearchPaths() const
+{
+ if (m_iconDirs.isEmpty()) {
+
+#if defined(Q_WS_X11)
+
+ QString xdgDirString = QFile::decodeName(getenv("XDG_DATA_DIRS"));
+ if (xdgDirString.isEmpty())
+ xdgDirString = QLatin1String("/usr/local/share/:/usr/share/");
+
+ QStringList xdgDirs = xdgDirString.split(QLatin1Char(':'));
+
+ for (int i = 0 ; i < xdgDirs.size() ; ++i) {
+ QDir dir(xdgDirs[i]);
+ if (dir.exists())
+ m_iconDirs.append(dir.path() +
+ QLatin1String("/icons"));
+ }
+
+ if (X11->desktopEnvironment == DE_KDE) {
+
+ m_iconDirs << QLatin1Char(':') +
+ QKde::kdeHome() +
+ QLatin1String("/share/icons");
+ QStringList kdeDirs =
+ QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':'));
+
+ for (int i = 0 ; i< kdeDirs.count() ; ++i) {
+ QDir dir(QLatin1Char(':') + kdeDirs.at(i) +
+ QLatin1String("/share/icons"));
+ if (dir.exists())
+ m_iconDirs.append(dir.path());
+ }
+ }
+
+ // Add home directory first in search path
+ QDir homeDir(QDir::homePath() + QLatin1String("/.icons"));
+ if (homeDir.exists())
+ m_iconDirs.prepend(homeDir.path());
+
+#elif defined(Q_WS_WIN)
+ m_iconDirs.append(qApp->applicationDirPath() +
+ QLatin1String("/icons"));
+#elif defined(Q_WS_MAC)
+ m_iconDirs.append(qApp->applicationDirPath() +
+ QLatin1String("/../Resources/icons"));
+#endif
+ }
+ return m_iconDirs;
+}
+
+QIconTheme::QIconTheme(const QString &themeName)
+ : m_valid(false)
+{
+ QFile themeIndex;
+
+ QList <QIconDirInfo> keyList;
+ QStringList iconDirs = QIcon::themeSearchPaths();
+ for ( int i = 0 ; i < iconDirs.size() ; ++i) {
+ QDir iconDir(iconDirs[i]);
+ QString themeDir = iconDir.path() + QLatin1Char('/') + themeName;
+ themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
+ if (themeIndex.exists()) {
+ m_contentDir = themeDir;
+ m_valid = true;
+ break;
+ }
+ }
+
+ if (themeIndex.exists()) {
+ const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
+ QStringListIterator keyIterator(indexReader.allKeys());
+ while (keyIterator.hasNext()) {
+
+ const QString key = keyIterator.next();
+ if (key.endsWith(QLatin1String("/Size"))) {
+ // Note the QSettings ini-format does not accept
+ // slashes in key names, hence we have to cheat
+ if (int size = indexReader.value(key).toInt()) {
+ QString directoryKey = key.left(key.size() - 5);
+ QIconDirInfo dirInfo(directoryKey);
+ dirInfo.size = size;
+ QString type = indexReader.value(directoryKey +
+ QLatin1String("/Type")
+ ).toString();
+
+ if (type == QLatin1String("Fixed"))
+ dirInfo.type = QIconDirInfo::Fixed;
+ else if (type == QLatin1String("Scalable"))
+ dirInfo.type = QIconDirInfo::Scalable;
+ else
+ dirInfo.type = QIconDirInfo::Threshold;
+
+ dirInfo.threshold = indexReader.value(directoryKey +
+ QLatin1String("/Threshold"),
+ 2).toInt();
+
+ dirInfo.minSize = indexReader.value(directoryKey +
+ QLatin1String("/MinSize"),
+ size).toInt();
+
+ dirInfo.maxSize = indexReader.value(directoryKey +
+ QLatin1String("/MaxSize"),
+ size).toInt();
+ m_keyList.append(dirInfo);
+ }
+ }
+ }
+
+ // Parent themes provide fallbacks for missing icons
+ m_parents = indexReader.value(
+ QLatin1String("Icon Theme/Inherits")).toStringList();
+
+ // Ensure a default platform fallback for all themes
+ if (m_parents.isEmpty())
+ m_parents.append(fallbackTheme());
+
+ // Ensure that all themes fall back to hicolor
+ if (!m_parents.isEmpty())
+ m_parents.append(QLatin1String("hicolor"));
+ }
+}
+
+QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
+ const QString &iconName,
+ QStringList &visited) const
+{
+ QThemeIconEntries entries;
+ Q_ASSERT(!themeName.isEmpty());
+
+ QPixmap pixmap;
+
+ // Used to protect against potential recursions
+ visited << themeName;
+
+ QIconTheme theme = themeList.value(themeName);
+ if (!theme.isValid()) {
+ theme = QIconTheme(themeName);
+ if (!theme.isValid())
+ theme = fallbackTheme();
+
+ themeList.insert(themeName, theme);
+ }
+
+ QString contentDir = theme.contentDir() + QLatin1Char('/');
+ QList<QIconDirInfo> subDirs = theme.keyList();
+
+ const QString svgext(QLatin1String(".svg"));
+ const QString pngext(QLatin1String(".png"));
+
+ // Add all relevant files
+ for (int i = 0; i < subDirs.size() ; ++i) {
+ const QIconDirInfo &dirInfo = subDirs.at(i);
+ QString subdir = dirInfo.path;
+ QDir currentDir(contentDir + subdir);
+
+ if (dirInfo.type == QIconDirInfo::Scalable && m_supportsSvg &&
+ currentDir.exists(iconName + svgext)) {
+ ScalableEntry *iconEntry = new ScalableEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + svgext);
+ entries.append(iconEntry);
+
+ } else if (currentDir.exists(iconName + pngext)) {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + pngext);
+ // Notice we ensure that pixmap entries allways come before
+ // scalable to preserve search order afterwards
+ entries.prepend(iconEntry);
+ }
+ }
+
+ if (entries.isEmpty()) {
+ const QStringList parents = theme.parents();
+ // Search recursively through inherited themes
+ for (int i = 0 ; i < parents.size() ; ++i) {
+
+ const QString parentTheme = parents.at(i).trimmed();
+
+ if (!visited.contains(parentTheme)) // guard against recursion
+ entries = findIconHelper(parentTheme, iconName, visited);
+
+ if (!entries.isEmpty()) // success
+ break;
+ }
+ }
+ return entries;
+}
+
+QThemeIconEntries QIconLoader::loadIcon(const QString &name) const
+{
+ if (!themeName().isEmpty()) {
+ QStringList visited;
+ return findIconHelper(themeName(), name, visited);
+ }
+
+ return QThemeIconEntries();
+}
+
+
+// -------- Icon Loader Engine -------- //
+
+
+QIconLoaderEngine::QIconLoaderEngine(const QString& iconName)
+ : m_iconName(iconName), m_key(0)
+{
+}
+
+QIconLoaderEngine::~QIconLoaderEngine()
+{
+ while (!m_entries.isEmpty())
+ delete m_entries.takeLast();
+ Q_ASSERT(m_entries.size() == 0);
+}
+
+QIconLoaderEngine::QIconLoaderEngine(const QIconLoaderEngine &other)
+ : QIconEngineV2(other),
+ m_iconName(other.m_iconName),
+ m_key(0)
+{
+}
+
+QIconEngineV2 *QIconLoaderEngine::clone() const
+{
+ return new QIconLoaderEngine(*this);
+}
+
+bool QIconLoaderEngine::read(QDataStream &in) {
+ in >> m_iconName;
+ return true;
+}
+
+bool QIconLoaderEngine::write(QDataStream &out) const
+{
+ out << m_iconName;
+ return true;
+}
+
+bool QIconLoaderEngine::hasIcon() const
+{
+ return !(m_entries.isEmpty());
+}
+
+// Lazily load the icon
+void QIconLoaderEngine::ensureLoaded()
+{
+ if (!(iconLoaderInstance()->themeKey() == m_key)) {
+
+ while (!m_entries.isEmpty())
+ delete m_entries.takeLast();
+
+ Q_ASSERT(m_entries.size() == 0);
+ m_entries = iconLoaderInstance()->loadIcon(m_iconName);
+ m_key = iconLoaderInstance()->themeKey();
+ }
+}
+
+void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
+ QIcon::Mode mode, QIcon::State state)
+{
+ QSize pixmapSize = rect.size();
+#if defined(Q_WS_MAC)
+ pixmapSize *= qt_mac_get_scalefactor();
+#endif
+ painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
+}
+
+/*
+ * This algorithm is defined by the freedesktop spec:
+ * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
+ */
+static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
+{
+ if (dir.type == QIconDirInfo::Fixed) {
+ return dir.size == iconsize;
+
+ } else if (dir.type == QIconDirInfo::Scalable) {
+ return dir.size <= dir.maxSize &&
+ iconsize >= dir.minSize;
+
+ } else if (dir.type == QIconDirInfo::Threshold) {
+ return iconsize >= dir.size - dir.threshold &&
+ iconsize <= dir.size + dir.threshold;
+ }
+
+ Q_ASSERT(1); // Not a valid value
+ return false;
+}
+
+/*
+ * This algorithm is defined by the freedesktop spec:
+ * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
+ */
+static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
+{
+ if (dir.type == QIconDirInfo::Fixed) {
+ return qAbs(dir.size - iconsize);
+
+ } else if (dir.type == QIconDirInfo::Scalable) {
+ if (iconsize < dir.minSize)
+ return dir.minSize - iconsize;
+ else if (iconsize > dir.maxSize)
+ return iconsize - dir.maxSize;
+ else
+ return 0;
+
+ } else if (dir.type == QIconDirInfo::Threshold) {
+ if (iconsize < dir.size - dir.threshold)
+ return dir.minSize - iconsize;
+ else if (iconsize > dir.size + dir.threshold)
+ return iconsize - dir.maxSize;
+ else return 0;
+ }
+
+ Q_ASSERT(1); // Not a valid value
+ return INT_MAX;
+}
+
+QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
+{
+ int iconsize = qMin(size.width(), size.height());
+
+ // Note that m_entries are sorted so that png-files
+ // come first
+
+ // Search for exact matches first
+ for (int i = 0; i < m_entries.count(); ++i) {
+ QIconLoaderEngineEntry *entry = m_entries.at(i);
+ if (directoryMatchesSize(entry->dir, iconsize)) {
+ return entry;
+ }
+ }
+
+ // Find the minimum distance icon
+ int minimalSize = INT_MAX;
+ QIconLoaderEngineEntry *closestMatch = 0;
+ for (int i = 0; i < m_entries.count(); ++i) {
+ QIconLoaderEngineEntry *entry = m_entries.at(i);
+ int distance = directorySizeDistance(entry->dir, iconsize);
+ if (distance < minimalSize) {
+ minimalSize = distance;
+ closestMatch = entry;
+ }
+ }
+ return closestMatch;
+}
+
+/*
+ * Returns the actual icon size. For scalable svg's this is equivalent
+ * to the requested size. Otherwise the closest match is returned.
+ *
+ * todo: the spec is a bit fuzzy in this area, but we should probably
+ * allow scaling down pixmap icons as well.
+ *
+ */
+QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode,
+ QIcon::State state)
+{
+ ensureLoaded();
+
+ QIconLoaderEngineEntry *entry = entryForSize(size);
+ if (entry) {
+ const QIconDirInfo &dir = entry->dir;
+ if (dir.type == QIconDirInfo::Scalable)
+ return size;
+ else
+ return QSize(dir.size, dir.size);
+ }
+ return QIconEngineV2::actualSize(size, mode, state);
+}
+
+QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ Q_UNUSED(state);
+
+ // Ensure that basePixmap is lazily initialized before generating the
+ // key, otherwise the cache key is not unique
+ if (basePixmap.isNull())
+ basePixmap.load(filename);
+
+ int actualSize = qMin(size.width(), size.height());
+ QString key = QLatin1String("$qt_theme_")
+ + QString::number(basePixmap.cacheKey(), 16)
+ + QLatin1Char('_')
+ + QString::number(mode)
+ + QLatin1Char('_')
+ + QString::number(qApp->palette().cacheKey(), 16)
+ + QLatin1Char('_')
+ + QString::number(actualSize);
+
+ QPixmap cachedPixmap;
+ if (QPixmapCache::find(key, &cachedPixmap)) {
+ return cachedPixmap;
+ } else {
+ QStyleOption opt(0);
+ opt.palette = qApp->palette();
+ cachedPixmap = qApp->style()->generatedIconPixmap(mode, basePixmap, &opt);
+ QPixmapCache::insert(key, cachedPixmap);
+ }
+ return cachedPixmap;
+}
+
+QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ if (svgIcon.isNull())
+ svgIcon = QIcon(filename);
+
+ // Simply reuse svg icon engine
+ return svgIcon.pixmap(size, mode, state);
+}
+
+QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode,
+ QIcon::State state)
+{
+ ensureLoaded();
+
+ QIconLoaderEngineEntry *entry = entryForSize(size);
+ if (entry)
+ return entry->pixmap(size, mode, state);
+
+ return QPixmap();
+}
+
+QString QIconLoaderEngine::key() const
+{
+ return QLatin1String("QIconLoaderEngine");
+}
+
+void QIconLoaderEngine::virtual_hook(int id, void *data)
+{
+ ensureLoaded();
+
+ switch (id) {
+ case QIconEngineV2::AvailableSizesHook:
+ {
+ QIconEngineV2::AvailableSizesArgument &arg
+ = *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);
+ const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
+ arg.sizes.clear();
+
+ // Gets all sizes from the DirectoryInfo entries
+ for (int i = 0 ; i < m_entries.size() ; ++i) {
+ int size = m_entries.at(i)->dir.size;
+ arg.sizes.append(QSize(size, size));
+ }
+ }
+ break;
+ default:
+ QIconEngineV2::virtual_hook(id, data);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
new file mode 100644
index 0000000..707107c
--- /dev/null
+++ b/src/gui/image/qiconloader_p.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESKTOPICON_P_H
+#define QDESKTOPICON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/QIcon>
+#include <QtGui/QIconEngine>
+#include <QtGui/QPixmapCache>
+#include <private/qicon_p.h>
+#include <private/qfactoryloader_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIconLoader;
+
+struct QIconDirInfo
+{
+ enum Type { Fixed, Scalable, Threshold };
+ QIconDirInfo(const QString &_path = QString()) :
+ path(_path),
+ size(0),
+ maxSize(0),
+ minSize(0),
+ threshold(0),
+ type(Threshold) {}
+ QString path;
+ short size;
+ short maxSize;
+ short minSize;
+ short threshold;
+ Type type : 4;
+};
+
+class QIconLoaderEngineEntry
+ {
+public:
+ virtual QPixmap pixmap(const QSize &size,
+ QIcon::Mode mode,
+ QIcon::State state) = 0;
+ QString filename;
+ QIconDirInfo dir;
+ static int count;
+};
+
+struct ScalableEntry : public QIconLoaderEngineEntry
+{
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QIcon svgIcon;
+};
+
+struct PixmapEntry : public QIconLoaderEngineEntry
+{
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QPixmap basePixmap;
+};
+
+typedef QList<QIconLoaderEngineEntry*> QThemeIconEntries;
+
+class QIconLoaderEngine : public QIconEngineV2
+{
+public:
+ QIconLoaderEngine(const QString& iconName = QString());
+ ~QIconLoaderEngine();
+
+ void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QIconEngineV2 *clone() const;
+ bool read(QDataStream &in);
+ bool write(QDataStream &out) const;
+
+private:
+ QString key() const;
+ bool hasIcon() const;
+ void ensureLoaded();
+ void virtual_hook(int id, void *data);
+ QIconLoaderEngineEntry *entryForSize(const QSize &size);
+ QIconLoaderEngine(const QIconLoaderEngine &other);
+ QThemeIconEntries m_entries;
+ QString m_iconName;
+ uint m_key;
+
+ friend class QIconLoader;
+};
+
+class QIconTheme
+{
+public:
+ QIconTheme(const QString &name);
+ QIconTheme() : m_valid(false) {};
+ QStringList parents() { return m_parents; }
+ QList <QIconDirInfo> keyList() { return m_keyList; }
+ QString contentDir() { return m_contentDir; }
+ bool isValid() { return m_valid; }
+
+private:
+ QString m_contentDir;
+ QList <QIconDirInfo> m_keyList;
+ QStringList m_parents;
+ bool m_valid;
+};
+
+class QIconLoader : public QObject
+{
+public:
+ QIconLoader();
+ QThemeIconEntries loadIcon(const QString &iconName) const;
+ uint themeKey() const { return m_themeKey; }
+
+ QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; }
+ void setThemeName(const QString &themeName);
+ QIconTheme theme() { return themeList.value(themeName()); }
+ void setThemeSearchPath(const QStringList &searchPaths);
+ QStringList themeSearchPaths() const;
+ QIconDirInfo dirInfo(int dirindex);
+ static QIconLoader *instance();
+ void updateSystemTheme();
+ void invalidateKey() { m_themeKey++; }
+
+private:
+ QThemeIconEntries findIconHelper(const QString &themeName,
+ const QString &iconName,
+ QStringList &visited) const;
+ uint m_themeKey;
+ bool m_supportsSvg;
+
+ mutable QString m_userTheme;
+ mutable QString m_systemTheme;
+ mutable QStringList m_iconDirs;
+ mutable QHash <QString, QIconTheme> themeList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESKTOPICON_P_H
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 32e7e3c..221101a 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -78,6 +78,7 @@
#include <private/qcrashhandler_p.h>
#include <private/qcolor_p.h>
#include <private/qcursor_p.h>
+#include <private/qiconloader_p.h>
#include "qstyle.h"
#include "qmetaobject.h"
#include "qtimer.h"
@@ -1087,7 +1088,6 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
if (QApplication::desktopSettingsAware()) {
// first, read from settings
QApplicationPrivate::x11_apply_settings();
-
// the call to QApplication::style() below creates the system
// palette, which breaks the logic after the RESOURCE_MANAGER
// loop... so I have to save this value to be able to use it later
@@ -1328,6 +1328,8 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
effects.contains(QLatin1String("animatetoolbox")));
}
+
+ QIconLoader::instance()->updateSystemTheme();
}
diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp
index f947ac1..c8b4fda 100644
--- a/src/gui/styles/gtksymbols.cpp
+++ b/src/gui/styles/gtksymbols.cpp
@@ -60,6 +60,7 @@
#include <QtCore/QHash>
#include <private/qapplication_p.h>
+#include <private/qiconloader_p.h>
#include <QtGui/QMenu>
#include <QtGui/QStyle>
@@ -341,9 +342,9 @@ static bool resolveGConf()
typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
-static QString getGConfString(const QString &value)
+QString QGtk::getGConfString(const QString &value, const QString &fallback)
{
- QString retVal;
+ QString retVal = fallback;
if (resolveGConf()) {
g_type_init();
GConfClient* client = QGtk::gconf_client_get_default();
@@ -393,7 +394,7 @@ static QString getThemeName()
// Fall back to gconf
if (themeName.isEmpty() && resolveGConf())
- themeName = getGConfString(QLS("/desktop/gnome/interface/gtk_theme"));
+ themeName = QGtk::getGConfString(QLS("/desktop/gnome/interface/gtk_theme"));
return themeName;
}
@@ -561,6 +562,7 @@ void QGtkStyleUpdateScheduler::updateTheme()
QApplication::sendEvent(widget, &e);
}
}
+ QIconLoader::instance()->updateSystemTheme();
}
static void add_widget(GtkWidget *widget)
diff --git a/src/gui/styles/gtksymbols_p.h b/src/gui/styles/gtksymbols_p.h
index 18c6dc5..68e970a 100644
--- a/src/gui/styles/gtksymbols_p.h
+++ b/src/gui/styles/gtksymbols_p.h
@@ -216,6 +216,7 @@ public:
static QString openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
static QStringList openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
QString *selectedFilter, QFileDialog::Options options);
+ static QString getGConfString(const QString &key, const QString &fallback = QString());
static Ptr_gtk_container_forall gtk_container_forall;
static Ptr_gtk_init gtk_init;
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index 8f88781..1782e36 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -462,26 +462,6 @@ static const char * const qt_cleanlooks_checkbox_checked[] = {
" ",
" "};
-#ifdef Q_WS_X11
-extern "C" {
- struct GConfClient;
- struct GError;
- typedef void (*Ptr_g_type_init)();
- typedef GConfClient* (*Ptr_gconf_client_get_default)();
- typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
- typedef void (*Ptr_g_object_unref)(void *);
- typedef void (*Ptr_g_error_free)(GError *);
- typedef void (*Ptr_g_free)(void*);
-}
-
-static Ptr_g_type_init p_g_type_init = 0;
-static Ptr_gconf_client_get_default p_gconf_client_get_default = 0;
-static Ptr_gconf_client_get_string p_gconf_client_get_string = 0;
-static Ptr_g_object_unref p_g_object_unref = 0;
-static Ptr_g_error_free p_g_error_free = 0;
-static Ptr_g_free p_g_free = 0;
-#endif
-
static void qt_cleanlooks_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart,
const QColor &gradientStop, Direction direction = TopDown, QBrush bgBrush = QBrush())
{
@@ -3848,17 +3828,6 @@ QSize QCleanlooksStyle::sizeFromContents(ContentsType type, const QStyleOption *
void QCleanlooksStyle::polish(QApplication *app)
{
QWindowsStyle::polish(app);
-#ifdef Q_WS_X11
- Q_D(QCleanlooksStyle);
-
- QString dataDirs = QLatin1String(getenv("XDG_DATA_DIRS"));
-
- if (dataDirs.isEmpty())
- dataDirs = QLatin1String("/usr/local/share/:/usr/share/");
-
- dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
- d->iconDirs = dataDirs.split(QLatin1Char(':'));
-#endif
}
/*!
@@ -4376,44 +4345,6 @@ QRect QCleanlooksStyle::subElementRect(SubElement sr, const QStyleOption *opt, c
return r;
}
-void QCleanlooksStylePrivate::lookupIconTheme() const
-{
-#ifdef Q_WS_X11
-
- if (themeName.isEmpty()) {
- //resolve glib and gconf functions
- p_g_type_init = (Ptr_g_type_init)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_type_init");
- p_gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_default");
- p_gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_string");
- p_g_object_unref = (Ptr_g_object_unref)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_object_unref");
- p_g_error_free = (Ptr_g_error_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_error_free");
- p_g_free = (Ptr_g_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_free");
-
- if (p_g_type_init &&
- p_gconf_client_get_default &&
- p_gconf_client_get_string &&
- p_g_object_unref &&
- p_g_error_free &&
- p_g_free) {
-
- p_g_type_init();
- GConfClient* client = p_gconf_client_get_default();
- GError *err = 0;
- char *str = p_gconf_client_get_string(client, "/desktop/gnome/interface/icon_theme", &err);
- if (!err) {
- themeName = QString::fromUtf8(str);
- p_g_free(str);
- }
- p_g_object_unref(client);
- if (err)
- p_g_error_free (err);
- }
- if (themeName.isEmpty())
- themeName = QLatin1String("gnome");
- }
-#endif
-}
-
/*!
\internal
*/
@@ -4421,165 +4352,6 @@ QIcon QCleanlooksStyle::standardIconImplementation(StandardPixmap standardIcon,
const QStyleOption *option,
const QWidget *widget) const
{
-#ifdef Q_WS_X11
- Q_D(const QCleanlooksStyle);
- if (!QApplication::desktopSettingsAware())
- return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
- QIcon icon;
- QPixmap pixmap;
- QPixmap link;
- d->lookupIconTheme();
- switch (standardIcon) {
- case SP_DirIcon: {
- icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget));
- icon.addPixmap(proxy()->standardPixmap(SP_DirClosedIcon, option, widget),
- QIcon::Normal, QIcon::Off);
- pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory.png"));
- if (!pixmap.isNull())
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
- pixmap = d->findIcon(48, QLatin1String("gnome-fs-directory.png"));
- if (!pixmap.isNull())
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
- pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory-accept.png"));
- if (!pixmap.isNull())
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
- pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory-accept.png"));
- if (!pixmap.isNull())
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
- }
- break;
- case SP_DirLinkIcon:
- {
- icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget));
- QPixmap link = d->findIcon(12, QLatin1String("emblem-symbolic-link.png"));
- if (!link.isNull()) {
- icon.addPixmap(proxy()->standardPixmap(SP_DirLinkIcon, option, widget));
- pixmap = d->findIcon(16, QLatin1String("gnome-fs-directory.png"));
- if (!pixmap.isNull()) {
- QPainter painter(&pixmap);
- painter.drawPixmap(8, 8, 8, 8, link);
- painter.end();
- icon.addPixmap(pixmap);
- }
- }
- break;
- }
- case SP_FileIcon:
- {
- icon = d->createIcon(QLatin1String("unknown.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("gnome-fs-regular.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("stock_new.png"));
- break;
- }
- case SP_DialogCloseButton:
- {
- icon = d->createIcon(QLatin1String("gtk-close.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("stock-close.png"));
- break;
- }
- case SP_DirHomeIcon:
- {
- icon = d->createIcon(QLatin1String("folder_home.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("gnome_home.png"));
- break;
- }
- case SP_DriveFDIcon:
- {
- icon = d->createIcon(QLatin1String("gnome-dev-floppy.png"));
- break;
- }
- case SP_ComputerIcon:
- {
- icon = d->createIcon(QLatin1String("gnome-fs-client.png"));
- break;
- }
- case SP_DesktopIcon:
- {
- icon = d->createIcon(QLatin1String("gnome-fs-desktop.png"));
- break;
- }
- case SP_TrashIcon:
- {
- icon = d->createIcon(QLatin1String("gnome-fs-trash-empty.png"));
- break;
- }
- case SP_DriveCDIcon:
- case SP_DriveDVDIcon:
- {
- icon = d->createIcon(QLatin1String("gnome-dev-cdrom.png"));
- break;
- }
- case SP_DriveHDIcon:
- {
- icon = d->createIcon(QLatin1String("gnome-dev-harddisk.png"));
- break;
- }
- case SP_ArrowUp:
- {
- icon = d->createIcon(QLatin1String("stock_up.png"));
- break;
- }
- case SP_ArrowDown:
- {
- icon = d->createIcon(QLatin1String("stock_down.png"));
- break;
- }
- case SP_ArrowRight:
- {
- icon = d->createIcon(QLatin1String("stock_right.png"));
- break;
- }
- case SP_ArrowLeft:
- {
- icon = d->createIcon(QLatin1String("stock_left.png"));
- break;
- }
- case SP_BrowserReload:
- {
- icon = d->createIcon(QLatin1String("view-refresh.png"));
- break;
- }
- case SP_BrowserStop:
- {
- pixmap = d->findIcon(24, QLatin1String("stop.png"));
- break;
- }
- case SP_FileLinkIcon:
- {
- icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget));
- QPixmap link = d->findIcon(12, QLatin1String("emblem-symbolic-link.png"));
- if (!link.isNull()) {
- icon.addPixmap(proxy()->standardPixmap(SP_FileLinkIcon,option, widget));
- pixmap = d->findIcon(16, QLatin1String("unknown.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("stock_new.png"));
- if (!pixmap.isNull()) {
- QPainter painter(&pixmap);
- painter.drawPixmap(8, 8, 8, 8, link);
- painter.end();
- icon.addPixmap(pixmap);
- }
- }
- break;
- }
- case SP_ArrowForward:
- if (QApplication::layoutDirection() == Qt::RightToLeft)
- return standardIconImplementation(SP_ArrowLeft, option, widget);
- return standardIconImplementation(SP_ArrowRight, option, widget);
- case SP_ArrowBack:
- if (QApplication::layoutDirection() == Qt::RightToLeft)
- return standardIconImplementation(SP_ArrowRight, option, widget);
- return standardIconImplementation(SP_ArrowLeft, option, widget);
- default:
- icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget));
- }
- if (!icon.isNull())
- return icon;
-#endif // Q_WS_X11
return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
}
@@ -4589,341 +4361,10 @@ QIcon QCleanlooksStyle::standardIconImplementation(StandardPixmap standardIcon,
QPixmap QCleanlooksStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
const QWidget *widget) const
{
-#ifdef Q_WS_X11
- Q_D(const QCleanlooksStyle);
QPixmap pixmap;
- if (!QApplication::desktopSettingsAware())
- return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
- d->lookupIconTheme();
+
#ifndef QT_NO_IMAGEFORMAT_XPM
switch (standardPixmap) {
- case SP_MessageBoxInformation:
- {
- pixmap = d->findIcon(48, QLatin1String("dialog-info.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(48, QLatin1String("stock_dialog-info.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MessageBoxWarning:
- {
- pixmap = d->findIcon(48, QLatin1String("dialog-warning.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(48, QLatin1String("stock_dialog-warning.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MessageBoxCritical:
- {
- pixmap = d->findIcon(48, QLatin1String("dialog-error.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(48, QLatin1String("stock_dialog-error.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MessageBoxQuestion:
- {
- pixmap = d->findIcon(48, QLatin1String("dialog-question.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DirHomeIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("folder_home.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("gnome_home.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogOpenButton:
- case SP_DirOpenIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("stock_open.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_FileIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("unknown.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(24, QLatin1String("gnome-fs-regular.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(24, QLatin1String("stock_new.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_FileLinkIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("emblem-symbolic-link.png"));
- if (!pixmap.isNull()) {
- QPixmap fileIcon = d->findIcon(24, QLatin1String("unknown.png"));
- if (fileIcon.isNull())
- fileIcon = d->findIcon(24, QLatin1String("stock_new.png"));
- if (!fileIcon.isNull()) {
- QPainter painter(&fileIcon);
- painter.setRenderHint(QPainter::SmoothPixmapTransform);
- painter.drawPixmap(12, 12, 12, 12, pixmap);
- return fileIcon;
- }
- }
- break;
- }
- case SP_DirClosedIcon:
- case SP_DirIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("gnome-fs-directory.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DirLinkIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("emblem-symbolic-link.png"));
- if (!pixmap.isNull()) {
- QPixmap dirIcon = d->findIcon(24, QLatin1String("gnome-fs-directory.png"));
- if (!dirIcon.isNull()) {
- QPainter painter(&dirIcon);
- painter.setRenderHint(QPainter::SmoothPixmapTransform);
- painter.drawPixmap(12, 12, 12, 12, pixmap);
- return dirIcon;
- }
- }
- break;
- }
- case SP_DriveFDIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("gnome-dev-floppy.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_ComputerIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("gnome-fs-client.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DesktopIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("gnome-fs-desktop.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_TrashIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("gnome-fs-trash-empty.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DriveCDIcon:
- case SP_DriveDVDIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("gnome-dev-cdrom.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DriveHDIcon:
- {
- pixmap = d->findIcon(24, QLatin1String("gnome-dev-harddisk.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_FileDialogToParent:
- {
- pixmap = d->findIcon(16, QLatin1String("stock_up.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_FileDialogNewFolder:
- {
- pixmap = d->findIcon(16, QLatin1String("stock_new-dir.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_ArrowUp:
- {
- pixmap = d->findIcon(16, QLatin1String("stock_up.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_ArrowDown:
- {
- pixmap = d->findIcon(16, QLatin1String("stock_down.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_ArrowRight:
- {
- pixmap = d->findIcon(16, QLatin1String("stock_right.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_ArrowLeft:
- {
- pixmap = d->findIcon(16, QLatin1String("stock_left.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogCloseButton:
- {
- pixmap = d->findIcon(24, QLatin1String("gtk-close.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(24, QLatin1String("stock-close.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogApplyButton:
- {
- pixmap = d->findIcon(24, QLatin1String("dialog-apply.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(24, QLatin1String("stock-apply.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogResetButton:
- {
- pixmap = d->findIcon(24, QLatin1String("gtk-clear.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogHelpButton:
- {
- pixmap = d->findIcon(24, QLatin1String("gtk-help.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogOkButton:
- {
- pixmap = d->findIcon(24, QLatin1String("dialog-ok.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(24, QLatin1String("stock-ok.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogCancelButton:
- {
- pixmap = d->findIcon(24, QLatin1String("dialog-cancel.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(24, QLatin1String("stock-cancel.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(24, QLatin1String("process-stop.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_DialogSaveButton:
- {
- pixmap = d->findIcon(24, QLatin1String("stock_save.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_BrowserStop:
- {
- pixmap = d->findIcon(16, QLatin1String("process-stop.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_BrowserReload:
- {
- pixmap = d->findIcon(16, QLatin1String("view-refresh.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaPlay:
- {
- pixmap = d->findIcon(24, QLatin1String("media-playback-start.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaPause:
- {
- pixmap = d->findIcon(24, QLatin1String("media-playback-pause.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaStop:
- {
- pixmap = d->findIcon(24, QLatin1String("media-playback-stop.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaVolume:
- {
- pixmap = d->findIcon(16, QLatin1String("audio-volume-medium.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaVolumeMuted:
- {
- pixmap = d->findIcon(16, QLatin1String("audio-volume-muted.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaSeekForward:
- {
- pixmap = d->findIcon(24, QLatin1String("media-seek-forward.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaSeekBackward:
- {
- pixmap = d->findIcon(24, QLatin1String("media-seek-backward.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaSkipForward:
- {
- pixmap = d->findIcon(24, QLatin1String("media-skip-forward.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_MediaSkipBackward:
- {
- pixmap = d->findIcon(24, QLatin1String("media-skip-backward.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_TitleBarMenuButton:
- case SP_TitleBarShadeButton:
- case SP_TitleBarUnshadeButton:
- case SP_TitleBarMaxButton:
- case SP_TitleBarContextHelpButton:
- return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
case SP_TitleBarNormalButton:
return QPixmap((const char **)dock_widget_restore_xpm);
case SP_TitleBarMinButton:
@@ -4936,7 +4377,7 @@ QPixmap QCleanlooksStyle::standardPixmap(StandardPixmap standardPixmap, const QS
break;
}
#endif //QT_NO_IMAGEFORMAT_XPM
-#endif //Q_WS_X11
+
return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
}
diff --git a/src/gui/styles/qcleanlooksstyle_p.h b/src/gui/styles/qcleanlooksstyle_p.h
index a26d40d..d325499 100644
--- a/src/gui/styles/qcleanlooksstyle_p.h
+++ b/src/gui/styles/qcleanlooksstyle_p.h
@@ -71,8 +71,6 @@ public:
~QCleanlooksStylePrivate() {
}
-
- void lookupIconTheme() const;
};
QT_END_NAMESPACE
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index c7feb25..3878856 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -840,176 +840,8 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut
#endif // QT_NO_TOOLBUTTON
-
#ifdef Q_WS_X11 // These functions are used to parse the X11 freedesktop icon spec
-void QCommonStylePrivate::lookupIconTheme() const
-{
- if (!themeName.isEmpty())
- return;
-
- QString dataDirs = QString::fromLocal8Bit(getenv("XDG_DATA_DIRS"));
- if (dataDirs.isEmpty())
- dataDirs = QLatin1String("/usr/local/share/:/usr/share/");
- dataDirs += QLatin1Char(':') + QKde::kdeHome() + QLatin1String("/share");
- dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
- QStringList kdeDirs = QString::fromLocal8Bit(getenv("KDEDIRS")).split(QLatin1Char(':'), QString::SkipEmptyParts);
- foreach (const QString &dirName, kdeDirs)
- dataDirs.append(QLatin1Char(':') + dirName + QLatin1String("/share"));
- iconDirs = dataDirs.split(QLatin1Char(':'));
-
- QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
- QDir dir(fileInfo.canonicalFilePath());
- QString kdeDefault = (X11->desktopEnvironment != DE_KDE || X11->desktopVersion >= 4)
- ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg");
- QString defaultTheme = fileInfo.exists() ? dir.dirName() : kdeDefault;
- QSettings settings(QKde::kdeHome() +
- QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
- settings.beginGroup(QLatin1String("Icons"));
- themeName = settings.value(QLatin1String("Theme"), defaultTheme).toString();
-}
-
-QIconTheme QCommonStylePrivate::parseIndexFile(const QString &themeName) const
-{
- Q_Q(const QCommonStyle);
- QIconTheme theme;
- QFile themeIndex;
- QStringList parents;
- QHash <int, QString> dirList;
-
- for ( int i = 0 ; i < iconDirs.size() && !themeIndex.exists() ; ++i) {
- QString contentDir = QLatin1String(iconDirs[i].startsWith(QDir::homePath()) ?
- "/.icons/" : "/icons/");
- themeIndex.setFileName(iconDirs[i] + contentDir +
- themeName + QLatin1String("/index.theme"));
- }
-
- if (themeIndex.open(QIODevice::ReadOnly | QIODevice::Text)) {
-
- QTextStream in(&themeIndex);
-
- while (!in.atEnd()) {
-
- QString line = in.readLine();
-
- if (line.startsWith(QLatin1String("Inherits="))) {
- line = line.right(line.length() - 9);
- parents = line.split(QLatin1Char(','));
- }
-
- if (line.startsWith(QLatin1Char('['))) {
- line = line.trimmed();
- line.chop(1);
- QString dirName = line.right(line.length() - 1);
- if (!in.atEnd()) {
- line = in.readLine();
- int size;
- if (line.startsWith(QLatin1String("Size="))) {
- size = line.right(line.length() - 5).toInt();
- if (size)
- dirList.insertMulti(size, dirName);
- }
- }
- }
- }
- }
-
- if (q->inherits("QPlastiqueStyle")) {
- QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
- QDir dir(fileInfo.canonicalFilePath());
- QString defaultKDETheme = dir.exists() ? dir.dirName() : QString::fromLatin1("crystalsvg");
- if (!parents.contains(defaultKDETheme) && themeName != defaultKDETheme)
- parents.append(defaultKDETheme);
- } else if (parents.isEmpty() && themeName != QLatin1String("hicolor")) {
- parents.append(QLatin1String("hicolor"));
- }
- theme = QIconTheme(dirList, parents);
- return theme;
-}
-
-QPixmap QCommonStylePrivate::findIconHelper(int size,
- const QString &themeName,
- const QString &iconName,
- QStringList &visited) const
-{
- QPixmap pixmap;
-
- if (!themeName.isEmpty()) {
-
- visited << themeName;
- QIconTheme theme = themeList.value(themeName);
-
- if (!theme.isValid()) {
- theme = parseIndexFile(themeName);
- themeList.insert(themeName, theme);
- }
-
- if (!theme.isValid())
- return QPixmap();
-
- QList <QString> subDirs = theme.dirList().values(size);
-
- for ( int i = 0 ; i < iconDirs.size() ; ++i) {
- for ( int j = 0 ; j < subDirs.size() ; ++j) {
- QString contentDir = (iconDirs[i].startsWith(QDir::homePath())) ?
- QLatin1String("/.icons/") : QLatin1String("/icons/");
- QString fileName = iconDirs[i] + contentDir + themeName + QLatin1Char('/') + subDirs[j] + QLatin1Char('/') + iconName;
- QFile file(fileName);
- if (file.exists())
- pixmap.load(fileName);
- if (!pixmap.isNull())
- break;
- }
- }
-
- if (pixmap.isNull()) {
- QStringList parents = theme.parents();
- //search recursively through inherited themes
- for (int i = 0 ; pixmap.isNull() && i < parents.size() ; ++i) {
- QString parentTheme = parents[i].trimmed();
- if (!visited.contains(parentTheme)) //guard against endless recursion
- pixmap = findIconHelper(size, parentTheme, iconName, visited);
- }
- }
- }
- return pixmap;
-}
-
-/*! \internal
- find a pixmap with the given size and name from the freedesktop theme.
-*/
-QPixmap QCommonStylePrivate::findIcon(int size, const QString &name) const
-{
- QIcon icon = QKde::kdeIcon(name);
- if (!icon.isNull())
- return icon.pixmap(size);
-
- QPixmap pixmap;
- QString pixmapName = QLatin1String("$qt") + name + QString::number(size);
-
- if (QPixmapCache::find(pixmapName, pixmap))
- return pixmap;
-
- if (!themeName.isEmpty()) {
- QStringList visited;
- pixmap = findIconHelper(size, themeName, name, visited);
- }
- QPixmapCache::insert(pixmapName, pixmap);
- return pixmap;
-}
-/*! \internal
- create an Icon from the freedesktop theme.
- */
-QIcon QCommonStylePrivate::createIcon(const QString &name) const
-{
- QIcon icon = QKde::kdeIcon(name);
- if (icon.isNull()) {
- icon.addPixmap(findIcon(16, name));
- icon.addPixmap(findIcon(24, name));
- icon.addPixmap(findIcon(32, name));
- }
- return icon;
-}
/*!internal
Checks if you are running KDE and looks up the toolbar
@@ -4859,8 +4691,24 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
ret = int(QStyleHelper::dpiScaled(6.));
break;
- case PM_TabBarIconSize:
case PM_ToolBarIconSize:
+#ifdef Q_WS_X11
+ if (X11->desktopVersion >= 4) {
+ static int iconSize = 0;
+ if (!iconSize) {
+ QSettings settings(QKde::kdeHome() +
+ QLatin1String("/share/config/kdeglobals"),
+ QSettings::IniFormat);
+ settings.beginGroup(QLatin1String("ToolbarIcons"));
+ iconSize = settings.value(QLatin1String("Size"), QLatin1String("22")).toInt();
+ }
+ ret = iconSize;
+ } else
+#endif
+ ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
+ break;
+
+ case PM_TabBarIconSize:
case PM_ListViewIconSize:
ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
break;
@@ -5371,293 +5219,161 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti
Q_UNUSED(widget);
Q_UNUSED(sp);
#else
-#ifdef Q_WS_X11
- Q_D(const QCommonStyle);
QPixmap pixmap;
- if (QApplication::desktopSettingsAware()) {
- d->lookupIconTheme();
+
+ if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
switch (sp) {
case SP_DirHomeIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("folder_home.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
+ pixmap = QIcon::fromTheme(QLatin1String("user-home")).pixmap(16);
+ break;
case SP_MessageBoxInformation:
- {
- pixmap = d->findIcon(32, QLatin1String("messagebox_info.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
+ pixmap = QIcon::fromTheme(QLatin1String("messagebox_info")).pixmap(16);
+ break;
case SP_MessageBoxWarning:
- {
- pixmap = d->findIcon(32, QLatin1String("messagebox_warning.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
+ pixmap = QIcon::fromTheme(QLatin1String("messagebox_warning")).pixmap(16);
+ break;
case SP_MessageBoxCritical:
- {
- pixmap = d->findIcon(32, QLatin1String("messagebox_critical.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
+ pixmap = QIcon::fromTheme(QLatin1String("messagebox_critical")).pixmap(16);
+ break;
case SP_MessageBoxQuestion:
- {
- pixmap = d->findIcon(32, QLatin1String("help.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
+ pixmap = QIcon::fromTheme(QLatin1String("help")).pixmap(16);
+ break;
case SP_DialogOpenButton:
case SP_DirOpenIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("folder-open.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("folder_open.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
+ pixmap = QIcon::fromTheme(QLatin1String("folder-open")).pixmap(16);
+ break;
case SP_FileIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("text-x-generic.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("empty.png"));
- if (!pixmap.isNull())
- return pixmap;
- break;
- }
- case SP_FileLinkIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("link_overlay.png"));
- if (!pixmap.isNull()) {
- QPixmap fileIcon = d->findIcon(16, QLatin1String("text-x-generic.png"));
- if (fileIcon.isNull())
- fileIcon = d->findIcon(16, QLatin1String("empty.png"));
- if (!fileIcon.isNull()) {
- QPainter painter(&fileIcon);
- painter.drawPixmap(0, 0, 16, 16, pixmap);
- return fileIcon;
- }
- }
- break;
- }
+ pixmap = QIcon::fromTheme(QLatin1String("text-x-generic"),
+ QIcon::fromTheme(QLatin1String("empty"))).pixmap(16);
+ break;
case SP_DirClosedIcon:
case SP_DirIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("folder.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("folder")).pixmap(16);
break;
- }
- case SP_DirLinkIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("link_overlay.png"));
- if (!pixmap.isNull()) {
- QPixmap dirIcon = d->findIcon(16, QLatin1String("folder.png"));
- if (!dirIcon.isNull()) {
- QPainter painter(&dirIcon);
- painter.drawPixmap(0, 0, 16, 16, pixmap);
- return dirIcon;
- }
- }
- break;
- }
case SP_DriveFDIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("media-floppy.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("3floppy_unmount.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-floppy"),
+ QIcon::fromTheme(QLatin1String("3floppy_unmount"))).pixmap(16);
break;
- }
case SP_ComputerIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("computer.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("system.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("computer"),
+ QIcon::fromTheme(QLatin1String("system"))).pixmap(16);
break;
- }
case SP_DesktopIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("user-desktop.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("desktop.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("user-desktop"),
+ QIcon::fromTheme(QLatin1String("desktop"))).pixmap(16);
break;
- }
case SP_TrashIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("user-trash.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("trashcan_empty.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("user-trash"),
+ QIcon::fromTheme(QLatin1String("trashcan_empty"))).pixmap(16);
break;
- }
case SP_DriveCDIcon:
case SP_DriveDVDIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("media-optical.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("cdrom_unmount.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-optical"),
+ QIcon::fromTheme(QLatin1String("cdrom_unmount"))).pixmap(16);
break;
- }
case SP_DriveHDIcon:
- {
- pixmap = d->findIcon(16, QLatin1String("drive-harddisk.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(16, QLatin1String("hdd_unmount.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("drive-harddisk"),
+ QIcon::fromTheme(QLatin1String("hdd_unmount"))).pixmap(16);
break;
- }
case SP_FileDialogToParent:
- {
- pixmap = d->findIcon(32, QLatin1String("go-up.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(32, QLatin1String("up.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("go-up"),
+ QIcon::fromTheme(QLatin1String("up"))).pixmap(16);
break;
- }
case SP_FileDialogNewFolder:
- {
- pixmap = d->findIcon(16, QLatin1String("folder_new.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("folder_new")).pixmap(16);
break;
- }
case SP_ArrowUp:
- {
- pixmap = d->findIcon(32, QLatin1String("go-up.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(32, QLatin1String("up.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("go-up"),
+ QIcon::fromTheme(QLatin1String("up"))).pixmap(16);
break;
- }
case SP_ArrowDown:
- {
- pixmap = d->findIcon(32, QLatin1String("go-down.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(32, QLatin1String("down.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("go-down"),
+ QIcon::fromTheme(QLatin1String("down"))).pixmap(16);
break;
- }
case SP_ArrowRight:
- {
- pixmap = d->findIcon(32, QLatin1String("go-next.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(32, QLatin1String("forward.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("go-next"),
+ QIcon::fromTheme(QLatin1String("forward"))).pixmap(16);
break;
- }
case SP_ArrowLeft:
- {
- pixmap = d->findIcon(32, QLatin1String("go-previous.png"));
- if (pixmap.isNull())
- pixmap = d->findIcon(32, QLatin1String("back.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("go-previous"),
+ QIcon::fromTheme(QLatin1String("back"))).pixmap(16);
break;
- }
case SP_FileDialogDetailedView:
- {
- pixmap = d->findIcon(16, QLatin1String("view_detailed.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("view_detailed")).pixmap(16);
break;
- }
-
case SP_FileDialogListView:
- {
- pixmap = d->findIcon(16, QLatin1String("view_icon.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("view_icon")).pixmap(16);
break;
- }
case SP_BrowserReload:
- {
- pixmap = d->findIcon(32, QLatin1String("reload.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("reload")).pixmap(16);
break;
- }
case SP_BrowserStop:
- {
- pixmap = d->findIcon(32, QLatin1String("stop.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("process-stop")).pixmap(16);
break;
- }
case SP_MediaPlay:
- {
- pixmap = d->findIcon(16, QLatin1String("player_play.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-playback-start")).pixmap(16);
break;
- }
case SP_MediaPause:
- {
- pixmap = d->findIcon(16, QLatin1String("player_pause.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-playback-pause")).pixmap(16);
break;
- }
case SP_MediaStop:
- {
- pixmap = d->findIcon(16, QLatin1String("player_stop.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-playback-stop")).pixmap(16);
break;
- }
case SP_MediaSeekForward:
- {
- pixmap = d->findIcon(16, QLatin1String("player_fwd.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-seek-forward")).pixmap(16);
break;
- }
case SP_MediaSeekBackward:
- {
- pixmap = d->findIcon(16, QLatin1String("player_rew.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-seek-backward")).pixmap(16);
break;
- }
case SP_MediaSkipForward:
- {
- pixmap = d->findIcon(16, QLatin1String("player_end.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16);
break;
- }
case SP_MediaSkipBackward:
- {
- pixmap = d->findIcon(16, QLatin1String("player_start.png"));
- if (!pixmap.isNull())
- return pixmap;
+ pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16);
+ break;
+ case SP_DialogResetButton:
+ pixmap = QIcon::fromTheme(QLatin1String("edit-clear")).pixmap(24);
+ break;
+ case SP_DialogHelpButton:
+ pixmap = QIcon::fromTheme(QLatin1String("help-contents")).pixmap(24);
+ break;
+ case SP_DialogCancelButton:
+ pixmap = QIcon::fromTheme(QLatin1String("process-stop")).pixmap(24);
+ break;
+ case SP_DialogSaveButton:
+ pixmap = QIcon::fromTheme(QLatin1String("document-save")).pixmap(24);
break;
+ case SP_FileLinkIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16);
+ if (!pixmap.isNull()) {
+ QPixmap fileIcon = QIcon::fromTheme(QLatin1String("text-x-generic")).pixmap(16);
+ if (fileIcon.isNull())
+ fileIcon = QIcon::fromTheme(QLatin1String("empty")).pixmap(16);
+ if (!fileIcon.isNull()) {
+ QPainter painter(&fileIcon);
+ painter.drawPixmap(0, 0, 16, 16, pixmap);
+ return fileIcon;
+ }
}
-
+ break;
+ case SP_DirLinkIcon:
+ pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16);
+ if (!pixmap.isNull()) {
+ QPixmap dirIcon = QIcon::fromTheme(QLatin1String("folder")).pixmap(16);
+ if (!dirIcon.isNull()) {
+ QPainter painter(&dirIcon);
+ painter.drawPixmap(0, 0, 16, 16, pixmap);
+ return dirIcon;
+ }
+ }
+ break;
default:
break;
}
}
-#endif //Q_WS_X11
+
+ if (!pixmap.isNull())
+ return pixmap;
#endif //QT_NO_IMAGEFORMAT_PNG
switch (sp) {
#ifndef QT_NO_IMAGEFORMAT_XPM
@@ -5793,254 +5509,178 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons
const QWidget *widget) const
{
QIcon icon;
- if (QApplication::desktopSettingsAware()) {
-#ifdef Q_WS_X11
- Q_D(const QCommonStyle);
- d->lookupIconTheme();
- QPixmap pixmap;
+ if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) {
switch (standardIcon) {
case SP_DirHomeIcon:
- {
- icon = d->createIcon(QLatin1String("folder_home.png"));
+ icon = QIcon::fromTheme(QLatin1String("user-home"));
break;
- }
case SP_MessageBoxInformation:
- {
- icon = d->createIcon(QLatin1String("dialog-information.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("messagebox_info.png"));
+ icon = QIcon::fromTheme(QLatin1String("dialog-information"));
break;
- }
case SP_MessageBoxWarning:
- {
- icon = d->createIcon(QLatin1String("dialog-warning.png"));
- icon = d->createIcon(QLatin1String("dialog-warning.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("messagebox_warning.png"));
+ icon = QIcon::fromTheme(QLatin1String("dialog-warning"));
break;
- }
case SP_MessageBoxCritical:
- {
- icon = d->createIcon(QLatin1String("dialog-error.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("messagebox_critical.png"));
+ icon = QIcon::fromTheme(QLatin1String("dialog-error"));
break;
- }
case SP_MessageBoxQuestion:
- {
- icon = d->createIcon(QLatin1String("help.png"));
+ icon = QIcon::fromTheme(QLatin1String("dialog-question"));
break;
- }
case SP_DialogOpenButton:
case SP_DirOpenIcon:
- {
- icon = d->createIcon(QLatin1String("folder-open.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("folder_open.png"));
+ icon = QIcon::fromTheme(QLatin1String("folder-open"));
break;
- }
case SP_FileIcon:
- {
- icon = d->createIcon(QLatin1String("text-x-generic.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("empty.png"));
+ icon = QIcon::fromTheme(QLatin1String("text-x-generic"));
break;
- }
case SP_DirClosedIcon:
case SP_DirIcon:
- {
- icon = d->createIcon(QLatin1String("folder.png"));
+ icon = QIcon::fromTheme(QLatin1String("folder"));
break;
- }
case SP_DriveFDIcon:
- {
- icon = d->createIcon(QLatin1String("floppy_unmount.png"));
+ icon = QIcon::fromTheme(QLatin1String("floppy_unmount"));
break;
- }
case SP_ComputerIcon:
- {
- icon = d->createIcon(QLatin1String("computer.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("system.png"));
+ icon = QIcon::fromTheme(QLatin1String("computer"),
+ QIcon::fromTheme(QLatin1String("system")));
break;
- }
case SP_DesktopIcon:
- {
- icon = d->createIcon(QLatin1String("user-desktop.png"));
+ icon = QIcon::fromTheme(QLatin1String("user-desktop"));
break;
- }
case SP_TrashIcon:
- {
- icon = d->createIcon(QLatin1String("user-trash.png"));
+ icon = QIcon::fromTheme(QLatin1String("user-trash"));
break;
- }
case SP_DriveCDIcon:
case SP_DriveDVDIcon:
- {
- icon = d->createIcon(QLatin1String("media-optical.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("cdrom_unmount.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-optical"));
break;
- }
case SP_DriveHDIcon:
- {
- icon = d->createIcon(QLatin1String("drive-harddisk.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("hdd_unmount.png"));
+ icon = QIcon::fromTheme(QLatin1String("drive-harddisk"));
break;
- }
case SP_FileDialogToParent:
- {
- icon = d->createIcon(QLatin1String("go-up.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("up.png"));
+ icon = QIcon::fromTheme(QLatin1String("go-up"));
break;
- }
case SP_FileDialogNewFolder:
- {
- icon = d->createIcon(QLatin1String("folder_new.png"));
+ icon = QIcon::fromTheme(QLatin1String("folder-new"));
break;
- }
case SP_ArrowUp:
- {
- icon = d->createIcon(QLatin1String("go-up.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("up.png"));
+ icon = QIcon::fromTheme(QLatin1String("go-up"));
break;
- }
case SP_ArrowDown:
- {
- icon = d->createIcon(QLatin1String("go-down.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("down.png"));
+ icon = QIcon::fromTheme(QLatin1String("go-down"));
break;
- }
case SP_ArrowRight:
- {
- icon = d->createIcon(QLatin1String("go-next.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("forward.png"));
+ icon = QIcon::fromTheme(QLatin1String("go-next"));
break;
- }
case SP_ArrowLeft:
- {
- icon = d->createIcon(QLatin1String("go-previous.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("back.png"));
+ icon = QIcon::fromTheme(QLatin1String("go-previous"));
+ break;
+ case SP_DialogHelpButton:
+ icon = QIcon::fromTheme(QLatin1String("help-contents"));
+ break;
+ case SP_DialogCancelButton:
+ icon = QIcon::fromTheme(QLatin1String("process-stop"));
+ break;
+ case SP_DialogCloseButton:
+ icon = QIcon::fromTheme(QLatin1String("window-close"));
+ break;
+ case SP_DialogApplyButton:
+ icon = QIcon::fromTheme(QLatin1String("dialog-ok-apply"));
+ break;
+ case SP_DialogOkButton:
+ icon = QIcon::fromTheme(QLatin1String("dialog-ok"));
break;
- }
case SP_FileDialogDetailedView:
- {
- icon = d->createIcon(QLatin1String("view-list-details.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("view_detailed.png"));
+ icon = QIcon::fromTheme(QLatin1String("view-list-details"));
break;
- }
case SP_FileDialogListView:
- {
- icon = d->createIcon(QLatin1String("view-list-icons.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("view_icon.png"));
+ icon = QIcon::fromTheme(QLatin1String("view-list-icons"));
break;
- }
case SP_BrowserReload:
- {
- icon = d->createIcon(QLatin1String("view-refresh.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("reload.png"));
+ icon = QIcon::fromTheme(QLatin1String("view-refresh"));
break;
- }
case SP_BrowserStop:
- {
- icon = d->createIcon(QLatin1String("process-stop.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("stop.png"));
+ icon = QIcon::fromTheme(QLatin1String("process-stop"));
break;
- }
case SP_MediaPlay:
- {
- icon = d->createIcon(QLatin1String("media-playback-start.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("player_play.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-playback-start"));
break;
- }
case SP_MediaPause:
- {
- icon = d->createIcon(QLatin1String("media-playback-pause.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("player_pause.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-playback-pause"));
break;
- }
case SP_MediaStop:
- {
- icon = d->createIcon(QLatin1String("media-playback-stop.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("player_stop.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-playback-stop"));
break;
- }
case SP_MediaSeekForward:
- {
- icon = d->createIcon(QLatin1String("media-skip-forward.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("player_fwd.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-seek-forward"));
break;
- }
case SP_MediaSeekBackward:
- {
- icon = d->createIcon(QLatin1String("media-skip-backward.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("player_rew.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-seek-backward"));
break;
- }
case SP_MediaSkipForward:
- {
- icon = d->createIcon(QLatin1String("media-skip-forward.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("player_end.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-skip-forward"));
break;
- }
case SP_MediaSkipBackward:
- {
- icon = d->createIcon(QLatin1String("media-skip-backward.png"));
- if (icon.isNull())
- icon = d->createIcon(QLatin1String("player_start.png"));
+ icon = QIcon::fromTheme(QLatin1String("media-skip-backward"));
break;
- }
-
- case SP_FileLinkIcon: {
- icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget));
- QPixmap pixmap = d->findIcon(32, QLatin1String("link_overlay.png"));
- if (!pixmap.isNull()) {
- QPixmap fileIcon = d->findIcon(32, QLatin1String("text-x-generic.png"));
- if (fileIcon.isNull())
- fileIcon = d->findIcon(32, QLatin1String("empty.png"));
- if (!fileIcon.isNull()) {
- QPainter painter(&fileIcon);
- painter.drawPixmap(0, 0, 32, 32, pixmap);
- icon.addPixmap(fileIcon);
+ case SP_MediaVolume:
+ icon = QIcon::fromTheme(QLatin1String("audio-volume-medium"));
+ break;
+ case SP_MediaVolumeMuted:
+ icon = QIcon::fromTheme(QLatin1String("audio-volume-muted"));
+ break;
+ case SP_DialogResetButton:
+ icon = QIcon::fromTheme(QLatin1String("edit-clear"));
+ break;
+ case SP_ArrowForward:
+ if (QApplication::layoutDirection() == Qt::RightToLeft)
+ return standardIconImplementation(SP_ArrowLeft, option, widget);
+ return standardIconImplementation(SP_ArrowRight, option, widget);
+ case SP_ArrowBack:
+ if (QApplication::layoutDirection() == Qt::RightToLeft)
+ return standardIconImplementation(SP_ArrowRight, option, widget);
+ return standardIconImplementation(SP_ArrowLeft, option, widget);
+ case SP_FileLinkIcon:
+ {
+ QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link"));
+ if (!linkIcon.isNull()) {
+ QIcon baseIcon = standardIconImplementation(SP_FileIcon, option, widget);
+ const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off);
+ for (int i = 0 ; i < sizes.size() ; ++i) {
+ int size = sizes[i].width();
+ QPixmap basePixmap = baseIcon.pixmap(size);
+ QPixmap linkPixmap = linkIcon.pixmap(size/2);
+ QPainter painter(&basePixmap);
+ painter.drawPixmap(size/2, size/2, linkPixmap);
+ icon.addPixmap(basePixmap);
+ }
}
}
- }
- break;
- case SP_DirLinkIcon: {
- icon = QIcon(proxy()->standardPixmap(standardIcon, option, widget));
- QPixmap pixmap = d->findIcon(32, QLatin1String("link_overlay.png"));
- if (!pixmap.isNull()) {
- QPixmap fileIcon = d->findIcon(32, QLatin1String("folder.png"));
- if (!fileIcon.isNull()) {
- QPainter painter(&fileIcon);
- painter.drawPixmap(0, 0, 32, 32, pixmap);
- icon.addPixmap(fileIcon);
+ break;
+ case SP_DirLinkIcon:
+ {
+ QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link"));
+ if (!linkIcon.isNull()) {
+ QIcon baseIcon = standardIconImplementation(SP_DirIcon, option, widget);
+ const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off);
+ for (int i = 0 ; i < sizes.size() ; ++i) {
+ int size = sizes[i].width();
+ QPixmap basePixmap = baseIcon.pixmap(size);
+ QPixmap linkPixmap = linkIcon.pixmap(size/2);
+ QPainter painter(&basePixmap);
+ painter.drawPixmap(size/2, size/2, linkPixmap);
+ icon.addPixmap(basePixmap);
+ }
}
- }
}
break;
default:
break;
}
+
if (!icon.isNull())
return icon;
-#elif defined(Q_WS_MAC)
+#if defined(Q_WS_MAC)
OSType iconType = 0;
switch (standardIcon) {
case QStyle::SP_MessageBoxQuestion:
@@ -6131,11 +5771,9 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons
ReleaseIconRef(overlayIcon);
return retIcon;
}
-
-#endif //Q_WS_X11 || Q_WS_MAC
+#endif // Q_WS_MAC
}
-
switch (standardIcon) {
#ifndef QT_NO_IMAGEFORMAT_PNG
case SP_FileDialogNewFolder:
diff --git a/src/gui/styles/qcommonstyle_p.h b/src/gui/styles/qcommonstyle_p.h
index f2af5b2..cff46e6 100644
--- a/src/gui/styles/qcommonstyle_p.h
+++ b/src/gui/styles/qcommonstyle_p.h
@@ -122,20 +122,7 @@ public:
}
#endif
mutable QIcon tabBarcloseButtonIcon;
-
-//icon detection on X11
-#ifdef Q_WS_X11
- void lookupIconTheme() const;
int lookupToolButtonStyle() const;
- QIcon createIcon(const QString &) const;
- QPixmap findIcon(int size, const QString &) const;
- QPixmap findIconHelper(int size, const QString &, const QString &, QStringList &visited) const;
- QIconTheme parseIndexFile(const QString &themeName) const;
- mutable QString themeName;
- mutable QStringList iconDirs;
- mutable QHash <QString, QIconTheme> themeList;
-#endif
-
};
QT_END_NAMESPACE
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index 660b4c3..f6d8c88 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -3239,6 +3239,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
return newSize;
}
+
/*! \reimp */
QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
const QWidget *widget) const
@@ -3271,65 +3272,80 @@ QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
}
break;
- case SP_DialogDiscardButton: {
+ case SP_DialogDiscardButton:
return QGtkPainter::getIcon(GTK_STOCK_DELETE);
- }
-
- case SP_DialogOkButton: {
+ case SP_DialogOkButton:
return QGtkPainter::getIcon(GTK_STOCK_OK);
- }
-
- case SP_DialogCancelButton: {
+ case SP_DialogCancelButton:
return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
- }
-
- case SP_DialogYesButton: {
+ case SP_DialogYesButton:
return QGtkPainter::getIcon(GTK_STOCK_YES);
- }
-
- case SP_DialogNoButton: {
+ case SP_DialogNoButton:
return QGtkPainter::getIcon(GTK_STOCK_NO);
- }
-
- case SP_DialogOpenButton: {
+ case SP_DialogOpenButton:
return QGtkPainter::getIcon(GTK_STOCK_OPEN);
- }
-
- case SP_DialogCloseButton: {
+ case SP_DialogCloseButton:
return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
- }
-
- case SP_DialogApplyButton: {
+ case SP_DialogApplyButton:
return QGtkPainter::getIcon(GTK_STOCK_APPLY);
- }
-
- case SP_DialogSaveButton: {
+ case SP_DialogSaveButton:
return QGtkPainter::getIcon(GTK_STOCK_SAVE);
- }
-
- case SP_MessageBoxWarning: {
+ case SP_MessageBoxWarning:
return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
- }
-
- case SP_MessageBoxQuestion: {
+ case SP_MessageBoxQuestion:
return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
- }
-
- case SP_MessageBoxInformation: {
+ case SP_MessageBoxInformation:
return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- }
-
- case SP_MessageBoxCritical: {
+ case SP_MessageBoxCritical:
return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
- }
-
default:
return QCleanlooksStyle::standardPixmap(sp, option, widget);
}
+ return pixmap;
+}
- return QPixmap();
+/*!
+ \internal
+*/
+QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QGtk::isThemeAvailable())
+ return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
+ switch (standardIcon) {
+ case SP_DialogDiscardButton:
+ return QGtkPainter::getIcon(GTK_STOCK_DELETE);
+ case SP_DialogOkButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OK);
+ case SP_DialogCancelButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
+ case SP_DialogYesButton:
+ return QGtkPainter::getIcon(GTK_STOCK_YES);
+ case SP_DialogNoButton:
+ return QGtkPainter::getIcon(GTK_STOCK_NO);
+ case SP_DialogOpenButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OPEN);
+ case SP_DialogCloseButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
+ case SP_DialogApplyButton:
+ return QGtkPainter::getIcon(GTK_STOCK_APPLY);
+ case SP_DialogSaveButton:
+ return QGtkPainter::getIcon(GTK_STOCK_SAVE);
+ case SP_MessageBoxWarning:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxQuestion:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxInformation:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxCritical:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
+ default:
+ return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
+ }
}
+
/*! \reimp */
QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
{
diff --git a/src/gui/styles/qgtkstyle.h b/src/gui/styles/qgtkstyle.h
index e12f175..f12de52 100644
--- a/src/gui/styles/qgtkstyle.h
+++ b/src/gui/styles/qgtkstyle.h
@@ -106,6 +106,10 @@ public:
void unpolish(QWidget *widget);
void unpolish(QApplication *app);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
};
diff --git a/tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.png b/tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.png
new file mode 100644
index 0000000..18b7c67
--- /dev/null
+++ b/tests/auto/qicon/icons/testtheme/16x16/actions/appointment-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.png b/tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.png
new file mode 100644
index 0000000..d676ffd
--- /dev/null
+++ b/tests/auto/qicon/icons/testtheme/22x22/actions/appointment-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.png b/tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.png
new file mode 100644
index 0000000..85daef3
--- /dev/null
+++ b/tests/auto/qicon/icons/testtheme/32x32/actions/appointment-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/testtheme/index.theme b/tests/auto/qicon/icons/testtheme/index.theme
new file mode 100644
index 0000000..e18736a
--- /dev/null
+++ b/tests/auto/qicon/icons/testtheme/index.theme
@@ -0,0 +1,492 @@
+[Icon Theme]
+_Name=Test
+_Comment=Test Theme
+Inherits=crystalsvg, themeparent
+Example=x-directory-normal
+
+# KDE Specific Stuff
+DisplayDepth=32
+LinkOverlay=link_overlay
+LockOverlay=lock_overlay
+ZipOverlay=zip_overlay
+DesktopDefault=48
+DesktopSizes=16,22,32,48,64,72,96,128
+ToolbarDefault=22
+ToolbarSizes=16,22,32,48
+MainToolbarDefault=22
+MainToolbarSizes=16,22,32,48
+SmallDefault=16
+SmallSizes=16
+PanelDefault=32
+PanelSizes=16,22,32,48,64,72,96,128
+
+# Directory list
+Directories=16x16/actions,16x16/apps,16x16/categories,16x16/devices,16x16/emblems,16x16/emotes,16x16/mimetypes,16x16/places,16x16/status,22x22/actions,22x22/apps,22x22/categories,22x22/devices,22x22/emblems,22x22/emotes,22x22/mimetypes,22x22/places,22x22/status,24x24/actions,24x24/apps,24x24/categories,24x24/devices,24x24/emblems,24x24/emotes,24x24/mimetypes,24x24/places,24x24/status,32x32/actions,32x32/apps,32x32/categories,32x32/devices,32x32/emblems,32x32/emotes,32x32/mimetypes,32x32/places,32x32/status,48x48/actions,48x48/apps,48x48/categories,48x48/devices,48x48/emblems,48x48/emotes,48x48/mimetypes,48x48/places,48x48/status,64x64/actions,64x64/apps,64x64/categories,64x64/devices,64x64/emblems,64x64/emotes,64x64/mimetypes,64x64/places,64x64/status,72x72/actions,72x72/apps,72x72/categories,72x72/devices,72x72/emblems,72x72/emotes,72x72/mimetypes,72x72/places,72x72/status,96x96/actions,96x96/apps,96x96/categories,96x96/devices,96x96/emblems,96x96/emotes,96x96/mimetypes,96x96/places,96x96/status,128x128/actions,128x128/apps,128x128/categories,128x128/devices,128x128/emblems,128x128/emotes,128x128/mimetypes,128x128/places,128x128/status,scalable/actions,scalable/apps,scalable/categories,scalable/devices,scalable/emblems,scalable/emotes,scalable/mimetypes,scalable/places,scalable/status
+
+[16x16/actions]
+Size=16
+Context=Actions
+Type=Fixed
+
+[16x16/apps]
+Size=16
+Context=Applications
+Type=Fixed
+
+[16x16/categories]
+Size=16
+Context=Categories
+Type=Fixed
+
+[16x16/devices]
+Size=16
+Context=Devices
+Type=Fixed
+
+[16x16/emblems]
+Size=16
+Context=Emblems
+Type=Fixed
+
+[16x16/emotes]
+Size=16
+Context=Emotes
+Type=Fixed
+
+[16x16/mimetypes]
+Size=16
+Context=MimeTypes
+Type=Fixed
+
+[16x16/places]
+Size=16
+Context=Places
+Type=Fixed
+
+[16x16/status]
+Size=16
+Context=Status
+Type=Fixed
+
+[22x22/actions]
+Size=22
+Context=Actions
+Type=Fixed
+
+[22x22/apps]
+Size=22
+Context=Applications
+Type=Fixed
+
+[22x22/categories]
+Size=22
+Context=Categories
+Type=Fixed
+
+[22x22/devices]
+Size=22
+Context=Devices
+Type=Fixed
+
+[22x22/emblems]
+Size=22
+Context=Emblems
+Type=Fixed
+
+[22x22/emotes]
+Size=22
+Context=Emotes
+Type=Fixed
+
+[22x22/mimetypes]
+Size=22
+Context=MimeTypes
+Type=Fixed
+
+[22x22/places]
+Size=22
+Context=Places
+Type=Fixed
+
+[22x22/status]
+Size=22
+Context=Status
+Type=Fixed
+
+[24x24/actions]
+Size=24
+Context=Actions
+Type=Fixed
+
+[24x24/apps]
+Size=24
+Context=Applications
+Type=Fixed
+
+[24x24/categories]
+Size=24
+Context=Categories
+Type=Fixed
+
+[24x24/devices]
+Size=24
+Context=Devices
+Type=Fixed
+
+[24x24/emblems]
+Size=24
+Context=Emblems
+Type=Fixed
+
+[24x24/emotes]
+Size=24
+Context=Emotes
+Type=Fixed
+
+[24x24/mimetypes]
+Size=24
+Context=MimeTypes
+Type=Fixed
+
+[24x24/places]
+Size=24
+Context=Places
+Type=Fixed
+
+[24x24/status]
+Size=24
+Context=Status
+Type=Fixed
+
+[32x32/actions]
+Size=32
+Context=Actions
+Type=Fixed
+
+[32x32/apps]
+Size=32
+Context=Applications
+Type=Fixed
+
+[32x32/categories]
+Size=32
+Context=Categories
+Type=Fixed
+
+[32x32/devices]
+Size=32
+Context=Devices
+Type=Fixed
+
+[32x32/emblems]
+Size=32
+Context=Emblems
+Type=Fixed
+
+[32x32/emotes]
+Size=32
+Context=Emotes
+Type=Fixed
+
+[32x32/mimetypes]
+Size=32
+Context=MimeTypes
+Type=Fixed
+
+[32x32/places]
+Size=32
+Context=Places
+Type=Fixed
+
+[32x32/status]
+Size=32
+Context=Status
+Type=Fixed
+
+[48x48/actions]
+Size=48
+Context=Actions
+Type=Fixed
+
+[48x48/apps]
+Size=48
+Context=Applications
+Type=Fixed
+
+[48x48/categories]
+Size=48
+Context=Categories
+Type=Fixed
+
+[48x48/devices]
+Size=48
+Context=Devices
+Type=Fixed
+
+[48x48/emblems]
+Size=48
+Context=Emblems
+Type=Fixed
+
+[48x48/emotes]
+Size=48
+Context=Emotes
+Type=Fixed
+
+[48x48/mimetypes]
+Size=48
+Context=MimeTypes
+Type=Fixed
+
+[48x48/places]
+Size=48
+Context=Places
+Type=Fixed
+
+[48x48/status]
+Size=48
+Context=Status
+Type=Fixed
+
+[64x64/actions]
+Size=64
+Context=Actions
+Type=Fixed
+
+[64x64/apps]
+Size=64
+Context=Applications
+Type=Fixed
+
+[64x64/categories]
+Size=64
+Context=Categories
+Type=Fixed
+
+[64x64/devices]
+Size=64
+Context=Devices
+Type=Fixed
+
+[64x64/emblems]
+Size=64
+Context=Emblems
+Type=Fixed
+
+[64x64/emotes]
+Size=64
+Context=Emotes
+Type=Fixed
+
+[64x64/mimetypes]
+Size=64
+Context=MimeTypes
+Type=Fixed
+
+[64x64/places]
+Size=64
+Context=Places
+Type=Fixed
+
+[64x64/status]
+Size=64
+Context=Status
+Type=Fixed
+
+[72x72/actions]
+Size=72
+Context=Actions
+Type=Fixed
+
+[72x72/apps]
+Size=72
+Context=Applications
+Type=Fixed
+
+[72x72/categories]
+Size=72
+Context=Categories
+Type=Fixed
+
+[72x72/devices]
+Size=72
+Context=Devices
+Type=Fixed
+
+[72x72/emblems]
+Size=72
+Context=Emblems
+Type=Fixed
+
+[72x72/emotes]
+Size=72
+Context=Emotes
+Type=Fixed
+
+[72x72/mimetypes]
+Size=72
+Context=MimeTypes
+Type=Fixed
+
+[72x72/places]
+Size=72
+Context=Places
+Type=Fixed
+
+[72x72/status]
+Size=72
+Context=Status
+Type=Fixed
+
+[96x96/actions]
+Size=96
+Context=Actions
+Type=Fixed
+
+[96x96/apps]
+Size=96
+Context=Applications
+Type=Fixed
+
+[96x96/categories]
+Size=96
+Context=Categories
+Type=Fixed
+
+[96x96/devices]
+Size=96
+Context=Devices
+Type=Fixed
+
+[96x96/emblems]
+Size=96
+Context=Emblems
+Type=Fixed
+
+[96x96/emotes]
+Size=96
+Context=Emotes
+Type=Fixed
+
+[96x96/mimetypes]
+Size=96
+Context=MimeTypes
+Type=Fixed
+
+[96x96/places]
+Size=96
+Context=Places
+Type=Fixed
+
+[96x96/status]
+Size=96
+Context=Status
+Type=Fixed
+
+[128x128/actions]
+Size=128
+Context=Actions
+Type=Fixed
+
+[128x128/apps]
+Size=128
+Context=Applications
+Type=Fixed
+
+[128x128/categories]
+Size=128
+Context=Categories
+Type=Fixed
+
+[128x128/devices]
+Size=128
+Context=Devices
+Type=Fixed
+
+[128x128/emblems]
+Size=128
+Context=Emblems
+Type=Fixed
+
+[128x128/emotes]
+Size=128
+Context=Emotes
+Type=Fixed
+
+[128x128/mimetypes]
+Size=128
+Context=MimeTypes
+Type=Fixed
+
+[128x128/places]
+Size=128
+Context=Places
+Type=Fixed
+
+[128x128/status]
+Size=128
+Context=Status
+Type=Fixed
+
+[scalable/actions]
+Size=48
+Context=Actions
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/apps]
+Size=48
+Context=Applications
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/categories]
+Size=48
+Context=Categories
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/devices]
+Size=48
+Context=Devices
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/emblems]
+Size=48
+Context=Emblems
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/emotes]
+Size=48
+Context=Emotes
+Type=Scalable
+Minsize=32
+MaxSize=256
+
+[scalable/mimetypes]
+Size=48
+Context=MimeTypes
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/places]
+Size=48
+Context=Places
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/status]
+Size=48
+Context=Status
+Type=Scalable
+MinSize=32
+MaxSize=256
diff --git a/tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg b/tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg
new file mode 100644
index 0000000..4cb14f8
--- /dev/null
+++ b/tests/auto/qicon/icons/testtheme/scalable/actions/svg-only.svg
@@ -0,0 +1,425 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="90.000000"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+ width="48px"
+ height="48px"
+ id="svg11300"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
+ sodipodi:docname="appointment-new.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective59" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5204">
+ <stop
+ style="stop-color:#c4a000;stop-opacity:1;"
+ offset="0"
+ id="stop5206" />
+ <stop
+ style="stop-color:#c4a000;stop-opacity:0;"
+ offset="1"
+ id="stop5208" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5196">
+ <stop
+ style="stop-color:#c4a000;stop-opacity:1;"
+ offset="0"
+ id="stop5198" />
+ <stop
+ style="stop-color:#c4a000;stop-opacity:0;"
+ offset="1"
+ id="stop5200" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12512">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop12513" />
+ <stop
+ style="stop-color:#fff520;stop-opacity:0.89108908;"
+ offset="0.50000000"
+ id="stop12517" />
+ <stop
+ style="stop-color:#fff300;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop12514" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12512"
+ id="radialGradient278"
+ gradientUnits="userSpaceOnUse"
+ cx="55.000000"
+ cy="125.00000"
+ fx="55.000000"
+ fy="125.00000"
+ r="14.375000" />
+ <linearGradient
+ id="linearGradient10653">
+ <stop
+ style="stop-color:#f3f4ff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop10655" />
+ <stop
+ style="stop-color:#9193af;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop10657" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42174">
+ <stop
+ style="stop-color:#a0a0a0;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop42176" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop42178" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2145">
+ <stop
+ style="stop-color:#fffffd;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2147" />
+ <stop
+ style="stop-color:#cbcbc9;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2149" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37935">
+ <stop
+ id="stop37937"
+ offset="0.0000000"
+ style="stop-color:#9497b3;stop-opacity:1.0000000;" />
+ <stop
+ id="stop37939"
+ offset="1.0000000"
+ style="stop-color:#4c4059;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2152">
+ <stop
+ id="stop2154"
+ offset="0.0000000"
+ style="stop-color:#9aa29a;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2156"
+ offset="1.0000000"
+ style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3816">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3818" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3820" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3816"
+ id="radialGradient3822"
+ cx="31.112698"
+ cy="19.008621"
+ fx="31.112698"
+ fy="19.008621"
+ r="8.6620579"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2152"
+ id="linearGradient4307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.123841,0.000000,0.000000,0.969691,-31.88758,-19.59492)"
+ x1="8.9156475"
+ y1="37.197018"
+ x2="9.8855033"
+ y2="52.090678" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10653"
+ id="radialGradient4309"
+ gradientUnits="userSpaceOnUse"
+ cx="11.329200"
+ cy="10.583970"
+ fx="11.329200"
+ fy="10.583970"
+ r="15.532059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2145"
+ id="radialGradient4311"
+ gradientUnits="userSpaceOnUse"
+ cx="11.901996"
+ cy="10.045444"
+ fx="11.901996"
+ fy="10.045444"
+ r="29.292715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42174"
+ id="linearGradient4313"
+ gradientUnits="userSpaceOnUse"
+ x1="6.3422160"
+ y1="7.7893324"
+ x2="22.218424"
+ y2="25.884274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5196"
+ id="radialGradient5202"
+ cx="23.375"
+ cy="10.972863"
+ fx="23.375"
+ fy="10.972863"
+ r="3.3478092"
+ gradientTransform="matrix(3.630420,1.654030e-15,-1.608743e-15,3.742066,-61.48607,-29.18618)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5204"
+ id="linearGradient5210"
+ x1="19.667364"
+ y1="4.2570662"
+ x2="20.329933"
+ y2="5.2845874"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37935"
+ id="radialGradient5212"
+ gradientUnits="userSpaceOnUse"
+ cx="8.7468252"
+ cy="6.8283234"
+ fx="8.7468252"
+ fy="6.8283234"
+ r="29.889715" />
+ </defs>
+ <sodipodi:namedview
+ stroke="#c4a000"
+ fill="#babdb6"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.25490196"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313708"
+ inkscape:cx="13.2248"
+ inkscape:cy="25.106052"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="833"
+ inkscape:window-height="772"
+ inkscape:window-x="305"
+ inkscape:window-y="76" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:title>New Appointment</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>appointment</rdf:li>
+ <rdf:li>new</rdf:li>
+ <rdf:li>meeting</rdf:li>
+ <rdf:li>rvsp</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4318"
+ style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(2.563158,0.000000,0.000000,1.219602,-55.98414,14.04144)" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path14341"
+ d="M 18.587591,1.403729 L 4.226755,18.096665 L 5.4854717,19.339844 L 18.587591,1.403729 z "
+ style="color:#000000;fill:url(#linearGradient4307);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path18921"
+ d="M 18.467176,1.3138035 L 5.6605716,19.072612 L 7.4900985,20.687913 L 18.467176,1.3138035 z "
+ style="fill:#fefefe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" />
+ <path
+ transform="matrix(1.431529,0.000000,0.000000,1.431529,0.569459,-1.654618)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path27786"
+ style="fill:url(#radialGradient5212);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:0.69855404;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.163838,0.000000,0.000000,1.163838,4.824801,2.777556)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path35549"
+ style="fill:url(#radialGradient4311);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4313);stroke-width:0.71139598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:url(#radialGradient5202);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5210);stroke-width:0.56498736;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path4120"
+ sodipodi:cx="23.375"
+ sodipodi:cy="11.875"
+ sodipodi:rx="8.5"
+ sodipodi:ry="8.5"
+ d="M 16.679382,6.6387137 A 8.5,8.5 0 0 1 23.332691,3.3751053 L 23.375,11.875 z"
+ transform="matrix(1.769951,0.000000,0.000000,1.769951,-17.02424,1.610741)"
+ sodipodi:start="3.8052902"
+ sodipodi:end="4.7074114" />
+ <path
+ transform="matrix(2.073295,0.000000,0.000000,2.073295,-7.310224,-13.13682)"
+ d="M 16.40625 17.28125 A 1.21875 1.21875 0 1 1 13.96875,17.28125 A 1.21875 1.21875 0 1 1 16.40625 17.28125 z"
+ sodipodi:ry="1.21875"
+ sodipodi:rx="1.21875"
+ sodipodi:cy="17.28125"
+ sodipodi:cx="15.1875"
+ id="path34778"
+ style="fill:#f3f3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48232403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ id="path35559"
+ d="M 22.176614,20.718014 L 13.155702,13.140282"
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ id="path35561"
+ d="M 19.408614,29.776506 L 22.368655,25.283228"
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,-12.40939)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35563"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,14.80922)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35565"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-35.91004,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35567"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-8.691448,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35569"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient4309);stroke-width:0.73656511;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ id="path10651"
+ sodipodi:cx="16.25"
+ sodipodi:cy="16.910715"
+ sodipodi:rx="14.910714"
+ sodipodi:ry="14.910714"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ transform="matrix(1.357654,0.000000,0.000000,1.357654,1.769896,-0.493735)" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#radialGradient278);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25000024;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block"
+ id="path12511"
+ sodipodi:cx="55"
+ sodipodi:cy="125"
+ sodipodi:rx="14.375"
+ sodipodi:ry="14.375"
+ d="M 69.375 125 A 14.375 14.375 0 1 1 40.625,125 A 14.375 14.375 0 1 1 69.375 125 z"
+ transform="matrix(0.611127,0.000000,0.000000,0.611127,5.544052,-66.92818)"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/stock_new-16.png"
+ inkscape:export-xdpi="33.852203"
+ inkscape:export-ydpi="33.852203" />
+ </g>
+</svg>
diff --git a/tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.png b/tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.png
new file mode 100644
index 0000000..2098cfd
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/16x16/actions/address-book-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.png b/tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.png
new file mode 100644
index 0000000..18b7c67
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/16x16/actions/appointment-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.png b/tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.png
new file mode 100644
index 0000000..fad446c
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/22x22/actions/address-book-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.png b/tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.png
new file mode 100644
index 0000000..d676ffd
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/22x22/actions/appointment-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.png b/tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.png
new file mode 100644
index 0000000..420139d
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/32x32/actions/address-book-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.png b/tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.png
new file mode 100644
index 0000000..85daef3
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/32x32/actions/appointment-new.png
Binary files differ
diff --git a/tests/auto/qicon/icons/themeparent/index.theme b/tests/auto/qicon/icons/themeparent/index.theme
new file mode 100644
index 0000000..e536a0b
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/index.theme
@@ -0,0 +1,492 @@
+[Icon Theme]
+_Name=Test
+_Comment=Test Theme
+Inherits=gnome,crystalsvg
+Example=x-directory-normal
+
+# KDE Specific Stuff
+DisplayDepth=32
+LinkOverlay=link_overlay
+LockOverlay=lock_overlay
+ZipOverlay=zip_overlay
+DesktopDefault=48
+DesktopSizes=16,22,32,48,64,72,96,128
+ToolbarDefault=22
+ToolbarSizes=16,22,32,48
+MainToolbarDefault=22
+MainToolbarSizes=16,22,32,48
+SmallDefault=16
+SmallSizes=16
+PanelDefault=32
+PanelSizes=16,22,32,48,64,72,96,128
+
+# Directory list
+Directories=16x16/actions,16x16/apps,16x16/categories,16x16/devices,16x16/emblems,16x16/emotes,16x16/mimetypes,16x16/places,16x16/status,22x22/actions,22x22/apps,22x22/categories,22x22/devices,22x22/emblems,22x22/emotes,22x22/mimetypes,22x22/places,22x22/status,24x24/actions,24x24/apps,24x24/categories,24x24/devices,24x24/emblems,24x24/emotes,24x24/mimetypes,24x24/places,24x24/status,32x32/actions,32x32/apps,32x32/categories,32x32/devices,32x32/emblems,32x32/emotes,32x32/mimetypes,32x32/places,32x32/status,48x48/actions,48x48/apps,48x48/categories,48x48/devices,48x48/emblems,48x48/emotes,48x48/mimetypes,48x48/places,48x48/status,64x64/actions,64x64/apps,64x64/categories,64x64/devices,64x64/emblems,64x64/emotes,64x64/mimetypes,64x64/places,64x64/status,72x72/actions,72x72/apps,72x72/categories,72x72/devices,72x72/emblems,72x72/emotes,72x72/mimetypes,72x72/places,72x72/status,96x96/actions,96x96/apps,96x96/categories,96x96/devices,96x96/emblems,96x96/emotes,96x96/mimetypes,96x96/places,96x96/status,128x128/actions,128x128/apps,128x128/categories,128x128/devices,128x128/emblems,128x128/emotes,128x128/mimetypes,128x128/places,128x128/status,scalable/actions,scalable/apps,scalable/categories,scalable/devices,scalable/emblems,scalable/emotes,scalable/mimetypes,scalable/places,scalable/status
+
+[16x16/actions]
+Size=16
+Context=Actions
+Type=Fixed
+
+[16x16/apps]
+Size=16
+Context=Applications
+Type=Fixed
+
+[16x16/categories]
+Size=16
+Context=Categories
+Type=Fixed
+
+[16x16/devices]
+Size=16
+Context=Devices
+Type=Fixed
+
+[16x16/emblems]
+Size=16
+Context=Emblems
+Type=Fixed
+
+[16x16/emotes]
+Size=16
+Context=Emotes
+Type=Fixed
+
+[16x16/mimetypes]
+Size=16
+Context=MimeTypes
+Type=Fixed
+
+[16x16/places]
+Size=16
+Context=Places
+Type=Fixed
+
+[16x16/status]
+Size=16
+Context=Status
+Type=Fixed
+
+[22x22/actions]
+Size=22
+Context=Actions
+Type=Fixed
+
+[22x22/apps]
+Size=22
+Context=Applications
+Type=Fixed
+
+[22x22/categories]
+Size=22
+Context=Categories
+Type=Fixed
+
+[22x22/devices]
+Size=22
+Context=Devices
+Type=Fixed
+
+[22x22/emblems]
+Size=22
+Context=Emblems
+Type=Fixed
+
+[22x22/emotes]
+Size=22
+Context=Emotes
+Type=Fixed
+
+[22x22/mimetypes]
+Size=22
+Context=MimeTypes
+Type=Fixed
+
+[22x22/places]
+Size=22
+Context=Places
+Type=Fixed
+
+[22x22/status]
+Size=22
+Context=Status
+Type=Fixed
+
+[24x24/actions]
+Size=24
+Context=Actions
+Type=Fixed
+
+[24x24/apps]
+Size=24
+Context=Applications
+Type=Fixed
+
+[24x24/categories]
+Size=24
+Context=Categories
+Type=Fixed
+
+[24x24/devices]
+Size=24
+Context=Devices
+Type=Fixed
+
+[24x24/emblems]
+Size=24
+Context=Emblems
+Type=Fixed
+
+[24x24/emotes]
+Size=24
+Context=Emotes
+Type=Fixed
+
+[24x24/mimetypes]
+Size=24
+Context=MimeTypes
+Type=Fixed
+
+[24x24/places]
+Size=24
+Context=Places
+Type=Fixed
+
+[24x24/status]
+Size=24
+Context=Status
+Type=Fixed
+
+[32x32/actions]
+Size=32
+Context=Actions
+Type=Fixed
+
+[32x32/apps]
+Size=32
+Context=Applications
+Type=Fixed
+
+[32x32/categories]
+Size=32
+Context=Categories
+Type=Fixed
+
+[32x32/devices]
+Size=32
+Context=Devices
+Type=Fixed
+
+[32x32/emblems]
+Size=32
+Context=Emblems
+Type=Fixed
+
+[32x32/emotes]
+Size=32
+Context=Emotes
+Type=Fixed
+
+[32x32/mimetypes]
+Size=32
+Context=MimeTypes
+Type=Fixed
+
+[32x32/places]
+Size=32
+Context=Places
+Type=Fixed
+
+[32x32/status]
+Size=32
+Context=Status
+Type=Fixed
+
+[48x48/actions]
+Size=48
+Context=Actions
+Type=Fixed
+
+[48x48/apps]
+Size=48
+Context=Applications
+Type=Fixed
+
+[48x48/categories]
+Size=48
+Context=Categories
+Type=Fixed
+
+[48x48/devices]
+Size=48
+Context=Devices
+Type=Fixed
+
+[48x48/emblems]
+Size=48
+Context=Emblems
+Type=Fixed
+
+[48x48/emotes]
+Size=48
+Context=Emotes
+Type=Fixed
+
+[48x48/mimetypes]
+Size=48
+Context=MimeTypes
+Type=Fixed
+
+[48x48/places]
+Size=48
+Context=Places
+Type=Fixed
+
+[48x48/status]
+Size=48
+Context=Status
+Type=Fixed
+
+[64x64/actions]
+Size=64
+Context=Actions
+Type=Fixed
+
+[64x64/apps]
+Size=64
+Context=Applications
+Type=Fixed
+
+[64x64/categories]
+Size=64
+Context=Categories
+Type=Fixed
+
+[64x64/devices]
+Size=64
+Context=Devices
+Type=Fixed
+
+[64x64/emblems]
+Size=64
+Context=Emblems
+Type=Fixed
+
+[64x64/emotes]
+Size=64
+Context=Emotes
+Type=Fixed
+
+[64x64/mimetypes]
+Size=64
+Context=MimeTypes
+Type=Fixed
+
+[64x64/places]
+Size=64
+Context=Places
+Type=Fixed
+
+[64x64/status]
+Size=64
+Context=Status
+Type=Fixed
+
+[72x72/actions]
+Size=72
+Context=Actions
+Type=Fixed
+
+[72x72/apps]
+Size=72
+Context=Applications
+Type=Fixed
+
+[72x72/categories]
+Size=72
+Context=Categories
+Type=Fixed
+
+[72x72/devices]
+Size=72
+Context=Devices
+Type=Fixed
+
+[72x72/emblems]
+Size=72
+Context=Emblems
+Type=Fixed
+
+[72x72/emotes]
+Size=72
+Context=Emotes
+Type=Fixed
+
+[72x72/mimetypes]
+Size=72
+Context=MimeTypes
+Type=Fixed
+
+[72x72/places]
+Size=72
+Context=Places
+Type=Fixed
+
+[72x72/status]
+Size=72
+Context=Status
+Type=Fixed
+
+[96x96/actions]
+Size=96
+Context=Actions
+Type=Fixed
+
+[96x96/apps]
+Size=96
+Context=Applications
+Type=Fixed
+
+[96x96/categories]
+Size=96
+Context=Categories
+Type=Fixed
+
+[96x96/devices]
+Size=96
+Context=Devices
+Type=Fixed
+
+[96x96/emblems]
+Size=96
+Context=Emblems
+Type=Fixed
+
+[96x96/emotes]
+Size=96
+Context=Emotes
+Type=Fixed
+
+[96x96/mimetypes]
+Size=96
+Context=MimeTypes
+Type=Fixed
+
+[96x96/places]
+Size=96
+Context=Places
+Type=Fixed
+
+[96x96/status]
+Size=96
+Context=Status
+Type=Fixed
+
+[128x128/actions]
+Size=128
+Context=Actions
+Type=Fixed
+
+[128x128/apps]
+Size=128
+Context=Applications
+Type=Fixed
+
+[128x128/categories]
+Size=128
+Context=Categories
+Type=Fixed
+
+[128x128/devices]
+Size=128
+Context=Devices
+Type=Fixed
+
+[128x128/emblems]
+Size=128
+Context=Emblems
+Type=Fixed
+
+[128x128/emotes]
+Size=128
+Context=Emotes
+Type=Fixed
+
+[128x128/mimetypes]
+Size=128
+Context=MimeTypes
+Type=Fixed
+
+[128x128/places]
+Size=128
+Context=Places
+Type=Fixed
+
+[128x128/status]
+Size=128
+Context=Status
+Type=Fixed
+
+[scalable/actions]
+Size=48
+Context=Actions
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/apps]
+Size=48
+Context=Applications
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/categories]
+Size=48
+Context=Categories
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/devices]
+Size=48
+Context=Devices
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/emblems]
+Size=48
+Context=Emblems
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/emotes]
+Size=48
+Context=Emotes
+Type=Scalable
+Minsize=32
+MaxSize=256
+
+[scalable/mimetypes]
+Size=48
+Context=MimeTypes
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/places]
+Size=48
+Context=Places
+Type=Scalable
+MinSize=32
+MaxSize=256
+
+[scalable/status]
+Size=48
+Context=Status
+Type=Scalable
+MinSize=32
+MaxSize=256
diff --git a/tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg b/tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg
new file mode 100644
index 0000000..600a82c
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/scalable/actions/address-book-new.svg
@@ -0,0 +1,389 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1256"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="address-book-new.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective58" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5060">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop5062" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5064" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5048">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop5050" />
+ <stop
+ id="stop5056"
+ offset="0.5"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5052" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12512">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop12513" />
+ <stop
+ style="stop-color:#fff520;stop-opacity:0.89108908;"
+ offset="0.50000000"
+ id="stop12517" />
+ <stop
+ style="stop-color:#fff300;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop12514" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12512"
+ id="radialGradient278"
+ gradientUnits="userSpaceOnUse"
+ cx="55.000000"
+ cy="125.00000"
+ fx="55.000000"
+ fy="125.00000"
+ r="14.375000" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2116">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2118" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2120" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2094">
+ <stop
+ style="stop-color:#d6e3f0;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2096" />
+ <stop
+ style="stop-color:#95b1cf;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2098" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2803">
+ <stop
+ id="stop2805"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2807"
+ offset="1.0000000"
+ style="stop-color:#cbcbcb;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2795">
+ <stop
+ id="stop2797"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:0.068627454;" />
+ <stop
+ id="stop2799"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="4.9530048"
+ x2="41.219128"
+ y1="4.9530050"
+ x1="35.433035"
+ gradientTransform="matrix(0.254000,0.000000,1.822151e-16,3.759813,0.788629,0.148567)"
+ id="linearGradient2801"
+ xlink:href="#linearGradient2795"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="84.287079"
+ x2="10.219901"
+ y1="93.338043"
+ x1="10.496115"
+ gradientTransform="matrix(2.262742,0.000000,0.000000,0.441942,1.000000,-0.875000)"
+ id="linearGradient2813"
+ xlink:href="#linearGradient2803"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2094"
+ id="linearGradient2100"
+ gradientTransform="matrix(0.957750,0.000000,0.000000,1.027989,1.000000,-0.571911)"
+ x1="6.5871811"
+ y1="22.132999"
+ x2="14.511404"
+ y2="22.132999"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2116"
+ id="linearGradient2112"
+ gradientTransform="matrix(1.025428,0.000000,0.000000,0.957303,0.000000,-0.806758)"
+ x1="73.361984"
+ y1="26.652197"
+ x2="-2.7582901"
+ y2="21.270376"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient5013"
+ gradientUnits="userSpaceOnUse"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient5016"
+ gradientUnits="userSpaceOnUse"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient5020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient5027"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient5029"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient5031"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.27843137"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-111.52422"
+ inkscape:cy="10.167608"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="872"
+ inkscape:window-height="688"
+ inkscape:window-x="562"
+ inkscape:window-y="160"
+ fill="#ef2929"
+ stroke="#cc0000"
+ inkscape:showpageshadow="false" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Addess Book - New</dc:title>
+ <dc:date />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>address</rdf:li>
+ <rdf:li>contact</rdf:li>
+ <rdf:li>book</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ style="opacity:1;color:#000000;fill:#edd400;fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 33.096456,4.6520202 L 40.521077,4.6520202 C 41.228184,4.6520202 41.758513,4.8287969 41.93529,5.71268 L 42.819174,12.606972 C 42.907562,13.667632 42.443523,14.021185 41.493349,14.021185 L 32.919679,14.021185 L 33.096456,4.6520202 z "
+ id="path21630"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path21632"
+ d="M 34.10295,5.638875 L 40.463507,5.638875 C 40.771656,5.638875 40.940266,5.669037 40.986054,5.960473 L 41.777489,12.344449 C 41.847258,12.775421 41.959897,13.019804 41.637211,13.034341 L 33.963412,13.034341 L 34.10295,5.638875 z "
+ style="opacity:0.48538011;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000006;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path21634"
+ d="M 35.596456,12.40202 L 43.021077,12.40202 C 43.728184,12.40202 44.258513,12.578797 44.43529,13.46268 L 45.319174,20.356972 C 45.407562,21.417632 44.943523,21.771185 43.993349,21.771185 L 35.419679,21.771185 L 35.596456,12.40202 z "
+ style="opacity:1;color:#000000;fill:#9db029;fill-opacity:1;fill-rule:evenodd;stroke:#727e0a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="opacity:0.48538011;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000006;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 36.60295,13.388875 L 42.963507,13.388875 C 43.271656,13.388875 43.440266,13.419037 43.486054,13.710473 L 44.277489,20.094449 C 44.347258,20.525421 44.459897,20.769804 44.137211,20.784341 L 36.463412,20.784341 L 36.60295,13.388875 z "
+ id="path21636"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;color:#000000;fill:#ef2929;fill-opacity:1;fill-rule:evenodd;stroke:#cc0000;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 36.06451,20.776498 L 44.50992,20.776498 C 45.314245,20.776498 45.917487,20.995896 46.118569,22.092882 L 47.123975,30.649381 C 47.224515,31.965765 46.696677,32.40456 45.615866,32.40456 L 35.863428,32.40456 L 36.06451,20.776498 z "
+ id="path21638"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path21640"
+ d="M 37.209384,21.763574 L 44.444435,21.763574 C 44.79495,21.763574 44.986742,21.801928 45.038825,22.172513 L 45.939072,30.290267 C 46.018433,30.838284 46.146559,31.149038 45.779508,31.167522 L 37.050661,31.167522 L 37.209384,21.763574 z "
+ style="opacity:0.48538011;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <g
+ id="g5022"
+ transform="matrix(2.165152e-2,0,0,4.307902e-2,43.08625,34.04509)">
+ <rect
+ y="-150.69685"
+ x="-1559.2523"
+ height="478.35718"
+ width="1339.6335"
+ id="rect4173"
+ style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path5058"
+ d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+ id="path5018"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <path
+ style="color:#000000;fill:#5b6b94;fill-opacity:1;fill-rule:nonzero;stroke:#364878;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 6.3643222,5.5185897 C 6.4551049,3.6036003 7.3719758,2.5542814 9.0788784,2.549044 L 38.405776,2.4590577 C 38.652361,2.4583011 38.974317,2.6592071 38.999012,2.9089888 L 42.257491,35.867228 L 40.942189,35.923862 L 41.571429,42.369516 C 41.632441,42.994499 41.390059,43.52882 40.5,43.533035 L 9.7893046,43.678474 C 7.25676,43.690468 4.6538454,41.59976 4.7759337,39.024403 L 6.3643222,5.5185897 z "
+ id="rect1408"
+ sodipodi:nodetypes="csssccsssss" />
+ <path
+ id="path2489"
+ d="M 40.125,34.875 L 10.9375,35 C 9.3809819,35.177868 8.125,36.39612 8.125,38 C 8.125,39.60388 9.3809819,40.822132 10.9375,41 L 40.125,41.125 L 40.125,41.0625 C 38.469378,40.984348 37.125,39.674851 37.125,38 C 37.125,36.325149 38.469378,35.015652 40.125,34.9375 L 40.125,34.875 z "
+ style="color:#000000;fill:url(#linearGradient2813);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="ccccccssc"
+ id="path2784"
+ d="M 9.6875,2.8125 C 7.9805897,2.8125 7.050103,3.8215062 6.96875,5.6738658 L 5.3125,37.825772 C 5.22054,40.904199 7.1393732,42.654485 9.125,43.15625 C 4.875,41.525579 5.4375,34.164455 10.75,34.195222 L 41.648286,34.195222 L 38.335786,3.2432432 C 38.310025,3.0025304 37.987878,2.8125 37.742036,2.8125 L 9.6875,2.8125 z "
+ style="color:#000000;fill:url(#linearGradient2100);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ y="3.968539"
+ x="9.7886267"
+ height="29.604792"
+ width="2"
+ id="rect2793"
+ style="opacity:0.48044691;color:#000000;fill:url(#linearGradient2801);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:0.60818715;visibility:visible;display:inline;overflow:visible"
+ transform="matrix(1.000000,0.000000,-3.582731e-2,0.999358,0.000000,0.000000)" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2112);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 9.8751008,3.3336831 C 8.1912014,3.3336831 7.5384236,4.0658459 7.4581673,5.887831 L 6.1592633,35.777198 C 7.0925916,34.170451 8.5988591,33.594437 11.011665,33.594437 L 40.963081,33.594437 L 38.137179,3.7573631 C 38.114727,3.5203092 37.793961,3.3336831 37.551434,3.3336831 L 9.8751008,3.3336831 z "
+ id="path2104"
+ sodipodi:nodetypes="cccscssc" />
+ <path
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:120.00000477%;writing-mode:lr-tb;text-anchor:start;fill:#ad7fa8;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ d="M 21.12553,18.381288 C 21.050283,19.50227 21.269376,20.384155 21.782812,21.026947 C 22.296751,21.661909 23.039741,21.979388 24.011788,21.979387 C 24.97597,21.979388 25.754005,21.65799 26.345892,21.01519 C 26.945589,20.372398 27.282799,19.49443 27.357529,18.381288 C 27.431173,17.283839 27.207372,16.413709 26.686123,15.770905 C 26.165371,15.120279 25.426826,14.794959 24.470482,14.79495 C 23.521952,14.794959 22.743917,15.11636 22.136378,15.759145 C 21.536656,16.401952 21.199707,17.275998 21.12553,18.381288 M 27.29793,21.897075 C 26.787062,22.500679 26.216183,22.947501 25.58529,23.237544 C 24.962734,23.519747 24.247754,23.66085 23.44035,23.660849 C 22.092032,23.66085 21.027197,23.174832 20.245835,22.202797 C 19.472826,21.222925 19.138938,19.949092 19.244172,18.381288 C 19.349395,16.813498 19.858197,15.539665 20.770584,14.559781 C 21.682954,13.579917 22.809375,13.089981 24.149854,13.089969 C 24.957257,13.089981 25.656689,13.238924 26.24815,13.536791 C 26.840107,13.826846 27.347352,14.269749 27.76988,14.865501 L 27.873267,13.325141 L 29.554732,13.325141 L 28.973868,21.979387 C 30.129917,21.806931 31.058551,21.285637 31.759769,20.415508 C 32.469312,19.537544 32.870659,18.404812 32.963808,17.017304 C 33.020082,16.178542 32.947536,15.390722 32.746168,14.653848 C 32.552597,13.916994 32.226018,13.235002 31.766435,12.607873 C 31.020085,11.580979 30.077151,10.79708 28.937625,10.256176 C 27.806428,9.707462 26.551007,9.433097 25.171361,9.433081 C 24.207151,9.433097 23.27347,9.56244 22.370314,9.821111 C 21.467662,10.071974 20.623234,10.448244 19.837027,10.949925 C 18.552629,11.749517 17.517932,12.79994 16.732929,14.101199 C 15.956279,15.394643 15.517185,16.797819 15.415642,18.310738 C 15.331983,19.557142 15.476998,20.725151 15.85069,21.814765 C 16.232213,22.904387 16.822316,23.864664 17.621,24.695594 C 18.389368,25.51085 19.300238,26.130129 20.353615,26.553435 C 21.406448,26.984578 22.54823,27.20015 23.778962,27.200153 C 24.790178,27.20015 25.793384,27.027692 26.788584,26.682781 C 27.791068,26.345701 28.72125,25.859684 29.579139,25.224728 L 30.549801,26.529919 C 29.518874,27.2903 28.409917,27.870384 27.222932,28.270174 C 26.043227,28.677799 24.857618,28.881612 23.666104,28.881616 C 22.215881,28.881612 20.865341,28.622926 19.614483,28.105557 C 18.36308,27.596019 17.268571,26.851316 16.330955,25.871444 C 15.393328,24.89157 14.705054,23.758838 14.266133,22.47324 C 13.827731,21.179813 13.658252,19.792311 13.757696,18.310738 C 13.853452,16.88405 14.211263,15.523986 14.831129,14.230542 C 15.450993,12.937121 16.287663,11.800469 17.34115,10.820582 C 18.419191,9.825045 19.638236,9.0646655 20.998287,8.5394366 C 22.358842,8.0064001 23.779908,7.7398759 25.261489,7.7398585 C 26.923341,7.7398759 28.440813,8.080872 29.813913,8.7628469 C 31.194815,9.444854 32.325282,10.41297 33.205316,11.667193 C 33.741656,12.435425 34.132443,13.270279 34.377679,14.171752 C 34.630708,15.073243 34.724877,16.006082 34.660187,16.970271 C 34.521787,19.031929 33.789414,20.658519 32.463064,21.850041 C 31.136671,23.04157 29.374449,23.66085 27.17639,23.707883 L 27.29793,21.897075"
+ id="text21625" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#radialGradient278);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25000024;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block"
+ id="path12511"
+ sodipodi:cx="55"
+ sodipodi:cy="125"
+ sodipodi:rx="14.375"
+ sodipodi:ry="14.375"
+ d="M 69.375 125 A 14.375 14.375 0 1 1 40.625,125 A 14.375 14.375 0 1 1 69.375 125 z"
+ transform="matrix(0.611127,0.000000,0.000000,0.611127,-24.94992,-67.63529)"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/stock_new-16.png"
+ inkscape:export-xdpi="33.852203"
+ inkscape:export-ydpi="33.852203" />
+ </g>
+</svg>
diff --git a/tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg b/tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg
new file mode 100644
index 0000000..4cb14f8
--- /dev/null
+++ b/tests/auto/qicon/icons/themeparent/scalable/actions/appointment-new.svg
@@ -0,0 +1,425 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="90.000000"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+ width="48px"
+ height="48px"
+ id="svg11300"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
+ sodipodi:docname="appointment-new.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective59" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5204">
+ <stop
+ style="stop-color:#c4a000;stop-opacity:1;"
+ offset="0"
+ id="stop5206" />
+ <stop
+ style="stop-color:#c4a000;stop-opacity:0;"
+ offset="1"
+ id="stop5208" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5196">
+ <stop
+ style="stop-color:#c4a000;stop-opacity:1;"
+ offset="0"
+ id="stop5198" />
+ <stop
+ style="stop-color:#c4a000;stop-opacity:0;"
+ offset="1"
+ id="stop5200" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12512">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop12513" />
+ <stop
+ style="stop-color:#fff520;stop-opacity:0.89108908;"
+ offset="0.50000000"
+ id="stop12517" />
+ <stop
+ style="stop-color:#fff300;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop12514" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12512"
+ id="radialGradient278"
+ gradientUnits="userSpaceOnUse"
+ cx="55.000000"
+ cy="125.00000"
+ fx="55.000000"
+ fy="125.00000"
+ r="14.375000" />
+ <linearGradient
+ id="linearGradient10653">
+ <stop
+ style="stop-color:#f3f4ff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop10655" />
+ <stop
+ style="stop-color:#9193af;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop10657" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42174">
+ <stop
+ style="stop-color:#a0a0a0;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop42176" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop42178" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2145">
+ <stop
+ style="stop-color:#fffffd;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2147" />
+ <stop
+ style="stop-color:#cbcbc9;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2149" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37935">
+ <stop
+ id="stop37937"
+ offset="0.0000000"
+ style="stop-color:#9497b3;stop-opacity:1.0000000;" />
+ <stop
+ id="stop37939"
+ offset="1.0000000"
+ style="stop-color:#4c4059;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2152">
+ <stop
+ id="stop2154"
+ offset="0.0000000"
+ style="stop-color:#9aa29a;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2156"
+ offset="1.0000000"
+ style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3816">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3818" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3820" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3816"
+ id="radialGradient3822"
+ cx="31.112698"
+ cy="19.008621"
+ fx="31.112698"
+ fy="19.008621"
+ r="8.6620579"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2152"
+ id="linearGradient4307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.123841,0.000000,0.000000,0.969691,-31.88758,-19.59492)"
+ x1="8.9156475"
+ y1="37.197018"
+ x2="9.8855033"
+ y2="52.090678" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10653"
+ id="radialGradient4309"
+ gradientUnits="userSpaceOnUse"
+ cx="11.329200"
+ cy="10.583970"
+ fx="11.329200"
+ fy="10.583970"
+ r="15.532059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2145"
+ id="radialGradient4311"
+ gradientUnits="userSpaceOnUse"
+ cx="11.901996"
+ cy="10.045444"
+ fx="11.901996"
+ fy="10.045444"
+ r="29.292715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42174"
+ id="linearGradient4313"
+ gradientUnits="userSpaceOnUse"
+ x1="6.3422160"
+ y1="7.7893324"
+ x2="22.218424"
+ y2="25.884274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5196"
+ id="radialGradient5202"
+ cx="23.375"
+ cy="10.972863"
+ fx="23.375"
+ fy="10.972863"
+ r="3.3478092"
+ gradientTransform="matrix(3.630420,1.654030e-15,-1.608743e-15,3.742066,-61.48607,-29.18618)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5204"
+ id="linearGradient5210"
+ x1="19.667364"
+ y1="4.2570662"
+ x2="20.329933"
+ y2="5.2845874"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37935"
+ id="radialGradient5212"
+ gradientUnits="userSpaceOnUse"
+ cx="8.7468252"
+ cy="6.8283234"
+ fx="8.7468252"
+ fy="6.8283234"
+ r="29.889715" />
+ </defs>
+ <sodipodi:namedview
+ stroke="#c4a000"
+ fill="#babdb6"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.25490196"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313708"
+ inkscape:cx="13.2248"
+ inkscape:cy="25.106052"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="833"
+ inkscape:window-height="772"
+ inkscape:window-x="305"
+ inkscape:window-y="76" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:title>New Appointment</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>appointment</rdf:li>
+ <rdf:li>new</rdf:li>
+ <rdf:li>meeting</rdf:li>
+ <rdf:li>rvsp</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4318"
+ style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(2.563158,0.000000,0.000000,1.219602,-55.98414,14.04144)" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path14341"
+ d="M 18.587591,1.403729 L 4.226755,18.096665 L 5.4854717,19.339844 L 18.587591,1.403729 z "
+ style="color:#000000;fill:url(#linearGradient4307);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path18921"
+ d="M 18.467176,1.3138035 L 5.6605716,19.072612 L 7.4900985,20.687913 L 18.467176,1.3138035 z "
+ style="fill:#fefefe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" />
+ <path
+ transform="matrix(1.431529,0.000000,0.000000,1.431529,0.569459,-1.654618)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path27786"
+ style="fill:url(#radialGradient5212);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:0.69855404;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.163838,0.000000,0.000000,1.163838,4.824801,2.777556)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path35549"
+ style="fill:url(#radialGradient4311);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4313);stroke-width:0.71139598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:url(#radialGradient5202);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5210);stroke-width:0.56498736;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path4120"
+ sodipodi:cx="23.375"
+ sodipodi:cy="11.875"
+ sodipodi:rx="8.5"
+ sodipodi:ry="8.5"
+ d="M 16.679382,6.6387137 A 8.5,8.5 0 0 1 23.332691,3.3751053 L 23.375,11.875 z"
+ transform="matrix(1.769951,0.000000,0.000000,1.769951,-17.02424,1.610741)"
+ sodipodi:start="3.8052902"
+ sodipodi:end="4.7074114" />
+ <path
+ transform="matrix(2.073295,0.000000,0.000000,2.073295,-7.310224,-13.13682)"
+ d="M 16.40625 17.28125 A 1.21875 1.21875 0 1 1 13.96875,17.28125 A 1.21875 1.21875 0 1 1 16.40625 17.28125 z"
+ sodipodi:ry="1.21875"
+ sodipodi:rx="1.21875"
+ sodipodi:cy="17.28125"
+ sodipodi:cx="15.1875"
+ id="path34778"
+ style="fill:#f3f3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48232403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ id="path35559"
+ d="M 22.176614,20.718014 L 13.155702,13.140282"
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ id="path35561"
+ d="M 19.408614,29.776506 L 22.368655,25.283228"
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,-12.40939)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35563"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,14.80922)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35565"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-35.91004,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35567"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-8.691448,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35569"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient4309);stroke-width:0.73656511;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ id="path10651"
+ sodipodi:cx="16.25"
+ sodipodi:cy="16.910715"
+ sodipodi:rx="14.910714"
+ sodipodi:ry="14.910714"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ transform="matrix(1.357654,0.000000,0.000000,1.357654,1.769896,-0.493735)" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#radialGradient278);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25000024;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block"
+ id="path12511"
+ sodipodi:cx="55"
+ sodipodi:cy="125"
+ sodipodi:rx="14.375"
+ sodipodi:ry="14.375"
+ d="M 69.375 125 A 14.375 14.375 0 1 1 40.625,125 A 14.375 14.375 0 1 1 69.375 125 z"
+ transform="matrix(0.611127,0.000000,0.000000,0.611127,5.544052,-66.92818)"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/stock_new-16.png"
+ inkscape:export-xdpi="33.852203"
+ inkscape:export-ydpi="33.852203" />
+ </g>
+</svg>
diff --git a/tests/auto/qicon/tst_qicon.cpp b/tests/auto/qicon/tst_qicon.cpp
index a266c16..545ca09 100644
--- a/tests/auto/qicon/tst_qicon.cpp
+++ b/tests/auto/qicon/tst_qicon.cpp
@@ -74,6 +74,7 @@ private slots:
void availableSizes();
void streamAvailableSizes_data();
void streamAvailableSizes();
+ void fromTheme();
void task184901_badCache();
void task223279_inconsistentAddFile();
@@ -605,6 +606,72 @@ void tst_QIcon::task184901_badCache()
QVERIFY( icon.pixmap(32, QIcon::Normal).toImage() == icon.pixmap(32, QIcon::Disabled).toImage() );
}
+void tst_QIcon::fromTheme()
+{
+ const QString prefix = QLatin1String(SRCDIR) + QLatin1String("/");
+ QString searchPath = prefix + QLatin1String("/icons");
+ QIcon::setThemeSearchPaths(QStringList() << searchPath);
+ QVERIFY(QIcon::themeSearchPaths().size() == 1);
+ QCOMPARE(searchPath, QIcon::themeSearchPaths()[0]);
+
+ QString themeName("testtheme");
+ QIcon::setThemeName(themeName);
+ QCOMPARE(QIcon::themeName(), themeName);
+
+ // Test normal icon
+ QIcon appointmentIcon = QIcon::fromTheme("appointment-new");
+ QVERIFY(!appointmentIcon.isNull());
+ QVERIFY(!appointmentIcon.availableSizes(QIcon::Normal, QIcon::Off).isEmpty());
+ QVERIFY(appointmentIcon.availableSizes().contains(QSize(16, 16)));
+ QVERIFY(appointmentIcon.availableSizes().contains(QSize(32, 32)));
+ QVERIFY(appointmentIcon.availableSizes().contains(QSize(22, 22)));
+
+ // Test icon from parent theme
+ QIcon abIcon = QIcon::fromTheme("address-book-new");
+ QVERIFY(!abIcon.isNull());
+ QVERIFY(QIcon::hasThemeIcon("address-book-new"));
+ QVERIFY(!abIcon.availableSizes().isEmpty());
+
+ // Test non existing icon
+ QIcon noIcon = QIcon::fromTheme("broken-icon");
+ QVERIFY(noIcon.isNull());
+ QVERIFY(!QIcon::hasThemeIcon("broken-icon"));
+
+ // Test non existing icon with fallback
+ noIcon = QIcon::fromTheme("broken-icon", abIcon);
+ QVERIFY(noIcon.cacheKey() == abIcon.cacheKey());
+
+ // Test svg-only icon
+ noIcon = QIcon::fromTheme("svg-icon", abIcon);
+ QVERIFY(!noIcon.availableSizes().isEmpty());
+
+ QByteArray ba;
+ // write to QByteArray
+ {
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::WriteOnly);
+ QDataStream stream(&buffer);
+ stream << abIcon;
+ }
+
+ // read from QByteArray
+ {
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::ReadOnly);
+ QDataStream stream(&buffer);
+ QIcon i;
+ stream >> i;
+ QCOMPARE(i.isNull(), abIcon.isNull());
+ QCOMPARE(i.availableSizes(), abIcon.availableSizes());
+ }
+
+ // Make sure setting the theme name clears the state
+ QIcon::setThemeName("");
+ abIcon = QIcon::fromTheme("address-book-new");
+ QVERIFY(abIcon.isNull());
+}
+
+
void tst_QIcon::task223279_inconsistentAddFile()
{
QIcon icon1;
diff --git a/tools/assistant/compat/mainwindow.cpp b/tools/assistant/compat/mainwindow.cpp
index 670b144..9d308df 100644
--- a/tools/assistant/compat/mainwindow.cpp
+++ b/tools/assistant/compat/mainwindow.cpp
@@ -140,6 +140,16 @@ MainWindow::MainWindow()
ui.actionZoomIn->setIcon(QIcon(MacIconPath + QLatin1String("/zoomin.png")));
ui.actionSyncToc->setIcon(QIcon(MacIconPath + QLatin1String("/synctoc.png")));
ui.actionHelpWhatsThis->setIcon(QIcon(MacIconPath + QLatin1String("/whatsthis.png")));
+#elif defined(Q_WS_X11)
+ ui.actionGoNext->setIcon(QIcon::fromTheme("go-next" , ui.actionGoNext->icon()));
+ ui.actionGoPrevious->setIcon(QIcon::fromTheme("go-previous" , ui.actionGoPrevious->icon()));
+ ui.actionGoHome->setIcon(QIcon::fromTheme("user-home" , ui.actionGoHome->icon()));
+ ui.actionEditCopy->setIcon(QIcon::fromTheme("edit-copy" , ui.actionEditCopy->icon()));
+ ui.actionEditFind->setIcon(QIcon::fromTheme("edit-find" , ui.actionEditFind->icon()));
+ ui.actionFilePrint->setIcon(QIcon::fromTheme("document-print" , ui.actionFilePrint->icon()));
+ ui.actionZoomOut->setIcon(QIcon::fromTheme("zoom-out" , ui.actionZoomOut->icon()));
+ ui.actionZoomIn->setIcon(QIcon::fromTheme("zoom-in" , ui.actionZoomIn->icon()));
+ ui.actionSyncToc->setIcon(QIcon::fromTheme("view-refresh" , ui.actionSyncToc->icon()));
#endif
}
diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp
index bc73b80..a0d4fbf 100644
--- a/tools/assistant/tools/assistant/mainwindow.cpp
+++ b/tools/assistant/tools/assistant/mainwindow.cpp
@@ -545,6 +545,19 @@ void MainWindow::setupActions()
m_aboutAction = menu->addAction(tr("About..."), this, SLOT(showAboutDialog()));
m_aboutAction->setMenuRole(QAction::AboutRole);
+#ifdef Q_WS_X11
+ m_backAction->setIcon(QIcon::fromTheme("go-previous" , m_backAction->icon()));
+ m_nextAction->setIcon(QIcon::fromTheme("go-next" , m_nextAction->icon()));
+ m_zoomInAction->setIcon(QIcon::fromTheme("zoom-in" , m_zoomInAction->icon()));
+ m_zoomOutAction->setIcon(QIcon::fromTheme("zoom-out" , m_zoomOutAction->icon()));
+ m_resetZoomAction->setIcon(QIcon::fromTheme("zoom-original" , m_resetZoomAction->icon()));
+ m_syncAction->setIcon(QIcon::fromTheme("view-refresh" , m_syncAction->icon()));
+ m_copyAction->setIcon(QIcon::fromTheme("edit-copy" , m_copyAction->icon()));
+ m_findAction->setIcon(QIcon::fromTheme("edit-find" , m_findAction->icon()));
+ m_homeAction->setIcon(QIcon::fromTheme("go-home" , m_homeAction->icon()));
+ m_printAction->setIcon(QIcon::fromTheme("document-print" , m_printAction->icon()));
+#endif
+
QToolBar *navigationBar = addToolBar(tr("Navigation Toolbar"));
navigationBar->setObjectName(QLatin1String("NavigationToolBar"));
navigationBar->addAction(m_backAction);
diff --git a/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp b/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
index ff0c3c6..cf838a2 100644
--- a/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
+++ b/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
@@ -72,8 +72,9 @@ void BuddyEditorPlugin::initialize(QDesignerFormEditorInterface *core)
m_action = new QAction(tr("Edit Buddies"), this);
m_action->setObjectName(QLatin1String("__qt_edit_buddies_action"));
- m_action->setIcon(QIcon(core->resourceLocation() + QLatin1String("/buddytool.png")));
- m_action->setIcon(QIcon(core->resourceLocation() + QLatin1String("/buddytool.png")));
+ QIcon buddyIcon = QIcon::fromTheme("designer-edit-buddy",
+ QIcon(core->resourceLocation() + QLatin1String("/buddytool.png")));
+ m_action->setIcon(buddyIcon);
m_action->setEnabled(false);
setParent(core);
diff --git a/tools/designer/src/components/formeditor/formwindowmanager.cpp b/tools/designer/src/components/formeditor/formwindowmanager.cpp
index 993bae9..a2a0a40 100644
--- a/tools/designer/src/components/formeditor/formwindowmanager.cpp
+++ b/tools/designer/src/components/formeditor/formwindowmanager.cpp
@@ -443,7 +443,8 @@ void FormWindowManager::setupActions()
m_actionVerticalLayout->setEnabled(false);
connect(m_actionVerticalLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
- QAction *actionFormLayout = new QAction(createIconSet(QLatin1String("editform.png")), tr("Lay Out in a &Form Layout"), this);
+ QIcon formIcon = QIcon::fromTheme("designer-form-layout", createIconSet(QLatin1String("editform.png")));
+ QAction *actionFormLayout = new QAction(formIcon, tr("Lay Out in a &Form Layout"), this);
actionFormLayout->setObjectName(QLatin1String("__qt_form_layout_action"));
actionFormLayout->setShortcut(Qt::CTRL + Qt::Key_6);
actionFormLayout->setStatusTip(tr("Lays out the selected widgets in a form layout"));
@@ -510,15 +511,30 @@ void FormWindowManager::setupActions()
m_actionUndo = m_undoGroup->createUndoAction(this);
m_actionUndo->setEnabled(false);
- m_actionUndo->setIcon(createIconSet(QLatin1String("undo.png")));
+
+ m_actionUndo->setIcon(QIcon::fromTheme("edit-undo", createIconSet(QLatin1String("undo.png"))));
m_actionRedo = m_undoGroup->createRedoAction(this);
m_actionRedo->setEnabled(false);
- m_actionRedo->setIcon(createIconSet(QLatin1String("redo.png")));
+ m_actionRedo->setIcon(QIcon::fromTheme("edit-redo", createIconSet(QLatin1String("redo.png"))));
m_actionShowFormWindowSettingsDialog = new QAction(tr("Form &Settings..."), this);
m_actionShowFormWindowSettingsDialog->setObjectName(QLatin1String("__qt_form_settings_action"));
connect(m_actionShowFormWindowSettingsDialog, SIGNAL(triggered()), this, SLOT(slotActionShowFormWindowSettingsDialog()));
m_actionShowFormWindowSettingsDialog->setEnabled(false);
+
+
+ m_actionCopy->setIcon(QIcon::fromTheme("edit-copy", m_actionCopy->icon()));
+ m_actionCut->setIcon(QIcon::fromTheme("edit-cut", m_actionCut->icon()));
+ m_actionPaste->setIcon(QIcon::fromTheme("edit-paste", m_actionPaste->icon()));
+
+ // These do not currently exist, but will allow theme authors to fill in the gaps
+ m_actionBreakLayout->setIcon(QIcon::fromTheme("designer-break-layout", m_actionBreakLayout->icon()));
+ m_actionGridLayout->setIcon(QIcon::fromTheme("designer-grid-layout", m_actionGridLayout->icon()));
+ m_actionHorizontalLayout->setIcon(QIcon::fromTheme("designer-horizontal-layout", m_actionHorizontalLayout->icon()));
+ m_actionVerticalLayout->setIcon(QIcon::fromTheme("designer-vertical-layout", m_actionVerticalLayout->icon()));
+ m_actionSplitHorizontal->setIcon(QIcon::fromTheme("designer-split-horizontal", m_actionSplitHorizontal->icon()));
+ m_actionSplitVertical->setIcon(QIcon::fromTheme("designer-split-vertical", m_actionSplitVertical->icon()));
+ m_actionAdjustSize->setIcon(QIcon::fromTheme("designer-adjust-size", m_actionAdjustSize->icon()));
}
void FormWindowManager::slotActionCutActivated()
diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
index e664ae7..a113041 100644
--- a/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
+++ b/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
@@ -72,7 +72,8 @@ void SignalSlotEditorPlugin::initialize(QDesignerFormEditorInterface *core)
m_action = new QAction(tr("Edit Signals/Slots"), this);
m_action->setObjectName(QLatin1String("__qt_edit_signals_slots_action"));
m_action->setShortcut(tr("F4"));
- QIcon icon(QIcon(core->resourceLocation() + QLatin1String("/signalslottool.png")));
+ QIcon icon = QIcon::fromTheme("designer-edit-signals",
+ QIcon(core->resourceLocation() + QLatin1String("/signalslottool.png")));
m_action->setIcon(icon);
m_action->setEnabled(false);
diff --git a/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp b/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
index 9b051c9..ddddd08 100644
--- a/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
+++ b/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
@@ -72,7 +72,9 @@ void TabOrderEditorPlugin::initialize(QDesignerFormEditorInterface *core)
m_action = new QAction(tr("Edit Tab Order"), this);
m_action->setObjectName(QLatin1String("_qt_edit_tab_order_action"));
- m_action->setIcon(QIcon(core->resourceLocation() + QLatin1String("/tabordertool.png")));
+ QIcon icon = QIcon::fromTheme("designer-edit-tabs",
+ QIcon(core->resourceLocation() + QLatin1String("/tabordertool.png")));
+ m_action->setIcon(icon);
m_action->setEnabled(false);
setParent(core);
diff --git a/tools/designer/src/designer/qdesigner_actions.cpp b/tools/designer/src/designer/qdesigner_actions.cpp
index c671386..567a13e 100644
--- a/tools/designer/src/designer/qdesigner_actions.cpp
+++ b/tools/designer/src/designer/qdesigner_actions.cpp
@@ -200,6 +200,10 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
#endif
m_previewManager(0)
{
+ m_newFormAction->setIcon(QIcon::fromTheme("document-new", m_newFormAction->icon()));
+ m_openFormAction->setIcon(QIcon::fromTheme("document-open", m_openFormAction->icon()));
+ m_saveFormAction->setIcon(QIcon::fromTheme("document-save", m_saveFormAction->icon()));
+
Q_ASSERT(m_core != 0);
qdesigner_internal::QDesignerFormWindowManager *ifwm = qobject_cast<qdesigner_internal::QDesignerFormWindowManager *>(m_core->formWindowManager());
Q_ASSERT(ifwm);
@@ -323,7 +327,8 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
shortcuts.append(QKeySequence(Qt::Key_Escape));
#endif
m_editWidgetsAction->setShortcuts(shortcuts);
- m_editWidgetsAction->setIcon(QIcon(m_core->resourceLocation() + QLatin1String("/widgettool.png")));
+ QIcon fallback(m_core->resourceLocation() + QLatin1String("/widgettool.png"));
+ m_editWidgetsAction->setIcon(QIcon::fromTheme("designer-edit-widget", fallback));
connect(m_editWidgetsAction, SIGNAL(triggered()), this, SLOT(editWidgetsSlot()));
m_editWidgetsAction->setChecked(true);
m_editWidgetsAction->setEnabled(false);
diff --git a/tools/designer/src/lib/shared/actioneditor.cpp b/tools/designer/src/lib/shared/actioneditor.cpp
index 1a236d6..a931b8a 100644
--- a/tools/designer/src/lib/shared/actioneditor.cpp
+++ b/tools/designer/src/lib/shared/actioneditor.cpp
@@ -147,7 +147,8 @@ ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent,
toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
l->addWidget(toolbar);
// edit actions
- m_actionNew->setIcon(createIconSet(QLatin1String("filenew.png")));
+ QIcon documentNewIcon = QIcon::fromTheme("document-new", createIconSet(QLatin1String("filenew.png")));
+ m_actionNew->setIcon(documentNewIcon);
m_actionNew->setEnabled(false);
connect(m_actionNew, SIGNAL(triggered()), this, SLOT(slotNewAction()));
toolbar->addAction(m_actionNew);
@@ -156,15 +157,18 @@ ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent,
m_actionCut->setEnabled(false);
connect(m_actionCut, SIGNAL(triggered()), this, SLOT(slotCut()));
- m_actionCut->setIcon(createIconSet(QLatin1String("editcut.png")));
+ QIcon editCutIcon = QIcon::fromTheme("edit-cut", createIconSet(QLatin1String("editcut.png")));
+ m_actionCut->setIcon(editCutIcon);
m_actionCopy->setEnabled(false);
connect(m_actionCopy, SIGNAL(triggered()), this, SLOT(slotCopy()));
- m_actionCopy->setIcon(createIconSet(QLatin1String("editcopy.png")));
+ QIcon editCopyIcon = QIcon::fromTheme("edit-copy", createIconSet(QLatin1String("editcopy.png")));
+ m_actionCopy->setIcon(editCopyIcon);
toolbar->addAction(m_actionCopy);
connect(m_actionPaste, SIGNAL(triggered()), this, SLOT(slotPaste()));
- m_actionPaste->setIcon(createIconSet(QLatin1String("editpaste.png")));
+ QIcon editPasteIcon = QIcon::fromTheme("edit-paste", createIconSet(QLatin1String("editpaste.png")));
+ m_actionPaste->setIcon(editPasteIcon);
toolbar->addAction(m_actionPaste);
m_actionEdit->setEnabled(false);
@@ -172,7 +176,8 @@ ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent,
connect(m_actionNavigateToSlot, SIGNAL(triggered()), this, SLOT(navigateToSlotCurrentAction()));
- m_actionDelete->setIcon(createIconSet(QLatin1String("editdelete.png")));
+ QIcon editDeleteIcon = QIcon::fromTheme("edit-delete", createIconSet(QLatin1String("editdelete.png")));
+ m_actionDelete->setIcon(editDeleteIcon);
m_actionDelete->setEnabled(false);
connect(m_actionDelete, SIGNAL(triggered()), this, SLOT(slotDelete()));
toolbar->addAction(m_actionDelete);
@@ -243,7 +248,8 @@ QToolButton *ActionEditor::createConfigureMenuButton(const QString &t, QMenu **p
{
QToolButton *configureButton = new QToolButton;
QAction *configureAction = new QAction(t, configureButton);
- configureAction->setIcon(createIconSet(QLatin1String("configure.png")));
+ QIcon configureIcon = QIcon::fromTheme("document-properties", createIconSet(QLatin1String("configure.png")));
+ configureAction->setIcon(configureIcon);
QMenu *configureMenu = new QMenu;
configureAction->setMenu(configureMenu);
configureButton->setDefaultAction(configureAction);
diff --git a/tools/designer/src/lib/shared/qtresourceview.cpp b/tools/designer/src/lib/shared/qtresourceview.cpp
index 40be3e6..f55f7ae 100644
--- a/tools/designer/src/lib/shared/qtresourceview.cpp
+++ b/tools/designer/src/lib/shared/qtresourceview.cpp
@@ -582,17 +582,21 @@ QtResourceView::QtResourceView(QDesignerFormEditorInterface *core, QWidget *pare
{
d_ptr->q_ptr = this;
- d_ptr->m_editResourcesAction = new QAction(qdesigner_internal::createIconSet(QLatin1String("edit.png")), tr("Edit Resources..."), this);
+ QIcon editIcon = QIcon::fromTheme("document-properties", qdesigner_internal::createIconSet(QLatin1String("edit.png")));
+ d_ptr->m_editResourcesAction = new QAction(editIcon, tr("Edit Resources..."), this);
d_ptr->m_toolBar->addAction(d_ptr->m_editResourcesAction);
connect(d_ptr->m_editResourcesAction, SIGNAL(triggered()), this, SLOT(slotEditResources()));
d_ptr->m_editResourcesAction->setEnabled(false);
- d_ptr->m_reloadResourcesAction = new QAction(qdesigner_internal::createIconSet(QLatin1String("reload.png")), tr("Reload"), this);
+ QIcon refreshIcon = QIcon::fromTheme("view-refresh", qdesigner_internal::createIconSet(QLatin1String("reload.png")));
+ d_ptr->m_reloadResourcesAction = new QAction(refreshIcon, tr("Reload"), this);
+
d_ptr->m_toolBar->addAction(d_ptr->m_reloadResourcesAction);
connect(d_ptr->m_reloadResourcesAction, SIGNAL(triggered()), this, SLOT(slotReloadResources()));
d_ptr->m_reloadResourcesAction->setEnabled(false);
- d_ptr->m_copyResourcePathAction = new QAction(qdesigner_internal::createIconSet(QLatin1String("editcopy.png")), tr("Copy Path"), this);
+ QIcon copyIcon = QIcon::fromTheme("edit-copy", qdesigner_internal::createIconSet(QLatin1String("editcopy.png")));
+ d_ptr->m_copyResourcePathAction = new QAction(copyIcon, tr("Copy Path"), this);
connect(d_ptr->m_copyResourcePathAction, SIGNAL(triggered()), this, SLOT(slotCopyResourcePath()));
d_ptr->m_copyResourcePathAction->setEnabled(false);