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