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 glHigVBoxClass *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,
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 =
86 g_type_register_static (gl_hig_vbox_get_type (),
88 &wdgt_text_entry_info, 0);
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 = g_type_class_peek_parent (class);
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;
125 text_entry->key_combo = NULL;
126 text_entry->key_entry = NULL;
127 text_entry->insert_button = NULL;
129 gl_debug (DEBUG_WDGT, "END");
133 gl_wdgt_text_entry_finalize (GObject *object)
135 glWdgtTextEntry *text_entry;
136 glWdgtTextEntryClass *class;
138 gl_debug (DEBUG_WDGT, "START");
140 g_return_if_fail (object != NULL);
141 g_return_if_fail (GL_IS_WDGT_TEXT_ENTRY (object));
143 text_entry = GL_WDGT_TEXT_ENTRY (object);
145 G_OBJECT_CLASS (parent_class)->finalize (object);
147 gl_debug (DEBUG_WDGT, "END");
150 /****************************************************************************/
152 /****************************************************************************/
154 gl_wdgt_text_entry_new (glMerge *merge)
156 glWdgtTextEntry *text_entry;
158 gl_debug (DEBUG_WDGT, "START");
160 text_entry = g_object_new (gl_wdgt_text_entry_get_type (), NULL);
162 gl_wdgt_text_entry_construct (text_entry, merge);
164 gl_debug (DEBUG_WDGT, "END");
166 return GTK_WIDGET (text_entry);
169 /*--------------------------------------------------------------------------*/
170 /* PRIVATE. Construct composite widget. */
171 /*--------------------------------------------------------------------------*/
173 gl_wdgt_text_entry_construct (glWdgtTextEntry *text_entry,
176 GtkWidget *wvbox, *whbox, *wscroll;
179 gl_debug (DEBUG_WDGT, "START");
181 wvbox = GTK_WIDGET (text_entry);
183 /* ---- Entry line ---- */
184 whbox = gl_hig_hbox_new ();
185 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox), whbox);
188 text_entry->edit_label = gtk_label_new (_("Edit text:"));
189 gtk_misc_set_alignment (GTK_MISC (text_entry->edit_label), 0, 0);
190 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), text_entry->edit_label);
192 /* Actual text entry widget */
193 wscroll = gtk_scrolled_window_new (NULL, NULL);
194 gtk_widget_set_size_request (wscroll, -1, 70);
195 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
196 GTK_POLICY_AUTOMATIC,
197 GTK_POLICY_AUTOMATIC);
198 gl_hig_hbox_add_widget_justify (GL_HIG_HBOX(whbox), wscroll);
199 text_entry->text_entry = gtk_text_view_new ();
200 text_entry->text_buffer =
201 gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
202 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (wscroll),
203 text_entry->text_entry);
204 g_signal_connect_swapped (G_OBJECT (text_entry->text_buffer),
205 "changed", G_CALLBACK (changed_cb),
206 G_OBJECT (text_entry));
208 /* ---- Merge field line ---- */
209 whbox = gl_hig_hbox_new ();
210 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox), whbox);
212 /* Insert merge field label */
213 text_entry->key_label = gtk_label_new (_("Key:"));
214 gtk_misc_set_alignment (GTK_MISC (text_entry->key_label), 0, 0.5);
215 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), text_entry->key_label);
217 /* Key entry widget */
218 text_entry->key_combo = gtk_combo_new ();
219 keys = gl_merge_get_key_list (merge);
221 gtk_combo_set_popdown_strings (GTK_COMBO (text_entry->key_combo),
223 gl_merge_free_key_list (&keys);
224 text_entry->key_entry = GTK_COMBO (text_entry->key_combo)->entry;
225 gtk_entry_set_editable (GTK_ENTRY (text_entry->key_entry), FALSE);
226 gtk_widget_set_size_request (text_entry->key_combo, 200, -1);
227 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), text_entry->key_combo);
230 text_entry->insert_button =
231 gtk_button_new_with_label (_("Insert merge field"));
232 g_signal_connect_swapped (G_OBJECT (text_entry->insert_button),
233 "clicked", G_CALLBACK (insert_cb),
234 G_OBJECT (text_entry));
235 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), text_entry->insert_button);
237 gl_debug (DEBUG_WDGT, "END");
240 /*--------------------------------------------------------------------------*/
241 /* PRIVATE. Callback for when text has changed. */
242 /*--------------------------------------------------------------------------*/
244 changed_cb (glWdgtTextEntry *text_entry)
246 gl_debug (DEBUG_WDGT, "START");
248 /* Emit our "changed" signal */
249 g_signal_emit (G_OBJECT (text_entry),
250 wdgt_text_entry_signals[CHANGED], 0);
252 gl_debug (DEBUG_WDGT, "END");
255 /*--------------------------------------------------------------------------*/
256 /* PRIVATE. Callback to insert field into text buffer. */
257 /*--------------------------------------------------------------------------*/
259 insert_cb (glWdgtTextEntry *text_entry)
261 GtkTextBuffer *buffer;
264 gl_debug (DEBUG_WDGT, "START");
267 gtk_editable_get_chars (GTK_EDITABLE (text_entry->key_entry), 0,
269 field = g_strdup_printf ("${%s}", key);
270 gl_debug (DEBUG_WDGT, "Inserting %s", field);
272 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
273 gtk_text_buffer_insert_at_cursor (buffer, field, -1);
279 gl_debug (DEBUG_WDGT, "END");
282 /****************************************************************************/
283 /* Set new field definitions. */
284 /****************************************************************************/
286 gl_wdgt_text_entry_set_field_defs (glWdgtTextEntry *text_entry,
291 keys = gl_merge_get_key_list (merge);
292 if ( keys != NULL ) {
293 gtk_combo_set_popdown_strings (GTK_COMBO (text_entry->key_combo),
295 gl_merge_free_key_list (&keys);
297 keys = g_list_append (keys, "");
298 gtk_combo_set_popdown_strings (GTK_COMBO (text_entry->key_combo),
304 /****************************************************************************/
305 /* Get widget data. */
306 /****************************************************************************/
308 gl_wdgt_text_entry_get_text (glWdgtTextEntry *text_entry)
310 GtkTextBuffer *buffer;
313 GtkTextIter start, end;
315 gl_debug (DEBUG_WDGT, "START");
317 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
319 gtk_text_buffer_get_bounds (buffer, &start, &end);
321 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
323 lines = gl_text_node_lines_new_from_text (text);
327 gl_debug (DEBUG_WDGT, "END");
332 /****************************************************************************/
333 /* Set widget data. */
334 /****************************************************************************/
336 gl_wdgt_text_entry_set_text (glWdgtTextEntry *text_entry,
340 GtkTextBuffer *buffer;
343 gl_debug (DEBUG_WDGT, "START");
345 gtk_widget_set_sensitive (text_entry->key_combo, merge_flag);
346 gtk_widget_set_sensitive (text_entry->insert_button, merge_flag);
348 text = gl_text_node_lines_expand (lines, NULL);
350 g_signal_handlers_block_by_func (G_OBJECT(text_entry->text_buffer),
351 changed_cb, text_entry);
352 gtk_text_buffer_set_text (text_entry->text_buffer, text, -1);
353 g_signal_handlers_unblock_by_func (G_OBJECT(text_entry->text_buffer),
354 changed_cb, text_entry);
356 gl_debug (DEBUG_WDGT, "END");
359 /*****************************************************************************/
360 /* Set size group for internal labels */
361 /*****************************************************************************/
363 gl_wdgt_text_entry_set_label_size_group (glWdgtTextEntry *text_entry,
364 GtkSizeGroup *label_size_group)
366 gtk_size_group_add_widget (label_size_group, text_entry->edit_label);
367 gtk_size_group_add_widget (label_size_group, text_entry->key_label);