improve deletion of consecutive variables #55357
[pspp] / src / ui / gui / psppire-dict.c
index 0afb889037788e74b577581844d0c5306065bbcf..9c3c38fa5a1f73f67b7f6cab97e2d0b83fdaa5b4 100644 (file)
@@ -107,14 +107,14 @@ gi (GListModel *list, guint id)
        PangoContext *context = gtk_widget_create_pango_context (button);
        PangoLayout *layout = pango_layout_new (context);
        PangoRectangle rect;
-      
+
        pango_layout_set_text (layout, "M", 1);
-      
+
        pango_layout_get_extents (layout, NULL, &rect);
-      
+
        g_object_unref (G_OBJECT (layout));
        g_object_unref (G_OBJECT (context));
-      
+
        gtk_widget_set_size_request (button,
                                     (0.25 + var_get_display_width (v))
                                     * rect.width / PANGO_SCALE,
@@ -288,6 +288,7 @@ psppire_dict_dispose (GObject *object)
   PsppireDict *d = PSPPIRE_DICT (object);
 
   dict_set_callbacks (d->dict, NULL, NULL);
+  dict_unref (d->dict);
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
@@ -367,7 +368,7 @@ PsppireDict*
 psppire_dict_new_from_dict (struct dictionary *d)
 {
   PsppireDict *new_dict = g_object_new (PSPPIRE_TYPE_DICT, NULL);
-  new_dict->dict = d;
+  new_dict->dict = dict_ref (d);
 
   dict_set_callbacks (new_dict->dict, &gui_callbacks, new_dict);
 
@@ -378,12 +379,15 @@ psppire_dict_new_from_dict (struct dictionary *d)
 void
 psppire_dict_replace_dictionary (PsppireDict *dict, struct dictionary *d)
 {
-  struct variable *var =  dict_get_weight (d);
+  const struct variable *var =  dict_get_weight (d);
+
+  struct dictionary *old_dict = dict->dict;
 
   guint old_n = dict_get_var_cnt (dict->dict);
   guint new_n = dict_get_var_cnt (d);
 
-  dict->dict = d;
+  dict->dict = dict_ref (d);
+  dict_unref (old_dict);
 
   weight_changed_callback (d, var ? var_get_dict_index (var) : -1, dict);
 
@@ -429,7 +433,8 @@ psppire_dict_generate_name (const PsppireDict *dict, char *name, size_t size)
 
 /* 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.
+   IDX may take the special value -1, which will be treated the same as
+   zero.   If NAME is null, then a name will be automatically assigned.
 */
 struct variable *
 psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name)
@@ -437,7 +442,8 @@ psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name)
   struct variable *var;
   char tmpname[64];
 
-  g_return_val_if_fail (idx >= 0, NULL);
+  if (idx == -1)    /* Note bug #56392. */
+    idx = 0;
   g_return_val_if_fail (d, NULL);
   g_return_val_if_fail (PSPPIRE_IS_DICT (d), NULL);
 
@@ -471,18 +477,13 @@ psppire_dict_delete_variables (PsppireDict *d, gint first, gint n)
   g_return_if_fail (d);
   g_return_if_fail (d->dict);
   g_return_if_fail (PSPPIRE_IS_DICT (d));
+  size_t varcnt = dict_get_var_cnt (d->dict);
+  g_return_if_fail (first < varcnt);
+  g_return_if_fail (first >= 0);
+  g_return_if_fail (n > 0);
+  g_return_if_fail (first + n <= varcnt);
 
-  for (idx = 0 ; idx < n ; ++idx )
-    {
-      struct variable *var;
-
-      /* Do nothing if it's out of bounds */
-      if ( first >= dict_get_var_cnt (d->dict))
-       break;
-
-      var = dict_get_var (d->dict, first);
-      dict_delete_var (d->dict, var);
-    }
+  dict_delete_consecutive_vars (d->dict, first, n);
 }