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