]> git.sur5r.net Git - glabels/blob - glabels2/src/ui-property-bar.c
2005-01-22 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / ui-property-bar.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  property-bar.c:  gLabels property bar
5  *
6  *  Copyright (C) 2003  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <config.h>
24
25 #include <libgnomeprint/gnome-font.h>
26
27 #include "ui-property-bar.h"
28 #include "ui-util.h"
29 #include "mygal/widget-color-combo.h"
30 #include "stock-pixmaps/stockpixbufs.h"
31 #include "prefs.h"
32 #include "color.h"
33
34 #include "debug.h"
35
36 /*============================================================================*/
37 /* Private macros and constants.                                              */
38 /*============================================================================*/
39
40 /*============================================================================*/
41 /* Private globals                                                            */
42 /*============================================================================*/
43
44 static GObjectClass *parent_class;
45
46 static gchar* doc_verbs [] = {
47         "/commands/PropFontName",
48         "/commands/PropFontSize",
49         "/commands/PropFontBold",
50         "/commands/PropFontItalic",
51         "/commands/PropTextAlignLeft",
52         "/commands/PropTextAlignCenter",
53         "/commands/PropTextAlignRight",
54         "/commands/PropFillColor",
55         "/commands/PropLineColor",
56         "/commands/PropTextColor",
57         "/commands/PropLineWidth",
58
59         NULL
60 };
61
62 static gchar* text_verbs [] = {
63         "/commands/PropFontName",
64         "/commands/PropFontSize",
65         "/commands/PropFontBold",
66         "/commands/PropFontItalic",
67         "/commands/PropTextAlignLeft",
68         "/commands/PropTextAlignCenter",
69         "/commands/PropTextAlignRight",
70         "/commands/PropTextColor",
71
72         NULL
73 };
74
75 static gchar* fill_verbs [] = {
76         "/commands/PropFillColor",
77
78         NULL
79 };
80
81 static gchar* line_color_verbs [] = {
82         "/commands/PropLineColor",
83
84         NULL
85 };
86
87 static gchar* line_width_verbs [] = {
88         "/commands/PropLineWidth",
89
90         NULL
91 };
92
93
94 /*============================================================================*/
95 /* Local function prototypes                                                  */
96 /*============================================================================*/
97
98 static void     gl_ui_property_bar_class_init    (glUIPropertyBarClass *class);
99 static void     gl_ui_property_bar_instance_init (glUIPropertyBar      *property_bar);
100 static void     gl_ui_property_bar_finalize      (GObject              *object);
101
102 static void     gl_ui_property_bar_construct     (glUIPropertyBar      *property_bar,
103                                                   BonoboUIComponent    *ui_component);
104
105 static void     selection_changed_cb             (glUIPropertyBar      *property_bar);
106
107 static void     font_family_changed_cb           (GtkEntry             *entry,
108                                                   glUIPropertyBar      *property_bar);
109
110 static void     font_size_changed_cb             (GtkSpinButton        *spin,
111                                                   glUIPropertyBar      *property_bar);
112
113 static void     text_color_changed_cb            (ColorCombo           *cc,
114                                                   GdkColor             *gdk_color,
115                                                   gboolean              custom,
116                                                   gboolean              by_user,
117                                                   gboolean              is_default,
118                                                   glUIPropertyBar      *property_bar);
119
120 static void     fill_color_changed_cb            (ColorCombo           *cc,
121                                                   GdkColor             *gdk_color,
122                                                   gboolean              custom,
123                                                   gboolean              by_user,
124                                                   gboolean              is_default,
125                                                   glUIPropertyBar      *property_bar);
126
127 static void     line_color_changed_cb            (ColorCombo           *cc,
128                                                   GdkColor             *gdk_color,
129                                                   gboolean              custom,
130                                                   gboolean              by_user,
131                                                   gboolean              is_default,
132                                                   glUIPropertyBar      *property_bar);
133
134 static void     line_width_changed_cb            (GtkSpinButton        *spin,
135                                                   glUIPropertyBar      *property_bar);
136
137 static void prop_item_toggled_cb (BonoboUIComponent           *ui_component,
138                                   const char                  *path,
139                                   Bonobo_UIComponent_EventType type,
140                                   const char                  *state,
141                                   glUIPropertyBar             *property_bar);
142
143 static void null_cmd             (BonoboUIComponent           *ui_component,
144                                   gpointer                     user_data,
145                                   const gchar                 *verbname);
146
147
148
149 \f
150 /****************************************************************************/
151 /* Boilerplate Object stuff.                                                */
152 /****************************************************************************/
153 GType
154 gl_ui_property_bar_get_type (void)
155 {
156         static GType type = 0;
157
158         if (!type) {
159                 static const GTypeInfo info = {
160                         sizeof (glUIPropertyBarClass),
161                         NULL,
162                         NULL,
163                         (GClassInitFunc) gl_ui_property_bar_class_init,
164                         NULL,
165                         NULL,
166                         sizeof (glUIPropertyBar),
167                         0,
168                         (GInstanceInitFunc) gl_ui_property_bar_instance_init,
169                         NULL
170                 };
171
172                 type = g_type_register_static (G_TYPE_OBJECT,
173                                                "glUIPropertyBar", &info, 0);
174         }
175
176         return type;
177 }
178
179 static void
180 gl_ui_property_bar_class_init (glUIPropertyBarClass *class)
181 {
182         GObjectClass   *object_class     = (GObjectClass *) class;
183
184         gl_debug (DEBUG_PROPERTY_BAR, "START");
185
186         parent_class = g_type_class_peek_parent (class);
187
188         object_class->finalize = gl_ui_property_bar_finalize;
189
190         gl_debug (DEBUG_PROPERTY_BAR, "END");
191 }
192
193 static void
194 gl_ui_property_bar_instance_init (glUIPropertyBar *property_bar)
195 {
196         gl_debug (DEBUG_PROPERTY_BAR, "START");
197
198         property_bar->view = NULL;
199
200         gl_debug (DEBUG_PROPERTY_BAR, "END");
201 }
202
203 static void
204 gl_ui_property_bar_finalize (GObject *object)
205 {
206         glUIPropertyBar *property_bar;
207
208         gl_debug (DEBUG_PROPERTY_BAR, "START");
209
210         g_return_if_fail (object != NULL);
211         g_return_if_fail (GL_IS_UI_PROPERTY_BAR (object));
212
213         property_bar = GL_UI_PROPERTY_BAR (object);
214
215         if (property_bar->view) {
216                 g_object_unref (G_OBJECT(property_bar->view));
217                 property_bar = NULL;
218         }
219
220         G_OBJECT_CLASS (parent_class)->finalize (object);
221
222         gl_debug (DEBUG_PROPERTY_BAR, "END");
223 }
224
225 /****************************************************************************/
226 /* Create a NEW property_bar.                                               */
227 /****************************************************************************/
228 GObject *
229 gl_ui_property_bar_new (BonoboUIComponent *ui_component)
230 {
231         glUIPropertyBar *property_bar;
232
233         gl_debug (DEBUG_PROPERTY_BAR, "START");
234
235         property_bar = g_object_new (gl_ui_property_bar_get_type (), NULL);
236
237         gl_ui_property_bar_construct (property_bar, ui_component);
238
239         gl_debug (DEBUG_PROPERTY_BAR, "END");
240
241         return G_OBJECT(property_bar);
242 }
243
244 /******************************************************************************/
245 /* Initialize property toolbar.                                               */
246 /******************************************************************************/
247 static void
248 gl_ui_property_bar_construct (glUIPropertyBar   *property_bar,
249                               BonoboUIComponent *ui_component)
250 {
251         GtkWidget  *wcombo;
252         GList      *family_names = NULL;
253         GtkObject  *adjust;
254         ColorGroup *cg;
255         GdkPixbuf  *pixbuf;
256         gchar      *good_font_family;
257         GdkColor   *gdk_color;
258
259         gl_debug (DEBUG_PROPERTY_BAR, "START");
260
261         property_bar->stop_signals = TRUE;
262         property_bar->ui_component = ui_component;
263
264         /* Font family entry widget */
265         wcombo = gtk_combo_new ();
266         family_names = gnome_font_family_list ();
267         gtk_combo_set_popdown_strings (GTK_COMBO (wcombo), family_names);
268         property_bar->font_family_entry = GTK_COMBO (wcombo)->entry;
269         gtk_combo_set_value_in_list (GTK_COMBO(wcombo), TRUE, TRUE);
270         gtk_entry_set_editable (GTK_ENTRY (property_bar->font_family_entry), FALSE);
271         gtk_widget_set_size_request (wcombo, 200, -1);
272
273         /* Make sure we have a valid font family.  if not provide a good default. */
274         if (g_list_find_custom (family_names,
275                                 gl_prefs->default_font_family,
276                                 (GCompareFunc)g_utf8_collate)) {
277                 good_font_family = g_strdup (gl_prefs->default_font_family);
278         } else {
279                 if (family_names != NULL) {
280                         good_font_family = g_strdup (family_names->data); /* 1st entry */
281                 } else {
282                         good_font_family = NULL;
283                 }
284         }
285         gtk_entry_set_text (GTK_ENTRY (property_bar->font_family_entry), good_font_family);
286         g_free (good_font_family);
287         gnome_font_family_list_free (family_names);
288
289         g_signal_connect (G_OBJECT (property_bar->font_family_entry),
290                           "changed", G_CALLBACK (font_family_changed_cb), property_bar);
291
292         gl_ui_util_insert_widget (ui_component, wcombo, "/PropertyToolbar/PropFontName");
293
294         /* Font size entry widget */
295         adjust = gtk_adjustment_new (1.0, 1.0, 250.0, 1.0, 10.0, 10.0);
296         property_bar->font_size_spin =  gtk_spin_button_new (GTK_ADJUSTMENT (adjust),
297                                                              1.0, 0);
298         gtk_spin_button_set_value (GTK_SPIN_BUTTON(property_bar->font_size_spin),
299                                    gl_prefs->default_font_size);
300
301         g_signal_connect (G_OBJECT (property_bar->font_size_spin),
302                           "changed", G_CALLBACK (font_size_changed_cb), property_bar);
303
304         gl_ui_util_insert_widget (ui_component, property_bar->font_size_spin,
305                                   "/PropertyToolbar/PropFontSize");
306
307         /* Bold and Italic toggles */
308         bonobo_ui_component_add_verb (ui_component, "PropFontBold", null_cmd, NULL);
309         gl_ui_util_set_verb_state (ui_component, "/commands/PropFontBold",
310                                    (gl_prefs->default_font_weight == GNOME_FONT_BOLD));
311         bonobo_ui_component_add_listener (ui_component, "PropFontBold", 
312                         (BonoboUIListenerFn)prop_item_toggled_cb, 
313                         (gpointer)property_bar);
314         bonobo_ui_component_add_verb (ui_component, "PropFontItalic", null_cmd, NULL);
315         gl_ui_util_set_verb_state (ui_component, "/commands/PropFontItalic",
316                                    gl_prefs->default_font_italic_flag);
317         bonobo_ui_component_add_listener (ui_component, "PropFontItalic", 
318                         (BonoboUIListenerFn)prop_item_toggled_cb, 
319                         (gpointer)property_bar);
320
321         /* Text alignment radio group */
322         bonobo_ui_component_add_verb (ui_component, "PropTextAlignLeft", null_cmd, NULL);
323         gl_ui_util_set_verb_state (ui_component, "/commands/PropTextAlignLeft",
324                                    (gl_prefs->default_text_alignment == GTK_JUSTIFY_LEFT));
325         bonobo_ui_component_add_listener (ui_component, "PropTextAlignLeft", 
326                         (BonoboUIListenerFn)prop_item_toggled_cb, 
327                         (gpointer)property_bar);
328         bonobo_ui_component_add_verb (ui_component, "PropTextAlignCenter", null_cmd, NULL);
329         gl_ui_util_set_verb_state (ui_component, "/commands/PropTextAlignCenter",
330                                    (gl_prefs->default_text_alignment == GTK_JUSTIFY_CENTER));
331         bonobo_ui_component_add_listener (ui_component, "PropTextAlignCenter", 
332                         (BonoboUIListenerFn)prop_item_toggled_cb, 
333                         (gpointer)property_bar);
334         bonobo_ui_component_add_verb (ui_component, "PropTextAlignRight", null_cmd, NULL);
335         gl_ui_util_set_verb_state (ui_component, "/commands/PropTextAlignRight",
336                                    (gl_prefs->default_text_alignment == GTK_JUSTIFY_RIGHT));
337         bonobo_ui_component_add_listener (ui_component, "PropTextAlignRight", 
338                         (BonoboUIListenerFn)prop_item_toggled_cb, 
339                         (gpointer)property_bar);
340
341         /* Text color widget */
342         cg = color_group_fetch ("text_color_group", NULL);
343         pixbuf = gdk_pixbuf_new_from_inline (-1, stock_text_24, FALSE, NULL);
344         gdk_color = gl_color_to_gdk_color (gl_prefs->default_text_color);
345         property_bar->text_color_combo = color_combo_new (pixbuf, _("Default"),
346                                                           gdk_color, cg);
347         g_free (gdk_color);
348
349         g_signal_connect (G_OBJECT (property_bar->text_color_combo),
350                           "color_changed",
351                           G_CALLBACK (text_color_changed_cb), property_bar);
352
353         gl_ui_util_insert_widget (ui_component, property_bar->text_color_combo,
354                                   "/PropertyToolbar/PropTextColor");
355
356         /* Fill color widget */
357         cg = color_group_fetch ("fill_color_group", NULL);
358         pixbuf = gdk_pixbuf_new_from_inline (-1, stock_bucket_fill_24, FALSE, NULL);
359         gdk_color = gl_color_to_gdk_color (gl_prefs->default_fill_color);
360         property_bar->fill_color_combo = color_combo_new (pixbuf, _("No fill"),
361                                                           gdk_color, cg);
362         g_free (gdk_color);
363
364         g_signal_connect (G_OBJECT (property_bar->fill_color_combo),
365                           "color_changed",
366                           G_CALLBACK (fill_color_changed_cb), property_bar);
367
368         gl_ui_util_insert_widget (ui_component, property_bar->fill_color_combo,
369                                   "/PropertyToolbar/PropFillColor");
370
371         /* Line color widget */
372         cg = color_group_fetch ("line_color_group", NULL);
373         pixbuf = gdk_pixbuf_new_from_inline (-1, stock_pencil_24, FALSE, NULL);
374         gdk_color = gl_color_to_gdk_color (gl_prefs->default_line_color);
375         property_bar->line_color_combo = color_combo_new (pixbuf, _("No line"),
376                                                           gdk_color, cg);
377         g_free (gdk_color);
378
379         g_signal_connect (G_OBJECT (property_bar->line_color_combo),
380                           "color_changed",
381                           G_CALLBACK (line_color_changed_cb), property_bar);
382
383         gl_ui_util_insert_widget (ui_component, property_bar->line_color_combo,
384                                   "/PropertyToolbar/PropLineColor");
385
386         /* Line width entry widget */
387         adjust = gtk_adjustment_new (1.0, 0.25, 4.0, 0.25, 1.0, 1.0);
388         property_bar->line_width_spin =  gtk_spin_button_new (GTK_ADJUSTMENT (adjust), 0.25, 2);
389
390         g_signal_connect (G_OBJECT (property_bar->line_width_spin),
391                           "changed",
392                           G_CALLBACK (line_width_changed_cb), property_bar);
393
394         gl_ui_util_insert_widget (ui_component, property_bar->line_width_spin,
395                                   "/PropertyToolbar/PropLineWidth");
396
397         gl_ui_util_set_verb_list_sensitive (ui_component, doc_verbs, FALSE);
398
399         property_bar->stop_signals = FALSE;
400
401         gl_debug (DEBUG_PROPERTY_BAR, "END");
402 }
403
404 /****************************************************************************/
405 /* Fill widgets with default values.                                        */
406 /****************************************************************************/
407 static void
408 reset_to_default_properties (glView *view,
409                         glUIPropertyBar *property_bar)
410 {
411         GList     *family_names;
412         gchar     *good_font_family;
413         GdkColor  *gdk_color;
414
415         /* Make sure we have a valid font family.  if not provide a good default. */
416         family_names = gnome_font_family_list ();
417         if (g_list_find_custom (family_names,
418                                 view->default_font_family,
419                                 (GCompareFunc)g_utf8_collate)) {
420                 good_font_family = g_strdup (view->default_font_family);
421         } else {
422                 if (family_names != NULL) {
423                         good_font_family = g_strdup (family_names->data); /* 1st entry */
424                 } else {
425                         good_font_family = NULL;
426                 }
427         }
428         gtk_entry_set_text (GTK_ENTRY (property_bar->font_family_entry), good_font_family);
429         g_free (good_font_family);
430
431         gtk_spin_button_set_value (GTK_SPIN_BUTTON(property_bar->font_size_spin),
432                                    view->default_font_size);
433
434         gl_ui_util_set_verb_state (property_bar->ui_component,
435                                    "/commands/PropFontBold",
436                                    (view->default_font_weight == GNOME_FONT_BOLD));
437         gl_ui_util_set_verb_state (property_bar->ui_component,
438                                    "/commands/PropFontItalic",
439                                    view->default_font_italic_flag);
440
441         gl_ui_util_set_verb_state (property_bar->ui_component,
442                                    "/commands/PropTextAlignLeft",
443                                    (view->default_text_alignment == GTK_JUSTIFY_LEFT));
444         gl_ui_util_set_verb_state (property_bar->ui_component,
445                                    "/commands/PropTextAlignCenter",
446                                    (view->default_text_alignment == GTK_JUSTIFY_CENTER));
447         gl_ui_util_set_verb_state (property_bar->ui_component,
448                                    "/commands/PropTextAlignRight",
449                                    (view->default_text_alignment == GTK_JUSTIFY_RIGHT));
450
451         gdk_color = gl_color_to_gdk_color (view->default_text_color);
452         color_combo_set_color (COLOR_COMBO(property_bar->text_color_combo), gdk_color);
453         g_free (gdk_color);
454
455         gdk_color = gl_color_to_gdk_color (view->default_fill_color);
456         color_combo_set_color (COLOR_COMBO(property_bar->fill_color_combo), gdk_color);
457         g_free (gdk_color);
458
459         gdk_color = gl_color_to_gdk_color (view->default_line_color);
460         color_combo_set_color (COLOR_COMBO(property_bar->line_color_combo), gdk_color);
461         g_free (gdk_color);
462
463         gtk_spin_button_set_value (GTK_SPIN_BUTTON(property_bar->line_width_spin),
464                                    view->default_line_width);
465 }
466
467 /****************************************************************************/
468 /* Set view associated with property_bar.                                   */
469 /****************************************************************************/
470 void
471 gl_ui_property_bar_set_view (glUIPropertyBar *property_bar,
472                              glView          *view)
473 {
474         glLabel   *label;
475
476         gl_debug (DEBUG_PROPERTY_BAR, "START");
477
478         g_return_if_fail (view && GL_IS_VIEW (view));
479         label = view->label;
480         g_return_if_fail (label && GL_IS_LABEL (label));
481
482         gl_ui_util_set_verb_list_sensitive (property_bar->ui_component, doc_verbs, TRUE);
483
484         property_bar->view = GL_VIEW (g_object_ref (G_OBJECT (view)));
485
486         reset_to_default_properties (view, property_bar);
487
488         g_signal_connect_swapped (G_OBJECT(view), "selection_changed",
489                                   G_CALLBACK(selection_changed_cb), property_bar);
490
491         g_signal_connect_swapped (G_OBJECT(view->label), "changed",
492                                   G_CALLBACK(selection_changed_cb), property_bar);
493
494         gl_debug (DEBUG_PROPERTY_BAR, "END");
495 }
496
497 /*---------------------------------------------------------------------------*/
498 /* PRIVATE.  View "selection state changed" callback.                        */
499 /*---------------------------------------------------------------------------*/
500
501 static void
502 update_text_properties (glView *view,
503                         glUIPropertyBar *property_bar)
504 {
505         gboolean can_text, is_first_object;
506         gboolean is_same_font_family, is_same_font_size;
507         gboolean is_same_text_color, is_same_is_italic;
508         gboolean is_same_is_bold, is_same_justification;
509         GList *p;
510         glLabelObject *object;
511         gchar *selection_font_family, *font_family;
512         gdouble selection_font_size, font_size;
513         guint selection_text_color, text_color;
514         glColorNode *text_color_node;
515         gboolean selection_is_italic, is_italic;
516         gboolean selection_is_bold, is_bold;
517         GtkJustification selection_justification, justification;
518         GdkColor *gdk_color;
519
520         can_text = gl_view_can_selection_text (view);
521         gl_ui_util_set_verb_list_sensitive (property_bar->ui_component,
522                                             text_verbs,
523                                             can_text);
524         if (!can_text) 
525                 return;
526
527         is_same_is_italic =
528         is_same_is_bold =
529         is_same_justification =
530         is_same_text_color =
531         is_same_font_size =
532         is_same_font_family = TRUE;
533         selection_font_family = NULL;
534         selection_font_size = -1;
535         is_first_object = TRUE;
536         
537         for (p = view->selected_object_list; p != NULL; p = p->next) {
538
539                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
540                 if (!gl_label_object_can_text (object)) 
541                         continue;
542
543                 font_family = gl_label_object_get_font_family (object);
544                 if (font_family != NULL) {
545                         if (selection_font_family == NULL)
546                                 selection_font_family = g_strdup (font_family);
547                         else 
548                                 if (strcmp (font_family, selection_font_family) != 0) 
549                                         is_same_font_family = FALSE;
550                         g_free (font_family);
551                 }       
552
553                 font_size = gl_label_object_get_font_size (object);
554                 
555                 text_color_node = gl_label_object_get_text_color (object);
556                 if (text_color_node->field_flag) {
557                         /* If a merge field is set we use the default color for merged color*/
558                         text_color = GL_COLOR_MERGE_DEFAULT;
559                         
560                 } else {
561                         text_color = text_color_node->color;
562                 }
563                 gl_color_node_free (&text_color_node);
564                 
565                 is_italic = gl_label_object_get_font_italic_flag (object);
566                 is_bold = gl_label_object_get_font_weight (object) == GNOME_FONT_BOLD;
567                 justification = gl_label_object_get_text_alignment (object);
568
569                 if (is_first_object) {
570                         selection_font_size = font_size;
571                         selection_text_color = text_color;
572                         selection_is_italic = is_italic;
573                         selection_is_bold = is_bold;
574                         selection_justification = justification;
575                 } else {
576                         if (font_size != selection_font_size) 
577                                 is_same_font_size = FALSE;
578                         if (text_color != selection_text_color)
579                                 is_same_text_color = FALSE;
580                         if (is_italic != selection_is_italic)
581                                 is_same_is_italic = FALSE;
582                         if (is_bold != selection_is_bold)
583                                 is_same_is_bold = FALSE;
584                         if (justification != selection_justification)
585                                 is_same_justification = FALSE;
586                 }
587                 is_first_object = FALSE;
588         }
589
590         if (is_same_font_family && (selection_font_family != NULL)) 
591                 gl_debug (DEBUG_PROPERTY_BAR, "same font family = %s", 
592                           selection_font_family);
593         gtk_entry_set_text (GTK_ENTRY (property_bar->font_family_entry),
594                             is_same_font_family?selection_font_family:"");
595         g_free (selection_font_family);
596
597         if (is_same_font_size) {
598                 gl_debug (DEBUG_PROPERTY_BAR, "same font size = %g", 
599                           selection_font_size);
600                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (property_bar->font_size_spin),
601                                            selection_font_size);
602         } else {
603                 gtk_entry_set_text (GTK_ENTRY (property_bar->font_size_spin), "");
604         }
605
606         if (is_same_text_color) {
607                 gl_debug (DEBUG_PROPERTY_BAR, "same text color = %08x", selection_text_color);
608                 gdk_color = gl_color_to_gdk_color (selection_text_color);
609                 color_combo_set_color (COLOR_COMBO (property_bar->text_color_combo),
610                                        gdk_color);
611                 g_free (gdk_color);
612         }
613
614         if (is_same_is_italic)  
615                 gl_debug (DEBUG_PROPERTY_BAR, "same italic flag = %d", 
616                           selection_is_italic);
617         gl_ui_util_set_verb_state (property_bar->ui_component,
618                                    "/commands/PropFontItalic",
619                                    selection_is_italic && is_same_is_italic);
620
621         if (is_same_is_bold)  
622                 gl_debug (DEBUG_PROPERTY_BAR, "same bold flag = %d",
623                           selection_is_bold);
624         gl_ui_util_set_verb_state (property_bar->ui_component,
625                                    "/commands/PropFontBold",
626                                    selection_is_bold && is_same_is_bold);
627
628         if (is_same_justification) 
629                 gl_debug (DEBUG_PROPERTY_BAR, "same justification");
630         gl_ui_util_set_verb_state (property_bar->ui_component,
631                                    "/commands/PropTextAlignRight",
632                                    (selection_justification == GTK_JUSTIFY_RIGHT) &&
633                                    is_same_justification);
634         gl_ui_util_set_verb_state (property_bar->ui_component,
635                                    "/commands/PropTextAlignLeft",
636                                    (selection_justification == GTK_JUSTIFY_LEFT) &&
637                                    is_same_justification);
638         gl_ui_util_set_verb_state (property_bar->ui_component,
639                                    "/commands/PropTextAlignCenter",
640                                    (selection_justification == GTK_JUSTIFY_CENTER) &&
641                                    is_same_justification);
642 }
643
644 static void
645 update_fill_color (glView *view,
646                    glUIPropertyBar *property_bar)
647 {
648         gboolean can, is_first_object;
649         gboolean is_same_fill_color;
650         GList *p;
651         glLabelObject *object;
652         guint selection_fill_color, fill_color;
653         GdkColor *gdk_color;
654         glColorNode *fill_color_node;
655
656         can = gl_view_can_selection_fill (view);
657         gl_ui_util_set_verb_list_sensitive (property_bar->ui_component,
658                                             fill_verbs,
659                                             can);
660         if (!can) 
661                 return;
662
663         is_same_fill_color = TRUE;
664         is_first_object = TRUE;
665         
666         for (p = view->selected_object_list; p != NULL; p = p->next) {
667
668                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
669                 if (!gl_label_object_can_fill (object)) 
670                         continue;
671
672                 fill_color_node = gl_label_object_get_fill_color (object);
673                 if (fill_color_node->field_flag) {
674                         /* If a merge field is set we use the default color for merged color*/
675                         fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
676                         
677                 } else {
678                         fill_color = fill_color_node->color;
679                 }
680                 gl_color_node_free (&fill_color_node);
681
682                 if (is_first_object) {
683                         selection_fill_color = fill_color;
684                 } else {
685                         if (fill_color != selection_fill_color)
686                                 is_same_fill_color = FALSE;
687                 }
688                 is_first_object = FALSE;
689         }
690
691         if (is_same_fill_color) {
692                 gl_debug (DEBUG_PROPERTY_BAR, "same fill color = %08x", selection_fill_color);
693                 gdk_color = gl_color_to_gdk_color (selection_fill_color);
694                 color_combo_set_color (COLOR_COMBO (property_bar->fill_color_combo),
695                                        gdk_color);
696                 g_free (gdk_color);
697         }
698 }
699
700 static void
701 update_line_color (glView *view,
702                    glUIPropertyBar *property_bar)
703 {
704         gboolean can, is_first_object;
705         gboolean is_same_line_color;
706         GList *p;
707         glLabelObject *object;
708         guint selection_line_color, line_color;
709         glColorNode *line_color_node;
710         GdkColor *gdk_color;
711
712         can = gl_view_can_selection_line_color (view);
713         gl_ui_util_set_verb_list_sensitive (property_bar->ui_component,
714                                             line_color_verbs,
715                                             can);
716         if (!can) 
717                 return;
718
719         is_same_line_color = TRUE;
720         is_first_object = TRUE;
721         
722         for (p = view->selected_object_list; p != NULL; p = p->next) {
723
724                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
725                 if (!gl_label_object_can_line_color (object)) 
726                         continue;
727
728                 line_color_node = gl_label_object_get_line_color (object);
729                 if (line_color_node->field_flag) {
730                         /* If a merge field is set we use the default color for merged color*/
731                         line_color = GL_COLOR_MERGE_DEFAULT;
732                         
733                 } else {
734                         line_color = line_color_node->color;
735                 }
736                 gl_color_node_free (&line_color_node);
737
738                 if (is_first_object) {
739                         selection_line_color = line_color;
740                 } else {
741                         if (line_color != selection_line_color)
742                                 is_same_line_color = FALSE;
743                 }
744                 is_first_object = FALSE;
745         }
746
747         if (is_same_line_color) {
748                 gl_debug (DEBUG_PROPERTY_BAR, "same line color = %08x", selection_line_color);
749                 gdk_color = gl_color_to_gdk_color (selection_line_color);
750                 color_combo_set_color (COLOR_COMBO (property_bar->line_color_combo),
751                                        gdk_color);
752                 g_free (gdk_color);
753         }
754 }
755
756 static void
757 update_line_width (glView *view,
758                    glUIPropertyBar *property_bar)
759 {
760         gboolean can, is_first_object;
761         gboolean is_same_line_width;
762         GList *p;
763         glLabelObject *object;
764         gdouble selection_line_width, line_width;
765
766         can = gl_view_can_selection_line_width (view);
767         gl_ui_util_set_verb_list_sensitive (property_bar->ui_component,
768                                             line_width_verbs,
769                                             can);
770         if (!can) 
771                 return;
772
773         is_same_line_width = TRUE;
774         is_first_object = TRUE;
775         
776         for (p = view->selected_object_list; p != NULL; p = p->next) {
777
778                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
779                 if (!gl_label_object_can_line_width (object)) 
780                         continue;
781
782                 line_width = gl_label_object_get_line_width (object);
783
784                 if (is_first_object) {
785                         selection_line_width = line_width;
786                 } else {
787                         if (line_width != selection_line_width)
788                                 is_same_line_width = FALSE;
789                 }
790                 is_first_object = FALSE;
791         }
792
793         if (is_same_line_width) {
794                 gl_debug (DEBUG_PROPERTY_BAR, "same line width = %g", selection_line_width);
795                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (property_bar->line_width_spin),
796                                            selection_line_width);
797         } else {
798                 gtk_entry_set_text (GTK_ENTRY (property_bar->line_width_spin), "");
799         }
800 }
801
802 static void 
803 selection_changed_cb (glUIPropertyBar *property_bar)
804 {
805         glView *view = property_bar->view;
806         
807         gl_debug (DEBUG_PROPERTY_BAR, "START");
808
809         g_return_if_fail (view && GL_IS_VIEW (view));
810         g_return_if_fail (property_bar && GL_IS_UI_PROPERTY_BAR (property_bar));
811
812         property_bar->stop_signals = TRUE;
813
814         if (gl_view_is_selection_empty (view)) {
815
816                 /* No selection: make all controls active. */
817                 reset_to_default_properties (view, property_bar);
818                 gl_ui_util_set_verb_list_sensitive (property_bar->ui_component,
819                                                     doc_verbs, TRUE);
820
821         } else {
822
823                 update_text_properties (view, property_bar);
824                 update_fill_color (view, property_bar);
825                 update_line_color (view, property_bar);
826                 update_line_width (view, property_bar);
827
828         }
829
830         property_bar->stop_signals = FALSE;
831
832         gl_debug (DEBUG_PROPERTY_BAR, "END");
833 }
834
835 /*--------------------------------------------------------------------------*/
836 /* PRIVATE.  Font family entry changed.                                     */
837 /*--------------------------------------------------------------------------*/
838 static void
839 font_family_changed_cb (GtkEntry        *entry,
840                         glUIPropertyBar *property_bar)
841 {
842         gchar *font_family;
843
844         if (property_bar->stop_signals)
845                 return;
846
847         gl_debug (DEBUG_PROPERTY_BAR, "START");
848
849         g_signal_handlers_block_by_func (G_OBJECT(property_bar->view->label),
850                                          selection_changed_cb,
851                                          property_bar);
852
853         font_family = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
854         if ( strlen(font_family) ) {
855                 gl_view_set_selection_font_family (property_bar->view,
856                                                    font_family);
857                 gl_view_set_default_font_family   (property_bar->view,
858                                                    font_family);
859         }
860         g_free (font_family);
861
862         g_signal_handlers_unblock_by_func (G_OBJECT(property_bar->view->label),
863                                            selection_changed_cb,
864                                            property_bar);
865
866         gl_debug (DEBUG_PROPERTY_BAR, "END");
867 }
868
869 /*--------------------------------------------------------------------------*/
870 /* PRIVATE.  Font size spin button changed.                                 */
871 /*--------------------------------------------------------------------------*/
872 static void
873 font_size_changed_cb (GtkSpinButton        *spin,
874                       glUIPropertyBar      *property_bar)
875 {
876         gdouble font_size;
877
878         if (property_bar->stop_signals)
879                 return;
880
881         gl_debug (DEBUG_PROPERTY_BAR, "START");
882
883         g_signal_handlers_block_by_func (G_OBJECT(property_bar->view->label),
884                                          selection_changed_cb,
885                                          property_bar);
886
887         font_size = gtk_spin_button_get_value (spin);
888
889         gl_view_set_selection_font_size (property_bar->view,
890                                          font_size);
891         gl_view_set_default_font_size   (property_bar->view,
892                                          font_size);
893
894         g_signal_handlers_unblock_by_func (G_OBJECT(property_bar->view->label),
895                                            selection_changed_cb,
896                                            property_bar);
897
898         gl_debug (DEBUG_PROPERTY_BAR, "END");
899 }
900
901 /*--------------------------------------------------------------------------*/
902 /* PRIVATE.  Text color combo changed.                                      */
903 /*--------------------------------------------------------------------------*/
904 static void
905 text_color_changed_cb (ColorCombo           *cc,
906                        GdkColor             *gdk_color,
907                        gboolean              custom,
908                        gboolean              by_user,
909                        gboolean              is_default,
910                        glUIPropertyBar      *property_bar)
911 {
912         glColorNode *text_color_node;
913
914         if (property_bar->stop_signals)
915                 return;
916
917         g_return_if_fail (property_bar && GL_IS_UI_PROPERTY_BAR (property_bar));
918
919         gl_debug (DEBUG_PROPERTY_BAR, "START");
920
921         g_signal_handlers_block_by_func (G_OBJECT(property_bar->view->label),
922                                          selection_changed_cb,
923                                          property_bar);
924
925         text_color_node = gl_color_node_new_default ();
926         text_color_node->color = gl_color_from_gdk_color (gdk_color);
927         
928         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Custom=%d, By_User=%d, Is_default=%d",
929                   text_color_node->color, custom, by_user, is_default);
930
931         if (is_default) {
932                 text_color_node->color = gl_prefs->default_text_color;
933                 gl_view_set_selection_text_color (property_bar->view,
934                                                   text_color_node);
935                 gl_view_set_default_text_color   (property_bar->view,
936                                                   gl_prefs->default_text_color);
937
938         } else {
939
940                 gl_view_set_selection_text_color (property_bar->view,
941                                                   text_color_node);
942                 gl_view_set_default_text_color   (property_bar->view,
943                                                   text_color_node->color);
944
945         }
946
947         gl_color_node_free (&text_color_node);
948         
949         g_signal_handlers_unblock_by_func (G_OBJECT(property_bar->view->label),
950                                            selection_changed_cb,
951                                            property_bar);
952
953         gl_debug (DEBUG_PROPERTY_BAR, "END");
954 }
955
956 /*--------------------------------------------------------------------------*/
957 /* PRIVATE.  Fill color combo changed.                                      */
958 /*--------------------------------------------------------------------------*/
959 static void
960 fill_color_changed_cb (ColorCombo           *cc,
961                        GdkColor             *gdk_color,
962                        gboolean              custom,
963                        gboolean              by_user,
964                        gboolean              is_default,
965                        glUIPropertyBar      *property_bar)
966 {
967         glColorNode *fill_color_node;
968
969         if (property_bar->stop_signals)
970                 return;
971
972         g_return_if_fail (property_bar && GL_IS_UI_PROPERTY_BAR (property_bar));
973
974         gl_debug (DEBUG_PROPERTY_BAR, "START");
975
976         g_signal_handlers_block_by_func (G_OBJECT(property_bar->view->label),
977                                          selection_changed_cb,
978                                          property_bar);
979
980         fill_color_node = gl_color_node_new_default ();
981
982         fill_color_node->color = gl_color_from_gdk_color (gdk_color);
983
984         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Custom=%d, By_User=%d, Is_default=%d",
985                   fill_color_node->color, custom, by_user, is_default);
986
987         if (is_default) {
988
989                 fill_color_node->color = GL_COLOR_NONE;
990                 gl_view_set_selection_fill_color (property_bar->view,
991                                                   fill_color_node);
992                 gl_view_set_default_fill_color   (property_bar->view,
993                                                   fill_color_node->color);
994
995         } else {
996
997                 gl_view_set_selection_fill_color (property_bar->view,
998                                                   fill_color_node);
999                 gl_view_set_default_fill_color   (property_bar->view,
1000                                                   fill_color_node->color);
1001
1002         }
1003         gl_color_node_free (&fill_color_node);
1004         
1005         g_signal_handlers_unblock_by_func (G_OBJECT(property_bar->view->label),
1006                                            selection_changed_cb,
1007                                            property_bar);
1008
1009         gl_debug (DEBUG_PROPERTY_BAR, "END");
1010 }
1011
1012 /*--------------------------------------------------------------------------*/
1013 /* PRIVATE.  Line color combo changed.                                      */
1014 /*--------------------------------------------------------------------------*/
1015 static void
1016 line_color_changed_cb (ColorCombo           *cc,
1017                        GdkColor             *gdk_color,
1018                        gboolean              custom,
1019                        gboolean              by_user,
1020                        gboolean              is_default,
1021                        glUIPropertyBar      *property_bar)
1022 {
1023         glColorNode *line_color_node;
1024
1025         if (property_bar->stop_signals)
1026                 return;
1027
1028         g_return_if_fail (property_bar && GL_IS_UI_PROPERTY_BAR (property_bar));
1029
1030         gl_debug (DEBUG_PROPERTY_BAR, "START");
1031
1032         g_signal_handlers_block_by_func (G_OBJECT(property_bar->view->label),
1033                                          selection_changed_cb,
1034                                          property_bar);
1035
1036         line_color_node = gl_color_node_new_default ();
1037         line_color_node->color = gl_color_from_gdk_color (gdk_color);
1038
1039         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Custom=%d, By_User=%d, Is_default=%d",
1040                   line_color_node->color, custom, by_user, is_default);
1041
1042         if (is_default) {
1043                 line_color_node->color = GL_COLOR_NONE;
1044                 gl_view_set_selection_line_color (property_bar->view,
1045                                                   line_color_node);
1046                 gl_view_set_default_line_color   (property_bar->view,
1047                                                   line_color_node->color);
1048
1049         } else {
1050
1051                 gl_view_set_selection_line_color (property_bar->view,
1052                                                   line_color_node);
1053                 gl_view_set_default_line_color   (property_bar->view,
1054                                                   line_color_node->color);
1055
1056         }
1057         gl_color_node_free (&line_color_node);
1058
1059         g_signal_handlers_unblock_by_func (G_OBJECT(property_bar->view->label),
1060                                            selection_changed_cb,
1061                                            property_bar);
1062
1063         gl_debug (DEBUG_PROPERTY_BAR, "END");
1064 }
1065
1066 /*--------------------------------------------------------------------------*/
1067 /* PRIVATE.  Line width spin button changed.                                */
1068 /*--------------------------------------------------------------------------*/
1069 static void
1070 line_width_changed_cb (GtkSpinButton        *spin,
1071                        glUIPropertyBar      *property_bar)
1072 {
1073         gdouble line_width;
1074
1075         if (property_bar->stop_signals)
1076                 return;
1077
1078         gl_debug (DEBUG_PROPERTY_BAR, "START");
1079
1080         g_signal_handlers_block_by_func (G_OBJECT(property_bar->view->label),
1081                                          selection_changed_cb,
1082                                          property_bar);
1083
1084         line_width = gtk_spin_button_get_value (spin);
1085
1086         gl_view_set_selection_line_width (property_bar->view,
1087                                           line_width);
1088         gl_view_set_default_line_width   (property_bar->view,
1089                                           line_width);
1090
1091         g_signal_handlers_unblock_by_func (G_OBJECT(property_bar->view->label),
1092                                            selection_changed_cb,
1093                                            property_bar);
1094
1095         gl_debug (DEBUG_PROPERTY_BAR, "END");
1096 }
1097
1098 /*---------------------------------------------------------------------------*/
1099 /* PRIVATE.  Property bar item toggled callback.                             */
1100 /*---------------------------------------------------------------------------*/
1101 static void
1102 prop_item_toggled_cb (BonoboUIComponent           *ui_component,
1103                       const char                  *path,
1104                       Bonobo_UIComponent_EventType type,
1105                       const char                  *state,
1106                       glUIPropertyBar             *property_bar)
1107 {
1108         gboolean s;
1109
1110         if (property_bar->stop_signals)
1111                 return;
1112
1113         gl_debug (DEBUG_PROPERTY_BAR, "");
1114
1115         g_signal_handlers_block_by_func (G_OBJECT(property_bar->view->label),
1116                                          selection_changed_cb,
1117                                          property_bar);
1118
1119         s = (strcmp (state, "1") == 0);
1120
1121         /*
1122          * Font properties: Bold & Italic
1123          */
1124         if (strcmp (path, "PropFontBold") == 0)
1125         {               
1126                 GnomeFontWeight weight = s ? GNOME_FONT_BOLD : GNOME_FONT_BOOK;
1127
1128                 gl_view_set_selection_font_weight (property_bar->view, weight);
1129                 gl_view_set_default_font_weight   (property_bar->view, weight);
1130         }
1131
1132         if (strcmp (path, "PropFontItalic") == 0)
1133         {               
1134                 gl_view_set_selection_font_italic_flag (property_bar->view, s);
1135                 gl_view_set_default_font_italic_flag   (property_bar->view, s);
1136         }
1137
1138
1139         /*
1140          * Text alignment group
1141          */
1142         if (s && (strcmp (path, "PropTextAlignLeft") == 0))
1143         {               
1144                 gl_view_set_selection_text_alignment (property_bar->view,
1145                                                       GTK_JUSTIFY_LEFT);
1146                 gl_view_set_default_text_alignment   (property_bar->view,
1147                                                       GTK_JUSTIFY_LEFT);
1148
1149                 /* Adjust state of siblings */
1150                 gl_ui_util_set_verb_state (ui_component,
1151                                            "/commands/PropTextAlignCenter",
1152                                            FALSE);
1153                 gl_ui_util_set_verb_state (ui_component,
1154                                            "/commands/PropTextAlignRight",
1155                                            FALSE);
1156         }
1157
1158         if (s && (strcmp (path, "PropTextAlignCenter") == 0))
1159         {               
1160                 gl_view_set_selection_text_alignment (property_bar->view,
1161                                                       GTK_JUSTIFY_CENTER);
1162                 gl_view_set_default_text_alignment   (property_bar->view,
1163                                                       GTK_JUSTIFY_CENTER);
1164
1165                 /* Adjust state of siblings */
1166                 gl_ui_util_set_verb_state (ui_component,
1167                                            "/commands/PropTextAlignLeft",
1168                                            FALSE);
1169                 gl_ui_util_set_verb_state (ui_component,
1170                                            "/commands/PropTextAlignRight",
1171                                            FALSE);
1172         }
1173
1174         if (s && (strcmp (path, "PropTextAlignRight") == 0))
1175         {               
1176                 gl_view_set_selection_text_alignment (property_bar->view,
1177                                                       GTK_JUSTIFY_RIGHT);
1178                 gl_view_set_default_text_alignment   (property_bar->view,
1179                                                       GTK_JUSTIFY_RIGHT);
1180
1181                 /* Adjust state of siblings */
1182                 gl_ui_util_set_verb_state (ui_component,
1183                                            "/commands/PropTextAlignLeft",
1184                                            FALSE);
1185                 gl_ui_util_set_verb_state (ui_component,
1186                                            "/commands/PropTextAlignCenter",
1187                                            FALSE);
1188         }
1189
1190         g_signal_handlers_unblock_by_func (G_OBJECT(property_bar->view->label),
1191                                            selection_changed_cb,
1192                                            property_bar);
1193
1194 }
1195
1196 /*---------------------------------------------------------------------------------------*/
1197 /* NULL command handler -- hides bogus "verb not found" errors for toggle toolbar items. */
1198 /*---------------------------------------------------------------------------------------*/
1199 static void
1200 null_cmd (BonoboUIComponent           *ui_component,
1201           gpointer                     user_data,
1202           const gchar                 *verbname)
1203 {
1204 }