]> git.sur5r.net Git - glabels/blob - glabels2/src/ui-property-bar.c
2008-10-23 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
340         g_signal_connect (G_OBJECT (this->priv->font_family_combo),
341                           "changed", G_CALLBACK (font_family_changed_cb), this);
342
343         /* Font size entry widget */
344         gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->font_size_spin),
345                                    gl_prefs->default_font_size);
346
347         g_signal_connect (G_OBJECT (this->priv->font_size_spin),
348                           "changed", G_CALLBACK (font_size_changed_cb), this);
349
350
351         /* Bold and Italic toggles */
352         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
353                                            (gl_prefs->default_font_weight == PANGO_WEIGHT_BOLD));
354         g_signal_connect (G_OBJECT (this->priv->font_bold_toggle),
355                           "toggled", G_CALLBACK (font_bold_toggled_cb), this);
356         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
357                                            gl_prefs->default_font_italic_flag);
358         g_signal_connect (G_OBJECT (this->priv->font_italic_toggle),
359                           "toggled", G_CALLBACK (font_italic_toggled_cb), this);
360
361
362         /* Text alignment radio group */
363         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
364                                            (gl_prefs->default_text_alignment == PANGO_ALIGN_LEFT));
365         g_signal_connect (G_OBJECT (this->priv->text_align_left_radio),
366                           "toggled", G_CALLBACK (text_align_toggled_cb), this);
367         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
368                                            (gl_prefs->default_text_alignment == PANGO_ALIGN_CENTER));
369         g_signal_connect (G_OBJECT (this->priv->text_align_center_radio),
370                           "toggled", G_CALLBACK (text_align_toggled_cb), this);
371         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
372                                            (gl_prefs->default_text_alignment == PANGO_ALIGN_RIGHT));
373         g_signal_connect (G_OBJECT (this->priv->text_align_right_radio),
374                           "toggled", G_CALLBACK (text_align_toggled_cb), this);
375
376         /* Text color widget */
377         gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->text_color_combo), gl_prefs->default_text_color);
378         g_signal_connect (G_OBJECT (this->priv->text_color_combo),
379                           "color_changed",
380                           G_CALLBACK (text_color_changed_cb), this);
381
382         /* Fill color widget */
383         gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->fill_color_combo), gl_prefs->default_fill_color);
384         g_signal_connect (G_OBJECT (this->priv->fill_color_combo),
385                           "color_changed",
386                           G_CALLBACK (fill_color_changed_cb), this);
387
388         /* Line color widget */
389         gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->line_color_combo), gl_prefs->default_line_color);
390         g_signal_connect (G_OBJECT (this->priv->line_color_combo),
391                           "color_changed",
392                           G_CALLBACK (line_color_changed_cb), this);
393
394         /* Line width entry widget */
395         g_signal_connect (G_OBJECT (this->priv->line_width_spin),
396                           "changed",
397                           G_CALLBACK (line_width_changed_cb), this);
398
399         this->priv->stop_signals = FALSE;
400
401         gl_debug (DEBUG_PROPERTY_BAR, "END");
402 }
403
404
405 /****************************************************************************/
406 /* Fill widgets with default values.                                        */
407 /****************************************************************************/
408 static void
409 reset_to_default_properties (glView *view,
410                              glUIPropertyBar *this)
411 {
412         GList     *family_names;
413         gchar     *good_font_family;
414
415         /* Make sure we have a valid font.  if not provide a good default. */
416         family_names = gl_util_get_font_family_list ();
417         if (g_list_find_custom (family_names,
418                                 view->default_font_family,
419                                 (GCompareFunc)g_utf8_collate))
420         {
421                 good_font_family = g_strdup (view->default_font_family);
422         }
423         else
424         {
425                 if (family_names != NULL)
426                 {
427                         good_font_family = g_strdup (family_names->data); /* 1st entry */
428                 }
429                 else
430                 {
431                         good_font_family = NULL;
432                 }
433         }
434         gl_util_combo_box_set_active_text (GTK_COMBO_BOX (this->priv->font_family_combo),
435                                            good_font_family);
436         g_free (good_font_family);
437
438         gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->font_size_spin),
439                                    view->default_font_size);
440
441         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
442                                            (view->default_font_weight == PANGO_WEIGHT_BOLD));
443         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
444                                            view->default_font_italic_flag);
445
446         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
447                                            (view->default_text_alignment == PANGO_ALIGN_LEFT));
448         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
449                                            (view->default_text_alignment == PANGO_ALIGN_CENTER));
450         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
451                                            (view->default_text_alignment == PANGO_ALIGN_RIGHT));
452
453         gl_color_combo_set_color (GL_COLOR_COMBO(this->priv->text_color_combo), view->default_text_color);
454
455         gl_color_combo_set_color (GL_COLOR_COMBO(this->priv->fill_color_combo), view->default_fill_color);
456
457         gl_color_combo_set_color (GL_COLOR_COMBO(this->priv->line_color_combo), view->default_line_color);
458
459         gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->line_width_spin),
460                                    view->default_line_width);
461 }
462
463
464 /****************************************************************************/
465 /* Set view associated with property_bar.                                   */
466 /****************************************************************************/
467 void
468 gl_ui_property_bar_set_view (glUIPropertyBar *this,
469                              glView          *view)
470 {
471         glLabel   *label;
472
473         gl_debug (DEBUG_PROPERTY_BAR, "START");
474
475         g_return_if_fail (view && GL_IS_VIEW (view));
476         label = view->label;
477         g_return_if_fail (label && GL_IS_LABEL (label));
478
479         set_doc_items_sensitive (this, TRUE);
480
481         this->priv->view = GL_VIEW (g_object_ref (G_OBJECT (view)));
482
483         reset_to_default_properties (view, this);
484
485         g_signal_connect_swapped (G_OBJECT(view), "selection_changed",
486                                   G_CALLBACK(selection_changed_cb), this);
487
488         g_signal_connect_swapped (G_OBJECT(view->label), "changed",
489                                   G_CALLBACK(selection_changed_cb), this);
490
491         gl_debug (DEBUG_PROPERTY_BAR, "END");
492 }
493
494
495 /****************************************************************************/
496 /** Set visiblity of property bar's tooltips.                               */
497 /****************************************************************************/
498 void
499 gl_ui_property_bar_set_tooltips (glUIPropertyBar *this,
500                                  gboolean         state)
501 {
502         GtkTooltipsData *data;
503
504         gl_debug (DEBUG_PROPERTY_BAR, "START");
505
506         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR(this));
507
508         /* HACK: peek into one of our widgets to get the tooltips group created by builder. */
509         data = gtk_tooltips_data_get (this->priv->font_size_spin);
510         g_return_if_fail (data);
511
512         if (state)
513         {
514                 gtk_tooltips_enable (data->tooltips);
515         }
516         else
517         {
518                 gtk_tooltips_disable (data->tooltips);
519         }
520
521         gl_debug (DEBUG_PROPERTY_BAR, "END");
522 }
523
524
525 /*---------------------------------------------------------------------------*/
526 /* PRIVATE.  View "selection state changed" callback.                        */
527 /*---------------------------------------------------------------------------*/
528 static void
529 update_text_properties (glView *view,
530                         glUIPropertyBar *this)
531 {
532         gboolean        can_text, is_first_object;
533         gboolean        is_same_font_family, is_same_font_size;
534         gboolean        is_same_text_color, is_same_is_italic;
535         gboolean        is_same_is_bold, is_same_align;
536         GList          *p;
537         glLabelObject  *object;
538         gchar          *selection_font_family, *font_family;
539         gdouble         selection_font_size, font_size;
540         guint           selection_text_color, text_color;
541         glColorNode    *text_color_node;
542         gboolean        selection_is_italic, is_italic;
543         gboolean        selection_is_bold, is_bold;
544         PangoAlignment  selection_align, align;
545
546         can_text = gl_view_can_selection_text (view);
547         set_text_items_sensitive (this, can_text);
548
549         if (!can_text) 
550                 return;
551
552         is_same_is_italic =
553         is_same_is_bold =
554         is_same_align =
555         is_same_text_color =
556         is_same_font_size =
557         is_same_font_family = TRUE;
558         selection_font_family = NULL;
559         selection_font_size = -1;
560         selection_align = PANGO_ALIGN_LEFT;
561         selection_is_italic = TRUE;
562         selection_is_bold = TRUE;
563         selection_text_color = 0;
564         
565         is_first_object = TRUE;
566         
567         for (p = view->selected_object_list; p != NULL; p = p->next)
568         {
569
570                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
571                 if (!gl_label_object_can_text (object)) 
572                         continue;
573
574                 font_family = gl_label_object_get_font_family (object);
575                 if (font_family != NULL)
576                 {
577                         if (selection_font_family == NULL)
578                         {
579                                 selection_font_family = g_strdup (font_family);
580                         }
581                         else 
582                         {
583                                 if (strcmp (font_family, selection_font_family) != 0)
584                                 {
585                                         is_same_font_family = FALSE;
586                                 }
587                         }
588                         g_free (font_family);
589                 }       
590
591                 font_size = gl_label_object_get_font_size (object);
592                 
593                 text_color_node = gl_label_object_get_text_color (object);
594                 if (text_color_node->field_flag)
595                 {
596                         /* If a merge field is set we use the default color for merged color*/
597                         text_color = GL_COLOR_MERGE_DEFAULT;
598                         
599                 }
600                 else
601                 {
602                         text_color = text_color_node->color;
603                 }
604                 gl_color_node_free (&text_color_node);
605                 
606                 is_italic = gl_label_object_get_font_italic_flag (object);
607                 is_bold = gl_label_object_get_font_weight (object) == PANGO_WEIGHT_BOLD;
608                 align = gl_label_object_get_text_alignment (object);
609
610                 if (is_first_object)
611                 {
612                         selection_font_size = font_size;
613                         selection_text_color = text_color;
614                         selection_is_italic = is_italic;
615                         selection_is_bold = is_bold;
616                         selection_align = align;
617                 }
618                 else
619                 {
620                         if (font_size != selection_font_size) 
621                                 is_same_font_size = FALSE;
622                         if (text_color != selection_text_color)
623                                 is_same_text_color = FALSE;
624                         if (is_italic != selection_is_italic)
625                                 is_same_is_italic = FALSE;
626                         if (is_bold != selection_is_bold)
627                                 is_same_is_bold = FALSE;
628                         if (align != selection_align)
629                                 is_same_align = FALSE;
630                 }
631                 is_first_object = FALSE;
632         }
633
634         if (is_same_font_family && (selection_font_family != NULL)) 
635                 gl_debug (DEBUG_PROPERTY_BAR, "same font family = %s", 
636                           selection_font_family);
637         gl_util_combo_box_set_active_text (GTK_COMBO_BOX (this->priv->font_family_combo),
638                                            is_same_font_family?selection_font_family:"");
639         g_free (selection_font_family);
640
641         if (is_same_font_size)
642         {
643                 gl_debug (DEBUG_PROPERTY_BAR, "same font size = %g", 
644                           selection_font_size);
645                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (this->priv->font_size_spin),
646                                            selection_font_size);
647         }
648         else
649         {
650                 gtk_entry_set_text (GTK_ENTRY (this->priv->font_size_spin), "");
651         }
652
653         if (is_same_text_color)
654         {
655                 gl_debug (DEBUG_PROPERTY_BAR, "same text color = %08x", selection_text_color);
656                 gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->text_color_combo),
657                                           selection_text_color);
658         }
659
660         if (is_same_is_italic)
661         {
662                 gl_debug (DEBUG_PROPERTY_BAR, "same italic flag = %d", 
663                           selection_is_italic);
664         }
665         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
666                                            selection_is_italic && is_same_is_italic);
667
668         if (is_same_is_bold)
669         {
670                 gl_debug (DEBUG_PROPERTY_BAR, "same bold flag = %d",
671                           selection_is_bold);
672         }
673         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
674                                            selection_is_bold && is_same_is_bold);
675
676         if (is_same_align) 
677                 gl_debug (DEBUG_PROPERTY_BAR, "same align");
678         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
679                                            (selection_align == PANGO_ALIGN_LEFT) &&
680                                            is_same_align);
681         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
682                                            (selection_align == PANGO_ALIGN_CENTER) &&
683                                            is_same_align);
684         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
685                                            (selection_align == PANGO_ALIGN_RIGHT) &&
686                                            is_same_align);
687 }
688
689
690 static void
691 update_fill_color (glView *view,
692                    glUIPropertyBar *this)
693 {
694         gboolean can, is_first_object;
695         gboolean is_same_fill_color;
696         GList *p;
697         glLabelObject *object;
698         guint selection_fill_color, fill_color;
699         glColorNode *fill_color_node;
700
701         can = gl_view_can_selection_fill (view);
702         set_fill_items_sensitive (this, can);
703
704         if (!can) 
705                 return;
706
707         is_same_fill_color = TRUE;
708         is_first_object = TRUE;
709         selection_fill_color = 0;
710         
711         for (p = view->selected_object_list; p != NULL; p = p->next)
712         {
713
714                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
715                 if (!gl_label_object_can_fill (object)) 
716                         continue;
717
718                 fill_color_node = gl_label_object_get_fill_color (object);
719                 if (fill_color_node->field_flag)
720                 {
721                         /* If a merge field is set we use the default color for merged color*/
722                         fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
723                         
724                 }
725                 else
726                 {
727                         fill_color = fill_color_node->color;
728                 }
729                 gl_color_node_free (&fill_color_node);
730
731                 if (is_first_object)
732                 {
733                         selection_fill_color = fill_color;
734                 }
735                 else
736                 {
737                         if (fill_color != selection_fill_color)
738                         {
739                                 is_same_fill_color = FALSE;
740                         }
741                 }
742                 is_first_object = FALSE;
743         }
744
745         if (is_same_fill_color)
746         {
747                 gl_debug (DEBUG_PROPERTY_BAR, "same fill color = %08x", selection_fill_color);
748                 gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->fill_color_combo),
749                                           selection_fill_color);
750         }
751 }
752
753
754 static void
755 update_line_color (glView *view,
756                    glUIPropertyBar *this)
757 {
758         gboolean can, is_first_object;
759         gboolean is_same_line_color;
760         GList *p;
761         glLabelObject *object;
762         guint selection_line_color, line_color;
763         glColorNode *line_color_node;
764
765         can = gl_view_can_selection_line_color (view);
766         set_line_color_items_sensitive (this, can);
767
768         if (!can) 
769                 return;
770
771         is_same_line_color = TRUE;
772         is_first_object = TRUE;
773         selection_line_color = 0;
774         
775         for (p = view->selected_object_list; p != NULL; p = p->next)
776         {
777
778                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
779                 if (!gl_label_object_can_line_color (object)) 
780                         continue;
781
782                 line_color_node = gl_label_object_get_line_color (object);
783                 if (line_color_node->field_flag)
784                 {
785                         /* If a merge field is set we use the default color for merged color*/
786                         line_color = GL_COLOR_MERGE_DEFAULT;
787                         
788                 }
789                 else
790                 {
791                         line_color = line_color_node->color;
792                 }
793                 gl_color_node_free (&line_color_node);
794
795                 if (is_first_object)
796                 {
797                         selection_line_color = line_color;
798                 }
799                 else
800                 {
801                         if (line_color != selection_line_color)
802                         {
803                                 is_same_line_color = FALSE;
804                         }
805                 }
806                 is_first_object = FALSE;
807         }
808
809         if (is_same_line_color)
810         {
811                 gl_debug (DEBUG_PROPERTY_BAR, "same line color = %08x", selection_line_color);
812                 gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->line_color_combo),
813                                           selection_line_color);
814         }
815 }
816
817
818 static void
819 update_line_width (glView *view,
820                    glUIPropertyBar *this)
821 {
822         gboolean can, is_first_object;
823         gboolean is_same_line_width;
824         GList *p;
825         glLabelObject *object;
826         gdouble selection_line_width, line_width;
827
828         can = gl_view_can_selection_line_width (view);
829         set_line_width_items_sensitive (this, can);
830
831         if (!can) 
832                 return;
833
834         is_same_line_width = TRUE;
835         is_first_object = TRUE;
836         selection_line_width = 0;
837         
838         for (p = view->selected_object_list; p != NULL; p = p->next)
839         {
840
841                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
842                 if (!gl_label_object_can_line_width (object)) 
843                         continue;
844
845                 line_width = gl_label_object_get_line_width (object);
846
847                 if (is_first_object)
848                 {
849                         selection_line_width = line_width;
850                 }
851                 else
852                 {
853                         if (line_width != selection_line_width)
854                         {
855                                 is_same_line_width = FALSE;
856                         }
857                 }
858                 is_first_object = FALSE;
859         }
860
861         if (is_same_line_width)
862         {
863                 gl_debug (DEBUG_PROPERTY_BAR, "same line width = %g", selection_line_width);
864                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (this->priv->line_width_spin),
865                                            selection_line_width);
866         }
867         else
868         {
869                 gtk_entry_set_text (GTK_ENTRY (this->priv->line_width_spin), "");
870         }
871 }
872
873
874 static void 
875 selection_changed_cb (glUIPropertyBar *this)
876 {
877         glView *view = this->priv->view;
878         
879         g_return_if_fail (view && GL_IS_VIEW (view));
880         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
881
882         if (this->priv->stop_signals) return;
883         this->priv->stop_signals = TRUE;
884
885         gl_debug (DEBUG_PROPERTY_BAR, "START");
886
887         if (gl_view_is_selection_empty (view))
888         {
889                 /* No selection: make all controls active. */
890                 reset_to_default_properties (view, this);
891                 set_doc_items_sensitive (this, TRUE);
892         }
893         else
894         {
895                 update_text_properties (view, this);
896                 update_fill_color (view, this);
897                 update_line_color (view, this);
898                 update_line_width (view, this);
899         }
900
901         gl_debug (DEBUG_PROPERTY_BAR, "END");
902
903         this->priv->stop_signals = FALSE;
904 }
905
906
907 /*--------------------------------------------------------------------------*/
908 /* PRIVATE.  Font family entry changed.                                     */
909 /*--------------------------------------------------------------------------*/
910 static void
911 font_family_changed_cb (GtkComboBox     *combo,
912                         glUIPropertyBar *this)
913 {
914         gchar *font_family;
915
916         if (this->priv->stop_signals) return;
917         this->priv->stop_signals = TRUE;
918
919         gl_debug (DEBUG_PROPERTY_BAR, "START");
920
921         font_family = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo));
922         if ( strlen(font_family) )
923         {
924                 gl_view_set_selection_font_family (this->priv->view,
925                                                    font_family);
926                 gl_view_set_default_font_family   (this->priv->view,
927                                                    font_family);
928         }
929         g_free (font_family);
930
931         gl_debug (DEBUG_PROPERTY_BAR, "END");
932
933         this->priv->stop_signals = FALSE;
934 }
935
936
937 /*--------------------------------------------------------------------------*/
938 /* PRIVATE.  Font size spin button changed.                                 */
939 /*--------------------------------------------------------------------------*/
940 static void
941 font_size_changed_cb (GtkSpinButton        *spin,
942                       glUIPropertyBar      *this)
943 {
944         gdouble font_size;
945
946         if (this->priv->stop_signals) return;
947         this->priv->stop_signals = TRUE;
948
949         gl_debug (DEBUG_PROPERTY_BAR, "START");
950
951         font_size = gtk_spin_button_get_value (spin);
952
953         gl_view_set_selection_font_size (this->priv->view,
954                                          font_size);
955         gl_view_set_default_font_size   (this->priv->view,
956                                          font_size);
957
958         gl_debug (DEBUG_PROPERTY_BAR, "END");
959
960         this->priv->stop_signals = FALSE;
961 }
962
963
964 /*--------------------------------------------------------------------------*/
965 /* PRIVATE.  Text color combo changed.                                      */
966 /*--------------------------------------------------------------------------*/
967 static void
968 text_color_changed_cb (glColorCombo         *cc,
969                        guint                 color,
970                        gboolean              is_default,
971                        glUIPropertyBar      *this)
972 {
973         glColorNode *text_color_node;
974
975         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
976
977         if (this->priv->stop_signals) return;
978         this->priv->stop_signals = TRUE;
979
980         gl_debug (DEBUG_PROPERTY_BAR, "START");
981
982         text_color_node = gl_color_node_new_default ();
983         text_color_node->color = color;
984         
985         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
986                   color, is_default);
987
988         if (is_default)
989         {
990                 text_color_node->color = gl_prefs->default_text_color;
991                 gl_view_set_selection_text_color (this->priv->view,
992                                                   text_color_node);
993                 gl_view_set_default_text_color   (this->priv->view,
994                                                   gl_prefs->default_text_color);
995         }
996         else
997         {
998                 gl_view_set_selection_text_color (this->priv->view,
999                                                   text_color_node);
1000                 gl_view_set_default_text_color   (this->priv->view,
1001                                                   text_color_node->color);
1002         }
1003
1004         gl_color_node_free (&text_color_node);
1005         
1006         gl_debug (DEBUG_PROPERTY_BAR, "END");
1007
1008         this->priv->stop_signals = FALSE;
1009 }
1010
1011
1012 /*--------------------------------------------------------------------------*/
1013 /* PRIVATE.  Fill color combo changed.                                      */
1014 /*--------------------------------------------------------------------------*/
1015 static void
1016 fill_color_changed_cb (glColorCombo         *cc,
1017                        guint                 color,
1018                        gboolean              is_default,
1019                        glUIPropertyBar      *this)
1020 {
1021         glColorNode *fill_color_node;
1022
1023         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
1024
1025         if (this->priv->stop_signals) return;
1026         this->priv->stop_signals = TRUE;
1027
1028         gl_debug (DEBUG_PROPERTY_BAR, "START");
1029
1030         fill_color_node = gl_color_node_new_default ();
1031
1032         fill_color_node->color = color;
1033
1034         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
1035                   color, is_default);
1036
1037         if (is_default)
1038         {
1039
1040                 fill_color_node->color = GL_COLOR_NONE;
1041                 gl_view_set_selection_fill_color (this->priv->view,
1042                                                   fill_color_node);
1043                 gl_view_set_default_fill_color   (this->priv->view,
1044                                                   fill_color_node->color);
1045         }
1046         else
1047         {
1048                 gl_view_set_selection_fill_color (this->priv->view,
1049                                                   fill_color_node);
1050                 gl_view_set_default_fill_color   (this->priv->view,
1051                                                   fill_color_node->color);
1052         }
1053         gl_color_node_free (&fill_color_node);
1054         
1055         gl_debug (DEBUG_PROPERTY_BAR, "END");
1056
1057         this->priv->stop_signals = FALSE;
1058 }
1059
1060
1061 /*--------------------------------------------------------------------------*/
1062 /* PRIVATE.  Line color combo changed.                                      */
1063 /*--------------------------------------------------------------------------*/
1064 static void
1065 line_color_changed_cb (glColorCombo         *cc,
1066                        guint                 color,
1067                        gboolean              is_default,
1068                        glUIPropertyBar      *this)
1069 {
1070         glColorNode *line_color_node;
1071
1072         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
1073
1074         if (this->priv->stop_signals) return;
1075         this->priv->stop_signals = TRUE;
1076
1077         gl_debug (DEBUG_PROPERTY_BAR, "START");
1078
1079         line_color_node = gl_color_node_new_default ();
1080         line_color_node->color = color;
1081
1082         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
1083                   color, is_default);
1084
1085         if (is_default)
1086         {
1087                 line_color_node->color = GL_COLOR_NONE;
1088                 gl_view_set_selection_line_color (this->priv->view,
1089                                                   line_color_node);
1090                 gl_view_set_default_line_color   (this->priv->view,
1091                                                   line_color_node->color);
1092         }
1093         else
1094         {
1095                 gl_view_set_selection_line_color (this->priv->view,
1096                                                   line_color_node);
1097                 gl_view_set_default_line_color   (this->priv->view,
1098                                                   line_color_node->color);
1099         }
1100         gl_color_node_free (&line_color_node);
1101
1102         gl_debug (DEBUG_PROPERTY_BAR, "END");
1103
1104         this->priv->stop_signals = FALSE;
1105 }
1106
1107
1108 /*--------------------------------------------------------------------------*/
1109 /* PRIVATE.  Line width spin button changed.                                */
1110 /*--------------------------------------------------------------------------*/
1111 static void
1112 line_width_changed_cb (GtkSpinButton        *spin,
1113                        glUIPropertyBar      *this)
1114 {
1115         gdouble line_width;
1116
1117         if (this->priv->stop_signals) return;
1118         this->priv->stop_signals = TRUE;
1119
1120         gl_debug (DEBUG_PROPERTY_BAR, "START");
1121
1122         if (this->priv->view)
1123         {
1124                 line_width = gtk_spin_button_get_value (spin);
1125
1126                 gl_view_set_selection_line_width (this->priv->view,
1127                                                   line_width);
1128                 gl_view_set_default_line_width   (this->priv->view,
1129                                                   line_width);
1130         }
1131
1132         gl_debug (DEBUG_PROPERTY_BAR, "END");
1133
1134         this->priv->stop_signals = FALSE;
1135 }
1136
1137
1138 /*---------------------------------------------------------------------------*/
1139 /* PRIVATE.  Font bold toggled callback.                                     */
1140 /*---------------------------------------------------------------------------*/
1141 static void
1142 font_bold_toggled_cb (GtkToggleToolButton  *toggle,
1143                       glUIPropertyBar      *this)
1144 {
1145         gboolean        state;
1146         PangoWeight     weight;
1147
1148
1149         if (this->priv->stop_signals) return;
1150         this->priv->stop_signals = TRUE;
1151
1152         gl_debug (DEBUG_PROPERTY_BAR, "START");
1153
1154         state = gtk_toggle_tool_button_get_active (toggle);
1155
1156         weight = state ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
1157
1158         gl_view_set_selection_font_weight (this->priv->view, weight);
1159         gl_view_set_default_font_weight   (this->priv->view, weight);
1160
1161         gl_debug (DEBUG_PROPERTY_BAR, "END");
1162
1163         this->priv->stop_signals = FALSE;
1164 }
1165                                                   
1166
1167 /*---------------------------------------------------------------------------*/
1168 /* PRIVATE.  Font italic toggled callback.                                   */
1169 /*---------------------------------------------------------------------------*/
1170 static void
1171 font_italic_toggled_cb (GtkToggleToolButton  *toggle,
1172                         glUIPropertyBar      *this)
1173 {
1174         gboolean state;
1175
1176         if (this->priv->stop_signals) return;
1177         this->priv->stop_signals = TRUE;
1178
1179         gl_debug (DEBUG_PROPERTY_BAR, "START");
1180
1181         state = gtk_toggle_tool_button_get_active (toggle);
1182
1183         gl_view_set_selection_font_italic_flag (this->priv->view, state);
1184         gl_view_set_default_font_italic_flag   (this->priv->view, state);
1185
1186         gl_debug (DEBUG_PROPERTY_BAR, "END");
1187
1188         this->priv->stop_signals = FALSE;
1189 }
1190                                                   
1191
1192 /*---------------------------------------------------------------------------*/
1193 /* PRIVATE.  Text align toggled callback.                                    */
1194 /*---------------------------------------------------------------------------*/
1195 static void
1196 text_align_toggled_cb (GtkToggleToolButton  *toggle,
1197                        glUIPropertyBar      *this)
1198 {
1199         if (this->priv->stop_signals) return;
1200         this->priv->stop_signals = TRUE;
1201
1202         gl_debug (DEBUG_PROPERTY_BAR, "START");
1203
1204         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio)))
1205         {               
1206                 gl_view_set_selection_text_alignment (this->priv->view,
1207                                                       PANGO_ALIGN_LEFT);
1208                 gl_view_set_default_text_alignment   (this->priv->view,
1209                                                       PANGO_ALIGN_LEFT);
1210         }
1211
1212         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio)))
1213         {               
1214                 gl_view_set_selection_text_alignment (this->priv->view,
1215                                                       PANGO_ALIGN_CENTER);
1216                 gl_view_set_default_text_alignment   (this->priv->view,
1217                                                       PANGO_ALIGN_CENTER);
1218         }
1219
1220         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio)))
1221         {
1222                 gl_view_set_selection_text_alignment (this->priv->view,
1223                                                       PANGO_ALIGN_RIGHT);
1224                 gl_view_set_default_text_alignment   (this->priv->view,
1225                                                       PANGO_ALIGN_RIGHT);
1226         }
1227
1228         gl_debug (DEBUG_PROPERTY_BAR, "END");
1229
1230         this->priv->stop_signals = FALSE;
1231 }
1232
1233
1234 /*---------------------------------------------------------------------------*/
1235 /* PRIVATE.  Set sensitivity of doc controls.                                */
1236 /*---------------------------------------------------------------------------*/
1237 static void
1238 set_doc_items_sensitive (glUIPropertyBar      *this,
1239                          gboolean              state)
1240 {
1241         gtk_widget_set_sensitive (this->priv->font_family_combo,       state);
1242         gtk_widget_set_sensitive (this->priv->font_size_spin,          state);
1243         gtk_widget_set_sensitive (this->priv->font_bold_toggle,        state);
1244         gtk_widget_set_sensitive (this->priv->font_italic_toggle,      state);
1245         gtk_widget_set_sensitive (this->priv->text_align_left_radio,   state);
1246         gtk_widget_set_sensitive (this->priv->text_align_center_radio, state);
1247         gtk_widget_set_sensitive (this->priv->text_align_right_radio,  state);
1248         gtk_widget_set_sensitive (this->priv->text_color_combo,        state);
1249         gtk_widget_set_sensitive (this->priv->fill_color_combo,        state);
1250         gtk_widget_set_sensitive (this->priv->line_color_combo,        state);
1251         gtk_widget_set_sensitive (this->priv->line_width_spin,         state);
1252 }
1253
1254
1255 /*---------------------------------------------------------------------------*/
1256 /* PRIVATE.  Set sensitivity of text related controls.                       */
1257 /*---------------------------------------------------------------------------*/
1258 static void
1259 set_text_items_sensitive (glUIPropertyBar      *this,
1260                           gboolean              state)
1261 {
1262         gtk_widget_set_sensitive (this->priv->font_family_combo,       state);
1263         gtk_widget_set_sensitive (this->priv->font_size_spin,          state);
1264         gtk_widget_set_sensitive (this->priv->font_bold_toggle,        state);
1265         gtk_widget_set_sensitive (this->priv->font_italic_toggle,      state);
1266         gtk_widget_set_sensitive (this->priv->text_align_left_radio,   state);
1267         gtk_widget_set_sensitive (this->priv->text_align_center_radio, state);
1268         gtk_widget_set_sensitive (this->priv->text_align_right_radio,  state);
1269         gtk_widget_set_sensitive (this->priv->text_color_combo,        state);
1270 }
1271
1272
1273 /*---------------------------------------------------------------------------*/
1274 /* PRIVATE.  Set sensitivity of fill related controls.                       */
1275 /*---------------------------------------------------------------------------*/
1276 static void
1277 set_fill_items_sensitive (glUIPropertyBar      *this,
1278                           gboolean              state)
1279 {
1280         gtk_widget_set_sensitive (this->priv->fill_color_combo,        state);
1281 }
1282
1283
1284 /*---------------------------------------------------------------------------*/
1285 /* PRIVATE.  Set sensitivity of line color related controls.                 */
1286 /*---------------------------------------------------------------------------*/
1287 static void
1288 set_line_color_items_sensitive (glUIPropertyBar      *this,
1289                                 gboolean              state)
1290 {
1291         gtk_widget_set_sensitive (this->priv->line_color_combo,        state);
1292 }
1293
1294
1295 /*---------------------------------------------------------------------------*/
1296 /* PRIVATE.  Set sensitivity of line width related controls.                 */
1297 /*---------------------------------------------------------------------------*/
1298 static void
1299 set_line_width_items_sensitive (glUIPropertyBar      *this,
1300                                 gboolean              state)
1301 {
1302         gtk_widget_set_sensitive (this->priv->line_width_spin,         state);
1303 }
1304
1305