]> icculus.org git repositories - dana/obconf.git/blob - src/theme.c
small cleanup for themes.c
[dana/obconf.git] / src / theme.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    theme.h for ObConf, the configuration tool for Openbox
4    Copyright (c) 2003-2007   Dana Jansens
5    Copyright (c) 2003        Tim Riley
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "main.h"
21 #include "tree.h"
22 #include "preview_update.h"
23 #include "gettext.h"
24 #include "archive.h"
25 #include "theme.h"
26
27 static gboolean mapping = FALSE;
28
29 static GList *themes;
30 static GtkListStore *theme_store;
31
32 static void add_theme_dir(const gchar *dirname);
33 static void reset_theme_names(GtkWidget *w);
34 static void on_theme_names_selection_changed(GtkTreeSelection *sel,
35                                              gpointer data);
36
37 void theme_setup_tab()
38 {
39     GtkCellRenderer *render;
40     GtkTreeViewColumn *column;
41     GtkTreeSelection *select;
42     GtkWidget *w;
43
44     mapping = TRUE;
45
46     w = get_widget("theme_names");
47
48     /* widget setup */
49     theme_store = gtk_list_store_new(2, G_TYPE_STRING, GDK_TYPE_PIXBUF);
50     gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(theme_store));
51     preview_update_set_list_store(theme_store);
52     g_object_unref (theme_store);
53
54     gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
55                                 GTK_SELECTION_SINGLE);
56
57     /* text column for the names */
58     render = gtk_cell_renderer_text_new();
59     column = gtk_tree_view_column_new_with_attributes
60         ("Name", render, "text", 0, NULL);
61     gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
62
63     /* pixbuf column, for theme previews */
64     render = gtk_cell_renderer_pixbuf_new();
65     g_object_set(render, "xalign", 1.0);
66     column = gtk_tree_view_column_new_with_attributes
67         ("Preview", render, "pixbuf", 1, NULL);
68     gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
69
70     /* setup the selection handler */
71     select = gtk_tree_view_get_selection(GTK_TREE_VIEW (w));
72     gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
73     g_signal_connect (G_OBJECT(select), "changed",
74                       G_CALLBACK(on_theme_names_selection_changed),
75                       NULL);
76
77     reset_theme_names(w);
78
79     mapping = FALSE;
80 }
81
82 static void on_theme_names_selection_changed(GtkTreeSelection *sel,
83                                              gpointer data)
84 {
85     GtkTreeIter iter;
86     GtkTreeModel *model;
87     const gchar *name;
88
89     if (mapping) return;
90
91     if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
92         gtk_tree_model_get(model, &iter, 0, &name, -1);
93     }
94
95     if(name)
96       tree_set_string("theme/name", name);
97 }
98
99 void on_install_theme_clicked(GtkButton *w, gpointer data)
100 {
101     GtkWidget *d;
102     gint r;
103     gchar *path = NULL;
104     GtkFileFilter *filter;
105
106     d = gtk_file_chooser_dialog_new(_("Choose an Openbox theme"),
107                                     GTK_WINDOW(mainwin),
108                                     GTK_FILE_CHOOSER_ACTION_OPEN,
109                                     GTK_STOCK_OK, GTK_RESPONSE_OK,
110                                     GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
111                                     NULL);
112
113     gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(d), FALSE);
114     filter = gtk_file_filter_new();
115     gtk_file_filter_set_name(filter, _("Openbox theme archives"));
116     gtk_file_filter_add_pattern(filter, "*.obt");
117     //gtk_file_filter_add_pattern(filter, "*.tgz");
118     //gtk_file_filter_add_pattern(filter, "*.tar.gz");
119     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(d), filter);
120
121     r = gtk_dialog_run(GTK_DIALOG(d));
122     if (r == GTK_RESPONSE_OK)
123         path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
124     gtk_widget_destroy(d);
125
126     if (path != NULL) {
127         theme_install(path);
128         g_free(path);
129     }
130 }
131
132 void on_theme_archive_clicked(GtkButton *w, gpointer data)
133 {
134     GtkWidget *d;
135     gint r;
136     gchar *path = NULL;
137
138     d = gtk_file_chooser_dialog_new(_("Choose an Openbox theme"),
139                                     GTK_WINDOW(mainwin),
140                                     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
141                                     GTK_STOCK_OK, GTK_RESPONSE_OK,
142                                     GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
143                                     NULL);
144
145     gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(d), TRUE);
146     r = gtk_dialog_run(GTK_DIALOG(d));
147     if (r == GTK_RESPONSE_OK)
148         path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
149     gtk_widget_destroy(d);
150
151     if (path != NULL) {
152         archive_create(path);
153         g_free(path);
154     }
155 }
156
157 void theme_install(const gchar *path)
158 {
159     gchar *name;
160
161     if ((name = archive_install(path))) {
162         GtkWidget *w;
163         GtkTreePath *path;
164         GList *it;
165         gint i;
166
167         w = glade_xml_get_widget(glade, "theme_names");
168         mapping = TRUE;
169         reset_theme_names(w);
170         mapping = FALSE;
171
172         /* go to the newly installed theme */
173         for (it = themes, i = 0; it; it = g_list_next(it), ++i)
174             if (!strcmp(it->data, name)) break;
175         if (it) {
176             path = gtk_tree_path_new_from_indices(i, -1);
177             gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE);
178             gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(w), path, NULL,
179                                          FALSE, 0, 0);
180         }
181
182         g_free(name);
183     }
184 }
185
186
187
188
189
190
191 static void reset_theme_names(GtkWidget *w)
192 {
193     gchar *name;
194     gchar *p;
195     GList *it, *next;
196     gint i;
197
198     RrFont *active, *inactive, *menu_t, *menu_i, *osd;
199
200     name = tree_get_string("theme/name", "TheBear");
201
202     for (it = themes; it; it = g_list_next(it))
203         g_free(it->data);
204     g_list_free(themes);
205     themes = NULL;
206
207     p = g_build_filename(g_get_home_dir(), ".themes", NULL);
208     add_theme_dir(p);
209     g_free(p);
210
211     {
212         GSList *it;
213         for (it = parse_xdg_data_dir_paths(); it; it = g_slist_next(it)) {
214             p = g_build_filename(it->data, "themes", NULL);
215             add_theme_dir(p);
216             g_free(p);
217         }
218     }
219
220     add_theme_dir(THEMEDIR);
221
222     themes = g_list_sort(themes, (GCompareFunc) strcasecmp);
223
224     gtk_list_store_clear(theme_store);
225
226     /* return to regular scheduled programming */
227     i = 0;
228     for (it = themes; it; it = next) {
229         GtkTreeIter iter;
230
231         next = g_list_next(it);
232
233         /* remove duplicates */
234         if (next && !strcmp(it->data, next->data)) {
235             g_free(it->data);
236             themes = g_list_delete_link(themes, it);
237             continue;
238         }
239
240         gtk_list_store_append(theme_store, &iter);
241         gtk_list_store_set(theme_store, &iter,
242                            0, it->data,
243                            1, NULL,
244                            -1);
245
246         if(!strcmp(name, it->data)) {
247             GtkTreePath *path;
248             path = gtk_tree_path_new_from_indices(i, -1);
249             gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE);
250             gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(w), path, NULL,
251                                          FALSE, 0, 0);
252         }
253
254
255         ++i;
256     }
257
258     preview_update_all();
259
260     g_free(name);
261 }
262
263 static void add_theme_dir(const gchar *dirname)
264 {
265     GDir *dir;
266     const gchar *n;
267
268     if ((dir = g_dir_open(dirname, 0, NULL))) {
269         while ((n = g_dir_read_name(dir))) {
270             {
271                 gchar *full;
272                 full = g_build_filename(dirname, n, "openbox-3",
273                                         "themerc", NULL);
274                 if (!g_file_test(full,
275                                  G_FILE_TEST_IS_REGULAR |
276                                  G_FILE_TEST_IS_SYMLINK))
277                     n = NULL;
278                 g_free(full);
279             }
280
281             if (n) {
282                 themes = g_list_append(themes, g_strdup(n));
283             }
284         }
285         g_dir_close(dir);
286     }
287 }
288