source: trunk/third/gtkhtml/src/gtkhtml-propmanager.c @ 18136

Revision 18136, 16.2 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18135, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/* This file is part of the GtkHTML library
3
4   Copyright (C) 2000, 2001, 2002 Ximian Inc.
5   Authors:           Larry Ewing <lewing@ximian.com>
6                      Radek Doulik <rodo@ximian.com>
7
8   This library is free software; you can redistribute it and/or
9   modify it under the terms of the GNU Library General Public
10   License as published by the Free Software Foundation; either
11   version 2 of the License, or (at your option) any later version.
12
13   This library is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHcANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   Library General Public License for more details.
17
18   You should have received a copy of the GNU Library General Public License
19   along with this library; see the file COPYING.LIB.  If not, write to
20   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21   Boston, MA 02111-1307, USA.
22*/
23#include <config.h>
24#include <glib.h>
25#include <gnome.h>
26
27
28#include "gtkhtml-propmanager.h"
29#include "gtkhtml-properties.h"
30
31#define d(x) x;
32
33static GtkObject *parent_class;
34
35enum {
36        CHANGED,
37        LAST_SIGNAL
38};
39
40enum {
41        KEYMAP_EMACS,
42        KEYMAP_XEMACS,
43        KEYMAP_MS,
44        KEYMAP_LAST
45};
46
47static char *keymap_names[KEYMAP_LAST + 1] = {"emacs", "xemacs", "ms", NULL};
48
49static guint signals [LAST_SIGNAL] = { 0 };
50
51struct _GtkHTMLPropmanagerPrivate {
52        GladeXML *xml;
53
54        GtkWidget *variable;
55        GtkWidget *variable_print;
56        GtkWidget *fixed;
57        GtkWidget *fixed_print;
58        GtkWidget *anim_check;
59        GtkWidget *live_spell_check;
60        GtkWidget *live_spell_options;
61        GtkWidget *magic_links_check;
62        GtkWidget *magic_smileys_check;
63        GtkWidget *keymap;
64       
65        GtkHTMLClassProperties *saved_prop;
66        GtkHTMLClassProperties *orig_prop;
67        GtkHTMLClassProperties *actual_prop;
68
69        GConfClient *client;
70       
71        guint notify_id;
72        gboolean active;
73
74        GHashTable *nametable;
75};
76
77static char *
78keymap_option_get (GtkWidget *option)
79{
80        GtkWidget *active;
81        char *name;
82        active = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (option))));
83       
84        name = gtk_object_get_data (GTK_OBJECT (active), "GtkHTMLPropKeymap");
85
86        return name ? name : "ms";
87}
88
89static void                           
90keymap_option_set (GtkWidget *option, char *name)
91{
92        int i = 0;
93       
94        while (i < KEYMAP_LAST) {
95                if (!strcmp (name, keymap_names[i])) {
96                        gtk_option_menu_set_history (GTK_OPTION_MENU (option), i);
97                }
98                i++;
99        }
100}
101
102
103static void
104gtk_html_propmanager_sync_gui (GtkHTMLPropmanager *pman)
105{
106        GtkHTMLPropmanagerPrivate *priv;
107
108        g_return_if_fail (pman != NULL);
109        priv = pman->priv;
110
111        if (priv->anim_check)
112                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->anim_check),
113                                              priv->actual_prop->animations);
114
115        if (priv->magic_links_check)
116                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->magic_links_check),
117                                              priv->actual_prop->magic_links);
118
119        if (priv->magic_smileys_check)
120                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->magic_smileys_check),
121                                              priv->actual_prop->magic_smileys);
122
123        if (priv->live_spell_check)
124                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->live_spell_check),
125                                              priv->actual_prop->live_spell_check);
126
127        if (priv->live_spell_options) {
128                gtk_widget_set_sensitive (GTK_WIDGET (priv->live_spell_options),
129                                          priv->actual_prop->live_spell_check);
130        }
131
132        if (priv->keymap) {
133                keymap_option_set (priv->keymap, priv->actual_prop->keybindings_theme);
134        }
135
136#define SET_FONT(f,w) \
137        if (w) gnome_font_picker_set_font_name (GNOME_FONT_PICKER (w), priv->actual_prop-> f);
138
139        SET_FONT (font_var,       priv->variable);
140        SET_FONT (font_fix,       priv->fixed);
141        SET_FONT (font_var_print, priv->variable_print);
142        SET_FONT (font_fix_print, priv->fixed_print);
143}
144       
145static void
146propmanager_client_notify (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer data)
147{
148        GtkHTMLPropmanager *pman = data;
149
150        if (!pman->priv->active) {
151                gtk_html_class_properties_load (pman->priv->actual_prop, client);
152                gtk_html_propmanager_sync_gui (pman);
153        }
154}
155
156static void
157propmanager_toggle_changed (GtkWidget *widget, GtkHTMLPropmanager *pman)
158{
159        g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
160
161        gtk_signal_emit (GTK_OBJECT (pman), signals[CHANGED]);
162}
163
164static void
165propmanager_keymap_changed (GtkWidget *menu, GtkHTMLPropmanager *pman)
166{
167        g_return_if_fail (GTK_IS_HTML_PROPMANAGER (pman));
168
169        gtk_signal_emit (GTK_OBJECT (pman), signals[CHANGED]); 
170}
171
172static void
173propmanager_font_changed (GtkWidget *picker, char *font_name, GtkHTMLPropmanager *pman)
174{
175        g_return_if_fail (GTK_IS_HTML_PROPMANAGER (pman));
176
177        gtk_signal_emit (GTK_OBJECT (pman), signals[CHANGED]);
178}
179
180#define SELECTOR(x) GTK_FONT_SELECTION_DIALOG (GNOME_FONT_PICKER (x)->font_dialog)
181
182static void
183propmanager_picker_clicked (GtkWidget *w, gpointer proportional)
184{
185        gchar *mono_spaced [] = { "c", "m", NULL };
186
187        if (!GPOINTER_TO_INT (proportional))
188                gtk_font_selection_dialog_set_filter (SELECTOR (w),
189                                                      GTK_FONT_FILTER_BASE, GTK_FONT_ALL,
190                                                      NULL, NULL, NULL, NULL,
191                                                      mono_spaced, NULL);
192}
193
194static void
195propmanager_child_destroyed (GtkWidget *w, GtkHTMLPropmanager *pman)
196{
197        GtkHTMLPropmanagerPrivate *priv;
198
199        g_return_if_fail (GTK_IS_HTML_PROPMANAGER (pman));
200        priv = pman->priv;
201
202        /* this is ugly but I am lazy */
203#define MAYBE_CLEAR(x) \
204        if (w == priv->x) priv->x = NULL;
205
206        MAYBE_CLEAR (variable);
207        MAYBE_CLEAR (variable_print);
208        MAYBE_CLEAR (fixed_print);
209        MAYBE_CLEAR (fixed);
210        MAYBE_CLEAR (anim_check);
211        MAYBE_CLEAR (live_spell_check);
212        MAYBE_CLEAR (magic_links_check);
213        MAYBE_CLEAR (magic_smileys_check);
214        MAYBE_CLEAR (live_spell_options);
215        MAYBE_CLEAR (keymap);
216
217        gtk_object_unref (GTK_OBJECT (pman));
218}
219
220static GtkWidget *
221propmanager_get_widget (GtkHTMLPropmanager *pman, char *name)
222{
223        char *xml_name = NULL;
224        GtkWidget *widget;
225
226        if (pman->priv->nametable)
227                xml_name = g_hash_table_lookup (pman->priv->nametable, name);
228
229        if (!xml_name)
230                xml_name = name;
231
232        widget = glade_xml_get_widget (pman->priv->xml, xml_name);
233
234        if (widget) {
235                gtk_object_ref (GTK_OBJECT (pman));
236
237                d(g_warning ("found_widget: %s", name));
238
239                gtk_signal_connect (GTK_OBJECT (widget), "destroy",
240                                    propmanager_child_destroyed, pman);
241        }
242
243        return glade_xml_get_widget (pman->priv->xml, xml_name);
244}
245
246static GtkWidget *
247propmanager_add_toggle (GtkHTMLPropmanager *pman,
248                        char *name,
249                        gboolean *found)
250{
251        GtkWidget *toggle;
252
253        toggle = propmanager_get_widget (pman, name);
254
255        if (toggle) {
256                if (!GTK_IS_TOGGLE_BUTTON (toggle))
257                        return NULL;
258
259                gtk_signal_connect (GTK_OBJECT (toggle), "toggled", propmanager_toggle_changed,
260                                    pman);
261
262                *found = TRUE;
263        }
264
265        return toggle;
266}
267
268static GtkWidget *
269propmanager_add_picker (GtkHTMLPropmanager *pman,
270                        char *name,
271                        gboolean proportional,
272                        gboolean *found)
273{
274        GtkWidget *picker;
275
276        picker = propmanager_get_widget (pman, name);
277
278        if (picker) {
279                if (!GNOME_IS_FONT_PICKER (picker))
280                        return NULL;
281
282                gtk_signal_connect (GTK_OBJECT (picker), "font_set", propmanager_font_changed,
283                                    pman);
284                gtk_signal_connect (GTK_OBJECT (picker), "clicked", propmanager_picker_clicked,
285                                    GINT_TO_POINTER (proportional));
286                *found = TRUE;
287        }
288        return picker;
289}
290
291static GtkWidget *
292propmanager_add_keymap (GtkHTMLPropmanager *pman, char *name, gboolean *found)
293{
294        GtkWidget *option;
295        GtkWidget *menu;
296        GList *items;
297        gint i;
298
299        option = propmanager_get_widget (pman, name);
300
301        if (option) {
302                if (!GTK_IS_OPTION_MENU (option))
303                        return NULL;
304
305                menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (option));
306               
307                i = 0;
308                items = GTK_MENU_SHELL (menu)->children;
309                while (items && (i < KEYMAP_LAST)) {
310                        gtk_object_set_data (GTK_OBJECT (items->data), "GtkHTMLPropKeymap", keymap_names[i]);
311                        items = items->next;
312                        i++;
313                }
314               
315                gtk_signal_connect (GTK_OBJECT (menu), "selection-done", propmanager_keymap_changed, pman);     
316               
317                *found = TRUE;
318        }
319
320        return option;
321}
322
323void
324gtk_html_propmanager_set_names (GtkHTMLPropmanager *pman, char *names[][2])
325{
326        GHashTable *ht;
327        int i;
328
329        g_return_if_fail (pman != NULL);
330        g_return_if_fail (names != NULL);
331
332        ht = g_hash_table_new (g_str_hash, g_str_equal);
333
334        i = 0;
335        while (names[i][0] != NULL) {
336                g_hash_table_insert (ht, names[i][0], names[i][1]);
337                i++;
338        }
339
340        gtk_html_propmanager_set_nametable (pman, ht);
341}
342
343void
344gtk_html_propmanager_set_nametable (GtkHTMLPropmanager *pman, GHashTable *ht)
345{
346        if (pman->priv->nametable)
347                g_hash_table_destroy (pman->priv->nametable);
348
349        pman->priv->nametable = ht;
350}
351
352gboolean
353gtk_html_propmanager_set_gui (GtkHTMLPropmanager *pman, GladeXML *xml, GHashTable *nametable)
354{
355        GtkHTMLPropmanagerPrivate *priv;
356        GError      *gconf_error  = NULL;
357        gboolean found_widget = FALSE;
358
359        g_return_val_if_fail (pman != NULL, FALSE);
360        g_return_val_if_fail (GTK_IS_HTML_PROPMANAGER (pman), FALSE);
361
362        if (nametable)
363                gtk_html_propmanager_set_nametable (pman, nametable);
364
365        priv = pman->priv;
366       
367        gtk_object_ref (GTK_OBJECT (xml));
368        priv->xml = xml;
369
370        gconf_client_add_dir (priv->client, GTK_HTML_GCONF_DIR, GCONF_CLIENT_PRELOAD_NONE, NULL);
371
372        priv->orig_prop = gtk_html_class_properties_new ();
373        priv->saved_prop = gtk_html_class_properties_new ();
374        priv->actual_prop = gtk_html_class_properties_new ();
375
376        gtk_html_class_properties_load (priv->actual_prop, priv->client);
377        gtk_html_class_properties_copy (priv->saved_prop, priv->actual_prop);
378        gtk_html_class_properties_copy (priv->orig_prop, priv->actual_prop);
379
380        /* Toggle Buttons */
381        priv->anim_check = propmanager_add_toggle (pman, "anim_check", &found_widget);
382        priv->magic_links_check = propmanager_add_toggle (pman, "magic_links_check", &found_widget);
383        priv->magic_smileys_check = propmanager_add_toggle (pman, "magic_smileys_check", &found_widget);
384        priv->live_spell_check = propmanager_add_toggle (pman, "live_spell_check", &found_widget);
385
386        if ((priv->live_spell_options = propmanager_get_widget (pman, "button_configure_spell_checking"))) {
387                found_widget = TRUE;
388        }
389
390        /* KEYMAP */
391        priv->keymap = propmanager_add_keymap (pman, "gtk_html_prop_keymap_option", &found_widget);
392
393        /* Font Pickers */
394        priv->variable = propmanager_add_picker (pman, "screen_variable", TRUE, &found_widget);
395        priv->variable_print = propmanager_add_picker (pman, "print_variable", TRUE, &found_widget);
396        priv->fixed = propmanager_add_picker (pman, "screen_fixed", FALSE, &found_widget);
397        priv->fixed_print = propmanager_add_picker (pman, "print_fixed", FALSE, &found_widget);
398
399        priv->notify_id = gconf_client_notify_add (priv->client, GTK_HTML_GCONF_DIR,
400                                                   propmanager_client_notify,
401                                                   pman, NULL, &gconf_error);
402        if (gconf_error)
403                g_warning ("gconf error: %s\n", gconf_error->message);
404               
405
406        /* only hold a ref while we retrieve the widgets */
407        gtk_object_unref (GTK_OBJECT (priv->xml));
408        priv->xml = NULL;
409
410        gtk_html_propmanager_sync_gui (pman);
411        return found_widget;
412}
413
414static gchar *
415get_attr (gchar *font_name, gint n)
416{
417    gchar *s, *end;
418
419    /* Search paramether */
420    for (s=font_name; n; n--,s++)
421            s = strchr (s,'-');
422
423    if (s && *s != 0) {
424            end = strchr (s, '-');
425            if (end)
426                    return g_strndup (s, end - s);
427            else
428                    return g_strdup (s);
429    } else
430            return g_strdup ("Unknown");
431}
432
433void
434gtk_html_propmanager_apply (GtkHTMLPropmanager *pman)
435{
436        GtkHTMLPropmanagerPrivate *priv;
437        gchar *size_str;
438
439        g_return_if_fail (pman != NULL);
440
441        priv = pman->priv;
442       
443        if (priv->anim_check)
444                priv->actual_prop->animations = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->anim_check));
445
446        if (priv->magic_links_check)
447                priv->actual_prop->magic_links = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->magic_links_check));
448
449        if (priv->magic_smileys_check)
450                priv->actual_prop->magic_smileys = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->magic_smileys_check));
451
452        if (priv->live_spell_check)
453                priv->actual_prop->live_spell_check = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->live_spell_check));
454
455        if (priv->keymap) {
456                g_free (priv->actual_prop->keybindings_theme);
457                priv->actual_prop->keybindings_theme = g_strdup (keymap_option_get (priv->keymap));
458        }
459
460#define APPLY(f,s,w) \
461        if (w) { \
462                g_free (priv->actual_prop-> f); \
463                priv->actual_prop-> f = g_strdup (gnome_font_picker_get_font_name (GNOME_FONT_PICKER (w))); \
464                size_str = get_attr (gnome_font_picker_get_font_name (GNOME_FONT_PICKER (w)), 7); \
465                if (!strcmp (size_str, "*")) { \
466                          g_free (size_str); \
467                          size_str = get_attr (gnome_font_picker_get_font_name (GNOME_FONT_PICKER (w)), 8); \
468                          priv->actual_prop-> f ## _points = TRUE; \
469                } else { \
470                          priv->actual_prop-> f ## _points = FALSE; \
471                } \
472                priv->actual_prop-> s = atoi (size_str); \
473                g_free (size_str); \
474        }
475
476        APPLY (font_var,       font_var_size,       priv->variable);
477        APPLY (font_fix,       font_fix_size,       priv->fixed);
478        APPLY (font_var_print, font_var_size_print, priv->variable_print);
479        APPLY (font_fix_print, font_fix_size_print, priv->fixed_print);
480
481        priv->active = TRUE;
482        gtk_html_class_properties_update (priv->actual_prop, priv->client,
483                                          priv->saved_prop);
484        priv->active = FALSE;
485        gtk_html_class_properties_copy (priv->saved_prop, priv->actual_prop);
486}
487
488void
489gtk_html_propmanager_reset (GtkHTMLPropmanager *pman)
490{
491        GtkHTMLPropmanagerPrivate *priv;
492
493        g_return_if_fail (GTK_IS_HTML_PROPMANAGER (pman));
494        priv = pman->priv;
495       
496        gtk_html_class_properties_copy (priv->actual_prop, priv->orig_prop);
497        gtk_html_class_properties_update (priv->actual_prop, priv->client,
498                                          priv->saved_prop);
499        gtk_html_class_properties_copy (priv->saved_prop, priv->orig_prop);
500        gtk_html_propmanager_sync_gui (pman);
501}
502
503static void
504gtk_html_propmanager_real_changed (GtkHTMLPropmanager *pman)
505{
506        GtkHTMLPropmanagerPrivate *priv = pman->priv;
507
508        if (priv->live_spell_options) {
509                gboolean sensitive;
510
511                d (g_warning ("spell sensitivity changed = %d", priv->actual_prop->live_spell_check));
512
513                sensitive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->live_spell_check));
514                gtk_widget_set_sensitive (GTK_WIDGET (priv->live_spell_options), sensitive);
515        }
516}
517
518static void
519gtk_html_propmanager_init (GtkHTMLPropmanager *pman)
520{
521        GtkHTMLPropmanagerPrivate *priv;
522
523        priv = g_new0 (GtkHTMLPropmanagerPrivate, 1);
524       
525        pman->priv = priv;
526
527        gtk_object_ref (GTK_OBJECT (pman));
528        gtk_object_sink (GTK_OBJECT (pman));
529}
530
531GtkObject *
532gtk_html_propmanager_new (GConfClient *client)
533{
534        GtkHTMLPropmanager *pman;
535       
536        pman = GTK_HTML_PROPMANAGER (gtk_type_new (GTK_TYPE_HTML_PROPMANAGER));
537       
538        if (client) {
539                pman->priv->client = client;
540                gtk_object_ref (GTK_OBJECT (client));
541        } else {
542                pman->priv->client = gconf_client_get_default ();
543        }
544
545        return (GtkObject *)pman;
546}
547
548static void
549gtk_html_propmanager_finalize (GtkObject *object)
550{
551        GtkHTMLPropmanagerPrivate *priv = GTK_HTML_PROPMANAGER (object)->priv;
552
553        if (priv->notify_id)
554                gconf_client_notify_remove (GTK_HTML_PROPMANAGER (object)->priv->client, priv->notify_id);
555
556        if (priv->orig_prop) {
557                gtk_html_class_properties_destroy (priv->orig_prop);
558                gtk_html_class_properties_destroy (priv->actual_prop);
559                gtk_html_class_properties_destroy (priv->saved_prop);
560        }
561
562        gtk_object_unref (GTK_OBJECT (priv->client));
563
564        g_free (priv);
565
566        if (GTK_OBJECT_CLASS (parent_class)->finalize)
567                (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);         
568}
569
570static void
571gtk_html_propmanager_class_init (GtkHTMLPropmanagerClass *klass)
572{
573        GtkObjectClass *object_class;
574        object_class = (GtkObjectClass *)klass;
575
576        parent_class = gtk_type_class (gtk_object_get_type ());
577
578        signals [CHANGED] =
579                gtk_signal_new ("changed",
580                                GTK_RUN_FIRST,
581                                object_class->type,
582                                GTK_SIGNAL_OFFSET (GtkHTMLPropmanagerClass, changed),
583                                gtk_marshal_NONE__NONE,
584                                GTK_TYPE_NONE, 0);
585
586        gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
587       
588        object_class->finalize = gtk_html_propmanager_finalize;
589        klass->changed = gtk_html_propmanager_real_changed;
590}
591
592       
593GtkType
594gtk_html_propmanager_get_type (void)
595{
596        static GtkType propmanager_type = 0;
597
598        if (!propmanager_type) {
599                GtkTypeInfo propmanager_type_info = {
600                        "GtkHTMLPropmanager",
601                        sizeof (GtkHTMLPropmanager),
602                        sizeof (GtkHTMLPropmanagerClass),
603                        (GtkClassInitFunc) gtk_html_propmanager_class_init,
604                        (GtkObjectInitFunc) gtk_html_propmanager_init,
605                        NULL,
606                        NULL
607                };
608               
609                propmanager_type = gtk_type_unique (gtk_object_get_type (), &propmanager_type_info);
610        }
611
612        return propmanager_type;
613}
Note: See TracBrowser for help on using the repository browser.