f23018421505a9ca6d497c97bcadfeb44872a6cd
[pspp-builds.git] / src / ui / gui / psppire-dict.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2004, 2006, 2007  Free Software Foundation
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <string.h>
19 #include <stdlib.h>
20
21 #include <gtk/gtk.h>
22 #include <gtksheet/psppire-marshal.h>
23
24 #include "psppire-dict.h"
25 #include <data/dictionary.h>
26 #include <data/missing-values.h>
27 #include <data/value-labels.h>
28 #include <data/variable.h>
29
30 #include "helper.h"
31 #include "message-dialog.h"
32
33
34 enum  {
35   BACKEND_CHANGED,
36
37   VARIABLE_CHANGED,
38   VARIABLE_RESIZED,
39   VARIABLE_INSERTED,
40   VARIABLE_DELETED,
41   VARIABLE_DISPLAY_WIDTH_CHANGED,
42
43   WEIGHT_CHANGED,
44   FILTER_CHANGED,
45   SPLIT_CHANGED,
46   n_SIGNALS
47 };
48
49
50 /* --- prototypes --- */
51 static void psppire_dict_class_init     (PsppireDictClass       *class);
52 static void psppire_dict_init   (PsppireDict            *dict);
53 static void psppire_dict_finalize       (GObject                *object);
54
55 static void dictionary_tree_model_init (GtkTreeModelIface *iface);
56
57
58 /* --- variables --- */
59 static GObjectClass     *parent_class = NULL;
60
61 static guint signals [n_SIGNALS];
62
63 /* --- functions --- */
64 /**
65  * psppire_dict_get_type:
66  * @returns: the type ID for accelerator groups.
67  */
68 GType
69 psppire_dict_get_type (void)
70 {
71   static GType object_type = 0;
72
73   if (!object_type)
74     {
75       static const GTypeInfo object_info = {
76         sizeof (PsppireDictClass),
77         (GBaseInitFunc) NULL,
78         (GBaseFinalizeFunc) NULL,
79         (GClassInitFunc) psppire_dict_class_init,
80         NULL,   /* class_finalize */
81         NULL,   /* class_data */
82         sizeof (PsppireDict),
83         0,      /* n_preallocs */
84         (GInstanceInitFunc) psppire_dict_init,
85       };
86
87       static const GInterfaceInfo tree_model_info = {
88         (GInterfaceInitFunc) dictionary_tree_model_init,
89         NULL,
90         NULL
91       };
92
93       object_type = g_type_register_static (G_TYPE_OBJECT,
94                                             "PsppireDict",
95                                             &object_info, 0);
96
97       g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL,
98                                    &tree_model_info);
99     }
100
101   return object_type;
102 }
103
104
105 static void
106 psppire_dict_class_init (PsppireDictClass *class)
107 {
108   GObjectClass *object_class = G_OBJECT_CLASS (class);
109
110   parent_class = g_type_class_peek_parent (class);
111
112   object_class->finalize = psppire_dict_finalize;
113
114   signals [BACKEND_CHANGED] =
115     g_signal_new ("backend-changed",
116                   G_TYPE_FROM_CLASS (class),
117                   G_SIGNAL_RUN_FIRST,
118                   0,
119                   NULL, NULL,
120                   g_cclosure_marshal_VOID__VOID,
121                   G_TYPE_NONE,
122                   0);
123
124
125   signals [VARIABLE_CHANGED] =
126     g_signal_new ("variable_changed",
127                   G_TYPE_FROM_CLASS (class),
128                   G_SIGNAL_RUN_FIRST,
129                   0,
130                   NULL, NULL,
131                   g_cclosure_marshal_VOID__INT,
132                   G_TYPE_NONE,
133                   1,
134                   G_TYPE_INT);
135
136
137
138   signals [VARIABLE_INSERTED] =
139     g_signal_new ("variable_inserted",
140                   G_TYPE_FROM_CLASS (class),
141                   G_SIGNAL_RUN_FIRST,
142                   0,
143                   NULL, NULL,
144                   g_cclosure_marshal_VOID__INT,
145                   G_TYPE_NONE,
146                   1,
147                   G_TYPE_INT);
148
149
150   signals [VARIABLE_DELETED] =
151     g_signal_new ("variable-deleted",
152                   G_TYPE_FROM_CLASS (class),
153                   G_SIGNAL_RUN_FIRST,
154                   0,
155                   NULL, NULL,
156                   marshaller_VOID__INT_INT_INT,
157                   G_TYPE_NONE,
158                   3,
159                   G_TYPE_INT,
160                   G_TYPE_INT,
161                   G_TYPE_INT);
162
163
164   signals [VARIABLE_RESIZED] =
165     g_signal_new ("dict-size-changed",
166                   G_TYPE_FROM_CLASS (class),
167                   G_SIGNAL_RUN_FIRST,
168                   0,
169                   NULL, NULL,
170                   psppire_marshal_VOID__INT_INT,
171                   G_TYPE_NONE,
172                   2,
173                   G_TYPE_INT,
174                   G_TYPE_INT);
175
176   signals [VARIABLE_DISPLAY_WIDTH_CHANGED] =
177     g_signal_new ("variable-display-width-changed",
178                   G_TYPE_FROM_CLASS (class),
179                   G_SIGNAL_RUN_FIRST,
180                   0,
181                   NULL, NULL,
182                   g_cclosure_marshal_VOID__INT,
183                   G_TYPE_NONE,
184                   1,
185                   G_TYPE_INT);
186
187
188   signals [WEIGHT_CHANGED] =
189     g_signal_new ("weight-changed",
190                   G_TYPE_FROM_CLASS (class),
191                   G_SIGNAL_RUN_FIRST,
192                   0,
193                   NULL, NULL,
194                   g_cclosure_marshal_VOID__INT,
195                   G_TYPE_NONE,
196                   1,
197                   G_TYPE_INT);
198
199
200   signals [FILTER_CHANGED] =
201     g_signal_new ("filter-changed",
202                   G_TYPE_FROM_CLASS (class),
203                   G_SIGNAL_RUN_FIRST,
204                   0,
205                   NULL, NULL,
206                   g_cclosure_marshal_VOID__INT,
207                   G_TYPE_NONE,
208                   1,
209                   G_TYPE_INT);
210
211
212   signals [SPLIT_CHANGED] =
213     g_signal_new ("split-changed",
214                   G_TYPE_FROM_CLASS (class),
215                   G_SIGNAL_RUN_FIRST,
216                   0,
217                   NULL, NULL,
218                   g_cclosure_marshal_VOID__VOID,
219                   G_TYPE_NONE,
220                   0);
221 }
222
223 static void
224 psppire_dict_finalize (GObject *object)
225 {
226   PsppireDict *d = PSPPIRE_DICT (object);
227
228   dict_destroy (d->dict);
229
230   G_OBJECT_CLASS (parent_class)->finalize (object);
231 }
232
233 /* Pass on callbacks from src/data/dictionary, as
234    signals in the Gtk library */
235 static void
236 addcb (struct dictionary *d, int idx, void *pd)
237 {
238   PsppireDict *dict = PSPPIRE_DICT (pd);
239
240   if ( ! dict->disable_insert_signal)
241     g_signal_emit (dict, signals [VARIABLE_INSERTED], 0, idx);
242 }
243
244 static void
245 delcb (struct dictionary *d, int dict_idx, int case_idx, int value_cnt,
246        void *pd)
247 {
248   g_signal_emit (pd, signals [VARIABLE_DELETED], 0,
249                  dict_idx, case_idx, value_cnt );
250 }
251
252 static void
253 mutcb (struct dictionary *d, int idx, void *pd)
254 {
255   g_signal_emit (pd, signals [VARIABLE_CHANGED], 0, idx);
256 }
257
258 static void
259 resize_cb (struct dictionary *d, int idx, int delta, void *pd)
260 {
261   g_signal_emit (pd, signals [VARIABLE_RESIZED], 0, idx, delta);
262 }
263
264 static void
265 weight_changed_callback (struct dictionary *d, int idx, void *pd)
266 {
267   g_signal_emit (pd, signals [WEIGHT_CHANGED], 0, idx);
268 }
269
270 static void
271 filter_changed_callback (struct dictionary *d, int idx, void *pd)
272 {
273   g_signal_emit (pd, signals [FILTER_CHANGED], 0, idx);
274 }
275
276 static void
277 split_changed_callback (struct dictionary *d, void *pd)
278 {
279   g_signal_emit (pd, signals [SPLIT_CHANGED], 0);
280 }
281
282 static void
283 variable_display_width_callback (struct dictionary *d, int idx, void *pd)
284 {
285   g_signal_emit (pd, signals [VARIABLE_DISPLAY_WIDTH_CHANGED], 0, idx);
286 }
287
288
289
290 static const struct dict_callbacks gui_callbacks =
291   {
292     addcb,
293     delcb,
294     mutcb,
295     resize_cb,
296     weight_changed_callback,
297     filter_changed_callback,
298     split_changed_callback,
299     variable_display_width_callback
300   };
301
302 static void
303 psppire_dict_init (PsppireDict *psppire_dict)
304 {
305   psppire_dict->stamp = g_random_int ();
306   psppire_dict->disable_insert_signal = FALSE;
307 }
308
309 /**
310  * psppire_dict_new_from_dict:
311  * @returns: a new #PsppireDict object
312  *
313  * Creates a new #PsppireDict.
314  */
315 PsppireDict*
316 psppire_dict_new_from_dict (struct dictionary *d)
317 {
318   PsppireDict *new_dict = g_object_new (G_TYPE_PSPPIRE_DICT, NULL);
319   new_dict->dict = d;
320
321   dict_set_callbacks (new_dict->dict, &gui_callbacks, new_dict);
322
323   return new_dict;
324 }
325
326
327 void
328 psppire_dict_replace_dictionary (PsppireDict *dict, struct dictionary *d)
329 {
330   struct variable *var =  dict_get_weight (d);
331
332   dict->dict = d;
333
334   weight_changed_callback (d, var ? var_get_dict_index (var) : -1, dict);
335
336   var = dict_get_filter (d);
337   filter_changed_callback (d, var ? var_get_dict_index (var) : -1, dict);
338
339   split_changed_callback (d, dict);
340
341   dict_set_callbacks (dict->dict, &gui_callbacks, dict);
342
343   g_signal_emit (dict, signals [BACKEND_CHANGED], 0);
344 }
345
346
347 /* Returns a valid name for a new variable in DICT.
348    The return value is statically allocated */
349 static gchar *
350 auto_generate_var_name (PsppireDict *dict)
351 {
352   gint d = 0;
353   static gchar name[10];
354
355   while (g_snprintf (name, 10, "VAR%05d",d++),
356          psppire_dict_lookup_var (dict, name))
357     ;
358
359   return name;
360 }
361
362 /* Insert a new variable at posn IDX, with the name NAME.
363    If NAME is null, then a name will be automatically assigned.
364 */
365 void
366 psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name)
367 {
368   struct variable *var ;
369   g_return_if_fail (idx >= 0);
370   g_return_if_fail (d);
371   g_return_if_fail (PSPPIRE_IS_DICT (d));
372
373   if ( ! name )
374     name = auto_generate_var_name (d);
375
376   d->disable_insert_signal = TRUE;
377
378   var = dict_create_var (d->dict, name, 0);
379
380   dict_reorder_var (d->dict, var, idx);
381
382   d->disable_insert_signal = FALSE;
383
384   g_signal_emit (d, signals[VARIABLE_INSERTED], 0, idx);
385 }
386
387 /* Delete N variables beginning at FIRST */
388 void
389 psppire_dict_delete_variables (PsppireDict *d, gint first, gint n)
390 {
391   gint idx;
392   g_return_if_fail (d);
393   g_return_if_fail (d->dict);
394   g_return_if_fail (PSPPIRE_IS_DICT (d));
395
396   for (idx = 0 ; idx < n ; ++idx )
397     {
398       struct variable *var;
399
400       /* Do nothing if it's out of bounds */
401       if ( first >= dict_get_var_cnt (d->dict))
402         break;
403
404       var = dict_get_var (d->dict, first);
405       dict_delete_var (d->dict, var);
406     }
407 }
408
409
410 gboolean
411 psppire_dict_set_name (PsppireDict* d, gint idx, const gchar *name)
412 {
413   struct variable *var;
414   g_assert (d);
415   g_assert (PSPPIRE_IS_DICT (d));
416
417   if ( ! var_is_valid_name (name, false))
418     return FALSE;
419
420   if ( idx < dict_get_var_cnt (d->dict))
421     {
422       /* This is an existing variable? */
423       var = dict_get_var (d->dict, idx);
424       dict_rename_var (d->dict, var, name);
425     }
426   else
427     {
428       /* new variable */
429       dict_create_var (d->dict, name, 0);
430     }
431
432   return TRUE;
433 }
434
435
436
437 /* Return the IDXth variable */
438 struct variable *
439 psppire_dict_get_variable (const PsppireDict *d, gint idx)
440 {
441   g_return_val_if_fail (d, NULL);
442   g_return_val_if_fail (d->dict, NULL);
443
444   if ( dict_get_var_cnt (d->dict) <= idx )
445     return NULL;
446
447   return dict_get_var (d->dict, idx);
448 }
449
450
451 /* Return the number of variables in the dictionary */
452 gint
453 psppire_dict_get_var_cnt (const PsppireDict *d)
454 {
455   g_return_val_if_fail (d, -1);
456   g_return_val_if_fail (d->dict, -1);
457
458   return dict_get_var_cnt (d->dict);
459 }
460
461
462 /* Return the number of `union value's in the dictionary */
463 size_t
464 psppire_dict_get_value_cnt (const PsppireDict *d)
465 {
466   g_return_val_if_fail (d, -1);
467   g_return_val_if_fail (d->dict, -1);
468
469   return dict_get_next_value_idx (d->dict);
470 }
471
472
473 /* Return a variable by name.
474    Return NULL if it doesn't exist
475 */
476 struct variable *
477 psppire_dict_lookup_var (const PsppireDict *d, const gchar *name)
478 {
479   g_return_val_if_fail (d, NULL);
480   g_return_val_if_fail (d->dict, NULL);
481
482   return dict_lookup_var (d->dict, name);
483 }
484
485 /* Clears the contents of D */
486 void
487 psppire_dict_clear (PsppireDict *d)
488 {
489   g_return_if_fail (d);
490   g_return_if_fail (d->dict);
491
492   {
493     dict_clear (d->dict);
494   }
495 }
496
497
498 /* Return true is NAME would be a valid name of a variable to add to the
499    dictionary.  False otherwise.
500    If REPORT is true, then invalid names will be reported as such as errors
501 */
502 gboolean
503 psppire_dict_check_name (const PsppireDict *dict,
504                          const gchar *name, gboolean report)
505 {
506   if ( ! var_is_valid_name (name, report ) )
507     return FALSE;
508
509   if (psppire_dict_lookup_var (dict, name))
510     {
511       if ( report )
512         msg (ME,"Duplicate variable name.");
513       return FALSE;
514     }
515
516   return TRUE;
517 }
518
519
520 gint
521 psppire_dict_get_next_value_idx (const PsppireDict *dict)
522 {
523   return dict_get_next_value_idx (dict->dict);
524 }
525
526
527 void
528 psppire_dict_resize_variable (PsppireDict *d, const struct variable *pv,
529                               gint old_size, gint new_size)
530 {
531   gint fv;
532   g_return_if_fail (d);
533   g_return_if_fail (d->dict);
534
535   if ( old_size == new_size )
536     return ;
537
538   fv = var_get_case_index (pv);
539
540   g_signal_emit (d, signals [VARIABLE_RESIZED], 0,
541                  fv + old_size,
542                  new_size - old_size );
543 }
544
545
546 /* Tree Model Stuff */
547
548 static GtkTreeModelFlags tree_model_get_flags (GtkTreeModel *model);
549
550 static gint tree_model_n_columns (GtkTreeModel *model);
551
552 static GType tree_model_column_type (GtkTreeModel *model, gint index);
553
554 static gboolean tree_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter,
555                                      GtkTreePath *path);
556
557 static gboolean tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter);
558
559 static GtkTreePath * tree_model_get_path (GtkTreeModel *model,
560                                           GtkTreeIter *iter);
561
562 static void tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
563                                   gint column, GValue *value);
564
565 static gboolean tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
566                                       GtkTreeIter *parent, gint n);
567
568 static gint tree_model_n_children (GtkTreeModel *tree_model,
569                                    GtkTreeIter  *iter);
570
571 static gboolean tree_model_iter_children (GtkTreeModel *,
572                                           GtkTreeIter *,
573                                           GtkTreeIter *);
574
575 static gboolean tree_model_iter_parent (GtkTreeModel *tree_model,
576                                         GtkTreeIter *iter,
577                                         GtkTreeIter *child);
578
579 static gboolean tree_model_iter_has_child  (GtkTreeModel *tree_model,
580                                             GtkTreeIter  *iter);
581
582 static void
583 dictionary_tree_model_init (GtkTreeModelIface *iface)
584 {
585   iface->get_flags = tree_model_get_flags;
586   iface->get_n_columns = tree_model_n_columns;
587   iface->get_column_type = tree_model_column_type;
588   iface->get_iter = tree_model_get_iter;
589   iface->iter_next = tree_model_iter_next;
590   iface->get_path = tree_model_get_path;
591   iface->get_value = tree_model_get_value;
592
593   iface->iter_children = tree_model_iter_children ;
594   iface->iter_has_child = tree_model_iter_has_child ;
595   iface->iter_n_children = tree_model_n_children ;
596   iface->iter_nth_child = tree_model_nth_child ;
597   iface->iter_parent = tree_model_iter_parent ;
598 }
599
600 static gboolean
601 tree_model_iter_has_child  (GtkTreeModel *tree_model,
602                             GtkTreeIter  *iter)
603 {
604   return FALSE;
605 }
606
607 static gboolean
608 tree_model_iter_parent (GtkTreeModel *tree_model,
609                         GtkTreeIter *iter,
610                         GtkTreeIter *child)
611 {
612   return TRUE;
613 }
614
615 static GtkTreeModelFlags
616 tree_model_get_flags (GtkTreeModel *model)
617 {
618   g_return_val_if_fail (PSPPIRE_IS_DICT (model), (GtkTreeModelFlags) 0);
619
620   return GTK_TREE_MODEL_LIST_ONLY;
621 }
622
623
624 static gint
625 tree_model_n_columns (GtkTreeModel *model)
626 {
627   return n_DICT_COLS;
628 }
629
630 static GType
631 tree_model_column_type (GtkTreeModel *model, gint index)
632 {
633   g_return_val_if_fail (PSPPIRE_IS_DICT (model), (GType) 0);
634
635   switch (index)
636     {
637     case DICT_TVM_COL_NAME:
638       return G_TYPE_STRING;
639       break;
640     case DICT_TVM_COL_VAR:
641       return G_TYPE_POINTER;
642       break;
643     default:
644       g_return_val_if_reached ((GType)0);
645       break;
646     }
647
648   g_assert_not_reached ();
649   return ((GType)0);
650 }
651
652 static gboolean
653 tree_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path)
654 {
655   gint *indices, depth;
656   gint n;
657   struct variable *var;
658
659   PsppireDict *dict = PSPPIRE_DICT (model);
660
661   g_return_val_if_fail (path, FALSE);
662
663   indices = gtk_tree_path_get_indices (path);
664   depth = gtk_tree_path_get_depth (path);
665
666   g_return_val_if_fail (depth == 1, FALSE);
667
668   n = indices [0];
669
670   if ( n < 0 || n >= psppire_dict_get_var_cnt (dict))
671     {
672       iter->stamp = 0;
673       iter->user_data = NULL;
674       return FALSE;
675     }
676
677   var = psppire_dict_get_variable (dict, n);
678
679   g_assert (var_get_dict_index (var) == n);
680
681   iter->stamp = dict->stamp;
682   iter->user_data = var;
683
684   return TRUE;
685 }
686
687
688 static gboolean
689 tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter)
690 {
691   PsppireDict *dict = PSPPIRE_DICT (model);
692   struct variable *var;
693   gint idx;
694
695   g_return_val_if_fail (iter->stamp == dict->stamp, FALSE);
696
697   if ( iter == NULL || iter->user_data == NULL)
698     return FALSE;
699
700   var = iter->user_data;
701
702   idx = var_get_dict_index (var);
703
704   if ( idx + 1 >= psppire_dict_get_var_cnt (dict))
705     {
706       iter->user_data = NULL;
707       iter->stamp = 0;
708       return FALSE;
709     }
710
711   var = psppire_dict_get_variable (dict, idx + 1);
712
713   g_assert (var_get_dict_index (var) == idx + 1);
714
715   iter->user_data = var;
716
717   return TRUE;
718 }
719
720 static GtkTreePath *
721 tree_model_get_path (GtkTreeModel *model, GtkTreeIter *iter)
722 {
723   GtkTreePath *path;
724   struct variable *var;
725   PsppireDict *dict = PSPPIRE_DICT (model);
726
727   g_return_val_if_fail (iter->stamp == dict->stamp, FALSE);
728
729   var = iter->user_data;
730
731   path = gtk_tree_path_new ();
732   gtk_tree_path_append_index (path, var_get_dict_index (var));
733
734   return path;
735 }
736
737
738 static void
739 tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
740                       gint column, GValue *value)
741 {
742   struct variable *var;
743   PsppireDict *dict = PSPPIRE_DICT (model);
744
745   g_return_if_fail (iter->stamp == dict->stamp);
746
747   var =  iter->user_data;
748
749   switch (column)
750     {
751     case DICT_TVM_COL_NAME:
752       {
753       gchar *name = pspp_locale_to_utf8(var_get_name (var), -1, NULL);
754       g_value_init (value, G_TYPE_STRING);
755       g_value_set_string (value, name);
756       g_free (name);
757       }
758       break;
759     case DICT_TVM_COL_VAR:
760       g_value_init (value, G_TYPE_POINTER);
761       g_value_set_pointer (value, var);
762       break;
763     default:
764       g_return_if_reached ();
765       break;
766     }
767 }
768
769 static gboolean
770 tree_model_iter_children (GtkTreeModel *tree_model,
771                           GtkTreeIter *iter,
772                           GtkTreeIter *parent)
773 {
774   return FALSE;
775 }
776
777 static gint
778 tree_model_n_children (GtkTreeModel *model,
779                        GtkTreeIter  *iter)
780 {
781   PsppireDict *dict = PSPPIRE_DICT (model);
782
783   if ( iter == NULL )
784     return psppire_dict_get_var_cnt (dict);
785
786   return 0;
787 }
788
789 static gboolean
790 tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
791                       GtkTreeIter *parent, gint n)
792 {
793   PsppireDict *dict;
794
795   g_return_val_if_fail (PSPPIRE_IS_DICT (model), FALSE);
796
797   dict = PSPPIRE_DICT (model);
798
799   if ( parent )
800     return FALSE;
801
802   if ( n >= psppire_dict_get_var_cnt (dict) )
803     return FALSE;
804
805   iter->stamp = dict->stamp;
806   iter->user_data = psppire_dict_get_variable (dict, n);
807
808   if ( !iter->user_data)
809     return FALSE;
810
811   return TRUE;
812 }
813
814
815 gboolean
816 psppire_dict_rename_var (PsppireDict *dict, struct variable *v,
817                          const gchar *name)
818 {
819   if ( ! var_is_valid_name (name, false))
820     return FALSE;
821
822   /* Make sure no other variable has this name */
823   if ( NULL != psppire_dict_lookup_var (dict, name))
824     return FALSE;
825
826   dict_rename_var (dict->dict, v, name);
827
828   return TRUE;
829 }
830
831
832 struct variable *
833 psppire_dict_get_weight_variable (const PsppireDict *dict)
834 {
835   return dict_get_weight (dict->dict);
836 }
837
838
839
840 #if DEBUGGING
841 void
842 psppire_dict_dump (const PsppireDict *dict)
843 {
844   gint i;
845   const struct dictionary *d = dict->dict;
846
847   for (i = 0; i < dict_get_var_cnt (d); ++i)
848     {
849       const struct variable *v = psppire_dict_get_variable (dict, i);
850       int di = var_get_dict_index (v);
851       g_print ("\"%s\" idx=%d, fv=%d, size=%d\n",
852                var_get_name(v),
853                di,
854                var_get_case_index(v),
855                value_cnt_from_width(var_get_width(v)));
856
857     }
858 }
859 #endif