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