1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include "data/dataset.h"
23 #include "language/lexer/lexer.h"
24 #include "libpspp/message.h"
25 #include "ui/gui/aggregate-dialog.h"
26 #include "ui/gui/binomial-dialog.h"
27 #include "ui/gui/chi-square-dialog.h"
28 #include "ui/gui/comments-dialog.h"
29 #include "ui/gui/compute-dialog.h"
30 #include "ui/gui/correlation-dialog.h"
31 #include "ui/gui/crosstabs-dialog.h"
32 #include "ui/gui/descriptives-dialog.h"
33 #include "ui/gui/examine-dialog.h"
34 #include "ui/gui/executor.h"
35 #include "ui/gui/factor-dialog.h"
36 #include "ui/gui/find-dialog.h"
37 #include "ui/gui/frequencies-dialog.h"
38 #include "ui/gui/goto-case-dialog.h"
39 #include "ui/gui/help-menu.h"
40 #include "ui/gui/helper.h"
41 #include "ui/gui/k-related-dialog.h"
42 #include "ui/gui/oneway-anova-dialog.h"
43 #include "ui/gui/psppire-data-window.h"
44 #include "ui/gui/psppire-syntax-window.h"
45 #include "ui/gui/psppire-window.h"
46 #include "ui/gui/psppire.h"
47 #include "ui/gui/rank-dialog.h"
48 #include "ui/gui/recode-dialog.h"
49 #include "ui/gui/regression-dialog.h"
50 #include "ui/gui/reliability-dialog.h"
51 #include "ui/gui/roc-dialog.h"
52 #include "ui/gui/select-cases-dialog.h"
53 #include "ui/gui/sort-cases-dialog.h"
54 #include "ui/gui/split-file-dialog.h"
55 #include "ui/gui/t-test-independent-samples-dialog.h"
56 #include "ui/gui/t-test-one-sample.h"
57 #include "ui/gui/t-test-paired-samples.h"
58 #include "ui/gui/text-data-import-dialog.h"
59 #include "ui/gui/transpose-dialog.h"
60 #include "ui/gui/variable-info-dialog.h"
61 #include "ui/gui/weight-cases-dialog.h"
62 #include "ui/syntax-gen.h"
65 #define _(msgid) gettext (msgid)
66 #define N_(msgid) msgid
68 static PsppireDataWindow *the_data_window;
70 static void psppire_data_window_class_init (PsppireDataWindowClass *class);
71 static void psppire_data_window_init (PsppireDataWindow *data_editor);
74 static void psppire_data_window_iface_init (PsppireWindowIface *iface);
76 static void psppire_data_window_dispose (GObject *object);
77 static void psppire_data_window_set_property (GObject *object,
81 static void psppire_data_window_get_property (GObject *object,
87 psppire_data_window_get_type (void)
89 static GType psppire_data_window_type = 0;
91 if (!psppire_data_window_type)
93 static const GTypeInfo psppire_data_window_info =
95 sizeof (PsppireDataWindowClass),
98 (GClassInitFunc)psppire_data_window_class_init,
99 (GClassFinalizeFunc) NULL,
101 sizeof (PsppireDataWindow),
103 (GInstanceInitFunc) psppire_data_window_init,
106 static const GInterfaceInfo window_interface_info =
108 (GInterfaceInitFunc) psppire_data_window_iface_init,
113 psppire_data_window_type =
114 g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireDataWindow",
115 &psppire_data_window_info, 0);
118 g_type_add_interface_static (psppire_data_window_type,
119 PSPPIRE_TYPE_WINDOW_MODEL,
120 &window_interface_info);
123 return psppire_data_window_type;
126 static GObjectClass *parent_class ;
133 psppire_data_window_class_init (PsppireDataWindowClass *class)
135 GObjectClass *object_class = G_OBJECT_CLASS (class);
137 parent_class = g_type_class_peek_parent (class);
139 object_class->dispose = psppire_data_window_dispose;
140 object_class->set_property = psppire_data_window_set_property;
141 object_class->get_property = psppire_data_window_get_property;
143 g_object_class_install_property (
144 object_class, PROP_DATASET,
145 g_param_spec_pointer ("dataset", "Dataset",
146 "'struct datset *' represented by the window",
147 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
151 extern GtkRecentManager *the_recent_mgr;
154 set_paste_menuitem_sensitivity (PsppireDataWindow *de, gboolean x)
156 GtkAction *edit_paste = get_action_assert (de->builder, "edit_paste");
158 gtk_action_set_sensitive (edit_paste, x);
162 set_cut_copy_menuitem_sensitivity (PsppireDataWindow *de, gboolean x)
164 GtkAction *edit_copy = get_action_assert (de->builder, "edit_copy");
165 GtkAction *edit_cut = get_action_assert (de->builder, "edit_cut");
167 gtk_action_set_sensitive (edit_copy, x);
168 gtk_action_set_sensitive (edit_cut, x);
171 /* Run the EXECUTE command. */
173 execute (PsppireDataWindow *dw)
175 execute_const_syntax_string (dw, "EXECUTE.");
179 transformation_change_callback (bool transformations_pending,
182 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
184 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
186 GtkWidget *menuitem =
187 gtk_ui_manager_get_widget (uim,"/ui/menubar/transform/transform_run-pending");
189 GtkWidget *status_label =
190 get_widget_assert (de->builder, "case-counter-area");
192 gtk_widget_set_sensitive (menuitem, transformations_pending);
195 if ( transformations_pending)
196 gtk_label_set_text (GTK_LABEL (status_label),
197 _("Transformations Pending"));
199 gtk_label_set_text (GTK_LABEL (status_label), "");
202 /* Callback for when the dictionary changes its filter variable */
204 on_filter_change (GObject *o, gint filter_index, gpointer data)
206 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
208 GtkWidget *filter_status_area =
209 get_widget_assert (de->builder, "filter-use-status-area");
211 if ( filter_index == -1 )
213 gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
217 PsppireVarStore *vs = NULL;
218 PsppireDict *dict = NULL;
219 struct variable *var ;
222 g_object_get (de->data_editor, "var-store", &vs, NULL);
223 g_object_get (vs, "dictionary", &dict, NULL);
225 var = psppire_dict_get_variable (dict, filter_index);
227 text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
229 gtk_label_set_text (GTK_LABEL (filter_status_area), text);
235 /* Callback for when the dictionary changes its split variables */
237 on_split_change (PsppireDict *dict, gpointer data)
239 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
241 size_t n_split_vars = dict_get_split_cnt (dict->dict);
243 GtkWidget *split_status_area =
244 get_widget_assert (de->builder, "split-file-status-area");
246 if ( n_split_vars == 0 )
248 gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
254 const struct variable *const * split_vars =
255 dict_get_split_vars (dict->dict);
257 text = g_string_new (_("Split by "));
259 for (i = 0 ; i < n_split_vars - 1; ++i )
261 g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
263 g_string_append (text, var_get_name (split_vars[i]));
265 gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
267 g_string_free (text, TRUE);
274 /* Callback for when the dictionary changes its weights */
276 on_weight_change (GObject *o, gint weight_index, gpointer data)
278 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
280 GtkWidget *weight_status_area =
281 get_widget_assert (de->builder, "weight-status-area");
283 if ( weight_index == -1 )
285 gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
289 struct variable *var ;
290 PsppireVarStore *vs = NULL;
291 PsppireDict *dict = NULL;
294 g_object_get (de->data_editor, "var-store", &vs, NULL);
295 g_object_get (vs, "dictionary", &dict, NULL);
297 var = psppire_dict_get_variable (dict, weight_index);
299 text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
301 gtk_label_set_text (GTK_LABEL (weight_status_area), text);
309 dump_rm (GtkRecentManager *rm)
311 GList *items = gtk_recent_manager_get_items (rm);
315 g_print ("Recent Items:\n");
316 for (i = items; i; i = i->next)
318 GtkRecentInfo *ri = i->data;
320 g_print ("Item: %s (Mime: %s) (Desc: %s) (URI: %s)\n",
321 gtk_recent_info_get_short_name (ri),
322 gtk_recent_info_get_mime_type (ri),
323 gtk_recent_info_get_description (ri),
324 gtk_recent_info_get_uri (ri)
328 gtk_recent_info_unref (ri);
337 load_file (PsppireWindow *de, const gchar *file_name)
339 gchar *utf8_file_name;
340 struct string filename;
344 ds_init_empty (&filename);
346 utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL, NULL);
348 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
350 g_free (utf8_file_name);
352 syntax = g_strdup_printf ("GET FILE=%s.", ds_cstr (&filename));
353 ds_destroy (&filename);
355 ok = execute_syntax (PSPPIRE_DATA_WINDOW (de),
356 lex_reader_for_string (syntax));
361 /* Returns true if NAME has a suffix which might denote a PSPP file */
363 name_has_suffix (const gchar *name)
365 if ( g_str_has_suffix (name, ".sav"))
367 if ( g_str_has_suffix (name, ".SAV"))
369 if ( g_str_has_suffix (name, ".por"))
371 if ( g_str_has_suffix (name, ".POR"))
378 /* Save DE to file */
380 save_file (PsppireWindow *w)
382 gchar *utf8_file_name = NULL;
383 gchar *file_name = NULL;
385 struct string filename ;
386 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (w);
389 g_object_get (w, "filename", &file_name, NULL);
391 fnx = g_string_new (file_name);
393 if ( ! name_has_suffix (fnx->str))
395 if ( de->save_as_portable)
396 g_string_append (fnx, ".por");
398 g_string_append (fnx, ".sav");
401 ds_init_empty (&filename);
403 utf8_file_name = g_filename_to_utf8 (fnx->str, -1, NULL, NULL, NULL);
405 g_string_free (fnx, TRUE);
407 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
408 g_free (utf8_file_name);
410 syntax = g_strdup_printf ("%s OUTFILE=%s.",
411 de->save_as_portable ? "EXPORT" : "SAVE",
412 ds_cstr (&filename));
414 ds_destroy (&filename);
416 g_free (execute_syntax_string (de, syntax));
421 insert_case (PsppireDataWindow *dw)
423 psppire_data_editor_insert_case (dw->data_editor);
427 on_insert_variable (PsppireDataWindow *dw)
429 psppire_data_editor_insert_variable (dw->data_editor);
434 display_dict (PsppireDataWindow *de)
436 execute_const_syntax_string (de, "DISPLAY DICTIONARY.");
440 sysfile_info (PsppireDataWindow *de)
442 GtkWidget *dialog = psppire_window_file_chooser_dialog (PSPPIRE_WINDOW (de));
444 if ( GTK_RESPONSE_ACCEPT == gtk_dialog_run (GTK_DIALOG (dialog)))
446 struct string filename;
448 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
450 gchar *utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL,
455 ds_init_empty (&filename);
457 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
459 g_free (utf8_file_name);
461 syntax = g_strdup_printf ("SYSFILE INFO %s.", ds_cstr (&filename));
462 g_free (execute_syntax_string (de, syntax));
465 gtk_widget_destroy (dialog);
469 /* Callback for data_save_as action. Prompt for a filename and save */
471 data_save_as_dialog (PsppireDataWindow *de)
473 GtkWidget *button_sys;
475 gtk_file_chooser_dialog_new (_("Save"),
477 GTK_FILE_CHOOSER_ACTION_SAVE,
478 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
479 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
482 GtkFileFilter *filter = gtk_file_filter_new ();
483 gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
484 gtk_file_filter_add_pattern (filter, "*.sav");
485 gtk_file_filter_add_pattern (filter, "*.SAV");
486 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
488 filter = gtk_file_filter_new ();
489 gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
490 gtk_file_filter_add_pattern (filter, "*.por");
491 gtk_file_filter_add_pattern (filter, "*.POR");
492 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
494 filter = gtk_file_filter_new ();
495 gtk_file_filter_set_name (filter, _("All Files"));
496 gtk_file_filter_add_pattern (filter, "*");
497 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
500 GtkWidget *button_por;
501 GtkWidget *vbox = gtk_vbox_new (TRUE, 5);
503 gtk_radio_button_new_with_label (NULL, _("System File"));
506 gtk_radio_button_new_with_label
507 (gtk_radio_button_get_group (GTK_RADIO_BUTTON(button_sys)),
510 psppire_box_pack_start_defaults (GTK_BOX (vbox), button_sys);
511 psppire_box_pack_start_defaults (GTK_BOX (vbox), button_por);
513 gtk_widget_show_all (vbox);
515 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), vbox);
518 switch (gtk_dialog_run (GTK_DIALOG (dialog)))
520 case GTK_RESPONSE_ACCEPT:
525 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog))
528 de->save_as_portable =
529 ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys));
531 if ( ! name_has_suffix (filename->str))
533 if ( de->save_as_portable)
534 g_string_append (filename, ".por");
536 g_string_append (filename, ".sav");
539 psppire_window_set_filename (PSPPIRE_WINDOW (de), filename->str);
541 save_file (PSPPIRE_WINDOW (de));
543 g_string_free (filename, TRUE);
550 gtk_widget_destroy (dialog);
554 /* Callback for data_save action.
557 data_save (PsppireWindow *de)
559 const gchar *fn = psppire_window_get_filename (de);
562 psppire_window_save (de);
564 data_save_as_dialog (PSPPIRE_DATA_WINDOW (de));
568 /* Callback for data_new action.
569 Performs the NEW FILE command */
571 new_file (PsppireDataWindow *de)
573 execute_const_syntax_string (de, "NEW FILE.");
574 psppire_window_set_filename (PSPPIRE_WINDOW (de), NULL);
580 on_edit_paste (PsppireDataWindow *de)
582 psppire_data_editor_clip_paste (de->data_editor);
586 on_edit_copy (PsppireDataWindow *de)
588 psppire_data_editor_clip_copy (de->data_editor);
594 on_edit_cut (PsppireDataWindow *de)
596 psppire_data_editor_clip_cut (de->data_editor);
601 status_bar_activate (PsppireDataWindow *de, GtkToggleAction *action)
603 GtkWidget *statusbar = get_widget_assert (de->builder, "status-bar");
605 if ( gtk_toggle_action_get_active (action))
606 gtk_widget_show (statusbar);
608 gtk_widget_hide (statusbar);
613 grid_lines_activate (PsppireDataWindow *de, GtkToggleAction *action)
615 const gboolean grid_visible = gtk_toggle_action_get_active (action);
617 psppire_data_editor_show_grid (de->data_editor, grid_visible);
621 data_view_activate (PsppireDataWindow *de)
623 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
628 variable_view_activate (PsppireDataWindow *de)
630 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
635 fonts_activate (PsppireDataWindow *de)
637 GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (de));
638 PangoFontDescription *current_font;
641 gtk_font_selection_dialog_new (_("Font Selection"));
644 current_font = GTK_WIDGET(de->data_editor)->style->font_desc;
645 font_name = pango_font_description_to_string (current_font);
647 gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name);
651 gtk_window_set_transient_for (GTK_WINDOW (dialog),
652 GTK_WINDOW (toplevel));
654 if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) )
656 const gchar *font = gtk_font_selection_dialog_get_font_name
657 (GTK_FONT_SELECTION_DIALOG (dialog));
659 PangoFontDescription* font_desc =
660 pango_font_description_from_string (font);
662 psppire_data_editor_set_font (de->data_editor, font_desc);
665 gtk_widget_hide (dialog);
670 /* Callback for the value labels action */
672 toggle_value_labels (PsppireDataWindow *de, GtkToggleAction *ta)
674 g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL);
678 toggle_split_window (PsppireDataWindow *de, GtkToggleAction *ta)
680 psppire_data_editor_split_window (de->data_editor,
681 gtk_toggle_action_get_active (ta));
686 file_quit (PsppireDataWindow *de)
688 /* FIXME: Need to be more intelligent here.
689 Give the user the opportunity to save any unsaved data.
691 g_object_unref (de->data_store);
698 on_recent_data_select (GtkMenuShell *menushell,
699 PsppireWindow *window)
704 gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
706 file = g_filename_from_uri (uri, NULL, NULL);
710 psppire_window_load (window, file);
716 on_recent_files_select (GtkMenuShell *menushell, gpointer user_data)
723 gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
725 file = g_filename_from_uri (uri, NULL, NULL);
729 se = psppire_syntax_window_new ();
731 if ( psppire_window_load (PSPPIRE_WINDOW (se), file) )
732 gtk_widget_show (se);
734 gtk_widget_destroy (se);
741 enable_delete_cases (GtkWidget *w, gint case_num, gpointer data)
743 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
745 gtk_action_set_visible (de->delete_cases, case_num != -1);
750 enable_delete_variables (GtkWidget *w, gint var, gpointer data)
752 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
754 gtk_action_set_visible (de->delete_variables, var != -1);
757 /* Callback for when the datasheet/varsheet is selected */
759 on_switch_sheet (GtkNotebook *notebook,
760 GtkNotebookPage *page,
764 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (user_data);
766 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
768 GtkWidget *view_data =
769 gtk_ui_manager_get_widget (uim,"/ui/menubar/view/view_data");
771 GtkWidget *view_variables =
772 gtk_ui_manager_get_widget (uim,"/ui/menubar/view/view_variables");
776 case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
777 gtk_widget_hide (view_variables);
778 gtk_widget_show (view_data);
779 gtk_action_set_sensitive (de->insert_variable, TRUE);
780 gtk_action_set_sensitive (de->insert_case, FALSE);
781 gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE);
783 case PSPPIRE_DATA_EDITOR_DATA_VIEW:
784 gtk_widget_show (view_variables);
785 gtk_widget_hide (view_data);
786 gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE);
787 gtk_action_set_sensitive (de->insert_case, TRUE);
790 g_assert_not_reached ();
795 update_paste_menuitem (de, page_num);
802 set_unsaved (gpointer w)
804 psppire_window_set_unsaved (PSPPIRE_WINDOW (w));
808 /* Connects the action called ACTION_NAME to HANDLER passing DW as the auxilliary data.
809 Returns a pointer to the action
812 connect_action (PsppireDataWindow *dw, const char *action_name,
815 GtkAction *action = get_action_assert (dw->builder, action_name);
817 g_signal_connect_swapped (action, "activate", handler, dw);
822 /* Initializes as much of a PsppireDataWindow as we can and must before the
823 dataset has been set.
825 In particular, the 'menu' member is required in case the "filename" property
826 is set before the "dataset" property: otherwise PsppireWindow will try to
827 modify the menu as part of the "filename" property_set() function and end up
828 with a Gtk-CRITICAL since 'menu' is NULL. */
830 psppire_data_window_init (PsppireDataWindow *de)
834 de->builder = builder_new ("data-editor.ui");
836 uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
838 PSPPIRE_WINDOW (de)->menu =
839 GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar/windows/windows_minimise_all")->parent);
843 psppire_data_window_finish_init (PsppireDataWindow *de,
846 static const struct dataset_callbacks cbs =
848 set_unsaved, /* changed */
849 transformation_change_callback, /* transformations_changed */
858 GtkWidget *box = gtk_vbox_new (FALSE, 0);
861 dict = psppire_dict_new_from_dict (dataset_dict (ds));
862 de->var_store = psppire_var_store_new (dict);
863 de->data_store = psppire_data_store_new (dict);
864 psppire_data_store_set_reader (de->data_store, NULL);
866 menubar = get_widget_assert (de->builder, "menubar");
867 hb = get_widget_assert (de->builder, "handlebox1");
868 sb = get_widget_assert (de->builder, "status-bar");
871 PSPPIRE_DATA_EDITOR (psppire_data_editor_new (de, de->var_store,
874 g_signal_connect_swapped (de->data_store, "case-changed",
875 G_CALLBACK (set_unsaved), de);
877 g_signal_connect_swapped (de->data_store, "case-inserted",
878 G_CALLBACK (set_unsaved), de);
880 g_signal_connect_swapped (de->data_store, "cases-deleted",
881 G_CALLBACK (set_unsaved), de);
883 dataset_set_callbacks (de->dataset, &cbs, de);
885 connect_help (de->builder);
887 gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
888 gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
889 gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
890 gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
892 gtk_container_add (GTK_CONTAINER (de), box);
894 set_cut_copy_menuitem_sensitivity (de, FALSE);
896 g_signal_connect_swapped (de->data_editor, "data-selection-changed",
897 G_CALLBACK (set_cut_copy_menuitem_sensitivity), de);
900 set_paste_menuitem_sensitivity (de, FALSE);
902 g_signal_connect_swapped (de->data_editor, "data-available-changed",
903 G_CALLBACK (set_paste_menuitem_sensitivity), de);
905 g_signal_connect (dict, "weight-changed",
906 G_CALLBACK (on_weight_change),
909 g_signal_connect (dict, "filter-changed",
910 G_CALLBACK (on_filter_change),
913 g_signal_connect (dict, "split-changed",
914 G_CALLBACK (on_split_change),
918 connect_action (de, "edit_copy", G_CALLBACK (on_edit_copy));
920 connect_action (de, "edit_cut", G_CALLBACK (on_edit_cut));
922 connect_action (de, "file_new_data", G_CALLBACK (new_file));
924 connect_action (de, "file_import-text", G_CALLBACK (text_data_import_assistant));
926 connect_action (de, "file_save", G_CALLBACK (data_save));
928 connect_action (de, "file_open", G_CALLBACK (psppire_window_open));
930 connect_action (de, "file_save_as", G_CALLBACK (data_save_as_dialog));
932 connect_action (de, "file_information_working-file", G_CALLBACK (display_dict));
934 connect_action (de, "file_information_external-file", G_CALLBACK (sysfile_info));
936 connect_action (de, "edit_paste", G_CALLBACK (on_edit_paste));
938 de->insert_case = connect_action (de, "edit_insert-case", G_CALLBACK (insert_case));
940 de->insert_variable = connect_action (de, "action_insert-variable", G_CALLBACK (on_insert_variable));
942 de->invoke_goto_dialog = connect_action (de, "edit_goto-case", G_CALLBACK (goto_case_dialog));
944 g_signal_connect_swapped (get_action_assert (de->builder, "view_value-labels"), "toggled", G_CALLBACK (toggle_value_labels), de);
947 de->delete_cases = get_action_assert (de->builder, "edit_clear-cases");
949 g_signal_connect_swapped (de->delete_cases, "activate", G_CALLBACK (psppire_data_editor_delete_cases), de->data_editor);
951 gtk_action_set_visible (de->delete_cases, FALSE);
956 de->delete_variables = get_action_assert (de->builder, "edit_clear-variables");
958 g_signal_connect_swapped (de->delete_variables, "activate", G_CALLBACK (psppire_data_editor_delete_variables), de->data_editor);
960 gtk_action_set_visible (de->delete_variables, FALSE);
964 connect_action (de, "data_transpose", G_CALLBACK (transpose_dialog));
966 connect_action (de, "data_select-cases", G_CALLBACK (select_cases_dialog));
968 connect_action (de, "data_sort-cases", G_CALLBACK (sort_cases_dialog));
970 connect_action (de, "data_aggregate", G_CALLBACK (aggregate_dialog));
972 connect_action (de, "transform_compute", G_CALLBACK (compute_dialog));
974 connect_action (de, "edit_find", G_CALLBACK (find_dialog));
976 connect_action (de, "data_split-file", G_CALLBACK (split_file_dialog));
978 connect_action (de, "data_weight-cases", G_CALLBACK (weight_cases_dialog));
981 connect_action (de, "utilities_variables", G_CALLBACK (variable_info_dialog));
983 connect_action (de, "oneway-anova", G_CALLBACK (oneway_anova_dialog));
985 connect_action (de, "indep-t-test", G_CALLBACK (t_test_independent_samples_dialog));
987 connect_action (de, "paired-t-test", G_CALLBACK (t_test_paired_samples_dialog));
989 connect_action (de, "one-sample-t-test", G_CALLBACK (t_test_one_sample_dialog));
991 connect_action (de, "utilities_comments", G_CALLBACK (comments_dialog));
993 connect_action (de, "transform_rank", G_CALLBACK (rank_dialog));
995 connect_action (de, "transform_recode-same", G_CALLBACK (recode_same_dialog));
997 connect_action (de, "transform_recode-different", G_CALLBACK (recode_different_dialog));
999 connect_action (de, "analyze_descriptives", G_CALLBACK (descriptives_dialog));
1001 connect_action (de, "analyze_frequencies", G_CALLBACK (frequencies_dialog));
1003 connect_action (de, "crosstabs", G_CALLBACK (crosstabs_dialog));
1005 connect_action (de, "analyze_explore", G_CALLBACK (examine_dialog));
1007 connect_action (de, "linear-regression", G_CALLBACK (regression_dialog));
1009 connect_action (de, "reliability", G_CALLBACK (reliability_dialog));
1011 connect_action (de, "roc-curve", G_CALLBACK (roc_dialog));
1013 connect_action (de, "correlation", G_CALLBACK (correlation_dialog));
1015 connect_action (de, "factor-analysis", G_CALLBACK (factor_dialog));
1017 connect_action (de, "chi-square", G_CALLBACK (chisquare_dialog));
1019 connect_action (de, "binomial", G_CALLBACK (binomial_dialog));
1021 connect_action (de, "k-related-samples", G_CALLBACK (k_related_dialog));
1025 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
1027 GtkWidget *recent_data =
1028 gtk_ui_manager_get_widget (uim,"/ui/menubar/file/file_recent-data");
1030 GtkWidget *recent_files =
1031 gtk_ui_manager_get_widget (uim,"/ui/menubar/file/file_recent-files");
1034 GtkWidget *menu_data =
1035 gtk_recent_chooser_menu_new_for_manager (the_recent_mgr);
1037 GtkWidget *menu_files =
1038 gtk_recent_chooser_menu_new_for_manager (the_recent_mgr);
1041 GtkRecentFilter *filter = gtk_recent_filter_new ();
1043 gtk_recent_filter_add_pattern (filter, "*.sav");
1044 gtk_recent_filter_add_pattern (filter, "*.SAV");
1045 gtk_recent_filter_add_pattern (filter, "*.por");
1046 gtk_recent_filter_add_pattern (filter, "*.POR");
1048 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_data), GTK_RECENT_SORT_MRU);
1050 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_data), filter);
1053 gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu_data);
1056 g_signal_connect (menu_data, "selection-done", G_CALLBACK (on_recent_data_select), de);
1059 GtkRecentFilter *filter = gtk_recent_filter_new ();
1061 gtk_recent_filter_add_pattern (filter, "*.sps");
1062 gtk_recent_filter_add_pattern (filter, "*.SPS");
1064 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_files), GTK_RECENT_SORT_MRU);
1066 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_files), filter);
1069 gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu_files);
1071 g_signal_connect (menu_files, "selection-done", G_CALLBACK (on_recent_files_select), de);
1075 connect_action (de, "file_new_syntax", G_CALLBACK (create_syntax_window));
1078 g_signal_connect (de->data_editor,
1080 G_CALLBACK (enable_delete_cases),
1083 g_signal_connect (de->data_editor,
1084 "variables-selected",
1085 G_CALLBACK (enable_delete_variables),
1089 g_signal_connect (de->data_editor,
1091 G_CALLBACK (on_switch_sheet), de);
1093 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
1094 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
1096 connect_action (de, "view_statusbar", G_CALLBACK (status_bar_activate));
1098 connect_action (de, "view_gridlines", G_CALLBACK (grid_lines_activate));
1100 connect_action (de, "view_data", G_CALLBACK (data_view_activate));
1102 connect_action (de, "view_variables", G_CALLBACK (variable_view_activate));
1104 connect_action (de, "view_fonts", G_CALLBACK (fonts_activate));
1106 connect_action (de, "file_quit", G_CALLBACK (file_quit));
1108 connect_action (de, "transform_run-pending", G_CALLBACK (execute));
1110 connect_action (de, "windows_minimise_all", G_CALLBACK (psppire_window_minimise_all));
1112 g_signal_connect_swapped (get_action_assert (de->builder, "windows_split"), "toggled", G_CALLBACK (toggle_split_window), de);
1115 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
1117 merge_help_menu (uim);
1121 GtkWidget *data_sheet_cases_popup_menu = get_widget_assert (de->builder,
1122 "datasheet-cases-popup");
1124 GtkWidget *var_sheet_variable_popup_menu = get_widget_assert (de->builder,
1125 "varsheet-variable-popup");
1127 GtkWidget *data_sheet_variable_popup_menu = get_widget_assert (de->builder,
1128 "datasheet-variable-popup");
1130 g_signal_connect_swapped (get_action_assert (de->builder, "sort-up"), "activate",
1131 G_CALLBACK (psppire_data_editor_sort_ascending),
1134 g_signal_connect_swapped (get_action_assert (de->builder, "sort-down"), "activate",
1135 G_CALLBACK (psppire_data_editor_sort_descending),
1138 g_object_set (de->data_editor,
1139 "datasheet-column-menu", data_sheet_variable_popup_menu,
1140 "datasheet-row-menu", data_sheet_cases_popup_menu,
1141 "varsheet-row-menu", var_sheet_variable_popup_menu,
1145 gtk_widget_show (GTK_WIDGET (de->data_editor));
1146 gtk_widget_show (box);
1148 the_data_window = de;
1152 psppire_data_window_dispose (GObject *object)
1154 PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
1156 if (dw->builder != NULL)
1158 g_object_unref (dw->builder);
1162 if (the_data_window == dw)
1163 the_data_window = NULL;
1165 G_OBJECT_CLASS (parent_class)->dispose (object);
1169 psppire_data_window_set_property (GObject *object,
1171 const GValue *value,
1174 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1179 psppire_data_window_finish_init (window, g_value_get_pointer (value));
1182 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1188 psppire_data_window_get_property (GObject *object,
1193 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1198 g_value_set_pointer (value, window->dataset);
1201 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1208 psppire_data_window_new (struct dataset *ds)
1212 psppire_data_window_get_type (),
1213 /* TRANSLATORS: This will form a filename. Please avoid whitespace. */
1214 "filename", _("PSPP-data"),
1215 "description", _("Data Editor"),
1222 psppire_data_window_iface_init (PsppireWindowIface *iface)
1224 iface->save = save_file;
1225 iface->load = load_file;
1230 psppire_default_data_window (void)
1232 if (the_data_window == NULL)
1233 gtk_widget_show (psppire_data_window_new (dataset_create ()));
1234 return the_data_window;