]> git.sur5r.net Git - glabels/blob - glabels2/src/merge-ui.c
Initial revision
[glabels] / glabels2 / src / merge-ui.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  merge_ui.c:  document merge user interface module
5  *
6  *  Copyright (C) 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 #include <config.h>
23
24 #include "merge-ui.h"
25 #include "marshal.h"
26
27 /* Backends */
28 #include "merge-ui-text.h"
29
30 #include "debug.h"
31
32 /*===========================================*/
33 /* Private types                             */
34 /*===========================================*/
35
36 enum {
37         CHANGED,
38         LAST_SIGNAL
39 };
40
41 typedef struct {
42
43         GtkWidget * (*src_new) (glMergeType);
44         void (*src_set_value) ();
45         gchar * (*src_get_value) ();
46
47         GtkWidget * (*field_ws_new) (glMergeType, gchar *);
48         void (*field_ws_set_field_defs) ();
49         GList * (*field_ws_get_field_defs) ();
50
51 } BackendFunctions;
52
53 /*===========================================*/
54 /* Private globals                           */
55 /*===========================================*/
56
57 static GtkContainerClass *parent_class;
58
59 static gint merge_ui_src_signals[LAST_SIGNAL] = { 0 };
60 static gint merge_ui_field_ws_signals[LAST_SIGNAL] = { 0 };
61
62 static BackendFunctions func[GL_MERGE_N_TYPES];
63
64 /*===========================================*/
65 /* Local function prototypes                 */
66 /*===========================================*/
67
68 static void gl_merge_ui_src_class_init (glMergeUISrcClass * class);
69 static void gl_merge_ui_src_instance_init (glMergeUISrc * src);
70 static void gl_merge_ui_src_finalize (GObject * object);
71
72 static void src_changed_cb (glMergeUISrc * src);
73
74 static void gl_merge_ui_field_ws_class_init (glMergeUIFieldWSClass * class);
75 static void gl_merge_ui_field_ws_instance_init (glMergeUIFieldWS * field_ws);
76 static void gl_merge_ui_field_ws_finalize (GObject * object);
77
78 static void field_ws_changed_cb (glMergeUIFieldWS * field_ws);
79 \f
80 /*****************************************************************************/
81 /* Initialize module.                                                        */
82 /*****************************************************************************/
83 void
84 gl_merge_ui_init (void)
85 {
86         gint i;
87
88         gl_debug (DEBUG_MERGE, "START");
89
90         /* Register backend functions. */
91
92         i = GL_MERGE_NONE;
93         func[i].src_new = NULL;
94         func[i].src_set_value = NULL;
95         func[i].src_get_value = NULL;
96         func[i].field_ws_new = NULL;
97         func[i].field_ws_set_field_defs = NULL;
98         func[i].field_ws_get_field_defs = NULL;
99
100         i = GL_MERGE_TEXT_TAB;
101         func[i].src_new = gl_merge_ui_text_src_new;
102         func[i].src_set_value = gl_merge_ui_text_src_set_value;
103         func[i].src_get_value = gl_merge_ui_text_src_get_value;
104         func[i].field_ws_new = gl_merge_ui_text_field_ws_new;
105         func[i].field_ws_set_field_defs =
106                 gl_merge_ui_text_field_ws_set_field_defs;
107         func[i].field_ws_get_field_defs =
108                 gl_merge_ui_text_field_ws_get_field_defs;
109
110         i = GL_MERGE_TEXT_COMMA;
111         func[i].src_new = gl_merge_ui_text_src_new;
112         func[i].src_set_value = gl_merge_ui_text_src_set_value;
113         func[i].src_get_value = gl_merge_ui_text_src_get_value;
114         func[i].field_ws_new = gl_merge_ui_text_field_ws_new;
115         func[i].field_ws_set_field_defs =
116                 gl_merge_ui_text_field_ws_set_field_defs;
117         func[i].field_ws_get_field_defs =
118                 gl_merge_ui_text_field_ws_get_field_defs;
119
120         i = GL_MERGE_TEXT_COLON;
121         func[i].src_new = gl_merge_ui_text_src_new;
122         func[i].src_set_value = gl_merge_ui_text_src_set_value;
123         func[i].src_get_value = gl_merge_ui_text_src_get_value;
124         func[i].field_ws_new = gl_merge_ui_text_field_ws_new;
125         func[i].field_ws_set_field_defs =
126                 gl_merge_ui_text_field_ws_set_field_defs;
127         func[i].field_ws_get_field_defs =
128                 gl_merge_ui_text_field_ws_get_field_defs;
129
130         gl_debug (DEBUG_MERGE, "END");
131 }
132
133 /*****************************************************************************/
134 /* Boilerplate Object stuff.                                                 */
135 /*****************************************************************************/
136 guint
137 gl_merge_ui_src_get_type (void)
138 {
139         static guint merge_ui_src_type = 0;
140
141         if (!merge_ui_src_type) {
142                 GTypeInfo merge_ui_src_info = {
143                         sizeof (glMergeUISrcClass),
144                         NULL,
145                         NULL,
146                         (GClassInitFunc) gl_merge_ui_src_class_init,
147                         NULL,
148                         NULL,
149                         sizeof (glMergeUISrc),
150                         0,
151                         (GInstanceInitFunc) gl_merge_ui_src_instance_init,
152                 };
153
154                 merge_ui_src_type =
155                         g_type_register_static (gtk_vbox_get_type (),
156                                                 "glMergeUISrc",
157                                                 &merge_ui_src_info, 0);
158         }
159
160         return merge_ui_src_type;
161 }
162
163 static void
164 gl_merge_ui_src_class_init (glMergeUISrcClass * class)
165 {
166         GObjectClass *object_class;
167
168         gl_debug (DEBUG_MERGE, "START");
169
170         object_class = (GObjectClass *) class;
171
172         parent_class = gtk_type_class (gtk_vbox_get_type ());
173
174         object_class->finalize = gl_merge_ui_src_finalize;
175
176         merge_ui_src_signals[CHANGED] =
177             g_signal_new ("changed",
178                           G_OBJECT_CLASS_TYPE(object_class),
179                           G_SIGNAL_RUN_LAST,
180                           G_STRUCT_OFFSET (glMergeUISrcClass, changed),
181                           NULL, NULL,
182                           gl_marshal_VOID__VOID,
183                           G_TYPE_NONE, 0);
184
185         gl_debug (DEBUG_MERGE, "END");
186 }
187
188 static void
189 gl_merge_ui_src_instance_init (glMergeUISrc * src)
190 {
191         gl_debug (DEBUG_MERGE, "START");
192         src->backend_widget = NULL;
193         gl_debug (DEBUG_MERGE, "END");
194 }
195
196 static void
197 gl_merge_ui_src_finalize (GObject * object)
198 {
199         glMergeUISrc *src;
200
201         gl_debug (DEBUG_MERGE, "START");
202
203         g_return_if_fail (object != NULL);
204         g_return_if_fail (GL_IS_MERGE_UI_SRC (object));
205
206         src = GL_MERGE_UI_SRC (object);
207
208         G_OBJECT_CLASS (parent_class)->finalize (object);
209
210         gl_debug (DEBUG_MERGE, "END");
211 }
212
213 GtkWidget *
214 gl_merge_ui_src_new (void)
215 {
216         glMergeUISrc *src;
217
218         gl_debug (DEBUG_MERGE, "START");
219
220         src = g_object_new (gl_merge_ui_src_get_type (), NULL);
221
222         src->type = GL_MERGE_NONE;
223         src->backend_widget = gtk_label_new (_("N/A"));
224         gtk_misc_set_alignment (GTK_MISC (src->backend_widget), 0, 0.5);
225         gtk_box_pack_start (GTK_BOX (src), src->backend_widget, FALSE, FALSE,
226                             0);
227
228         gl_debug (DEBUG_MERGE, "END");
229
230         return GTK_WIDGET (src);
231 }
232
233 /*--------------------------------------------------------------------------*/
234 /* PRIVATE.  Callback for when our backend widget has changed.              */
235 /*--------------------------------------------------------------------------*/
236 static void
237 src_changed_cb (glMergeUISrc * src)
238 {
239         gl_debug (DEBUG_MERGE, "START");
240
241         /* Emit our "changed" signal */
242         g_signal_emit (G_OBJECT (src), merge_ui_src_signals[CHANGED], 0);
243
244         gl_debug (DEBUG_MERGE, "END");
245 }
246
247 /*****************************************************************************/
248 /* Set type.                                                                 */
249 /*****************************************************************************/
250 void
251 gl_merge_ui_src_set_type (glMergeUISrc * src,
252                           glMergeType type)
253 {
254         gl_debug (DEBUG_MERGE, "START");
255
256         if (type != src->type) {
257
258                 gtk_widget_destroy (src->backend_widget);
259
260                 src->type = type;
261
262                 if (type != GL_MERGE_NONE) {
263                         src->backend_widget = (func[type].src_new) (type);
264                 } else {
265                         src->backend_widget = gtk_label_new (_("N/A"));
266                         gtk_misc_set_alignment (GTK_MISC (src->backend_widget),
267                                                 0, 0.5);
268                 }
269
270                 gtk_box_pack_start (GTK_BOX (src), src->backend_widget,
271                                     FALSE, FALSE, 0);
272
273                 if (GTK_WIDGET_VISIBLE (src)) {
274                         gtk_widget_show_all (src->backend_widget);
275                 }
276
277                 if (type != GL_MERGE_NONE) {
278                         g_signal_connect_swapped (G_OBJECT(src->backend_widget),
279                                                   "changed",
280                                                   G_CALLBACK(src_changed_cb),
281                                                   G_OBJECT (src));
282                 }
283
284                 /* Emit our "changed" signal */
285                 g_signal_emit (G_OBJECT (src),
286                                merge_ui_src_signals[CHANGED], 0);
287         }
288
289
290         gl_debug (DEBUG_MERGE, "END");
291 }
292
293 /*****************************************************************************/
294 /* Set src.                                                                  */
295 /*****************************************************************************/
296 void
297 gl_merge_ui_src_set_value (glMergeUISrc * src,
298                            gchar * text)
299 {
300         glMergeType type;
301
302         gl_debug (DEBUG_MERGE, "START");
303
304         type = src->type;
305
306         if (type != GL_MERGE_NONE) {
307                 func[type].src_set_value (src->backend_widget, text);
308         } else {
309                 gl_debug (DEBUG_MERGE, "END");
310                 return;
311         }
312
313         gl_debug (DEBUG_MERGE, "END");
314 }
315
316 /*****************************************************************************/
317 /* Get src name.                                                             */
318 /*****************************************************************************/
319 gchar *
320 gl_merge_ui_src_get_value (glMergeUISrc * src)
321 {
322         glMergeType type;
323
324         gl_debug (DEBUG_MERGE, "");
325
326         type = src->type;
327
328         if (type != GL_MERGE_NONE) {
329                 return func[type].src_get_value (src->backend_widget);
330         } else {
331                 return NULL;
332         }
333
334 }
335
336 /*****************************************************************************/
337 /* Boilerplate Object stuff.                                                 */
338 /*****************************************************************************/
339 guint
340 gl_merge_ui_field_ws_get_type (void)
341 {
342         static guint merge_ui_field_ws_type = 0;
343
344         gl_debug (DEBUG_MERGE, "START");
345
346         if (!merge_ui_field_ws_type) {
347                 GTypeInfo merge_ui_field_ws_info = {
348                         sizeof (glMergeUIFieldWSClass),
349                         NULL,
350                         NULL,
351                         (GClassInitFunc) gl_merge_ui_field_ws_class_init,
352                         NULL,
353                         NULL,
354                         sizeof (glMergeUIFieldWS),
355                         0,
356                         (GInstanceInitFunc) gl_merge_ui_field_ws_instance_init,
357                 };
358
359                 merge_ui_field_ws_type =
360                         g_type_register_static (gtk_vbox_get_type (),
361                                                 "glMergeUIFieldWS",
362                                                 &merge_ui_field_ws_info, 0);
363         }
364
365         gl_debug (DEBUG_MERGE, "END");
366
367         return merge_ui_field_ws_type;
368 }
369
370 static void
371 gl_merge_ui_field_ws_class_init (glMergeUIFieldWSClass * class)
372 {
373         GObjectClass *object_class;
374
375         gl_debug (DEBUG_MERGE, "START");
376
377         object_class = (GObjectClass *) class;
378
379         parent_class = gtk_type_class (gtk_vbox_get_type ());
380
381         object_class->finalize = gl_merge_ui_field_ws_finalize;
382
383         merge_ui_field_ws_signals[CHANGED] =
384             g_signal_new ("changed",
385                           G_OBJECT_CLASS_TYPE(object_class),
386                           G_SIGNAL_RUN_LAST,
387                           G_STRUCT_OFFSET (glMergeUIFieldWSClass, changed),
388                           NULL, NULL,
389                           gl_marshal_VOID__VOID,
390                           G_TYPE_NONE, 0);
391
392         gl_debug (DEBUG_MERGE, "END");
393 }
394
395 static void
396 gl_merge_ui_field_ws_instance_init (glMergeUIFieldWS * field_ws)
397 {
398         gl_debug (DEBUG_MERGE, "START");
399
400         field_ws->type = GL_MERGE_NONE;
401         field_ws->src = NULL;
402         field_ws->backend_widget = NULL;
403
404         gl_debug (DEBUG_MERGE, "END");
405 }
406
407 static void
408 gl_merge_ui_field_ws_finalize (GObject * object)
409 {
410         glMergeUIFieldWS *field_ws;
411         glMergeUIFieldWSClass *class;
412
413         gl_debug (DEBUG_MERGE, "START");
414
415         g_return_if_fail (object != NULL);
416         g_return_if_fail (GL_IS_MERGE_UI_FIELD_WS (object));
417
418         field_ws = GL_MERGE_UI_FIELD_WS (object);
419
420         G_OBJECT_CLASS (parent_class)->finalize (object);
421
422         gl_debug (DEBUG_MERGE, "END");
423 }
424
425 GtkWidget *
426 gl_merge_ui_field_ws_new (void)
427 {
428         glMergeUIFieldWS *field_ws;
429
430         gl_debug (DEBUG_MERGE, "START");
431
432         field_ws = g_object_new (gl_merge_ui_field_ws_get_type (), NULL);
433
434         field_ws->type = GL_MERGE_NONE;
435         field_ws->backend_widget = gtk_label_new (_("N/A"));
436         gtk_misc_set_alignment (GTK_MISC (field_ws->backend_widget), 0, 0.5);
437         gtk_box_pack_start (GTK_BOX (field_ws), field_ws->backend_widget,
438                             FALSE, FALSE, 0);
439
440         gl_debug (DEBUG_MERGE, "END");
441
442         return GTK_WIDGET (field_ws);
443 }
444
445 /*--------------------------------------------------------------------------*/
446 /* PRIVATE.  Callback for when our backend widget has changed.              */
447 /*--------------------------------------------------------------------------*/
448 static void
449 field_ws_changed_cb (glMergeUIFieldWS * field_ws)
450 {
451         gl_debug (DEBUG_MERGE, "START");
452
453         /* Emit our "changed" signal */
454         g_signal_emit (G_OBJECT (field_ws),
455                        merge_ui_field_ws_signals[CHANGED], 0);
456
457         gl_debug (DEBUG_MERGE, "END");
458 }
459
460 /*****************************************************************************/
461 /* set type and src data, create appropriate backend widget.                 */
462 /*****************************************************************************/
463 void
464 gl_merge_ui_field_ws_set_type_src (glMergeUIFieldWS * field_ws,
465                                    glMergeType type,
466                                    gchar * src)
467 {
468         gl_debug (DEBUG_MERGE, "START");
469
470         if (field_ws->src != NULL)
471                 g_free (field_ws->src);
472         if (field_ws->backend_widget != NULL) {
473                 gtk_widget_destroy (field_ws->backend_widget);
474         }
475
476         field_ws->type = type;
477         field_ws->src = g_strdup (src);
478
479         if (type != GL_MERGE_NONE) {
480                 field_ws->backend_widget =
481                     (func[type].field_ws_new) (type, src);
482         } else {
483                 field_ws->backend_widget = gtk_label_new (_("N/A"));
484                 gtk_misc_set_alignment (GTK_MISC (field_ws->backend_widget), 0,
485                                         0.5);
486         }
487
488         gtk_box_pack_start (GTK_BOX (field_ws), field_ws->backend_widget,
489                             FALSE, FALSE, 0);
490
491         if (type != GL_MERGE_NONE) {
492                 g_signal_connect_swapped (G_OBJECT(field_ws->backend_widget),
493                                           "changed",
494                                           G_CALLBACK(field_ws_changed_cb),
495                                           G_OBJECT (field_ws));
496         }
497
498         if (GTK_WIDGET_VISIBLE (field_ws)) {
499                 gtk_widget_show_all (field_ws->backend_widget);
500         }
501         /* Emit our "changed" signal */
502         g_signal_emit (G_OBJECT (field_ws),
503                        merge_ui_field_ws_signals[CHANGED], 0);
504
505         gl_debug (DEBUG_MERGE, "END");
506 }
507
508 /*****************************************************************************/
509 /* Set field definitions (associate ids with raw fields).                    */
510 /*****************************************************************************/
511 void
512 gl_merge_ui_field_ws_set_field_defs (glMergeUIFieldWS * field_ws,
513                                      GList * field_defs)
514 {
515         glMergeType type;
516
517         gl_debug (DEBUG_MERGE, "START");
518
519         type = field_ws->type;
520
521         if (type != GL_MERGE_NONE) {
522
523                 (func[type].field_ws_set_field_defs) (field_ws->backend_widget,
524                                                       field_defs);
525
526                 /* Emit our "changed" signal */
527                 g_signal_emit (G_OBJECT (field_ws),
528                                merge_ui_field_ws_signals[CHANGED], 0);
529
530         }
531
532         gl_debug (DEBUG_MERGE, "END");
533 }
534
535 /*****************************************************************************/
536 /* Get field definitions (associate ids with raw fields).                    */
537 /*****************************************************************************/
538 GList *
539 gl_merge_ui_field_ws_get_field_defs (glMergeUIFieldWS * field_ws)
540 {
541         glMergeType type;
542
543         gl_debug (DEBUG_MERGE, "");
544
545         type = field_ws->type;
546
547         if (type != GL_MERGE_NONE) {
548
549                 return (func[type].field_ws_get_field_defs) (field_ws->
550                                                              backend_widget);
551         } else {
552
553                 return NULL;
554
555         }
556
557 }