source: trunk/third/gnome-applets/geyes/themes.c @ 20910

Revision 20910, 14.3 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20909, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (C) 1999 Dave Camp <dave@davec.dhs.org>
3 * 
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 * 
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 * 
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 * 
18 */
19
20#include <config.h>
21#include <gnome.h>
22#include <string.h>
23#include <dirent.h>
24#include <limits.h>
25#include <ctype.h>
26
27#include <gconf/gconf-client.h>
28#include <panel-applet-gconf.h>
29#include <libgnomeui/gnome-help.h>
30#include "geyes.h"
31
32#define NUM_THEME_DIRECTORIES 2
33#define HIG_IDENTATION  "    "
34
35gchar *theme_directories[NUM_THEME_DIRECTORIES];
36
37void
38theme_dirs_create (void)
39{
40        static gboolean themes_created = FALSE;
41       
42        if (themes_created == TRUE)
43                return;
44
45        theme_directories[0] = g_strdup (GEYES_THEMES_DIR);
46        theme_directories[1] = g_strdup_printf ("%s/.gnome2/geyes-themes/", g_get_home_dir());
47
48        themes_created = TRUE;
49}
50
51static void
52parse_theme_file (EyesApplet *eyes_applet, FILE *theme_file)
53{
54        gchar line_buf [512]; /* prolly overkill */
55        gchar *token;
56        fgets (line_buf, 512, theme_file);
57        while (!feof (theme_file)) {
58                token = strtok (line_buf, "=");
59                if (strncmp (token, "wall-thickness",
60                             strlen ("wall-thickness")) == 0) {
61                        token += strlen ("wall-thickness");
62                        while (!isdigit (*token)) {
63                                token++;
64                        }
65                        sscanf (token, "%d", &eyes_applet->wall_thickness);
66                } else if (strncmp (token, "num-eyes", strlen ("num-eyes")) == 0) {
67                        token += strlen ("num-eyes");
68                        while (!isdigit (*token)) {
69                                token++;
70                        }
71                        sscanf (token, "%d", &eyes_applet->num_eyes);
72                        if (eyes_applet->num_eyes > MAX_EYES)
73                                eyes_applet->num_eyes = MAX_EYES;
74                } else if (strncmp (token, "eye-pixmap", strlen ("eye-pixmap")) == 0) {
75                        token = strtok (NULL, "\"");
76                        token = strtok (NULL, "\"");         
77                        if (eyes_applet->eye_filename != NULL)
78                                g_free (eyes_applet->eye_filename);
79                        eyes_applet->eye_filename = g_strdup_printf ("%s%s",
80                                                                    eyes_applet->theme_dir,
81                                                                    token);
82                } else if (strncmp (token, "pupil-pixmap", strlen ("pupil-pixmap")) == 0) {
83                        token = strtok (NULL, "\"");
84                        token = strtok (NULL, "\"");     
85            if (eyes_applet->pupil_filename != NULL)
86                    g_free (eyes_applet->pupil_filename);
87            eyes_applet->pupil_filename
88                    = g_strdup_printf ("%s%s",
89                                       eyes_applet->theme_dir,
90                                       token);   
91                }
92                fgets (line_buf, 512, theme_file);
93        }       
94}
95
96int
97load_theme (EyesApplet *eyes_applet, const gchar *theme_dir)
98{
99        GtkWidget *dialog;
100
101        FILE* theme_file;
102        gchar *file_name;
103
104        eyes_applet->theme_dir = g_strdup_printf ("%s/", theme_dir);
105
106        file_name = g_strdup_printf("%s%s",theme_dir,"/config");
107        theme_file = fopen (file_name, "r");
108        if (theme_file == NULL) {
109                g_free (eyes_applet->theme_dir);
110                eyes_applet->theme_dir = g_strdup_printf (GEYES_THEMES_DIR "Default-tiny/");
111                g_free (file_name);
112                file_name = g_strdup (GEYES_THEMES_DIR "Default-tiny/config");
113                theme_file = fopen (file_name, "r");
114        }
115
116        /* if it's still NULL we've got a major problem */
117        if (theme_file == NULL) {
118                dialog = gtk_message_dialog_new_with_markup (NULL,
119                                GTK_DIALOG_DESTROY_WITH_PARENT,
120                                GTK_MESSAGE_ERROR,
121                                GTK_BUTTONS_OK,
122                                "<b>%s</b>\n\n%s",
123                                _("Can not launch the eyes applet."),
124                                _("There was a fatal error while trying to load the theme."));
125
126                gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
127
128                gtk_dialog_run (GTK_DIALOG (dialog));
129                gtk_widget_destroy (dialog);
130
131                gtk_widget_destroy (GTK_WIDGET (eyes_applet->applet));
132
133                return FALSE;
134        }
135
136        parse_theme_file (eyes_applet, theme_file);
137        fclose (theme_file);
138
139        eyes_applet->theme_name = g_strdup (theme_dir);
140       
141        if (eyes_applet->eye_image)
142                g_object_unref (eyes_applet->eye_image);
143        eyes_applet->eye_image = gdk_pixbuf_new_from_file (eyes_applet->eye_filename, NULL);
144        if (eyes_applet->pupil_image)
145                g_object_unref (eyes_applet->pupil_image);
146        eyes_applet->pupil_image = gdk_pixbuf_new_from_file (eyes_applet->pupil_filename, NULL);
147
148        eyes_applet->eye_height = gdk_pixbuf_get_height (eyes_applet->eye_image);
149        eyes_applet->eye_width = gdk_pixbuf_get_width (eyes_applet->eye_image);
150        eyes_applet->pupil_height = gdk_pixbuf_get_height (eyes_applet->pupil_image);
151        eyes_applet->pupil_width = gdk_pixbuf_get_width (eyes_applet->pupil_image);
152       
153        g_free (file_name);
154   
155        return TRUE;
156}
157
158static void
159destroy_theme (EyesApplet *eyes_applet)
160{
161        /* Dunno about this - to unref or not to unref? */
162        if (eyes_applet->eye_image != NULL) {
163                gdk_pixbuf_unref (eyes_applet->eye_image);
164                eyes_applet->eye_image = NULL;
165        }
166        if (eyes_applet->pupil_image != NULL) {
167                gdk_pixbuf_unref (eyes_applet->pupil_image);
168                eyes_applet->pupil_image = NULL;
169        }
170       
171        g_free (eyes_applet->theme_dir);
172        g_free (eyes_applet->theme_name);
173}
174
175static gboolean
176key_writable (PanelApplet *applet, const char *key)
177{
178        gboolean writable;
179        char *fullkey;
180        static GConfClient *client = NULL;
181
182        if (client == NULL)
183                client = gconf_client_get_default ();
184
185        fullkey = panel_applet_gconf_get_full_key (applet, key);
186
187        writable = gconf_client_key_is_writable (client, fullkey, NULL);
188
189        g_free (fullkey);
190
191        return writable;
192}
193
194static void
195theme_selected_cb (GtkTreeSelection *selection, gpointer data)
196{
197        EyesApplet *eyes_applet = data;
198        GtkTreeModel *model;
199        GtkTreeIter iter;
200        gchar *theme;
201        gchar *theme_dir;
202       
203        if (!gtk_tree_selection_get_selected (selection, &model, &iter))
204                return;
205       
206        gtk_tree_model_get (model, &iter, 0, &theme, -1);
207       
208        g_return_if_fail (theme);
209       
210        theme_dir = g_strdup_printf ("%s/", theme);
211        if (!g_ascii_strncasecmp (theme_dir, eyes_applet->theme_dir, strlen (theme_dir))) {
212                g_free (theme_dir);
213                return;
214        }
215        g_free (theme_dir);
216               
217        destroy_eyes (eyes_applet);
218        destroy_theme (eyes_applet);
219        load_theme (eyes_applet, theme);
220        setup_eyes (eyes_applet);
221       
222        panel_applet_gconf_set_string (
223                eyes_applet->applet, "theme_path", theme, NULL);
224       
225        g_free (theme);
226}
227
228static void
229phelp_cb (GtkDialog *dialog)
230{
231        GError *error = NULL;
232
233        gnome_help_display_on_screen (
234                "geyes", "geyes-settings",
235                gtk_window_get_screen (GTK_WINDOW (dialog)),
236                &error);
237
238        if (error) { /* FIXME: the user needs to see this */
239                g_warning ("help error: %s\n", error->message);
240                g_error_free (error);
241                error = NULL;
242        }
243}
244
245static void
246presponse_cb (GtkDialog *dialog, gint id, gpointer data)
247{
248        EyesApplet *eyes_applet = data;
249        if(id == GTK_RESPONSE_HELP){
250                phelp_cb (dialog);
251                return;
252        }
253
254
255        gtk_widget_destroy (GTK_WIDGET (dialog));
256
257        eyes_applet->prop_box.pbox = NULL;
258}
259
260void
261properties_cb (BonoboUIComponent *uic,
262               EyesApplet        *eyes_applet,
263               const gchar       *verbname)
264{
265        GtkWidget *pbox, *hbox;
266        GtkWidget *vbox, *indent;
267        GtkWidget *categories_vbox;
268        GtkWidget *category_vbox, *control_vbox;
269        GtkWidget *tree;
270        GtkWidget *scrolled;
271        GtkWidget *label;
272        GtkListStore *model;
273        GtkTreeViewColumn *column;
274        GtkCellRenderer *cell;
275        GtkTreeSelection *selection;
276        GtkTreeIter iter;
277        DIR *dfd;
278        struct dirent *dp;
279        int i;
280#ifdef PATH_MAX
281        gchar filename [PATH_MAX];
282#else
283        gchar *filename;
284#endif
285        gchar *title;
286     
287        if (eyes_applet->prop_box.pbox) {
288                gtk_window_set_screen (
289                        GTK_WINDOW (eyes_applet->prop_box.pbox),
290                        gtk_widget_get_screen (GTK_WIDGET (eyes_applet->applet)));
291                gtk_window_present (GTK_WINDOW (eyes_applet->prop_box.pbox));
292                return;
293        }
294
295        pbox = gtk_dialog_new_with_buttons (_("Geyes Preferences"), NULL,
296                                             GTK_DIALOG_DESTROY_WITH_PARENT,
297                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
298                                             GTK_STOCK_HELP, GTK_RESPONSE_HELP,
299                                             NULL);
300
301        gtk_window_set_screen (GTK_WINDOW (pbox),
302                               gtk_widget_get_screen (GTK_WIDGET (eyes_applet->applet)));
303       
304        gtk_widget_set_size_request (GTK_WIDGET (pbox), 300, 200);
305        gtk_window_set_resizable (GTK_WINDOW (pbox), FALSE);
306        gtk_dialog_set_default_response(GTK_DIALOG (pbox), GTK_RESPONSE_CLOSE);
307        gtk_dialog_set_has_separator (GTK_DIALOG (pbox), FALSE);
308        gtk_container_set_border_width (GTK_CONTAINER (pbox), 5);
309        gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (pbox)->vbox), 2);
310
311        g_signal_connect (pbox, "response",
312                          G_CALLBACK (presponse_cb),
313                          eyes_applet);
314       
315        vbox = gtk_vbox_new (FALSE, 0);
316        gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
317        gtk_widget_show (vbox);
318       
319        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pbox)->vbox), vbox,
320                            TRUE, TRUE, 0);
321
322        categories_vbox = gtk_vbox_new (FALSE, 18);
323        gtk_box_pack_start (GTK_BOX (vbox), categories_vbox, TRUE, TRUE, 0);
324        gtk_widget_show (categories_vbox);
325
326        category_vbox = gtk_vbox_new (FALSE, 6);
327        gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0);
328        gtk_widget_show (category_vbox);
329       
330        title = g_strconcat ("<span weight=\"bold\">", _("Themes"), "</span>", NULL);
331        label = gtk_label_new (_(title));
332        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
333        gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
334        gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
335        gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0);
336        g_free (title);
337       
338        hbox = gtk_hbox_new (FALSE, 0);
339        gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0);
340        gtk_widget_show (hbox);
341       
342        indent = gtk_label_new (HIG_IDENTATION);
343        gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT);
344        gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0);
345        gtk_widget_show (indent);
346       
347        control_vbox = gtk_vbox_new (FALSE, 6);
348        gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0);
349        gtk_widget_show (control_vbox);
350       
351        label = gtk_label_new_with_mnemonic (_("_Select a theme:"));
352        gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
353        gtk_box_pack_start (GTK_BOX (control_vbox), label, FALSE, FALSE, 0);
354
355        scrolled = gtk_scrolled_window_new (NULL, NULL);
356        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN);
357        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
358                                        GTK_POLICY_AUTOMATIC,
359                                        GTK_POLICY_AUTOMATIC);
360
361        model = gtk_list_store_new (1, G_TYPE_STRING);
362        tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
363        gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree), FALSE);
364        gtk_label_set_mnemonic_widget (GTK_LABEL (label), tree);
365        g_object_unref (model);
366
367        gtk_container_add (GTK_CONTAINER (scrolled), tree);
368       
369        cell = gtk_cell_renderer_text_new ();
370        column = gtk_tree_view_column_new_with_attributes ("not used", cell,
371                                                           "text", 0, NULL);
372        gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
373                                                           
374        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
375        g_signal_connect (selection, "changed",
376                          G_CALLBACK (theme_selected_cb),
377                          eyes_applet);
378
379        if ( ! key_writable (eyes_applet->applet, "theme_path")) {
380                gtk_widget_set_sensitive (tree, FALSE);
381                gtk_widget_set_sensitive (label, FALSE);
382        }
383
384        for (i = 0; i < NUM_THEME_DIRECTORIES; i++) {
385                if ((dfd = opendir (theme_directories[i])) != NULL) {
386                        while ((dp = readdir (dfd)) != NULL) {
387                                if (dp->d_name[0] != '.') {
388                                        gchar *elems[2] = {NULL, NULL };
389                                        gchar *theme_dir;
390                                        elems[0] = filename;
391#ifdef PATH_MAX
392                                        strcpy (filename,
393                                                theme_directories[i]);
394                                        strcat (filename, dp->d_name);
395#else
396                                        asprintf (&filename, theme_directories[i], dp->d_name);
397#endif
398                                        gtk_list_store_insert (model, &iter, 0);
399                                        gtk_list_store_set (model, &iter, 0, &filename, -1);
400                                        theme_dir = g_strdup_printf ("%s/", filename);
401                                       
402                                        if (!g_ascii_strncasecmp (eyes_applet->theme_dir, theme_dir, strlen (theme_dir))) {
403                                                GtkTreePath *path;
404                                                path = gtk_tree_model_get_path (GTK_TREE_MODEL (model),
405                                                                                &iter);
406                                                gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree),
407                                                                          path,
408                                                                          NULL,
409                                                                          FALSE);
410                                                gtk_tree_path_free (path);
411                                        }
412                                        g_free (theme_dir);
413                                }
414                        }
415                        closedir (dfd);
416                }
417        }
418#ifndef PATH_MAX
419        g_free (filename);
420#endif
421       
422        gtk_box_pack_start (GTK_BOX (control_vbox), scrolled, TRUE, TRUE, 0);
423       
424        gtk_widget_show_all (pbox);
425       
426        eyes_applet->prop_box.pbox = pbox;
427       
428        return;
429}
430
431
Note: See TracBrowser for help on using the repository browser.