The attached patches I believe represent improvements to the psppsheet branch
They don't fix all of the problems I had hoped, but I think it'll make the
branch easier to work on.

A review would be appreciated.

J'

-- 
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://keys.gnupg.net or any PGP keyserver for public key.

From f84ddbdb146f4e519b8e051658393fce6fd52a1c Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Thu, 5 Jul 2012 18:46:33 +0200
Subject: [PATCH 01/11] PsppireDataSheet: Reference handler improvements.

Changed the destroy method to dispose, because all it does is drop
references.  Also, keep a reference to the object returned by _get_ui_manager
since this seems to be causing issues elsewhere.
---
 src/ui/gui/psppire-data-sheet.c |   41 +++++++++++++++++++++++++-------------
 src/ui/gui/psppire-data-sheet.h |    8 +++++-
 2 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/src/ui/gui/psppire-data-sheet.c b/src/ui/gui/psppire-data-sheet.c
index b25b189..b6bf67c 100644
--- a/src/ui/gui/psppire-data-sheet.c
+++ b/src/ui/gui/psppire-data-sheet.c
@@ -47,7 +47,7 @@
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-static void psppire_data_sheet_destroy (GtkObject *);
+static void psppire_data_sheet_dispose (GObject *);
 static void psppire_data_sheet_unset_data_store (PsppireDataSheet *);
 
 static void psppire_data_sheet_update_clip_actions (PsppireDataSheet *);
@@ -1168,38 +1168,48 @@ psppire_data_sheet_get_current_case (const PsppireDataSheet *data_sheet)
 GtkUIManager *
 psppire_data_sheet_get_ui_manager (PsppireDataSheet *data_sheet)
 {
-  return GTK_UI_MANAGER (get_object_assert (data_sheet->builder,
-                                            "data_sheet_uim",
-                                            GTK_TYPE_UI_MANAGER));
+  if (data_sheet->uim == NULL)
+    {
+      data_sheet->uim = 
+	GTK_UI_MANAGER (get_object_assert (data_sheet->builder,
+					   "data_sheet_uim",
+					   GTK_TYPE_UI_MANAGER));
+      g_object_ref (data_sheet->uim);
+    }
+
+  return data_sheet->uim;
 }
 
 static void
-psppire_data_sheet_destroy (GtkObject *object)
+psppire_data_sheet_dispose (GObject *object)
 {
   PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (object);
 
+  if (data_sheet->dispose_has_run)
+    return;
+
+  data_sheet->dispose_has_run = TRUE;
+
   psppire_data_sheet_unset_data_store (data_sheet);
-  if (data_sheet->builder)
-    {
-      g_object_unref (data_sheet->builder);
-      data_sheet->builder = NULL;
-    }
 
-  GTK_OBJECT_CLASS (psppire_data_sheet_parent_class)->destroy (object);
+  g_object_unref (data_sheet->builder);
+
+  if (data_sheet->uim)
+    g_object_unref (data_sheet->uim);
+
+  G_OBJECT_CLASS (psppire_data_sheet_parent_class)->dispose (object);
 }
 
 static void
 psppire_data_sheet_class_init (PsppireDataSheetClass *class)
 {
   GObjectClass *gobject_class;
-  GtkObjectClass *gtk_object_class;
 
   gobject_class = G_OBJECT_CLASS (class);
   gobject_class->set_property = psppire_data_sheet_set_property;
   gobject_class->get_property = psppire_data_sheet_get_property;
 
-  gtk_object_class = GTK_OBJECT_CLASS (class);
-  gtk_object_class->destroy = psppire_data_sheet_destroy;
+  gobject_class->dispose = psppire_data_sheet_dispose;
 
   g_signal_new ("var-double-clicked",
                 G_OBJECT_CLASS_TYPE (gobject_class),
@@ -1622,6 +1632,9 @@ psppire_data_sheet_init (PsppireDataSheet *obj)
   obj->new_variable_column = NULL;
   obj->container = NULL;
 
+  obj->uim = NULL;
+  obj->dispose_has_run = FALSE;
+
   pspp_sheet_view_set_special_cells (sheet_view, PSPP_SHEET_VIEW_SPECIAL_CELLS_YES);
 
   g_signal_connect (obj, "notify::model",
diff --git a/src/ui/gui/psppire-data-sheet.h b/src/ui/gui/psppire-data-sheet.h
index e17278e..a94bad7 100644
--- a/src/ui/gui/psppire-data-sheet.h
+++ b/src/ui/gui/psppire-data-sheet.h
@@ -38,7 +38,8 @@ G_BEGIN_DECLS
 typedef struct _PsppireDataSheet      PsppireDataSheet;
 typedef struct _PsppireDataSheetClass PsppireDataSheetClass;
 
-struct _PsppireDataSheet {
+struct _PsppireDataSheet
+{
   PsppSheetView parent;
 
   struct _PsppireDataStore *data_store;
@@ -55,9 +56,12 @@ struct _PsppireDataSheet {
   GtkBuilder *builder;
 
   GtkWidget *container;
+  GtkUIManager *uim;
+  gboolean dispose_has_run;
 };
 
-struct _PsppireDataSheetClass {
+struct _PsppireDataSheetClass 
+{
   PsppSheetViewClass parent_class;
 };
 
-- 
1.7.2.5

From 0756f0fac7c580238977e158d5bdb8386ce6727a Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Thu, 5 Jul 2012 19:03:08 +0200
Subject: [PATCH 02/11] PsppireCellRendererButton: Replace destroy with dispose

The destroy method did nothing except drop references, so was
appropriate for dispose.
---
 src/ui/gui/psppire-cell-renderer-button.c |   35 ++++++++++-------------------
 src/ui/gui/psppire-cell-renderer-button.h |    5 ++-
 2 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/src/ui/gui/psppire-cell-renderer-button.c b/src/ui/gui/psppire-cell-renderer-button.c
index 8bf90a2..ac90984 100644
--- a/src/ui/gui/psppire-cell-renderer-button.c
+++ b/src/ui/gui/psppire-cell-renderer-button.c
@@ -30,7 +30,7 @@
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-static void psppire_cell_renderer_button_destroy (GtkObject *);
+static void psppire_cell_renderer_button_dispose (GObject *);
 static void psppire_cell_renderer_button_finalize (GObject *);
 
 static void update_style_cache (PsppireCellRendererButton *button,
@@ -135,13 +135,6 @@ on_style_set (GtkWidget                 *base,
 }
 
 static void
-on_destroy (GtkObject                 *base,
-            PsppireCellRendererButton *button)
-{
-  update_style_cache (button, NULL);
-}
-
-static void
 update_style_cache (PsppireCellRendererButton *button,
                     GtkWidget                 *widget)
 {
@@ -167,11 +160,6 @@ update_style_cache (PsppireCellRendererButton *button,
                                        button->style_set_handler);
           button->style_set_handler = 0;
         }
-      if (button->destroy_handler)
-        {
-          g_signal_handler_disconnect (button->base, button->destroy_handler);
-          button->destroy_handler = 0;
-        }
       g_object_unref (button->base);
       button->base = NULL;
     }
@@ -186,10 +174,6 @@ update_style_cache (PsppireCellRendererButton *button,
       button->style_set_handler = g_signal_connect (widget, "style-set",
                                                     G_CALLBACK (on_style_set),
                                                     button);
-      button->destroy_handler = g_signal_connect (widget, "destroy",
-                                                  G_CALLBACK (on_destroy),
-                                                  button);
-
       g_object_ref (widget);
       g_object_ref (button->button_style);
       g_object_ref (button->label_style);
@@ -476,14 +460,12 @@ static void
 psppire_cell_renderer_button_class_init (PsppireCellRendererButtonClass *class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-  GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (class);
   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
 
   gobject_class->set_property = psppire_cell_renderer_button_set_property;
   gobject_class->get_property = psppire_cell_renderer_button_get_property;
   gobject_class->finalize = psppire_cell_renderer_button_finalize;
-
-  gtk_object_class->destroy = psppire_cell_renderer_button_destroy;
+  gobject_class->dispose = psppire_cell_renderer_button_dispose;
 
   cell_class->get_size = psppire_cell_renderer_button_get_size;
   cell_class->render = psppire_cell_renderer_button_render;
@@ -550,7 +532,7 @@ psppire_cell_renderer_button_init (PsppireCellRendererButton *obj)
   obj->label_style = NULL;
   obj->base = NULL;
   obj->style_set_handler = 0;
-  obj->destroy_handler = 0;
+  obj->dispose_has_run = FALSE;
 }
 
 static void
@@ -562,13 +544,20 @@ psppire_cell_renderer_button_finalize (GObject *obj)
 }
 
 static void
-psppire_cell_renderer_button_destroy (GtkObject *obj)
+psppire_cell_renderer_button_dispose (GObject *obj)
 {
   PsppireCellRendererButton *button = PSPPIRE_CELL_RENDERER_BUTTON (obj);
 
+  if (button->dispose_has_run)
+    return;
+  
+  button->dispose_has_run = TRUE;
+
+  /* When called with NULL, as we are doing here, update_style_cache
+     does nothing more than to drop references */
   update_style_cache (button, NULL);
 
-  GTK_OBJECT_CLASS (psppire_cell_renderer_button_parent_class)->destroy (obj);
+  G_OBJECT_CLASS (psppire_cell_renderer_button_parent_class)->dispose (obj);
 }
 
 GtkCellRenderer *
diff --git a/src/ui/gui/psppire-cell-renderer-button.h b/src/ui/gui/psppire-cell-renderer-button.h
index a878f51..28d5dd1 100644
--- a/src/ui/gui/psppire-cell-renderer-button.h
+++ b/src/ui/gui/psppire-cell-renderer-button.h
@@ -31,7 +31,8 @@ G_BEGIN_DECLS
 typedef struct _PsppireCellRendererButton      PsppireCellRendererButton;
 typedef struct _PsppireCellRendererButtonClass PsppireCellRendererButtonClass;
 
-struct _PsppireCellRendererButton {
+struct _PsppireCellRendererButton
+{
   GtkCellRenderer parent;
 
   gboolean editable;
@@ -52,7 +53,7 @@ struct _PsppireCellRendererButton {
   GtkStyle *label_style;
   GtkWidget *base;
   gulong style_set_handler;
-  gulong destroy_handler;
+  gboolean dispose_has_run;
 };
 
 struct _PsppireCellRendererButtonClass {
-- 
1.7.2.5

From 4b9760b5fe332eca8c6ed45021f9e94123ed0f8b Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Thu, 5 Jul 2012 19:36:08 +0200
Subject: [PATCH 03/11] PsppireVarSheet: Replace Destroy with Dispose

Also, use a statically allocated array for signal handler ids, since
it just complicates things to have a dynamically allocated one.
---
 src/ui/gui/psppire-var-sheet.c |   82 ++++++++++++++++++---------------------
 src/ui/gui/psppire-var-sheet.h |   12 +++++-
 2 files changed, 49 insertions(+), 45 deletions(-)

diff --git a/src/ui/gui/psppire-var-sheet.c b/src/ui/gui/psppire-var-sheet.c
index b937608..3a8f423 100644
--- a/src/ui/gui/psppire-var-sheet.c
+++ b/src/ui/gui/psppire-var-sheet.c
@@ -908,48 +908,50 @@ psppire_var_sheet_realize (GtkWidget *w)
 }
 
 static void
-psppire_var_sheet_destroy (GtkObject *obj)
+psppire_var_sheet_dispose (GObject *obj)
 {
   PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (obj);
+  int i;
 
-  GTK_OBJECT_CLASS (psppire_var_sheet_parent_class)->destroy (obj);
+  if (var_sheet->dispose_has_run)
+    return;
 
-  psppire_var_sheet_set_dictionary (var_sheet, NULL);
+  var_sheet->dispose_has_run = TRUE;
 
-  if (var_sheet->val_labs_dialog)
-    {
-      g_object_unref (var_sheet->val_labs_dialog);
-      var_sheet->val_labs_dialog = NULL;
-    }
+  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->missing_val_dialog)
-    {
-      g_object_unref (var_sheet->missing_val_dialog);
-      var_sheet->missing_val_dialog = NULL;
-    }
+  if (var_sheet->dict)
+    g_object_unref (var_sheet->dict);
+  
 
-  if (var_sheet->var_type_dialog)
-    {
-      g_object_unref (var_sheet->var_type_dialog);
-      var_sheet->var_type_dialog = NULL;
-    }
+  /* 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_class_init (PsppireVarSheetClass *class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-  GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
   GParamSpec *pspec;
 
   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;
 
-  gtk_object_class->destroy = psppire_var_sheet_destroy;
-
   g_signal_new ("var-double-clicked",
                 G_OBJECT_CLASS_TYPE (gobject_class),
                 G_SIGNAL_RUN_LAST,
@@ -1165,6 +1167,7 @@ psppire_var_sheet_init (PsppireVarSheet *obj)
   obj->scroll_to_bottom_signal = 0;
 
   obj->container = NULL;
+  obj->dispose_has_run = FALSE;
 
   pspp_sheet_view_append_column (sheet_view, make_row_number_column (obj));
 
@@ -1309,26 +1312,19 @@ void
 psppire_var_sheet_set_dictionary (PsppireVarSheet *var_sheet,
                                   PsppireDict *dict)
 {
-  enum {
-    BACKEND_CHANGED,
-    VARIABLE_INSERTED,
-    VARIABLE_DELETED,
-    N_SIGNALS
-  };
-
   if (var_sheet->dict != NULL)
     {
-      if (var_sheet->dict_signals)
-        {
-          int i;
-
-          for (i = 0; i < N_SIGNALS; i++)
-            g_signal_handler_disconnect (var_sheet->dict,
-                                         var_sheet->dict_signals[i]);
+      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_free (var_sheet->dict_signals);
-          var_sheet->dict_signals = NULL;
-        }
       g_object_unref (var_sheet->dict);
     }
 
@@ -1338,21 +1334,19 @@ psppire_var_sheet_set_dictionary (PsppireVarSheet *var_sheet,
     {
       g_object_ref (dict);
 
-      var_sheet->dict_signals = g_malloc0 (
-        N_SIGNALS * sizeof *var_sheet->dict_signals);
-
-      var_sheet->dict_signals[BACKEND_CHANGED]
+      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[VARIABLE_DELETED]
+      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[VARIABLE_INSERTED]
+      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);
 }
 
diff --git a/src/ui/gui/psppire-var-sheet.h b/src/ui/gui/psppire-var-sheet.h
index 97efcf4..b115b9b 100644
--- a/src/ui/gui/psppire-var-sheet.h
+++ b/src/ui/gui/psppire-var-sheet.h
@@ -44,6 +44,14 @@ GType psppire_fmt_use_get_type (void) G_GNUC_CONST;
 typedef struct _PsppireVarSheet       PsppireVarSheet;
 typedef struct _PsppireVarSheetClass  PsppireVarSheetClass;
 
+enum
+{
+    PSPPIRE_VAR_SHEET_BACKEND_CHANGED,
+    PSPPIRE_VAR_SHEET_VARIABLE_INSERTED,
+    PSPPIRE_VAR_SHEET_VARIABLE_DELETED,
+    PSPPIRE_VAR_SHEET_N_SIGNALS
+ };
+
 struct _PsppireVarSheet
 {
   PsppSheetView parent;
@@ -58,12 +66,14 @@ struct _PsppireVarSheet
   struct var_type_dialog *var_type_dialog;
 
   gulong scroll_to_bottom_signal;
-  gulong *dict_signals;
+  gulong dict_signals[PSPPIRE_VAR_SHEET_N_SIGNALS];
 
   GtkBuilder *builder;
 
   GtkWidget *container;
   gulong on_switch_page_handler;
+
+  gboolean dispose_has_run;
 };
 
 struct _PsppireVarSheetClass
-- 
1.7.2.5

From 1a53f11fa9662a6a7e8abdfdd6863f8163227ea4 Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Thu, 5 Jul 2012 19:55:52 +0200
Subject: [PATCH 04/11] PsppireVarSheet: Keep reference to the return value of _get_ui_manager

---
 src/ui/gui/psppire-var-sheet.c |   15 ++++++++++++---
 src/ui/gui/psppire-var-sheet.h |    2 ++
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/ui/gui/psppire-var-sheet.c b/src/ui/gui/psppire-var-sheet.c
index 3a8f423..930c277 100644
--- a/src/ui/gui/psppire-var-sheet.c
+++ b/src/ui/gui/psppire-var-sheet.c
@@ -926,6 +926,8 @@ psppire_var_sheet_dispose (GObject *obj)
   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
@@ -1168,6 +1170,7 @@ psppire_var_sheet_init (PsppireVarSheet *obj)
 
   obj->container = NULL;
   obj->dispose_has_run = FALSE;
+  obj->uim = NULL;
 
   pspp_sheet_view_append_column (sheet_view, make_row_number_column (obj));
 
@@ -1418,8 +1421,14 @@ psppire_var_sheet_goto_variable (PsppireVarSheet *var_sheet, int dict_index)
 GtkUIManager *
 psppire_var_sheet_get_ui_manager (PsppireVarSheet *var_sheet)
 {
-  return GTK_UI_MANAGER (get_object_assert (var_sheet->builder,
-                                            "var_sheet_uim",
-                                            GTK_TYPE_UI_MANAGER));
+  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;
 }
 
diff --git a/src/ui/gui/psppire-var-sheet.h b/src/ui/gui/psppire-var-sheet.h
index b115b9b..754dd25 100644
--- a/src/ui/gui/psppire-var-sheet.h
+++ b/src/ui/gui/psppire-var-sheet.h
@@ -73,6 +73,8 @@ struct _PsppireVarSheet
   GtkWidget *container;
   gulong on_switch_page_handler;
 
+  GtkUIManager *uim;
+
   gboolean dispose_has_run;
 };
 
-- 
1.7.2.5

From 3614ff3ba9589f8baa0d4f573631e1b6c26eb110 Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Thu, 5 Jul 2012 20:33:58 +0200
Subject: [PATCH 05/11] PsppireDataStore: Move datasheet_destroy from dispose to finalize

This actually destroys stuff, not merely unreffing.  So it belongs in finalize.
---
 src/ui/gui/psppire-data-store.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/ui/gui/psppire-data-store.c b/src/ui/gui/psppire-data-store.c
index 83933c4..047cca7 100644
--- a/src/ui/gui/psppire-data-store.c
+++ b/src/ui/gui/psppire-data-store.c
@@ -389,6 +389,13 @@ psppire_data_store_set_dictionary (PsppireDataStore *data_store, PsppireDict *di
 static void
 psppire_data_store_finalize (GObject *object)
 {
+  PsppireDataStore *ds = PSPPIRE_DATA_STORE (object);
+
+  if (ds->datasheet)
+    {
+      datasheet_destroy (ds->datasheet);
+      ds->datasheet = NULL;
+    }
 
   /* must chain up */
   (* parent_class->finalize) (object);
@@ -403,11 +410,6 @@ psppire_data_store_dispose (GObject *object)
   if (ds->dispose_has_run)
     return;
 
-  if (ds->datasheet)
-    {
-      datasheet_destroy (ds->datasheet);
-      ds->datasheet = NULL;
-    }
 
   /* must chain up */
   (* parent_class->dispose) (object);
-- 
1.7.2.5

From d071e665968b93d119a195a2487c583c1df3b12b Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Thu, 5 Jul 2012 21:53:17 +0200
Subject: [PATCH 06/11] pspp-sheet-view.c: Separate destroy method into finalize and dispose.

This still needs work to disentangle them completely, but I think this
is an improvement.
---
 src/ui/gui/pspp-sheet-view.c |   88 ++++++++++++++++++++++--------------------
 src/ui/gui/pspp-sheet-view.h |    2 +
 2 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/src/ui/gui/pspp-sheet-view.c b/src/ui/gui/pspp-sheet-view.c
index 6a690f4..8cf4756 100644
--- a/src/ui/gui/pspp-sheet-view.c
+++ b/src/ui/gui/pspp-sheet-view.c
@@ -160,8 +160,7 @@ static void     pspp_sheet_view_get_property         (GObject         *object,
 						    GValue          *value,
 						    GParamSpec      *pspec);
 
-/* gtkobject signals */
-static void     pspp_sheet_view_destroy              (GtkObject        *object);
+static void     pspp_sheet_view_dispose              (GObject        *object);
 
 /* gtkwidget signals */
 static void     pspp_sheet_view_realize              (GtkWidget        *widget);
@@ -444,7 +443,6 @@ static void
 pspp_sheet_view_class_init (PsppSheetViewClass *class)
 {
   GObjectClass *o_class;
-  GtkObjectClass *object_class;
   GtkWidgetClass *widget_class;
   GtkContainerClass *container_class;
   GtkBindingSet *binding_set[2];
@@ -456,7 +454,6 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
   edit_bindings = binding_set[1];
 
   o_class = (GObjectClass *) class;
-  object_class = (GtkObjectClass *) class;
   widget_class = (GtkWidgetClass *) class;
   container_class = (GtkContainerClass *) class;
 
@@ -464,9 +461,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
   o_class->set_property = pspp_sheet_view_set_property;
   o_class->get_property = pspp_sheet_view_get_property;
   o_class->finalize = pspp_sheet_view_finalize;
-
-  /* GtkObject signals */
-  object_class->destroy = pspp_sheet_view_destroy;
+  o_class->dispose = pspp_sheet_view_dispose;
 
   /* GtkWidget signals */
   widget_class->map = pspp_sheet_view_map;
@@ -823,7 +818,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
 
   tree_view_signals[MOVE_CURSOR] =
     g_signal_new ("move-cursor",
-		  G_TYPE_FROM_CLASS (object_class),
+		  G_TYPE_FROM_CLASS (o_class),
 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 		  G_STRUCT_OFFSET (PsppSheetViewClass, move_cursor),
 		  NULL, NULL,
@@ -834,7 +829,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
 
   tree_view_signals[SELECT_ALL] =
     g_signal_new ("select-all",
-		  G_TYPE_FROM_CLASS (object_class),
+		  G_TYPE_FROM_CLASS (o_class),
 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 		  G_STRUCT_OFFSET (PsppSheetViewClass, select_all),
 		  NULL, NULL,
@@ -843,7 +838,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
 
   tree_view_signals[UNSELECT_ALL] =
     g_signal_new ("unselect-all",
-		  G_TYPE_FROM_CLASS (object_class),
+		  G_TYPE_FROM_CLASS (o_class),
 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 		  G_STRUCT_OFFSET (PsppSheetViewClass, unselect_all),
 		  NULL, NULL,
@@ -852,7 +847,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
 
   tree_view_signals[SELECT_CURSOR_ROW] =
     g_signal_new ("select-cursor-row",
-		  G_TYPE_FROM_CLASS (object_class),
+		  G_TYPE_FROM_CLASS (o_class),
 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 		  G_STRUCT_OFFSET (PsppSheetViewClass, select_cursor_row),
 		  NULL, NULL,
@@ -862,7 +857,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
 
   tree_view_signals[TOGGLE_CURSOR_ROW] =
     g_signal_new ("toggle-cursor-row",
-		  G_TYPE_FROM_CLASS (object_class),
+		  G_TYPE_FROM_CLASS (o_class),
 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 		  G_STRUCT_OFFSET (PsppSheetViewClass, toggle_cursor_row),
 		  NULL, NULL,
@@ -871,7 +866,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
 
   tree_view_signals[START_INTERACTIVE_SEARCH] =
     g_signal_new ("start-interactive-search",
-		  G_TYPE_FROM_CLASS (object_class),
+		  G_TYPE_FROM_CLASS (o_class),
 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 		  G_STRUCT_OFFSET (PsppSheetViewClass, start_interactive_search),
 		  NULL, NULL,
@@ -1060,6 +1055,8 @@ pspp_sheet_view_init (PsppSheetView *tree_view)
   tree_view->priv->anchor_column = NULL;
 
   tree_view->priv->button_style = NULL;
+
+  tree_view->dispose_has_run = FALSE;
 }
 
 
@@ -1217,9 +1214,41 @@ pspp_sheet_view_get_property (GObject    *object,
 }
 
 static void
-pspp_sheet_view_finalize (GObject *object)
+pspp_sheet_view_dispose (GObject *object)
 {
-  G_OBJECT_CLASS (pspp_sheet_view_parent_class)->finalize (object);
+  PsppSheetView *tree_view = PSPP_SHEET_VIEW (object);
+
+  if (tree_view->dispose_has_run)
+    return;
+
+  tree_view->dispose_has_run = TRUE;
+
+  if (tree_view->priv->selection != NULL)
+    {
+      _pspp_sheet_selection_set_tree_view (tree_view->priv->selection, NULL);
+      g_object_unref (tree_view->priv->selection);
+      tree_view->priv->selection = NULL;
+    }
+
+  if (tree_view->priv->hadjustment)
+    {
+      g_object_unref (tree_view->priv->hadjustment);
+      tree_view->priv->hadjustment = NULL;
+    }
+  if (tree_view->priv->vadjustment)
+    {
+      g_object_unref (tree_view->priv->vadjustment);
+      tree_view->priv->vadjustment = NULL;
+    }
+
+  if (tree_view->priv->button_style)
+    {
+      g_object_unref (tree_view->priv->button_style);
+      tree_view->priv->button_style = NULL;
+    }
+
+
+  G_OBJECT_CLASS (pspp_sheet_view_parent_class)->dispose (object);
 }
 
 
@@ -1233,11 +1262,8 @@ pspp_sheet_view_buildable_add_child (GtkBuildable *tree_view,
   pspp_sheet_view_append_column (PSPP_SHEET_VIEW (tree_view), PSPP_SHEET_VIEW_COLUMN (child));
 }
 
-/* GtkObject Methods
- */
-
 static void
-pspp_sheet_view_destroy (GtkObject *object)
+pspp_sheet_view_finalize (GObject *object)
 {
   PsppSheetView *tree_view = PSPP_SHEET_VIEW (object);
   GList *list;
@@ -1265,12 +1291,6 @@ pspp_sheet_view_destroy (GtkObject *object)
 
   tree_view->priv->prelight_node = -1;
 
-  if (tree_view->priv->selection != NULL)
-    {
-      _pspp_sheet_selection_set_tree_view (tree_view->priv->selection, NULL);
-      g_object_unref (tree_view->priv->selection);
-      tree_view->priv->selection = NULL;
-    }
 
   if (tree_view->priv->scroll_to_path != NULL)
     {
@@ -1337,24 +1357,8 @@ pspp_sheet_view_destroy (GtkObject *object)
 
   pspp_sheet_view_set_model (tree_view, NULL);
 
-  if (tree_view->priv->hadjustment)
-    {
-      g_object_unref (tree_view->priv->hadjustment);
-      tree_view->priv->hadjustment = NULL;
-    }
-  if (tree_view->priv->vadjustment)
-    {
-      g_object_unref (tree_view->priv->vadjustment);
-      tree_view->priv->vadjustment = NULL;
-    }
-
-  if (tree_view->priv->button_style)
-    {
-      g_object_unref (tree_view->priv->button_style);
-      tree_view->priv->button_style = NULL;
-    }
 
-  GTK_OBJECT_CLASS (pspp_sheet_view_parent_class)->destroy (object);
+  G_OBJECT_CLASS (pspp_sheet_view_parent_class)->finalize (object);
 }
 
 
diff --git a/src/ui/gui/pspp-sheet-view.h b/src/ui/gui/pspp-sheet-view.h
index 73210f1..dc9bf68 100644
--- a/src/ui/gui/pspp-sheet-view.h
+++ b/src/ui/gui/pspp-sheet-view.h
@@ -102,6 +102,8 @@ struct _PsppSheetView
   GtkContainer parent;
 
   PsppSheetViewPrivate *GSEAL (priv);
+
+  gboolean dispose_has_run ;
 };
 
 struct _PsppSheetViewClass
-- 
1.7.2.5

From 3ecf89ac7f5371f27da3ca0a25d51568d36f877a Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Thu, 5 Jul 2012 23:17:48 +0200
Subject: [PATCH 07/11] Reduce the flicker when redrawing the toolbar and menubar.

---
 src/ui/gui/pspp-sheet-view.c     |   28 +++++++++++++++-------------
 src/ui/gui/psppire-data-editor.c |    8 +++++++-
 src/ui/gui/psppire-data-editor.h |    1 +
 src/ui/gui/psppire-data-window.c |    6 ------
 4 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/src/ui/gui/pspp-sheet-view.c b/src/ui/gui/pspp-sheet-view.c
index 8cf4756..51ceafc 100644
--- a/src/ui/gui/pspp-sheet-view.c
+++ b/src/ui/gui/pspp-sheet-view.c
@@ -1276,18 +1276,6 @@ pspp_sheet_view_finalize (GObject *object)
       tree_view->priv->selected = NULL;
     }
 
-  if (tree_view->priv->columns != NULL)
-    {
-      list = tree_view->priv->columns;
-      while (list)
-	{
-	  PsppSheetViewColumn *column;
-	  column = PSPP_SHEET_VIEW_COLUMN (list->data);
-	  list = list->next;
-	  pspp_sheet_view_remove_column (tree_view, column);
-	}
-      tree_view->priv->columns = NULL;
-    }
 
   tree_view->priv->prelight_node = -1;
 
@@ -1595,6 +1583,19 @@ pspp_sheet_view_unrealize (GtkWidget *widget)
   for (x = 0 ; x < 5 ; ++x)
     g_object_unref (priv->grid_line_gc[x]);
 
+  if (tree_view->priv->columns != NULL)
+    {
+      list = tree_view->priv->columns;
+      while (list)
+	{
+	  PsppSheetViewColumn *column;
+	  column = PSPP_SHEET_VIEW_COLUMN (list->data);
+	  list = list->next;
+	  pspp_sheet_view_remove_column (tree_view, column);
+	}
+      tree_view->priv->columns = NULL;
+    }
+
   GTK_WIDGET_CLASS (pspp_sheet_view_parent_class)->unrealize (widget);
 }
 
@@ -9233,7 +9234,8 @@ pspp_sheet_view_remove_column (PsppSheetView       *tree_view,
 	}
 
       if (tree_view->priv->n_columns == 0 &&
-	  pspp_sheet_view_get_headers_visible (tree_view))
+	  pspp_sheet_view_get_headers_visible (tree_view) && 
+	  tree_view->priv->header_window)
 	gdk_window_hide (tree_view->priv->header_window);
 
       gtk_widget_queue_resize (GTK_WIDGET (tree_view));
diff --git a/src/ui/gui/psppire-data-editor.c b/src/ui/gui/psppire-data-editor.c
index b5f2273..7db408b 100644
--- a/src/ui/gui/psppire-data-editor.c
+++ b/src/ui/gui/psppire-data-editor.c
@@ -695,6 +695,7 @@ psppire_data_editor_init (PsppireDataEditor *de)
 
   de->font = NULL;
   de->ui_manager = NULL;
+  de->old_vbox_widget = NULL;
 
   g_object_set (de, "tab-pos", GTK_POS_BOTTOM, NULL);
 
@@ -813,12 +814,17 @@ psppire_data_editor_split_window (PsppireDataEditor *de, gboolean split)
     PSPP_SHEET_VIEW (de->data_sheets[0]));
 
   disconnect_data_sheets (de);
-  gtk_widget_destroy (de->datasheet_vbox_widget);
+  if (de->old_vbox_widget)
+    g_object_unref (de->old_vbox_widget);
+  de->old_vbox_widget = de->datasheet_vbox_widget;
+  g_object_ref (de->old_vbox_widget);
+  gtk_container_remove (de->vbox, de->datasheet_vbox_widget);
 
   if (split)
     de->datasheet_vbox_widget = make_split_datasheet (de, grid_lines);
   else
     de->datasheet_vbox_widget = make_single_datasheet (de, grid_lines);
+
   psppire_data_editor_refresh_model (de);
 
   gtk_box_pack_start (GTK_BOX (de->vbox), de->datasheet_vbox_widget,
diff --git a/src/ui/gui/psppire-data-editor.h b/src/ui/gui/psppire-data-editor.h
index 879953d..3566660 100644
--- a/src/ui/gui/psppire-data-editor.h
+++ b/src/ui/gui/psppire-data-editor.h
@@ -72,6 +72,7 @@ struct _PsppireDataEditor
 
   /* UI manager for whichever var or data sheet is currently in use. */
   GtkUIManager *ui_manager;
+  GtkWidget *old_vbox_widget;
 };
 
 struct _PsppireDataEditorClass
diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c
index 3d97745..f64c334 100644
--- a/src/ui/gui/psppire-data-window.c
+++ b/src/ui/gui/psppire-data-window.c
@@ -1176,12 +1176,6 @@ psppire_data_window_remove_ui (PsppireDataWindow *pdw,
 
   gtk_window_remove_accel_group (GTK_WINDOW (pdw),
                                  gtk_ui_manager_get_accel_group (uim));
-
-  /* Our caller unrefs 'uim', possibly causing 'uim' to be freed.  The
-     following call appears to be necessary to ensure that pdw->ui_manager
-     drops all references to 'uim'.  Otherwise, I get valgrind complaints about
-     access to freed memory (and segfaults) on e.g. Windows|Split View.  */
-  gtk_ui_manager_ensure_update (pdw->ui_manager);
 }
 
 GtkWidget*
-- 
1.7.2.5

From a99b6902c1195a795a3c06cd7f50bbc6ae6b2175 Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Sat, 7 Jul 2012 07:14:53 +0200
Subject: [PATCH 08/11] PsppSheetView resize handler:  Do nothing if the widget is not realized

This seems to avoid the occasional GtkCritical that I get.
---
 src/ui/gui/pspp-sheet-view.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/src/ui/gui/pspp-sheet-view.c b/src/ui/gui/pspp-sheet-view.c
index 51ceafc..0282548 100644
--- a/src/ui/gui/pspp-sheet-view.c
+++ b/src/ui/gui/pspp-sheet-view.c
@@ -5361,6 +5361,9 @@ do_presize_handler (PsppSheetView *tree_view)
   validate_visible_area (tree_view);
   tree_view->priv->presize_handler_timer = 0;
 
+  if (! gtk_widget_get_realized (GTK_WIDGET (tree_view)))
+    return FALSE;
+
   gtk_widget_size_request (GTK_WIDGET (tree_view), &requisition);
 
   tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
-- 
1.7.2.5

From 7096934e6c6cb2f0eac25529dbe98c23bcf3e210 Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Sat, 7 Jul 2012 09:30:17 +0200
Subject: [PATCH 09/11] PsppireDataWindow: Deal with ui_manager in dispose routine

---
 src/ui/gui/psppire-data-window.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c
index f64c334..3db9b28 100644
--- a/src/ui/gui/psppire-data-window.c
+++ b/src/ui/gui/psppire-data-window.c
@@ -1053,6 +1053,13 @@ psppire_data_window_dispose (GObject *object)
 {
   PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
 
+  if (dw->uim)
+    {
+      psppire_data_window_remove_ui (dw, dw->uim, dw->merge_id);
+      g_object_unref (dw->uim);
+      dw->uim = NULL;
+    }
+
   if (dw->builder != NULL)
     {
       g_object_unref (dw->builder);
-- 
1.7.2.5

From 23b336c9b5317108b930f79b1afee75814dc4664 Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Sat, 7 Jul 2012 09:34:18 +0200
Subject: [PATCH 10/11] Delete module customentry

This is no longer used, so am removing it completely.
---
 src/ui/gui/automake.mk   |    2 -
 src/ui/gui/customentry.c |  443 ----------------------------------------------
 src/ui/gui/customentry.h |  106 -----------
 3 files changed, 0 insertions(+), 551 deletions(-)
 delete mode 100644 src/ui/gui/customentry.c
 delete mode 100644 src/ui/gui/customentry.h

diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk
index aa1047b..14beeb9 100644
--- a/src/ui/gui/automake.mk
+++ b/src/ui/gui/automake.mk
@@ -176,8 +176,6 @@ src_ui_gui_psppire_SOURCES = \
 	src/ui/gui/count-dialog.h \
 	src/ui/gui/crosstabs-dialog.c \
 	src/ui/gui/crosstabs-dialog.h \
-	src/ui/gui/customentry.c \
-	src/ui/gui/customentry.h \
 	src/ui/gui/dialog-common.c \
 	src/ui/gui/dialog-common.h \
 	src/ui/gui/dict-display.h \
diff --git a/src/ui/gui/customentry.c b/src/ui/gui/customentry.c
deleted file mode 100644
index b7d0ce2..0000000
--- a/src/ui/gui/customentry.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2005, 2007, 2010, 2011  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/>. */
-
-/*
-   This widget is a subclass of GtkEntry.  It's an entry widget with a
-   button on the right hand side.
-
-   This code is heavily based upon the GtkSpinButton widget.  Therefore
-   the copyright notice of that code is pasted below.
-
-   Please note however,  this code is covered by the GPL, not the LGPL.
-*/
-
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * GtkSpinButton widget for GTK+
- * Copyright (C) 1998 Lars Hamann and Stefan Jeske
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-
-/*
- * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
- * file for a list of people on the GTK+ Team.  See the ChangeLog
- * files for a list of changes.  These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#include <config.h>
-
-#include <gtk/gtk.h>
-#include "customentry.h"
-#include "helper.h"
-
-static void psppire_custom_entry_class_init          (PsppireCustomEntryClass *klass);
-static void psppire_custom_entry_init                (PsppireCustomEntry      *ce);
-
-static GtkEntryClass *parent_class = NULL;
-
-/* Signals */
-enum
-{
-  CLICKED,
-  n_SIGNALS
-};
-
-
-static guint custom_entry_signals[n_SIGNALS] = {0};
-
-
-GType
-psppire_custom_entry_get_type (void)
-{
-  static GType ce_type = 0;
-
-  if (!ce_type)
-    {
-      static const GTypeInfo ce_info =
-	{
-	  sizeof (PsppireCustomEntryClass),
-	  NULL, /* base_init */
-	  NULL, /* base_finalize */
-	  (GClassInitFunc) psppire_custom_entry_class_init,
-	  NULL, /* class_finalize */
-	  NULL, /* class_data */
-	  sizeof (PsppireCustomEntry),
-	  0,
-	  (GInstanceInitFunc) psppire_custom_entry_init,
-	};
-
-      ce_type = g_type_register_static (GTK_TYPE_ENTRY, "PsppireCustomEntry",
-					&ce_info, 0);
-    }
-
-  return ce_type;
-}
-
-
-static void
-psppire_custom_entry_map (GtkWidget *widget)
-{
-  if (gtk_widget_get_realized (widget) && !gtk_widget_get_mapped (widget))
-    {
-      GTK_WIDGET_CLASS (parent_class)->map (widget);
-      gdk_window_show (PSPPIRE_CUSTOM_ENTRY (widget)->panel);
-    }
-}
-
-static void
-psppire_custom_entry_unmap (GtkWidget *widget)
-{
-  if (gtk_widget_get_mapped (widget))
-    {
-      gdk_window_hide (PSPPIRE_CUSTOM_ENTRY (widget)->panel);
-      GTK_WIDGET_CLASS (parent_class)->unmap (widget);
-    }
-}
-
-static gint psppire_custom_entry_get_button_width (PsppireCustomEntry *custom_entry);
-
-static void
-psppire_custom_entry_realize (GtkWidget *widget)
-{
-  PsppireCustomEntry *custom_entry;
-  GdkWindowAttr attributes;
-  gint attributes_mask;
-  guint real_width;
-  gint button_size ;
-
-  custom_entry = PSPPIRE_CUSTOM_ENTRY (widget);
-
-  button_size = psppire_custom_entry_get_button_width (custom_entry);
-
-  real_width = widget->allocation.width;
-  widget->allocation.width -= button_size + 2 * widget->style->xthickness;
-  gtk_widget_set_events (widget, gtk_widget_get_events (widget) |
-			 GDK_KEY_RELEASE_MASK);
-  GTK_WIDGET_CLASS (parent_class)->realize (widget);
-
-  widget->allocation.width = real_width;
-
-  attributes.window_type = GDK_WINDOW_CHILD;
-  attributes.wclass = GDK_INPUT_OUTPUT;
-  attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
-  attributes.event_mask = gtk_widget_get_events (widget);
-  attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
-    | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
-    | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
-
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-
-  attributes.x = (widget->allocation.x +
-		  widget->allocation.width - button_size -
-		  2 * widget->style->xthickness);
-  attributes.y = widget->allocation.y + (widget->allocation.height -
-					 widget->requisition.height) / 2;
-  attributes.width = button_size + 2 * widget->style->xthickness;
-  attributes.height = widget->requisition.height;
-
-  custom_entry->panel = gdk_window_new (gtk_widget_get_parent_window (widget),
-					&attributes, attributes_mask);
-  gdk_window_set_user_data (custom_entry->panel, widget);
-
-  gtk_style_set_background (widget->style, custom_entry->panel, GTK_STATE_NORMAL);
-
-
-  gtk_widget_queue_resize (GTK_WIDGET (custom_entry));
-}
-
-
-#define MIN_BUTTON_WIDTH  6
-
-static gint
-psppire_custom_entry_get_button_width (PsppireCustomEntry *custom_entry)
-{
-  const gint size = pango_font_description_get_size
-    (GTK_WIDGET (custom_entry)->style->font_desc);
-
-  gint button_width = MAX (PANGO_PIXELS (size), MIN_BUTTON_WIDTH);
-
-  return button_width - button_width % 2; /* force even */
-}
-
-/**
- * custom_entry_get_shadow_type:
- * @custom_entry: a #PsppireCustomEntry
- *
- * Convenience function to Get the shadow type from the underlying widget's
- * style.
- *
- * Return value: the #GtkShadowType
- **/
-static gint
-psppire_custom_entry_get_shadow_type (PsppireCustomEntry *custom_entry)
-{
-  GtkShadowType rc_shadow_type;
-
-  gtk_widget_style_get (GTK_WIDGET (custom_entry), "shadow_type", &rc_shadow_type, NULL);
-
-  return rc_shadow_type;
-}
-
-
-static void
-psppire_custom_entry_unrealize (GtkWidget *widget)
-{
-  PsppireCustomEntry *ce = PSPPIRE_CUSTOM_ENTRY (widget);
-
-  GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
-
-  if (ce->panel)
-    {
-      gdk_window_set_user_data (ce->panel, NULL);
-      gdk_window_destroy (ce->panel);
-      ce->panel = NULL;
-    }
-}
-
-
-static void
-psppire_custom_entry_redraw (PsppireCustomEntry *custom_entry)
-{
-  GtkWidget *widget;
-
-  widget = GTK_WIDGET (custom_entry);
-
-  if (gtk_widget_is_drawable (widget))
-    {
-      gtk_widget_queue_draw (widget);
-
-      /* We must invalidate the panel window ourselves, because it
-       * is not a child of widget->window
-       */
-      gdk_window_invalidate_rect (custom_entry->panel, NULL, TRUE);
-    }
-}
-
-
-static gint
-psppire_custom_entry_expose (GtkWidget      *widget,
-		     GdkEventExpose *event)
-{
-  PsppireCustomEntry *ce = PSPPIRE_CUSTOM_ENTRY (widget);
-
-  g_return_val_if_fail (PSPPIRE_IS_CUSTOM_ENTRY (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (gtk_widget_is_drawable (widget))
-    {
-      gboolean is_editable;
-      GtkShadowType shadow_type;
-      GdkRectangle rect;
-
-      rect.x = 0;
-      rect.y = 0;
-
-      if (event->window != ce->panel)
-	GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
-
-      gdk_drawable_get_size (ce->panel, &rect.width, &rect.height);
-
-      gdk_window_begin_paint_rect (ce->panel, &rect);
-
-
-      shadow_type = psppire_custom_entry_get_shadow_type (ce);
-
-      g_object_get (widget, "editable", &is_editable, NULL);
-
-      gtk_paint_box (widget->style, ce->panel,
-		     is_editable ? GTK_STATE_NORMAL: GTK_STATE_INSENSITIVE,
-		     shadow_type,
-		     NULL, widget, "customentry",
-		     rect.x, rect.y, rect.width, rect.height);
-
-
-      gdk_window_end_paint (ce->panel);
-    }
-
-  return FALSE;
-}
-
-
-static gint
-psppire_custom_entry_button_press (GtkWidget      *widget,
-			   GdkEventButton *event);
-
-static void
-psppire_custom_entry_size_allocate (GtkWidget     *widget,
-			    GtkAllocation *allocation);
-
-
-
-static void
-psppire_custom_entry_class_init (PsppireCustomEntryClass *klass)
-{
-  GObjectClass     *gobject_class = G_OBJECT_CLASS (klass);
-
-  GtkWidgetClass   *widget_class;
-  GtkEntryClass   *entry_class;
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  widget_class   = (GtkWidgetClass*)   klass;
-  entry_class   = (GtkEntryClass*)   klass;
-
-  widget_class->map = psppire_custom_entry_map;
-  widget_class->unmap = psppire_custom_entry_unmap;
-
-  widget_class->realize = psppire_custom_entry_realize;
-  widget_class->unrealize = psppire_custom_entry_unrealize;
-
-  widget_class->expose_event = psppire_custom_entry_expose;
-  widget_class->button_press_event = psppire_custom_entry_button_press;
-
-  widget_class->size_allocate = psppire_custom_entry_size_allocate;
-
-
-  gtk_widget_class_install_style_property_parser
-    (widget_class,
-     g_param_spec_enum ("shadow_type",
-			"Shadow Type",
-			"Style of bevel around the custom entry button",
-			GTK_TYPE_SHADOW_TYPE,
-			GTK_SHADOW_ETCHED_IN,
-			G_PARAM_READABLE),
-     gtk_rc_property_parse_enum);
-
-  custom_entry_signals[CLICKED] =
-    g_signal_new ("clicked",
-		  G_TYPE_FROM_CLASS (gobject_class),
-		  G_SIGNAL_RUN_LAST,
-		  0,
-		  NULL, NULL,
-		  g_cclosure_marshal_VOID__VOID,
-		  G_TYPE_NONE,
-		  0);
-
-
-}
-
-static void
-psppire_custom_entry_init (PsppireCustomEntry *ce)
-{
-}
-
-GtkWidget*
-psppire_custom_entry_new ()
-{
-  return GTK_WIDGET (g_object_new (psppire_custom_entry_get_type (), NULL));
-}
-
-
-
-static gint
-psppire_custom_entry_button_press (GtkWidget *widget,
-				   GdkEventButton *event)
-{
-  PsppireCustomEntry *ce = PSPPIRE_CUSTOM_ENTRY (widget);
-
-  if (event->window == ce->panel)
-    {
-      gboolean is_editable ;
-      if (!gtk_widget_has_focus (widget))
-	gtk_widget_grab_focus (widget);
-
-      g_object_get (ce, "editable", &is_editable, NULL);
-
-      if ( event->button == 1 && is_editable )
-	g_signal_emit (widget, custom_entry_signals[CLICKED], 0);
-
-    }
-  else
-    return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event);
-
-  return FALSE;
-}
-
-
-
-static void
-psppire_custom_entry_size_allocate (GtkWidget     *widget,
-			    GtkAllocation *allocation)
-{
-  PsppireCustomEntry *ce;
-  GtkAllocation entry_allocation;
-  GtkAllocation panel_allocation;
-  gint button_width;
-  gint panel_width;
-
-  g_return_if_fail (PSPPIRE_IS_CUSTOM_ENTRY (widget));
-  g_return_if_fail (allocation != NULL);
-
-  ce = PSPPIRE_CUSTOM_ENTRY (widget);
-  button_width = psppire_custom_entry_get_button_width (ce);
-  panel_width = button_width + 2 * widget->style->xthickness;
-
-  widget->allocation = *allocation;
-
-  entry_allocation = *allocation;
-  entry_allocation.width -= panel_width;
-
-  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-    {
-      entry_allocation.x += panel_width;
-      panel_allocation.x = allocation->x;
-    }
-  else
-    {
-      panel_allocation.x = allocation->x + allocation->width - panel_width;
-    }
-
-  panel_allocation.width = panel_width;
-  panel_allocation.height = MIN (widget->requisition.height, allocation->height);
-
-  panel_allocation.y = allocation->y + (allocation->height -
-					panel_allocation.height) / 2;
-
-  GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, &entry_allocation);
-
-  if (gtk_widget_get_realized (widget))
-    {
-      gdk_window_move_resize (PSPPIRE_CUSTOM_ENTRY (widget)->panel,
-			      panel_allocation.x,
-			      panel_allocation.y,
-			      panel_allocation.width,
-			      panel_allocation.height);
-    }
-
-  psppire_custom_entry_redraw (ce);
-}
-
-
-
-
-
diff --git a/src/ui/gui/customentry.h b/src/ui/gui/customentry.h
deleted file mode 100644
index 123ab8c..0000000
--- a/src/ui/gui/customentry.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2005  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/>. */
-
-/*
-   This widget is a subclass of GtkEntry.  It's an entry widget with a
-   button on the right hand side.
-
-   This code is heavily based upon the GtkSpinButton widget.  Therefore
-   the copyright notice of that code is pasted below.
-
-   Please note however,  this code is covered by the GPL, not the LGPL.
-*/
-
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * GtkSpinButton widget for GTK+
- * Copyright (C) 1998 Lars Hamann and Stefan Jeske
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
- * file for a list of people on the GTK+ Team.  See the ChangeLog
- * files for a list of changes.  These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-
-#ifndef __PSPPIRE_CUSTOM_ENTRY_H__
-#define __PSPPIRE_CUSTOM_ENTRY_H__
-
-
-#include <glib.h>
-#include <glib-object.h>
-
-
-GType psppire_custom_entry_get_type (void);
-
-G_BEGIN_DECLS
-
-#define PSPPIRE_CUSTOM_ENTRY_TYPE (psppire_custom_entry_get_type ())
-
-#define PSPPIRE_CUSTOM_ENTRY(obj)            \
-     (G_TYPE_CHECK_INSTANCE_CAST ((obj),PSPPIRE_CUSTOM_ENTRY_TYPE, PsppireCustomEntry))
-
-#define PSPPIRE_CUSTOM_ENTRY_CLASS(klass)    \
-     (G_TYPE_CHECK_CLASS_CAST ((klass),PSPPIRE_CUSTOM_ENTRY_TYPE, PsppireCustomEntryClass))
-
-#define PSPPIRE_IS_CUSTOM_ENTRY(obj)         \
-     (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_CUSTOM_ENTRY_TYPE))
-
-#define IS_PSPPIRE_CUSTOM_ENTRY_CLASS(klass) \
-     (G_TYPE_CHECK_CLASS_TYPE ((klass),  PSPPIRE_CUSTOM_ENTRY_TYPE))
-
-
-typedef struct _PsppireCustomEntry       PsppireCustomEntry;
-typedef struct _PsppireCustomEntryClass  PsppireCustomEntryClass;
-
-struct _PsppireCustomEntry
-{
-  GtkEntry entry;
-
-  GdkWindow *panel;
-};
-
-struct _PsppireCustomEntryClass
-{
-  GtkEntryClass parent_class;
-
-  void (*clicked)  (PsppireCustomEntry *spin_button);
-
-};
-
-GType          custom_entry_get_type        (void);
-GtkWidget*     custom_entry_new             (void);
-
-G_END_DECLS
-
-#endif /* __PSPPIRE_CUSTOM_ENTRY_H__ */
-- 
1.7.2.5

From fc937c9638dc76d39250bfd3ec06d7693a8b2a37 Mon Sep 17 00:00:00 2001
From: John Darrington <j...@darrington.wattle.id.au>
Date: Sat, 7 Jul 2012 09:39:21 +0200
Subject: [PATCH 11/11] PsppSheetView unrealize: Call parent method before any other operation

If this is not done, then gtk_widget_get_realized returns true, during
the unrealize execution, leading to mutual recursion.
---
 src/ui/gui/pspp-sheet-view.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/ui/gui/pspp-sheet-view.c b/src/ui/gui/pspp-sheet-view.c
index 0282548..38eeb5d 100644
--- a/src/ui/gui/pspp-sheet-view.c
+++ b/src/ui/gui/pspp-sheet-view.c
@@ -1519,6 +1519,8 @@ pspp_sheet_view_unrealize (GtkWidget *widget)
   PsppSheetViewPrivate *priv = tree_view->priv;
   GList *list;
 
+  GTK_WIDGET_CLASS (pspp_sheet_view_parent_class)->unrealize (widget);
+
   if (priv->scroll_timeout != 0)
     {
       g_source_remove (priv->scroll_timeout);
@@ -1595,8 +1597,6 @@ pspp_sheet_view_unrealize (GtkWidget *widget)
 	}
       tree_view->priv->columns = NULL;
     }
-
-  GTK_WIDGET_CLASS (pspp_sheet_view_parent_class)->unrealize (widget);
 }
 
 /* GtkWidget::size_request helper */
-- 
1.7.2.5

Attachment: signature.asc
Description: Digital signature

_______________________________________________
pspp-dev mailing list
pspp-dev@gnu.org
https://lists.gnu.org/mailman/listinfo/pspp-dev

Reply via email to