]> git.sur5r.net Git - glabels/blob - glabels2/src/wdgt-text-entry.c
Initial revision
[glabels] / glabels2 / src / wdgt-text-entry.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  wdgt_text_entry.c:  text entry widget module
5  *
6  *  Copyright (C) 2001-2002  Jim Evins <evins@snaught.com>.
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #include <config.h>
24
25 #include "wdgt-text-entry.h"
26 #include "merge.h"
27 #include "text-node.h"
28 #include "marshal.h"
29
30 #include "debug.h"
31
32 /*===========================================*/
33 /* Private types                             */
34 /*===========================================*/
35
36 enum {
37         CHANGED,
38         LAST_SIGNAL
39 };
40
41 typedef void (*glWdgtTextEntrySignal) (GObject * object, gpointer data);
42
43 /*===========================================*/
44 /* Private globals                           */
45 /*===========================================*/
46
47 static GtkContainerClass *parent_class;
48
49 static gint wdgt_text_entry_signals[LAST_SIGNAL] = { 0 };
50
51 /*===========================================*/
52 /* Local function prototypes                 */
53 /*===========================================*/
54
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);
60
61 static void changed_cb (glWdgtTextEntry * text_entry);
62 static void insert_cb (glWdgtTextEntry * text_entry);
63 \f
64 /*================================================================*/
65 /* Boilerplate Object stuff.                                      */
66 /*================================================================*/
67 guint
68 gl_wdgt_text_entry_get_type (void)
69 {
70         static guint wdgt_text_entry_type = 0;
71
72         if (!wdgt_text_entry_type) {
73                 GTypeInfo wdgt_text_entry_info = {
74                         sizeof (glWdgtTextEntryClass),
75                         NULL,
76                         NULL,
77                         (GClassInitFunc) gl_wdgt_text_entry_class_init,
78                         NULL,
79                         NULL,
80                         sizeof (glWdgtTextEntry),
81                         0,
82                         (GInstanceInitFunc) gl_wdgt_text_entry_instance_init,
83                 };
84
85                 wdgt_text_entry_type = g_type_register_static (gtk_vbox_get_type (),
86                                                                "glWdgtTextEntry",
87                                                                &wdgt_text_entry_info,
88                                                                0);
89         }
90
91         return wdgt_text_entry_type;
92 }
93
94 static void
95 gl_wdgt_text_entry_class_init (glWdgtTextEntryClass * class)
96 {
97         GObjectClass *object_class;
98
99         gl_debug (DEBUG_WDGT, "START");
100
101         object_class = (GObjectClass *) class;
102
103         parent_class = gtk_type_class (gtk_vbox_get_type ());
104
105         object_class->finalize = gl_wdgt_text_entry_finalize;
106
107         wdgt_text_entry_signals[CHANGED] =
108             g_signal_new ("changed",
109                           G_OBJECT_CLASS_TYPE(object_class),
110                           G_SIGNAL_RUN_LAST,
111                           G_STRUCT_OFFSET (glWdgtTextEntryClass, changed),
112                           NULL, NULL,
113                           gl_marshal_VOID__VOID, G_TYPE_NONE, 0);
114
115         gl_debug (DEBUG_WDGT, "END");
116 }
117
118 static void
119 gl_wdgt_text_entry_instance_init (glWdgtTextEntry * text_entry)
120 {
121         gl_debug (DEBUG_WDGT, "START");
122
123         text_entry->text_entry = NULL;
124         text_entry->key_entry = NULL;
125         text_entry->insert_button = NULL;
126
127         gl_debug (DEBUG_WDGT, "END");
128 }
129
130 static void
131 gl_wdgt_text_entry_finalize (GObject * object)
132 {
133         glWdgtTextEntry *text_entry;
134         glWdgtTextEntryClass *class;
135
136         gl_debug (DEBUG_WDGT, "START");
137
138         g_return_if_fail (object != NULL);
139         g_return_if_fail (GL_IS_WDGT_TEXT_ENTRY (object));
140
141         text_entry = GL_WDGT_TEXT_ENTRY (object);
142
143         G_OBJECT_CLASS (parent_class)->finalize (object);
144
145         gl_debug (DEBUG_WDGT, "END");
146 }
147
148 GtkWidget *
149 gl_wdgt_text_entry_new (gchar * label,
150                         GList * field_defs)
151 {
152         glWdgtTextEntry *text_entry;
153
154         gl_debug (DEBUG_WDGT, "START");
155
156         text_entry = g_object_new (gl_wdgt_text_entry_get_type (), NULL);
157
158         gl_wdgt_text_entry_construct (text_entry, label, field_defs);
159
160         gl_debug (DEBUG_WDGT, "END");
161
162         return GTK_WIDGET (text_entry);
163 }
164
165 /*============================================================*/
166 /* Construct composite widget.                                */
167 /*============================================================*/
168 static void
169 gl_wdgt_text_entry_construct (glWdgtTextEntry * text_entry,
170                               gchar * label,
171                               GList * field_defs)
172 {
173         GtkWidget *wvbox, *wframe, *wtable, *wlabel, *wcombo;
174         GList *keys;
175
176         gl_debug (DEBUG_WDGT, "START");
177
178         wvbox = GTK_WIDGET (text_entry);
179
180         wframe = gtk_frame_new (label);
181         gtk_box_pack_start (GTK_BOX (wvbox), wframe, FALSE, FALSE, 0);
182
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);
188
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,
198                                    0, 3, 0, 1);
199
200         /* Insert merge field label */
201         wlabel = gtk_label_new (_("Key:"));
202         gtk_table_attach_defaults (GTK_TABLE (wtable), wlabel, 0, 1, 1, 2);
203
204         /* Key entry widget */
205         wcombo = gtk_combo_new ();
206         keys = gl_merge_get_key_list (field_defs);
207         if (keys != NULL)
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);
214
215         /* Insert button */
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);
223
224         gl_debug (DEBUG_WDGT, "END");
225 }
226
227 /*--------------------------------------------------------------------------*/
228 /* PRIVATE.  Callback for when text has changed.                            */
229 /*--------------------------------------------------------------------------*/
230 static void
231 changed_cb (glWdgtTextEntry * text_entry)
232 {
233         gl_debug (DEBUG_WDGT, "START");
234
235         /* Emit our "changed" signal */
236         g_signal_emit (G_OBJECT (text_entry),
237                        wdgt_text_entry_signals[CHANGED], 0);
238
239         gl_debug (DEBUG_WDGT, "END");
240 }
241
242 /*--------------------------------------------------------------------------*/
243 /* PRIVATE.  Callback to insert field into text buffer.                     */
244 /*--------------------------------------------------------------------------*/
245 static void
246 insert_cb (glWdgtTextEntry * text_entry)
247 {
248         GtkTextBuffer *buffer;
249         gchar *key, *field;
250
251         gl_debug (DEBUG_WDGT, "START");
252
253         key =
254             gtk_editable_get_chars (GTK_EDITABLE (text_entry->key_entry), 0,
255                                     -1);
256         field = g_strdup_printf ("FIELD{%s}", key);
257
258         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
259         gtk_text_buffer_insert_at_cursor (buffer, field, -1);
260
261         g_free (field);
262         g_free (key);
263
264
265         gl_debug (DEBUG_WDGT, "END");
266 }
267
268 /*--------------------------------------------------------------------------*/
269 /* Get widget data.                                                         */
270 /*--------------------------------------------------------------------------*/
271 GList *
272 gl_wdgt_text_entry_get_text (glWdgtTextEntry * text_entry)
273 {
274         GtkTextBuffer *buffer;
275         gchar *text;
276         GList *lines;
277         GtkTextIter start, end;
278
279         gl_debug (DEBUG_WDGT, "START");
280
281         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_entry->text_entry));
282
283         gtk_text_buffer_get_bounds (buffer, &start, &end);
284
285         text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
286
287         lines = gl_text_node_lines_new_from_text (text);
288
289         g_free (text);
290
291         gl_debug (DEBUG_WDGT, "END");
292
293         return lines;
294 }
295
296 /*--------------------------------------------------------------------------*/
297 /* Set widget data.                                                         */
298 /*--------------------------------------------------------------------------*/
299 void
300 gl_wdgt_text_entry_set_text (glWdgtTextEntry * text_entry,
301                              gboolean merge_flag,
302                              GList * lines)
303 {
304         GtkTextBuffer *buffer;
305         gchar *text;
306
307         gl_debug (DEBUG_WDGT, "START");
308
309         gtk_widget_set_sensitive (text_entry->key_entry, merge_flag);
310         gtk_widget_set_sensitive (text_entry->insert_button, merge_flag);
311
312         text = gl_text_node_lines_expand (lines, NULL);
313
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);
319
320         gl_debug (DEBUG_WDGT, "END");
321 }