]> git.sur5r.net Git - glabels/blob - glabels2/src/ui-property-bar.c
2009-02-21 JimEvins <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 /* PRIVATE.  View "selection state changed" callback.                        */
497 /*---------------------------------------------------------------------------*/
498 static void
499 update_text_properties (glView *view,
500                         glUIPropertyBar *this)
501 {
502         gboolean        can_text, is_first_object;
503         gboolean        is_same_font_family, is_same_font_size;
504         gboolean        is_same_text_color, is_same_is_italic;
505         gboolean        is_same_is_bold, is_same_align;
506         GList          *p;
507         glLabelObject  *object;
508         gchar          *selection_font_family, *font_family;
509         gdouble         selection_font_size, font_size;
510         guint           selection_text_color, text_color;
511         glColorNode    *text_color_node;
512         gboolean        selection_is_italic, is_italic;
513         gboolean        selection_is_bold, is_bold;
514         PangoAlignment  selection_align, align;
515
516         can_text = gl_view_can_selection_text (view);
517         set_text_items_sensitive (this, can_text);
518
519         if (!can_text) 
520                 return;
521
522         is_same_is_italic =
523         is_same_is_bold =
524         is_same_align =
525         is_same_text_color =
526         is_same_font_size =
527         is_same_font_family = TRUE;
528         selection_font_family = NULL;
529         selection_font_size = -1;
530         selection_align = PANGO_ALIGN_LEFT;
531         selection_is_italic = TRUE;
532         selection_is_bold = TRUE;
533         selection_text_color = 0;
534         
535         is_first_object = TRUE;
536         
537         for (p = view->selected_object_list; p != NULL; p = p->next)
538         {
539
540                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
541                 if (!gl_label_object_can_text (object)) 
542                         continue;
543
544                 font_family = gl_label_object_get_font_family (object);
545                 if (font_family != NULL)
546                 {
547                         if (selection_font_family == NULL)
548                         {
549                                 selection_font_family = g_strdup (font_family);
550                         }
551                         else 
552                         {
553                                 if (strcmp (font_family, selection_font_family) != 0)
554                                 {
555                                         is_same_font_family = FALSE;
556                                 }
557                         }
558                         g_free (font_family);
559                 }       
560
561                 font_size = gl_label_object_get_font_size (object);
562                 
563                 text_color_node = gl_label_object_get_text_color (object);
564                 if (text_color_node->field_flag)
565                 {
566                         /* If a merge field is set we use the default color for merged color*/
567                         text_color = GL_COLOR_MERGE_DEFAULT;
568                         
569                 }
570                 else
571                 {
572                         text_color = text_color_node->color;
573                 }
574                 gl_color_node_free (&text_color_node);
575                 
576                 is_italic = gl_label_object_get_font_italic_flag (object);
577                 is_bold = gl_label_object_get_font_weight (object) == PANGO_WEIGHT_BOLD;
578                 align = gl_label_object_get_text_alignment (object);
579
580                 if (is_first_object)
581                 {
582                         selection_font_size = font_size;
583                         selection_text_color = text_color;
584                         selection_is_italic = is_italic;
585                         selection_is_bold = is_bold;
586                         selection_align = align;
587                 }
588                 else
589                 {
590                         if (font_size != selection_font_size) 
591                                 is_same_font_size = FALSE;
592                         if (text_color != selection_text_color)
593                                 is_same_text_color = FALSE;
594                         if (is_italic != selection_is_italic)
595                                 is_same_is_italic = FALSE;
596                         if (is_bold != selection_is_bold)
597                                 is_same_is_bold = FALSE;
598                         if (align != selection_align)
599                                 is_same_align = FALSE;
600                 }
601                 is_first_object = FALSE;
602         }
603
604         if (is_same_font_family && (selection_font_family != NULL)) 
605                 gl_debug (DEBUG_PROPERTY_BAR, "same font family = %s", 
606                           selection_font_family);
607         gl_util_combo_box_set_active_text (GTK_COMBO_BOX (this->priv->font_family_combo),
608                                            is_same_font_family?selection_font_family:"");
609         g_free (selection_font_family);
610
611         if (is_same_font_size)
612         {
613                 gl_debug (DEBUG_PROPERTY_BAR, "same font size = %g", 
614                           selection_font_size);
615                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (this->priv->font_size_spin),
616                                            selection_font_size);
617         }
618         else
619         {
620                 gtk_entry_set_text (GTK_ENTRY (this->priv->font_size_spin), "");
621         }
622
623         if (is_same_text_color)
624         {
625                 gl_debug (DEBUG_PROPERTY_BAR, "same text color = %08x", selection_text_color);
626                 gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->text_color_combo),
627                                           selection_text_color);
628         }
629
630         if (is_same_is_italic)
631         {
632                 gl_debug (DEBUG_PROPERTY_BAR, "same italic flag = %d", 
633                           selection_is_italic);
634         }
635         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
636                                            selection_is_italic && is_same_is_italic);
637
638         if (is_same_is_bold)
639         {
640                 gl_debug (DEBUG_PROPERTY_BAR, "same bold flag = %d",
641                           selection_is_bold);
642         }
643         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
644                                            selection_is_bold && is_same_is_bold);
645
646         if (is_same_align) 
647                 gl_debug (DEBUG_PROPERTY_BAR, "same align");
648         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
649                                            (selection_align == PANGO_ALIGN_LEFT) &&
650                                            is_same_align);
651         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
652                                            (selection_align == PANGO_ALIGN_CENTER) &&
653                                            is_same_align);
654         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
655                                            (selection_align == PANGO_ALIGN_RIGHT) &&
656                                            is_same_align);
657 }
658
659
660 static void
661 update_fill_color (glView *view,
662                    glUIPropertyBar *this)
663 {
664         gboolean can, is_first_object;
665         gboolean is_same_fill_color;
666         GList *p;
667         glLabelObject *object;
668         guint selection_fill_color, fill_color;
669         glColorNode *fill_color_node;
670
671         can = gl_view_can_selection_fill (view);
672         set_fill_items_sensitive (this, can);
673
674         if (!can) 
675                 return;
676
677         is_same_fill_color = TRUE;
678         is_first_object = TRUE;
679         selection_fill_color = 0;
680         
681         for (p = view->selected_object_list; p != NULL; p = p->next)
682         {
683
684                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
685                 if (!gl_label_object_can_fill (object)) 
686                         continue;
687
688                 fill_color_node = gl_label_object_get_fill_color (object);
689                 if (fill_color_node->field_flag)
690                 {
691                         /* If a merge field is set we use the default color for merged color*/
692                         fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
693                         
694                 }
695                 else
696                 {
697                         fill_color = fill_color_node->color;
698                 }
699                 gl_color_node_free (&fill_color_node);
700
701                 if (is_first_object)
702                 {
703                         selection_fill_color = fill_color;
704                 }
705                 else
706                 {
707                         if (fill_color != selection_fill_color)
708                         {
709                                 is_same_fill_color = FALSE;
710                         }
711                 }
712                 is_first_object = FALSE;
713         }
714
715         if (is_same_fill_color)
716         {
717                 gl_debug (DEBUG_PROPERTY_BAR, "same fill color = %08x", selection_fill_color);
718                 gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->fill_color_combo),
719                                           selection_fill_color);
720         }
721 }
722
723
724 static void
725 update_line_color (glView *view,
726                    glUIPropertyBar *this)
727 {
728         gboolean can, is_first_object;
729         gboolean is_same_line_color;
730         GList *p;
731         glLabelObject *object;
732         guint selection_line_color, line_color;
733         glColorNode *line_color_node;
734
735         can = gl_view_can_selection_line_color (view);
736         set_line_color_items_sensitive (this, can);
737
738         if (!can) 
739                 return;
740
741         is_same_line_color = TRUE;
742         is_first_object = TRUE;
743         selection_line_color = 0;
744         
745         for (p = view->selected_object_list; p != NULL; p = p->next)
746         {
747
748                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
749                 if (!gl_label_object_can_line_color (object)) 
750                         continue;
751
752                 line_color_node = gl_label_object_get_line_color (object);
753                 if (line_color_node->field_flag)
754                 {
755                         /* If a merge field is set we use the default color for merged color*/
756                         line_color = GL_COLOR_MERGE_DEFAULT;
757                         
758                 }
759                 else
760                 {
761                         line_color = line_color_node->color;
762                 }
763                 gl_color_node_free (&line_color_node);
764
765                 if (is_first_object)
766                 {
767                         selection_line_color = line_color;
768                 }
769                 else
770                 {
771                         if (line_color != selection_line_color)
772                         {
773                                 is_same_line_color = FALSE;
774                         }
775                 }
776                 is_first_object = FALSE;
777         }
778
779         if (is_same_line_color)
780         {
781                 gl_debug (DEBUG_PROPERTY_BAR, "same line color = %08x", selection_line_color);
782                 gl_color_combo_set_color (GL_COLOR_COMBO (this->priv->line_color_combo),
783                                           selection_line_color);
784         }
785 }
786
787
788 static void
789 update_line_width (glView *view,
790                    glUIPropertyBar *this)
791 {
792         gboolean can, is_first_object;
793         gboolean is_same_line_width;
794         GList *p;
795         glLabelObject *object;
796         gdouble selection_line_width, line_width;
797
798         can = gl_view_can_selection_line_width (view);
799         set_line_width_items_sensitive (this, can);
800
801         if (!can) 
802                 return;
803
804         is_same_line_width = TRUE;
805         is_first_object = TRUE;
806         selection_line_width = 0;
807         
808         for (p = view->selected_object_list; p != NULL; p = p->next)
809         {
810
811                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
812                 if (!gl_label_object_can_line_width (object)) 
813                         continue;
814
815                 line_width = gl_label_object_get_line_width (object);
816
817                 if (is_first_object)
818                 {
819                         selection_line_width = line_width;
820                 }
821                 else
822                 {
823                         if (line_width != selection_line_width)
824                         {
825                                 is_same_line_width = FALSE;
826                         }
827                 }
828                 is_first_object = FALSE;
829         }
830
831         if (is_same_line_width)
832         {
833                 gl_debug (DEBUG_PROPERTY_BAR, "same line width = %g", selection_line_width);
834                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (this->priv->line_width_spin),
835                                            selection_line_width);
836         }
837         else
838         {
839                 gtk_entry_set_text (GTK_ENTRY (this->priv->line_width_spin), "");
840         }
841 }
842
843
844 static void 
845 selection_changed_cb (glUIPropertyBar *this)
846 {
847         glView *view = this->priv->view;
848         
849         g_return_if_fail (view && GL_IS_VIEW (view));
850         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
851
852         if (this->priv->stop_signals) return;
853         this->priv->stop_signals = TRUE;
854
855         gl_debug (DEBUG_PROPERTY_BAR, "START");
856
857         if (gl_view_is_selection_empty (view))
858         {
859                 /* No selection: make all controls active. */
860                 reset_to_default_properties (view, this);
861                 set_doc_items_sensitive (this, TRUE);
862         }
863         else
864         {
865                 update_text_properties (view, this);
866                 update_fill_color (view, this);
867                 update_line_color (view, this);
868                 update_line_width (view, this);
869         }
870
871         gl_debug (DEBUG_PROPERTY_BAR, "END");
872
873         this->priv->stop_signals = FALSE;
874 }
875
876
877 /*--------------------------------------------------------------------------*/
878 /* PRIVATE.  Font family entry changed.                                     */
879 /*--------------------------------------------------------------------------*/
880 static void
881 font_family_changed_cb (GtkComboBox     *combo,
882                         glUIPropertyBar *this)
883 {
884         gchar *font_family;
885
886         if (this->priv->stop_signals) return;
887         this->priv->stop_signals = TRUE;
888
889         gl_debug (DEBUG_PROPERTY_BAR, "START");
890
891         font_family = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo));
892         if ( strlen(font_family) )
893         {
894                 gl_view_set_selection_font_family (this->priv->view,
895                                                    font_family);
896                 gl_view_set_default_font_family   (this->priv->view,
897                                                    font_family);
898         }
899         g_free (font_family);
900
901         gl_debug (DEBUG_PROPERTY_BAR, "END");
902
903         this->priv->stop_signals = FALSE;
904 }
905
906
907 /*--------------------------------------------------------------------------*/
908 /* PRIVATE.  Font size spin button changed.                                 */
909 /*--------------------------------------------------------------------------*/
910 static void
911 font_size_changed_cb (GtkSpinButton        *spin,
912                       glUIPropertyBar      *this)
913 {
914         gdouble font_size;
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_size = gtk_spin_button_get_value (spin);
922
923         gl_view_set_selection_font_size (this->priv->view,
924                                          font_size);
925         gl_view_set_default_font_size   (this->priv->view,
926                                          font_size);
927
928         gl_debug (DEBUG_PROPERTY_BAR, "END");
929
930         this->priv->stop_signals = FALSE;
931 }
932
933
934 /*--------------------------------------------------------------------------*/
935 /* PRIVATE.  Text color combo changed.                                      */
936 /*--------------------------------------------------------------------------*/
937 static void
938 text_color_changed_cb (glColorCombo         *cc,
939                        guint                 color,
940                        gboolean              is_default,
941                        glUIPropertyBar      *this)
942 {
943         glColorNode *text_color_node;
944
945         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
946
947         if (this->priv->stop_signals) return;
948         this->priv->stop_signals = TRUE;
949
950         gl_debug (DEBUG_PROPERTY_BAR, "START");
951
952         text_color_node = gl_color_node_new_default ();
953         text_color_node->color = color;
954         
955         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
956                   color, is_default);
957
958         if (is_default)
959         {
960                 text_color_node->color = gl_prefs->default_text_color;
961                 gl_view_set_selection_text_color (this->priv->view,
962                                                   text_color_node);
963                 gl_view_set_default_text_color   (this->priv->view,
964                                                   gl_prefs->default_text_color);
965         }
966         else
967         {
968                 gl_view_set_selection_text_color (this->priv->view,
969                                                   text_color_node);
970                 gl_view_set_default_text_color   (this->priv->view,
971                                                   text_color_node->color);
972         }
973
974         gl_color_node_free (&text_color_node);
975         
976         gl_debug (DEBUG_PROPERTY_BAR, "END");
977
978         this->priv->stop_signals = FALSE;
979 }
980
981
982 /*--------------------------------------------------------------------------*/
983 /* PRIVATE.  Fill color combo changed.                                      */
984 /*--------------------------------------------------------------------------*/
985 static void
986 fill_color_changed_cb (glColorCombo         *cc,
987                        guint                 color,
988                        gboolean              is_default,
989                        glUIPropertyBar      *this)
990 {
991         glColorNode *fill_color_node;
992
993         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
994
995         if (this->priv->stop_signals) return;
996         this->priv->stop_signals = TRUE;
997
998         gl_debug (DEBUG_PROPERTY_BAR, "START");
999
1000         fill_color_node = gl_color_node_new_default ();
1001
1002         fill_color_node->color = color;
1003
1004         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
1005                   color, is_default);
1006
1007         if (is_default)
1008         {
1009
1010                 fill_color_node->color = GL_COLOR_NONE;
1011                 gl_view_set_selection_fill_color (this->priv->view,
1012                                                   fill_color_node);
1013                 gl_view_set_default_fill_color   (this->priv->view,
1014                                                   fill_color_node->color);
1015         }
1016         else
1017         {
1018                 gl_view_set_selection_fill_color (this->priv->view,
1019                                                   fill_color_node);
1020                 gl_view_set_default_fill_color   (this->priv->view,
1021                                                   fill_color_node->color);
1022         }
1023         gl_color_node_free (&fill_color_node);
1024         
1025         gl_debug (DEBUG_PROPERTY_BAR, "END");
1026
1027         this->priv->stop_signals = FALSE;
1028 }
1029
1030
1031 /*--------------------------------------------------------------------------*/
1032 /* PRIVATE.  Line color combo changed.                                      */
1033 /*--------------------------------------------------------------------------*/
1034 static void
1035 line_color_changed_cb (glColorCombo         *cc,
1036                        guint                 color,
1037                        gboolean              is_default,
1038                        glUIPropertyBar      *this)
1039 {
1040         glColorNode *line_color_node;
1041
1042         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
1043
1044         if (this->priv->stop_signals) return;
1045         this->priv->stop_signals = TRUE;
1046
1047         gl_debug (DEBUG_PROPERTY_BAR, "START");
1048
1049         line_color_node = gl_color_node_new_default ();
1050         line_color_node->color = color;
1051
1052         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
1053                   color, is_default);
1054
1055         if (is_default)
1056         {
1057                 line_color_node->color = GL_COLOR_NONE;
1058                 gl_view_set_selection_line_color (this->priv->view,
1059                                                   line_color_node);
1060                 gl_view_set_default_line_color   (this->priv->view,
1061                                                   line_color_node->color);
1062         }
1063         else
1064         {
1065                 gl_view_set_selection_line_color (this->priv->view,
1066                                                   line_color_node);
1067                 gl_view_set_default_line_color   (this->priv->view,
1068                                                   line_color_node->color);
1069         }
1070         gl_color_node_free (&line_color_node);
1071
1072         gl_debug (DEBUG_PROPERTY_BAR, "END");
1073
1074         this->priv->stop_signals = FALSE;
1075 }
1076
1077
1078 /*--------------------------------------------------------------------------*/
1079 /* PRIVATE.  Line width spin button changed.                                */
1080 /*--------------------------------------------------------------------------*/
1081 static void
1082 line_width_changed_cb (GtkSpinButton        *spin,
1083                        glUIPropertyBar      *this)
1084 {
1085         gdouble line_width;
1086
1087         if (this->priv->stop_signals) return;
1088         this->priv->stop_signals = TRUE;
1089
1090         gl_debug (DEBUG_PROPERTY_BAR, "START");
1091
1092         if (this->priv->view)
1093         {
1094                 line_width = gtk_spin_button_get_value (spin);
1095
1096                 gl_view_set_selection_line_width (this->priv->view,
1097                                                   line_width);
1098                 gl_view_set_default_line_width   (this->priv->view,
1099                                                   line_width);
1100         }
1101
1102         gl_debug (DEBUG_PROPERTY_BAR, "END");
1103
1104         this->priv->stop_signals = FALSE;
1105 }
1106
1107
1108 /*---------------------------------------------------------------------------*/
1109 /* PRIVATE.  Font bold toggled callback.                                     */
1110 /*---------------------------------------------------------------------------*/
1111 static void
1112 font_bold_toggled_cb (GtkToggleToolButton  *toggle,
1113                       glUIPropertyBar      *this)
1114 {
1115         gboolean        state;
1116         PangoWeight     weight;
1117
1118
1119         if (this->priv->stop_signals) return;
1120         this->priv->stop_signals = TRUE;
1121
1122         gl_debug (DEBUG_PROPERTY_BAR, "START");
1123
1124         state = gtk_toggle_tool_button_get_active (toggle);
1125
1126         weight = state ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
1127
1128         gl_view_set_selection_font_weight (this->priv->view, weight);
1129         gl_view_set_default_font_weight   (this->priv->view, weight);
1130
1131         gl_debug (DEBUG_PROPERTY_BAR, "END");
1132
1133         this->priv->stop_signals = FALSE;
1134 }
1135                                                   
1136
1137 /*---------------------------------------------------------------------------*/
1138 /* PRIVATE.  Font italic toggled callback.                                   */
1139 /*---------------------------------------------------------------------------*/
1140 static void
1141 font_italic_toggled_cb (GtkToggleToolButton  *toggle,
1142                         glUIPropertyBar      *this)
1143 {
1144         gboolean state;
1145
1146         if (this->priv->stop_signals) return;
1147         this->priv->stop_signals = TRUE;
1148
1149         gl_debug (DEBUG_PROPERTY_BAR, "START");
1150
1151         state = gtk_toggle_tool_button_get_active (toggle);
1152
1153         gl_view_set_selection_font_italic_flag (this->priv->view, state);
1154         gl_view_set_default_font_italic_flag   (this->priv->view, state);
1155
1156         gl_debug (DEBUG_PROPERTY_BAR, "END");
1157
1158         this->priv->stop_signals = FALSE;
1159 }
1160                                                   
1161
1162 /*---------------------------------------------------------------------------*/
1163 /* PRIVATE.  Text align toggled callback.                                    */
1164 /*---------------------------------------------------------------------------*/
1165 static void
1166 text_align_toggled_cb (GtkToggleToolButton  *toggle,
1167                        glUIPropertyBar      *this)
1168 {
1169         if (this->priv->stop_signals) return;
1170         this->priv->stop_signals = TRUE;
1171
1172         gl_debug (DEBUG_PROPERTY_BAR, "START");
1173
1174         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio)))
1175         {               
1176                 gl_view_set_selection_text_alignment (this->priv->view,
1177                                                       PANGO_ALIGN_LEFT);
1178                 gl_view_set_default_text_alignment   (this->priv->view,
1179                                                       PANGO_ALIGN_LEFT);
1180         }
1181
1182         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio)))
1183         {               
1184                 gl_view_set_selection_text_alignment (this->priv->view,
1185                                                       PANGO_ALIGN_CENTER);
1186                 gl_view_set_default_text_alignment   (this->priv->view,
1187                                                       PANGO_ALIGN_CENTER);
1188         }
1189
1190         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio)))
1191         {
1192                 gl_view_set_selection_text_alignment (this->priv->view,
1193                                                       PANGO_ALIGN_RIGHT);
1194                 gl_view_set_default_text_alignment   (this->priv->view,
1195                                                       PANGO_ALIGN_RIGHT);
1196         }
1197
1198         gl_debug (DEBUG_PROPERTY_BAR, "END");
1199
1200         this->priv->stop_signals = FALSE;
1201 }
1202
1203
1204 /*---------------------------------------------------------------------------*/
1205 /* PRIVATE.  Set sensitivity of doc controls.                                */
1206 /*---------------------------------------------------------------------------*/
1207 static void
1208 set_doc_items_sensitive (glUIPropertyBar      *this,
1209                          gboolean              state)
1210 {
1211         gtk_widget_set_sensitive (this->priv->font_family_combo,       state);
1212         gtk_widget_set_sensitive (this->priv->font_size_spin,          state);
1213         gtk_widget_set_sensitive (this->priv->font_bold_toggle,        state);
1214         gtk_widget_set_sensitive (this->priv->font_italic_toggle,      state);
1215         gtk_widget_set_sensitive (this->priv->text_align_left_radio,   state);
1216         gtk_widget_set_sensitive (this->priv->text_align_center_radio, state);
1217         gtk_widget_set_sensitive (this->priv->text_align_right_radio,  state);
1218         gtk_widget_set_sensitive (this->priv->text_color_combo,        state);
1219         gtk_widget_set_sensitive (this->priv->fill_color_combo,        state);
1220         gtk_widget_set_sensitive (this->priv->line_color_combo,        state);
1221         gtk_widget_set_sensitive (this->priv->line_width_spin,         state);
1222 }
1223
1224
1225 /*---------------------------------------------------------------------------*/
1226 /* PRIVATE.  Set sensitivity of text related controls.                       */
1227 /*---------------------------------------------------------------------------*/
1228 static void
1229 set_text_items_sensitive (glUIPropertyBar      *this,
1230                           gboolean              state)
1231 {
1232         gtk_widget_set_sensitive (this->priv->font_family_combo,       state);
1233         gtk_widget_set_sensitive (this->priv->font_size_spin,          state);
1234         gtk_widget_set_sensitive (this->priv->font_bold_toggle,        state);
1235         gtk_widget_set_sensitive (this->priv->font_italic_toggle,      state);
1236         gtk_widget_set_sensitive (this->priv->text_align_left_radio,   state);
1237         gtk_widget_set_sensitive (this->priv->text_align_center_radio, state);
1238         gtk_widget_set_sensitive (this->priv->text_align_right_radio,  state);
1239         gtk_widget_set_sensitive (this->priv->text_color_combo,        state);
1240 }
1241
1242
1243 /*---------------------------------------------------------------------------*/
1244 /* PRIVATE.  Set sensitivity of fill related controls.                       */
1245 /*---------------------------------------------------------------------------*/
1246 static void
1247 set_fill_items_sensitive (glUIPropertyBar      *this,
1248                           gboolean              state)
1249 {
1250         gtk_widget_set_sensitive (this->priv->fill_color_combo,        state);
1251 }
1252
1253
1254 /*---------------------------------------------------------------------------*/
1255 /* PRIVATE.  Set sensitivity of line color related controls.                 */
1256 /*---------------------------------------------------------------------------*/
1257 static void
1258 set_line_color_items_sensitive (glUIPropertyBar      *this,
1259                                 gboolean              state)
1260 {
1261         gtk_widget_set_sensitive (this->priv->line_color_combo,        state);
1262 }
1263
1264
1265 /*---------------------------------------------------------------------------*/
1266 /* PRIVATE.  Set sensitivity of line width related controls.                 */
1267 /*---------------------------------------------------------------------------*/
1268 static void
1269 set_line_width_items_sensitive (glUIPropertyBar      *this,
1270                                 gboolean              state)
1271 {
1272         gtk_widget_set_sensitive (this->priv->line_width_spin,         state);
1273 }
1274
1275