2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * wdgt_text_entry.c: text entry widget module
6 * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wdgt-text-entry.h"
27 #include "text-node.h"
32 /*===========================================*/
34 /*===========================================*/
41 typedef void (*glWdgtTextEntrySignal) (GObject * object, gpointer data);
43 /*===========================================*/
45 /*===========================================*/
47 static GtkContainerClass *parent_class;
49 static gint wdgt_text_entry_signals[LAST_SIGNAL] = { 0 };
51 /*===========================================*/
52 /* Local function prototypes */
53 /*===========================================*/
55 static void gl_wdgt_text_entry_class_init (glWdgtTextEntryClass * class);
56 static void gl_wdgt_text_entry_instance_init (glWdgtTextEntry * text_entry);
57 static void gl_wdgt_text_entry_finalize (GObject * object);
58 static void gl_wdgt_text_entry_construct (glWdgtTextEntry * text_entry,
59 gchar * label, GList * field_defs);
61 static void changed_cb (glWdgtTextEntry * text_entry);
62 static void insert_cb (glWdgtTextEntry * text_entry);
64 /*================================================================*/
65 /* Boilerplate Object stuff. */
66 /*================================================================*/
68 gl_wdgt_text_entry_get_type (void)
70 static guint wdgt_text_entry_type = 0;
72 if (!wdgt_text_entry_type) {
73 GTypeInfo wdgt_text_entry_info = {
74 sizeof (glWdgtTextEntryClass),
77 (GClassInitFunc) gl_wdgt_text_entry_class_init,
80 sizeof (glWdgtTextEntry),
82 (GInstanceInitFunc) gl_wdgt_text_entry_instance_init,
85 wdgt_text_entry_type = g_type_register_static (gtk_vbox_get_type (),
87 &wdgt_text_entry_info,
91 return wdgt_text_entry_type;
95 gl_wdgt_text_entry_class_init (glWdgtTextEntryClass * class)
97 GObjectClass *object_class;
99 gl_debug (DEBUG_WDGT, "START");
101 object_class = (GObjectClass *) class;
103 parent_class = gtk_type_class (gtk_vbox_get_type ());
105 object_class->finalize = gl_wdgt_text_entry_finalize;
107 wdgt_text_entry_signals[CHANGED] =
108 g_signal_new ("changed",
109 G_OBJECT_CLASS_TYPE(object_class),
111 G_STRUCT_OFFSET (glWdgtTextEntryClass, changed),
113 gl_marshal_VOID__VOID, G_TYPE_NONE, 0);
115 gl_debug (DEBUG_WDGT, "END");
119 gl_wdgt_text_entry_instance_init (glWdgtTextEntry * text_entry)
121 gl_debug (DEBUG_WDGT, "START");
123 text_entry->text_entry = NULL;
124 text_entry->key_entry = NULL;
125 text_entry->insert_button = NULL;
127 gl_debug (DEBUG_WDGT, "END");
131 gl_wdgt_text_entry_finalize (GObject * object)
133 glWdgtTextEntry *text_entry;
134 glWdgtTextEntryClass *class;
136 gl_debug (DEBUG_WDGT, "START");
138 g_return_if_fail (object != NULL);
139 g_return_if_fail (GL_IS_WDGT_TEXT_ENTRY (object));
141 text_entry = GL_WDGT_TEXT_ENTRY (object);
143 G_OBJECT_CLASS (parent_class)->finalize (object);
145 gl_debug (DEBUG_WDGT, "END");
149 gl_wdgt_text_entry_new (gchar * label,
152 glWdgtTextEntry *text_entry;
154 gl_debug (DEBUG_WDGT, "START");
156 text_entry = g_object_new (gl_wdgt_text_entry_get_type (), NULL);
158 gl_wdgt_text_entry_construct (text_entry, label, field_defs);
160 gl_debug (DEBUG_WDGT, "END");
162 return GTK_WIDGET (text_entry);
165 /*============================================================*/
166 /* Construct composite widget. */
167 /*============================================================*/
169 gl_wdgt_text_entry_construct (glWdgtTextEntry * text_entry,
173 GtkWidget *wvbox, *wframe, *wtable, *wlabel, *wcombo;
176 gl_debug (DEBUG_WDGT, "START");
178 wvbox = GTK_WIDGET (text_entry);
180 wframe = gtk_frame_new (label);
181 gtk_box_pack_start (GTK_BOX (wvbox), wframe, FALSE, FALSE, 0);
183 wtable = gtk_table_new (2, 3, FALSE);
184 gtk_container_set_border_width (GTK_CONTAINER (wtable), 10);
185 gtk_table_set_row_spacings (GTK_TABLE (wtable), 5);
186 gtk_table_set_col_spacings (GTK_TABLE (wtable), 5);
187 gtk_container_add (GTK_CONTAINER (wframe), wtable);
189 /* Actual text entry widget */
190 text_entry->text_entry = gtk_text_view_new ();
191 text_entry->text_buffer =
192 gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
193 g_signal_connect_swapped (G_OBJECT (text_entry->text_buffer),
194 "changed", G_CALLBACK (changed_cb),
195 G_OBJECT (text_entry));
196 gtk_widget_set_size_request (text_entry->text_entry, -1, 70);
197 gtk_table_attach_defaults (GTK_TABLE (wtable), text_entry->text_entry,
200 /* Insert merge field label */
201 wlabel = gtk_label_new (_("Key:"));
202 gtk_table_attach_defaults (GTK_TABLE (wtable), wlabel, 0, 1, 1, 2);
204 /* Key entry widget */
205 wcombo = gtk_combo_new ();
206 keys = gl_merge_get_key_list (field_defs);
208 gtk_combo_set_popdown_strings (GTK_COMBO (wcombo), keys);
209 gl_merge_free_key_list (&keys);
210 text_entry->key_entry = GTK_COMBO (wcombo)->entry;
211 gtk_entry_set_editable (GTK_ENTRY (text_entry->key_entry), FALSE);
212 gtk_widget_set_size_request (wcombo, 200, -1);
213 gtk_table_attach_defaults (GTK_TABLE (wtable), wcombo, 1, 2, 1, 2);
216 text_entry->insert_button =
217 gtk_button_new_with_label (_("Insert merge field"));
218 g_signal_connect_swapped (G_OBJECT (text_entry->insert_button),
219 "clicked", G_CALLBACK (insert_cb),
220 G_OBJECT (text_entry));
221 gtk_table_attach_defaults (GTK_TABLE (wtable),
222 text_entry->insert_button, 2, 3, 1, 2);
224 gl_debug (DEBUG_WDGT, "END");
227 /*--------------------------------------------------------------------------*/
228 /* PRIVATE. Callback for when text has changed. */
229 /*--------------------------------------------------------------------------*/
231 changed_cb (glWdgtTextEntry * text_entry)
233 gl_debug (DEBUG_WDGT, "START");
235 /* Emit our "changed" signal */
236 g_signal_emit (G_OBJECT (text_entry),
237 wdgt_text_entry_signals[CHANGED], 0);
239 gl_debug (DEBUG_WDGT, "END");
242 /*--------------------------------------------------------------------------*/
243 /* PRIVATE. Callback to insert field into text buffer. */
244 /*--------------------------------------------------------------------------*/
246 insert_cb (glWdgtTextEntry * text_entry)
248 GtkTextBuffer *buffer;
251 gl_debug (DEBUG_WDGT, "START");
254 gtk_editable_get_chars (GTK_EDITABLE (text_entry->key_entry), 0,
256 field = g_strdup_printf ("FIELD{%s}", key);
258 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
259 gtk_text_buffer_insert_at_cursor (buffer, field, -1);
265 gl_debug (DEBUG_WDGT, "END");
268 /*--------------------------------------------------------------------------*/
269 /* Get widget data. */
270 /*--------------------------------------------------------------------------*/
272 gl_wdgt_text_entry_get_text (glWdgtTextEntry * text_entry)
274 GtkTextBuffer *buffer;
277 GtkTextIter start, end;
279 gl_debug (DEBUG_WDGT, "START");
281 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
283 gtk_text_buffer_get_bounds (buffer, &start, &end);
285 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
287 lines = gl_text_node_lines_new_from_text (text);
291 gl_debug (DEBUG_WDGT, "END");
296 /*--------------------------------------------------------------------------*/
297 /* Set widget data. */
298 /*--------------------------------------------------------------------------*/
300 gl_wdgt_text_entry_set_text (glWdgtTextEntry * text_entry,
304 GtkTextBuffer *buffer;
307 gl_debug (DEBUG_WDGT, "START");
309 gtk_widget_set_sensitive (text_entry->key_entry, merge_flag);
310 gtk_widget_set_sensitive (text_entry->insert_button, merge_flag);
312 text = gl_text_node_lines_expand (lines, NULL);
314 g_signal_handlers_block_by_func (G_OBJECT(text_entry->text_buffer),
315 changed_cb, text_entry);
316 gtk_text_buffer_set_text (text_entry->text_buffer, text, -1);
317 g_signal_handlers_unblock_by_func (G_OBJECT(text_entry->text_buffer),
318 changed_cb, text_entry);
320 gl_debug (DEBUG_WDGT, "END");