Revert "psppire-dict: g_return_if_fail for idx in psppire_dict_get_variable()."
[pspp] / src / ui / gui / psppire-dict.c
index 9e2190b2909e181475309ed1c58e10b3ce304872..04bd3e319ce82052c6a857375e0828f0ae6ccc5f 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2004, 2006, 2007, 2009  Free Software Foundation
+   Copyright (C) 2004, 2006, 2007, 2009, 2010, 2011, 2012  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
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
+
+#include "ui/gui/psppire-dict.h"
+
 #include <string.h>
 #include <stdlib.h>
-
 #include <gtk/gtk.h>
-#include <ui/gui/psppire-marshal.h>
-
-#include "psppire-var-ptr.h"
-#include "psppire-dict.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"
 
+#include "data/dictionary.h"
+#include "data/identifier.h"
+#include "data/missing-values.h"
+#include "data/value-labels.h"
+#include "data/variable.h"
+#include "libpspp/i18n.h"
+#include "libpspp/message.h"
+#include "ui/gui/helper.h"
+#include "ui/gui/psppire-marshal.h"
+#include "ui/gui/psppire-var-ptr.h"
+
+#include <gettext.h>
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
 
 enum  {
   BACKEND_CHANGED,
@@ -155,10 +159,10 @@ psppire_dict_class_init (PsppireDictClass *class)
                  G_SIGNAL_RUN_FIRST,
                  0,
                  NULL, NULL,
-                 psppire_marshal_VOID__INT_INT_INT,
+                 psppire_marshal_VOID__POINTER_INT_INT,
                  G_TYPE_NONE,
                  3,
-                 G_TYPE_INT,
+                 G_TYPE_POINTER,
                  G_TYPE_INT,
                  G_TYPE_INT);
 
@@ -244,10 +248,11 @@ addcb (struct dictionary *d, int idx, void *pd)
 }
 
 static void
-delcb (struct dictionary *d, int dict_idx, int case_idx, int width, void *pd)
+delcb (struct dictionary *d, const struct variable *var,
+       int dict_idx, int case_idx, void *pd)
 {
   g_signal_emit (pd, signals [VARIABLE_DELETED], 0,
-                 dict_idx, case_idx, width );
+                 var, dict_idx, case_idx);
 }
 
 static void
@@ -345,34 +350,56 @@ psppire_dict_replace_dictionary (PsppireDict *dict, struct dictionary *d)
 }
 
 
-/* Returns a valid name for a new variable in DICT.
-   The return value is statically allocated */
-static gchar *
-auto_generate_var_name (PsppireDict *dict)
+/* Stores a valid name for a new variable in DICT into the SIZE bytes in NAME.
+   Returns true if successful, false if SIZE is insufficient. */
+bool
+psppire_dict_generate_name (const PsppireDict *dict, char *name, size_t size)
 {
-  gint d = 0;
-  static gchar name[10];
+  gint d;
 
-  while (g_snprintf (name, 10, "VAR%05d",d++),
-        psppire_dict_lookup_var (dict, name))
-    ;
+  for (d = 1; ; d++)
+    {
+      int len;
+
+      /* TRANSLATORS: This string must be a valid variable name.  That means:
+         - The string must be at most 64 bytes (not characters) long.
+         - The string may not contain whitespace.
+         - The first character may not be '$'
+         - The first character may not be a digit
+         - The final charactor may not be '.' or '_'
+      */
+      len = snprintf (name, size, _("Var%04d"), d);
+      if (len + 1 >= size)
+        return false;
+
+      if (psppire_dict_lookup_var (dict, name) == NULL)
+        return true;
+    }
 
   return name;
 }
 
-/* Insert a new variable at posn IDX, with the name NAME.
+/* Insert a new variable at posn IDX, with the name NAME, and return the
+   new variable.
    If NAME is null, then a name will be automatically assigned.
 */
-void
+struct variable *
 psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name)
 {
-  struct variable *var ;
-  g_return_if_fail (idx >= 0);
-  g_return_if_fail (d);
-  g_return_if_fail (PSPPIRE_IS_DICT (d));
+  struct variable *var;
+  char tmpname[64];
 
-  if ( ! name )
-    name = auto_generate_var_name (d);
+  g_return_val_if_fail (idx >= 0, NULL);
+  g_return_val_if_fail (d, NULL);
+  g_return_val_if_fail (PSPPIRE_IS_DICT (d), NULL);
+
+  if (name == NULL)
+    {
+      if (!psppire_dict_generate_name (d, tmpname, sizeof tmpname))
+        g_return_val_if_reached (NULL);
+
+      name = tmpname;
+    }
 
   d->disable_insert_signal = TRUE;
 
@@ -383,6 +410,8 @@ psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name)
   d->disable_insert_signal = FALSE;
 
   g_signal_emit (d, signals[VARIABLE_INSERTED], 0, idx);
+
+  return var;
 }
 
 /* Delete N variables beginning at FIRST */
@@ -415,7 +444,7 @@ psppire_dict_set_name (PsppireDict* d, gint idx, const gchar *name)
   g_assert (d);
   g_assert (PSPPIRE_IS_DICT (d));
 
-  if ( ! var_is_valid_name (name, false))
+  if ( ! dict_id_is_valid (d->dict, name, false))
     return FALSE;
 
   if ( idx < dict_get_var_cnt (d->dict))
@@ -517,13 +546,13 @@ gboolean
 psppire_dict_check_name (const PsppireDict *dict,
                         const gchar *name, gboolean report)
 {
-  if ( ! var_is_valid_name (name, report ) )
+  if ( ! dict_id_is_valid (dict->dict, name, report ) )
     return FALSE;
 
   if (psppire_dict_lookup_var (dict, name))
     {
       if ( report )
-       msg (ME,"Duplicate variable name.");
+       msg (ME, _("Duplicate variable name."));
       return FALSE;
     }
 
@@ -825,7 +854,7 @@ gboolean
 psppire_dict_rename_var (PsppireDict *dict, struct variable *v,
                         const gchar *name)
 {
-  if ( ! var_is_valid_name (name, false))
+  if ( ! dict_id_is_valid (dict->dict, name, false))
     return FALSE;
 
   /* Make sure no other variable has this name */
@@ -857,7 +886,7 @@ 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\n",
+      g_print ("`%s' idx=%d, fv=%d\n",
               var_get_name(v),
               di,
               var_get_case_index(v));