2
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
#include "icontheme.h"
26
#include <QApplication>
27
#include <QDesktopWidget>
31
static IconTheme* theIconTheme = NULL; // the global single instance of IconTheme.
32
static const char* fallbackNames[] = {"unknown", "application-octet-stream", NULL};
34
static void fmIconDataDestroy(gpointer data) {
35
QIcon* picon = reinterpret_cast<QIcon*>(data);
39
IconTheme::IconTheme():
40
currentThemeName_(QIcon::themeName()) {
41
// NOTE: only one instance is allowed
42
Q_ASSERT(theIconTheme == NULL);
43
Q_ASSERT(qApp != NULL); // QApplication should exists before contructing IconTheme.
46
fm_icon_set_user_data_destroy(reinterpret_cast<GDestroyNotify>(fmIconDataDestroy));
47
fallbackIcon_ = iconFromNames(fallbackNames);
49
// We need to get notified when there is a QEvent::StyleChange event so
50
// we can check if the current icon theme name is changed.
51
// To do this, we can filter QApplication object itself to intercept
52
// signals of all widgets, but this may be too inefficient.
53
// So, we only filter the events on QDesktopWidget instead.
54
qApp->desktop()->installEventFilter(this);
57
IconTheme::~IconTheme() {
60
IconTheme* IconTheme::instance() {
64
// check if the icon theme name is changed and emit "changed()" signal if any change is detected.
65
void IconTheme::checkChanged() {
66
if(QIcon::themeName() != theIconTheme->currentThemeName_) {
67
// if the icon theme is changed
68
theIconTheme->currentThemeName_ = QIcon::themeName();
69
// invalidate the cached data
70
fm_icon_reset_user_data_cache(fm_qdata_id);
72
theIconTheme->fallbackIcon_ = iconFromNames(fallbackNames);
73
Q_EMIT theIconTheme->changed();
77
QIcon IconTheme::iconFromNames(const char* const* names) {
78
const gchar* const* name;
79
// qDebug("names: %p", names);
80
for(name = names; *name; ++name) {
81
// qDebug("icon name=%s", *name);
82
QString qname = *name;
83
QIcon qicon = QIcon::fromTheme(qname);
91
QIcon IconTheme::convertFromGIcon(GIcon* gicon) {
92
if(G_IS_THEMED_ICON(gicon)) {
93
const gchar * const * names = g_themed_icon_get_names(G_THEMED_ICON(gicon));
94
QIcon icon = iconFromNames(names);
98
else if(G_IS_FILE_ICON(gicon)) {
99
GFile* file = g_file_icon_get_file(G_FILE_ICON(gicon));
100
char* fpath = g_file_get_path(file);
101
QString path = fpath;
105
return theIconTheme->fallbackIcon_;
110
QIcon IconTheme::icon(FmIcon* fmicon) {
111
// check if we have a cached version
112
QIcon* picon = reinterpret_cast<QIcon*>(fm_icon_get_user_data(fmicon));
113
if(!picon) { // we don't have a cache yet
114
picon = new QIcon(); // what a waste!
115
*picon = convertFromGIcon(G_ICON(fmicon));
116
fm_icon_set_user_data(fmicon, picon); // store it in FmIcon
122
QIcon IconTheme::icon(GIcon* gicon) {
123
if(G_IS_THEMED_ICON(gicon)) {
124
FmIcon* fmicon = fm_icon_from_gicon(gicon);
125
QIcon qicon = icon(fmicon);
126
fm_icon_unref(fmicon);
129
else if(G_IS_FILE_ICON(gicon)) {
130
// we do not map GFileIcon to FmIcon deliberately.
131
return convertFromGIcon(gicon);
133
return theIconTheme->fallbackIcon_;
136
// this method is called whenever there is an event on the QDesktopWidget object.
137
bool IconTheme::eventFilter(QObject* obj, QEvent* event) {
138
// we're only interested in the StyleChange event.
139
if(event->type() == QEvent::StyleChange) {
140
checkChanged(); // check if the icon theme is changed
142
return QObject::eventFilter(obj, event);