Merge 'master' into 'psppsheet'.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 19 Aug 2012 20:16:05 +0000 (13:16 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 19 Aug 2012 20:16:05 +0000 (13:16 -0700)
1  2 
src/ui/gui/aggregate-dialog.c
src/ui/gui/automake.mk
src/ui/gui/psppire-var-sheet.c
src/ui/gui/psppire-var-sheet.h
src/ui/gui/text-data-import-dialog.c
src/ui/gui/val-labs-dialog.h
src/ui/gui/var-type-dialog.h

Simple merge
index 14beeb9a1ee85c2ecf47294f845bf9bed673c23d,405671095fe0693d91833c866916711ecd6466fb..87795d8dd388d1211fd2de416a49b1521500f933
@@@ -42,7 -44,7 +43,8 @@@ UI_FILES = 
        src/ui/gui/data-editor.ui \
        src/ui/gui/output-viewer.ui \
        src/ui/gui/syntax-editor.ui \
-       src/ui/gui/var-sheet.ui
++      src/ui/gui/var-sheet.ui \
+       src/ui/gui/var-type-dialog.ui
  
  EXTRA_DIST += \
        src/ui/gui/OChangeLog \
index 03d43dd9c2549ac1d1d9b4015103e1fbad1a4f20,b02a0a03ec613b4b272b9d323bfb170be440f192..dfd5ce1c4c7732ad1f102309da2de65313599368
     along with this program.  If not, see <http://www.gnu.org/licenses/>. */
  
  #include <config.h>
 -#include "psppire-var-sheet.h"
 -#include <ui/gui/sheet/psppire-axis.h>
  
 -#include "builder-wrapper.h"
 -#include "helper.h"
 +#include "ui/gui/psppire-var-sheet.h"
  
 -#include "customentry.h"
 -#include <data/variable.h>
 +#include "data/format.h"
  #include "data/value-labels.h"
 -#include "psppire-var-store.h"
 +#include "libpspp/range-set.h"
 +#include "ui/gui/builder-wrapper.h"
 +#include "ui/gui/helper.h"
 +#include "ui/gui/missing-val-dialog.h"
 +#include "ui/gui/pspp-sheet-selection.h"
 +#include "ui/gui/psppire-cell-renderer-button.h"
 +#include "ui/gui/psppire-data-editor.h"
 +#include "ui/gui/psppire-data-window.h"
 +#include "ui/gui/psppire-dialog-action-var-info.h"
 +#include "ui/gui/psppire-empty-list-store.h"
 +#include "ui/gui/psppire-marshal.h"
  #include "ui/gui/val-labs-dialog.h"
+ #include "ui/gui/var-type-dialog.h"
 +#include "ui/gui/var-display.h"
 +#include "ui/gui/var-type-dialog.h"
 +
 +#include "gl/intprops.h"
  
  #include <gettext.h>
  #define _(msgid) gettext (msgid)
@@@ -445,255 -287,95 +446,281 @@@ path_string_to_variable (PsppireVarShee
  }
  
  static void
 -var_sheet_show_var_type_dialog (PsppireVarSheet *vs)
 +on_type_click (PsppireCellRendererButton *cell,
 +               gchar *path,
 +               PsppireVarSheet *var_sheet)
  {
-   var_sheet->var_type_dialog->pv = path_string_to_variable (var_sheet, path);
-   var_type_dialog_show (var_sheet->var_type_dialog);
 -  PsppireVarStore *var_store;
++  GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (var_sheet));
+   struct fmt_spec format;
+   struct variable *var;
 -  gint row;
 -  var_store = PSPPIRE_VAR_STORE (psppire_sheet_get_model (PSPPIRE_SHEET (vs)));
 -
 -  psppire_sheet_get_active_cell (PSPPIRE_SHEET (vs), &row, NULL);
 -  var = psppire_var_store_get_var (var_store, row);
++  var = path_string_to_variable (var_sheet, path);
+   g_return_if_fail (var != NULL);
+   format = *var_get_print_format (var);
 -  psppire_var_type_dialog_run (GTK_WINDOW (gtk_widget_get_toplevel (
 -                                             GTK_WIDGET (vs))), &format);
++  psppire_var_type_dialog_run (GTK_WINDOW (toplevel), &format);
+   var_set_width (var, fmt_var_width (&format));
+   var_set_both_formats (var, &format);
  }
  
  static void
 -var_sheet_show_val_labs_dialog (PsppireVarSheet *vs)
 +on_value_labels_click (PsppireCellRendererButton *cell,
 +                       gchar *path,
 +                       PsppireVarSheet *var_sheet)
  {
-   struct variable *var = path_string_to_variable (var_sheet, path);
-   val_labs_dialog_set_target_variable (var_sheet->val_labs_dialog, var);
-   val_labs_dialog_show (var_sheet->val_labs_dialog);
 -  PsppireVarStore *var_store;
++  GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (var_sheet));
+   struct val_labs *labels;
+   struct variable *var;
 -  gint row;
 -
 -  var_store = PSPPIRE_VAR_STORE (psppire_sheet_get_model (PSPPIRE_SHEET (vs)));
 -  psppire_sheet_get_active_cell (PSPPIRE_SHEET (vs), &row, NULL);
 -  var = psppire_var_store_get_var (var_store, row);
++  var = path_string_to_variable (var_sheet, path);
+   g_return_if_fail (var != NULL);
 -  labels = psppire_val_labs_dialog_run (GTK_WINDOW (gtk_widget_get_toplevel (
 -                                                      GTK_WIDGET (vs))), var);
++  labels = psppire_val_labs_dialog_run (GTK_WINDOW (toplevel), var);
+   if (labels)
+     {
+       var_set_value_labels (var, labels);
+       val_labs_destroy (labels);
+     }
  }
  
  static void
 -var_sheet_show_miss_vals_dialog (PsppireVarSheet *vs)
 +on_missing_values_click (PsppireCellRendererButton *cell,
 +                         gchar *path,
 +                         PsppireVarSheet *var_sheet)
  {
-   var_sheet->missing_val_dialog->pv = path_string_to_variable (var_sheet,
-                                                                path);
-   missing_val_dialog_show (var_sheet->missing_val_dialog);
 -  PsppireVarStore *var_store;
++  GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (var_sheet));
+   struct missing_values mv;
+   struct variable *var;
 -  gint row;
 -
 -  var_store = PSPPIRE_VAR_STORE (psppire_sheet_get_model (PSPPIRE_SHEET (vs)));
 -  psppire_sheet_get_active_cell (PSPPIRE_SHEET (vs), &row, NULL);
 -  var = psppire_var_store_get_var (var_store, row);
++  var = path_string_to_variable (var_sheet, path);
+   g_return_if_fail (var != NULL);
 -  psppire_missing_val_dialog_run (GTK_WINDOW (gtk_widget_get_toplevel (
 -                                                GTK_WIDGET (vs))), var, &mv);
++  psppire_missing_val_dialog_run (GTK_WINDOW (toplevel), var, &mv);
+   var_set_missing_values (var, &mv);
+   mv_destroy (&mv);
  }
  
 -/*
 -   Callback whenever the active cell changes on the var sheet.
 -*/
 +static gint
 +get_string_width (PsppSheetView *treeview, GtkCellRenderer *renderer,
 +                  const char *string)
 +{
 +  gint width;
 +  g_object_set (G_OBJECT (renderer),
 +                PSPPIRE_IS_CELL_RENDERER_BUTTON (renderer) ? "label" : "text",
 +                string, (void *) NULL);
 +  gtk_cell_renderer_get_size (renderer, GTK_WIDGET (treeview),
 +                              NULL, NULL, NULL, &width, NULL);
 +  return width;
 +}
 +
 +static gint
 +get_monospace_width (PsppSheetView *treeview, GtkCellRenderer *renderer,
 +                     size_t char_cnt)
 +{
 +  struct string s;
 +  gint width;
 +
 +  ds_init_empty (&s);
 +  ds_put_byte_multiple (&s, '0', char_cnt);
 +  ds_put_byte (&s, ' ');
 +  width = get_string_width (treeview, renderer, ds_cstr (&s));
 +  ds_destroy (&s);
 +
 +  return width;
 +}
 +
 +static PsppSheetViewColumn *
 +add_var_sheet_column (PsppireVarSheet *var_sheet, GtkCellRenderer *renderer,
 +                      enum vs_column column_id,
 +                      const char *title, int width)
 +{
 +  PsppSheetView *sheet_view = PSPP_SHEET_VIEW (var_sheet);
 +  int title_width, content_width;
 +  PsppSheetViewColumn *column;
 +
 +  column = pspp_sheet_view_column_new_with_attributes (title, renderer, NULL);
 +  g_object_set_data (G_OBJECT (column), "column-number",
 +                     GINT_TO_POINTER (column_id) + 1);
 +
 +  pspp_sheet_view_column_set_cell_data_func (
 +    column, renderer, render_var_cell, var_sheet, NULL);
 +
 +  title_width = get_string_width (sheet_view, renderer, title);
 +  content_width = get_monospace_width (sheet_view, renderer, width);
 +  g_object_set_data (G_OBJECT (column), "content-width",
 +                     GINT_TO_POINTER (content_width));
 +
 +  pspp_sheet_view_column_set_fixed_width (column,
 +                                          MAX (title_width, content_width));
 +  pspp_sheet_view_column_set_resizable (column, TRUE);
 +
 +  pspp_sheet_view_append_column (sheet_view, column);
 +
 +  g_signal_connect (renderer, "edited",
 +                    G_CALLBACK (on_var_column_edited),
 +                    var_sheet);
 +  g_object_set_data (G_OBJECT (renderer), "column-id",
 +                     GINT_TO_POINTER (column_id));
 +  g_object_set_data (G_OBJECT (renderer), "var-sheet", var_sheet);
 +
 +  return column;
 +}
 +
 +static PsppSheetViewColumn *
 +add_text_column (PsppireVarSheet *var_sheet, enum vs_column column_id,
 +                 const char *title, int width)
 +{
 +  return add_var_sheet_column (var_sheet, gtk_cell_renderer_text_new (),
 +                               column_id, title, width);
 +}
 +
 +static PsppSheetViewColumn *
 +add_spin_column (PsppireVarSheet *var_sheet, enum vs_column column_id,
 +                 const char *title, int width)
 +{
 +  return add_var_sheet_column (var_sheet, gtk_cell_renderer_spin_new (),
 +                               column_id, title, width);
 +}
 +
 +static PsppSheetViewColumn *
 +add_combo_column (PsppireVarSheet *var_sheet, enum vs_column column_id,
 +                  const char *title, int width,
 +                  ...)
 +{
 +  GtkCellRenderer *cell;
 +  GtkListStore *store;
 +  const char *name;
 +  va_list args;
 +
 +  store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
 +  va_start (args, width);
 +  while ((name = va_arg (args, const char *)) != NULL)
 +    {
 +      int value = va_arg (args, int);
 +      gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
 +                                         0, value,
 +                                         1, name,
 +                                         -1);
 +    }
 +  va_end (args);
 +
 +  cell = gtk_cell_renderer_combo_new ();
 +  g_object_set (cell,
 +                "has-entry", FALSE,
 +                "model", GTK_TREE_MODEL (store),
 +                "text-column", 1,
 +                NULL);
 +
 +  return add_var_sheet_column (var_sheet, cell, column_id, title, width);
 +
 +}
 +
  static void
 -var_sheet_change_active_cell (PsppireVarSheet *vs,
 -                            gint row, gint column,
 -                            gint oldrow, gint oldcolumn,
 -                            gpointer data)
 +add_popup_menu (PsppireVarSheet *var_sheet,
 +                PsppSheetViewColumn *column,
 +                void (*on_click) (PsppireCellRendererButton *,
 +                                  gchar *path,
 +                                  PsppireVarSheet *var_sheet))
  {
 -  PsppireVarStore *var_store;
 -  PsppireVarSheetClass *vs_class =
 -    PSPPIRE_VAR_SHEET_CLASS(G_OBJECT_GET_CLASS (vs));
 +  PsppSheetView *sheet_view = PSPP_SHEET_VIEW (var_sheet);
 +  const char *button_label = "...";
 +  GtkCellRenderer *button_renderer;
 +  gint content_width;
 +
 +  button_renderer = psppire_cell_renderer_button_new ();
 +  g_object_set (button_renderer,
 +                "label", button_label,
 +                "editable", TRUE,
 +                NULL);
 +  g_signal_connect (button_renderer, "clicked", G_CALLBACK (on_click),
 +                    var_sheet);
 +  pspp_sheet_view_column_pack_start (column, button_renderer, FALSE);
 +  pspp_sheet_view_column_set_cell_data_func (
 +    column, button_renderer, render_popup_cell, var_sheet, NULL);
 +
 +  content_width = GPOINTER_TO_INT (g_object_get_data (
 +                                     G_OBJECT (column), "content-width"));
 +  content_width += get_string_width (sheet_view, button_renderer,
 +                                     button_label);
 +  if (content_width > pspp_sheet_view_column_get_fixed_width (column))
 +    pspp_sheet_view_column_set_fixed_width (column, content_width);
 +}
  
 -  struct variable *var ;
 -  PsppireSheet *sheet = PSPPIRE_SHEET (vs);
 +static gboolean
 +get_tooltip_location (GtkWidget *widget, GtkTooltip *tooltip,
 +                      gint wx, gint wy, size_t *row, size_t *column)
 +{
 +  PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget);
 +  gint bx, by;
 +  GtkTreePath *path;
 +  GtkTreeIter iter;
 +  PsppSheetViewColumn *tree_column;
 +  GtkTreeModel *tree_model;
 +  gpointer column_ptr;
 +  bool ok;
 +
 +  /* Check that WIDGET is really visible on the screen before we
 +     do anything else.  This is a bug fix for a sticky situation:
 +     when text_data_import_assistant() returns, it frees the data
 +     necessary to compose the tool tip message, but there may be
 +     a tool tip under preparation at that point (even if there is
 +     no visible tool tip) that will call back into us a little
 +     bit later.  Perhaps the correct solution to this problem is
 +     to make the data related to the tool tips part of a GObject
 +     that only gets destroyed when all references are released,
 +     but this solution appears to be effective too. */
 +  if (!gtk_widget_get_mapped (widget))
 +    return FALSE;
 +
 +  pspp_sheet_view_convert_widget_to_bin_window_coords (tree_view,
 +                                                     wx, wy, &bx, &by);
 +  if (!pspp_sheet_view_get_path_at_pos (tree_view, bx, by,
 +                                      &path, &tree_column, NULL, NULL))
 +    return FALSE;
 +
 +  column_ptr = g_object_get_data (G_OBJECT (tree_column), "column-number");
 +  if (column_ptr == NULL)
 +    return FALSE;
 +  *column = GPOINTER_TO_INT (column_ptr) - 1;
 +
 +  pspp_sheet_view_set_tooltip_cell (tree_view, tooltip, path, tree_column,
 +                                    NULL);
 +
 +  tree_model = pspp_sheet_view_get_model (tree_view);
 +  ok = gtk_tree_model_get_iter (tree_model, &iter, path);
 +  gtk_tree_path_free (path);
 +  if (!ok)
 +    return FALSE;
 +
 +  *row = GPOINTER_TO_INT (iter.user_data);
 +  return TRUE;
 +}
  
 -  g_return_if_fail (sheet != NULL);
 +static gboolean
 +on_query_var_tooltip (GtkWidget *widget, gint wx, gint wy,
 +                      gboolean keyboard_mode UNUSED,
 +                      GtkTooltip *tooltip, gpointer *user_data UNUSED)
 +{
 +  PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (widget);
 +  PsppireDict *dict;
 +  struct variable *var;
 +  size_t row, column;
  
 -  var_store = PSPPIRE_VAR_STORE (psppire_sheet_get_model (sheet));
 +  if (!get_tooltip_location (widget, tooltip, wx, wy, &row, &column))
 +    return FALSE;
  
 -  g_assert (var_store);
 +  dict = psppire_var_sheet_get_dictionary (var_sheet);
 +  g_return_val_if_fail (dict != NULL, FALSE);
  
 -  g_return_if_fail (oldcolumn == PSPPIRE_VAR_STORE_COL_NAME ||
 -                  row < psppire_var_store_get_var_cnt (var_store));
 +  if (row >= psppire_dict_get_var_cnt (dict))
 +    {
 +      gtk_tooltip_set_text (tooltip, _("Enter a variable name to add a "
 +                                       "new variable."));
 +      return TRUE;
 +    }
  
 -  var = psppire_var_store_get_var (var_store, row);
 +  var = psppire_dict_get_variable (dict, row);
 +  g_return_val_if_fail (var != NULL, FALSE);
  
    switch (column)
      {
@@@ -895,560 -525,64 +922,543 @@@ psppire_var_sheet_get_property (GObjec
      }
  }
  
- static void
- psppire_var_sheet_realize (GtkWidget *w)
- {
-   PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (w);
-   GtkWindow *toplevel;
-   GTK_WIDGET_CLASS (psppire_var_sheet_parent_class)->realize (w);
-   toplevel = GTK_WINDOW (gtk_widget_get_toplevel (w));
-   var_sheet->val_labs_dialog = val_labs_dialog_create (toplevel);
-   var_sheet->missing_val_dialog = missing_val_dialog_create (toplevel);
-   var_sheet->var_type_dialog = var_type_dialog_create (toplevel);
- }
 +static void
 +psppire_var_sheet_dispose (GObject *obj)
 +{
 +  PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (obj);
 +  int i;
 +
 +  if (var_sheet->dispose_has_run)
 +    return;
 +
 +  var_sheet->dispose_has_run = TRUE;
 +
 +  for (i = 0; i < PSPPIRE_VAR_SHEET_N_SIGNALS; i++)
 +    if ( var_sheet->dict_signals[i])
 +      g_signal_handler_disconnect (var_sheet->dict,
 +                                 var_sheet->dict_signals[i]);
 +
 +  if (var_sheet->dict)
 +    g_object_unref (var_sheet->dict);
 +  
 +  if (var_sheet->uim)
 +    g_object_unref (var_sheet->uim);
 +
 +  /* These dialogs are not GObjects (although they should be!)
 +    But for now, unreffing them only causes a GCritical Error
 +    so comment them out for now. (and accept the memory leakage)
 +
 +  g_object_unref (var_sheet->val_labs_dialog);
 +  g_object_unref (var_sheet->missing_val_dialog);
 +  g_object_unref (var_sheet->var_type_dialog);
 +  */
 +
 +  G_OBJECT_CLASS (psppire_var_sheet_parent_class)->dispose (obj);
 +}
  
  static void
 -psppire_var_sheet_init (PsppireVarSheet *vs)
 +psppire_var_sheet_class_init (PsppireVarSheetClass *class)
  {
 -  GtkBuilder *builder = builder_new ("data-editor.ui");
 +  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
 +  GParamSpec *pspec;
  
 -  connect_help (builder);
 +  gobject_class->set_property = psppire_var_sheet_set_property;
 +  gobject_class->get_property = psppire_var_sheet_get_property;
 +  gobject_class->dispose = psppire_var_sheet_dispose;
 +
-   widget_class->realize = psppire_var_sheet_realize;
 +  g_signal_new ("var-double-clicked",
 +                G_OBJECT_CLASS_TYPE (gobject_class),
 +                G_SIGNAL_RUN_LAST,
 +                0,
 +                g_signal_accumulator_true_handled, NULL,
 +                psppire_marshal_BOOLEAN__INT,
 +                G_TYPE_BOOLEAN, 1, G_TYPE_INT);
 +
 +  pspec = g_param_spec_object ("dictionary",
 +                               "Dictionary displayed by the sheet",
 +                               "The PsppireDict that the sheet displays "
 +                               "may allow the user to edit",
 +                               PSPPIRE_TYPE_DICT,
 +                               G_PARAM_READWRITE);
 +  g_object_class_install_property (gobject_class, PROP_DICTIONARY, pspec);
  
 -  g_object_unref (builder);
 +  pspec = g_param_spec_boolean ("may-create-vars",
 +                                "May create variables",
 +                                "Whether the user may create more variables",
 +                                TRUE,
 +                                G_PARAM_READWRITE);
 +  g_object_class_install_property (gobject_class, PROP_MAY_CREATE_VARS, pspec);
  
 -  vs->dispose_has_run = FALSE;
 -  vs->may_create_vars = TRUE;
 +  pspec = g_param_spec_boolean ("may-delete-vars",
 +                                "May delete variables",
 +                                "Whether the user may delete variables",
 +                                TRUE,
 +                                G_PARAM_READWRITE);
 +  g_object_class_install_property (gobject_class, PROP_MAY_DELETE_VARS, pspec);
 +
 +  pspec = g_param_spec_enum ("format-use",
 +                             "Use of variable format",
 +                             ("Whether variables have input or output "
 +                              "formats"),
 +                             PSPPIRE_TYPE_FMT_USE,
 +                             FMT_FOR_OUTPUT,
 +                             G_PARAM_READWRITE);
 +  g_object_class_install_property (gobject_class, PROP_FORMAT_TYPE, pspec);
 +
 +  pspec = g_param_spec_object ("ui-manager",
 +                               "UI Manager",
 +                               "UI manager for the variable sheet.  The client should merge this UI manager with the active UI manager to obtain variable sheet specific menu items and tool bar items.",
 +                               GTK_TYPE_UI_MANAGER,
 +                               G_PARAM_READABLE);
 +  g_object_class_install_property (gobject_class, PROP_UI_MANAGER, pspec);
 +}
  
 -  g_signal_connect (vs, "activate",
 -                  G_CALLBACK (var_sheet_change_active_cell),
 -                  NULL);
 +static void
 +render_row_number_cell (PsppSheetViewColumn *tree_column,
 +                        GtkCellRenderer *cell,
 +                        GtkTreeModel *model,
 +                        GtkTreeIter *iter,
 +                        gpointer user_data)
 +{
 +  PsppireVarSheet *var_sheet = user_data;
 +  GValue gvalue = { 0, };
 +  gint row;
 +
 +  row = GPOINTER_TO_INT (iter->user_data);
 +
 +  g_value_init (&gvalue, G_TYPE_INT);
 +  g_value_set_int (&gvalue, row + 1);
 +  g_object_set_property (G_OBJECT (cell), "label", &gvalue);
 +  g_value_unset (&gvalue);
 +
 +  if (!var_sheet->dict || row < psppire_dict_get_var_cnt (var_sheet->dict))
 +    g_object_set (cell, "editable", TRUE, NULL);
 +  else
 +    g_object_set (cell, "editable", FALSE, NULL);
 +}
 +
 +static void
 +psppire_var_sheet_row_number_double_clicked (PsppireCellRendererButton *button,
 +                                             gchar *path_string,
 +                                             PsppireVarSheet *var_sheet)
 +{
 +  GtkTreePath *path;
 +
 +  g_return_if_fail (var_sheet->dict != NULL);
 +
 +  path = gtk_tree_path_new_from_string (path_string);
 +  if (gtk_tree_path_get_depth (path) == 1)
 +    {
 +      gint *indices = gtk_tree_path_get_indices (path);
 +      if (indices[0] < psppire_dict_get_var_cnt (var_sheet->dict))
 +        {
 +          gboolean handled;
 +          g_signal_emit_by_name (var_sheet, "var-double-clicked",
 +                                 indices[0], &handled);
 +        }
 +    }
 +  gtk_tree_path_free (path);
 +}
 +
 +static PsppSheetViewColumn *
 +make_row_number_column (PsppireVarSheet *var_sheet)
 +{
 +  PsppSheetViewColumn *column;
 +  GtkCellRenderer *renderer;
 +
 +  renderer = psppire_cell_renderer_button_new ();
 +  g_object_set (renderer, "xalign", 1.0, NULL);
 +  g_signal_connect (renderer, "double-clicked",
 +                    G_CALLBACK (psppire_var_sheet_row_number_double_clicked),
 +                    var_sheet);
 +
 +  column = pspp_sheet_view_column_new_with_attributes (_("Variable"),
 +                                                       renderer, NULL);
 +  pspp_sheet_view_column_set_cell_data_func (
 +    column, renderer, render_row_number_cell, var_sheet, NULL);
 +  pspp_sheet_view_column_set_fixed_width (column, 50);
 +  return column;
 +}
 +
 +static void
 +on_edit_clear_variables (GtkAction *action, PsppireVarSheet *var_sheet)
 +{
 +  PsppSheetView *sheet_view = PSPP_SHEET_VIEW (var_sheet);
 +  PsppSheetSelection *selection = pspp_sheet_view_get_selection (sheet_view);
 +  PsppireDict *dict = var_sheet->dict;
 +  const struct range_set_node *node;
 +  struct range_set *selected;
 +
 +  selected = pspp_sheet_selection_get_range_set (selection);
 +  for (node = range_set_last (selected); node != NULL;
 +       node = range_set_prev (selected, node))
 +    {
 +      int i;
 +
 +      for (i = 1; i <= range_set_node_get_width (node); i++)
 +        {
 +          unsigned long row = range_set_node_get_end (node) - i;
 +          if (row >= 0 && row < psppire_dict_get_var_cnt (dict))
 +            psppire_dict_delete_variables (dict, row, 1);
 +        }
 +    }
 +  range_set_destroy (selected);
 +}
 +
 +static void
 +on_selection_changed (PsppSheetSelection *selection,
 +                      gpointer user_data UNUSED)
 +{
 +  PsppSheetView *sheet_view = pspp_sheet_selection_get_tree_view (selection);
 +  PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (sheet_view);
 +  gint n_selected_rows;
 +  gboolean may_delete;
 +  GtkTreePath *path;
 +  GtkAction *action;
 +
 +  n_selected_rows = pspp_sheet_selection_count_selected_rows (selection);
 +
 +  action = get_action_assert (var_sheet->builder, "edit_insert-variable");
 +  gtk_action_set_sensitive (action, (var_sheet->may_create_vars
 +                                     && n_selected_rows > 0));
 +
 +  switch (n_selected_rows)
 +    {
 +    case 0:
 +      may_delete = FALSE;
 +      break;
 +
 +    case 1:
 +      /* The row used for inserting new variables cannot be deleted. */
 +      path = gtk_tree_path_new_from_indices (
 +        psppire_dict_get_var_cnt (var_sheet->dict), -1);
 +      may_delete = !pspp_sheet_selection_path_is_selected (selection, path);
 +      gtk_tree_path_free (path);
 +      break;
  
 -  g_signal_connect (vs, "traverse",
 -                  G_CALLBACK (traverse_cell_callback), NULL);
 +    default:
 +      may_delete = TRUE;
 +      break;
 +    }
 +  action = get_action_assert (var_sheet->builder, "edit_clear-variables");
 +  gtk_action_set_sensitive (action, var_sheet->may_delete_vars && may_delete);
  }
  
 +static void
 +on_edit_insert_variable (GtkAction *action, PsppireVarSheet *var_sheet)
 +{
 +  PsppSheetView *sheet_view = PSPP_SHEET_VIEW (var_sheet);
 +  PsppSheetSelection *selection = pspp_sheet_view_get_selection (sheet_view);
 +  PsppireDict *dict = var_sheet->dict;
 +  struct range_set *selected;
 +  unsigned long row;
 +
 +  selected = pspp_sheet_selection_get_range_set (selection);
 +  row = range_set_scan (selected, 0);
 +  range_set_destroy (selected);
 +
 +  if (row <= psppire_dict_get_var_cnt (dict))
 +    {
 +      gchar name[64];;
 +      if (psppire_dict_generate_name (dict, name, sizeof name))
 +        psppire_dict_insert_variable (dict, row, name);
 +    }
 +}
 +
 +static void
 +psppire_var_sheet_init (PsppireVarSheet *obj)
 +{
 +  PsppSheetView *sheet_view = PSPP_SHEET_VIEW (obj);
 +  PsppSheetViewColumn *column;
 +  GtkAction *action;
 +  GList *list;
 +
 +  obj->dict = NULL;
 +  obj->format_use = FMT_FOR_OUTPUT;
 +  obj->may_create_vars = TRUE;
 +  obj->may_delete_vars = TRUE;
  
 -static const struct column_parameters column_def[] = {
 -  { N_("Name"),    80},
 -  { N_("Type"),    100},
 -  { N_("Width"),   57},
 -  { N_("Decimals"),91},
 -  { N_("Label"),   95},
 -  { N_("Values"),  103},
 -  { N_("Missing"), 95},
 -  { N_("Columns"), 80},
 -  { N_("Align"),   69},
 -  { N_("Measure"), 99},
 -};
 +  obj->scroll_to_bottom_signal = 0;
  
 -GtkWidget*
 +  obj->container = NULL;
 +  obj->dispose_has_run = FALSE;
 +  obj->uim = NULL;
 +
 +  pspp_sheet_view_append_column (sheet_view, make_row_number_column (obj));
 +
 +  column = add_text_column (obj, VS_NAME, _("Name"), 12);
 +  list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
 +  g_signal_connect (list->data, "editing-started",
 +                    G_CALLBACK (on_name_column_editing_started), NULL);
 +  g_list_free (list);
 +
 +  column = add_text_column (obj, VS_TYPE, _("Type"), 8);
 +  add_popup_menu (obj, column, on_type_click);
 +
 +  add_spin_column (obj, VS_WIDTH, _("Width"), 5);
 +
 +  add_spin_column (obj, VS_DECIMALS, _("Decimals"), 2);
 +
 +  add_text_column (obj, VS_LABEL, _("Label"), 20);
 +
 +  column = add_text_column (obj, VS_VALUES, _("Value Labels"), 20);
 +  add_popup_menu (obj, column, on_value_labels_click);
 +
 +  column = add_text_column (obj, VS_MISSING, _("Missing Values"), 20);
 +  add_popup_menu (obj, column, on_missing_values_click);
 +
 +  add_spin_column (obj, VS_COLUMNS, _("Columns"), 3);
 +
 +  add_combo_column (obj, VS_ALIGN, _("Align"), 6,
 +                    alignment_to_string (ALIGN_LEFT), ALIGN_LEFT,
 +                    alignment_to_string (ALIGN_CENTRE), ALIGN_CENTRE,
 +                    alignment_to_string (ALIGN_RIGHT), ALIGN_RIGHT,
 +                    NULL);
 +
 +  add_combo_column (obj, VS_MEASURE, _("Measure"), 10,
 +                    measure_to_string (MEASURE_NOMINAL), MEASURE_NOMINAL,
 +                    measure_to_string (MEASURE_ORDINAL), MEASURE_ORDINAL,
 +                    measure_to_string (MEASURE_SCALE), MEASURE_SCALE,
 +                    NULL);
 +
 +  pspp_sheet_view_set_rubber_banding (sheet_view, TRUE);
 +  pspp_sheet_selection_set_mode (pspp_sheet_view_get_selection (sheet_view),
 +                                 PSPP_SHEET_SELECTION_MULTIPLE);
 +
 +  g_object_set (G_OBJECT (obj), "has-tooltip", TRUE, NULL);
 +  g_signal_connect (obj, "query-tooltip",
 +                    G_CALLBACK (on_query_var_tooltip), NULL);
 +  g_signal_connect (obj, "button-press-event",
 +                    G_CALLBACK (on_button_pressed), NULL);
 +  g_signal_connect (obj, "popup-menu", G_CALLBACK (on_popup_menu), NULL);
 +
 +  obj->builder = builder_new ("var-sheet.ui");
 +
 +  action = get_action_assert (obj->builder, "edit_clear-variables");
 +  g_signal_connect (action, "activate", G_CALLBACK (on_edit_clear_variables),
 +                    obj);
 +  gtk_action_set_sensitive (action, FALSE);
 +  g_signal_connect (pspp_sheet_view_get_selection (sheet_view),
 +                    "changed", G_CALLBACK (on_selection_changed), NULL);
 +
 +  action = get_action_assert (obj->builder, "edit_insert-variable");
 +  gtk_action_set_sensitive (action, FALSE);
 +  g_signal_connect (action, "activate", G_CALLBACK (on_edit_insert_variable),
 +                    obj);
 +}
 +
 +GtkWidget *
  psppire_var_sheet_new (void)
  {
 -  gint i;
 -  PsppireAxis *ha = psppire_axis_new ();
 -  PsppireAxis *va = psppire_axis_new ();
 +  return g_object_new (PSPPIRE_VAR_SHEET_TYPE, NULL);
 +}
  
 -  GtkWidget *w = g_object_new (psppire_var_sheet_get_type (), NULL);
 +PsppireDict *
 +psppire_var_sheet_get_dictionary (PsppireVarSheet *var_sheet)
 +{
 +  return var_sheet->dict;
 +}
  
 -  for (i = 0 ; i < 10 ; ++i)
 -    psppire_axis_append (ha, column_def[i].width);
 +static void
 +refresh_model (PsppireVarSheet *var_sheet)
 +{
 +  pspp_sheet_view_set_model (PSPP_SHEET_VIEW (var_sheet), NULL);
  
 -  g_object_set (va,
 -              "default-size", 25,
 -              NULL);
 +  if (var_sheet->dict != NULL)
 +    {
 +      PsppireEmptyListStore *store;
 +      int n_rows;
 +
 +      n_rows = (psppire_dict_get_var_cnt (var_sheet->dict)
 +                + var_sheet->may_create_vars);
 +      store = psppire_empty_list_store_new (n_rows);
 +      pspp_sheet_view_set_model (PSPP_SHEET_VIEW (var_sheet),
 +                                 GTK_TREE_MODEL (store));
 +      g_object_unref (store);
 +    }
 +}
 +
 +static void
 +on_var_changed (PsppireDict *dict, glong row, PsppireVarSheet *var_sheet)
 +{
 +  PsppireEmptyListStore *store;
 +
 +  g_return_if_fail (dict == var_sheet->dict);
 +
 +  store = PSPPIRE_EMPTY_LIST_STORE (pspp_sheet_view_get_model (
 +                                      PSPP_SHEET_VIEW (var_sheet)));
 +  g_return_if_fail (store != NULL);
 +
 +  psppire_empty_list_store_row_changed (store, row);
 +}
 +
 +static void
 +on_var_inserted (PsppireDict *dict, glong row, PsppireVarSheet *var_sheet)
 +{
 +  PsppireEmptyListStore *store;
 +  int n_rows;
  
 -  g_object_set (ha, "minimum-extent", 0,
 -              NULL);
 +  g_return_if_fail (dict == var_sheet->dict);
  
 -  g_object_set (w,
 -              "horizontal-axis", ha,
 -              "vertical-axis", va,
 -              NULL);
 +  store = PSPPIRE_EMPTY_LIST_STORE (pspp_sheet_view_get_model (
 +                                      PSPP_SHEET_VIEW (var_sheet)));
 +  g_return_if_fail (store != NULL);
  
 -  return w;
 +  n_rows = (psppire_dict_get_var_cnt (var_sheet->dict)
 +            + var_sheet->may_create_vars);
 +  psppire_empty_list_store_set_n_rows (store, n_rows);
 +  psppire_empty_list_store_row_inserted (store, row);
 +}
 +
 +static void
 +on_var_deleted (PsppireDict *dict,
 +                const struct variable *var, int dict_idx, int case_idx,
 +                PsppireVarSheet *var_sheet)
 +{
 +  PsppireEmptyListStore *store;
 +  int n_rows;
 +
 +  g_return_if_fail (dict == var_sheet->dict);
 +
 +  store = PSPPIRE_EMPTY_LIST_STORE (pspp_sheet_view_get_model (
 +                                      PSPP_SHEET_VIEW (var_sheet)));
 +  g_return_if_fail (store != NULL);
 +
 +  n_rows = (psppire_dict_get_var_cnt (var_sheet->dict)
 +            + var_sheet->may_create_vars);
 +  psppire_empty_list_store_set_n_rows (store, n_rows);
 +  psppire_empty_list_store_row_deleted (store, dict_idx);
 +}
 +
 +static void
 +on_backend_changed (PsppireDict *dict, PsppireVarSheet *var_sheet)
 +{
 +  g_return_if_fail (dict == var_sheet->dict);
 +  refresh_model (var_sheet);
  }
 +
 +void
 +psppire_var_sheet_set_dictionary (PsppireVarSheet *var_sheet,
 +                                  PsppireDict *dict)
 +{
 +  if (var_sheet->dict != NULL)
 +    {
 +      int i;
 +      
 +      for (i = 0; i < PSPPIRE_VAR_SHEET_N_SIGNALS; i++)
 +      {
 +        if (var_sheet->dict_signals[i])
 +          g_signal_handler_disconnect (var_sheet->dict,
 +                                       var_sheet->dict_signals[i]);
 +        
 +        var_sheet->dict_signals[i] = 0;
 +      }
 +
 +      g_object_unref (var_sheet->dict);
 +    }
 +
 +  var_sheet->dict = dict;
 +
 +  if (dict != NULL)
 +    {
 +      g_object_ref (dict);
 +
 +      var_sheet->dict_signals[PSPPIRE_VAR_SHEET_BACKEND_CHANGED]
 +        = g_signal_connect (dict, "backend-changed",
 +                            G_CALLBACK (on_backend_changed), var_sheet);
 +
 +      var_sheet->dict_signals[PSPPIRE_VAR_SHEET_VARIABLE_CHANGED]
 +        = g_signal_connect (dict, "variable-changed",
 +                            G_CALLBACK (on_var_changed), var_sheet);
 +
 +      var_sheet->dict_signals[PSPPIRE_VAR_SHEET_VARIABLE_DELETED]
 +        = g_signal_connect (dict, "variable-inserted",
 +                            G_CALLBACK (on_var_inserted), var_sheet);
 +
 +      var_sheet->dict_signals[PSPPIRE_VAR_SHEET_VARIABLE_INSERTED]
 +        = g_signal_connect (dict, "variable-deleted",
 +                            G_CALLBACK (on_var_deleted), var_sheet);
 +    }
 +
 +  refresh_model (var_sheet);
 +}
 +
 +gboolean
 +psppire_var_sheet_get_may_create_vars (PsppireVarSheet *var_sheet)
 +{
 +  return var_sheet->may_create_vars;
 +}
 +
 +void
 +psppire_var_sheet_set_may_create_vars (PsppireVarSheet *var_sheet,
 +                                       gboolean may_create_vars)
 +{
 +  if (var_sheet->may_create_vars != may_create_vars)
 +    {
 +      PsppireEmptyListStore *store;
 +      gint n_rows;
 +
 +      var_sheet->may_create_vars = may_create_vars;
 +
 +      store = PSPPIRE_EMPTY_LIST_STORE (pspp_sheet_view_get_model (
 +                                          PSPP_SHEET_VIEW (var_sheet)));
 +      g_return_if_fail (store != NULL);
 +
 +      n_rows = (psppire_dict_get_var_cnt (var_sheet->dict)
 +                + var_sheet->may_create_vars);
 +      psppire_empty_list_store_set_n_rows (store, n_rows);
 +
 +      if (may_create_vars)
 +        psppire_empty_list_store_row_inserted (store, n_rows - 1);
 +      else
 +        psppire_empty_list_store_row_deleted (store, n_rows);
 +
 +      on_selection_changed (pspp_sheet_view_get_selection (
 +                              PSPP_SHEET_VIEW (var_sheet)), NULL);
 +    }
 +}
 +
 +gboolean
 +psppire_var_sheet_get_may_delete_vars (PsppireVarSheet *var_sheet)
 +{
 +  return var_sheet->may_delete_vars;
 +}
 +
 +void
 +psppire_var_sheet_set_may_delete_vars (PsppireVarSheet *var_sheet,
 +                                       gboolean may_delete_vars)
 +{
 +  if (var_sheet->may_delete_vars != may_delete_vars)
 +    {
 +      var_sheet->may_delete_vars = may_delete_vars;
 +      on_selection_changed (pspp_sheet_view_get_selection (
 +                              PSPP_SHEET_VIEW (var_sheet)), NULL);
 +    }
 +}
 +
 +void
 +psppire_var_sheet_goto_variable (PsppireVarSheet *var_sheet, int dict_index)
 +{
 +  PsppSheetView *sheet_view = PSPP_SHEET_VIEW (var_sheet);
 +  GtkTreePath *path;
 +
 +  path = gtk_tree_path_new_from_indices (dict_index, -1);
 +  pspp_sheet_view_scroll_to_cell (sheet_view, path, NULL, FALSE, 0.0, 0.0);
 +  pspp_sheet_view_set_cursor (sheet_view, path, NULL, FALSE);
 +  gtk_tree_path_free (path);
 +}
 +
 +GtkUIManager *
 +psppire_var_sheet_get_ui_manager (PsppireVarSheet *var_sheet)
 +{
 +  if (var_sheet->uim == NULL)
 +    {
 +      var_sheet->uim = GTK_UI_MANAGER (get_object_assert (var_sheet->builder,
 +                                                        "var_sheet_uim",
 +                                                        GTK_TYPE_UI_MANAGER));
 +      g_object_ref (var_sheet->uim);
 +    }
 +
 +  return var_sheet->uim;
 +}
 +
index cd4bd20b3b0e36d6dad9fd8f6b157eefe1260847,058821b7b30d583236e36b2ae0817187148c0c42..e8db83e12ac4e0b4c0598b7f5d383b01eab0ce61
@@@ -44,45 -36,25 +44,42 @@@ GType psppire_fmt_use_get_type (void) G
  typedef struct _PsppireVarSheet       PsppireVarSheet;
  typedef struct _PsppireVarSheetClass  PsppireVarSheetClass;
  
 +enum
 +{
 +    PSPPIRE_VAR_SHEET_BACKEND_CHANGED,
 +    PSPPIRE_VAR_SHEET_VARIABLE_CHANGED,
 +    PSPPIRE_VAR_SHEET_VARIABLE_INSERTED,
 +    PSPPIRE_VAR_SHEET_VARIABLE_DELETED,
 +    PSPPIRE_VAR_SHEET_N_SIGNALS
 + };
 +
  struct _PsppireVarSheet
  {
 -  PsppireSheet parent;
 +  PsppSheetView parent;
  
 -  gboolean dispose_has_run;
    gboolean may_create_vars;
 -};
 +  gboolean may_delete_vars;
 +  enum fmt_use format_use;
  
-   struct val_labs_dialog *val_labs_dialog;
-   struct missing_val_dialog *missing_val_dialog;
-   struct var_type_dialog *var_type_dialog;
 +  struct _PsppireDict *dict;
  
 -struct _PsppireVarSheetClass
 -{
 -  PsppireSheetClass parent_class;
 +  gulong scroll_to_bottom_signal;
 +  gulong dict_signals[PSPPIRE_VAR_SHEET_N_SIGNALS];
 +
 +  GtkBuilder *builder;
  
 -  GtkListStore *alignment_list;
 -  GtkListStore *measure_list;
 +  GtkWidget *container;
 +  gulong on_switch_page_handler;
  
 -  void (*var_sheet)(PsppireVarSheet*);
 +  GtkUIManager *uim;
 +
 +  gboolean dispose_has_run;
  };
  
 +struct _PsppireVarSheetClass
 +{
 +  PsppSheetViewClass parent_class;
 +};
  
  GType          psppire_var_sheet_get_type        (void);
  GtkWidget*     psppire_var_sheet_new             (void);
Simple merge
index 89b85d073e9bb9cd322fd5c77d3ed67f557d2d42,379a5eeb3ee8fd1bf7968806582b605d788ac7f2..74b752e142d8ae2ac31e7a44c2d62327bed206d8
  
  
  #include <gtk/gtk.h>
- #include <data/variable.h>
+ #include "data/format.h"
+ #include "data/variable.h"
+ #include "ui/gui/psppire-dialog.h"
 -#include "ui/gui/psppire-var-store.h"
  
- struct val_labs;
+ G_BEGIN_DECLS
  
+ #define PSPPIRE_TYPE_VAL_LABS_DIALOG             (psppire_val_labs_dialog_get_type())
+ #define PSPPIRE_VAL_LABS_DIALOG(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj),PSPPIRE_TYPE_VAL_LABS_DIALOG,PsppireValLabsDialog))
+ #define PSPPIRE_VAL_LABS_DIALOG_CLASS(class)     (G_TYPE_CHECK_CLASS_CAST ((class),PSPPIRE_TYPE_VAL_LABS_DIALOG,PsppireValLabsDialogClass))
+ #define PSPPIRE_IS_VAL_LABS_DIALOG(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj),PSPPIRE_TYPE_VAL_LABS_DIALOG))
+ #define PSPPIRE_IS_VAL_LABS_DIALOG_CLASS(class)  (G_TYPE_CHECK_CLASS_TYPE ((class),PSPPIRE_TYPE_VAL_LABS_DIALOG))
+ #define PSPPIRE_VAL_LABS_DIALOG_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),PSPPIRE_TYPE_VAL_LABS_DIALOG,PsppireValLabsDialogClass))
  
- struct val_labs_dialog * val_labs_dialog_create (GtkWindow *);
+ typedef struct _PsppireValLabsDialog      PsppireValLabsDialog;
+ typedef struct _PsppireValLabsDialogClass PsppireValLabsDialogClass;
  
- void val_labs_dialog_show (struct val_labs_dialog *);
+ struct _PsppireValLabsDialog {
+   PsppireDialog parent;
  
- void val_labs_dialog_set_target_variable (struct val_labs_dialog *,
-                                         struct variable *);
+   struct val_labs *labs;
+   gchar *encoding;
+   struct fmt_spec format;
  
- #endif
+   /* Actions */
+   GtkWidget *add_button;
+   GtkWidget *remove_button;
+   GtkWidget *change_button;
+   /* Entry Boxes */
+   GtkWidget *value_entry;
+   GtkWidget *label_entry;
+   /* Signal handler ids */
+   gint change_handler_id;
+   gint value_handler_id;
+   GtkWidget *treeview;
+ };
+ struct _PsppireValLabsDialogClass {
+   PsppireDialogClass parent_class;
+ };
+ GType psppire_val_labs_dialog_get_type (void) G_GNUC_CONST;
+ PsppireValLabsDialog* psppire_val_labs_dialog_new (const struct variable *);
+ void psppire_val_labs_dialog_set_variable (PsppireValLabsDialog *,
+                                            const struct variable *);
+ const struct val_labs *psppire_val_labs_dialog_get_value_labels (
+   const PsppireValLabsDialog *);
+ struct val_labs *psppire_val_labs_dialog_run (GtkWindow *parent_window,
+                                               const struct variable *);
+ G_END_DECLS
+ #endif /* psppire-val-labs-dialog.h */
index 8e11160e3e46386774c0870b17185f7d926be4eb,0251cbe519c89a723dc226a0e861c3a91a3ff50f..b2d58d2a7386b5579b91e1f2e29e489ce0f81dd5
     along with this program.  If not, see <http://www.gnu.org/licenses/>. */
  
  
- #ifndef __PSPPIRE_VAR_TYPE_DIALOG_H
- #define __PSPPIRE_VAR_TYPE_DIALOG_H
+ #ifndef PSPPIRE_VAR_TYPE_DIALOG_H
+ #define PSPPIRE_VAR_TYPE_DIALOG_H 1
  
- #include <data/format.h>
+ #include "data/format.h"
+ #include "psppire-dialog.h"
 -#include "psppire-var-store.h"
+ G_BEGIN_DECLS
+ #define PSPPIRE_TYPE_VAR_TYPE_DIALOG             (psppire_var_type_dialog_get_type())
+ #define PSPPIRE_VAR_TYPE_DIALOG(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj),PSPPIRE_TYPE_VAR_TYPE_DIALOG,PsppireVarTypeDialog))
+ #define PSPPIRE_VAR_TYPE_DIALOG_CLASS(class)     (G_TYPE_CHECK_CLASS_CAST ((class),PSPPIRE_TYPE_VAR_TYPE_DIALOG,PsppireVarTypeDialogClass))
+ #define PSPPIRE_IS_VAR_TYPE_DIALOG(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj),PSPPIRE_TYPE_VAR_TYPE_DIALOG))
+ #define PSPPIRE_IS_VAR_TYPE_DIALOG_CLASS(class)  (G_TYPE_CHECK_CLASS_TYPE ((class),PSPPIRE_TYPE_VAR_TYPE_DIALOG))
+ #define PSPPIRE_VAR_TYPE_DIALOG_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),PSPPIRE_TYPE_VAR_TYPE_DIALOG,PsppireVarTypeDialogClass))
+ typedef struct _PsppireVarTypeDialog      PsppireVarTypeDialog;
+ typedef struct _PsppireVarTypeDialogClass PsppireVarTypeDialogClass;
  
  /*  This module describes the behaviour of the Variable Type dialog box,
      used for input of the variable type parameter in the var sheet */