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