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
signature.asc
Description: Digital signature
_______________________________________________ pspp-dev mailing list pspp-dev@gnu.org https://lists.gnu.org/mailman/listinfo/pspp-dev