From: Ben Pfaff Date: Fri, 29 Apr 2011 13:59:55 +0000 (-0700) Subject: gui: Eliminate dataset-related global variables. X-Git-Tag: v0.7.8~10 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp-builds.git;a=commitdiff_plain;h=119d57cbddc317d9bde6831787026c84a6e7415f gui: Eliminate dataset-related global variables. This should make it easier to introduce support for multiple datasets later. --- diff --git a/src/ui/gui/executor.c b/src/ui/gui/executor.c index 584b1376..6a3f1e15 100644 --- a/src/ui/gui/executor.c +++ b/src/ui/gui/executor.c @@ -27,9 +27,6 @@ #include "ui/gui/psppire-data-store.h" #include "ui/gui/psppire-output-window.h" -extern struct dataset *the_dataset; -extern PsppireDataStore *the_data_store; - /* Lazy casereader callback function used by execute_syntax. */ static struct casereader * create_casereader_from_data_store (void *data_store_) @@ -62,14 +59,14 @@ execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader) needed. If the data store casereader is never needed, then it is reused the next time syntax is run, without wrapping it in another layer. */ - proto = psppire_data_store_get_proto (the_data_store); - case_cnt = psppire_data_store_get_case_count (the_data_store); + proto = psppire_data_store_get_proto (window->data_store); + case_cnt = psppire_data_store_get_case_count (window->data_store); reader = lazy_casereader_create (proto, case_cnt, create_casereader_from_data_store, - the_data_store, &lazy_serial); - dataset_set_source (the_dataset, reader); + window->data_store, &lazy_serial); + dataset_set_source (window->dataset, reader); - g_return_val_if_fail (dataset_has_source (the_dataset), FALSE); + g_return_val_if_fail (dataset_has_source (window->dataset), FALSE); lexer = lex_create (); psppire_set_lexer (lexer); @@ -77,7 +74,7 @@ execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader) for (;;) { - enum cmd_result result = cmd_parse (lexer, the_dataset); + enum cmd_result result = cmd_parse (lexer, window->dataset); if ( cmd_result_is_failure (result)) { @@ -90,14 +87,14 @@ execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader) break; } - proc_execute (the_dataset); + proc_execute (window->dataset); - psppire_dict_replace_dictionary (the_data_store->dict, - dataset_dict (the_dataset)); + psppire_dict_replace_dictionary (window->data_store->dict, + dataset_dict (window->dataset)); - reader = dataset_steal_source (the_dataset); + reader = dataset_steal_source (window->dataset); if (!lazy_casereader_destroy (reader, lazy_serial)) - psppire_data_store_set_reader (the_data_store, reader); + psppire_data_store_set_reader (window->data_store, reader); /* Destroy the lexer only after obtaining the dataset, because the dataset might depend on the lexer, if the casereader specifies inline data. (In diff --git a/src/ui/gui/psppire-data-editor.c b/src/ui/gui/psppire-data-editor.c index 99bc9074..c5a3cd36 100644 --- a/src/ui/gui/psppire-data-editor.c +++ b/src/ui/gui/psppire-data-editor.c @@ -89,6 +89,7 @@ psppire_data_editor_dispose (GObject *obj) if (de->dispose_has_run) return; + g_object_unref (de->data_window); g_object_unref (de->data_store); g_object_unref (de->var_store); @@ -195,6 +196,7 @@ traverse_cell_callback (PsppireSheet *sheet, enum { PROP_0, + PROP_DATA_WINDOW, PROP_DATA_STORE, PROP_VAR_STORE, PROP_VS_ROW_MENU, @@ -374,6 +376,10 @@ psppire_data_editor_set_property (GObject *object, case PROP_SPLIT_WINDOW: psppire_data_editor_split_window (de, g_value_get_boolean (value)); break; + case PROP_DATA_WINDOW: + de->data_window = g_value_get_pointer (value); + g_object_ref (de->data_window); + break; case PROP_DATA_STORE: if ( de->data_store) g_object_unref (de->data_store); de->data_store = g_value_get_pointer (value); @@ -501,6 +507,9 @@ psppire_data_editor_get_property (GObject *object, case PROP_SPLIT_WINDOW: g_value_set_boolean (value, de->split); break; + case PROP_DATA_WINDOW: + g_value_set_pointer (value, de->data_window); + break; case PROP_DATA_STORE: g_value_set_pointer (value, de->data_store); break; @@ -534,6 +543,7 @@ psppire_data_editor_get_property (GObject *object, static void psppire_data_editor_class_init (PsppireDataEditorClass *klass) { + GParamSpec *data_window_spec ; GParamSpec *data_store_spec ; GParamSpec *var_store_spec ; GParamSpec *column_menu_spec; @@ -556,6 +566,16 @@ psppire_data_editor_class_init (PsppireDataEditorClass *klass) + data_window_spec = + g_param_spec_pointer ("data-window", + "Data Window", + "A pointer to the data window associated with this editor", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_READABLE ); + + g_object_class_install_property (object_class, + PROP_DATA_WINDOW, + data_window_spec); + data_store_spec = g_param_spec_pointer ("data-store", "Data Store", @@ -1008,13 +1028,15 @@ psppire_data_editor_init (PsppireDataEditor *de) GtkWidget* -psppire_data_editor_new (PsppireVarStore *var_store, +psppire_data_editor_new (PsppireDataWindow *data_window, + PsppireVarStore *var_store, PsppireDataStore *data_store) { return g_object_new (PSPPIRE_DATA_EDITOR_TYPE, - "var-store", var_store, - "data-store", data_store, - NULL); + "data-window", data_window, + "var-store", var_store, + "data-store", data_store, + NULL); } @@ -1254,7 +1276,7 @@ do_sort (PsppireDataEditor *de, int var, gboolean descend) syntax = g_strdup_printf ("SORT CASES BY %s%s.", var_get_name (v), descend ? " (D)" : ""); - g_free (execute_syntax_string (psppire_default_data_window (), syntax)); + g_free (execute_syntax_string (de->data_window, syntax)); } diff --git a/src/ui/gui/psppire-data-editor.h b/src/ui/gui/psppire-data-editor.h index 0c555a98..f6f55d7c 100644 --- a/src/ui/gui/psppire-data-editor.h +++ b/src/ui/gui/psppire-data-editor.h @@ -48,6 +48,7 @@ struct _PsppireDataEditor GtkWidget *cell_ref_entry; GtkWidget *datum_entry; GtkWidget *var_sheet; + struct _PsppireDataWindow *data_window; PsppireDataStore *data_store; PsppireVarStore *var_store; @@ -74,7 +75,7 @@ struct _PsppireDataEditorClass GType psppire_data_editor_get_type (void); -GtkWidget* psppire_data_editor_new (PsppireVarStore *, PsppireDataStore *); +GtkWidget* psppire_data_editor_new (struct _PsppireDataWindow *, PsppireVarStore *, PsppireDataStore *); void psppire_data_editor_clip_copy (PsppireDataEditor *); void psppire_data_editor_clip_paste (PsppireDataEditor *); void psppire_data_editor_clip_cut (PsppireDataEditor *); diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c index 74c4ca69..7e248f8e 100644 --- a/src/ui/gui/psppire-data-window.c +++ b/src/ui/gui/psppire-data-window.c @@ -66,7 +66,7 @@ #define _(msgid) gettext (msgid) #define N_(msgid) msgid - +static PsppireDataWindow *the_data_window; static void psppire_data_window_class_init (PsppireDataWindowClass *class); static void psppire_data_window_init (PsppireDataWindow *data_editor); @@ -75,6 +75,14 @@ static void psppire_data_window_init (PsppireDataWindow *data_edit static void psppire_data_window_iface_init (PsppireWindowIface *iface); static void psppire_data_window_dispose (GObject *object); +static void psppire_data_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void psppire_data_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); GType psppire_data_window_get_type (void) @@ -118,6 +126,10 @@ psppire_data_window_get_type (void) static GObjectClass *parent_class ; +enum { + PROP_DATASET = 1 +}; + static void psppire_data_window_class_init (PsppireDataWindowClass *class) { @@ -126,14 +138,17 @@ psppire_data_window_class_init (PsppireDataWindowClass *class) parent_class = g_type_class_peek_parent (class); object_class->dispose = psppire_data_window_dispose; + object_class->set_property = psppire_data_window_set_property; + object_class->get_property = psppire_data_window_get_property; + + g_object_class_install_property ( + object_class, PROP_DATASET, + g_param_spec_pointer ("dataset", "Dataset", + "'struct datset *' represented by the window", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); } - -extern PsppireVarStore *the_var_store; -extern struct dataset *the_dataset; -extern PsppireDataStore *the_data_store ; - extern GtkRecentManager *the_recent_mgr; static void @@ -771,12 +786,12 @@ toggle_split_window (PsppireDataWindow *de, GtkToggleAction *ta) static void -file_quit (void) +file_quit (PsppireDataWindow *de) { /* FIXME: Need to be more intelligent here. Give the user the opportunity to save any unsaved data. */ - g_object_unref (the_data_store); + g_object_unref (de->data_store); psppire_quit (); } @@ -907,8 +922,29 @@ connect_action (PsppireDataWindow *dw, const char *action_name, return action; } +/* Initializes as much of a PsppireDataWindow as we can and must before the + dataset has been set. + + In particular, the 'menu' member is required in case the "filename" property + is set before the "dataset" property: otherwise PsppireWindow will try to + modify the menu as part of the "filename" property_set() function and end up + with a Gtk-CRITICAL since 'menu' is NULL. */ static void psppire_data_window_init (PsppireDataWindow *de) +{ + GtkUIManager *uim; + + de->builder = builder_new ("data-editor.ui"); + + uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER)); + + PSPPIRE_WINDOW (de)->menu = + GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar/windows/windows_minimise_all")->parent); +} + +static void +psppire_data_window_finish_init (PsppireDataWindow *de, + struct dataset *ds) { static const struct dataset_callbacks cbs = { @@ -916,33 +952,38 @@ psppire_data_window_init (PsppireDataWindow *de) transformation_change_callback, /* transformations_changed */ }; - PsppireVarStore *vs; - PsppireDict *dict = NULL; + PsppireDict *dict; GtkWidget *menubar; GtkWidget *hb ; GtkWidget *sb ; GtkWidget *box = gtk_vbox_new (FALSE, 0); - de->builder = builder_new ("data-editor.ui"); + + de->dataset = ds; + dict = psppire_dict_new_from_dict (dataset_dict (ds)); + de->var_store = psppire_var_store_new (dict); + de->data_store = psppire_data_store_new (dict); + psppire_data_store_set_reader (de->data_store, NULL); menubar = get_widget_assert (de->builder, "menubar"); hb = get_widget_assert (de->builder, "handlebox1"); sb = get_widget_assert (de->builder, "status-bar"); de->data_editor = - PSPPIRE_DATA_EDITOR (psppire_data_editor_new (the_var_store, the_data_store)); + PSPPIRE_DATA_EDITOR (psppire_data_editor_new (de, de->var_store, + de->data_store)); - g_signal_connect_swapped (the_data_store, "case-changed", + g_signal_connect_swapped (de->data_store, "case-changed", G_CALLBACK (set_unsaved), de); - g_signal_connect_swapped (the_data_store, "case-inserted", + g_signal_connect_swapped (de->data_store, "case-inserted", G_CALLBACK (set_unsaved), de); - g_signal_connect_swapped (the_data_store, "cases-deleted", + g_signal_connect_swapped (de->data_store, "cases-deleted", G_CALLBACK (set_unsaved), de); - dataset_set_callbacks (the_dataset, &cbs, de); + dataset_set_callbacks (de->dataset, &cbs, de); connect_help (de->builder); @@ -964,12 +1005,6 @@ psppire_data_window_init (PsppireDataWindow *de) g_signal_connect_swapped (de->data_editor, "data-available-changed", G_CALLBACK (set_paste_menuitem_sensitivity), de); - vs = the_var_store; - - g_assert(vs); /* Traps a possible bug in w32 build */ - - g_object_get (vs, "dictionary", &dict, NULL); - g_signal_connect (dict, "weight-changed", G_CALLBACK (on_weight_change), de); @@ -1183,9 +1218,6 @@ psppire_data_window_init (PsppireDataWindow *de) GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER)); merge_help_menu (uim); - - PSPPIRE_WINDOW (de)->menu = - GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar/windows/windows_minimise_all")->parent); } { @@ -1215,6 +1247,8 @@ psppire_data_window_init (PsppireDataWindow *de) gtk_widget_show (GTK_WIDGET (de->data_editor)); gtk_widget_show (box); + + the_data_window = de; } static void @@ -1228,17 +1262,62 @@ psppire_data_window_dispose (GObject *object) dw->builder = NULL; } + if (the_data_window == dw) + the_data_window = NULL; + G_OBJECT_CLASS (parent_class)->dispose (object); } +static void +psppire_data_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object); + + switch (prop_id) + { + case PROP_DATASET: + psppire_data_window_finish_init (window, g_value_get_pointer (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + }; +} + +static void +psppire_data_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object); + + switch (prop_id) + { + case PROP_DATASET: + g_value_set_pointer (value, window->dataset); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + }; +} + + GtkWidget* -psppire_data_window_new (void) +psppire_data_window_new (struct dataset *ds) { - return GTK_WIDGET (g_object_new (psppire_data_window_get_type (), - /* TRANSLATORS: This will form a filename. Please avoid whitespace. */ - "filename", _("PSPP-data"), - "description", _("Data Editor"), - NULL)); + return GTK_WIDGET ( + g_object_new ( + psppire_data_window_get_type (), + /* TRANSLATORS: This will form a filename. Please avoid whitespace. */ + "filename", _("PSPP-data"), + "description", _("Data Editor"), + "dataset", ds, + NULL)); } @@ -1249,3 +1328,11 @@ psppire_data_window_iface_init (PsppireWindowIface *iface) iface->load = load_file; } + +PsppireDataWindow * +psppire_default_data_window (void) +{ + if (the_data_window == NULL) + gtk_widget_show (psppire_data_window_new (dataset_create ())); + return the_data_window; +} diff --git a/src/ui/gui/psppire-data-window.h b/src/ui/gui/psppire-data-window.h index 1e024939..01002543 100644 --- a/src/ui/gui/psppire-data-window.h +++ b/src/ui/gui/psppire-data-window.h @@ -26,6 +26,8 @@ #include "ui/gui/psppire-window.h" #include "ui/gui/psppire-data-editor.h" +struct dataset; + G_BEGIN_DECLS #define PSPPIRE_DATA_WINDOW_TYPE (psppire_data_window_get_type ()) @@ -50,6 +52,9 @@ struct _PsppireDataWindow PsppireDataEditor *data_editor; GtkBuilder *builder; + PsppireVarStore *var_store; + struct dataset *dataset; + PsppireDataStore *data_store; GtkAction *invoke_goto_dialog; @@ -68,7 +73,8 @@ struct _PsppireDataWindowClass }; GType psppire_data_window_get_type (void); -GtkWidget* psppire_data_window_new (void); +GtkWidget* psppire_data_window_new (struct dataset *); +PsppireDataWindow *psppire_default_data_window (void); G_END_DECLS diff --git a/src/ui/gui/psppire-syntax-window.c b/src/ui/gui/psppire-syntax-window.c index 66292351..45b65212 100644 --- a/src/ui/gui/psppire-syntax-window.c +++ b/src/ui/gui/psppire-syntax-window.c @@ -17,20 +17,21 @@ #include #include -#include "executor.h" -#include "helper.h" - -#include -#include #include -#include "help-menu.h" -#include "psppire.h" -#include "psppire-data-window.h" -#include "psppire-window-register.h" -#include "psppire-syntax-window.h" +#include "language/lexer/lexer.h" +#include "libpspp/message.h" +#include "ui/gui/executor.h" +#include "ui/gui/help-menu.h" +#include "ui/gui/helper.h" +#include "ui/gui/psppire-data-window.h" +#include "ui/gui/psppire-syntax-window.h" +#include "ui/gui/psppire-syntax-window.h" +#include "ui/gui/psppire-window-register.h" +#include "ui/gui/psppire.h" +#include "ui/gui/psppire.h" -#include "xalloc.h" +#include "gl/xalloc.h" #include #define _(msgid) gettext (msgid) @@ -165,10 +166,7 @@ editor_execute_syntax (const PsppireSyntaxWindow *sw, GtkTextIter start, execute_syntax (psppire_default_data_window (), reader); } - - - /* Delete the currently selected text */ static void on_edit_delete (PsppireSyntaxWindow *sw) diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 1b11c119..80983e01 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -59,34 +59,19 @@ #include "gl/xalloc.h" #include "gl/relocatable.h" -GtkRecentManager *the_recent_mgr = 0; -PsppireDataStore *the_data_store = 0; -PsppireVarStore *the_var_store = 0; +GtkRecentManager *the_recent_mgr; static void create_icon_factory (void); - -struct dataset * the_dataset = NULL; - -static GtkWidget *the_data_window; - -static void load_data_file (const char *); - -static void -replace_casereader (struct casereader *s) -{ - psppire_data_store_set_reader (the_data_store, s); -} +static void load_data_file (PsppireDataWindow *, const char *); #define _(msgid) gettext (msgid) #define N_(msgid) msgid - - void initialize (const char *data_file) { - PsppireDict *dictionary = 0; + PsppireDataWindow *data_window; i18n_init (); @@ -96,19 +81,10 @@ initialize (const char *data_file) settings_init (); fh_init (); - the_dataset = dataset_create (); psppire_set_lexer (NULL); - dictionary = psppire_dict_new_from_dict (dataset_dict (the_dataset)); - bind_textdomain_codeset (PACKAGE, "UTF-8"); - /* Create the model for the var_sheet */ - the_var_store = psppire_var_store_new (dictionary); - - the_data_store = psppire_data_store_new (dictionary); - replace_casereader (NULL); - create_icon_factory (); psppire_output_window_setup (); @@ -123,13 +99,10 @@ initialize (const char *data_file) psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view); psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view); - the_data_window = psppire_data_window_new (); + data_window = psppire_default_data_window (); if (data_file != NULL) - load_data_file (data_file); - - execute_const_syntax_string (PSPPIRE_DATA_WINDOW (the_data_window), ""); - - gtk_widget_show (the_data_window); + load_data_file (data_window, data_file); + execute_const_syntax_string (data_window, ""); } @@ -141,12 +114,6 @@ de_initialize (void) i18n_done (); } -PsppireDataWindow * -psppire_default_data_window (void) -{ - return PSPPIRE_DATA_WINDOW (the_data_window); -} - static void func (gpointer key, gpointer value, gpointer data) { @@ -239,7 +206,7 @@ create_icon_factory (void) } static void -load_data_file (const char *arg) +load_data_file (PsppireDataWindow *window, const char *arg) { gchar *filename = NULL; gchar *utf8 = NULL; @@ -291,7 +258,7 @@ load_data_file (const char *arg) if ( filename == NULL) filename = xstrdup (arg); - psppire_window_load (PSPPIRE_WINDOW (the_data_window), filename); + psppire_window_load (PSPPIRE_WINDOW (window), filename); g_free (filename); } diff --git a/src/ui/gui/psppire.h b/src/ui/gui/psppire.h index 4b9cdbef..8817824a 100644 --- a/src/ui/gui/psppire.h +++ b/src/ui/gui/psppire.h @@ -17,8 +17,6 @@ #ifndef PSPPIRE_H #define PSPPIRE_H -#include "ui/gui/psppire-data-window.h" - struct lexer; void initialize (const char *data_file); @@ -29,6 +27,5 @@ void psppire_quit (void); const char * output_file_name (void); void psppire_set_lexer (struct lexer *); -PsppireDataWindow *psppire_default_data_window (void); #endif /* PSPPIRE_H */