]> icculus.org git repositories - dana/obconf.git/blob - src/theme.c
don't show the main window until the theme previews are done.
[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 #include "preview.h"
27
28 static gboolean mapping = FALSE;
29
30 static GList *themes;
31 static GtkListStore *theme_store;
32
33 static void add_theme_dir(const gchar *dirname);
34 static void reset_theme_names(GtkWidget *w);
35 static void on_theme_names_selection_changed(GtkTreeSelection *sel,
36                                              gpointer data);
37
38 void theme_setup_tab()
39 {
40     GtkCellRenderer *render;
41     GtkTreeViewColumn *column;
42     GtkTreeSelection *select;
43     GtkWidget *w;
44
45     mapping = TRUE;
46
47     w = get_widget("theme_names");
48
49     /* widget setup */
50     theme_store = gtk_list_store_new(2, G_TYPE_STRING, GDK_TYPE_PIXBUF);
51     gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(theme_store));
52     preview_update_set_tree_view(GTK_TREE_VIEW(w), theme_store);
53     g_object_unref (theme_store);
54
55     gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
56                                 GTK_SELECTION_SINGLE);
57
58     /* text column for the names */
59     render = gtk_cell_renderer_text_new();
60     column = gtk_tree_view_column_new_with_attributes
61         ("Name", render, "text", 0, NULL);
62     gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
63
64     /* pixbuf column, for theme previews */
65     render = gtk_cell_renderer_pixbuf_new();
66     g_object_set(render, "xalign", 1.0);
67     column = gtk_tree_view_column_new_with_attributes
68         ("Preview", render, "pixbuf", 1, NULL);
69     gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
70
71     /* setup the selection handler */
72     select = gtk_tree_view_get_selection(GTK_TREE_VIEW (w));
73     gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
74     g_signal_connect (G_OBJECT(select), "changed",
75                       G_CALLBACK(on_theme_names_selection_changed),
76                       NULL);
77
78     reset_theme_names(w);
79
80     mapping = FALSE;
81 }
82
83 static void on_theme_names_selection_changed(GtkTreeSelection *sel,
84                                              gpointer data)
85 {
86     GtkTreeIter iter;
87     GtkTreeModel *model;
88     const gchar *name;
89
90     if (mapping) return;
91
92     if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
93         gtk_tree_model_get(model, &iter, 0, &name, -1);
94     }
95
96     if(name)
97       tree_set_string("theme/name", name);
98 }
99
100 void on_install_theme_clicked(GtkButton *w, gpointer data)
101 {
102     GtkWidget *d;
103     gint r;
104     gchar *path = NULL;
105     GtkFileFilter *filter;
106
107     d = gtk_file_chooser_dialog_new(_("Choose an Openbox theme"),
108                                     GTK_WINDOW(mainwin),
109                                     GTK_FILE_CHOOSER_ACTION_OPEN,
110                                     GTK_STOCK_OK, GTK_RESPONSE_OK,
111                                     GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
112                                     NULL);
113
114     gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(d), FALSE);
115     filter = gtk_file_filter_new();
116     gtk_file_filter_set_name(filter, _("Openbox theme archives"));
117     gtk_file_filter_add_pattern(filter, "*.obt");
118     //gtk_file_filter_add_pattern(filter, "*.tgz");
119     //gtk_file_filter_add_pattern(filter, "*.tar.gz");
120     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(d), filter);
121
122     r = gtk_dialog_run(GTK_DIALOG(d));
123     if (r == GTK_RESPONSE_OK)
124         path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
125     gtk_widget_destroy(d);
126
127     if (path != NULL) {
128         theme_install(path);
129         g_free(path);
130     }
131 }
132
133 void on_theme_archive_clicked(GtkButton *w, gpointer data)
134 {
135     GtkWidget *d;
136     gint r;
137     gchar *path = NULL;
138
139     d = gtk_file_chooser_dialog_new(_("Choose an Openbox theme"),
140                                     GTK_WINDOW(mainwin),
141                                     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
142                                     GTK_STOCK_OK, GTK_RESPONSE_OK,
143                                     GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
144                                     NULL);
145
146     gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(d), TRUE);
147     r = gtk_dialog_run(GTK_DIALOG(d));
148     if (r == GTK_RESPONSE_OK)
149         path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
150     gtk_widget_destroy(d);
151
152     if (path != NULL) {
153         archive_create(path);
154         g_free(path);
155     }
156 }
157
158 void theme_install(const gchar *path)
159 {
160     gchar *name;
161
162     if ((name = archive_install(path))) {
163         GtkWidget *w;
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             GtkTreePath *path;
177
178             path = gtk_tree_path_new_from_indices(i, -1);
179             gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE);
180             gtk_tree_path_free(path);
181         }
182
183         g_free(name);
184     }
185 }
186
187
188
189
190
191
192 static void reset_theme_names(GtkWidget *w)
193 {
194     gchar *name;
195     gchar *p;
196     GList *it, *next;
197     gint i;
198     GtkTreePath *path = NULL;
199
200     RrFont *active, *inactive, *menu_t, *menu_i, *osd;
201
202     name = tree_get_string("theme/name", "TheBear");
203
204     for (it = themes; it; it = g_list_next(it))
205         g_free(it->data);
206     g_list_free(themes);
207     themes = NULL;
208
209     p = g_build_filename(g_get_home_dir(), ".themes", NULL);
210     add_theme_dir(p);
211     g_free(p);
212
213     {
214         GSList *it;
215         for (it = parse_xdg_data_dir_paths(); it; it = g_slist_next(it)) {
216             p = g_build_filename(it->data, "themes", NULL);
217             add_theme_dir(p);
218             g_free(p);
219         }
220     }
221
222     add_theme_dir(THEMEDIR);
223
224     themes = g_list_sort(themes, (GCompareFunc) strcasecmp);
225
226     gtk_list_store_clear(theme_store);
227
228     /* return to regular scheduled programming */
229     i = 0;
230     for (it = themes; it; it = next) {
231         GtkTreeIter iter;
232
233         next = g_list_next(it);
234
235         /* remove duplicates */
236         if (next && !strcmp(it->data, next->data)) {
237             g_free(it->data);
238             themes = g_list_delete_link(themes, it);
239             continue;
240         }
241
242         gtk_list_store_append(theme_store, &iter);
243         gtk_list_store_set(theme_store, &iter,
244                            0, it->data,
245                            1, NULL,
246                            -1);
247
248         if(!strcmp(name, it->data))
249             path = gtk_tree_path_new_from_indices(i, -1);
250
251         ++i;
252     }
253
254     preview_update_all();
255
256     /* do this after starting the preview update */
257     if (path) {
258         gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE);
259         gtk_tree_path_free(path);
260     }
261
262     g_free(name);
263 }
264
265 static void add_theme_dir(const gchar *dirname)
266 {
267     GDir *dir;
268     const gchar *n;
269
270     if ((dir = g_dir_open(dirname, 0, NULL))) {
271         while ((n = g_dir_read_name(dir))) {
272             {
273                 gchar *full;
274                 full = g_build_filename(dirname, n, "openbox-3",
275                                         "themerc", NULL);
276                 if (!g_file_test(full,
277                                  G_FILE_TEST_IS_REGULAR |
278                                  G_FILE_TEST_IS_SYMLINK))
279                     n = NULL;
280                 g_free(full);
281             }
282
283             if (n) {
284                 themes = g_list_append(themes, g_strdup(n));
285             }
286         }
287         g_dir_close(dir);
288     }
289 }
290