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