~ubuntu-branches/ubuntu/jaunty/mlview/jaunty

« back to all changes in this revision

Viewing changes to src/mlview-attribute-picker.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2004-05-11 23:55:05 UTC
  • Revision ID: james.westby@ubuntu.com-20040511235505-ktq97vaz6sl5amy7
Tags: upstream-0.6.3
ImportĀ upstreamĀ versionĀ 0.6.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8-*- */
 
2
 
 
3
/*This file is part of MlView
 
4
 *
 
5
 *MlView is free software; you can redistribute 
 
6
 *it and/or modify it under the terms of 
 
7
 *the GNU General Public License as 
 
8
 *published by the Free Software Foundation; either version 2, 
 
9
 *or (at your option) any later version.
 
10
 *
 
11
 *MlView is distributed in the hope that 
 
12
 *it will be useful, but WITHOUT ANY WARRANTY; 
 
13
 *without even the implied warranty of 
 
14
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
15
 *See the GNU General Public License for more details.
 
16
 *
 
17
 *You should have received a copy of the 
 
18
 *GNU General Public License along with MlView; 
 
19
 *see the file COPYING. If not, write to the 
 
20
 *Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 
21
 *Boston, MA 02111-1307, USA.
 
22
 *
 
23
 *See COPYRIGHT file for copyright information.
 
24
 */
 
25
#include <string.h>
 
26
#include <libxml/parser.h>
 
27
#include <libxml/valid.h>
 
28
#include <libxml/tree.h>
 
29
 
 
30
#include "mlview-attribute-picker.h"
 
31
#include "mlview-parsing-utils.h"
 
32
#include "mlview-utils.h"
 
33
 
 
34
/**
 
35
 *@file
 
36
 *The definition of the class #MlViewAttributePicker.
 
37
 *This class is a business widget. It lets the user enter the name/value of
 
38
 *an attribute. It can for example perform an attribute name completion given
 
39
 *the xmlNode on which the attribute is to be defined.
 
40
 */
 
41
 
 
42
 
 
43
/**
 
44
 *The private instance members of #MlViewAttributePicker.
 
45
 *Theses member should not be accessed directly. They
 
46
 *must only be accessed through the available accessors.
 
47
 */
 
48
struct _MlViewAttributePickerPrivate {
 
49
 /**the entry used to edit attribute name*/
 
50
        GtkCombo *name_edit_entry;
 
51
 
 
52
 /**the entry used to edit attribute type*/
 
53
        GtkCombo *type_edit_entry;
 
54
 
 
55
 /**the entry used to edit the attribute value*/
 
56
        GtkEntry *value_edit_entry;
 
57
 
 
58
 /**The attribute values list*/
 
59
        GtkList *values_list;
 
60
 
 
61
 /**used to set attr value to the selected attr val*/
 
62
        GtkButton *set_value_button;
 
63
 
 
64
 /**adding a string to the attr value*/
 
65
        GtkButton *add_to_value_button;
 
66
 
 
67
        GtkTable *value_list_table;
 
68
 
 
69
 /**the list of possible attr names*/
 
70
        GList *names_completion_list;
 
71
 
 
72
 /**the list of possible attribute values*/
 
73
        GList *values_completion_list;
 
74
 
 
75
 /**the current xml node*/
 
76
        xmlNode *cur_xml_node;
 
77
 
 
78
 /**the current selected attribute value*/
 
79
        gchar *current_attribute_value;
 
80
 
 
81
 /**The app context passed to this object at creation time*/
 
82
        MlViewAppContext *app_context;
 
83
};
 
84
 
 
85
#define PRIVATE(object) (object)->private
 
86
 
 
87
/*a pointer to the parent class. Necessary for the gtk typing system framework*/
 
88
static GtkDialogClass *parent_class = NULL;
 
89
 
 
90
static gboolean gv_attributes_completion = TRUE;
 
91
 
 
92
static void mlview_attribute_picker_destroy (GtkObject *
 
93
                                             a_object);
 
94
static void
 
95
 mlview_attribute_picker_init_class (MlViewAttributePickerClass *
 
96
                                     a_klass);
 
97
static void mlview_attribute_picker_init (MlViewAttributePicker *
 
98
                                          a_this);
 
99
 
 
100
static void
 
101
 mlview_attribute_picker_show_attr_values (MlViewAttributePicker *
 
102
                                           a_this);
 
103
static void
 
104
 mlview_attribute_picker_hide_attr_values (MlViewAttributePicker *
 
105
                                           a_this);
 
106
static xmlAttributeType
 
107
mlview_attribute_picker_parse_attr_type (const gchar * a_string);
 
108
 
 
109
static void attribute_name_changed_cb (GtkEditable *
 
110
                                       a_text_entry,
 
111
                                       gpointer a_this);
 
112
static void add_to_value_button_cb (GtkButton * a_button,
 
113
                                    gpointer a_this);
 
114
static void set_value_button_cb (GtkButton * a_button,
 
115
                                 gpointer a_this);
 
116
static void attribute_value_selected_cb (GtkList *
 
117
                                         a_attribute_values_list,
 
118
                                         GtkWidget * a_list_item,
 
119
                                         gpointer * a_this);
 
120
static void attribute_type_changed_cb (GtkEditable *
 
121
                                       a_text_entry,
 
122
                                       gpointer a_this);
 
123
 
 
124
/*----------------------------------------------------
 
125
 *Private functions
 
126
 *----------------------------------------------------*/
 
127
 
 
128
/**
 
129
 *The class structure initialyzer. 
 
130
 *@param a_klass the current vtable.
 
131
 */
 
132
static void
 
133
mlview_attribute_picker_init_class (MlViewAttributePickerClass *
 
134
                                    a_klass)
 
135
{
 
136
        GtkObjectClass *object_class;
 
137
 
 
138
        g_return_if_fail (a_klass != NULL);
 
139
 
 
140
        parent_class = g_type_class_peek_parent (a_klass);
 
141
        g_return_if_fail (GTK_IS_DIALOG_CLASS (a_klass));
 
142
        object_class = GTK_OBJECT_CLASS (a_klass);
 
143
        object_class->destroy = mlview_attribute_picker_destroy;
 
144
}
 
145
 
 
146
 
 
147
/**
 
148
 *The allocator of the instances of #MlViewAttributePicker.
 
149
 *Allocates memory for the members (and initialyzes them) 
 
150
 *of  MlViewAttributePicker.
 
151
 *
 
152
 *@param a_this the current instance of #MlViewAttributePicker.
 
153
 */
 
154
static void
 
155
mlview_attribute_picker_init (MlViewAttributePicker * a_this)
 
156
{
 
157
        GtkWidget *label = NULL,
 
158
                *table = NULL,
 
159
                *vbox = NULL,
 
160
                *separator = NULL;
 
161
 
 
162
        g_return_if_fail (a_this != NULL);
 
163
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
164
 
 
165
        gtk_dialog_add_buttons (GTK_DIALOG (a_this),
 
166
                                _("OK"),
 
167
                                GTK_RESPONSE_ACCEPT,
 
168
                                _("Cancel"),
 
169
                                GTK_RESPONSE_REJECT, NULL);
 
170
 
 
171
        gtk_window_set_modal (GTK_WINDOW (a_this), TRUE);
 
172
 
 
173
        PRIVATE (a_this) = g_try_malloc
 
174
                (sizeof (MlViewAttributePickerPrivate));
 
175
        if (!PRIVATE (a_this)) {
 
176
                g_warning ("System may be out of memory");
 
177
                return;
 
178
        }
 
179
 
 
180
        memset (PRIVATE (a_this), 0,
 
181
                sizeof (MlViewAttributePickerPrivate));
 
182
 
 
183
        label = gtk_label_new (_("attribute name"));
 
184
        PRIVATE (a_this)->name_edit_entry =
 
185
                GTK_COMBO (gtk_combo_new ());
 
186
 
 
187
        g_signal_connect (G_OBJECT
 
188
                          (PRIVATE (a_this)->name_edit_entry->
 
189
                           entry), "changed",
 
190
                          G_CALLBACK (attribute_name_changed_cb),
 
191
                          a_this);
 
192
 
 
193
        table = gtk_table_new (1, 2, TRUE);
 
194
        gtk_table_attach_defaults (GTK_TABLE (table), label,
 
195
                                   0, 1, 0, 1);
 
196
        gtk_table_attach_defaults (GTK_TABLE (table),
 
197
                                   GTK_WIDGET (PRIVATE
 
198
                                               (a_this)->
 
199
                                               name_edit_entry),
 
200
                                   1, 2, 0, 1);
 
201
        gtk_box_pack_start (GTK_BOX
 
202
                            (GTK_DIALOG (a_this)->vbox), table,
 
203
                            FALSE, TRUE, 0);
 
204
        gtk_widget_show_all (table);
 
205
 
 
206
        label = gtk_label_new (_("attribute type"));
 
207
        PRIVATE (a_this)->type_edit_entry =
 
208
                GTK_COMBO (gtk_combo_new ());
 
209
 
 
210
        g_signal_connect (G_OBJECT
 
211
                          (PRIVATE (a_this)->type_edit_entry->
 
212
                           entry), "changed",
 
213
                          G_CALLBACK (attribute_type_changed_cb),
 
214
                          a_this);
 
215
 
 
216
        table = gtk_table_new (1, 2, TRUE);
 
217
        gtk_table_attach_defaults (GTK_TABLE (table), label,
 
218
                                   0, 1, 0, 1);
 
219
        gtk_table_attach_defaults (GTK_TABLE (table),
 
220
                                   GTK_WIDGET (PRIVATE
 
221
                                               (a_this)->
 
222
                                               type_edit_entry),
 
223
                                   1, 2, 0, 1);
 
224
        gtk_box_pack_start (GTK_BOX
 
225
                            (GTK_DIALOG (a_this)->vbox), table,
 
226
                            FALSE, TRUE, 0);
 
227
        gtk_widget_show_all (table);
 
228
 
 
229
        separator = gtk_hseparator_new ();
 
230
        gtk_box_pack_start (GTK_BOX
 
231
                            (GTK_DIALOG (a_this)->vbox),
 
232
                            separator, FALSE, TRUE, 0);
 
233
        gtk_widget_show (separator);
 
234
 
 
235
        label = gtk_label_new (_("attribute value:"));
 
236
        PRIVATE (a_this)->value_edit_entry =
 
237
                GTK_ENTRY (gtk_entry_new ());
 
238
        table = gtk_table_new (1, 2, FALSE);
 
239
        gtk_table_attach_defaults (GTK_TABLE (table), label,
 
240
                                   0, 1, 0, 1);
 
241
        gtk_table_attach_defaults (GTK_TABLE (table),
 
242
                                   GTK_WIDGET (PRIVATE
 
243
                                               (a_this)->
 
244
                                               value_edit_entry),
 
245
                                   1, 2, 0, 1);
 
246
        gtk_box_pack_start (GTK_BOX
 
247
                            (GTK_DIALOG (a_this)->vbox), table,
 
248
                            FALSE, TRUE, 0);
 
249
        gtk_widget_show_all (table);
 
250
 
 
251
 
 
252
        PRIVATE (a_this)->values_list =
 
253
                GTK_LIST (gtk_list_new ());
 
254
        g_signal_connect (G_OBJECT
 
255
                          (PRIVATE (a_this)->values_list),
 
256
                          "select-child",
 
257
                          G_CALLBACK
 
258
                          (attribute_value_selected_cb),
 
259
                          a_this);
 
260
        PRIVATE (a_this)->set_value_button =
 
261
                GTK_BUTTON (gtk_button_new_with_label
 
262
                            (_("set value")));
 
263
        PRIVATE (a_this)->add_to_value_button =
 
264
                GTK_BUTTON (gtk_button_new_with_label
 
265
                            (_("add to value")));
 
266
        g_signal_connect (G_OBJECT
 
267
                          (PRIVATE (a_this)->set_value_button),
 
268
                          "clicked",
 
269
                          G_CALLBACK (set_value_button_cb),
 
270
                          a_this);
 
271
        g_signal_connect (G_OBJECT
 
272
                          (PRIVATE (a_this)->
 
273
                           add_to_value_button), "clicked",
 
274
                          G_CALLBACK (add_to_value_button_cb),
 
275
                          a_this);
 
276
 
 
277
        vbox = gtk_vbox_new (FALSE, 0);
 
278
        gtk_box_pack_start (GTK_BOX (vbox),
 
279
                            GTK_WIDGET (PRIVATE (a_this)->
 
280
                                        set_value_button), FALSE,
 
281
                            TRUE, 0);
 
282
        gtk_box_pack_start (GTK_BOX (vbox),
 
283
                            GTK_WIDGET (PRIVATE (a_this)->
 
284
                                        add_to_value_button),
 
285
                            FALSE, TRUE, 0);
 
286
        PRIVATE (a_this)->value_list_table =
 
287
                GTK_TABLE (gtk_table_new (1, 2, FALSE));
 
288
 
 
289
        gtk_table_attach_defaults (PRIVATE (a_this)->
 
290
                                   value_list_table,
 
291
                                   GTK_WIDGET (PRIVATE
 
292
                                               (a_this)->
 
293
                                               values_list), 0,
 
294
                                   1, 1, 2);
 
295
        gtk_table_attach_defaults (PRIVATE (a_this)->
 
296
                                   value_list_table, vbox, 1, 2,
 
297
                                   1, 2);
 
298
 
 
299
        gtk_widget_ref (GTK_WIDGET
 
300
                        (PRIVATE (a_this)->value_list_table));
 
301
}
 
302
 
 
303
 
 
304
/**
 
305
 *The destroy method.
 
306
 *@param a_object the instance of #MlViewAttributePicker to 
 
307
 *destroy.
 
308
 */
 
309
static void
 
310
mlview_attribute_picker_destroy (GtkObject * a_object)
 
311
{
 
312
        MlViewAttributePicker *picker;
 
313
 
 
314
        g_return_if_fail (a_object != NULL);
 
315
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_object));
 
316
 
 
317
        picker = MLVIEW_ATTRIBUTE_PICKER (a_object);
 
318
 
 
319
        if (PRIVATE (picker) == NULL)
 
320
                return;
 
321
 
 
322
        gtk_widget_unref (GTK_WIDGET
 
323
                          (PRIVATE (picker)->value_list_table));
 
324
 
 
325
        if (PRIVATE (picker)->names_completion_list) {
 
326
                g_list_free (PRIVATE (picker)->
 
327
                             names_completion_list);
 
328
                PRIVATE (picker)->names_completion_list = NULL;
 
329
        }
 
330
 
 
331
        if (PRIVATE (picker)->values_completion_list) {
 
332
                g_list_free (PRIVATE (picker)->
 
333
                             values_completion_list);
 
334
                PRIVATE (picker)->values_completion_list = NULL;
 
335
        }
 
336
 
 
337
        if (PRIVATE (picker)) {
 
338
                g_free (PRIVATE (picker));
 
339
                PRIVATE (picker) = NULL;
 
340
        }
 
341
 
 
342
        if (GTK_OBJECT_CLASS (parent_class)->destroy) {
 
343
                GTK_OBJECT_CLASS (parent_class)->
 
344
                        destroy (a_object);
 
345
        }
 
346
 
 
347
}
 
348
 
 
349
 
 
350
/**
 
351
 *Converts the xmlAttributeType into a string that can be displayed
 
352
 *to the user.
 
353
 *@param a_attribute_type the xmlAttributeType to convert into a string.
 
354
 *@return the converted string or NULL if the conversion could not be made.
 
355
 */
 
356
static gchar *
 
357
mlview_attribute_picker_attr_type_to_str (xmlAttributeType
 
358
                                          a_attribute_type)
 
359
{
 
360
        gchar *result = NULL;
 
361
 
 
362
        switch (a_attribute_type) {
 
363
        case XML_ATTRIBUTE_CDATA:
 
364
                result = g_strdup ("CDATA");
 
365
                break;
 
366
        case XML_ATTRIBUTE_ID:
 
367
                result = g_strdup ("ID");
 
368
                break;
 
369
        case XML_ATTRIBUTE_IDREF:
 
370
                result = g_strdup ("IDREF");
 
371
                break;
 
372
        case XML_ATTRIBUTE_IDREFS:
 
373
                result = g_strdup ("IDREFS");
 
374
                break;
 
375
        case XML_ATTRIBUTE_ENTITY:
 
376
                result = g_strdup ("ENTITY");
 
377
                break;
 
378
        case XML_ATTRIBUTE_ENTITIES:
 
379
                result = g_strdup ("ENTITIES");
 
380
                break;
 
381
        case XML_ATTRIBUTE_NMTOKEN:
 
382
                result = g_strdup ("NMTOKEN");
 
383
                break;
 
384
        case XML_ATTRIBUTE_NMTOKENS:
 
385
                result = g_strdup ("NMTOKENS");
 
386
                break;
 
387
        case XML_ATTRIBUTE_ENUMERATION:
 
388
                result = g_strdup ("ENUMERATION");
 
389
                break;
 
390
        case XML_ATTRIBUTE_NOTATION:
 
391
                result = g_strdup ("NOTATION");
 
392
                break;
 
393
        default:
 
394
                break;
 
395
        }
 
396
        return result;
 
397
}
 
398
 
 
399
/**
 
400
 *Parses the string a_string and return the matching xmlAttributeType.
 
401
 *@param a_string the string to parse.
 
402
 *@return the matching xmlAttributeType. Note that if
 
403
 *the string could not be parsed, this function returns the xmlAttributeType
 
404
 *XML_ATTRIBUTE_CDATA.
 
405
 */
 
406
static xmlAttributeType
 
407
mlview_attribute_picker_parse_attr_type (const gchar * a_string)
 
408
{
 
409
        if (a_string == NULL
 
410
            || mlview_utils_is_white_string (a_string))
 
411
                return XML_ATTRIBUTE_CDATA;
 
412
 
 
413
        if (!strcmp (a_string, "CDATA"))
 
414
                return XML_ATTRIBUTE_CDATA;
 
415
        if (!strcmp (a_string, "ID"))
 
416
                return XML_ATTRIBUTE_ID;
 
417
        if (!strcmp (a_string, "IDREF"))
 
418
                return XML_ATTRIBUTE_IDREF;
 
419
        if (!strcmp (a_string, "IDREFS"))
 
420
                return XML_ATTRIBUTE_IDREFS;
 
421
        if (!strcmp (a_string, "ENTITY"))
 
422
                return XML_ATTRIBUTE_ENTITY;
 
423
        if (!strcmp (a_string, "ENTITIES"))
 
424
                return XML_ATTRIBUTE_ENTITIES;
 
425
        if (!strcmp (a_string, "NMTOKEN"))
 
426
                return XML_ATTRIBUTE_NMTOKEN;
 
427
        if (!strcmp (a_string, "NMTOKENS"))
 
428
                return XML_ATTRIBUTE_NMTOKENS;
 
429
        if (!strcmp (a_string, "ENUMERATION"))
 
430
                return XML_ATTRIBUTE_ENUMERATION;
 
431
        if (!strcmp (a_string, "NOTATION"))
 
432
                return XML_ATTRIBUTE_NOTATION;
 
433
 
 
434
        return XML_ATTRIBUTE_CDATA;
 
435
}
 
436
 
 
437
 
 
438
/**
 
439
 *Shows the attribute values list that has been build and cached into
 
440
 *the object a_this.
 
441
 *@param a_this the current instance of #MlViewAttributePicker.
 
442
 */
 
443
static void
 
444
mlview_attribute_picker_show_attr_values (MlViewAttributePicker *a_this)
 
445
{
 
446
        g_return_if_fail (a_this != NULL);
 
447
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
448
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
449
 
 
450
        /*make sure the attribute list table is not there already... */
 
451
        if (GTK_WIDGET (PRIVATE (a_this)->value_list_table)->
 
452
            parent == GTK_WIDGET (GTK_DIALOG (a_this)->vbox))
 
453
                gtk_container_remove (GTK_CONTAINER
 
454
                                      (GTK_DIALOG (a_this)->
 
455
                                       vbox),
 
456
                                      GTK_WIDGET (PRIVATE
 
457
                                                  (a_this)->
 
458
                                                  value_list_table));
 
459
 
 
460
        /*now, pack the attr list table */
 
461
        gtk_box_pack_start (GTK_BOX
 
462
                            (GTK_DIALOG (a_this)->vbox),
 
463
                            GTK_WIDGET (PRIVATE (a_this)->
 
464
                                        value_list_table), FALSE,
 
465
                            TRUE, 0);
 
466
 
 
467
        gtk_widget_show_all (GTK_WIDGET
 
468
                             (PRIVATE (a_this)->
 
469
                              value_list_table));
 
470
        gtk_widget_show_all (GTK_WIDGET
 
471
                             (GTK_DIALOG (a_this)->vbox));
 
472
}
 
473
 
 
474
 
 
475
/**
 
476
 *Hides the attribute values list that has been build and shown.
 
477
 *@param a_this the current instance of #MlViewAttributePicker.
 
478
 */
 
479
static void
 
480
mlview_attribute_picker_hide_attr_values (MlViewAttributePicker *
 
481
                                          a_this)
 
482
{
 
483
        g_return_if_fail (a_this != NULL);
 
484
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
485
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
486
 
 
487
        /*Make sure the value_list_table is packed in the dialog vbox */
 
488
        if (GTK_WIDGET (PRIVATE (a_this)->value_list_table)->
 
489
            parent == GTK_WIDGET (GTK_DIALOG (a_this)->vbox)) {
 
490
                gtk_container_remove (GTK_CONTAINER
 
491
                                      (GTK_DIALOG (a_this)->
 
492
                                       vbox),
 
493
                                      GTK_WIDGET (PRIVATE
 
494
                                                  (a_this)->
 
495
                                                  value_list_table));
 
496
                gtk_widget_show_all (GTK_WIDGET
 
497
                                     (GTK_DIALOG (a_this)->
 
498
                                      vbox));
 
499
        }
 
500
}
 
501
 
 
502
 
 
503
/*----------------------------------------------------
 
504
 *Private function callbacks.
 
505
 *----------------------------------------------------*/
 
506
 
 
507
 
 
508
/**
 
509
 *Callback function invoked when the attribute name
 
510
 *changes. It actually sets the type of the attribute,
 
511
 *computes the attribute value and displays that choice list if necessary. 
 
512
 *
 
513
 */
 
514
static void
 
515
attribute_name_changed_cb (GtkEditable * a_text_entry,
 
516
                           gpointer a_this)
 
517
{
 
518
        gchar *content = NULL;
 
519
        MlViewAttributePicker *picker = NULL;
 
520
 
 
521
        g_return_if_fail (a_text_entry != NULL);
 
522
        g_return_if_fail (GTK_IS_EDITABLE (a_text_entry));
 
523
        g_return_if_fail (a_this != NULL);
 
524
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
525
 
 
526
        picker = MLVIEW_ATTRIBUTE_PICKER (a_this);
 
527
 
 
528
        if (gv_attributes_completion == FALSE) {
 
529
                return;
 
530
        }
 
531
 
 
532
        gtk_entry_set_text (PRIVATE (picker)->value_edit_entry,
 
533
                            "");
 
534
 
 
535
        content = gtk_editable_get_chars (a_text_entry, 0, -1);
 
536
 
 
537
        if (!content) {
 
538
                mlview_attribute_picker_hide_attr_values
 
539
                        (picker);
 
540
                return;
 
541
        }
 
542
 
 
543
        if (PRIVATE (picker)->cur_xml_node
 
544
            && PRIVATE (picker)->cur_xml_node->name) {
 
545
                xmlAttribute *attr_desc = NULL;
 
546
 
 
547
                /*test if the current attr is a defined attribute */
 
548
                if (PRIVATE (picker)->cur_xml_node->doc->
 
549
                    intSubset) {
 
550
                        attr_desc =
 
551
                                xmlGetDtdAttrDesc (PRIVATE
 
552
                                                   (picker)->
 
553
                                                   cur_xml_node->
 
554
                                                   doc->
 
555
                                                   intSubset,
 
556
                                                   PRIVATE
 
557
                                                   (picker)->
 
558
                                                   cur_xml_node->
 
559
                                                   name,
 
560
                                                   content);
 
561
                }
 
562
                if (attr_desc == NULL
 
563
                    && PRIVATE (picker)->cur_xml_node->doc->
 
564
                    extSubset) {
 
565
                        attr_desc =
 
566
                                xmlGetDtdAttrDesc (PRIVATE
 
567
                                                   (picker)->
 
568
                                                   cur_xml_node->
 
569
                                                   doc->
 
570
                                                   extSubset,
 
571
                                                   PRIVATE
 
572
                                                   (picker)->
 
573
                                                   cur_xml_node->
 
574
                                                   name,
 
575
                                                   content);
 
576
                }
 
577
                if (attr_desc == NULL) { /*attribute is unknown by the dtd */
 
578
                        gchar *attr_type = NULL;
 
579
 
 
580
                        mlview_attribute_picker_hide_attr_values
 
581
                                (picker);
 
582
                        attr_type =
 
583
                                mlview_attribute_picker_attr_type_to_str
 
584
                                (XML_ATTRIBUTE_CDATA);
 
585
 
 
586
                        gtk_entry_set_text (GTK_ENTRY
 
587
                                            (PRIVATE
 
588
                                             (picker)->
 
589
                                             type_edit_entry->
 
590
                                             entry), attr_type);
 
591
                        if (attr_type) {
 
592
                                g_free (attr_type);
 
593
                                attr_type = NULL;
 
594
                        }
 
595
                } else {        /*set the the attribute type and the attribute list */
 
596
                        GList *attr_vals = NULL;
 
597
                        gchar *attr_type = NULL;
 
598
                        gint *last_id_ptr =
 
599
                                mlview_app_context_get_last_id_ptr
 
600
                                (PRIVATE (picker)->app_context);
 
601
 
 
602
                        g_return_if_fail (last_id_ptr != NULL);
 
603
 
 
604
                        attr_type =
 
605
                                mlview_attribute_picker_attr_type_to_str
 
606
                                (attr_desc->atype);
 
607
 
 
608
                        gtk_entry_set_text
 
609
                                (GTK_ENTRY
 
610
                                 (PRIVATE (picker)->
 
611
                                  type_edit_entry->entry),
 
612
                                 attr_type);
 
613
 
 
614
                        if (attr_type) {
 
615
                                g_free (attr_type);
 
616
                                attr_type = NULL;
 
617
                        }
 
618
 
 
619
                        attr_vals =
 
620
                                mlview_parsing_utils_build_graphical_attr_values
 
621
                                (PRIVATE (picker)->app_context,
 
622
                                 attr_desc, last_id_ptr);
 
623
 
 
624
                        if (attr_vals != NULL) {
 
625
 
 
626
                                gtk_list_clear_items
 
627
                                        (PRIVATE (picker)->
 
628
                                         values_list, 0, -1);
 
629
 
 
630
                                gtk_list_append_items
 
631
                                        (PRIVATE (picker)->
 
632
                                         values_list, attr_vals);
 
633
 
 
634
                                mlview_attribute_picker_show_attr_values
 
635
                                        (picker);
 
636
 
 
637
                        } else {
 
638
                                mlview_attribute_picker_hide_attr_values
 
639
                                        (picker);
 
640
                        }
 
641
                }
 
642
        }
 
643
        g_free (content);
 
644
}
 
645
 
 
646
 
 
647
/**
 
648
 *Callback invoked when the attribute type changes. It just enable/disable the
 
649
 *add to value button when necessary. Actually, if the type of the attribute
 
650
 *is either "IDREFS" or "ENTITIES", this function enable the "add to value" button. 
 
651
 *
 
652
 */
 
653
static void
 
654
attribute_type_changed_cb (GtkEditable * a_text_entry,
 
655
                           gpointer a_this)
 
656
{
 
657
        gchar *content = NULL;
 
658
        MlViewAttributePicker *picker = a_this;
 
659
 
 
660
        g_return_if_fail (a_text_entry != NULL);
 
661
        g_return_if_fail (GTK_IS_EDITABLE (a_text_entry));
 
662
        g_return_if_fail (a_this != NULL);
 
663
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
664
 
 
665
        content =
 
666
                gtk_editable_get_chars (GTK_EDITABLE
 
667
                                        (a_text_entry), 0, -1);
 
668
 
 
669
        if (!strcmp (content, "IDRREFS")
 
670
            || !strcmp (content, "ENTITIES")) {
 
671
                gtk_widget_set_sensitive (GTK_WIDGET
 
672
                                          (PRIVATE (picker)->
 
673
                                           add_to_value_button),
 
674
                                          TRUE);
 
675
        } else {
 
676
                gtk_widget_set_sensitive
 
677
                        (GTK_WIDGET
 
678
                         (PRIVATE (picker)->add_to_value_button),
 
679
                         FALSE);
 
680
        }
 
681
}
 
682
 
 
683
 
 
684
/**
 
685
 *The callback executed when the user clicks on the "add to value" button. 
 
686
 *
 
687
 */
 
688
static void
 
689
add_to_value_button_cb (GtkButton * a_button, gpointer a_this)
 
690
{
 
691
        MlViewAttributePicker *picker =
 
692
                (MlViewAttributePicker *) a_this;
 
693
 
 
694
        g_return_if_fail (a_button != NULL);
 
695
        g_return_if_fail (GTK_IS_BUTTON (a_button));
 
696
        g_return_if_fail (a_this != NULL);
 
697
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (picker));
 
698
        g_return_if_fail (PRIVATE (picker) != NULL);
 
699
 
 
700
        if (PRIVATE (picker)->current_attribute_value) {
 
701
                gchar *str = NULL;
 
702
 
 
703
                str = gtk_editable_get_chars
 
704
                        (GTK_EDITABLE
 
705
                         (PRIVATE (picker)->value_edit_entry), 0,
 
706
                         -1);
 
707
                str = g_strconcat (str, " ",
 
708
                                   PRIVATE (picker)->
 
709
                                   current_attribute_value,
 
710
                                   NULL);
 
711
                gtk_entry_set_text (PRIVATE (picker)->
 
712
                                    value_edit_entry, str);
 
713
 
 
714
                if (str) {
 
715
                        g_free (str);
 
716
                        str = NULL;
 
717
                }
 
718
        }
 
719
}
 
720
 
 
721
/**
 
722
 *Callback called when the user clicks on the "set value" button to set
 
723
 *the attribute value to the currently selected value. 
 
724
 *
 
725
 */
 
726
static void
 
727
set_value_button_cb (GtkButton * a_button, gpointer a_this)
 
728
{
 
729
        MlViewAttributePicker *picker =
 
730
                (MlViewAttributePicker *) a_this;
 
731
 
 
732
        g_return_if_fail (a_button != NULL);
 
733
        g_return_if_fail (GTK_IS_BUTTON (a_button));
 
734
        g_return_if_fail (picker != NULL);
 
735
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (picker));
 
736
        g_return_if_fail (PRIVATE (picker) != NULL);
 
737
 
 
738
        if (PRIVATE (picker)->current_attribute_value) {
 
739
                gtk_entry_set_text (PRIVATE (picker)->
 
740
                                    value_edit_entry,
 
741
                                    PRIVATE (picker)->
 
742
                                    current_attribute_value);
 
743
        }
 
744
}
 
745
 
 
746
 
 
747
/**
 
748
 *
 
749
 */
 
750
static void
 
751
attribute_value_selected_cb (GtkList * a_attribute_values_list,
 
752
                             GtkWidget * a_list_item,
 
753
                             gpointer * a_this)
 
754
{
 
755
        MlViewAttributePicker *picker =
 
756
                (MlViewAttributePicker *) a_this;
 
757
        GList *list = NULL;
 
758
 
 
759
        g_return_if_fail (a_attribute_values_list != NULL);
 
760
        g_return_if_fail (a_list_item != NULL);
 
761
        g_return_if_fail (picker != NULL);
 
762
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (picker));
 
763
        g_return_if_fail (PRIVATE (picker) != NULL);
 
764
 
 
765
        /*get the label contained in the GtkItem */
 
766
        list = gtk_container_children (GTK_CONTAINER
 
767
                                       (a_list_item));
 
768
 
 
769
        if (list && list->data && GTK_IS_LABEL (list->data)) {
 
770
                GtkLabel *label = NULL;
 
771
 
 
772
                label = GTK_LABEL (list->data);
 
773
                gtk_label_get (label,
 
774
                               &PRIVATE (picker)->
 
775
                               current_attribute_value);
 
776
 
 
777
        } else {
 
778
                PRIVATE (picker)->current_attribute_value = NULL;
 
779
        }
 
780
}
 
781
 
 
782
 
 
783
/*----------------------------------------------------
 
784
 *Public functions
 
785
 *----------------------------------------------------*/
 
786
 
 
787
 
 
788
/**
 
789
 *Type builder. 
 
790
 *@return the id of the type MlViewAttribute.
 
791
 */
 
792
gint
 
793
mlview_attribute_picker_get_type (void)
 
794
{
 
795
        static gint type = 0;
 
796
 
 
797
        if (!type) {
 
798
                static const GTypeInfo type_info = {
 
799
                        sizeof (MlViewAttributePickerClass),
 
800
                        NULL,   /* base_init */
 
801
                        NULL,   /* base_finalize */
 
802
                        (GClassInitFunc)
 
803
                                mlview_attribute_picker_init_class,
 
804
                        NULL,   /* class_finalize */
 
805
                        NULL,   /* class_data */
 
806
                        sizeof (MlViewAttributePicker),
 
807
                        0,
 
808
                        (GInstanceInitFunc)
 
809
                        mlview_attribute_picker_init
 
810
                };
 
811
 
 
812
                type = g_type_register_static (GTK_TYPE_DIALOG,
 
813
                                               "MlViewAttributePicker",
 
814
                                               &type_info, 0);
 
815
        }
 
816
        return type;
 
817
}
 
818
 
 
819
/**
 
820
 *Builds a brand new attribute picker. 
 
821
 *@param a_title the title the window of the attribute picker.
 
822
 *@param a_app_context the current application context.
 
823
 *@return the widget of the attribute picker. 
 
824
 */
 
825
GtkWidget *
 
826
mlview_attribute_picker_new (gchar * a_title,
 
827
                             MlViewAppContext * a_app_context)
 
828
{
 
829
        MlViewAttributePicker *result = NULL;
 
830
 
 
831
        result = gtk_type_new (MLVIEW_TYPE_ATTRIBUTE_PICKER);
 
832
        mlview_attribute_picker_set_app_context (result,
 
833
                                                 a_app_context);
 
834
        gtk_window_set_title (GTK_WINDOW (result), a_title);
 
835
 
 
836
        return GTK_WIDGET (result);
 
837
}
 
838
 
 
839
 
 
840
/**
 
841
 *Sets a new app context. 
 
842
 *@param a_this the current instance of #MlViewAttributePicker.
 
843
 *@param a_app_context the new application context.
 
844
 */
 
845
void
 
846
mlview_attribute_picker_set_app_context (MlViewAttributePicker *a_this,
 
847
                                         MlViewAppContext *a_app_context)
 
848
{
 
849
        g_return_if_fail (a_this != NULL);
 
850
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
851
        g_return_if_fail (PRIVATE (a_this));
 
852
 
 
853
        PRIVATE (a_this)->app_context = a_app_context;
 
854
 
 
855
}
 
856
 
 
857
/**
 
858
 *Sets the focus to the name entry of 
 
859
 *#MlViewAttributePicker widget. 
 
860
 *@param a_this the current instance of #MlViewAttributePicker.
 
861
 */
 
862
void
 
863
mlview_attribute_picker_grab_focus_to_name_entry (MlViewAttributePicker * a_this) 
 
864
{
 
865
        g_return_if_fail (a_this != NULL);
 
866
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
867
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
868
 
 
869
        if (PRIVATE (a_this)->name_edit_entry)
 
870
                gtk_widget_grab_focus (PRIVATE (a_this)->
 
871
                                       name_edit_entry->entry);
 
872
}
 
873
 
 
874
 
 
875
/**
 
876
 *Sets the focus to the value entry of 
 
877
 *#MlViewAttributePicker widget. 
 
878
 *@param a_this the current instance 
 
879
 *of #MlViewAttributePicker.
 
880
 */
 
881
void
 
882
mlview_attribute_picker_grab_focus_to_value_entry (MlViewAttributePicker * a_this) 
 
883
{
 
884
        g_return_if_fail (a_this != NULL);
 
885
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
886
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
887
 
 
888
        if (PRIVATE (a_this)->value_edit_entry)
 
889
                gtk_widget_grab_focus (GTK_WIDGET
 
890
                                       (PRIVATE (a_this)->
 
891
                                        value_edit_entry));
 
892
}
 
893
 
 
894
 
 
895
/**
 
896
 *Gets the content of the name entry of attribute picker. 
 
897
 *@param a_this the current instance of #MlViewAttributePicker.
 
898
 *@return a pointer to the name entry of attribute picker. 
 
899
 *DO NOT FREE THIS POINTER or you will hang the process. 
 
900
 */
 
901
guchar *
 
902
mlview_attribute_picker_get_attribute_name (MlViewAttributePicker* a_this)
 
903
{
 
904
        g_return_val_if_fail (a_this != NULL, NULL);
 
905
        g_return_val_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER
 
906
                              (a_this), NULL);
 
907
        g_return_val_if_fail (PRIVATE (a_this) != NULL, NULL);
 
908
 
 
909
        if (PRIVATE (a_this)->name_edit_entry
 
910
            && PRIVATE (a_this)->name_edit_entry->entry)
 
911
                return (guchar *) gtk_entry_get_text
 
912
                        (GTK_ENTRY
 
913
                         (PRIVATE
 
914
                          (a_this)->name_edit_entry->entry));
 
915
        else
 
916
                return NULL;
 
917
}
 
918
 
 
919
/**
 
920
 *Gets the content of the value entry of the attribute picker. 
 
921
 *@param a_this the current instance of #MlViewAttributePicker.
 
922
 *@return a pointer to the content of the value entry of the #MlViewAttributePicker widget. 
 
923
 */
 
924
guchar *
 
925
mlview_attribute_picker_get_attribute_value (MlViewAttributePicker * a_this) 
 
926
{
 
927
        g_return_val_if_fail (a_this != NULL, NULL);
 
928
        g_return_val_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER
 
929
                              (a_this), NULL);
 
930
        g_return_val_if_fail (PRIVATE (a_this) != NULL, NULL);
 
931
 
 
932
        if (PRIVATE (a_this)->value_edit_entry)
 
933
                return (guchar *) gtk_entry_get_text
 
934
                        (PRIVATE (a_this)->value_edit_entry);
 
935
        else
 
936
                return NULL;
 
937
}
 
938
 
 
939
/**
 
940
 *Gets the type of the last attribute the user has entered in the picker.
 
941
 *@param a_this the current instance of #MlViewAttributePicker.
 
942
 *@return the type of the last attribute entered by the user in the picker a_this.
 
943
 */
 
944
xmlAttributeType
 
945
mlview_attribute_picker_get_attribute_type (MlViewAttributePicker* a_this)
 
946
{
 
947
        gchar *type_str = NULL;
 
948
 
 
949
        g_return_val_if_fail (a_this != NULL,
 
950
                              XML_ATTRIBUTE_CDATA);
 
951
        g_return_val_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER
 
952
                              (a_this), XML_ATTRIBUTE_CDATA);
 
953
        g_return_val_if_fail (PRIVATE (a_this) != NULL,
 
954
                              XML_ATTRIBUTE_CDATA);
 
955
 
 
956
        if (PRIVATE (a_this)->type_edit_entry
 
957
            && PRIVATE (a_this)->type_edit_entry->entry)
 
958
                type_str = (guchar *) gtk_entry_get_text
 
959
                        (GTK_ENTRY
 
960
                         (PRIVATE
 
961
                          (a_this)->type_edit_entry->entry));
 
962
 
 
963
        if (type_str != NULL
 
964
            && mlview_utils_is_white_string (type_str) ==
 
965
            FALSE) {
 
966
                return mlview_attribute_picker_parse_attr_type
 
967
                        (type_str);
 
968
        } else {
 
969
                return XML_ATTRIBUTE_CDATA;
 
970
        }
 
971
}
 
972
 
 
973
/**
 
974
 *Graphically selects all the content of the name entry of the #MlViewAttributePicker widget. 
 
975
 *@param a_this the current instance of #MlViewAttributePicker.
 
976
 */
 
977
void
 
978
mlview_attribute_picker_select_attribute_name (MlViewAttributePicker * a_this) 
 
979
{
 
980
        g_return_if_fail (a_this != NULL);
 
981
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
982
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
983
 
 
984
        if (PRIVATE (a_this)->name_edit_entry
 
985
            && PRIVATE (a_this)->name_edit_entry->entry)
 
986
                gtk_entry_select_region (GTK_ENTRY
 
987
                                         (PRIVATE (a_this)->
 
988
                                          name_edit_entry->
 
989
                                          entry), 0, -1);
 
990
}
 
991
 
 
992
/**
 
993
 *Graphically selects all the content of 
 
994
 *the value entry of the #MlViewAttributePicker
 
995
 *widget. 
 
996
 *@param a_this the current instance of #MlViewAttributePicker.
 
997
 */
 
998
void
 
999
mlview_attribute_picker_select_attribute_value (MlViewAttributePicker * a_this) 
 
1000
{
 
1001
        g_return_if_fail (a_this != NULL);
 
1002
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
1003
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
1004
 
 
1005
        if (PRIVATE (a_this)->value_edit_entry)
 
1006
                gtk_entry_select_region (PRIVATE (a_this)->
 
1007
                                         value_edit_entry, 0,
 
1008
                                         -1);
 
1009
}
 
1010
 
 
1011
/**
 
1012
 *Associates an xml node to this picker.
 
1013
 *That xml node is used for example to build the attribute name
 
1014
 *completion list if needed.
 
1015
 *
 
1016
 *@param a_this the current instance of #MlViewAttributePicker.
 
1017
 *@param a_xml_node the xmlNode to associate to the current node.
 
1018
 */
 
1019
void
 
1020
mlview_attribute_picker_set_current_xml_node (MlViewAttributePicker * a_this, 
 
1021
                                              xmlNode * a_xml_node)
 
1022
{
 
1023
        g_return_if_fail (a_this != NULL);
 
1024
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
1025
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
1026
 
 
1027
        PRIVATE (a_this)->cur_xml_node = a_xml_node;
 
1028
 
 
1029
}
 
1030
 
 
1031
/**
 
1032
 *Sets the attribute completion on/off.
 
1033
 *All the instances of #MlViewAttributePicker of the current process
 
1034
 *will be affected by this method.
 
1035
 *
 
1036
 *@param a_completion_on wether to set the completion on or not.
 
1037
 */
 
1038
void
 
1039
mlview_attribute_picker_set_attribute_completion (gboolean a_completion_on)
 
1040
{
 
1041
        gv_attributes_completion = a_completion_on;
 
1042
}
 
1043
 
 
1044
 
 
1045
/**
 
1046
 *Builds the attribute name completion list.
 
1047
 *The list is built, cached in the current instance of #MlViewAttributePicker, and displayed to the user
 
1048
 *whenever she clicks in the attribute names completion list.
 
1049
 *This function uses mlview_parsing_utils_build_attribute_name_completion_list() to 
 
1050
 *actually build the completion list.
 
1051
 *@param a_this the current instance of #MlViewAttributePicker.
 
1052
 *@param a_xml_node the xmlNode used to build the attribute name completion list.
 
1053
 *
 
1054
 */
 
1055
void
 
1056
mlview_attribute_picker_build_attribute_name_choice_list (MlViewAttributePicker * a_this, 
 
1057
                                                          xmlNode * a_xml_node)
 
1058
{
 
1059
        gint nb_of_attribute_names = 0;
 
1060
 
 
1061
        g_return_if_fail (a_this != NULL);
 
1062
        g_return_if_fail (MLVIEW_IS_ATTRIBUTE_PICKER (a_this));
 
1063
        g_return_if_fail (PRIVATE (a_this) != NULL);
 
1064
 
 
1065
        gtk_list_clear_items (GTK_LIST
 
1066
                              (PRIVATE (a_this)->values_list),
 
1067
                              0, -1);
 
1068
        gtk_list_clear_items (GTK_LIST
 
1069
                              (PRIVATE (a_this)->
 
1070
                               name_edit_entry->list), 0, -1);
 
1071
        gtk_list_clear_items (GTK_LIST
 
1072
                              (PRIVATE (a_this)->
 
1073
                               type_edit_entry->list), 0, -1);
 
1074
        /*FIXME: clear the two GktEntry widgets too. This is a bug. */
 
1075
 
 
1076
        if (a_xml_node == NULL || a_xml_node->doc == NULL
 
1077
            || gv_attributes_completion == FALSE) {
 
1078
                return;
 
1079
        }
 
1080
 
 
1081
        nb_of_attribute_names =
 
1082
                mlview_parsing_utils_build_attribute_name_completion_list
 
1083
                (PRIVATE (a_this)->app_context, a_xml_node,
 
1084
                 &PRIVATE (a_this)->names_completion_list,
 
1085
                 FALSE
 
1086
                 /*get all the attributes, even the optional */
 
1087
                );
 
1088
 
 
1089
        if (nb_of_attribute_names > 0) {
 
1090
                if (PRIVATE (a_this)->names_completion_list)
 
1091
                        gtk_combo_set_popdown_strings
 
1092
                                (PRIVATE (a_this)->
 
1093
                                 name_edit_entry,
 
1094
                                 PRIVATE (a_this)->
 
1095
                                 names_completion_list);
 
1096
        }
 
1097
}