/*
PSPPIRE --- A Graphical User Interface for PSPP
- Copyright (C) 2006 Free Software Foundation
+ 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
#include <glade/glade.h>
#include <gtk/gtk.h>
-
+#include "window-manager.h"
#include <gtksheet/gtksheet.h>
#include "helper.h"
#include "about.h"
+#include "psppire-dialog.h"
+#include "psppire-var-select.h"
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
#include "data-editor.h"
#include "syntax-editor.h"
+#include <language/syntax-string-source.h>
#include "window-manager.h"
#include "psppire-data-store.h"
#include "psppire-var-store.h"
+#include "weight-cases-dialog.h"
+
+
+static void insert_variable (GtkCheckMenuItem *m, gpointer data);
+
+
/* Switch between the VAR SHEET and the DATA SHEET */
enum {PAGE_DATA_SHEET = 0, PAGE_VAR_SHEET};
static void select_sheet (struct data_editor *de, guint page_num);
+/* Callback for when the dictionary changes properties*/
+static void on_weight_change (GObject *, gint, gpointer);
+static void on_filter_change (GObject *, gint, gpointer);
+static void on_split_change (PsppireDict *, gpointer);
+
static void data_var_select (GtkNotebook *notebook,
GtkNotebookPage *page,
guint page_num,
static void file_quit (GtkCheckMenuItem *, gpointer );
+static void on_clear_activate (GtkMenuItem *, gpointer);
+
+static void
+enable_edit_clear (GtkWidget *w, gint row, gpointer data)
+{
+ struct data_editor *de = data;
+
+ GtkWidget *menuitem = get_widget_assert (de->xml, "edit_clear");
+
+ gtk_widget_set_sensitive (menuitem, TRUE);
+}
+
+static gboolean
+disable_edit_clear (GtkWidget *w, gint x, gint y, gpointer data)
+{
+ struct data_editor *de = data;
+
+ GtkWidget *menuitem = get_widget_assert (de->xml, "edit_clear");
+
+ gtk_widget_set_sensitive (menuitem, FALSE);
+
+ return FALSE;
+}
+
+static void weight_cases_dialog (GObject *o, gpointer data);
+
/*
Create a new data editor.
{
struct data_editor *de ;
struct editor_window *e;
+ GtkSheet *var_sheet ;
+ PsppireVarStore *vs;
de = g_malloc (sizeof (*de));
de->xml = glade_xml_new (PKGDATADIR "/data-editor.glade", NULL, NULL);
- e->window = get_widget_assert (de->xml, "data_editor");
+
+ var_sheet = GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+ vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
+
+ g_signal_connect (vs->dict, "weight-changed",
+ G_CALLBACK (on_weight_change),
+ de);
+
+ g_signal_connect (vs->dict, "filter-changed",
+ G_CALLBACK (on_filter_change),
+ de);
+
+ g_signal_connect (vs->dict, "split-changed",
+ G_CALLBACK (on_split_change),
+ de);
+
+ connect_help (de->xml);
+
+ de->invoke_weight_cases_dialog =
+ gtk_action_new ("weight-cases-dialog",
+ _("Weights"),
+ _("Weight cases by variable"),
+ "pspp-weight-cases");
+
+
+ g_signal_connect (de->invoke_weight_cases_dialog, "activate",
+ G_CALLBACK (weight_cases_dialog), de);
+
+ e->window = GTK_WINDOW (get_widget_assert (de->xml, "data_editor"));
g_signal_connect (get_widget_assert (de->xml,"file_new_data"),
"activate",
G_CALLBACK (open_syntax_window),
e->window);
+
+ g_signal_connect (get_widget_assert (de->xml,"edit_clear"),
+ "activate",
+ G_CALLBACK (on_clear_activate),
+ 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")
+ );
+
+ /*
+ g_signal_connect (get_widget_assert (de->xml,"data_weight-cases"),
+ "activate",
+ G_CALLBACK (weight_cases_dialog),
+ de);
+ */
+
+
g_signal_connect (get_widget_assert (de->xml,"help_about"),
"activate",
G_CALLBACK (about_new),
e->window);
+ g_signal_connect (get_widget_assert (de->xml,"help_reference"),
+ "activate",
+ G_CALLBACK (reference_manual),
+ e->window);
+
+
+
g_signal_connect (get_widget_assert (de->xml,"data_sheet"),
"double-click-column",
G_CALLBACK (click2column),
de);
+ g_signal_connect (get_widget_assert (de->xml, "variable_sheet"),
+ "select-row",
+ GTK_SIGNAL_FUNC (enable_edit_clear),
+ de);
+
+ g_signal_connect (get_widget_assert (de->xml, "variable_sheet"),
+ "activate",
+ GTK_SIGNAL_FUNC (disable_edit_clear),
+ de);
+
+
g_signal_connect (get_widget_assert (de->xml, "notebook"),
"switch-page",
G_CALLBACK (data_var_select), de);
G_CALLBACK (value_labels_toggled), de);
+ gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
+ get_widget_assert (de->xml, "button-weight-cases")
+ );
+
g_signal_connect (get_widget_assert (de->xml, "file_quit"),
"activate",
G_CALLBACK (file_quit), de);
+ g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"),
+ "activate",
+ G_CALLBACK (minimise_all_windows), NULL);
+
+
+
select_sheet (de, PAGE_DATA_SHEET);
return de;
data_editor_select_sheet (de, PAGE_DATA_SHEET);
- gtk_sheet_get_active_cell (GTK_SHEET(data_sheet),
+ gtk_sheet_get_active_cell (GTK_SHEET (data_sheet),
¤t_row, ¤t_column);
- gtk_sheet_set_active_cell (GTK_SHEET(data_sheet), current_row, row);
+ gtk_sheet_set_active_cell (GTK_SHEET (data_sheet), current_row, row);
return FALSE;
}
data_editor_select_sheet (de, PAGE_VAR_SHEET);
- gtk_sheet_get_active_cell (GTK_SHEET(var_sheet),
+ gtk_sheet_get_active_cell (GTK_SHEET (var_sheet),
¤t_row, ¤t_column);
- gtk_sheet_set_active_cell (GTK_SHEET(var_sheet), col, current_column);
+ gtk_sheet_set_active_cell (GTK_SHEET (var_sheet), col, current_column);
return FALSE;
}
-
-
void
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, "insert-variable");
+ 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");
case PAGE_DATA_SHEET:
gtk_widget_show (view_variables);
gtk_widget_hide (view_data);
- gtk_widget_set_sensitive (insert_variable, FALSE);
+#if 0
gtk_widget_set_sensitive (insert_cases, TRUE);
+#endif
break;
default:
g_assert_not_reached ();
gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
gtk_file_filter_add_pattern (filter, "*.sav");
gtk_file_filter_add_pattern (filter, "*.SAV");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
gtk_file_filter_add_pattern (filter, "*.por");
gtk_file_filter_add_pattern (filter, "*.POR");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All Files"));
gtk_file_filter_add_pattern (filter, "*");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
do {
status_bar_activate (GtkCheckMenuItem *menuitem, gpointer data)
{
struct data_editor *de = data;
- GtkWidget *statusbar = get_widget_assert (de->xml, "statusbar");
+ GtkWidget *statusbar = get_widget_assert (de->xml, "status-bar");
if ( gtk_check_menu_item_get_active (menuitem) )
gtk_widget_show (statusbar);
}
-
-
static void
grid_lines_activate (GtkCheckMenuItem *menuitem, gpointer data)
{
if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) )
{
GtkSheet *data_sheet =
- GTK_SHEET(get_widget_assert (de->xml, "data_sheet"));
+ GTK_SHEET (get_widget_assert (de->xml, "data_sheet"));
GtkSheet *var_sheet =
- GTK_SHEET(get_widget_assert (de->xml, "variable_sheet"));
+ GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
PsppireDataStore *ds = PSPPIRE_DATA_STORE (gtk_sheet_get_model (data_sheet));
PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
*/
gtk_main_quit ();
}
+
+
+
+/* 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;
+
+ GtkNotebook *notebook = GTK_NOTEBOOK (get_widget_assert (de->xml,
+ "notebook"));
+
+ switch ( gtk_notebook_get_current_page (notebook) )
+ {
+ 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) );
+
+ /* 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,
+ 1 +
+ var_sheet->range.rowi -
+ var_sheet->range.row0 );
+ }
+ break;
+ case PAGE_DATA_SHEET:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+
+/* 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)
+{
+ struct data_editor *de = data;
+ gint posn;
+
+ GtkWidget *notebook = get_widget_assert (de->xml, "notebook");
+
+ GtkSheet *var_sheet =
+ GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+ PsppireVarStore *vs = PSPPIRE_VAR_STORE
+ (gtk_sheet_get_model (var_sheet) );
+
+ switch ( gtk_notebook_get_current_page ( GTK_NOTEBOOK (notebook)) )
+ {
+ case PAGE_VAR_SHEET:
+ posn = var_sheet->active_cell.row;
+ break;
+ case PAGE_DATA_SHEET:
+ {
+ GtkSheet *data_sheet =
+ GTK_SHEET (get_widget_assert (de->xml, "data_sheet"));
+
+ if ( data_sheet->state == GTK_SHEET_COLUMN_SELECTED )
+ posn = data_sheet->range.col0;
+ else
+ posn = data_sheet->active_cell.col;
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ psppire_dict_insert_variable (vs->dict, posn, NULL);
+}
+
+/* Callback for when the dictionary changes its split variables */
+static void
+on_split_change (PsppireDict *dict, gpointer data)
+{
+ struct data_editor *de = data;
+
+ size_t n_split_vars = dict_get_split_cnt (dict->dict);
+
+ GtkWidget *split_status_area =
+ get_widget_assert (de->xml, "split-file-status-area");
+
+ if ( n_split_vars == 0 )
+ {
+ gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
+ }
+ else
+ {
+ gint i;
+ GString *text;
+ struct variable *const * split_vars = dict_get_split_vars (dict->dict);
+
+ text = g_string_new (_("Split by "));
+
+ for (i = 0 ; i < n_split_vars - 1; ++i )
+ {
+ g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
+ }
+ g_string_append (text, var_get_name (split_vars[i]));
+
+ gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
+
+ g_string_free (text, TRUE);
+ }
+}
+
+
+/* Callback for when the dictionary changes its filter variable */
+static void
+on_filter_change (GObject *o, gint filter_index, gpointer data)
+{
+ struct data_editor *de = data;
+ GtkWidget *filter_status_area =
+ get_widget_assert (de->xml, "filter-use-status-area");
+
+ if ( filter_index == -1 )
+ {
+ gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
+ }
+ else
+ {
+ GtkSheet *var_sheet =
+ GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+ PsppireVarStore *vs = PSPPIRE_VAR_STORE
+ (gtk_sheet_get_model (var_sheet) );
+
+ struct variable *var = psppire_dict_get_variable (vs->dict,
+ filter_index);
+
+ gchar *text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
+
+ gtk_label_set_text (GTK_LABEL (filter_status_area), text);
+
+ g_free (text);
+ }
+}
+
+/* Callback for when the dictionary changes its weights */
+static void
+on_weight_change (GObject *o, gint weight_index, gpointer data)
+{
+ struct data_editor *de = data;
+ GtkWidget *weight_status_area =
+ get_widget_assert (de->xml, "weight-status-area");
+
+ if ( weight_index == -1 )
+ {
+ gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
+ }
+ else
+ {
+ GtkSheet *var_sheet =
+ GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+ PsppireVarStore *vs = PSPPIRE_VAR_STORE
+ (gtk_sheet_get_model (var_sheet) );
+
+ struct variable *var = psppire_dict_get_variable (vs->dict,
+ weight_index);
+
+ gchar *text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
+
+ gtk_label_set_text (GTK_LABEL (weight_status_area), text);
+
+ g_free (text);
+ }
+}
+
+static void
+weight_cases_dialog (GObject *o, gpointer data)
+{
+ gint response;
+ struct data_editor *de = data;
+ GtkSheet *var_sheet =
+ GTK_SHEET (get_widget_assert (de->xml, "variable_sheet"));
+
+
+ GladeXML *xml = glade_xml_new (PKGDATADIR "/psppire.glade",
+ "weight-cases-dialog", NULL);
+
+
+ GtkWidget *treeview = get_widget_assert (xml, "treeview");
+ GtkWidget *entry = get_widget_assert (xml, "entry1");
+
+
+ PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet));
+
+ PsppireVarSelect *select = psppire_var_select_new (treeview,
+ entry, vs->dict);
+
+
+ PsppireDialog *dialog = create_weight_dialog (select, xml);
+
+ response = psppire_dialog_run (dialog);
+
+ g_object_unref (xml);
+
+ switch (response)
+ {
+ case GTK_RESPONSE_OK:
+ {
+ struct getl_interface *sss ;
+ const GList *list = psppire_var_select_get_variables (select);
+
+ g_assert ( g_list_length ((GList *)list) <= 1 );
+
+ if ( list == NULL)
+ {
+ sss = create_syntax_string_source ("WEIGHT OFF.");
+ }
+ else
+ {
+ struct variable *var = list->data;
+
+ sss = create_syntax_string_source ("WEIGHT BY %s.\n",
+ var_get_name (var));
+ }
+
+ execute_syntax (sss);
+ }
+ break;
+ case PSPPIRE_RESPONSE_PASTE:
+ {
+ struct syntax_editor *se = (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
+
+ const GList *list = psppire_var_select_get_variables (select);
+
+ g_assert ( g_list_length ((GList *)list) <= 1 );
+
+ if ( list == NULL)
+ {
+ gtk_text_buffer_insert_at_cursor (se->buffer, "WEIGHT OFF.", -1);
+ }
+ else
+ {
+ struct variable *var = list->data;
+
+ gchar *text = g_strdup_printf ("WEIGHT BY %s.",
+ var_get_name (var));
+
+ gtk_text_buffer_insert_at_cursor (se->buffer,
+ text, -1);
+
+ g_free (text);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+