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