]> git.sur5r.net Git - glabels/blob - src/ui-property-bar.c
Organized master branch to be top-level directory for glabels, instead of
[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 "stock-pixmaps/stockpixbufs.h"
33 #include "prefs.h"
34 #include "color.h"
35
36 #include "debug.h"
37
38
39 /*===========================================================================*/
40 /* Private macros and constants.                                             */
41 /*===========================================================================*/
42
43
44 /*===========================================================================*/
45 /* Private data types                                                        */
46 /*===========================================================================*/
47
48 struct _glUIPropertyBarPrivate {
49
50         glView     *view;
51
52         GtkBuilder *builder;
53
54         GtkWidget  *tool_bar;
55
56         /* Font selection */
57         GtkWidget  *font_family_eventbox;
58         GtkWidget  *font_family_combo;
59         GtkWidget  *font_size_spin;
60         GtkWidget  *font_bold_toggle;
61         GtkWidget  *font_italic_toggle;
62
63         /* Text alignemnt radios */
64         GtkWidget  *text_align_left_radio;
65         GtkWidget  *text_align_center_radio;
66         GtkWidget  *text_align_right_radio;
67
68         /* Color combos */
69         GtkWidget  *text_color_eventbox;
70         GtkWidget  *text_color_button;
71         GtkWidget  *fill_color_eventbox;
72         GtkWidget  *fill_color_button;
73         GtkWidget  *line_color_eventbox;
74         GtkWidget  *line_color_button;
75
76         /* Line width */
77         GtkWidget  *line_width_spin;
78
79         /* Prevent recursion */
80         gboolean    stop_signals;
81 };
82
83
84 /*===========================================================================*/
85 /* Private globals                                                           */
86 /*===========================================================================*/
87
88
89 /*===========================================================================*/
90 /* Local function prototypes                                                 */
91 /*===========================================================================*/
92
93 static void     gl_ui_property_bar_finalize      (GObject              *object);
94
95 static void     gl_ui_property_bar_construct     (glUIPropertyBar      *this);
96
97 static void     selection_changed_cb             (glUIPropertyBar      *this);
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->view)
191         {
192                 g_object_unref (G_OBJECT(this->priv->view));
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         GtkBuilder    *builder;
233         static gchar  *object_ids[] = { "property_toolbar",
234                                         "adjustment1", "adjustment2",
235                                         NULL };
236         GError        *error = NULL;
237         GdkPixbuf     *pixbuf = NULL;
238
239         gl_debug (DEBUG_PROPERTY_BAR, "START");
240
241         this->priv->stop_signals = TRUE;
242
243         builder = gtk_builder_new ();
244         gtk_builder_add_objects_from_file (builder,
245                                            GLABELS_BUILDER_DIR "property-bar.builder",
246                                            object_ids,
247                                            &error);
248         if (error) {
249                 g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
250                 g_error_free (error);
251                 return;
252         }
253
254         gl_builder_util_get_widgets (builder,
255                                      "property_toolbar",        &this->priv->tool_bar,
256                                      "font_family_eventbox",    &this->priv->font_family_eventbox,
257                                      "font_size_spin",          &this->priv->font_size_spin,
258                                      "font_bold_toggle",        &this->priv->font_bold_toggle,
259                                      "font_italic_toggle",      &this->priv->font_italic_toggle,
260                                      "text_align_left_radio",   &this->priv->text_align_left_radio,
261                                      "text_align_center_radio", &this->priv->text_align_center_radio,
262                                      "text_align_right_radio",  &this->priv->text_align_right_radio,
263                                      "text_color_eventbox",     &this->priv->text_color_eventbox,
264                                      "fill_color_eventbox",     &this->priv->fill_color_eventbox,
265                                      "line_color_eventbox",     &this->priv->line_color_eventbox,
266                                      "line_width_spin",         &this->priv->line_width_spin,
267                                      NULL);
268
269         gtk_container_add (GTK_CONTAINER (this), this->priv->tool_bar);
270
271         this->priv->font_family_combo = gl_font_combo_new (gl_prefs->default_font_family);
272         gtk_container_add (GTK_CONTAINER (this->priv->font_family_eventbox),
273                            this->priv->font_family_combo);
274
275         pixbuf = gdk_pixbuf_new_from_inline (-1, stock_text_24, FALSE, NULL);
276         this->priv->text_color_button =
277                 gl_color_combo_button_new (pixbuf,
278                                            _("Default"),
279                                            GL_COLOR_TEXT_DEFAULT,
280                                            gl_prefs->default_text_color);
281         gl_color_combo_button_set_relief (GL_COLOR_COMBO_BUTTON(this->priv->text_color_button),
282                                           GTK_RELIEF_NONE);
283         g_object_unref (G_OBJECT (pixbuf));
284         gtk_container_add (GTK_CONTAINER (this->priv->text_color_eventbox),
285                            this->priv->text_color_button);
286
287         pixbuf = gdk_pixbuf_new_from_inline (-1, stock_bucket_fill_24, FALSE, NULL);
288         this->priv->fill_color_button =
289                 gl_color_combo_button_new (pixbuf,
290                                            _("No Fill"),
291                                            GL_COLOR_NO_FILL,
292                                            gl_prefs->default_fill_color);
293         gl_color_combo_button_set_relief (GL_COLOR_COMBO_BUTTON(this->priv->fill_color_button),
294                                           GTK_RELIEF_NONE);
295         g_object_unref (G_OBJECT (pixbuf));
296         gtk_container_add (GTK_CONTAINER (this->priv->fill_color_eventbox),
297                            this->priv->fill_color_button);
298
299         pixbuf = gdk_pixbuf_new_from_inline (-1, stock_pencil_24, FALSE, NULL);
300         this->priv->line_color_button =
301                 gl_color_combo_button_new (pixbuf,
302                                            _("No Line"),
303                                            GL_COLOR_NO_LINE,
304                                            gl_prefs->default_line_color);
305         gl_color_combo_button_set_relief (GL_COLOR_COMBO_BUTTON(this->priv->line_color_button),
306                                           GTK_RELIEF_NONE);
307         g_object_unref (G_OBJECT (pixbuf));
308         gtk_container_add (GTK_CONTAINER (this->priv->line_color_eventbox),
309                            this->priv->line_color_button);
310
311         /* Save reference to gui tree so we don't lose tooltips */
312         this->priv->builder = builder;
313
314         set_doc_items_sensitive (this, FALSE);
315
316         /* Font family entry widget */
317         g_signal_connect (G_OBJECT (this->priv->font_family_combo),
318                           "changed", G_CALLBACK (font_family_changed_cb), this);
319
320         /* Font size entry widget */
321         gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->font_size_spin),
322                                    gl_prefs->default_font_size);
323
324         g_signal_connect (G_OBJECT (this->priv->font_size_spin),
325                           "changed", G_CALLBACK (font_size_changed_cb), this);
326
327
328         /* Bold and Italic toggles */
329         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
330                                            (gl_prefs->default_font_weight == PANGO_WEIGHT_BOLD));
331         g_signal_connect (G_OBJECT (this->priv->font_bold_toggle),
332                           "toggled", G_CALLBACK (font_bold_toggled_cb), this);
333         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
334                                            gl_prefs->default_font_italic_flag);
335         g_signal_connect (G_OBJECT (this->priv->font_italic_toggle),
336                           "toggled", G_CALLBACK (font_italic_toggled_cb), this);
337
338
339         /* Text alignment radio group */
340         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
341                                            (gl_prefs->default_text_alignment == PANGO_ALIGN_LEFT));
342         g_signal_connect (G_OBJECT (this->priv->text_align_left_radio),
343                           "toggled", G_CALLBACK (text_align_toggled_cb), this);
344         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
345                                            (gl_prefs->default_text_alignment == PANGO_ALIGN_CENTER));
346         g_signal_connect (G_OBJECT (this->priv->text_align_center_radio),
347                           "toggled", G_CALLBACK (text_align_toggled_cb), this);
348         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
349                                            (gl_prefs->default_text_alignment == PANGO_ALIGN_RIGHT));
350         g_signal_connect (G_OBJECT (this->priv->text_align_right_radio),
351                           "toggled", G_CALLBACK (text_align_toggled_cb), this);
352
353         /* Text color widget */
354         gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON (this->priv->text_color_button),
355                                          gl_prefs->default_text_color);
356         g_signal_connect (G_OBJECT (this->priv->text_color_button),
357                           "color_changed",
358                           G_CALLBACK (text_color_changed_cb), this);
359
360         /* Fill color widget */
361         gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON (this->priv->fill_color_button),
362                                          gl_prefs->default_fill_color);
363         g_signal_connect (G_OBJECT (this->priv->fill_color_button),
364                           "color_changed",
365                           G_CALLBACK (fill_color_changed_cb), this);
366
367         /* Line color widget */
368         gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON (this->priv->line_color_button),
369                                          gl_prefs->default_line_color);
370         g_signal_connect (G_OBJECT (this->priv->line_color_button),
371                           "color_changed",
372                           G_CALLBACK (line_color_changed_cb), this);
373
374         /* Line width entry widget */
375         g_signal_connect (G_OBJECT (this->priv->line_width_spin),
376                           "changed",
377                           G_CALLBACK (line_width_changed_cb), this);
378
379         this->priv->stop_signals = FALSE;
380
381         gl_debug (DEBUG_PROPERTY_BAR, "END");
382 }
383
384
385 /****************************************************************************/
386 /* Fill widgets with default values.                                        */
387 /****************************************************************************/
388 static void
389 reset_to_default_properties (glView          *view,
390                              glUIPropertyBar *this)
391 {
392
393         gl_font_combo_set_family (GL_FONT_COMBO (this->priv->font_family_combo),
394                                   view->default_font_family);
395
396         gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->font_size_spin),
397                                    view->default_font_size);
398
399         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
400                                            (view->default_font_weight == PANGO_WEIGHT_BOLD));
401         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
402                                            view->default_font_italic_flag);
403
404         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
405                                            (view->default_text_alignment == PANGO_ALIGN_LEFT));
406         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
407                                            (view->default_text_alignment == PANGO_ALIGN_CENTER));
408         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
409                                            (view->default_text_alignment == PANGO_ALIGN_RIGHT));
410
411         gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON(this->priv->text_color_button),
412                                          view->default_text_color);
413
414         gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON(this->priv->fill_color_button),
415                                          view->default_fill_color);
416
417         gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON(this->priv->line_color_button),
418                                          view->default_line_color);
419
420         gtk_spin_button_set_value (GTK_SPIN_BUTTON(this->priv->line_width_spin),
421                                    view->default_line_width);
422 }
423
424
425 /****************************************************************************/
426 /* Set view associated with property_bar.                                   */
427 /****************************************************************************/
428 void
429 gl_ui_property_bar_set_view (glUIPropertyBar *this,
430                              glView          *view)
431 {
432         glLabel   *label;
433
434         gl_debug (DEBUG_PROPERTY_BAR, "START");
435
436         g_return_if_fail (view && GL_IS_VIEW (view));
437         label = view->label;
438         g_return_if_fail (label && GL_IS_LABEL (label));
439
440         set_doc_items_sensitive (this, TRUE);
441
442         this->priv->view = GL_VIEW (g_object_ref (G_OBJECT (view)));
443
444         reset_to_default_properties (view, this);
445
446         g_signal_connect_swapped (G_OBJECT(view), "selection_changed",
447                                   G_CALLBACK(selection_changed_cb), this);
448
449         g_signal_connect_swapped (G_OBJECT(view->label), "changed",
450                                   G_CALLBACK(selection_changed_cb), this);
451
452         gl_debug (DEBUG_PROPERTY_BAR, "END");
453 }
454
455
456 /*---------------------------------------------------------------------------*/
457 /* PRIVATE.  View "selection state changed" callback.                        */
458 /*---------------------------------------------------------------------------*/
459 static void
460 update_text_properties (glView *view,
461                         glUIPropertyBar *this)
462 {
463         gboolean        can_text, is_first_object;
464         gboolean        is_same_font_family, is_same_font_size;
465         gboolean        is_same_text_color, is_same_is_italic;
466         gboolean        is_same_is_bold, is_same_align;
467         GList          *p;
468         glLabelObject  *object;
469         gchar          *selection_font_family, *font_family;
470         gdouble         selection_font_size, font_size;
471         guint           selection_text_color, text_color;
472         glColorNode    *text_color_node;
473         gboolean        selection_is_italic, is_italic;
474         gboolean        selection_is_bold, is_bold;
475         PangoAlignment  selection_align, align;
476
477         can_text = gl_view_can_selection_text (view);
478         set_text_items_sensitive (this, can_text);
479
480         if (!can_text) 
481                 return;
482
483         is_same_is_italic =
484         is_same_is_bold =
485         is_same_align =
486         is_same_text_color =
487         is_same_font_size =
488         is_same_font_family = TRUE;
489         selection_font_family = NULL;
490         selection_font_size = -1;
491         selection_align = PANGO_ALIGN_LEFT;
492         selection_is_italic = TRUE;
493         selection_is_bold = TRUE;
494         selection_text_color = 0;
495         
496         is_first_object = TRUE;
497         
498         for (p = view->selected_object_list; p != NULL; p = p->next)
499         {
500
501                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
502                 if (!gl_label_object_can_text (object)) 
503                         continue;
504
505                 font_family = gl_label_object_get_font_family (object);
506                 if (font_family != NULL)
507                 {
508                         if (selection_font_family == NULL)
509                         {
510                                 selection_font_family = g_strdup (font_family);
511                         }
512                         else 
513                         {
514                                 if (strcmp (font_family, selection_font_family) != 0)
515                                 {
516                                         is_same_font_family = FALSE;
517                                 }
518                         }
519                         g_free (font_family);
520                 }       
521
522                 font_size = gl_label_object_get_font_size (object);
523                 
524                 text_color_node = gl_label_object_get_text_color (object);
525                 if (text_color_node->field_flag)
526                 {
527                         /* If a merge field is set we use the default color for merged color*/
528                         text_color = GL_COLOR_MERGE_DEFAULT;
529                         
530                 }
531                 else
532                 {
533                         text_color = text_color_node->color;
534                 }
535                 gl_color_node_free (&text_color_node);
536                 
537                 is_italic = gl_label_object_get_font_italic_flag (object);
538                 is_bold = gl_label_object_get_font_weight (object) == PANGO_WEIGHT_BOLD;
539                 align = gl_label_object_get_text_alignment (object);
540
541                 if (is_first_object)
542                 {
543                         selection_font_size = font_size;
544                         selection_text_color = text_color;
545                         selection_is_italic = is_italic;
546                         selection_is_bold = is_bold;
547                         selection_align = align;
548                 }
549                 else
550                 {
551                         if (font_size != selection_font_size) 
552                                 is_same_font_size = FALSE;
553                         if (text_color != selection_text_color)
554                                 is_same_text_color = FALSE;
555                         if (is_italic != selection_is_italic)
556                                 is_same_is_italic = FALSE;
557                         if (is_bold != selection_is_bold)
558                                 is_same_is_bold = FALSE;
559                         if (align != selection_align)
560                                 is_same_align = FALSE;
561                 }
562                 is_first_object = FALSE;
563         }
564
565         if (is_same_font_family && (selection_font_family != NULL)) 
566                 gl_debug (DEBUG_PROPERTY_BAR, "same font family = %s", 
567                           selection_font_family);
568         gl_font_combo_set_family (GL_FONT_COMBO (this->priv->font_family_combo),
569                                   is_same_font_family?selection_font_family:"");
570         g_free (selection_font_family);
571
572         if (is_same_font_size)
573         {
574                 gl_debug (DEBUG_PROPERTY_BAR, "same font size = %g", 
575                           selection_font_size);
576                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (this->priv->font_size_spin),
577                                            selection_font_size);
578         }
579         else
580         {
581                 gtk_entry_set_text (GTK_ENTRY (this->priv->font_size_spin), "");
582         }
583
584         if (is_same_text_color)
585         {
586                 gl_debug (DEBUG_PROPERTY_BAR, "same text color = %08x", selection_text_color);
587                 gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON (this->priv->text_color_button),
588                                                  selection_text_color);
589         }
590
591         if (is_same_is_italic)
592         {
593                 gl_debug (DEBUG_PROPERTY_BAR, "same italic flag = %d", 
594                           selection_is_italic);
595         }
596         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_italic_toggle),
597                                            selection_is_italic && is_same_is_italic);
598
599         if (is_same_is_bold)
600         {
601                 gl_debug (DEBUG_PROPERTY_BAR, "same bold flag = %d",
602                           selection_is_bold);
603         }
604         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->font_bold_toggle),
605                                            selection_is_bold && is_same_is_bold);
606
607         if (is_same_align) 
608                 gl_debug (DEBUG_PROPERTY_BAR, "same align");
609         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio),
610                                            (selection_align == PANGO_ALIGN_LEFT) &&
611                                            is_same_align);
612         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio),
613                                            (selection_align == PANGO_ALIGN_CENTER) &&
614                                            is_same_align);
615         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio),
616                                            (selection_align == PANGO_ALIGN_RIGHT) &&
617                                            is_same_align);
618 }
619
620
621 static void
622 update_fill_color (glView *view,
623                    glUIPropertyBar *this)
624 {
625         gboolean can, is_first_object;
626         gboolean is_same_fill_color;
627         GList *p;
628         glLabelObject *object;
629         guint selection_fill_color, fill_color;
630         glColorNode *fill_color_node;
631
632         can = gl_view_can_selection_fill (view);
633         set_fill_items_sensitive (this, can);
634
635         if (!can) 
636                 return;
637
638         is_same_fill_color = TRUE;
639         is_first_object = TRUE;
640         selection_fill_color = 0;
641         
642         for (p = view->selected_object_list; p != NULL; p = p->next)
643         {
644
645                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
646                 if (!gl_label_object_can_fill (object)) 
647                         continue;
648
649                 fill_color_node = gl_label_object_get_fill_color (object);
650                 if (fill_color_node->field_flag)
651                 {
652                         /* If a merge field is set we use the default color for merged color*/
653                         fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
654                         
655                 }
656                 else
657                 {
658                         fill_color = fill_color_node->color;
659                 }
660                 gl_color_node_free (&fill_color_node);
661
662                 if (is_first_object)
663                 {
664                         selection_fill_color = fill_color;
665                 }
666                 else
667                 {
668                         if (fill_color != selection_fill_color)
669                         {
670                                 is_same_fill_color = FALSE;
671                         }
672                 }
673                 is_first_object = FALSE;
674         }
675
676         if (is_same_fill_color)
677         {
678                 gl_debug (DEBUG_PROPERTY_BAR, "same fill color = %08x", selection_fill_color);
679                 gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON (this->priv->fill_color_button),
680                                                  selection_fill_color);
681         }
682 }
683
684
685 static void
686 update_line_color (glView *view,
687                    glUIPropertyBar *this)
688 {
689         gboolean can, is_first_object;
690         gboolean is_same_line_color;
691         GList *p;
692         glLabelObject *object;
693         guint selection_line_color, line_color;
694         glColorNode *line_color_node;
695
696         can = gl_view_can_selection_line_color (view);
697         set_line_color_items_sensitive (this, can);
698
699         if (!can) 
700                 return;
701
702         is_same_line_color = TRUE;
703         is_first_object = TRUE;
704         selection_line_color = 0;
705         
706         for (p = view->selected_object_list; p != NULL; p = p->next)
707         {
708
709                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
710                 if (!gl_label_object_can_line_color (object)) 
711                         continue;
712
713                 line_color_node = gl_label_object_get_line_color (object);
714                 if (line_color_node->field_flag)
715                 {
716                         /* If a merge field is set we use the default color for merged color*/
717                         line_color = GL_COLOR_MERGE_DEFAULT;
718                         
719                 }
720                 else
721                 {
722                         line_color = line_color_node->color;
723                 }
724                 gl_color_node_free (&line_color_node);
725
726                 if (is_first_object)
727                 {
728                         selection_line_color = line_color;
729                 }
730                 else
731                 {
732                         if (line_color != selection_line_color)
733                         {
734                                 is_same_line_color = FALSE;
735                         }
736                 }
737                 is_first_object = FALSE;
738         }
739
740         if (is_same_line_color)
741         {
742                 gl_debug (DEBUG_PROPERTY_BAR, "same line color = %08x", selection_line_color);
743                 gl_color_combo_button_set_color (GL_COLOR_COMBO_BUTTON (this->priv->line_color_button),
744                                                  selection_line_color);
745         }
746 }
747
748
749 static void
750 update_line_width (glView *view,
751                    glUIPropertyBar *this)
752 {
753         gboolean can, is_first_object;
754         gboolean is_same_line_width;
755         GList *p;
756         glLabelObject *object;
757         gdouble selection_line_width, line_width;
758
759         can = gl_view_can_selection_line_width (view);
760         set_line_width_items_sensitive (this, can);
761
762         if (!can) 
763                 return;
764
765         is_same_line_width = TRUE;
766         is_first_object = TRUE;
767         selection_line_width = 0;
768         
769         for (p = view->selected_object_list; p != NULL; p = p->next)
770         {
771
772                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
773                 if (!gl_label_object_can_line_width (object)) 
774                         continue;
775
776                 line_width = gl_label_object_get_line_width (object);
777
778                 if (is_first_object)
779                 {
780                         selection_line_width = line_width;
781                 }
782                 else
783                 {
784                         if (line_width != selection_line_width)
785                         {
786                                 is_same_line_width = FALSE;
787                         }
788                 }
789                 is_first_object = FALSE;
790         }
791
792         if (is_same_line_width)
793         {
794                 gl_debug (DEBUG_PROPERTY_BAR, "same line width = %g", selection_line_width);
795                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (this->priv->line_width_spin),
796                                            selection_line_width);
797         }
798         else
799         {
800                 gtk_entry_set_text (GTK_ENTRY (this->priv->line_width_spin), "");
801         }
802 }
803
804
805 static void 
806 selection_changed_cb (glUIPropertyBar *this)
807 {
808         glView *view = this->priv->view;
809         
810         g_return_if_fail (view && GL_IS_VIEW (view));
811         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
812
813         if (this->priv->stop_signals) return;
814         this->priv->stop_signals = TRUE;
815
816         gl_debug (DEBUG_PROPERTY_BAR, "START");
817
818         if (gl_view_is_selection_empty (view))
819         {
820                 /* No selection: make all controls active. */
821                 reset_to_default_properties (view, this);
822                 set_doc_items_sensitive (this, TRUE);
823         }
824         else
825         {
826                 update_text_properties (view, this);
827                 update_fill_color (view, this);
828                 update_line_color (view, this);
829                 update_line_width (view, this);
830         }
831
832         gl_debug (DEBUG_PROPERTY_BAR, "END");
833
834         this->priv->stop_signals = FALSE;
835 }
836
837
838 /*--------------------------------------------------------------------------*/
839 /* PRIVATE.  Font family entry changed.                                     */
840 /*--------------------------------------------------------------------------*/
841 static void
842 font_family_changed_cb (GtkComboBox     *combo,
843                         glUIPropertyBar *this)
844 {
845         gchar *font_family;
846
847         if (this->priv->stop_signals) return;
848         this->priv->stop_signals = TRUE;
849
850         gl_debug (DEBUG_PROPERTY_BAR, "START");
851
852         font_family = gl_font_combo_get_family (GL_FONT_COMBO (combo));
853         if ( strlen(font_family) )
854         {
855                 gl_view_set_selection_font_family (this->priv->view,
856                                                    font_family);
857                 gl_view_set_default_font_family   (this->priv->view,
858                                                    font_family);
859         }
860         g_free (font_family);
861
862         gl_debug (DEBUG_PROPERTY_BAR, "END");
863
864         this->priv->stop_signals = FALSE;
865 }
866
867
868 /*--------------------------------------------------------------------------*/
869 /* PRIVATE.  Font size spin button changed.                                 */
870 /*--------------------------------------------------------------------------*/
871 static void
872 font_size_changed_cb (GtkSpinButton        *spin,
873                       glUIPropertyBar      *this)
874 {
875         gdouble font_size;
876
877         if (this->priv->stop_signals) return;
878         this->priv->stop_signals = TRUE;
879
880         gl_debug (DEBUG_PROPERTY_BAR, "START");
881
882         font_size = gtk_spin_button_get_value (spin);
883
884         gl_view_set_selection_font_size (this->priv->view,
885                                          font_size);
886         gl_view_set_default_font_size   (this->priv->view,
887                                          font_size);
888
889         gl_debug (DEBUG_PROPERTY_BAR, "END");
890
891         this->priv->stop_signals = FALSE;
892 }
893
894
895 /*--------------------------------------------------------------------------*/
896 /* PRIVATE.  Text color combo changed.                                      */
897 /*--------------------------------------------------------------------------*/
898 static void
899 text_color_changed_cb (glColorComboButton   *cc,
900                        guint                 color,
901                        gboolean              is_default,
902                        glUIPropertyBar      *this)
903 {
904         glColorNode *text_color_node;
905
906         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
907
908         if (this->priv->stop_signals) return;
909         this->priv->stop_signals = TRUE;
910
911         gl_debug (DEBUG_PROPERTY_BAR, "START");
912
913         text_color_node = gl_color_node_new_default ();
914         text_color_node->color = color;
915         
916         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
917                   color, is_default);
918
919         if (is_default)
920         {
921                 text_color_node->color = gl_prefs->default_text_color;
922                 gl_view_set_selection_text_color (this->priv->view,
923                                                   text_color_node);
924                 gl_view_set_default_text_color   (this->priv->view,
925                                                   gl_prefs->default_text_color);
926         }
927         else
928         {
929                 gl_view_set_selection_text_color (this->priv->view,
930                                                   text_color_node);
931                 gl_view_set_default_text_color   (this->priv->view,
932                                                   text_color_node->color);
933         }
934
935         gl_color_node_free (&text_color_node);
936         
937         gl_debug (DEBUG_PROPERTY_BAR, "END");
938
939         this->priv->stop_signals = FALSE;
940 }
941
942
943 /*--------------------------------------------------------------------------*/
944 /* PRIVATE.  Fill color combo changed.                                      */
945 /*--------------------------------------------------------------------------*/
946 static void
947 fill_color_changed_cb (glColorComboButton   *cc,
948                        guint                 color,
949                        gboolean              is_default,
950                        glUIPropertyBar      *this)
951 {
952         glColorNode *fill_color_node;
953
954         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
955
956         if (this->priv->stop_signals) return;
957         this->priv->stop_signals = TRUE;
958
959         gl_debug (DEBUG_PROPERTY_BAR, "START");
960
961         fill_color_node = gl_color_node_new_default ();
962
963         fill_color_node->color = color;
964
965         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
966                   color, is_default);
967
968         if (is_default)
969         {
970
971                 fill_color_node->color = GL_COLOR_NONE;
972                 gl_view_set_selection_fill_color (this->priv->view,
973                                                   fill_color_node);
974                 gl_view_set_default_fill_color   (this->priv->view,
975                                                   fill_color_node->color);
976         }
977         else
978         {
979                 gl_view_set_selection_fill_color (this->priv->view,
980                                                   fill_color_node);
981                 gl_view_set_default_fill_color   (this->priv->view,
982                                                   fill_color_node->color);
983         }
984         gl_color_node_free (&fill_color_node);
985         
986         gl_debug (DEBUG_PROPERTY_BAR, "END");
987
988         this->priv->stop_signals = FALSE;
989 }
990
991
992 /*--------------------------------------------------------------------------*/
993 /* PRIVATE.  Line color combo changed.                                      */
994 /*--------------------------------------------------------------------------*/
995 static void
996 line_color_changed_cb (glColorComboButton   *cc,
997                        guint                 color,
998                        gboolean              is_default,
999                        glUIPropertyBar      *this)
1000 {
1001         glColorNode *line_color_node;
1002
1003         g_return_if_fail (this && GL_IS_UI_PROPERTY_BAR (this));
1004
1005         if (this->priv->stop_signals) return;
1006         this->priv->stop_signals = TRUE;
1007
1008         gl_debug (DEBUG_PROPERTY_BAR, "START");
1009
1010         line_color_node = gl_color_node_new_default ();
1011         line_color_node->color = color;
1012
1013         gl_debug (DEBUG_PROPERTY_BAR, "Color=%08x, Is_default=%d",
1014                   color, is_default);
1015
1016         if (is_default)
1017         {
1018                 line_color_node->color = GL_COLOR_NONE;
1019                 gl_view_set_selection_line_color (this->priv->view,
1020                                                   line_color_node);
1021                 gl_view_set_default_line_color   (this->priv->view,
1022                                                   line_color_node->color);
1023         }
1024         else
1025         {
1026                 gl_view_set_selection_line_color (this->priv->view,
1027                                                   line_color_node);
1028                 gl_view_set_default_line_color   (this->priv->view,
1029                                                   line_color_node->color);
1030         }
1031         gl_color_node_free (&line_color_node);
1032
1033         gl_debug (DEBUG_PROPERTY_BAR, "END");
1034
1035         this->priv->stop_signals = FALSE;
1036 }
1037
1038
1039 /*--------------------------------------------------------------------------*/
1040 /* PRIVATE.  Line width spin button changed.                                */
1041 /*--------------------------------------------------------------------------*/
1042 static void
1043 line_width_changed_cb (GtkSpinButton        *spin,
1044                        glUIPropertyBar      *this)
1045 {
1046         gdouble line_width;
1047
1048         if (this->priv->stop_signals) return;
1049         this->priv->stop_signals = TRUE;
1050
1051         gl_debug (DEBUG_PROPERTY_BAR, "START");
1052
1053         if (this->priv->view)
1054         {
1055                 line_width = gtk_spin_button_get_value (spin);
1056
1057                 gl_view_set_selection_line_width (this->priv->view,
1058                                                   line_width);
1059                 gl_view_set_default_line_width   (this->priv->view,
1060                                                   line_width);
1061         }
1062
1063         gl_debug (DEBUG_PROPERTY_BAR, "END");
1064
1065         this->priv->stop_signals = FALSE;
1066 }
1067
1068
1069 /*---------------------------------------------------------------------------*/
1070 /* PRIVATE.  Font bold toggled callback.                                     */
1071 /*---------------------------------------------------------------------------*/
1072 static void
1073 font_bold_toggled_cb (GtkToggleToolButton  *toggle,
1074                       glUIPropertyBar      *this)
1075 {
1076         gboolean        state;
1077         PangoWeight     weight;
1078
1079
1080         if (this->priv->stop_signals) return;
1081         this->priv->stop_signals = TRUE;
1082
1083         gl_debug (DEBUG_PROPERTY_BAR, "START");
1084
1085         state = gtk_toggle_tool_button_get_active (toggle);
1086
1087         weight = state ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
1088
1089         gl_view_set_selection_font_weight (this->priv->view, weight);
1090         gl_view_set_default_font_weight   (this->priv->view, weight);
1091
1092         gl_debug (DEBUG_PROPERTY_BAR, "END");
1093
1094         this->priv->stop_signals = FALSE;
1095 }
1096                                                   
1097
1098 /*---------------------------------------------------------------------------*/
1099 /* PRIVATE.  Font italic toggled callback.                                   */
1100 /*---------------------------------------------------------------------------*/
1101 static void
1102 font_italic_toggled_cb (GtkToggleToolButton  *toggle,
1103                         glUIPropertyBar      *this)
1104 {
1105         gboolean state;
1106
1107         if (this->priv->stop_signals) return;
1108         this->priv->stop_signals = TRUE;
1109
1110         gl_debug (DEBUG_PROPERTY_BAR, "START");
1111
1112         state = gtk_toggle_tool_button_get_active (toggle);
1113
1114         gl_view_set_selection_font_italic_flag (this->priv->view, state);
1115         gl_view_set_default_font_italic_flag   (this->priv->view, state);
1116
1117         gl_debug (DEBUG_PROPERTY_BAR, "END");
1118
1119         this->priv->stop_signals = FALSE;
1120 }
1121                                                   
1122
1123 /*---------------------------------------------------------------------------*/
1124 /* PRIVATE.  Text align toggled callback.                                    */
1125 /*---------------------------------------------------------------------------*/
1126 static void
1127 text_align_toggled_cb (GtkToggleToolButton  *toggle,
1128                        glUIPropertyBar      *this)
1129 {
1130         if (this->priv->stop_signals) return;
1131         this->priv->stop_signals = TRUE;
1132
1133         gl_debug (DEBUG_PROPERTY_BAR, "START");
1134
1135         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_left_radio)))
1136         {               
1137                 gl_view_set_selection_text_alignment (this->priv->view,
1138                                                       PANGO_ALIGN_LEFT);
1139                 gl_view_set_default_text_alignment   (this->priv->view,
1140                                                       PANGO_ALIGN_LEFT);
1141         }
1142
1143         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_center_radio)))
1144         {               
1145                 gl_view_set_selection_text_alignment (this->priv->view,
1146                                                       PANGO_ALIGN_CENTER);
1147                 gl_view_set_default_text_alignment   (this->priv->view,
1148                                                       PANGO_ALIGN_CENTER);
1149         }
1150
1151         if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (this->priv->text_align_right_radio)))
1152         {
1153                 gl_view_set_selection_text_alignment (this->priv->view,
1154                                                       PANGO_ALIGN_RIGHT);
1155                 gl_view_set_default_text_alignment   (this->priv->view,
1156                                                       PANGO_ALIGN_RIGHT);
1157         }
1158
1159         gl_debug (DEBUG_PROPERTY_BAR, "END");
1160
1161         this->priv->stop_signals = FALSE;
1162 }
1163
1164
1165 /*---------------------------------------------------------------------------*/
1166 /* PRIVATE.  Set sensitivity of doc controls.                                */
1167 /*---------------------------------------------------------------------------*/
1168 static void
1169 set_doc_items_sensitive (glUIPropertyBar      *this,
1170                          gboolean              state)
1171 {
1172         gtk_widget_set_sensitive (this->priv->font_family_combo,       state);
1173         gtk_widget_set_sensitive (this->priv->font_size_spin,          state);
1174         gtk_widget_set_sensitive (this->priv->font_bold_toggle,        state);
1175         gtk_widget_set_sensitive (this->priv->font_italic_toggle,      state);
1176         gtk_widget_set_sensitive (this->priv->text_align_left_radio,   state);
1177         gtk_widget_set_sensitive (this->priv->text_align_center_radio, state);
1178         gtk_widget_set_sensitive (this->priv->text_align_right_radio,  state);
1179         gtk_widget_set_sensitive (this->priv->text_color_button,       state);
1180         gtk_widget_set_sensitive (this->priv->fill_color_button,       state);
1181         gtk_widget_set_sensitive (this->priv->line_color_button,       state);
1182         gtk_widget_set_sensitive (this->priv->line_width_spin,         state);
1183 }
1184
1185
1186 /*---------------------------------------------------------------------------*/
1187 /* PRIVATE.  Set sensitivity of text related controls.                       */
1188 /*---------------------------------------------------------------------------*/
1189 static void
1190 set_text_items_sensitive (glUIPropertyBar      *this,
1191                           gboolean              state)
1192 {
1193         gtk_widget_set_sensitive (this->priv->font_family_combo,       state);
1194         gtk_widget_set_sensitive (this->priv->font_size_spin,          state);
1195         gtk_widget_set_sensitive (this->priv->font_bold_toggle,        state);
1196         gtk_widget_set_sensitive (this->priv->font_italic_toggle,      state);
1197         gtk_widget_set_sensitive (this->priv->text_align_left_radio,   state);
1198         gtk_widget_set_sensitive (this->priv->text_align_center_radio, state);
1199         gtk_widget_set_sensitive (this->priv->text_align_right_radio,  state);
1200         gtk_widget_set_sensitive (this->priv->text_color_button,       state);
1201 }
1202
1203
1204 /*---------------------------------------------------------------------------*/
1205 /* PRIVATE.  Set sensitivity of fill related controls.                       */
1206 /*---------------------------------------------------------------------------*/
1207 static void
1208 set_fill_items_sensitive (glUIPropertyBar      *this,
1209                           gboolean              state)
1210 {
1211         gtk_widget_set_sensitive (this->priv->fill_color_button,       state);
1212 }
1213
1214
1215 /*---------------------------------------------------------------------------*/
1216 /* PRIVATE.  Set sensitivity of line color related controls.                 */
1217 /*---------------------------------------------------------------------------*/
1218 static void
1219 set_line_color_items_sensitive (glUIPropertyBar      *this,
1220                                 gboolean              state)
1221 {
1222         gtk_widget_set_sensitive (this->priv->line_color_button,       state);
1223 }
1224
1225
1226 /*---------------------------------------------------------------------------*/
1227 /* PRIVATE.  Set sensitivity of line width related controls.                 */
1228 /*---------------------------------------------------------------------------*/
1229 static void
1230 set_line_width_items_sensitive (glUIPropertyBar      *this,
1231                                 gboolean              state)
1232 {
1233         gtk_widget_set_sensitive (this->priv->line_width_spin,         state);
1234 }
1235
1236
1237
1238 /*
1239  * Local Variables:       -- emacs
1240  * mode: C                -- emacs
1241  * c-basic-offset: 8      -- emacs
1242  * tab-width: 8           -- emacs
1243  * indent-tabs-mode: nil  -- emacs
1244  * End:                   -- emacs
1245  */