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