~ubuntu-branches/ubuntu/karmic/mergeant/karmic

« back to all changes in this revision

Viewing changes to libmergeant/mg-form.c

  • Committer: Bazaar Package Importer
  • Author(s): Gustavo R. Montesino
  • Date: 2007-11-29 08:44:48 UTC
  • mfrom: (2.1.4 hardy)
  • Revision ID: james.westby@ubuntu.com-20071129084448-6aon73d22bv6hzfw
Tags: 0.67-3
* Re-enable installation of the mime files in mergeant.install
* mergeant.dirs: create usr/share/mime/packages to make dh_installmime add
  the update-mime-database code snippets

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* mg-form.c
2
 
 *
3
 
 * Copyright (C) 2002 - 2004 Vivien Malerba
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License as
7
 
 * published by the Free Software Foundation; either version 2 of the
8
 
 * License, or (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18
 
 * USA
19
 
 */
20
 
 
21
 
#include <string.h>
22
 
#ifdef has_libgnomedb
23
 
#include <libgnomedb/libgnomedb.h>
24
 
#endif
25
 
#include "mg-form.h"
26
 
#include "mg-server.h"
27
 
#include "marshal.h"
28
 
#include "mg-parameter.h"
29
 
#include "mg-data-handler.h"
30
 
#include "mg-data-entry.h"
31
 
#include "mg-server-data-type.h"
32
 
#include "mg-query.h"
33
 
#include "mg-field.h"
34
 
#include "mg-context.h"
35
 
#include <libmergeant/handlers/mg-entry-combo.h>
36
 
 
37
 
static void mg_form_class_init (MgFormClass * class);
38
 
static void mg_form_init (MgForm * wid);
39
 
static void mg_form_dispose (GObject   * object);
40
 
 
41
 
static void entry_contents_modified (MgDataEntry *entry, MgForm *form);
42
 
static void parameter_changed_cb (MgParameter *param, MgDataEntry *entry);
43
 
 
44
 
static void mark_not_null_entry_labels (MgForm *form, gboolean show_mark);
45
 
enum
46
 
{
47
 
        PARAM_CHANGED,
48
 
        LAST_SIGNAL
49
 
};
50
 
 
51
 
 
52
 
struct _MgFormPriv
53
 
{
54
 
        MgConf            *conf;
55
 
        MgContext         *context;/* parameters, etc */
56
 
        GSList            *entries;/* list of MgDataEntry widgets */
57
 
        GSList            *not_null_labels;/* list of GtkLabel widgets corresponding to NOT NULL entries */
58
 
        gulong            *signal_ids; /* array of signal ids */
59
 
        GtkWidget         *entries_table;
60
 
        GSList            *hidden_entries;
61
 
 
62
 
        gboolean           forward_param_updates; /* forward them to the MgDataEntry widgets ? */
63
 
        GtkTooltips       *tooltips;
64
 
};
65
 
 
66
 
 
67
 
static gint mg_form_signals[LAST_SIGNAL] = { 0 };
68
 
 
69
 
/* get a pointer to the parents to be able to call their destructor */
70
 
static GObjectClass *parent_class = NULL;
71
 
 
72
 
guint
73
 
mg_form_get_type (void)
74
 
{
75
 
        static GType type = 0;
76
 
 
77
 
        if (!type) {
78
 
                static const GTypeInfo info = {
79
 
                        sizeof (MgFormClass),
80
 
                        (GBaseInitFunc) NULL,
81
 
                        (GBaseFinalizeFunc) NULL,
82
 
                        (GClassInitFunc) mg_form_class_init,
83
 
                        NULL,
84
 
                        NULL,
85
 
                        sizeof (MgForm),
86
 
                        0,
87
 
                        (GInstanceInitFunc) mg_form_init
88
 
                };              
89
 
                
90
 
                type = g_type_register_static (GTK_TYPE_VBOX, "MgForm", &info, 0);
91
 
        }
92
 
 
93
 
        return type;
94
 
}
95
 
 
96
 
static void
97
 
mg_form_class_init (MgFormClass * class)
98
 
{
99
 
        GObjectClass   *object_class = G_OBJECT_CLASS (class);
100
 
        
101
 
        parent_class = g_type_class_peek_parent (class);
102
 
 
103
 
        mg_form_signals[PARAM_CHANGED] =
104
 
                g_signal_new ("param_changed",
105
 
                              G_TYPE_FROM_CLASS (object_class),
106
 
                              G_SIGNAL_RUN_FIRST,
107
 
                              G_STRUCT_OFFSET (MgFormClass, param_changed),
108
 
                              NULL, NULL,
109
 
                              marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
110
 
                              G_TYPE_OBJECT, G_TYPE_BOOLEAN);
111
 
 
112
 
        class->param_changed = NULL;
113
 
        object_class->dispose = mg_form_dispose;
114
 
}
115
 
 
116
 
static void
117
 
mg_form_init (MgForm * wid)
118
 
{
119
 
        wid->priv = g_new0 (MgFormPriv, 1);
120
 
        wid->priv->conf = NULL;
121
 
        wid->priv->context = NULL;
122
 
        wid->priv->entries = NULL;
123
 
        wid->priv->not_null_labels = NULL;
124
 
        wid->priv->entries_table = NULL;
125
 
        wid->priv->hidden_entries = NULL;
126
 
        wid->priv->signal_ids = NULL;
127
 
 
128
 
        wid->priv->forward_param_updates = TRUE;
129
 
        wid->priv->tooltips = NULL;
130
 
}
131
 
 
132
 
static void mg_form_initialize (MgForm *form, MgConf *conf, GtkWidget *layout, GHashTable *box_widgets);
133
 
static void widget_shown_cb (GtkWidget *wid, MgForm *form);
134
 
static void mg_conf_weak_notify (MgForm *form, MgConf *conf);
135
 
/**
136
 
 * mg_form_new
137
 
 * @conf: a #MgConf object
138
 
 * @context: a #MgContext structure
139
 
 *
140
 
 * Creates a new #MgForm widget using all the parameters provided in @context.
141
 
 * @context is copied in the process.
142
 
 *
143
 
 * The global layout is rendered using a table (a #GtkTable), and an entry is created for each
144
 
 * node of @context.
145
 
 *
146
 
 * Returns: the new widget
147
 
 */
148
 
GtkWidget *
149
 
mg_form_new (MgConf *conf, MgContext *context)
150
 
{
151
 
        return mg_form_new_in_layout (conf, context, NULL, NULL);
152
 
}
153
 
 
154
 
static void context_translate_boxes (gpointer key, gpointer value, GHashTable *data_hash);
155
 
/**
156
 
 * mg_form_new_in_layout
157
 
 * @conf: a #MgConf object
158
 
 * @context: a #MgContext structure
159
 
 * @layout: a #GtkWidget container of all the widgets in @box_widgets
160
 
 * @box_widgets: a #GHashTable of #GtkBox widgets
161
 
 *
162
 
 * Creates a new #MgForm widget using all the parameters provided in @context.
163
 
 * @context is copied in the process.
164
 
 *
165
 
 * This function is identical to mg_form_new() except that the layout is not done using a table, but
166
 
 * using the @layout widget; and each entry is packed into one of the #GtkBox widgets of @box_widgets
167
 
 * (specifically each entry corresponds to a #MgContextNode of @context, and that context node
168
 
 * is used a the key to @box_widgets to find the box to pack the entry in).
169
 
 *
170
 
 * If any of @layout or @box_widgets is %NULL, then this function is equivalent to mg_form_new().
171
 
 *
172
 
 * Returns: the new widget
173
 
 */
174
 
GtkWidget *
175
 
mg_form_new_in_layout (MgConf *conf, MgContext *context, GtkWidget *layout, GHashTable *box_widgets)
176
 
{
177
 
        GObject *obj;
178
 
        MgForm *form;
179
 
        GHashTable *repl = NULL;
180
 
 
181
 
        g_return_val_if_fail (conf && IS_MG_CONF (conf), NULL);
182
 
        if (context) 
183
 
                g_return_val_if_fail (mg_context_is_coherent (context, NULL), NULL);
184
 
 
185
 
        obj = g_object_new (MG_FORM_TYPE, NULL);
186
 
        form = MG_FORM (obj);
187
 
 
188
 
        form->priv->conf = conf;
189
 
        
190
 
        /* context copy, parameters are not copied */
191
 
        if (context) {
192
 
                if (box_widgets) {
193
 
                        repl = g_hash_table_new (NULL, NULL);
194
 
                        form->priv->context = MG_CONTEXT (mg_context_new_copy (context, FALSE, repl));
195
 
                        g_hash_table_foreach (box_widgets, (GHFunc) context_translate_boxes, repl);
196
 
                        box_widgets = repl;
197
 
                }
198
 
                else
199
 
                        form->priv->context = MG_CONTEXT (mg_context_new_copy (context, FALSE, repl));  
200
 
        }
201
 
        else
202
 
                form->priv->context = MG_CONTEXT (mg_context_new (conf, NULL));
203
 
 
204
 
        g_object_weak_ref (G_OBJECT (form->priv->conf),
205
 
                           (GWeakNotify) mg_conf_weak_notify, form);
206
 
 
207
 
        mg_form_initialize (form, conf, layout, box_widgets);
208
 
        if (repl)
209
 
                g_hash_table_destroy (repl);
210
 
 
211
 
        return GTK_WIDGET (obj);
212
 
}
213
 
 
214
 
static void
215
 
context_translate_boxes (gpointer key, gpointer value, GHashTable *data_hash)
216
 
{
217
 
        gpointer newkey = g_hash_table_lookup (data_hash, key);
218
 
        g_hash_table_insert (data_hash, newkey, value);
219
 
}
220
 
 
221
 
static void
222
 
widget_shown_cb (GtkWidget *wid, MgForm *form)
223
 
{
224
 
        if (g_slist_find (form->priv->hidden_entries, wid)) {
225
 
                if (form->priv->entries_table && g_slist_find (form->priv->entries, wid)) {
226
 
                        gint row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (wid), "row_no"));
227
 
                        gtk_table_set_row_spacing (GTK_TABLE (form->priv->entries_table), row, 0);
228
 
                }
229
 
                
230
 
                gtk_widget_hide (wid);
231
 
        }
232
 
}
233
 
 
234
 
static void
235
 
mg_conf_weak_notify (MgForm *form, MgConf *conf)
236
 
{
237
 
        GSList *list;
238
 
 
239
 
        /* render all the entries non sensitive */
240
 
        list = form->priv->entries;
241
 
        while (list) {
242
 
                gtk_widget_set_sensitive (GTK_WIDGET (list->data), FALSE);
243
 
                list = g_slist_next (list);
244
 
        }
245
 
 
246
 
        /* Tell that we don't need to weak unref the MgConf */
247
 
        form->priv->conf = NULL;
248
 
}
249
 
 
250
 
static void
251
 
mg_form_dispose (GObject *object)
252
 
{
253
 
        MgForm *form;
254
 
 
255
 
        g_return_if_fail (object != NULL);
256
 
        g_return_if_fail (IS_MG_FORM (object));
257
 
        form = MG_FORM (object);
258
 
 
259
 
        if (form->priv) {
260
 
                GSList *list;
261
 
 
262
 
                /* context */
263
 
                if (form->priv->context) {
264
 
                        gint i = 0;
265
 
                        list = form->priv->context->parameters;;
266
 
                        while (list) {
267
 
                                g_signal_handler_disconnect (G_OBJECT (list->data), form->priv->signal_ids[i]);
268
 
 
269
 
                                list = g_slist_next (list);
270
 
                                i++;
271
 
                        }
272
 
 
273
 
                        g_object_unref (G_OBJECT (form->priv->context));
274
 
                        form->priv->context = NULL;
275
 
                }
276
 
 
277
 
                /* list of entries */
278
 
                list = form->priv->hidden_entries;
279
 
                if (list) {
280
 
                        while (list) { 
281
 
                                g_signal_handlers_disconnect_by_func (G_OBJECT (list->data), 
282
 
                                                                      G_CALLBACK (widget_shown_cb), form);
283
 
                                list = g_slist_next (list);
284
 
                        }
285
 
                        g_slist_free (form->priv->hidden_entries);
286
 
                        form->priv->hidden_entries = NULL;
287
 
                }
288
 
 
289
 
                list = form->priv->entries;
290
 
                if (list) {
291
 
                        while (list) { 
292
 
                                g_object_set_data (G_OBJECT (list->data), "param", NULL);
293
 
                                list = g_slist_next (list);
294
 
                        }
295
 
                        g_slist_free (form->priv->entries);
296
 
                        form->priv->entries = NULL;
297
 
                }
298
 
 
299
 
                if (form->priv->not_null_labels)
300
 
                        g_slist_free (form->priv->not_null_labels);
301
 
 
302
 
                /* Weak unref the MgConf is necessary */
303
 
                if (form->priv->conf)
304
 
                        g_object_weak_unref (G_OBJECT (form->priv->conf),
305
 
                                             (GWeakNotify) mg_conf_weak_notify, form);
306
 
                
307
 
                /* tooltips */
308
 
                if (form->priv->tooltips) {
309
 
                        gtk_object_destroy (GTK_OBJECT (form->priv->tooltips));
310
 
                        form->priv->tooltips = NULL;
311
 
                }
312
 
 
313
 
 
314
 
                /* the private area itself */
315
 
                g_free (form->priv);
316
 
                form->priv = NULL;
317
 
        }
318
 
 
319
 
        /* for the parent class */
320
 
        parent_class->dispose (object);
321
 
}
322
 
 
323
 
 
324
 
 
325
 
/*
326
 
 * create the entries in the widget
327
 
 */
328
 
static void 
329
 
mg_form_initialize (MgForm *form, MgConf *conf, GtkWidget *layout, GHashTable *box_widgets)
330
 
{
331
 
        GSList *list;
332
 
        MgParameter *param;
333
 
        MgContextNode *node;
334
 
        gint i;
335
 
        
336
 
        /* tooltips */
337
 
        form->priv->tooltips = gtk_tooltips_new ();
338
 
 
339
 
        /* context management */
340
 
        if (form->priv->context && !form->priv->context->nodes) {
341
 
                MgContext *ncontext = MG_CONTEXT (mg_context_new (conf, form->priv->context->parameters));
342
 
                g_object_unref (G_OBJECT (form->priv->context));
343
 
                form->priv->context = ncontext;
344
 
        }
345
 
 
346
 
        /* allocating space for the signal ids */
347
 
        form->priv->signal_ids = g_new0 (gulong, g_slist_length (form->priv->context->parameters));
348
 
        i = 0;
349
 
 
350
 
        /* creating all the entries */
351
 
        list = form->priv->context->nodes;
352
 
        while (list) {
353
 
                GtkWidget *entry = NULL;
354
 
 
355
 
                node = MG_CONTEXT_NODE (list->data);
356
 
                if ((param = node->param)) { /* single direct parameter */
357
 
                        MgServerDataType *type;
358
 
                        const GdaValue *val, *default_val, *value;
359
 
                        gboolean nnul;
360
 
                        MgDataHandler *dh = NULL;
361
 
                        gchar *plugin = NULL;
362
 
 
363
 
                        type = mg_parameter_get_data_type (param);
364
 
                        g_assert (type);
365
 
 
366
 
                        g_object_get (G_OBJECT (param), "handler_plugin", &plugin, NULL);
367
 
                        if (plugin) {
368
 
                                dh = mg_server_get_handler_by_name (mg_conf_get_server (conf), plugin);
369
 
 
370
 
                                /* test if plugin can handle the parameter's data type */
371
 
                                if (!mg_data_handler_accepts_gda_type (dh, mg_server_data_type_get_gda_type (type)))
372
 
                                        dh = NULL;
373
 
                        }
374
 
                        else
375
 
                                dh = mg_server_data_type_get_handler (type);
376
 
                        val = mg_parameter_get_value (param);
377
 
                        default_val = mg_parameter_get_default_value (param);
378
 
                        nnul = mg_parameter_get_not_null (param);
379
 
 
380
 
                        /* determine initial value */
381
 
                        value = val;
382
 
                        if (!value && default_val && 
383
 
                            (gda_value_get_type (default_val) == mg_server_data_type_get_gda_type (type)))
384
 
                                value = default_val;
385
 
                        
386
 
                        /* create entry */
387
 
                        entry = GTK_WIDGET (mg_data_handler_get_entry_from_value (dh, value,
388
 
                                             mg_server_data_type_get_gda_type (type)));
389
 
 
390
 
                        /* set current value */
391
 
                        mg_data_entry_set_value (MG_DATA_ENTRY (entry), val);
392
 
 
393
 
                        if (!nnul ||
394
 
                            (nnul && value && (gda_value_get_type (value) != GDA_VALUE_TYPE_NULL)))
395
 
                                mg_data_entry_set_value_orig (MG_DATA_ENTRY (entry), value);
396
 
                        
397
 
                        if (default_val) {
398
 
                                mg_data_entry_set_value_default (MG_DATA_ENTRY (entry), default_val);
399
 
                                mg_data_entry_set_attributes (MG_DATA_ENTRY (entry),
400
 
                                                              MG_DATA_ENTRY_CAN_BE_DEFAULT,
401
 
                                                              MG_DATA_ENTRY_CAN_BE_DEFAULT);
402
 
                        }
403
 
 
404
 
                        mg_data_entry_set_attributes (MG_DATA_ENTRY (entry),
405
 
                                                      nnul ? 0 : MG_DATA_ENTRY_CAN_BE_NULL,
406
 
                                                      MG_DATA_ENTRY_CAN_BE_NULL);
407
 
                            
408
 
                        g_object_set_data (G_OBJECT (entry), "param", param);
409
 
                        g_object_set_data (G_OBJECT (entry), "form", form);
410
 
                        form->priv->entries = g_slist_append (form->priv->entries, entry);
411
 
 
412
 
                        /* connect to the parameter's changes */
413
 
                        form->priv->signal_ids[i] = g_signal_connect (G_OBJECT (param), "changed",
414
 
                                                                      G_CALLBACK (parameter_changed_cb), entry);
415
 
                        i++;
416
 
                }
417
 
                else { /* parameter depending on a sub query */
418
 
                        GSList *plist;
419
 
                        gboolean nnul = TRUE;
420
 
 
421
 
                        entry = mg_entry_combo_new (conf, form->priv->context, node);
422
 
                        g_object_set_data (G_OBJECT (entry), "node", node);
423
 
                        g_object_set_data (G_OBJECT (entry), "form", form);
424
 
                        form->priv->entries = g_slist_append (form->priv->entries, entry);
425
 
 
426
 
                        /* connect to the parameter's changes */
427
 
                        plist = node->params;
428
 
                        while (plist) {
429
 
                                if (!mg_parameter_get_not_null (plist->data))
430
 
                                        nnul = FALSE;
431
 
                                form->priv->signal_ids[i] = g_signal_connect (G_OBJECT (plist->data), "changed",
432
 
                                                                              G_CALLBACK (parameter_changed_cb), entry);
433
 
                                i++;
434
 
                                plist = g_slist_next (plist);
435
 
                        }
436
 
                        mg_data_entry_set_attributes (MG_DATA_ENTRY (entry),
437
 
                                                      nnul ? 0 : MG_DATA_ENTRY_CAN_BE_NULL,
438
 
                                                      MG_DATA_ENTRY_CAN_BE_NULL);
439
 
                }
440
 
 
441
 
                /* connect the entry's changes */
442
 
                g_signal_connect (G_OBJECT (entry), "contents_modified",
443
 
                                  G_CALLBACK (entry_contents_modified), form);
444
 
                list = g_slist_next (list);
445
 
        }
446
 
 
447
 
        if (layout) {
448
 
                /* there is actually a layout, test it */
449
 
                /* tests: GtkWindow? already parented widget? */
450
 
                /* set layout to NULL on error */
451
 
                
452
 
                if (!box_widgets)
453
 
                        layout = NULL;
454
 
        }
455
 
 
456
 
        if (!layout) {
457
 
                GtkWidget *table, *label;
458
 
 
459
 
                /* creating a table for all the entries */
460
 
                table = gtk_table_new (g_slist_length (form->priv->entries), 2, FALSE);
461
 
                gtk_table_set_row_spacings (GTK_TABLE (table), 5);
462
 
                gtk_table_set_col_spacings (GTK_TABLE (table), 5);
463
 
                form->priv->entries_table = table;
464
 
                gtk_box_pack_start (GTK_BOX (form), table,  FALSE, TRUE, 0);
465
 
                list = form->priv->entries;
466
 
                i = 0;
467
 
                while (list) {
468
 
                        gboolean expand;
469
 
                        GtkWidget *entry_label;
470
 
                        
471
 
                        /* label for the entry */
472
 
                        param = g_object_get_data (G_OBJECT (list->data), "param");
473
 
                        if (param) {
474
 
                                const gchar *str;
475
 
                                gchar *str2;
476
 
                                GtkWidget *evbox;
477
 
                                
478
 
                                str = mg_base_get_name (MG_BASE (param));
479
 
                                if (!str)
480
 
                                        str = _("Value");
481
 
                                str2 = g_strdup_printf ("%s:", str);
482
 
                                evbox = gtk_event_box_new ();
483
 
                                label = gtk_label_new (str2);
484
 
                                if (mg_parameter_get_not_null (param))
485
 
                                        form->priv->not_null_labels = g_slist_append (form->priv->not_null_labels, label);
486
 
                                
487
 
                                gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
488
 
                                g_free (str2);
489
 
                                gtk_container_add (GTK_CONTAINER (evbox), label);
490
 
                                
491
 
                                gtk_table_attach (GTK_TABLE (table), evbox, 0, 1, i, i+1,
492
 
                                                  GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
493
 
                                gtk_widget_show (evbox);
494
 
                                gtk_widget_show (label);
495
 
                                entry_label = evbox;
496
 
                                
497
 
                                str = mg_base_get_description (MG_BASE (param));
498
 
                                if (str && *str)
499
 
                                        gtk_tooltips_set_tip (form->priv->tooltips, evbox, str, NULL);
500
 
                        }
501
 
                        else {
502
 
                                /* FIXME: find a better label and tooltip and improve data entry attributes */
503
 
                                const gchar *str = NULL;
504
 
                                gchar *str2;
505
 
                                GtkWidget *evbox;
506
 
                                gboolean nullok = TRUE;
507
 
                                GSList *params;
508
 
                                
509
 
                                node = g_object_get_data (G_OBJECT (list->data), "node");
510
 
                                params = node->params;
511
 
                                while (params && nullok) {
512
 
                                        if (mg_parameter_get_not_null (MG_PARAMETER (params->data)))
513
 
                                                nullok = FALSE;
514
 
                                        params = g_slist_next (params);
515
 
                                }
516
 
                                
517
 
                                str = mg_base_get_name (MG_BASE (node->query));
518
 
                                if (!str)
519
 
                                        str = _("Value");
520
 
                                str2 = g_strdup_printf ("%s:", str);
521
 
                                evbox = gtk_event_box_new ();
522
 
                                label = gtk_label_new (str2);
523
 
                                if (!nullok) 
524
 
                                        form->priv->not_null_labels = g_slist_append (form->priv->not_null_labels, label);
525
 
                                gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
526
 
                                g_free (str2);
527
 
                                gtk_container_add (GTK_CONTAINER (evbox), label);
528
 
                                
529
 
                                gtk_table_attach (GTK_TABLE (table), evbox, 0, 1, i, i+1,
530
 
                                                  GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
531
 
                                gtk_widget_show (evbox);
532
 
                                gtk_widget_show (label);
533
 
                                entry_label = evbox;
534
 
                                
535
 
                                str = mg_base_get_description (MG_BASE (node->query));
536
 
                                if (str && *str)
537
 
                                        gtk_tooltips_set_tip (form->priv->tooltips, evbox, str, NULL);
538
 
                        }
539
 
 
540
 
                        /* add the entry itself to the table */
541
 
                        expand = mg_data_entry_expand_in_layout (MG_DATA_ENTRY (list->data));
542
 
                        gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (list->data), 1, 2, i, i+1,
543
 
                                          GTK_FILL | GTK_SHRINK | GTK_EXPAND, 
544
 
                                          GTK_FILL | GTK_SHRINK | expand? GTK_EXPAND : 0, 0, 0);
545
 
                        gtk_widget_show (GTK_WIDGET (list->data));
546
 
                        g_object_set_data (G_OBJECT (list->data), "entry_label", entry_label);
547
 
                        g_object_set_data (G_OBJECT (list->data), "row_no", GINT_TO_POINTER (i));
548
 
                        
549
 
                        list = g_slist_next (list);
550
 
                        i++;
551
 
                }
552
 
                mark_not_null_entry_labels (form, TRUE);
553
 
                gtk_widget_show (table);
554
 
        }
555
 
        else {
556
 
                /* really use the provided layout */
557
 
                GtkWidget *box;
558
 
                GSList *nodes;
559
 
 
560
 
                gtk_box_pack_start (GTK_BOX (form), layout,  FALSE, TRUE, 0);
561
 
                list = form->priv->entries;
562
 
                nodes = form->priv->context->nodes;
563
 
                while (nodes && list) {
564
 
                        box = g_hash_table_lookup (box_widgets, nodes->data);
565
 
                        if (box) {
566
 
                                gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (list->data),
567
 
                                                    mg_data_entry_expand_in_layout (MG_DATA_ENTRY (list->data)),
568
 
                                                    TRUE, 0);
569
 
                                gtk_widget_show (GTK_WIDGET (list->data));
570
 
                                if (! g_object_get_data (G_OBJECT (box), "show_actions")) 
571
 
                                        mg_data_entry_set_attributes (MG_DATA_ENTRY (list->data),
572
 
                                                                      0, MG_DATA_ENTRY_ACTIONS_SHOWN);
573
 
                        }
574
 
                        list = g_slist_next (list);
575
 
                        nodes = g_slist_next (nodes);
576
 
                }
577
 
                g_assert (!nodes && !list);
578
 
                gtk_widget_show (layout);
579
 
        }
580
 
}
581
 
 
582
 
/*
583
 
 * if @show_mark is TRUE, display the label as bold */
584
 
static void
585
 
mark_not_null_entry_labels (MgForm *form, gboolean show_mark)
586
 
{
587
 
        PangoAttrList *attrs = NULL;
588
 
        PangoAttribute *att;
589
 
 
590
 
        if (show_mark) {
591
 
                attrs = pango_attr_list_new ();
592
 
                att = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
593
 
                att->start_index = 0;
594
 
                att->end_index = G_MAXUINT;
595
 
                pango_attr_list_insert (attrs, att);
596
 
        }
597
 
 
598
 
        GSList *list = form->priv->not_null_labels;
599
 
        while (list) {
600
 
                gtk_label_set_attributes (GTK_LABEL (list->data), attrs);
601
 
                list = g_slist_next (list);
602
 
        }
603
 
 
604
 
        if (show_mark)
605
 
                pango_attr_list_unref (attrs);
606
 
}
607
 
 
608
 
static void
609
 
entry_contents_modified (MgDataEntry *entry, MgForm *form)
610
 
{
611
 
        MgParameter *param;
612
 
        MgContextNode *node;
613
 
        guint attr;
614
 
 
615
 
        attr = mg_data_entry_get_attributes (entry);
616
 
        param = g_object_get_data (G_OBJECT (entry), "param");
617
 
        if (param) { /* single parameter */
618
 
                GdaValue *value;
619
 
                
620
 
                form->priv->forward_param_updates = FALSE;
621
 
 
622
 
                /* parameter's value */
623
 
                value = mg_data_entry_get_value (entry);
624
 
                if ((!value || gda_value_is_null (value)) &&
625
 
                    (attr & MG_DATA_ENTRY_IS_DEFAULT))
626
 
                        g_object_set (G_OBJECT (param), "use_default_value", TRUE, NULL);
627
 
                else
628
 
                        g_object_set (G_OBJECT (param), "use_default_value", FALSE, NULL);
629
 
                mg_parameter_set_value (param, value);
630
 
#ifdef debug_signal
631
 
                g_print (">> 'PARAM_CHANGED' from %s\n", __FUNCTION__);
632
 
#endif
633
 
                g_signal_emit (G_OBJECT (form), mg_form_signals[PARAM_CHANGED], 0, param, TRUE);
634
 
#ifdef debug_signal
635
 
                g_print ("<< 'PARAM_CHANGED' from %s\n", __FUNCTION__);
636
 
#endif
637
 
                form->priv->forward_param_updates = TRUE;
638
 
                gda_value_free (value);
639
 
        }
640
 
        else { /* multiple parameters */
641
 
                GSList *params;
642
 
                GList *values, *list;
643
 
                node = g_object_get_data (G_OBJECT (entry), "node");
644
 
                params = node->params;
645
 
                values = mg_entry_combo_get_values (MG_ENTRY_COMBO (entry));
646
 
                g_assert (g_slist_length (params) == g_list_length (values));
647
 
 
648
 
                list = values;
649
 
                while (list) {
650
 
                        /* REM: if there is more than one value in 'params', then a signal is emitted for each
651
 
                           param that is changed, and there is no way for the listener of that signal to know if it
652
 
                           the end of the "param_changed" sequence. What could be done is:
653
 
                           - adding another boolean to tell if that signal is the last one in the "param_changed" sequence, or
654
 
                           - modify the signal to add a list of parameters which are changed and emit only one signal.
655
 
                        */
656
 
                        form->priv->forward_param_updates = FALSE;
657
 
 
658
 
                        /* parameter's value */
659
 
                        mg_parameter_set_value (MG_PARAMETER (params->data), (GdaValue *)(list->data));
660
 
#ifdef debug_signal
661
 
                        g_print (">> 'PARAM_CHANGED' from %s\n", __FUNCTION__);
662
 
#endif
663
 
                        g_signal_emit (G_OBJECT (form), mg_form_signals[PARAM_CHANGED], 0, param, TRUE);
664
 
#ifdef debug_signal
665
 
                        g_print ("<< 'PARAM_CHANGED' from %s\n", __FUNCTION__);
666
 
#endif
667
 
                        form->priv->forward_param_updates = TRUE;;
668
 
                        gda_value_free (list->data);
669
 
 
670
 
                        list = g_list_next (list);
671
 
                        params = g_slist_next (params);
672
 
                }
673
 
                g_list_free (values);
674
 
        }
675
 
}
676
 
 
677
 
 
678
 
/*
679
 
 * Called when a parameter changes
680
 
 * We emit a "param_changed" signal only if the 'form->priv->forward_param_updates' is TRUE, which means
681
 
 * the param change does not come from a MgDataEntry change.
682
 
 */ 
683
 
static void
684
 
parameter_changed_cb (MgParameter *param, MgDataEntry *entry)
685
 
{
686
 
        MgForm *form = g_object_get_data (G_OBJECT (entry), "form");
687
 
        MgContextNode *node = g_object_get_data (G_OBJECT (entry), "node");
688
 
        const GdaValue *value = mg_parameter_get_value (param);
689
 
 
690
 
        if (form->priv->forward_param_updates) {
691
 
                gboolean param_valid;
692
 
                gboolean default_if_invalid = FALSE;
693
 
 
694
 
                /* There can be a feedback from the entry if the param is invalid and "set_default_if_invalid"
695
 
                   exists and is TRUE */
696
 
                param_valid = mg_parameter_is_valid (param);
697
 
                if (!param_valid) 
698
 
                        if (g_object_class_find_property (G_OBJECT_GET_CLASS (entry), "set_default_if_invalid"))
699
 
                                g_object_get (G_OBJECT (entry), "set_default_if_invalid", &default_if_invalid, NULL);
700
 
 
701
 
                /* updating the corresponding entry */
702
 
                if (! default_if_invalid)
703
 
                        g_signal_handlers_block_by_func (G_OBJECT (entry),
704
 
                                                         G_CALLBACK (entry_contents_modified), form);
705
 
                if (node) {
706
 
                        GList *values = NULL;
707
 
                        GSList *list = node->params;
708
 
                        gboolean allnull = TRUE;
709
 
 
710
 
                        while (list) {
711
 
                                const GdaValue *pvalue = mg_parameter_get_value (MG_PARAMETER (list->data));
712
 
                                values = g_list_append (values, pvalue);
713
 
                                if (allnull && pvalue && (gda_value_get_type (pvalue) != GDA_VALUE_TYPE_NULL))
714
 
                                        allnull = FALSE;
715
 
 
716
 
                                list = g_slist_next (list);
717
 
                        }
718
 
                        
719
 
                        if (!allnull) 
720
 
                                mg_entry_combo_set_values_orig (MG_ENTRY_COMBO (entry), values);
721
 
                        else 
722
 
                                mg_entry_combo_set_values_orig (MG_ENTRY_COMBO (entry), NULL);
723
 
 
724
 
                        g_list_free (values);
725
 
                }
726
 
                else
727
 
                        mg_data_entry_set_value_orig (entry, value);
728
 
 
729
 
                if (! default_if_invalid)
730
 
                        g_signal_handlers_unblock_by_func (G_OBJECT (entry),
731
 
                                                           G_CALLBACK (entry_contents_modified), form);
732
 
 
733
 
#ifdef debug_signal
734
 
                g_print (">> 'PARAM_CHANGED' from %s\n", __FUNCTION__);
735
 
#endif
736
 
                g_signal_emit (G_OBJECT (form), mg_form_signals[PARAM_CHANGED], 0, param, FALSE);
737
 
#ifdef debug_signal
738
 
                g_print ("<< 'PARAM_CHANGED' from %s\n", __FUNCTION__);
739
 
#endif
740
 
        }
741
 
}
742
 
 
743
 
/**
744
 
 * mg_form_set_current_as_orig
745
 
 * @form: a #MgForm widget
746
 
 *
747
 
 * Tells @form that the current values in the different entries are
748
 
 * to be considered as the original values for all the entries; the immediate
749
 
 * consequence is that any sub-sequent call to mg_form_has_been_changed()
750
 
 * will return FALSE (of course until any entry is changed).
751
 
 */
752
 
void
753
 
mg_form_set_current_as_orig (MgForm *form)
754
 
{
755
 
        GSList *list;
756
 
        MgParameter *param;
757
 
 
758
 
        g_return_if_fail (form && IS_MG_FORM (form));
759
 
        g_return_if_fail (form->priv);
760
 
 
761
 
        list = form->priv->entries;
762
 
        while (list) {
763
 
                MgContextNode *node = g_object_get_data (G_OBJECT (list->data), "node");
764
 
 
765
 
                if (node) {
766
 
                        /* Combo entry */
767
 
                        GList *values = NULL;
768
 
                        GSList *params = node->params;
769
 
                        gboolean allnull = TRUE;
770
 
                        
771
 
                        while (params) {
772
 
                                const GdaValue *pvalue = mg_parameter_get_value (MG_PARAMETER (params->data));
773
 
                                values = g_list_append (values, pvalue);
774
 
                                if (allnull && pvalue && (gda_value_get_type (pvalue) != GDA_VALUE_TYPE_NULL))
775
 
                                        allnull = FALSE;
776
 
                                
777
 
                                params = g_slist_next (params);
778
 
                        }
779
 
                        
780
 
                        if (!allnull) 
781
 
                                mg_entry_combo_set_values_orig (MG_ENTRY_COMBO (list->data), values);
782
 
                        else 
783
 
                                mg_entry_combo_set_values_orig (MG_ENTRY_COMBO (list->data), NULL);
784
 
                        
785
 
                        g_list_free (values);
786
 
                }
787
 
                else {
788
 
                        /* non combo entry */
789
 
                        param = g_object_get_data (G_OBJECT (list->data), "param");
790
 
                        mg_data_entry_set_value_orig (MG_DATA_ENTRY (list->data), mg_parameter_get_value (param));
791
 
                }
792
 
                list = g_slist_next (list);
793
 
        }
794
 
}
795
 
 
796
 
/**
797
 
 * mg_form_is_valid 
798
 
 * @form: a #MgForm widget
799
 
 *
800
 
 * Tells if the form can be used as-is (if all the parameters do have some valid values)
801
 
 *
802
 
 * Returns: TRUE if the form is valid
803
 
 */
804
 
gboolean
805
 
mg_form_is_valid (MgForm *form)
806
 
{
807
 
        g_return_val_if_fail (form && IS_MG_FORM (form), FALSE);
808
 
        g_return_val_if_fail (form->priv, FALSE);
809
 
 
810
 
        return mg_context_is_valid (form->priv->context);
811
 
}
812
 
 
813
 
/**
814
 
 * mg_form_has_been_changed
815
 
 * @form: a #MgForm widget
816
 
 *
817
 
 * Tells if the form has had at least on entry changed, or not
818
 
 *
819
 
 * Returns:
820
 
 */
821
 
gboolean
822
 
mg_form_has_been_changed (MgForm *form)
823
 
{
824
 
        gboolean changed = FALSE;
825
 
        GSList *list;
826
 
 
827
 
        g_return_val_if_fail (form && IS_MG_FORM (form), FALSE);
828
 
        g_return_val_if_fail (form->priv, FALSE);
829
 
        
830
 
        list = form->priv->entries;
831
 
        while (list && !changed) {
832
 
                if (! (mg_data_entry_get_attributes (MG_DATA_ENTRY (list->data)) & MG_DATA_ENTRY_IS_UNCHANGED))
833
 
                        changed = TRUE;
834
 
                list = g_slist_next (list);
835
 
        }
836
 
 
837
 
        return changed;
838
 
}
839
 
 
840
 
/**
841
 
 * mg_form_show_entries_actions
842
 
 * @form: a #MgForm widget
843
 
 * @show_actions: a boolean
844
 
 *
845
 
 * Show or hide the actions button available at the end of each data entry
846
 
 * in the form
847
 
 */
848
 
void
849
 
mg_form_show_entries_actions (MgForm *form, gboolean show_actions)
850
 
{
851
 
        GSList *entries;
852
 
        guint show;
853
 
        
854
 
        g_return_if_fail (form && IS_MG_FORM (form));
855
 
        g_return_if_fail (form->priv);
856
 
 
857
 
        show = show_actions ? MG_DATA_ENTRY_ACTIONS_SHOWN : 0;
858
 
 
859
 
        entries = form->priv->entries;
860
 
        while (entries) {
861
 
                mg_data_entry_set_attributes (MG_DATA_ENTRY (entries->data), show, MG_DATA_ENTRY_ACTIONS_SHOWN);
862
 
                entries = g_slist_next (entries);
863
 
        }
864
 
 
865
 
        mark_not_null_entry_labels (form, show_actions);
866
 
}
867
 
 
868
 
/**
869
 
 * mg_form_reset
870
 
 * @form: a #MgForm widget
871
 
 *
872
 
 * Resets all the entries in the form to their
873
 
 * original values
874
 
 */
875
 
void
876
 
mg_form_reset (MgForm *form)
877
 
{
878
 
        GSList *list;
879
 
 
880
 
        g_return_if_fail (form && IS_MG_FORM (form));
881
 
        g_return_if_fail (form->priv);
882
 
        
883
 
        list = form->priv->entries;
884
 
        while (list) {
885
 
                MgContextNode *node = g_object_get_data (G_OBJECT (list->data), "node");
886
 
 
887
 
                if (node) {
888
 
                        /* Combo entry */
889
 
                        GList *values = NULL;
890
 
 
891
 
                        values = mg_entry_combo_get_values_orig (MG_ENTRY_COMBO (list->data));
892
 
                        mg_entry_combo_set_values (MG_ENTRY_COMBO (list->data), values);
893
 
                        g_list_free (values);
894
 
                }
895
 
                else {
896
 
                        /* non combo entry */
897
 
                        const GdaValue *value;
898
 
 
899
 
                        value = mg_data_entry_get_value_orig (MG_DATA_ENTRY (list->data));
900
 
                        mg_data_entry_set_value (MG_DATA_ENTRY (list->data), value);
901
 
                }
902
 
                list = g_slist_next (list);
903
 
        }
904
 
}
905
 
 
906
 
 
907
 
/**
908
 
 * mg_form_entry_show
909
 
 * @form: a #MgForm widget
910
 
 * @param: a #MgParameter object
911
 
 * @show:
912
 
 *
913
 
 * Shows or hides the #MgDataEntry in @form which corresponds to the
914
 
 * @param parameter
915
 
 */
916
 
void
917
 
mg_form_entry_show (MgForm *form, MgParameter *param, gboolean show)
918
 
{
919
 
        GSList *entries;
920
 
 
921
 
        g_return_if_fail (form && IS_MG_FORM (form));
922
 
        g_return_if_fail (form->priv);
923
 
 
924
 
        entries = form->priv->entries;
925
 
        while (entries) {
926
 
                GtkWidget *entry = NULL;
927
 
                MgParameter *thisparam = g_object_get_data (G_OBJECT (entries->data), "param");
928
 
 
929
 
                if (thisparam) {
930
 
                        if (thisparam == param)
931
 
                                entry = GTK_WIDGET (entries->data);
932
 
                }
933
 
                else {
934
 
                        /* multiple parameters */
935
 
                        GSList *params;
936
 
                        MgContextNode *node;
937
 
 
938
 
                        node = g_object_get_data (G_OBJECT (entries->data), "node");
939
 
                        params = node->params;
940
 
                        while (params && !entry) {
941
 
                                if (params->data == (gpointer) param)
942
 
                                        entry = GTK_WIDGET (entries->data);
943
 
                                params = g_slist_next (params);
944
 
                        }
945
 
                }
946
 
 
947
 
                if (entry) {
948
 
                        gint row = -1;
949
 
                        GtkWidget *entry_label = g_object_get_data (G_OBJECT (entry), "entry_label");
950
 
 
951
 
                        if (form->priv->entries_table)
952
 
                                row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (entry), "row_no"));
953
 
 
954
 
                        if (show) {
955
 
                                if (g_slist_find (form->priv->hidden_entries, entry)) {
956
 
                                        form->priv->hidden_entries = g_slist_remove (form->priv->hidden_entries, entry);
957
 
                                        g_signal_handlers_disconnect_by_func (G_OBJECT (entry), 
958
 
                                                                              G_CALLBACK (widget_shown_cb), form);
959
 
                                }
960
 
                                gtk_widget_show (entry);
961
 
 
962
 
                                if (entry_label) {
963
 
                                        if (g_slist_find (form->priv->hidden_entries, entry_label)) {
964
 
                                                form->priv->hidden_entries = g_slist_remove (form->priv->hidden_entries, 
965
 
                                                                                             entry_label);
966
 
                                                g_signal_handlers_disconnect_by_func (G_OBJECT (entry_label), 
967
 
                                                                                      G_CALLBACK (widget_shown_cb), form);
968
 
                                        }
969
 
                                        gtk_widget_show (entry_label);
970
 
                                }
971
 
                                if (row > -1) 
972
 
                                        gtk_table_set_row_spacing (GTK_TABLE (form->priv->entries_table), row, 5);
973
 
                        }
974
 
                        else {
975
 
                                if (!g_slist_find (form->priv->hidden_entries, entry)) {
976
 
                                        form->priv->hidden_entries = g_slist_append (form->priv->hidden_entries, entry);
977
 
                                        g_signal_connect_after (G_OBJECT (entry), "show", 
978
 
                                                                G_CALLBACK (widget_shown_cb), form);
979
 
                                }
980
 
                                gtk_widget_hide (entry);
981
 
 
982
 
                                if (entry_label) {
983
 
                                        if (!g_slist_find (form->priv->hidden_entries, entry_label)) {
984
 
                                                form->priv->hidden_entries = g_slist_append (form->priv->hidden_entries, 
985
 
                                                                                             entry_label);
986
 
                                                g_signal_connect_after (G_OBJECT (entry_label), "show", 
987
 
                                                                        G_CALLBACK (widget_shown_cb), form);
988
 
                                        }
989
 
                                        gtk_widget_hide (entry_label);
990
 
                                }
991
 
                                if (row > -1)
992
 
                                        gtk_table_set_row_spacing (GTK_TABLE (form->priv->entries_table), row, 0);
993
 
                        }
994
 
                }
995
 
 
996
 
                entries = g_slist_next (entries);
997
 
        }
998
 
}
999
 
 
1000
 
/**
1001
 
 * mg_form_entry_set_sensitive
1002
 
 * @form: a #MgForm widget
1003
 
 * @param: a #MgParameter object
1004
 
 * @sensitive:
1005
 
 *
1006
 
 * Shows or hides the #MgDataEntry in @form which corresponds to the
1007
 
 * @param parameter
1008
 
 */
1009
 
void
1010
 
mg_form_entry_set_sensitive (MgForm *form, MgParameter *param, gboolean sensitive)
1011
 
{
1012
 
        GSList *entries;
1013
 
 
1014
 
        g_return_if_fail (form && IS_MG_FORM (form));
1015
 
        g_return_if_fail (form->priv);
1016
 
 
1017
 
        entries = form->priv->entries;
1018
 
        while (entries) {
1019
 
                GtkWidget *entry = NULL;
1020
 
                MgParameter *thisparam = g_object_get_data (G_OBJECT (entries->data), "param");
1021
 
 
1022
 
                if (thisparam) {
1023
 
                        if (thisparam == param)
1024
 
                                entry = GTK_WIDGET (entries->data);
1025
 
                }
1026
 
                else {
1027
 
                        /* multiple parameters */
1028
 
                        GSList *params;
1029
 
                        MgContextNode *node;
1030
 
 
1031
 
                        node = g_object_get_data (G_OBJECT (entries->data), "node");
1032
 
                        params = node->params;
1033
 
                        while (params && !entry) {
1034
 
                                if (params->data == (gpointer) param)
1035
 
                                        entry = GTK_WIDGET (entries->data);
1036
 
                                params = g_slist_next (params);
1037
 
                        }
1038
 
                }
1039
 
 
1040
 
                if (entry) {
1041
 
                        GtkWidget *entry_label = g_object_get_data (G_OBJECT (entry), "entry_label");
1042
 
 
1043
 
                        gtk_widget_set_sensitive (entry, sensitive);
1044
 
                        if (entry_label)
1045
 
                                gtk_widget_set_sensitive (entry_label, sensitive);
1046
 
                }
1047
 
 
1048
 
                entries = g_slist_next (entries);
1049
 
        }
1050
 
}
1051
 
 
1052
 
 
1053
 
/**
1054
 
 * mg_form_set_entries_auto_default
1055
 
 * @form: a #MgForm widget
1056
 
 * @auto_default:
1057
 
 *
1058
 
 * Sets weather all the #MgDataEntry entries in the form must default
1059
 
 * to a default value if they are assigned a non valid value.
1060
 
 * Depending on the real type of entry, it will provide a default value
1061
 
 * which the user does not need to modify if it is OK.
1062
 
 *
1063
 
 * For example a date entry can by default display the current date.
1064
 
 */
1065
 
void
1066
 
mg_form_set_entries_auto_default (MgForm *form, gboolean auto_default)
1067
 
{
1068
 
        GSList *entries;
1069
 
 
1070
 
        g_return_if_fail (form && IS_MG_FORM (form));
1071
 
        g_return_if_fail (form->priv);
1072
 
 
1073
 
        entries = form->priv->entries;
1074
 
        while (entries) {
1075
 
                if (g_object_class_find_property (G_OBJECT_GET_CLASS (entries->data), "set_default_if_invalid"))
1076
 
                        g_object_set (G_OBJECT (entries->data), "set_default_if_invalid", auto_default, NULL);
1077
 
                entries = g_slist_next (entries);
1078
 
        }       
1079
 
}
1080
 
 
1081
 
/**
1082
 
 * mg_form_set_entries_default
1083
 
 * @form: a #MgForm widget
1084
 
 *
1085
 
 * For each entry in the form, sets it to a default value if it is possible to do so.
1086
 
 */
1087
 
void
1088
 
mg_form_set_entries_default (MgForm *form)
1089
 
{
1090
 
        GSList *entries;
1091
 
        guint attrs;
1092
 
 
1093
 
        g_return_if_fail (form && IS_MG_FORM (form));
1094
 
        g_return_if_fail (form->priv);
1095
 
 
1096
 
        entries = form->priv->entries;
1097
 
        while (entries) {
1098
 
                attrs = mg_data_entry_get_attributes (MG_DATA_ENTRY (entries->data));
1099
 
                if (attrs & MG_DATA_ENTRY_CAN_BE_DEFAULT)
1100
 
                        mg_data_entry_set_attributes (MG_DATA_ENTRY (entries->data), 
1101
 
                                                      MG_DATA_ENTRY_IS_DEFAULT, MG_DATA_ENTRY_IS_DEFAULT);
1102
 
                entries = g_slist_next (entries);
1103
 
        }
1104
 
}
1105
 
 
1106
 
static void form_param_changed (MgForm *form, MgParameter *param, gboolean is_user_modif, GtkDialog *dlg);
1107
 
 
1108
 
/**
1109
 
 * mg_form_new_in_dialog
1110
 
 * @conf: a #MgConf object
1111
 
 * @context: a #MgContext structure
1112
 
 * @parent: the parent window for the new dialog, or %NULL
1113
 
 * @title: the title of the dialog window, or %NULL
1114
 
 * @header: a helper text displayed at the top of the dialog, or %NULL
1115
 
 *
1116
 
 * Creates a new #MgForm widget in the same way as mg_form_new()
1117
 
 * and puts it into a #GtkDialog widget.
1118
 
 *
1119
 
 * The #MgForm widget is attached to the dialog using the user property
1120
 
 * "form".
1121
 
 *
1122
 
 * Returns: the new #GtkDialog widget
1123
 
 */
1124
 
GtkWidget *
1125
 
mg_form_new_in_dialog (MgConf *conf, MgContext *context, GtkWindow *parent,
1126
 
                       const gchar *title, const gchar *header)
1127
 
{
1128
 
        GtkWidget *form;
1129
 
        GtkWidget *dlg;
1130
 
        const gchar *rtitle;
1131
 
 
1132
 
        form = mg_form_new (conf, context);
1133
 
 
1134
 
        rtitle = title;
1135
 
        if (!rtitle)
1136
 
                rtitle = _("Values to be filled");
1137
 
                
1138
 
        dlg = gtk_dialog_new_with_buttons (rtitle, parent,
1139
 
                                           GTK_DIALOG_MODAL,
1140
 
                                           GTK_STOCK_OK,
1141
 
                                           GTK_RESPONSE_ACCEPT,
1142
 
                                           GTK_STOCK_CANCEL,
1143
 
                                           GTK_RESPONSE_REJECT,
1144
 
                                           NULL);
1145
 
        if (header && *header) {
1146
 
                GtkWidget *label;
1147
 
 
1148
 
                label = gtk_label_new (NULL);
1149
 
                gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
1150
 
                gtk_label_set_markup (GTK_LABEL (label), header);
1151
 
                gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), label, FALSE, FALSE, 5);
1152
 
                gtk_widget_show (label);
1153
 
        }
1154
 
 
1155
 
        gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox), 4);
1156
 
        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), form, TRUE, TRUE, 10);
1157
 
 
1158
 
        g_signal_connect (G_OBJECT (form), "param_changed",
1159
 
                          G_CALLBACK (form_param_changed), dlg);
1160
 
        g_object_set_data (G_OBJECT (dlg), "form", form);
1161
 
 
1162
 
        gtk_widget_show_all (form);
1163
 
        form_param_changed (MG_FORM (form), NULL, FALSE, GTK_DIALOG (dlg));
1164
 
 
1165
 
        return dlg;
1166
 
}
1167
 
 
1168
 
static void
1169
 
form_param_changed (MgForm *form, MgParameter *param, gboolean is_user_modif, GtkDialog *dlg)
1170
 
{
1171
 
        gboolean valid;
1172
 
 
1173
 
        valid = mg_form_is_valid (form);
1174
 
 
1175
 
        gtk_dialog_set_response_sensitive (dlg, GTK_RESPONSE_ACCEPT, valid);
1176
 
}