Add Icon and IconLoader
[quassel.git] / src / uisupport / iconloader.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include <QDebug>
22 #include <QDir>
23 #include <QFile>
24
25 #include "iconloader.h"
26
27 IconLoader IconLoader::_iconLoader;
28 int IconLoader::_groupSize[] = { 48, 22, 22, 16, 32, 22 };  // default sizes taken from Oxygen
29
30 IconLoader *IconLoader::global() {
31   return &_iconLoader;
32 }
33
34 IconLoader::IconLoader(QObject *parent) : QObject(parent) {
35
36   setTheme("oxygen");
37 }
38
39 IconLoader::~IconLoader() {
40
41 }
42
43 void IconLoader::setTheme(const QString &theme) {
44   _theme = theme;
45   // check which dirs could contain themed icons
46   _themedIconDirNames.clear();
47   _plainIconDirNames.clear();
48   QString path;
49   QStringList dataDirNames = QString(qgetenv("XDG_DATA_DIRS")).split(':');
50
51   // System theme in $data/icons/$theme
52   foreach(QString dir, dataDirNames) {
53     path = QString("%1/icons/%2").arg(dir, theme);
54     if(QFile::exists(path))
55       _themedIconDirNames.append(path);
56   }
57   // Resource for system theme :/icons/$theme
58   path = QString(":/icons/%2");
59   if(QFile::exists(path))
60     _themedIconDirNames.append(path);
61
62   // Own icons in $data/apps/quassel/icons/hicolor and :/icons/hicolor
63   // Also, plain icon dirs $data/apps/quassel/pics and :/pics
64   dataDirNames.append(":");
65   foreach(QString dir, dataDirNames) {
66     path = QString("%1/apps/quassel/icons/hicolor");
67     if(QFile::exists(path))
68       _themedIconDirNames.append(path);
69     path = QString("%1/apps/quassel/pics");
70     if(QFile::exists(path))
71       _plainIconDirNames.append(path);
72   }
73 }
74
75 // TODO: optionally implement cache (speed/memory tradeoff?)
76 QPixmap IconLoader::loadIcon(const QString &name, IconLoader::Group group, int size) {
77   if(group < 0 || group >= LastGroup) {
78     qWarning() << "Invalid icon group!";
79     return QPixmap();
80   }
81   if(size == 0)
82     size = _groupSize[group];
83
84   QString path = findIconPath(name, size);
85   if(path.isEmpty()) return QPixmap();
86
87   // load the icon
88   return QPixmap(path);
89 }
90
91 QString IconLoader::findIconPath(const QString &name, int size) {
92   QString fname = QString("%1.png").arg(name);  // we only support PNG so far
93   // First, look for a themed icon... we don't do anything fancy here, only exact match for both name and size
94   foreach(QString basedir, _themedIconDirNames) {
95     QDir sizedir(QString("%1/%2x%2").arg(basedir).arg(QString::number(size)));
96     if(sizedir.exists()) {
97       // ignore context, i.e. scan all subdirs
98       QStringList contextdirs = sizedir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
99       foreach(QString dir, contextdirs) {
100         QString path = QString("%1/%2/%3").arg(sizedir.absolutePath(), dir, fname);
101         if(QFile::exists(path)) return path;
102       }
103     }
104   }
105   // Now check the plain dirs
106   foreach(QString dir, _plainIconDirNames) {
107     QString path = QString("%1/%2").arg(dir, name);
108     if(QFile::exists(path)) return path;
109   }
110
111   return QString();
112 }