X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fdata-editor.c;h=d6cf50b395bf2e6d8737f3df71de31b0a2cc8bda;hb=d52355bcda20563736bd83aed3ab58e534672cb5;hp=2f15096c3f274cf8140457c139ba9cfe2f0b95be;hpb=3e2bf013a731344daed7ab206d4a3c2460688208;p=pspp diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c index 2f15096c3f..d6cf50b395 100644 --- a/src/ui/gui/data-editor.c +++ b/src/ui/gui/data-editor.c @@ -1,21 +1,18 @@ -/* - PSPPIRE --- A Graphical User Interface for PSPP - Copyright (C) 2006, 2007 Free Software Foundation +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2006, 2007 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 2 of the License, or - (at your option) any later version. + 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. + 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include #include @@ -36,6 +33,7 @@ #include "transpose-dialog.h" #include "sort-cases-dialog.h" #include "compute-dialog.h" +#include "goto-case-dialog.h" #include "comments-dialog.h" #include "variable-info-dialog.h" #include "dict-display.h" @@ -59,7 +57,10 @@ static gint update_data_ref_entry (const GtkSheet *sheet, static void register_data_editor_actions (struct data_editor *de); -static void insert_variable (GtkCheckMenuItem *m, gpointer data); +static void insert_variable (GtkAction *, gpointer data); + +static void insert_case (GtkAction *a, gpointer data); + /* Switch between the VAR SHEET and the DATA SHEET */ @@ -132,7 +133,6 @@ static void on_recent_data_select (GtkMenuShell *menushell, gpointer user_data) { gchar *file; - struct data_editor *de = user_data; gchar *uri = @@ -171,7 +171,22 @@ on_recent_files_select (GtkMenuShell *menushell, gpointer user_data) #endif +static void +datum_entry_activate (GtkEntry *entry, gpointer data) +{ + gint row, column; + GtkSheet *data_sheet = GTK_SHEET (data); + PsppireDataStore *store = PSPPIRE_DATA_STORE (gtk_sheet_get_model (data_sheet)); + + const char *text = gtk_entry_get_text (entry); + gtk_sheet_get_active_cell (data_sheet, &row, &column); + + if ( row == -1 || column == -1) + return; + + psppire_data_store_set_string (store, text, row, column); +} /* Create a new data editor. @@ -184,6 +199,7 @@ new_data_editor (void) GtkSheet *var_sheet ; GtkSheet *data_sheet ; PsppireVarStore *vs; + GtkWidget *datum_entry; de = g_malloc0 (sizeof (*de)); @@ -202,6 +218,12 @@ new_data_editor (void) G_CALLBACK (update_data_ref_entry), de->xml); + datum_entry = get_widget_assert (de->xml, "datum_entry"); + + g_signal_connect (G_OBJECT (datum_entry), "activate", + G_CALLBACK (datum_entry_activate), + data_sheet); + g_signal_connect (vs->dict, "weight-changed", G_CALLBACK (on_weight_change), de); @@ -219,6 +241,66 @@ new_data_editor (void) register_data_editor_actions (de); + de->insert_variable = + gtk_action_new ("insert-variable", + _("Insert Variable"), + _("Create a new variable at the current position"), + "pspp-insert-variable"); + + g_signal_connect (de->insert_variable, "activate", + G_CALLBACK (insert_variable), de); + + + gtk_action_connect_proxy (de->insert_variable, + get_widget_assert (de->xml, "button-insert-variable") + ); + + gtk_action_connect_proxy (de->insert_variable, + get_widget_assert (de->xml, "data_insert-variable") + ); + + + de->insert_case = + gtk_action_new ("insert-case", + _("Insert Case"), + _("Create a new case at the current position"), + "pspp-insert-case"); + + g_signal_connect (de->insert_case, "activate", + G_CALLBACK (insert_case), de); + + + gtk_action_connect_proxy (de->insert_case, + get_widget_assert (de->xml, "button-insert-case") + ); + + + gtk_action_connect_proxy (de->insert_case, + get_widget_assert (de->xml, "data_insert-case") + ); + + + + de->invoke_goto_dialog = + gtk_action_new ("goto-case-dialog", + _("Goto Case"), + _("Jump to a Case in the Data Sheet"), + "gtk-jump-to"); + + + gtk_action_connect_proxy (de->invoke_goto_dialog, + get_widget_assert (de->xml, "button-goto-case") + ); + + gtk_action_connect_proxy (de->invoke_goto_dialog, + get_widget_assert (de->xml, "data_goto-case") + ); + + + g_signal_connect (de->invoke_goto_dialog, "activate", + G_CALLBACK (goto_case_dialog), de); + + de->invoke_weight_cases_dialog = gtk_action_new ("weight-cases-dialog", _("Weights"), @@ -302,19 +384,21 @@ new_data_editor (void) de->action_data_open); - - - #if RECENT_LISTS_AVAILABLE { GtkRecentManager *rm = gtk_recent_manager_get_default (); GtkWidget *recent_data = get_widget_assert (de->xml, "file_recent-data"); GtkWidget *recent_files = get_widget_assert (de->xml, "file_recent-files"); + GtkWidget *recent_separator = get_widget_assert (de->xml, "file_separator1"); GtkWidget *menu = gtk_recent_chooser_menu_new_for_manager (rm); GtkRecentFilter *filter = gtk_recent_filter_new (); + gtk_widget_show (recent_data); + gtk_widget_show (recent_files); + gtk_widget_show (recent_separator); + gtk_recent_filter_add_pattern (filter, "*.sav"); gtk_recent_filter_add_pattern (filter, "*.SAV"); @@ -370,10 +454,6 @@ new_data_editor (void) de); - g_signal_connect (get_widget_assert (de->xml,"data_insert-variable"), - "activate", - G_CALLBACK (insert_variable), - de); gtk_action_connect_proxy (de->invoke_weight_cases_dialog, get_widget_assert (de->xml, "data_weight-cases") @@ -414,21 +494,27 @@ new_data_editor (void) G_CALLBACK (reference_manual), e->window); - - - g_signal_connect (get_widget_assert (de->xml,"data_sheet"), + g_signal_connect (data_sheet, "double-click-column", G_CALLBACK (click2column), de); + g_signal_connect (data_sheet, + "select-row", + GTK_SIGNAL_FUNC (enable_edit_clear), + de); - g_signal_connect (get_widget_assert (de->xml, "variable_sheet"), + g_signal_connect (data_sheet, + "activate", + GTK_SIGNAL_FUNC (disable_edit_clear), + de); + + g_signal_connect (var_sheet, "double-click-row", GTK_SIGNAL_FUNC (click2row), de); - - g_signal_connect (get_widget_assert (de->xml, "variable_sheet"), + g_signal_connect (var_sheet, "select-row", GTK_SIGNAL_FUNC (enable_edit_clear), de); @@ -523,6 +609,7 @@ static gboolean click2row (GtkWidget *w, gint row, gpointer data) { struct data_editor *de = data; + GtkSheetRange visible_range; gint current_row, current_column; @@ -535,6 +622,14 @@ click2row (GtkWidget *w, gint row, gpointer data) gtk_sheet_set_active_cell (GTK_SHEET (data_sheet), current_row, row); + gtk_sheet_get_visible_range (GTK_SHEET (data_sheet), &visible_range); + + if ( row < visible_range.col0 || row > visible_range.coli) + { + gtk_sheet_moveto (GTK_SHEET (data_sheet), + current_row, row, 0, 0); + } + return FALSE; } @@ -571,9 +666,6 @@ new_data_window (GtkMenuItem *menuitem, gpointer parent) static void select_sheet (struct data_editor *de, guint page_num) { - GtkWidget *insert_variable = get_widget_assert (de->xml, "data_insert-variable"); - GtkWidget *insert_cases = get_widget_assert (de->xml, "insert-cases"); - GtkWidget *view_data = get_widget_assert (de->xml, "view_data"); GtkWidget *view_variables = get_widget_assert (de->xml, "view_variables"); @@ -582,15 +674,15 @@ select_sheet (struct data_editor *de, guint page_num) case PAGE_VAR_SHEET: gtk_widget_hide (view_variables); gtk_widget_show (view_data); - gtk_widget_set_sensitive (insert_variable, TRUE); - gtk_widget_set_sensitive (insert_cases, FALSE); + gtk_action_set_sensitive (de->insert_variable, TRUE); + gtk_action_set_sensitive (de->insert_case, FALSE); + gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE); break; case PAGE_DATA_SHEET: gtk_widget_show (view_variables); gtk_widget_hide (view_data); -#if 0 - gtk_widget_set_sensitive (insert_cases, TRUE); -#endif + gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE); + gtk_action_set_sensitive (de->insert_case, TRUE); break; default: g_assert_not_reached (); @@ -762,52 +854,96 @@ file_quit (GtkCheckMenuItem *menuitem, gpointer data) } - /* Callback for when the Clear item in the edit menu is activated */ static void on_clear_activate (GtkMenuItem *menuitem, gpointer data) { struct data_editor *de = data; + GtkSheet *sheet = NULL; + GtkSheetRange range ; + GtkNotebook *notebook = GTK_NOTEBOOK (get_widget_assert (de->xml, "notebook")); - switch ( gtk_notebook_get_current_page (notebook) ) + const gint page = gtk_notebook_get_current_page (notebook); + + sheet = GTK_SHEET + (get_widget_assert (de->xml, + (page == PAGE_VAR_SHEET) ? "variable_sheet" : "data_sheet")); + + /* This shouldn't be able to happen, because the menuitem + should be disabled */ + g_return_if_fail (gtk_sheet_get_state (sheet) == GTK_SHEET_ROW_SELECTED ); + + + gtk_sheet_get_selected_range (sheet, &range); + + switch ( page ) { case PAGE_VAR_SHEET: { - GtkSheet *var_sheet = - GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); - PsppireVarStore *vs = PSPPIRE_VAR_STORE - (gtk_sheet_get_model (var_sheet) ); + (gtk_sheet_get_model (sheet) ); - /* This shouldn't be able to happen, because the menuitem - should be disabled */ - g_return_if_fail (var_sheet->state == GTK_SHEET_ROW_SELECTED ); psppire_dict_delete_variables (vs->dict, - var_sheet->range.row0, + range.row0, 1 + - var_sheet->range.rowi - - var_sheet->range.row0 ); + range.rowi - + range.row0 ); } break; - case PAGE_DATA_SHEET: - break; - default: - g_assert_not_reached (); + case PAGE_DATA_SHEET: + { + PsppireDataStore *data_store = PSPPIRE_DATA_STORE + (gtk_sheet_get_model (sheet) ); + + + /* This shouldn't be able to happen, because the menuitem + should be disabled */ + g_return_if_fail (gtk_sheet_get_state (sheet) + == GTK_SHEET_ROW_SELECTED ); + + + psppire_data_store_delete_cases (data_store, range.row0, + 1 + range.rowi - range.row0); + } + break; + default: + g_assert_not_reached (); } + + gtk_sheet_unselect_range (sheet); } +static void +insert_case (GtkAction *action, gpointer data) +{ + gint current_row ; + struct data_editor *de = data; + + GtkSheet *data_sheet = + GTK_SHEET (get_widget_assert (de->xml, "data_sheet")); + + PsppireDataStore *ds = PSPPIRE_DATA_STORE + (gtk_sheet_get_model (data_sheet) ); + + + gtk_sheet_get_active_cell (data_sheet, ¤t_row, NULL); + + if (current_row < 0) current_row = 0; + + psppire_data_store_insert_new_case (ds, current_row); +} /* Insert a new variable before the current row in the variable sheet, or before the current column in the data sheet, whichever is selected */ static void -insert_variable (GtkCheckMenuItem *m, gpointer data) +insert_variable (GtkAction *action, gpointer data) { struct data_editor *de = data; - gint posn; + gint posn = -1; GtkWidget *notebook = get_widget_assert (de->xml, "notebook"); @@ -837,6 +973,8 @@ insert_variable (GtkCheckMenuItem *m, gpointer data) g_assert_not_reached (); } + if ( posn == -1 ) posn = 0; + psppire_dict_insert_variable (vs->dict, posn, NULL); } @@ -1247,34 +1385,54 @@ update_data_ref_entry (const GtkSheet *sheet, gint row, gint col, gpointer data) { GladeXML *data_editor_xml = data; - /* The entry where the reference to the current cell is displayed */ - GtkEntry *cell_ref_entry; - - PsppireDataStore *data_store = PSPPIRE_DATA_STORE (gtk_sheet_get_model (sheet)); + PsppireDataStore *data_store = + PSPPIRE_DATA_STORE (gtk_sheet_get_model (sheet)); g_return_val_if_fail (data_editor_xml, FALSE); if (data_store) { - const struct variable *pv = + const struct variable *var = psppire_dict_get_variable (data_store->dict, col); - gchar *text ; - gchar *s ; + /* The entry where the reference to the current cell is displayed */ + GtkEntry *cell_ref_entry = + GTK_ENTRY (get_widget_assert (data_editor_xml, + "cell_ref_entry")); + GtkEntry *datum_entry = + GTK_ENTRY (get_widget_assert (data_editor_xml, + "datum_entry")); - text = g_strdup_printf ("%d: %s", row, - pv ? var_get_name (pv) : ""); + if ( var ) + { + gchar *text = g_strdup_printf ("%d: %s", row + FIRST_CASE_NUMBER, + var_get_name (var)); - cell_ref_entry = GTK_ENTRY (get_widget_assert (data_editor_xml, - "cell_ref_entry")); + gchar *s = pspp_locale_to_utf8 (text, -1, 0); - s = pspp_locale_to_utf8 (text, -1, 0); + g_free (text); - g_free (text); + gtk_entry_set_text (cell_ref_entry, s); - gtk_entry_set_text (cell_ref_entry, s); + g_free (s); + } + else + gtk_entry_set_text (cell_ref_entry, ""); - g_free (s); + + if ( var ) + { + gchar *text = + psppire_data_store_get_string (data_store, row, + var_get_dict_index(var)); + g_strchug (text); + + gtk_entry_set_text (datum_entry, text); + + free (text); + } + else + gtk_entry_set_text (datum_entry, ""); } return FALSE;