Merge branch 'rewrite-sheet' of ssh://jmd@git.sv.gnu.org/srv/git/pspp into rewrite...
authorJohn Darrington <john@darrington.wattle.id.au>
Mon, 24 Nov 2008 13:16:02 +0000 (22:16 +0900)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 24 Nov 2008 13:16:02 +0000 (22:16 +0900)
Conflicts:

lib/gtksheet/gtksheet.c

1  2 
lib/gtksheet/gtksheet.c
lib/gtksheet/psppire-axis.c
lib/gtksheet/psppire-axis.h
src/data/dictionary.c
src/data/dictionary.h
src/data/vardict.h
src/data/variable.c
src/ui/gui/psppire-data-editor.c
src/ui/gui/psppire-dict.c
src/ui/gui/psppire-dict.h
src/ui/gui/psppire-var-sheet.c

index 31f242d28f1283648c517f7d122a2a1bd53a3751,e38b389553d33d694189cb7cd4af56d7dd44157e..8b25902c3b1cc2421c2e5e101b9dbeb77bc7aff8
@@@ -2338,16 -2271,16 +2257,11 @@@ gtk_sheet_range_draw_selection (GtkShee
    gtk_sheet_draw_border (sheet, sheet->range);
  }
  
--static void gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col,
--                              GtkJustification justification,
--                              const gchar *text);
--
--
  static inline gint
  safe_strcmp (const gchar *s1, const gchar *s2)
  {
    if ( !s1 && !s2) return 0;
--  if ( !s1) return - 1;
++  if ( !s1) return -1;
    if ( !s2) return +1;
    return strcmp (s1, s2);
  }
@@@ -2373,6 -2306,6 +2287,9 @@@ gtk_sheet_set_cell (GtkSheet *sheet, gi
  
    old_text = g_sheet_model_get_string (model, row, col);
  
++  if (0 != safe_strcmp (old_text, text))
++    g_sheet_model_set_string (model, text, row, col);
++
    if ( g_sheet_model_free_strings (model))
      g_free (old_text);
  }
@@@ -2625,6 -2558,6 +2542,8 @@@ gtk_sheet_entry_changed (GtkWidget *wid
  
    text = gtk_entry_get_text (GTK_ENTRY (gtk_sheet_get_entry (sheet)));
  
++
++
    if (text && strlen (text) > 0)
      {
        gtk_sheet_get_attributes (sheet, row, col, &attributes);
@@@ -4921,20 -4812,38 +4794,35 @@@ draw_column_title_buttons_range (GtkShe
  
    if (!sheet->column_titles_visible) return;
  
-   if (column < min_visible_column (sheet)) return;
-   if (column > max_visible_column (sheet)) return;
+   g_return_if_fail (first >= min_visible_column (sheet));
+   g_return_if_fail (last <= max_visible_column (sheet));
  
-   button = g_sheet_model_get_column_button (sheet->model, column);
-   allocation.y = 0;
-   allocation.x = psppire_axis_pixel_start (sheet->haxis, column) + CELL_SPACING;
-   allocation.x -= sheet->hadjustment->value;
+   region =
+     gdk_drawable_get_visible_region (GDK_DRAWABLE (sheet->column_title_window));
  
-   allocation.height = sheet->column_title_area.height;
-   allocation.width = psppire_axis_unit_size (sheet->haxis, column);
-   is_sensitive = g_sheet_model_get_column_sensitivity (sheet->model, column);
+   gdk_window_begin_paint_region (sheet->column_title_window, region);
  
-   gtk_sheet_button_draw (sheet, sheet->column_title_window,
-                        button, is_sensitive, allocation);
+   for (col = first ; col <= last ; ++col)
+     {
+       GdkRectangle allocation;
+       gboolean is_sensitive = FALSE;
+       GtkSheetButton *
 -      button = g_sheet_column_get_button (sheet->column_geometry, col);
++      button = g_sheet_model_get_column_button (sheet->model, col);
+       allocation.y = 0;
 -      allocation.x =
 -      g_sheet_column_start_pixel (sheet->column_geometry, col)
++      allocation.x = psppire_axis_pixel_start (sheet->haxis, col)
+       + CELL_SPACING;
+       allocation.x -= sheet->hadjustment->value;
+       allocation.height = sheet->column_title_area.height;
 -      allocation.width =
 -      g_sheet_column_get_width (sheet->column_geometry, col);
 -      is_sensitive =
 -      g_sheet_column_get_sensitivity (sheet->column_geometry, col);
++      allocation.width = psppire_axis_unit_size (sheet->haxis, col);
++      is_sensitive = g_sheet_model_get_column_sensitivity (sheet->model, col);
+       draw_button (sheet, sheet->column_title_window,
+                  button, is_sensitive, allocation);
+     }
+   gdk_window_end_paint (sheet->column_title_window);
  }
  
  
index 2a69fbef07351a6d4ca7d24ed981a2c0a9ab142c,0000000000000000000000000000000000000000..a3609afae6101fa925cb9705513dbd577c8763f4
mode 100644,000000..100644
--- /dev/null
@@@ -1,181 -1,0 +1,204 @@@
-   tower_init (&axis->tower);
 +/* PSPPIRE - a graphical user interface for PSPP.
 +   Copyright (C) 2008  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
 +   the Free Software Foundation, either version 3 of the License, or
 +   (at your option) any later version.
 +
 +   This program is distributed in the hope that it will be useful,
 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +   GNU General Public License for more details.
 +
 +   You should have received a copy of the GNU General Public License
 +   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 +
 +#include <config.h>
 +#include <string.h>
 +#include <stdlib.h>
 +
 +#include <libpspp/tower.h>
++#include <libpspp/pool.h>
 +#include "psppire-axis.h"
 +#include <gtk/gtk.h>
 +
 +
 +/* --- prototypes --- */
 +static void psppire_axis_class_init (PsppireAxisClass *class);
 +static void psppire_axis_init (PsppireAxis            *axis);
 +static void psppire_axis_finalize   (GObject          *object);
 +
 +
 +/* --- variables --- */
 +static GObjectClass     *parent_class = NULL;
 +
 +/* --- functions --- */
 +/**
 + * psppire_axis_get_type:
 + * @returns: the type ID for accelerator groups.
 + */
 +GType
 +psppire_axis_get_type (void)
 +{
 +  static GType object_type = 0;
 +
 +  if (!object_type)
 +    {
 +      static const GTypeInfo object_info = {
 +      sizeof (PsppireAxisClass),
 +      (GBaseInitFunc) NULL,
 +      (GBaseFinalizeFunc) NULL,
 +      (GClassInitFunc) psppire_axis_class_init,
 +      NULL,   /* class_finalize */
 +      NULL,   /* class_data */
 +      sizeof (PsppireAxis),
 +      0,      /* n_preallocs */
 +      (GInstanceInitFunc) psppire_axis_init,
 +      };
 +
 +      object_type = g_type_register_static (G_TYPE_OBJECT,
 +                                          "PsppireAxis",
 +                                          &object_info, 0);
 +    }
 +
 +  return object_type;
 +}
 +
 +
 +static void
 +psppire_axis_class_init (PsppireAxisClass *class)
 +{
 +  GObjectClass *object_class = G_OBJECT_CLASS (class);
 +
 +  parent_class = g_type_class_peek_parent (class);
 +
 +  object_class->finalize = psppire_axis_finalize;
 +}
 +
 +static void
 +psppire_axis_init (PsppireAxis *axis)
 +{
- psppire_axis_new (gint w)
++  axis->pool = NULL;
++  psppire_axis_clear (axis);
 +}
 +
 +
 +static void
 +psppire_axis_finalize (GObject *object)
 +{
++  PsppireAxis *a = PSPPIRE_AXIS (object);
++  pool_destroy (a->pool);
 +  G_OBJECT_CLASS (parent_class)->finalize (object);
 +}
 +
 +/**
 + * psppire_axis_new:
 + * @returns: a new #PsppireAxis object
 + *
 + * Creates a new #PsppireAxis.
 + */
 +PsppireAxis*
-   PsppireAxis *new_axis = g_object_new (G_TYPE_PSPPIRE_AXIS, NULL);
-   new_axis->width = w;
-   return new_axis;
++psppire_axis_new (void)
 +{
-   if ( a->width == -1)
-     {
-       const struct tower_node *node;
-       if  (unit >= tower_count (&a->tower))
-       return 0;
++  return g_object_new (G_TYPE_PSPPIRE_AXIS, NULL);
 +}
 +
 +
 +gint
 +psppire_axis_unit_size (PsppireAxis *a, gint unit)
 +{
-       node = tower_get (&a->tower, unit);
-       return tower_node_get_size (node);
-     }
++  const struct tower_node *node;
++  if  (unit >= tower_count (&a->tower))
++    return 0;
 +
-   return a->width;
++  node = tower_get (&a->tower, unit);
 +
-   if (a->width == -1)
-     return tower_count (&a->tower);
-   return 600;
++  return tower_node_get_size (node);
 +}
 +
 +gint
 +psppire_axis_unit_count (PsppireAxis *a)
 +{
-   if ( a->width == -1 )
-     {
-       const struct tower_node *node;
++  return tower_count (&a->tower);
 +}
 +
 +glong
 +psppire_axis_pixel_start (PsppireAxis *a, gint unit)
 +{
-       if ( unit >= tower_count (&a->tower))
-       return tower_height (&a->tower);
++  const struct tower_node *node;
 +
-       node = tower_get (&a->tower, unit);
-       return  tower_node_get_level (node);
-     }
++  if ( unit >= tower_count (&a->tower))
++    return tower_height (&a->tower);
 +
-   return a->width * unit;
++  node = tower_get (&a->tower, unit);
 +
-   if (a->width == -1)
-     {
-       const struct tower_node *node;
-       unsigned long int node_start;
++  return  tower_node_get_level (node);
 +}
 +
 +gint
 +psppire_axis_get_unit_at_pixel (PsppireAxis *a, glong pixel)
 +{
-       if (pixel >= tower_height (&a->tower))
-       return tower_count (&a->tower);
++  const struct tower_node *node;
++  unsigned long int node_start;
 +
-       node = tower_lookup (&a->tower, pixel, &node_start);
++  if (pixel >= tower_height (&a->tower))
++    return tower_count (&a->tower);
 +
-       return tower_node_get_index (node);
-     }
++  node = tower_lookup (&a->tower, pixel, &node_start);
 +
-   return pixel / a->width;
++  return tower_node_get_index (node);
++}
 +
- psppire_axis_append (PsppireAxis *a, gint width)
++void
++psppire_axis_append (PsppireAxis *a, gint size)
++{
++  struct tower_node *new = pool_malloc (a->pool, sizeof *new);
++
++  tower_insert (&a->tower, size, new, NULL);
 +}
 +
++
++
++/* Insert a new unit of size SIZE before position POSN */
 +void
-   struct tower_node *new = g_slice_alloc0 (sizeof *new);
-   tower_insert (&a->tower, width, new, NULL);
++psppire_axis_insert (PsppireAxis *a, gint size, gint posn)
 +{
++  struct tower_node *new = pool_malloc (a->pool, sizeof *new);
++
++  struct tower_node *before = tower_get (&a->tower, posn);
++
++  tower_insert (&a->tower, size, new, before);
++}
++
++
++void
++psppire_axis_remove (PsppireAxis *a, gint posn)
++{
++  struct tower_node *node = tower_get (&a->tower, posn);
++
++  tower_delete (&a->tower, node);
++
++  pool_free (a->pool, node);
 +}
 +
 +
++void
++psppire_axis_resize_unit (PsppireAxis *a, gint size, gint posn)
++{
++  struct tower_node *node = tower_get (&a->tower, posn);
++
++  tower_resize (&a->tower, node, size);
++}
++
 +
 +
++void
++psppire_axis_clear (PsppireAxis *a)
++{
++  pool_destroy (a->pool);
++  a->pool = pool_create ();
++  tower_init (&a->tower);
++}
++
 +
index 8c362d6e11036b31f784b1d21bda348b209edf03,0000000000000000000000000000000000000000..72484773e895c88767b794887e065609440b46a6
mode 100644,000000..100644
--- /dev/null
@@@ -1,82 -1,0 +1,92 @@@
-   gint width ;
 +/* PSPPIRE - a graphical user interface for PSPP.
 +   Copyright (C) 2008  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
 +   the Free Software Foundation, either version 3 of the License, or
 +   (at your option) any later version.
 +
 +   This program is distributed in the hope that it will be useful,
 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +   GNU General Public License for more details.
 +
 +   You should have received a copy of the GNU General Public License
 +   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 +
 +
 +#ifndef PSPPIRE_AXIS_H__
 +#define PSPPIRE_AXIS_H__
 +
 +
 +#include <glib-object.h>
 +#include <glib.h>
 +
 +#include <libpspp/tower.h>
 +
 +G_BEGIN_DECLS
 +
 +
 +/* --- type macros --- */
 +#define G_TYPE_PSPPIRE_AXIS              (psppire_axis_get_type ())
 +#define PSPPIRE_AXIS(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS, PsppireAxis))
 +#define PSPPIRE_AXIS_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_AXIS, PsppireAxisClass))
 +#define PSPPIRE_IS_AXIS(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_AXIS))
 +#define PSPPIRE_IS_AXIS_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_AXIS))
 +#define PSPPIRE_AXIS_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS, PsppireAxisClass))
 +
 +
 +
 +/* --- typedefs & structures --- */
 +typedef struct _PsppireAxis      PsppireAxis;
 +typedef struct _PsppireAxisClass PsppireAxisClass;
 +
++struct pool;
 +
 +struct _PsppireAxis
 +{
 +  GObject             parent;
- PsppireAxis*   psppire_axis_new (gint w);
 +
 +  struct tower tower;
++  struct pool *pool;
 +};
 +
 +struct _PsppireAxisClass
 +{
 +  GObjectClass parent_class;
 +
 +};
 +
 +GType          psppire_axis_get_type (void);
 +
- void psppire_axis_append (PsppireAxis *a, gint width);
++PsppireAxis*   psppire_axis_new (void);
 +
 +\f
 +/* Interface between sheet and axis */
 +
 +gint psppire_axis_unit_size (PsppireAxis *a, gint unit);
 +
 +gint psppire_axis_unit_count (PsppireAxis *a);
 +
 +glong psppire_axis_pixel_start (PsppireAxis *a, gint unit);
 +
 +gint psppire_axis_get_unit_at_pixel (PsppireAxis *a, glong pixel);
 +
 +
 +
 +/* Interface between axis and model */
 +
++void psppire_axis_clear (PsppireAxis *a);
++
++void psppire_axis_append (PsppireAxis *a, gint size);
++
++void psppire_axis_insert (PsppireAxis *a, gint size, gint posn);
++
++void psppire_axis_remove (PsppireAxis *a, gint posn);
++
++void psppire_axis_resize_unit (PsppireAxis *a, gint size, gint posn);
++
 +
 +G_END_DECLS
 +
 +#endif /* PSPPIRE_AXIS_H__ */
index caf8e2fc3490cc81968197e732b74f45a5aa14f3,caf8e2fc3490cc81968197e732b74f45a5aa14f3..02c6aa76bc5c991a2bc077ed9bc91a3e60972eea
@@@ -1352,3 -1352,3 +1352,21 @@@ dict_var_resized (const struct variabl
        d->callbacks->var_resized (d, var_get_dict_index (v), delta, d->cb_data);
      }
  }
++
++/* Called from variable.c to notify the dictionary that the variable's display width
++   has changed */
++void
++dict_var_display_width_changed (const struct variable *v)
++{
++  if ( var_has_vardict (v))
++    {
++      const struct vardict_info *vdi = var_get_vardict (v);
++      struct dictionary *d;
++
++      d = vdi->dict;
++
++      if ( d->callbacks && d->callbacks->var_display_width_changed )
++      d->callbacks->var_display_width_changed (d, var_get_dict_index (v), d->cb_data);
++    }
++}
++
index bb14f52ebef0fe7560ddab190693f75be8b6457f,bb14f52ebef0fe7560ddab190693f75be8b6457f..682409e24216a11c7492cb39082b30d62f101f19
@@@ -157,6 -157,6 +157,7 @@@ struct dict_callback
    void (*weight_changed) (struct dictionary *, int, void *);
    void (*filter_changed) (struct dictionary *, int, void *);
    void (*split_changed) (struct dictionary *, void *);
++  void (*var_display_width_changed) (struct dictionary *, int, void *);
   };
  
  void dict_set_callbacks (struct dictionary *, const struct dict_callbacks *,
index 35440a0de644af2fbeb3a407d7da837fe97aca1d,35440a0de644af2fbeb3a407d7da837fe97aca1d..dfde1bffc0b3802d553c7717da47b82a4300908b
@@@ -41,5 -41,5 +41,6 @@@ void var_clear_vardict (struct variabl
  /* Called by variable.c, defined in dictionary.c. */
  void dict_var_changed (const struct variable *v);
  void dict_var_resized (const struct variable *v, int delta);
++void dict_var_display_width_changed (const struct variable *v);
  
  #endif /* data/vardict.h */
index d14237d925c3442e4baa8bbf9204a09044f41818,d14237d925c3442e4baa8bbf9204a09044f41818..ccbe65dc0ed9757be75091637bb346b276182d84
@@@ -778,9 -778,9 +778,15 @@@ var_get_display_width (const struct var
  
  /* Sets V's display width to DISPLAY_WIDTH. */
  void
--var_set_display_width (struct variable *v, int display_width)
++var_set_display_width (struct variable *v, int new_width)
  {
--  v->display_width = display_width;
++  int old_width = v->display_width;
++
++  v->display_width = new_width;
++
++  if ( old_width != new_width)
++    dict_var_display_width_changed (v);
++
    dict_var_changed (v);
  }
  
index fe4fcb62a5ed8b81d5035e4326fe02f41a96f44a,072e55bad3dc54e2bffe5e50d589563123faa18c..2e1dee8954aa5a59dd7d3707d19c96fcecd04eb9
@@@ -198,6 -199,6 +198,81 @@@ enu
      PROP_SPLIT_WINDOW
    };
  
++
++#define WIDTH_OF_M 10
++
++static void
++new_variables_callback (PsppireDict *dict, gpointer data)
++{
++  gint v, i;
++  PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
++
++  for (i = 0 ; i < 4 ; ++i)
++    {
++      PsppireAxis *haxis;
++      g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
++
++      psppire_axis_clear (haxis);
++
++      for (v = 0 ; v < psppire_dict_get_var_cnt (dict); ++v)
++      {
++        const struct variable *var = psppire_dict_get_variable (dict, v);
++
++        psppire_axis_append (haxis, 10 * var_get_display_width (var));
++      }
++    }
++}
++
++static void
++insert_variable_callback (PsppireDict *dict, gint x, gpointer data)
++{
++  gint i;
++  PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
++
++  for (i = 0 ; i < 4 ; ++i)
++    {
++      const struct variable *var = psppire_dict_get_variable (dict, x);
++      PsppireAxis *haxis;
++      g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
++
++      psppire_axis_insert (haxis, WIDTH_OF_M * var_get_display_width (var), x);
++    }
++}
++
++
++static void
++delete_variable_callback (PsppireDict *dict, gint posn, gint x UNUSED, gint y UNUSED, gpointer data)
++{
++  gint i;
++  PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
++
++  for (i = 0 ; i < 4 ; ++i)
++    {
++      PsppireAxis *haxis;
++      g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
++
++      psppire_axis_remove (haxis, posn);
++    }
++}
++
++
++static void
++rewidth_variable_callback (PsppireDict *dict, gint posn, gpointer data)
++{
++  gint i;
++  PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
++
++  for (i = 0 ; i < 4 ; ++i)
++    {
++      const struct variable *var = psppire_dict_get_variable (dict, posn);
++      PsppireAxis *haxis;
++      g_object_get (de->data_sheet[i], "horizontal-axis", &haxis, NULL);
++
++      psppire_axis_resize_unit (haxis, WIDTH_OF_M * var_get_display_width (var), posn);
++    }
++}
++
++
  static void
  psppire_data_editor_set_property (GObject         *object,
                                  guint            prop_id,
        for (i = 0 ; i < 4 ; ++i )
        g_object_set (de->data_sheet[i],
                      "row-geometry", de->data_store,
 -                    "column-geometry", de->data_store,
                      "model", de->data_store,
                      NULL);
++
++      g_signal_connect (de->data_store->dict, "backend-changed",   G_CALLBACK (new_variables_callback), de);
++      g_signal_connect (de->data_store->dict, "variable-inserted", G_CALLBACK (insert_variable_callback), de);
++      g_signal_connect (de->data_store->dict, "variable-deleted",  G_CALLBACK (delete_variable_callback), de);
++      //      g_signal_connect (de->data_store->dict, "variable-changed",  G_CALLBACK (alter_variable_callback), de);
++      g_signal_connect (de->data_store->dict, "variable-display-width-changed",  G_CALLBACK (rewidth_variable_callback), de);
        break;
      case PROP_VAR_STORE:
        if ( de->var_store) g_object_unref (de->var_store);
@@@ -611,7 -613,6 +692,7 @@@ static voi
  init_sheet (PsppireDataEditor *de, int i,
            GtkAdjustment *hadj, GtkAdjustment *vadj)
  {
-   PsppireAxis *haxis = psppire_axis_new (100);
++  PsppireAxis *haxis = psppire_axis_new ();
    de->sheet_bin[i] = gtk_scrolled_window_new (hadj, vadj);
  
    de->data_sheet[i] = gtk_sheet_new (NULL, NULL, NULL);
@@@ -789,16 -786,16 +870,10 @@@ GtkWidget
  psppire_data_editor_new (PsppireVarStore *var_store,
                         PsppireDataStore *data_store)
  {
--  GtkWidget *widget;
--
--  widget =  g_object_new (PSPPIRE_DATA_EDITOR_TYPE,
--                        "var-store",  var_store,
--                        "data-store",  data_store,
--                        NULL);
--
--
--
--  return widget;
++  return  g_object_new (PSPPIRE_DATA_EDITOR_TYPE,
++                                   "var-store",  var_store,
++                                   "data-store",  data_store,
++                                   NULL);
  }
  
  
index e6f1373a54d969ed76de022e0135924ace674c8c,e6f1373a54d969ed76de022e0135924ace674c8c..8f7fed618fcedbfd8e8d4463eca07dff111ee2c5
  #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,
@@@ -48,6 -48,6 +38,7 @@@
    VARIABLE_RESIZED,
    VARIABLE_INSERTED,
    VARIABLE_DELETED,
++  VARIABLE_DISPLAY_WIDTH_CHANGED,
  
    WEIGHT_CHANGED,
    FILTER_CHANGED,
    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 --- */
@@@ -93,8 -93,8 +96,6 @@@ psppire_dict_get_type (void
  
        g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL,
                                   &tree_model_info);
--
--
      }
  
    return object_type;
@@@ -172,6 -172,6 +173,17 @@@ psppire_dict_class_init (PsppireDictCla
                  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",
@@@ -223,7 -223,7 +235,10 @@@ 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
@@@ -264,6 -264,6 +279,13 @@@ split_changed_callback (struct dictiona
    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 =
    {
      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;
  }
  
  /**
@@@ -349,9 -349,9 +373,15 @@@ psppire_dict_insert_variable (PsppireDi
    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 */
index 1bf8bd3523b849aac1c2918f2794895c088714af,1bf8bd3523b849aac1c2918f2794895c088714af..534f0707ea22df8bc6084a1d8193c917d4ae0e0a
@@@ -38,7 -38,7 +38,6 @@@ G_BEGIN_DECL
  #define PSPPIRE_DICT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_DICT, PsppireDictClass))
  
  
--
  /* --- typedefs & structures --- */
  typedef struct _PsppireDict      PsppireDict;
  typedef struct _PsppireDictClass PsppireDictClass;
@@@ -50,6 -50,6 +49,7 @@@ struct _PsppireDic
    GObject             parent;
    struct dictionary *dict;
  
++  gboolean disable_insert_signal;
    /* For GtkTreeModelIface */
    gint stamp;
  };
index 5406949108968a467a6b1686b73d93eda5f07dc3,0708bf3e047f8c416ce0d2cc6500a7ad75282520..033652025a870812214b84dcf630702cb04942a2
@@@ -533,16 -538,5 +533,16 @@@ static const struct column_parameters c
  GtkWidget*
  psppire_var_sheet_new (void)
  {
 -  return GTK_WIDGET (g_object_new (psppire_var_sheet_get_type (), NULL));
 +  gint i;
-   PsppireAxis *a = psppire_axis_new (-1);
++  PsppireAxis *a = psppire_axis_new ();
 +  GtkWidget *w = g_object_new (psppire_var_sheet_get_type (), NULL);
 +
 +  for (i = 0 ; i < 10 ; ++i)
 +    psppire_axis_append (a, column_def[i].width);
 +
 +  g_object_set (w,
 +              "horizontal-axis", a,
 +              NULL);
 +
 +  return w;
  }