From 4ea6e37d180c9412cbcd39afa48a516522e6dd71 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Thu, 26 Jul 2007 02:02:22 +0000 Subject: [PATCH] Patch #6086. Adds "transformation pending" state. Thanks to Ben for the review. --- src/data/ChangeLog | 5 ++++ src/data/procedure.c | 45 ++++++++++++++++++++++++++++++++---- src/data/procedure.h | 8 ++++--- src/ui/gui/ChangeLog | 8 +++++++ src/ui/gui/data-editor.c | 43 ++++++++++++++++++++++++++++++++++ src/ui/gui/data-editor.glade | 18 ++++++++++++++- src/ui/gui/helper.c | 12 ++-------- src/ui/gui/helper.h | 2 +- 8 files changed, 122 insertions(+), 19 deletions(-) diff --git a/src/data/ChangeLog b/src/data/ChangeLog index 70485fd9..ddf6e685 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,8 @@ +2007-07-26 John Darrington + + * procedure.c procedure.h: Added callbacks which get invoked whenever + a dataset's transformation chain changes. + 2007-07-24 Ben Pfaff Fix bug #6113. diff --git a/src/data/procedure.c b/src/data/procedure.c index 5f3ad206..6690490f 100644 --- a/src/data/procedure.c +++ b/src/data/procedure.c @@ -37,6 +37,7 @@ #include #include + struct dataset { /* Cases are read from source, their transformation variables are initialized, @@ -61,6 +62,11 @@ struct dataset { /* Callback which occurs whenever the DICT is replaced by a new one */ replace_dictionary_callback *replace_dict; + /* Callback which occurs whenever the transformation chain(s) have + been modified */ + transformation_change_callback_func *xform_callback; + void *xform_callback_aux; + /* If true, cases are discarded instead of being written to sink. */ bool discard_output; @@ -384,6 +390,10 @@ proc_capture_transformations (struct dataset *ds) assert (ds->temporary_trns_chain == NULL); chain = ds->permanent_trns_chain; ds->cur_trns_chain = ds->permanent_trns_chain = trns_chain_create (); + + if ( ds->xform_callback) + ds->xform_callback (false, ds->xform_callback_aux); + return chain; } @@ -394,6 +404,8 @@ void add_transformation (struct dataset *ds, trns_proc_func *proc, trns_free_func *free, void *aux) { trns_chain_append (ds->cur_trns_chain, NULL, proc, free, aux); + if ( ds->xform_callback) + ds->xform_callback (true, ds->xform_callback_aux); } /* Adds a transformation that processes a case with PROC and @@ -408,6 +420,9 @@ add_transformation_with_finalizer (struct dataset *ds, trns_free_func *free, void *aux) { trns_chain_append (ds->cur_trns_chain, finalize, proc, free, aux); + + if ( ds->xform_callback) + ds->xform_callback (true, ds->xform_callback_aux); } /* Returns the index of the next transformation. @@ -442,6 +457,9 @@ proc_start_temporary_transformations (struct dataset *ds) trns_chain_finalize (ds->permanent_trns_chain); ds->temporary_trns_chain = ds->cur_trns_chain = trns_chain_create (); + + if ( ds->xform_callback) + ds->xform_callback (true, ds->xform_callback_aux); } } @@ -483,6 +501,10 @@ proc_cancel_temporary_transformations (struct dataset *ds) trns_chain_destroy (ds->temporary_trns_chain); ds->temporary_trns_chain = NULL; + if ( ds->xform_callback) + ds->xform_callback (!trns_chain_is_empty (ds->permanent_trns_chain), + ds->xform_callback_aux); + return true; } else @@ -500,23 +522,35 @@ proc_cancel_all_transformations (struct dataset *ds) ok = trns_chain_destroy (ds->temporary_trns_chain) && ok; ds->permanent_trns_chain = ds->cur_trns_chain = trns_chain_create (); ds->temporary_trns_chain = NULL; + if ( ds->xform_callback) + ds->xform_callback (false, ds->xform_callback_aux); + return ok; } /* Initializes procedure handling. */ struct dataset * -create_dataset (replace_source_callback *rps, - replace_dictionary_callback *rds) +create_dataset (transformation_change_callback_func *cb, void *aux) { struct dataset *ds = xzalloc (sizeof(*ds)); ds->dict = dict_create (); ds->caseinit = caseinit_create (); - ds->replace_source = rps; - ds->replace_dict = rds; + ds->xform_callback = cb; + ds->xform_callback_aux = aux; proc_cancel_all_transformations (ds); return ds; } + +void +dataset_add_transform_change_callback (struct dataset *ds, + transformation_change_callback_func *cb, + void *aux) +{ + ds->xform_callback = cb; + ds->xform_callback_aux = aux; +} + /* Finishes up procedure handling. */ void destroy_dataset (struct dataset *ds) @@ -525,6 +559,9 @@ destroy_dataset (struct dataset *ds) dict_destroy (ds->dict); caseinit_destroy (ds->caseinit); trns_chain_destroy (ds->permanent_trns_chain); + + if ( ds->xform_callback) + ds->xform_callback (false, ds->xform_callback_aux); free (ds); } diff --git a/src/data/procedure.h b/src/data/procedure.h index 1b014e81..cfb8f218 100644 --- a/src/data/procedure.h +++ b/src/data/procedure.h @@ -51,12 +51,14 @@ struct dictionary ; typedef void replace_source_callback (struct casereader *); typedef void replace_dictionary_callback (struct dictionary *); +typedef void transformation_change_callback_func (bool non_empty, void *aux); -struct dataset * create_dataset (replace_source_callback *, - replace_dictionary_callback *); - +struct dataset * create_dataset (transformation_change_callback_func *, void *); void destroy_dataset (struct dataset *); +void dataset_add_transform_change_callback (struct dataset *, + transformation_change_callback_func *, void *); + void proc_discard_active_file (struct dataset *); void proc_set_active_file (struct dataset *, struct casereader *, struct dictionary *); diff --git a/src/ui/gui/ChangeLog b/src/ui/gui/ChangeLog index e0b6a971..4f0a0949 100644 --- a/src/ui/gui/ChangeLog +++ b/src/ui/gui/ChangeLog @@ -1,3 +1,11 @@ +2007-07-26 John Darrington + + * helper.c helper.h (execute_syntax): removed implicit EXECUTE at end + of commands. + + * data-editor.c data-editor.glade: Added "Run Pending Transformations" + menuitem. + 2007-07-25 John Darrington * customentry.c: Redraw button in insensitive state, if the widget's diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c index 94094dff..9681a09f 100644 --- a/src/ui/gui/data-editor.c +++ b/src/ui/gui/data-editor.c @@ -26,6 +26,7 @@ #include "helper.h" #include "about.h" +#include #include "psppire-dialog.h" #include "psppire-selector.h" #include "weight-cases-dialog.h" @@ -119,6 +120,37 @@ enable_delete_variables (GtkWidget *w, gint var, gpointer data) } + +/* Run the EXECUTE command. */ +static void +execute (GtkMenuItem *mi, gpointer data) +{ + struct getl_interface *sss = create_syntax_string_source ("EXECUTE."); + + execute_syntax (sss); +} + +static void +transformation_change_callback (bool transformations_pending, + gpointer data) +{ + struct data_editor *de = data; + GtkWidget *menuitem = + get_widget_assert (de->xml, "transform_run-pending"); + GtkWidget *status_label = + get_widget_assert (de->xml, "case-counter-area"); + + gtk_widget_set_sensitive (menuitem, transformations_pending); + + + if ( transformations_pending) + gtk_label_set_text (GTK_LABEL (status_label), + _("Transformations Pending")); + else + gtk_label_set_text (GTK_LABEL (status_label), ""); +} + + static void open_data_file (const gchar *, struct data_editor *); @@ -184,6 +216,8 @@ datum_entry_activate (GtkEntry *entry, gpointer data) psppire_data_store_set_string (store, text, row, column); } +extern struct dataset *the_dataset; + /* Create a new data editor. */ @@ -203,6 +237,11 @@ new_data_editor (void) de->xml = XML_NEW ("data-editor.glade"); + + dataset_add_transform_change_callback (the_dataset, + transformation_change_callback, + de); + var_sheet = GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); data_sheet = GTK_SHEET (get_widget_assert (de->xml, "data_sheet")); @@ -614,6 +653,10 @@ new_data_editor (void) "activate", G_CALLBACK (file_quit), de); + g_signal_connect (get_widget_assert (de->xml, "transform_run-pending"), + "activate", + G_CALLBACK (execute), de); + g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"), "activate", diff --git a/src/ui/gui/data-editor.glade b/src/ui/gui/data-editor.glade index 18e34001..68813e02 100644 --- a/src/ui/gui/data-editor.glade +++ b/src/ui/gui/data-editor.glade @@ -399,6 +399,22 @@ True + + + True + + + + + + True + False + _Run Pending Transforms + True + + + + @@ -921,7 +937,7 @@ True - 10 + 25 True diff --git a/src/ui/gui/helper.c b/src/ui/gui/helper.c index 09711f1b..56684968 100644 --- a/src/ui/gui/helper.c +++ b/src/ui/gui/helper.c @@ -164,17 +164,16 @@ extern struct dataset *the_dataset; extern struct source_stream *the_source_stream; extern PsppireDataStore *the_data_store; -gboolean +void execute_syntax (struct getl_interface *sss) { - gboolean status; struct lexer *lexer; struct casereader *reader = psppire_data_store_get_reader (the_data_store); proc_set_active_file_data (the_dataset, reader); - g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE); + g_return_if_fail (proc_has_active_file (the_dataset)); lexer = lex_create (the_source_stream); @@ -192,11 +191,6 @@ execute_syntax (struct getl_interface *sss) lex_destroy (lexer); - /* GUI syntax needs this implicit EXECUTE command at the end of - every script. Otherwise commands like GET could leave the GUI - without a datasheet. */ - status = proc_execute (the_dataset); - psppire_dict_replace_dictionary (the_data_store->dict, dataset_dict (the_dataset)); @@ -205,8 +199,6 @@ execute_syntax (struct getl_interface *sss) psppire_data_store_set_case_file (the_data_store, pcf); } - - return status; } diff --git a/src/ui/gui/helper.h b/src/ui/gui/helper.h index ddced00f..7ada5b52 100644 --- a/src/ui/gui/helper.h +++ b/src/ui/gui/helper.h @@ -54,7 +54,7 @@ void connect_help (GladeXML *); void reference_manual (GtkMenuItem *, gpointer); struct getl_interface; -gboolean execute_syntax (struct getl_interface *sss); +void execute_syntax (struct getl_interface *sss); #define XML_NEW(FILE) \ -- 2.30.2