~lubuntu-dev/lxde/libfm-qt-debian-git

« back to all changes in this revision

Viewing changes to src/icontheme.cpp

  • Committer: Alf Gaida
  • Date: 2015-12-17 15:45:00 UTC
  • Revision ID: git-v1:99d4cf5e0b3761023e2285ffb96a79d050f0bdf4
Tags: upstream/0.10.0+20151214
Adding upstream version 0.10.0+20151214.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2012 - 2015  Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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
 
17
 *
 
18
 */
 
19
 
 
20
 
 
21
#include "icontheme.h"
 
22
#include <libfm/fm.h>
 
23
#include <QList>
 
24
#include <QIcon>
 
25
#include <QtGlobal>
 
26
#include <QApplication>
 
27
#include <QDesktopWidget>
 
28
 
 
29
namespace Fm {
 
30
 
 
31
static IconTheme* theIconTheme = NULL; // the global single instance of IconTheme.
 
32
static const char* fallbackNames[] = {"unknown", "application-octet-stream", NULL};
 
33
 
 
34
static void fmIconDataDestroy(gpointer data) {
 
35
  QIcon* picon = reinterpret_cast<QIcon*>(data);
 
36
  delete picon;
 
37
}
 
38
 
 
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.
 
44
 
 
45
  theIconTheme = this;
 
46
  fm_icon_set_user_data_destroy(reinterpret_cast<GDestroyNotify>(fmIconDataDestroy));
 
47
  fallbackIcon_ = iconFromNames(fallbackNames);
 
48
 
 
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);
 
55
}
 
56
 
 
57
IconTheme::~IconTheme() {
 
58
}
 
59
 
 
60
IconTheme* IconTheme::instance() {
 
61
  return theIconTheme;
 
62
}
 
63
 
 
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);
 
71
 
 
72
    theIconTheme->fallbackIcon_ = iconFromNames(fallbackNames);
 
73
    Q_EMIT theIconTheme->changed();
 
74
  }
 
75
}
 
76
 
 
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);
 
84
    if(!qicon.isNull()) {
 
85
      return qicon;
 
86
    }
 
87
  }
 
88
  return QIcon();
 
89
}
 
90
 
 
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);
 
95
    if(!icon.isNull())
 
96
      return icon;
 
97
  }
 
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;
 
102
    g_free(fpath);
 
103
    return QIcon(path);
 
104
  }
 
105
  return theIconTheme->fallbackIcon_;
 
106
}
 
107
 
 
108
 
 
109
//static
 
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
 
117
  }
 
118
  return *picon;
 
119
}
 
120
 
 
121
//static
 
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);
 
127
    return qicon;
 
128
  }
 
129
  else if(G_IS_FILE_ICON(gicon)) {
 
130
    // we do not map GFileIcon to FmIcon deliberately.
 
131
    return convertFromGIcon(gicon);
 
132
  }
 
133
  return theIconTheme->fallbackIcon_;
 
134
}
 
135
 
 
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
 
141
  }
 
142
  return QObject::eventFilter(obj, event);
 
143
}
 
144
 
 
145
 
 
146
} // namespace Fm