1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * object-editor.c: object properties editor module
8 * Copyright (C) 2003 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "object-editor.h"
28 #include <glib/gi18n.h>
29 #include <glade/glade-xml.h>
30 #include <gtk/gtklabel.h>
31 #include <gtk/gtknotebook.h>
32 #include <gtk/gtkcombobox.h>
33 #include <gtk/gtktogglebutton.h>
38 #include "mygal/widget-color-combo.h"
40 #include "wdgt-chain-button.h"
43 #include "object-editor-private.h"
47 /*===========================================*/
49 /*===========================================*/
51 /*===========================================*/
52 /* Private data types */
53 /*===========================================*/
55 typedef void (*ChangedSignal) (GObject * object, gpointer data);
57 /*===========================================*/
59 /*===========================================*/
61 gint gl_object_editor_signals[LAST_SIGNAL] = { 0 };
63 static GtkVBoxClass *parent_class = NULL;
65 /*===========================================*/
66 /* Local function prototypes */
67 /*===========================================*/
69 static void gl_object_editor_class_init (glObjectEditorClass *klass);
70 static void gl_object_editor_init (glObjectEditor *editor);
71 static void gl_object_editor_finalize (GObject *object);
73 static void gl_object_notebook_construct_valist (glObjectEditor *editor,
74 glObjectEditorOption first_option,
77 static void prefs_changed_cb (glObjectEditor *editor);
80 /*****************************************************************************/
81 /* Boilerplate object stuff. */
82 /*****************************************************************************/
84 gl_object_editor_get_type (void)
86 static GType type = 0;
90 static const GTypeInfo info =
92 sizeof (glObjectEditorClass),
94 NULL, /* base_finalize */
95 (GClassInitFunc) gl_object_editor_class_init,
96 NULL, /* class_finalize */
97 NULL, /* class_data */
98 sizeof (glObjectEditor),
100 (GInstanceInitFunc) gl_object_editor_init,
104 type = g_type_register_static (GTK_TYPE_VBOX,
105 "glObjectEditor", &info, 0);
112 gl_object_editor_class_init (glObjectEditorClass *klass)
114 GObjectClass *object_class = G_OBJECT_CLASS (klass);
116 gl_debug (DEBUG_EDITOR, "START");
118 parent_class = g_type_class_peek_parent (klass);
120 object_class->finalize = gl_object_editor_finalize;
122 gl_object_editor_signals[CHANGED] =
123 g_signal_new ("changed",
124 G_OBJECT_CLASS_TYPE(object_class),
126 G_STRUCT_OFFSET (glObjectEditorClass, changed),
128 gl_marshal_VOID__VOID,
131 gl_object_editor_signals[SIZE_CHANGED] =
132 g_signal_new ("size_changed",
133 G_OBJECT_CLASS_TYPE(object_class),
135 G_STRUCT_OFFSET (glObjectEditorClass, size_changed),
137 gl_marshal_VOID__VOID,
140 gl_debug (DEBUG_EDITOR, "END");
144 gl_object_editor_init (glObjectEditor *editor)
146 gl_debug (DEBUG_EDITOR, "START");
148 editor->priv = g_new0 (glObjectEditorPrivate, 1);
150 editor->priv->gui = glade_xml_new (GLABELS_GLADE_DIR "object-editor.glade",
154 if (!editor->priv->gui) {
155 g_critical ("Could not open object-editor.glade. gLabels may not be installed correctly!");
159 editor->priv->editor_vbox = glade_xml_get_widget (editor->priv->gui,
161 gtk_box_pack_start (GTK_BOX(editor),
162 editor->priv->editor_vbox,
165 editor->priv->title_image = glade_xml_get_widget (editor->priv->gui,
167 editor->priv->title_label = glade_xml_get_widget (editor->priv->gui,
169 editor->priv->notebook = glade_xml_get_widget (editor->priv->gui,
172 gtk_widget_show_all (GTK_WIDGET(editor));
174 /* Hide all notebook pages to start with. */
175 gtk_widget_hide_all (editor->priv->notebook);
176 gtk_widget_set_no_show_all (editor->priv->notebook, TRUE);
178 gl_debug (DEBUG_EDITOR, "END");
182 gl_object_editor_finalize (GObject *object)
184 glObjectEditor* editor;
186 gl_debug (DEBUG_EDITOR, "START");
188 g_return_if_fail (object != NULL);
190 editor = GL_OBJECT_EDITOR (object);
192 g_return_if_fail (GL_IS_OBJECT_EDITOR (editor));
193 g_return_if_fail (editor->priv != NULL);
195 if (editor->priv->gui) {
196 g_object_unref (G_OBJECT (editor->priv->gui));
199 g_free (editor->priv);
201 g_signal_handlers_disconnect_by_func (G_OBJECT(gl_prefs),
202 prefs_changed_cb, editor);
204 G_OBJECT_CLASS (parent_class)->finalize (object);
206 gl_debug (DEBUG_EDITOR, "END");
209 /*****************************************************************************/
210 /* NEW object editor. */
211 /*****************************************************************************/
213 gl_object_editor_new (gchar *image,
215 glObjectEditorOption first_option, ...)
217 glObjectEditor *editor;
220 gl_debug (DEBUG_EDITOR, "START");
222 editor = GL_OBJECT_EDITOR (g_object_new (GL_TYPE_OBJECT_EDITOR, NULL));
225 gtk_image_set_from_stock (GTK_IMAGE(editor->priv->title_image),
227 GTK_ICON_SIZE_LARGE_TOOLBAR);
233 s = g_strdup_printf ("<span weight=\"bold\">%s</span>",
235 gtk_label_set_text (GTK_LABEL(editor->priv->title_label), s);
238 gtk_label_set_use_markup (GTK_LABEL(editor->priv->title_label), TRUE);
242 gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK(editor->priv->notebook), TRUE);
244 va_start (args, first_option);
245 gl_object_notebook_construct_valist (editor, first_option, args);
248 gl_debug (DEBUG_EDITOR, "END");
250 return GTK_WIDGET(editor);
253 /*--------------------------------------------------------------------------*/
254 /* PRIVATE. Construct notebook. */
255 /*--------------------------------------------------------------------------*/
257 gl_object_notebook_construct_valist (glObjectEditor *editor,
258 glObjectEditorOption first_option,
261 glObjectEditorOption option;
264 gl_debug (DEBUG_EDITOR, "START");
266 option = first_option;
268 for ( option=first_option; option; option=va_arg (args, glObjectEditorOption) ) {
272 case GL_OBJECT_EDITOR_EMPTY:
273 gtk_widget_set_sensitive (editor->priv->title_image, FALSE);
274 gtk_widget_set_sensitive (editor->priv->title_label, FALSE);
277 case GL_OBJECT_EDITOR_POSITION_PAGE:
278 gl_object_editor_prepare_position_page (editor);
282 case GL_OBJECT_EDITOR_SIZE_PAGE:
283 case GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE:
284 gl_object_editor_prepare_size_page (editor, option);
288 case GL_OBJECT_EDITOR_SIZE_LINE_PAGE:
289 gl_object_editor_prepare_lsize_page (editor);
293 case GL_OBJECT_EDITOR_FILL_PAGE:
294 gl_object_editor_prepare_fill_page (editor);
298 case GL_OBJECT_EDITOR_LINE_PAGE:
299 gl_object_editor_prepare_line_page (editor);
303 case GL_OBJECT_EDITOR_IMAGE_PAGE:
304 gl_object_editor_prepare_image_page (editor);
308 case GL_OBJECT_EDITOR_TEXT_PAGE:
309 gl_object_editor_prepare_text_page (editor);
313 case GL_OBJECT_EDITOR_EDIT_PAGE:
314 gl_object_editor_prepare_edit_page (editor);
318 case GL_OBJECT_EDITOR_BC_PAGE:
319 gl_object_editor_prepare_bc_page (editor);
323 case GL_OBJECT_EDITOR_DATA_PAGE:
324 gl_object_editor_prepare_data_page (editor);
328 case GL_OBJECT_EDITOR_SHADOW_PAGE:
329 gl_object_editor_prepare_shadow_page (editor);
334 g_message ("option = %d", option);
335 g_assert_not_reached ();
340 gtk_widget_show (editor->priv->notebook);
343 g_signal_connect_swapped (G_OBJECT (gl_prefs), "changed",
344 G_CALLBACK (prefs_changed_cb),
347 gl_debug (DEBUG_EDITOR, "END");
350 /*--------------------------------------------------------------------------*/
351 /* PRIVATE. Widget changed callback. Emit our "changed" signal. */
352 /*--------------------------------------------------------------------------*/
354 gl_object_editor_changed_cb (glObjectEditor *editor)
356 gl_debug (DEBUG_EDITOR, "START");
358 /* Emit our "changed" signal */
359 g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
361 gl_debug (DEBUG_EDITOR, "END");
364 /*--------------------------------------------------------------------------*/
365 /* PRIVATE. Widget size changed callback. Emit our "size-changed" signal. */
366 /*--------------------------------------------------------------------------*/
368 gl_object_editor_size_changed_cb (glObjectEditor *editor)
370 gl_debug (DEBUG_EDITOR, "START");
372 /* Emit our "size_changed" signal */
373 g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
375 gl_debug (DEBUG_EDITOR, "END");
378 /*****************************************************************************/
379 /* Set possible key names from merge object. */
380 /*****************************************************************************/
382 gl_object_editor_set_key_names (glObjectEditor *editor,
390 gl_debug (DEBUG_EDITOR, "START");
392 if (editor->priv->edit_key_label) {
393 gtk_widget_set_sensitive (editor->priv->edit_key_label, merge != NULL);
396 if (editor->priv->edit_key_combo) {
397 gtk_widget_set_sensitive (editor->priv->edit_key_combo, merge != NULL);
400 if (editor->priv->text_auto_shrink_check) {
401 gtk_widget_set_sensitive (editor->priv->text_auto_shrink_check,
405 if (editor->priv->text_page_vbox) {
406 gtk_widget_set_sensitive (editor->priv->text_color_key_radio, merge != NULL);
408 gtk_toggle_button_set_active (
409 GTK_TOGGLE_BUTTON(editor->priv->text_color_radio), TRUE);
410 gtk_widget_set_sensitive (editor->priv->text_color_combo, TRUE);
411 gtk_widget_set_sensitive (editor->priv->text_color_key_combo, FALSE);
413 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->text_color_key_radio));
414 gtk_widget_set_sensitive (editor->priv->text_color_combo, !state);
415 gtk_widget_set_sensitive (editor->priv->text_color_key_combo, state);
420 if (editor->priv->edit_insert_field_button) {
421 gtk_widget_set_sensitive (editor->priv->edit_insert_field_button,
425 if (editor->priv->img_key_combo) {
426 gtk_widget_set_sensitive (editor->priv->img_key_combo, merge != NULL);
429 if (editor->priv->img_key_radio) {
430 gtk_widget_set_sensitive (editor->priv->img_key_radio, merge != NULL);
432 gtk_toggle_button_set_active (
433 GTK_TOGGLE_BUTTON(editor->priv->img_file_radio), TRUE);
437 if (editor->priv->data_key_combo) {
438 gtk_widget_set_sensitive (editor->priv->data_key_combo, merge != NULL);
441 if (editor->priv->data_key_radio) {
442 gtk_widget_set_sensitive (editor->priv->data_key_radio, merge != NULL);
444 gtk_toggle_button_set_active (
445 GTK_TOGGLE_BUTTON(editor->priv->data_literal_radio), TRUE);
449 fixed_flag = editor->priv->data_format_fixed_flag;
450 if (editor->priv->data_format_label) {
451 gtk_widget_set_sensitive (editor->priv->data_format_label,
454 if (editor->priv->data_ex_label) {
455 gtk_widget_set_sensitive (editor->priv->data_ex_label,
458 if (editor->priv->data_digits_label) {
459 gtk_widget_set_sensitive (editor->priv->data_digits_label,
460 (merge != NULL) && !fixed_flag);
462 if (editor->priv->data_digits_spin) {
463 gtk_widget_set_sensitive (editor->priv->data_digits_spin,
464 (merge != NULL) && !fixed_flag);
467 if (editor->priv->fill_page_vbox) {
468 gtk_widget_set_sensitive (editor->priv->fill_key_radio, merge != NULL);
470 gtk_toggle_button_set_active (
471 GTK_TOGGLE_BUTTON(editor->priv->fill_color_radio), TRUE);
472 gtk_widget_set_sensitive (editor->priv->fill_color_combo, TRUE);
473 gtk_widget_set_sensitive (editor->priv->fill_key_combo, FALSE);
475 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->fill_key_radio));
476 gtk_widget_set_sensitive (editor->priv->fill_color_combo, !state);
477 gtk_widget_set_sensitive (editor->priv->fill_key_combo, state);
482 if (editor->priv->line_page_vbox) {
483 gtk_widget_set_sensitive (editor->priv->line_key_radio, merge != NULL);
485 gtk_toggle_button_set_active (
486 GTK_TOGGLE_BUTTON(editor->priv->line_color_radio), TRUE);
487 gtk_widget_set_sensitive (editor->priv->line_color_combo, TRUE);
488 gtk_widget_set_sensitive (editor->priv->line_key_combo, FALSE);
490 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->line_key_radio));
491 gtk_widget_set_sensitive (editor->priv->line_color_combo, !state);
492 gtk_widget_set_sensitive (editor->priv->line_key_combo, state);
497 if (editor->priv->bc_page_vbox) {
498 gtk_widget_set_sensitive (editor->priv->bc_key_radio, merge != NULL);
500 gtk_toggle_button_set_active (
501 GTK_TOGGLE_BUTTON(editor->priv->bc_color_radio), TRUE);
502 gtk_widget_set_sensitive (editor->priv->bc_color_combo, TRUE);
503 gtk_widget_set_sensitive (editor->priv->bc_key_combo, FALSE);
505 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->bc_key_radio));
506 gtk_widget_set_sensitive (editor->priv->bc_color_combo, !state);
507 gtk_widget_set_sensitive (editor->priv->bc_key_combo, state);
512 if (editor->priv->shadow_page_vbox) {
513 gtk_widget_set_sensitive (editor->priv->shadow_key_radio, merge != NULL);
515 gtk_toggle_button_set_active (
516 GTK_TOGGLE_BUTTON(editor->priv->shadow_color_radio), TRUE);
517 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, TRUE);
518 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, FALSE);
520 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->shadow_key_radio));
521 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, !state);
522 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, state);
527 keys = gl_merge_get_key_list (merge);
528 if ( keys == NULL ) {
529 keys = g_list_append (keys, "");
532 combo = editor->priv->img_key_combo;
534 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
537 combo = editor->priv->edit_key_combo;
539 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
542 combo = editor->priv->data_key_combo;
544 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
547 combo = editor->priv->fill_key_combo;
549 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
552 combo = editor->priv->text_color_key_combo;
554 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
557 combo = editor->priv->line_key_combo;
559 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
562 combo = editor->priv->bc_key_combo;
564 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
567 combo = editor->priv->shadow_key_combo;
569 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
572 gl_merge_free_key_list (&keys);
574 gl_debug (DEBUG_EDITOR, "END");
577 /*****************************************************************************/
578 /* Construct color combo "Custom widget". */
579 /*****************************************************************************/
581 gl_object_editor_construct_color_combo (gchar *name,
587 GtkWidget *color_combo;
597 cg_name = "shadow_color_group";
598 color = GL_COLOR_SHADOW_DEFAULT;
599 no_color = _("Default");
603 cg_name = "text_color_group";
604 color = gl_prefs->default_text_color;
605 no_color = _("Default");
609 cg_name = "line_color_group";
610 color = gl_prefs->default_line_color;
611 no_color = _("No line");
616 cg_name = "fill_color_group";
617 color = gl_prefs->default_fill_color;
618 no_color = _("No fill");
623 cg = color_group_fetch (cg_name, NULL);
624 gdk_color = gl_color_to_gdk_color (color);
625 color_combo = color_combo_new (NULL, no_color, gdk_color, cg);
628 color_combo_box_set_preview_relief (COLOR_COMBO(color_combo), GTK_RELIEF_NORMAL);
633 /*****************************************************************************/
634 /* Construct chain button "Custom widget". */
635 /*****************************************************************************/
637 gl_object_editor_construct_chain_button (gchar *name,
643 GtkWidget *chain_button;
645 chain_button = gl_wdgt_chain_button_new (GL_WDGT_CHAIN_RIGHT);
646 gl_wdgt_chain_button_set_active (GL_WDGT_CHAIN_BUTTON(chain_button), TRUE);
651 /*--------------------------------------------------------------------------*/
652 /* PRIVATE. Prefs changed callback. Update units related items. */
653 /*--------------------------------------------------------------------------*/
655 prefs_changed_cb (glObjectEditor *editor)
658 gl_debug (DEBUG_EDITOR, "START");
660 if (editor->priv->lsize_r_spin) {
661 lsize_prefs_changed_cb (editor);
664 if (editor->priv->size_w_spin) {
665 size_prefs_changed_cb (editor);
668 if (editor->priv->pos_x_spin) {
669 position_prefs_changed_cb (editor);
672 if (editor->priv->shadow_x_spin) {
673 shadow_prefs_changed_cb (editor);
676 gl_debug (DEBUG_EDITOR, "END");