1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; 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"
44 #include "object-editor-private.h"
48 /*===========================================*/
50 /*===========================================*/
52 /*===========================================*/
53 /* Private data types */
54 /*===========================================*/
56 typedef void (*ChangedSignal) (GObject * object, gpointer data);
58 /*===========================================*/
60 /*===========================================*/
62 gint gl_object_editor_signals[LAST_SIGNAL] = { 0 };
64 /*===========================================*/
65 /* Local function prototypes */
66 /*===========================================*/
68 static void gl_object_editor_finalize (GObject *object);
70 static void gl_object_notebook_construct_valist (glObjectEditor *editor,
71 glObjectEditorOption first_option,
74 static void prefs_changed_cb (glObjectEditor *editor);
77 /*****************************************************************************/
78 /* Boilerplate object stuff. */
79 /*****************************************************************************/
80 G_DEFINE_TYPE (glObjectEditor, gl_object_editor, GTK_TYPE_VBOX);
83 gl_object_editor_class_init (glObjectEditorClass *class)
85 GObjectClass *object_class = G_OBJECT_CLASS (class);
87 gl_debug (DEBUG_EDITOR, "START");
89 gl_object_editor_parent_class = g_type_class_peek_parent (class);
91 object_class->finalize = gl_object_editor_finalize;
93 gl_object_editor_signals[CHANGED] =
94 g_signal_new ("changed",
95 G_OBJECT_CLASS_TYPE(object_class),
97 G_STRUCT_OFFSET (glObjectEditorClass, changed),
99 gl_marshal_VOID__VOID,
102 gl_object_editor_signals[SIZE_CHANGED] =
103 g_signal_new ("size_changed",
104 G_OBJECT_CLASS_TYPE(object_class),
106 G_STRUCT_OFFSET (glObjectEditorClass, size_changed),
108 gl_marshal_VOID__VOID,
111 gl_debug (DEBUG_EDITOR, "END");
115 gl_object_editor_init (glObjectEditor *editor)
117 gl_debug (DEBUG_EDITOR, "START");
119 editor->priv = g_new0 (glObjectEditorPrivate, 1);
121 editor->priv->gui = glade_xml_new (GLABELS_GLADE_DIR "object-editor.glade",
125 if (!editor->priv->gui) {
126 g_critical ("Could not open object-editor.glade. gLabels may not be installed correctly!");
130 editor->priv->editor_vbox = glade_xml_get_widget (editor->priv->gui,
132 gtk_box_pack_start (GTK_BOX(editor),
133 editor->priv->editor_vbox,
136 editor->priv->title_image = glade_xml_get_widget (editor->priv->gui,
138 editor->priv->title_label = glade_xml_get_widget (editor->priv->gui,
140 editor->priv->notebook = glade_xml_get_widget (editor->priv->gui,
143 gtk_widget_show_all (GTK_WIDGET(editor));
145 /* Hide all notebook pages to start with. */
146 gtk_widget_hide_all (editor->priv->notebook);
147 gtk_widget_set_no_show_all (editor->priv->notebook, TRUE);
149 gl_debug (DEBUG_EDITOR, "END");
153 gl_object_editor_finalize (GObject *object)
155 glObjectEditor* editor = GL_OBJECT_EDITOR (object);;
157 gl_debug (DEBUG_EDITOR, "START");
159 g_return_if_fail (object != NULL);
160 g_return_if_fail (GL_IS_OBJECT_EDITOR (editor));
161 g_return_if_fail (editor->priv != NULL);
163 g_free (editor->priv);
165 g_signal_handlers_disconnect_by_func (G_OBJECT(gl_prefs),
166 prefs_changed_cb, editor);
168 G_OBJECT_CLASS (gl_object_editor_parent_class)->finalize (object);
170 gl_debug (DEBUG_EDITOR, "END");
173 /*****************************************************************************/
174 /* NEW object editor. */
175 /*****************************************************************************/
177 gl_object_editor_new (gchar *image,
179 glObjectEditorOption first_option, ...)
181 glObjectEditor *editor;
184 gl_debug (DEBUG_EDITOR, "START");
186 editor = GL_OBJECT_EDITOR (g_object_new (GL_TYPE_OBJECT_EDITOR, NULL));
189 gtk_image_set_from_stock (GTK_IMAGE(editor->priv->title_image),
191 GTK_ICON_SIZE_LARGE_TOOLBAR);
197 s = g_strdup_printf ("<span weight=\"bold\">%s</span>",
199 gtk_label_set_text (GTK_LABEL(editor->priv->title_label), s);
202 gtk_label_set_use_markup (GTK_LABEL(editor->priv->title_label), TRUE);
206 gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK(editor->priv->notebook), TRUE);
208 va_start (args, first_option);
209 gl_object_notebook_construct_valist (editor, first_option, args);
212 if (editor->priv->gui) {
213 g_object_unref (G_OBJECT (editor->priv->gui));
216 gl_debug (DEBUG_EDITOR, "END");
218 return GTK_WIDGET(editor);
221 /*--------------------------------------------------------------------------*/
222 /* PRIVATE. Construct notebook. */
223 /*--------------------------------------------------------------------------*/
225 gl_object_notebook_construct_valist (glObjectEditor *editor,
226 glObjectEditorOption first_option,
229 glObjectEditorOption option;
232 gl_debug (DEBUG_EDITOR, "START");
234 option = first_option;
236 for ( option=first_option; option; option=va_arg (args, glObjectEditorOption) ) {
240 case GL_OBJECT_EDITOR_EMPTY:
241 gtk_widget_set_sensitive (editor->priv->title_image, FALSE);
242 gtk_widget_set_sensitive (editor->priv->title_label, FALSE);
245 case GL_OBJECT_EDITOR_POSITION_PAGE:
246 gl_object_editor_prepare_position_page (editor);
250 case GL_OBJECT_EDITOR_SIZE_PAGE:
251 case GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE:
252 gl_object_editor_prepare_size_page (editor, option);
256 case GL_OBJECT_EDITOR_SIZE_LINE_PAGE:
257 gl_object_editor_prepare_lsize_page (editor);
261 case GL_OBJECT_EDITOR_FILL_PAGE:
262 gl_object_editor_prepare_fill_page (editor);
266 case GL_OBJECT_EDITOR_LINE_PAGE:
267 gl_object_editor_prepare_line_page (editor);
271 case GL_OBJECT_EDITOR_IMAGE_PAGE:
272 gl_object_editor_prepare_image_page (editor);
276 case GL_OBJECT_EDITOR_TEXT_PAGE:
277 gl_object_editor_prepare_text_page (editor);
281 case GL_OBJECT_EDITOR_EDIT_PAGE:
282 gl_object_editor_prepare_edit_page (editor);
286 case GL_OBJECT_EDITOR_BC_PAGE:
287 gl_object_editor_prepare_bc_page (editor);
291 case GL_OBJECT_EDITOR_DATA_PAGE:
292 gl_object_editor_prepare_data_page (editor);
296 case GL_OBJECT_EDITOR_SHADOW_PAGE:
297 gl_object_editor_prepare_shadow_page (editor);
302 g_message ("option = %d", option);
303 g_assert_not_reached ();
308 gtk_widget_show (editor->priv->notebook);
311 g_signal_connect_swapped (G_OBJECT (gl_prefs), "changed",
312 G_CALLBACK (prefs_changed_cb),
315 gl_debug (DEBUG_EDITOR, "END");
318 /*--------------------------------------------------------------------------*/
319 /* PRIVATE. Widget changed callback. Emit our "changed" signal. */
320 /*--------------------------------------------------------------------------*/
322 gl_object_editor_changed_cb (glObjectEditor *editor)
324 if (editor->priv->stop_signals) return;
326 gl_debug (DEBUG_EDITOR, "START");
328 /* Emit our "changed" signal */
329 g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
331 gl_debug (DEBUG_EDITOR, "END");
334 /*--------------------------------------------------------------------------*/
335 /* PRIVATE. Widget size changed callback. Emit our "size-changed" signal. */
336 /*--------------------------------------------------------------------------*/
338 gl_object_editor_size_changed_cb (glObjectEditor *editor)
340 if (editor->priv->stop_signals) return;
342 gl_debug (DEBUG_EDITOR, "START");
344 /* Emit our "size_changed" signal */
345 g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
347 gl_debug (DEBUG_EDITOR, "END");
350 /*****************************************************************************/
351 /* Set possible key names from merge object. */
352 /*****************************************************************************/
354 gl_object_editor_set_key_names (glObjectEditor *editor,
362 gl_debug (DEBUG_EDITOR, "START");
364 if (editor->priv->edit_key_label) {
365 gtk_widget_set_sensitive (editor->priv->edit_key_label, merge != NULL);
368 if (editor->priv->edit_key_combo) {
369 gtk_widget_set_sensitive (editor->priv->edit_key_combo, merge != NULL);
372 if (editor->priv->text_auto_shrink_check) {
373 gtk_widget_set_sensitive (editor->priv->text_auto_shrink_check,
377 if (editor->priv->text_page_vbox) {
378 gtk_widget_set_sensitive (editor->priv->text_color_key_radio, merge != NULL);
380 gtk_toggle_button_set_active (
381 GTK_TOGGLE_BUTTON(editor->priv->text_color_radio), TRUE);
382 gtk_widget_set_sensitive (editor->priv->text_color_combo, TRUE);
383 gtk_widget_set_sensitive (editor->priv->text_color_key_combo, FALSE);
385 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->text_color_key_radio));
386 gtk_widget_set_sensitive (editor->priv->text_color_combo, !state);
387 gtk_widget_set_sensitive (editor->priv->text_color_key_combo, state);
392 if (editor->priv->edit_insert_field_button) {
393 gtk_widget_set_sensitive (editor->priv->edit_insert_field_button,
397 if (editor->priv->img_key_combo) {
398 gtk_widget_set_sensitive (editor->priv->img_key_combo, merge != NULL);
401 if (editor->priv->img_key_radio) {
402 gtk_widget_set_sensitive (editor->priv->img_key_radio, merge != NULL);
404 gtk_toggle_button_set_active (
405 GTK_TOGGLE_BUTTON(editor->priv->img_file_radio), TRUE);
409 if (editor->priv->data_key_combo) {
410 gtk_widget_set_sensitive (editor->priv->data_key_combo, merge != NULL);
413 if (editor->priv->data_key_radio) {
414 gtk_widget_set_sensitive (editor->priv->data_key_radio, merge != NULL);
416 gtk_toggle_button_set_active (
417 GTK_TOGGLE_BUTTON(editor->priv->data_literal_radio), TRUE);
421 fixed_flag = editor->priv->data_format_fixed_flag;
422 if (editor->priv->data_format_label) {
423 gtk_widget_set_sensitive (editor->priv->data_format_label,
426 if (editor->priv->data_ex_label) {
427 gtk_widget_set_sensitive (editor->priv->data_ex_label,
430 if (editor->priv->data_digits_label) {
431 gtk_widget_set_sensitive (editor->priv->data_digits_label,
432 (merge != NULL) && !fixed_flag);
434 if (editor->priv->data_digits_spin) {
435 gtk_widget_set_sensitive (editor->priv->data_digits_spin,
436 (merge != NULL) && !fixed_flag);
439 if (editor->priv->fill_page_vbox) {
440 gtk_widget_set_sensitive (editor->priv->fill_key_radio, merge != NULL);
442 gtk_toggle_button_set_active (
443 GTK_TOGGLE_BUTTON(editor->priv->fill_color_radio), TRUE);
444 gtk_widget_set_sensitive (editor->priv->fill_color_combo, TRUE);
445 gtk_widget_set_sensitive (editor->priv->fill_key_combo, FALSE);
447 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->fill_key_radio));
448 gtk_widget_set_sensitive (editor->priv->fill_color_combo, !state);
449 gtk_widget_set_sensitive (editor->priv->fill_key_combo, state);
454 if (editor->priv->line_page_vbox) {
455 gtk_widget_set_sensitive (editor->priv->line_key_radio, merge != NULL);
457 gtk_toggle_button_set_active (
458 GTK_TOGGLE_BUTTON(editor->priv->line_color_radio), TRUE);
459 gtk_widget_set_sensitive (editor->priv->line_color_combo, TRUE);
460 gtk_widget_set_sensitive (editor->priv->line_key_combo, FALSE);
462 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->line_key_radio));
463 gtk_widget_set_sensitive (editor->priv->line_color_combo, !state);
464 gtk_widget_set_sensitive (editor->priv->line_key_combo, state);
469 if (editor->priv->bc_page_vbox) {
470 gtk_widget_set_sensitive (editor->priv->bc_key_radio, merge != NULL);
472 gtk_toggle_button_set_active (
473 GTK_TOGGLE_BUTTON(editor->priv->bc_color_radio), TRUE);
474 gtk_widget_set_sensitive (editor->priv->bc_color_combo, TRUE);
475 gtk_widget_set_sensitive (editor->priv->bc_key_combo, FALSE);
477 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->bc_key_radio));
478 gtk_widget_set_sensitive (editor->priv->bc_color_combo, !state);
479 gtk_widget_set_sensitive (editor->priv->bc_key_combo, state);
484 if (editor->priv->shadow_page_vbox) {
485 gtk_widget_set_sensitive (editor->priv->shadow_key_radio, merge != NULL);
487 gtk_toggle_button_set_active (
488 GTK_TOGGLE_BUTTON(editor->priv->shadow_color_radio), TRUE);
489 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, TRUE);
490 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, FALSE);
492 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->priv->shadow_key_radio));
493 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, !state);
494 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, state);
499 keys = gl_merge_get_key_list (merge);
500 if ( keys == NULL ) {
501 keys = g_list_append (keys, g_strdup (""));
504 combo = editor->priv->img_key_combo;
506 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
509 combo = editor->priv->edit_key_combo;
511 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
514 combo = editor->priv->data_key_combo;
516 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
519 combo = editor->priv->fill_key_combo;
521 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
524 combo = editor->priv->text_color_key_combo;
526 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
529 combo = editor->priv->line_key_combo;
531 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
534 combo = editor->priv->bc_key_combo;
536 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
539 combo = editor->priv->shadow_key_combo;
541 gl_util_combo_box_set_strings (GTK_COMBO_BOX (combo), keys);
544 gl_merge_free_key_list (&keys);
546 gl_debug (DEBUG_EDITOR, "END");
549 /*****************************************************************************/
550 /* Construct color combo "Custom widget". */
551 /*****************************************************************************/
553 gl_object_editor_construct_color_combo (gchar *name,
559 GtkWidget *color_combo;
569 cg_name = "shadow_color_group";
570 color = GL_COLOR_SHADOW_DEFAULT;
571 no_color = _("Default");
575 cg_name = "text_color_group";
576 color = gl_prefs->default_text_color;
577 no_color = _("Default");
581 cg_name = "line_color_group";
582 color = gl_prefs->default_line_color;
583 no_color = _("No line");
588 cg_name = "fill_color_group";
589 color = gl_prefs->default_fill_color;
590 no_color = _("No fill");
595 cg = color_group_fetch (cg_name, NULL);
596 gdk_color = gl_color_to_gdk_color (color);
597 color_combo = color_combo_new (NULL, no_color, gdk_color, cg);
600 color_combo_box_set_preview_relief (COLOR_COMBO(color_combo), GTK_RELIEF_NORMAL);
605 /*****************************************************************************/
606 /* Construct chain button "Custom widget". */
607 /*****************************************************************************/
609 gl_object_editor_construct_chain_button (gchar *name,
615 GtkWidget *chain_button;
617 chain_button = gl_wdgt_chain_button_new (GL_WDGT_CHAIN_RIGHT);
618 gl_wdgt_chain_button_set_active (GL_WDGT_CHAIN_BUTTON(chain_button), TRUE);
623 /*--------------------------------------------------------------------------*/
624 /* PRIVATE. Prefs changed callback. Update units related items. */
625 /*--------------------------------------------------------------------------*/
627 prefs_changed_cb (glObjectEditor *editor)
630 gl_debug (DEBUG_EDITOR, "START");
632 if (editor->priv->lsize_r_spin) {
633 lsize_prefs_changed_cb (editor);
636 if (editor->priv->size_w_spin) {
637 size_prefs_changed_cb (editor);
640 if (editor->priv->pos_x_spin) {
641 position_prefs_changed_cb (editor);
644 if (editor->priv->shadow_x_spin) {
645 shadow_prefs_changed_cb (editor);
648 gl_debug (DEBUG_EDITOR, "END");