Rewrite of LXAppearance.
[lxde/lxappearance.git] / src / widget-theme.c
1 /*
2 * widget-theme.c
3 *
4 * Copyright 2010 PCMan <pcman.tw@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include "widget-theme.h"
23 #include <string.h>
24
25 static GtkWidget* widget_theme_view;
26 static GtkListStore* store;
27
28 static GSList* load_themes_in_dir(const char* theme_dir, GSList* themes)
29 {
30 GDir* dir = g_dir_open(theme_dir, 0, NULL);
31 if(dir)
32 {
33 const char* name;
34 while(name = g_dir_read_name(dir))
35 {
36 /* test if we already have this in list */
37 if(!g_slist_find_custom(themes, name, (GCompareFunc)strcmp))
38 {
39 /* test if this is a gtk theme */
40 char* gtkrc = g_build_filename(theme_dir, name, "gtk-2.0/gtkrc", NULL);
41 if(g_file_test(gtkrc, G_FILE_TEST_EXISTS))
42 themes = g_list_prepend(themes, g_strdup(name));
43 g_free(gtkrc);
44 }
45 }
46 g_dir_close(dir);
47 }
48 return themes;
49 }
50
51 static void on_sel_changed(GtkTreeSelection* sel, gpointer user_data)
52 {
53 GtkTreeIter it;
54 GtkTreeModel* model;
55 if(gtk_tree_selection_get_selected(sel, &model, &it))
56 {
57 char* theme_name;
58 gtk_tree_model_get(model, &it, 0, &theme_name, -1);
59 g_object_set(gtk_settings_get_default(), "gtk-theme-name", theme_name, NULL);
60 g_free(theme_name);
61
62 /*
63 FIXME: check if current theme support color schemes.
64
65 char* color_scheme;
66 g_object_get(gtk_settings_get_default(), "gtk-color-scheme", &color_scheme, NULL);
67 g_debug("gtk-color-scheme:%s", color_scheme);
68 g_free(color_scheme);
69 */
70 }
71 }
72
73 static void load_themes()
74 {
75 char* dir;
76 GSList* themes = NULL, *l;
77 GtkTreeViewColumn* col;
78 char* current;
79 GtkTreeIter sel_it = {0};
80 GtkTreeSelection* tree_sel;
81
82 g_object_get(gtk_settings_get_default(), "gtk-theme-name", &current, NULL);
83
84 /* load user dir */
85 dir = g_build_filename(g_get_home_dir(), ".themes", NULL);
86 themes = load_themes_in_dir(dir, themes);
87 g_free(dir);
88
89 /* load system default */
90 dir = gtk_rc_get_theme_dir();
91 themes = load_themes_in_dir(dir, themes);
92 g_free(dir);
93
94 col = gtk_tree_view_column_new_with_attributes("", gtk_cell_renderer_text_new(), "text", 0, NULL);
95 gtk_tree_view_append_column(widget_theme_view, col);
96
97 themes = g_slist_sort(themes, (GCompareFunc)strcmp);
98 for(l = themes; l; l=l->next)
99 {
100 GtkTreeIter it;
101 char* name = (char*)l->data;
102 gtk_list_store_insert_with_values(store, &it, -1, 0, name, -1);
103 /* if this theme is the one currently in use */
104 if(!sel_it.user_data)
105 {
106 if(strcmp(name, current) == 0)
107 sel_it = it;
108 }
109 g_free(name);
110 }
111 g_free(current);
112
113 gtk_tree_view_set_model(widget_theme_view, GTK_TREE_MODEL(store));
114 tree_sel = gtk_tree_view_get_selection(widget_theme_view);
115 if(sel_it.user_data)
116 gtk_tree_selection_select_iter(tree_sel, &sel_it);
117
118 g_list_free(themes);
119
120 g_signal_connect(tree_sel, "changed", G_CALLBACK(on_sel_changed), NULL);
121
122 /* FIXME: we need to handle this, too. */
123 // g_signal_connect(gtk_settings_get_default(), "notify::gtk-theme-name", G_CALLBACK(on_sel_changed), NULL);
124 }
125
126 void widget_theme_init(GtkBuilder* b)
127 {
128 GtkWidget* demo;
129 GdkColor black = {0, 0, 0, 0};
130
131 demo = GTK_WIDGET(gtk_builder_get_object(b, "demo"));
132 widget_theme_view = GTK_WIDGET(gtk_builder_get_object(b, "widget_theme_view"));
133
134 gtk_widget_modify_bg(demo, GTK_STATE_NORMAL, &black);
135
136 /* load available themes */
137 store = gtk_list_store_new(1, G_TYPE_STRING);
138 load_themes();
139 }