rebuilt pot after UI changes
[lxde/lxappearance.git] / src / icon-theme.c
CommitLineData
0cd84ed6
HJYP
1/*
2 * icon-theme.c
3 *
4 * Copyright 2010 PCMan <pcman.tw@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22#include "icon-theme.h"
15c155a6
HJYP
23#include "lxappearance2.h"
24#include <string.h>
2800b8a3 25#include "utils.h"
0cd84ed6 26
15c155a6
HJYP
27gint icon_theme_cmp_name(IconTheme* t, const char* name)
28{
29 return strcmp(t->name, name);
30}
31
32gint icon_theme_cmp_disp_name(IconTheme* t1, IconTheme* t2)
33{
34 return g_utf8_collate(t1->disp_name, t2->disp_name);
35}
36
37static void icon_theme_free(IconTheme* theme)
38{
39 g_free(theme->comment);
40 g_free(theme->name);
41 if(theme->disp_name != theme->name)
42 g_free(theme->disp_name);
43 g_slice_free(IconTheme, theme);
44}
45
46static void load_icon_themes_from_dir(const char* theme_dir, GKeyFile* kf)
47{
48 GDir* dir = g_dir_open(theme_dir, 0, NULL);
49 if(dir)
50 {
51 const char* name;
52 while(name = g_dir_read_name(dir))
53 {
54 /* skip "default" */
55 if(G_UNLIKELY(strcmp(name, "default") == 0))
56 continue;
57 /* test if we already have this in list */
58 if(!g_slist_find_custom(app.icon_themes, name, (GCompareFunc)icon_theme_cmp_name))
59 {
60 IconTheme* theme = g_slice_new0(IconTheme);
61 char* index_theme;
62 char* cursor_subdir;
63
64 theme->name = g_strdup(name);
65 index_theme = g_build_filename(theme_dir, name, "index.theme", NULL);
66 if(g_key_file_load_from_file(kf, index_theme, 0, NULL))
67 {
68 /* skip hidden ones */
69 if(!g_key_file_get_boolean(kf, "Icon Theme", "Hidden", NULL))
70 {
71 theme->disp_name = g_key_file_get_locale_string(kf, "Icon Theme", "Name", NULL, NULL);
72 /* test if this is a icon theme or it's a cursor theme */
73 theme->comment = g_key_file_get_locale_string(kf, "Icon Theme", "Comment", NULL, NULL);
74
75 /* icon theme must have this key, so it has icons if it has this key */
76 theme->has_icon = g_key_file_has_key(kf, "Icon Theme", "Directories", NULL);
77 }
78 }
79 else
80 theme->disp_name = theme->name;
81 g_free(index_theme);
82
83 cursor_subdir = g_build_filename(theme_dir, name, "cursors", NULL);
84 /* it contains a cursor theme */
85 if(g_file_test(cursor_subdir, G_FILE_TEST_IS_DIR))
86 theme->has_cursor = TRUE;
87 g_free(cursor_subdir);
88
89 if(theme->has_icon || theme->has_cursor)
90 app.icon_themes = g_slist_prepend(app.icon_themes, theme);
91 else /* this dir contains no icon or cursor theme, drop it. */
92 icon_theme_free(theme);
93 }
94 }
95 g_dir_close(dir);
96 }
97}
98
99static void load_icon_themes()
100{
101 const char* const *dirs = g_get_system_data_dirs();
102 const char* const *pdir;
103 char* dir_path;
104 GKeyFile* kf = g_key_file_new();
105
106 dir_path = g_build_filename(g_get_home_dir(), ".icons", NULL);
107 load_icon_themes_from_dir(dir_path, kf);
108 g_free(dir_path);
109
110 dir_path = g_build_filename(g_get_user_data_dir(), "icons", NULL);
111 load_icon_themes_from_dir(dir_path, kf);
112 g_free(dir_path);
113
114 for(pdir = dirs; *pdir; ++pdir)
115 {
116 dir_path = g_build_filename(*pdir, "icons", NULL);
117 load_icon_themes_from_dir(dir_path, kf);
118 g_free(dir_path);
119 }
120 g_key_file_free(kf);
121
122 app.icon_themes = g_slist_sort(app.icon_themes, (GCompareFunc)icon_theme_cmp_disp_name);
123}
124
125static void icon_sizes_init(GtkBuilder* b)
126{
127 const char* names[] = {
128 "gtk-menu",
129 "gtk-button",
130 "gtk-small-toolbar",
131 "gtk-large-toolbar",
132 "gtk-dnd",
133 "gtk-dialog"
134 };
135 char* sizes_str;
d023f0a4 136 g_object_get(gtk_settings_get_default(), "gtk-icon-sizes", &sizes_str, NULL);
15c155a6
HJYP
137 g_debug("%s", sizes_str);
138}
0cd84ed6 139
4e409096
HJYP
140static void on_icon_theme_sel_changed(GtkTreeSelection* tree_sel, gpointer user_data)
141{
142 GtkTreeModel* model;
143 GtkTreeIter it;
144 if(gtk_tree_selection_get_selected(tree_sel, &model, &it))
145 {
146 IconTheme* theme;
147 gtk_tree_model_get(model, &it, 1, &theme, -1);
148 if(g_strcmp0(theme->name, app.icon_theme))
149 {
150 g_free(app.icon_theme);
151 app.icon_theme = g_strdup(theme->name);
152 g_object_set(gtk_settings_get_default(), "gtk-icon-theme-name", app.icon_theme, NULL);
153
154 lxappearance_changed();
155 }
156 }
157}
158
2800b8a3
HJYP
159static void on_install_theme_clicked(GtkButton* btn, gpointer user_data)
160{
161 install_icon_theme(gtk_widget_get_toplevel(btn));
162}
163
0cd84ed6
HJYP
164void icon_theme_init(GtkBuilder* b)
165{
15c155a6
HJYP
166 GSList* l;
167 GtkTreeIter it;
168 GtkTreeIter icon_theme_sel_it = {0};
169 GtkTreeIter cursor_theme_sel_it = {0};
170 GtkTreeSelection* sel;
171
172 app.icon_theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
173 app.cursor_theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
174 app.icon_theme_view = GTK_WIDGET(gtk_builder_get_object(b, "icon_theme_view"));
175 app.cursor_theme_view = GTK_WIDGET(gtk_builder_get_object(b, "cursor_theme_view"));
176
0cd84ed6 177 /* load icon themes */
15c155a6
HJYP
178 load_icon_themes();
179
180 for(l = app.icon_themes; l; l=l->next)
181 {
182 IconTheme* theme = (IconTheme*)l->data;
183
184 if(theme->has_icon)
185 {
186 gtk_list_store_insert_with_values(app.icon_theme_store, &it, -1, 0, theme->disp_name, 1, theme, -1);
187 if(!icon_theme_sel_it.user_data)
188 {
189 if(strcmp(theme->name, app.icon_theme) == 0)
190 icon_theme_sel_it = it;
191 }
192 }
193
194 if(theme->has_cursor)
195 {
196 gtk_list_store_insert_with_values(app.cursor_theme_store, &it, -1, 0, theme->disp_name, 1, theme, -1);
197 if(!cursor_theme_sel_it.user_data)
198 {
199 if(g_strcmp0(theme->name, app.cursor_theme) == 0)
200 cursor_theme_sel_it = it;
201 }
202 }
203 }
204
205 /* select the currently used theme from the list */
206 gtk_tree_view_set_model(app.icon_theme_view, GTK_TREE_MODEL(app.icon_theme_store));
207 sel = gtk_tree_view_get_selection(app.icon_theme_view);
208 if(icon_theme_sel_it.user_data)
e597424e
HJYP
209 {
210 GtkTreePath* tp = gtk_tree_model_get_path(GTK_TREE_MODEL(app.icon_theme_store), &icon_theme_sel_it);
15c155a6 211 gtk_tree_selection_select_iter(sel, &icon_theme_sel_it);
e597424e
HJYP
212 gtk_tree_view_scroll_to_cell(app.icon_theme_view, tp, NULL, FALSE, 0, 0);
213 gtk_tree_path_free(tp);
214 }
4e409096 215 g_signal_connect(sel, "changed", G_CALLBACK(on_icon_theme_sel_changed), NULL);
15c155a6
HJYP
216
217 gtk_tree_view_set_model(app.cursor_theme_view, GTK_TREE_MODEL(app.cursor_theme_store));
218 sel = gtk_tree_view_get_selection(app.cursor_theme_view);
219 if(cursor_theme_sel_it.user_data)
e597424e
HJYP
220 {
221 GtkTreePath* tp = gtk_tree_model_get_path(GTK_TREE_MODEL(app.cursor_theme_store), &cursor_theme_sel_it);
15c155a6 222 gtk_tree_selection_select_iter(sel, &cursor_theme_sel_it);
e597424e
HJYP
223 gtk_tree_view_scroll_to_cell(app.cursor_theme_view, tp, NULL, FALSE, 0, 0);
224 gtk_tree_path_free(tp);
225 }
0cd84ed6
HJYP
226
227 /* load "gtk-icon-sizes" */
15c155a6 228 icon_sizes_init(b);
2800b8a3
HJYP
229
230 GtkWidget* btn = gtk_builder_get_object(b, "install_icon_theme");
231 g_signal_connect(btn, "clicked", G_CALLBACK(on_install_theme_clicked), NULL);
0cd84ed6 232}