Convert to utf8 in data_out function.
[pspp-builds.git] / src / ui / gui / psppire-dict.c
index cf66ca13c2820d6bf64d57a18bae52ddf4dd1a3d..c82395f2ebdc047e1f8678b9e9d6873df2452207 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2004, 2006, 2007  Free Software Foundation
+   Copyright (C) 2004, 2006, 2007, 2009  Free Software Foundation
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include <stdlib.h>
 
 #include <gtk/gtk.h>
-#include <gtksheet/gtkextra-marshal.h>
+#include <ui/gui/psppire-marshal.h>
 
 #include "psppire-dict.h"
-#include <data/format.h>
 #include <data/dictionary.h>
 #include <data/missing-values.h>
 #include <data/value-labels.h>
 #include <data/variable.h>
+#include <libpspp/i18n.h>
 
 #include "helper.h"
 #include "message-dialog.h"
 
-/* --- prototypes --- */
-static void psppire_dict_class_init    (PsppireDictClass       *class);
-static void psppire_dict_init  (PsppireDict            *dict);
-static void psppire_dict_finalize      (GObject                *object);
-
-static void dictionary_tree_model_init (GtkTreeModelIface *iface);
-
-
-/* --- variables --- */
-static GObjectClass     *parent_class = NULL;
 
 enum  {
   BACKEND_CHANGED,
@@ -49,6 +39,7 @@ enum  {
   VARIABLE_RESIZED,
   VARIABLE_INSERTED,
   VARIABLE_DELETED,
+  VARIABLE_DISPLAY_WIDTH_CHANGED,
 
   WEIGHT_CHANGED,
   FILTER_CHANGED,
@@ -56,6 +47,18 @@ enum  {
   n_SIGNALS
 };
 
+
+/* --- prototypes --- */
+static void psppire_dict_class_init    (PsppireDictClass       *class);
+static void psppire_dict_init  (PsppireDict            *dict);
+static void psppire_dict_finalize      (GObject                *object);
+
+static void dictionary_tree_model_init (GtkTreeModelIface *iface);
+
+
+/* --- variables --- */
+static GObjectClass     *parent_class = NULL;
+
 static guint signals [n_SIGNALS];
 
 /* --- functions --- */
@@ -94,8 +97,6 @@ psppire_dict_get_type (void)
 
       g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL,
                                   &tree_model_info);
-
-
     }
 
   return object_type;
@@ -153,7 +154,7 @@ psppire_dict_class_init (PsppireDictClass *class)
                  G_SIGNAL_RUN_FIRST,
                  0,
                  NULL, NULL,
-                 marshaller_VOID__INT_INT_INT,
+                 psppire_marshal_VOID__INT_INT_INT,
                  G_TYPE_NONE,
                  3,
                  G_TYPE_INT,
@@ -167,12 +168,23 @@ psppire_dict_class_init (PsppireDictClass *class)
                  G_SIGNAL_RUN_FIRST,
                  0,
                  NULL, NULL,
-                 gtkextra_VOID__INT_INT,
+                 psppire_marshal_VOID__INT_INT,
                  G_TYPE_NONE,
                  2,
                  G_TYPE_INT,
                  G_TYPE_INT);
 
+  signals [VARIABLE_DISPLAY_WIDTH_CHANGED] =
+    g_signal_new ("variable-display-width-changed",
+                 G_TYPE_FROM_CLASS (class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__INT,
+                 G_TYPE_NONE,
+                 1,
+                 G_TYPE_INT);
+
 
   signals [WEIGHT_CHANGED] =
     g_signal_new ("weight-changed",
@@ -224,15 +236,17 @@ psppire_dict_finalize (GObject *object)
 static void
 addcb (struct dictionary *d, int idx, void *pd)
 {
-  g_signal_emit (pd, signals [VARIABLE_INSERTED], 0, idx);
+  PsppireDict *dict = PSPPIRE_DICT (pd);
+
+  if ( ! dict->disable_insert_signal)
+    g_signal_emit (dict, signals [VARIABLE_INSERTED], 0, idx);
 }
 
 static void
-delcb (struct dictionary *d, int dict_idx, int case_idx, int value_cnt,
-       void *pd)
+delcb (struct dictionary *d, int dict_idx, int case_idx, int width, void *pd)
 {
   g_signal_emit (pd, signals [VARIABLE_DELETED], 0,
-                dict_idx, case_idx, value_cnt );
+                 dict_idx, case_idx, width );
 }
 
 static void
@@ -242,9 +256,9 @@ mutcb (struct dictionary *d, int idx, void *pd)
 }
 
 static void
-resize_cb (struct dictionary *d, int idx, int delta, void *pd)
+resize_cb (struct dictionary *d, int idx, int old_width, void *pd)
 {
-  g_signal_emit (pd, signals [VARIABLE_RESIZED], 0, idx, delta);
+  g_signal_emit (pd, signals [VARIABLE_RESIZED], 0, idx, old_width);
 }
 
 static void
@@ -265,6 +279,13 @@ split_changed_callback (struct dictionary *d, void *pd)
   g_signal_emit (pd, signals [SPLIT_CHANGED], 0);
 }
 
+static void
+variable_display_width_callback (struct dictionary *d, int idx, void *pd)
+{
+  g_signal_emit (pd, signals [VARIABLE_DISPLAY_WIDTH_CHANGED], 0, idx);
+}
+
+
 
 static const struct dict_callbacks gui_callbacks =
   {
@@ -274,13 +295,15 @@ static const struct dict_callbacks gui_callbacks =
     resize_cb,
     weight_changed_callback,
     filter_changed_callback,
-    split_changed_callback
+    split_changed_callback,
+    variable_display_width_callback
   };
 
 static void
 psppire_dict_init (PsppireDict *psppire_dict)
 {
   psppire_dict->stamp = g_random_int ();
+  psppire_dict->disable_insert_signal = FALSE;
 }
 
 /**
@@ -292,7 +315,7 @@ psppire_dict_init (PsppireDict *psppire_dict)
 PsppireDict*
 psppire_dict_new_from_dict (struct dictionary *d)
 {
-  PsppireDict *new_dict = g_object_new (G_TYPE_PSPPIRE_DICT, NULL);
+  PsppireDict *new_dict = g_object_new (PSPPIRE_TYPE_DICT, NULL);
   new_dict->dict = d;
 
   dict_set_callbacks (new_dict->dict, &gui_callbacks, new_dict);
@@ -350,9 +373,15 @@ psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name)
   if ( ! name )
     name = auto_generate_var_name (d);
 
+  d->disable_insert_signal = TRUE;
+
   var = dict_create_var (d->dict, name, 0);
 
   dict_reorder_var (d->dict, var, idx);
+
+  d->disable_insert_signal = FALSE;
+
+  g_signal_emit (d, signals[VARIABLE_INSERTED], 0, idx);
 }
 
 /* Delete N variables beginning at FIRST */
@@ -405,7 +434,9 @@ psppire_dict_set_name (PsppireDict* d, gint idx, const gchar *name)
 
 
 
-/* Return the IDXth variable */
+/* Return the IDXth variable.
+   Will return NULL if IDX  exceeds the number of variables in the dictionary.
+ */
 struct variable *
 psppire_dict_get_variable (const PsppireDict *d, gint idx)
 {
@@ -441,6 +472,17 @@ psppire_dict_get_value_cnt (const PsppireDict *d)
 }
 
 
+/* Returns the prototype for the cases that match the dictionary */
+const struct caseproto *
+psppire_dict_get_proto (const PsppireDict *d)
+{
+  g_return_val_if_fail (d, NULL);
+  g_return_val_if_fail (d->dict, NULL);
+
+  return dict_get_proto (d->dict);
+}
+
+
 /* Return a variable by name.
    Return NULL if it doesn't exist
 */
@@ -488,7 +530,7 @@ psppire_dict_check_name (const PsppireDict *dict,
 }
 
 
-inline gint
+gint
 psppire_dict_get_next_value_idx (const PsppireDict *dict)
 {
   return dict_get_next_value_idx (dict->dict);
@@ -499,17 +541,14 @@ void
 psppire_dict_resize_variable (PsppireDict *d, const struct variable *pv,
                              gint old_size, gint new_size)
 {
-  gint fv;
   g_return_if_fail (d);
   g_return_if_fail (d->dict);
 
   if ( old_size == new_size )
     return ;
 
-  fv = var_get_case_index (pv);
-
   g_signal_emit (d, signals [VARIABLE_RESIZED], 0,
-                fv + old_size,
+                var_get_dict_index (pv),
                 new_size - old_size );
 }
 
@@ -721,10 +760,8 @@ tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
     {
     case DICT_TVM_COL_NAME:
       {
-      gchar *name = pspp_locale_to_utf8(var_get_name (var), -1, NULL);
-      g_value_init (value, G_TYPE_STRING);
-      g_value_set_string (value, name);
-      g_free (name);
+       g_value_init (value, G_TYPE_STRING);
+       g_value_set_string (value, var_get_name (var));
       }
       break;
     case DICT_TVM_COL_VAR:
@@ -790,6 +827,10 @@ psppire_dict_rename_var (PsppireDict *dict, struct variable *v,
   if ( ! var_is_valid_name (name, false))
     return FALSE;
 
+  /* Make sure no other variable has this name */
+  if ( NULL != psppire_dict_lookup_var (dict, name))
+    return FALSE;
+
   dict_rename_var (dict->dict, v, name);
 
   return TRUE;
@@ -815,12 +856,20 @@ psppire_dict_dump (const PsppireDict *dict)
     {
       const struct variable *v = psppire_dict_get_variable (dict, i);
       int di = var_get_dict_index (v);
-      g_print ("\"%s\" idx=%d, fv=%d, size=%d\n",
+      g_print ("\"%s\" idx=%d, fv=%d\n",
               var_get_name(v),
               di,
-              var_get_case_index(v),
-              value_cnt_from_width(var_get_width(v)));
+              var_get_case_index(v));
 
     }
 }
 #endif
+
+
+
+
+const gchar *
+psppire_dict_encoding (const PsppireDict *dict)
+{
+  return dict_get_encoding (dict->dict);
+}