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 "data/session.h"
24 #include "language/lexer/lexer.h"
25 #include "libpspp/message.h"
26 #include "ui/gui/aggregate-dialog.h"
27 #include "ui/gui/binomial-dialog.h"
28 #include "ui/gui/chi-square-dialog.h"
29 #include "ui/gui/comments-dialog.h"
30 #include "ui/gui/compute-dialog.h"
31 #include "ui/gui/correlation-dialog.h"
32 #include "ui/gui/crosstabs-dialog.h"
33 #include "ui/gui/descriptives-dialog.h"
34 #include "ui/gui/entry-dialog.h"
35 #include "ui/gui/examine-dialog.h"
36 #include "ui/gui/executor.h"
37 #include "ui/gui/factor-dialog.h"
38 #include "ui/gui/find-dialog.h"
39 #include "ui/gui/frequencies-dialog.h"
40 #include "ui/gui/goto-case-dialog.h"
41 #include "ui/gui/help-menu.h"
42 #include "ui/gui/helper.h"
43 #include "ui/gui/k-related-dialog.h"
44 #include "ui/gui/oneway-anova-dialog.h"
45 #include "ui/gui/psppire-data-window.h"
46 #include "ui/gui/psppire-syntax-window.h"
47 #include "ui/gui/psppire-window.h"
48 #include "ui/gui/psppire.h"
49 #include "ui/gui/rank-dialog.h"
50 #include "ui/gui/recode-dialog.h"
51 #include "ui/gui/regression-dialog.h"
52 #include "ui/gui/reliability-dialog.h"
53 #include "ui/gui/roc-dialog.h"
54 #include "ui/gui/select-cases-dialog.h"
55 #include "ui/gui/sort-cases-dialog.h"
56 #include "ui/gui/split-file-dialog.h"
57 #include "ui/gui/t-test-independent-samples-dialog.h"
58 #include "ui/gui/t-test-one-sample.h"
59 #include "ui/gui/t-test-paired-samples.h"
60 #include "ui/gui/text-data-import-dialog.h"
61 #include "ui/gui/transpose-dialog.h"
62 #include "ui/gui/variable-info-dialog.h"
63 #include "ui/gui/weight-cases-dialog.h"
64 #include "ui/syntax-gen.h"
66 #include "gl/xvasprintf.h"
69 #define _(msgid) gettext (msgid)
70 #define N_(msgid) msgid
72 struct session *the_session;
73 struct ll_list all_data_windows = LL_INITIALIZER (all_data_windows);
75 static void psppire_data_window_class_init (PsppireDataWindowClass *class);
76 static void psppire_data_window_init (PsppireDataWindow *data_editor);
79 static void psppire_data_window_iface_init (PsppireWindowIface *iface);
81 static void psppire_data_window_dispose (GObject *object);
82 static void psppire_data_window_set_property (GObject *object,
86 static void psppire_data_window_get_property (GObject *object,
92 psppire_data_window_get_type (void)
94 static GType psppire_data_window_type = 0;
96 if (!psppire_data_window_type)
98 static const GTypeInfo psppire_data_window_info =
100 sizeof (PsppireDataWindowClass),
103 (GClassInitFunc)psppire_data_window_class_init,
104 (GClassFinalizeFunc) NULL,
106 sizeof (PsppireDataWindow),
108 (GInstanceInitFunc) psppire_data_window_init,
111 static const GInterfaceInfo window_interface_info =
113 (GInterfaceInitFunc) psppire_data_window_iface_init,
118 psppire_data_window_type =
119 g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireDataWindow",
120 &psppire_data_window_info, 0);
123 g_type_add_interface_static (psppire_data_window_type,
124 PSPPIRE_TYPE_WINDOW_MODEL,
125 &window_interface_info);
128 return psppire_data_window_type;
131 static GObjectClass *parent_class ;
138 psppire_data_window_class_init (PsppireDataWindowClass *class)
140 GObjectClass *object_class = G_OBJECT_CLASS (class);
142 parent_class = g_type_class_peek_parent (class);
144 object_class->dispose = psppire_data_window_dispose;
145 object_class->set_property = psppire_data_window_set_property;
146 object_class->get_property = psppire_data_window_get_property;
148 g_object_class_install_property (
149 object_class, PROP_DATASET,
150 g_param_spec_pointer ("dataset", "Dataset",
151 "'struct datset *' represented by the window",
152 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
156 set_paste_menuitem_sensitivity (PsppireDataWindow *de, gboolean x)
158 GtkAction *edit_paste = get_action_assert (de->builder, "edit_paste");
160 gtk_action_set_sensitive (edit_paste, x);
164 set_cut_copy_menuitem_sensitivity (PsppireDataWindow *de, gboolean x)
166 GtkAction *edit_copy = get_action_assert (de->builder, "edit_copy");
167 GtkAction *edit_cut = get_action_assert (de->builder, "edit_cut");
169 gtk_action_set_sensitive (edit_copy, x);
170 gtk_action_set_sensitive (edit_cut, x);
173 /* Run the EXECUTE command. */
175 execute (PsppireDataWindow *dw)
177 execute_const_syntax_string (dw, "EXECUTE.");
181 transformation_change_callback (bool transformations_pending,
184 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
186 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
188 GtkWidget *menuitem =
189 gtk_ui_manager_get_widget (uim,"/ui/menubar/transform/transform_run-pending");
191 GtkWidget *status_label =
192 get_widget_assert (de->builder, "case-counter-area");
194 gtk_widget_set_sensitive (menuitem, transformations_pending);
197 if ( transformations_pending)
198 gtk_label_set_text (GTK_LABEL (status_label),
199 _("Transformations Pending"));
201 gtk_label_set_text (GTK_LABEL (status_label), "");
204 /* Callback for when the dictionary changes its filter variable */
206 on_filter_change (GObject *o, gint filter_index, gpointer data)
208 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
210 GtkWidget *filter_status_area =
211 get_widget_assert (de->builder, "filter-use-status-area");
213 if ( filter_index == -1 )
215 gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
219 PsppireVarStore *vs = NULL;
220 PsppireDict *dict = NULL;
221 struct variable *var ;
224 g_object_get (de->data_editor, "var-store", &vs, NULL);
225 g_object_get (vs, "dictionary", &dict, NULL);
227 var = psppire_dict_get_variable (dict, filter_index);
229 text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
231 gtk_label_set_text (GTK_LABEL (filter_status_area), text);
237 /* Callback for when the dictionary changes its split variables */
239 on_split_change (PsppireDict *dict, gpointer data)
241 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
243 size_t n_split_vars = dict_get_split_cnt (dict->dict);
245 GtkWidget *split_status_area =
246 get_widget_assert (de->builder, "split-file-status-area");
248 if ( n_split_vars == 0 )
250 gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
256 const struct variable *const * split_vars =
257 dict_get_split_vars (dict->dict);
259 text = g_string_new (_("Split by "));
261 for (i = 0 ; i < n_split_vars - 1; ++i )
263 g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
265 g_string_append (text, var_get_name (split_vars[i]));
267 gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
269 g_string_free (text, TRUE);
276 /* Callback for when the dictionary changes its weights */
278 on_weight_change (GObject *o, gint weight_index, gpointer data)
280 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
282 GtkWidget *weight_status_area =
283 get_widget_assert (de->builder, "weight-status-area");
285 if ( weight_index == -1 )
287 gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
291 struct variable *var ;
292 PsppireVarStore *vs = NULL;
293 PsppireDict *dict = NULL;
296 g_object_get (de->data_editor, "var-store", &vs, NULL);
297 g_object_get (vs, "dictionary", &dict, NULL);
299 var = psppire_dict_get_variable (dict, weight_index);
301 text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
303 gtk_label_set_text (GTK_LABEL (weight_status_area), text);
311 dump_rm (GtkRecentManager *rm)
313 GList *items = gtk_recent_manager_get_items (rm);
317 g_print ("Recent Items:\n");
318 for (i = items; i; i = i->next)
320 GtkRecentInfo *ri = i->data;
322 g_print ("Item: %s (Mime: %s) (Desc: %s) (URI: %s)\n",
323 gtk_recent_info_get_short_name (ri),
324 gtk_recent_info_get_mime_type (ri),
325 gtk_recent_info_get_description (ri),
326 gtk_recent_info_get_uri (ri)
330 gtk_recent_info_unref (ri);
339 load_file (PsppireWindow *de, const gchar *file_name)
341 gchar *utf8_file_name;
342 struct string filename;
346 ds_init_empty (&filename);
348 utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL, NULL);
350 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
352 g_free (utf8_file_name);
354 syntax = g_strdup_printf ("GET FILE=%s.", ds_cstr (&filename));
355 ds_destroy (&filename);
357 ok = execute_syntax (PSPPIRE_DATA_WINDOW (de),
358 lex_reader_for_string (syntax));
363 /* Returns true if NAME has a suffix which might denote a PSPP file */
365 name_has_suffix (const gchar *name)
367 if ( g_str_has_suffix (name, ".sav"))
369 if ( g_str_has_suffix (name, ".SAV"))
371 if ( g_str_has_suffix (name, ".por"))
373 if ( g_str_has_suffix (name, ".POR"))
380 /* Save DE to file */
382 save_file (PsppireWindow *w)
384 const gchar *file_name = NULL;
385 gchar *utf8_file_name = NULL;
387 struct string filename ;
388 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (w);
391 file_name = psppire_window_get_filename (w);
393 fnx = g_string_new (file_name);
395 if ( ! name_has_suffix (fnx->str))
397 if ( de->save_as_portable)
398 g_string_append (fnx, ".por");
400 g_string_append (fnx, ".sav");
403 ds_init_empty (&filename);
405 utf8_file_name = g_filename_to_utf8 (fnx->str, -1, NULL, NULL, NULL);
407 g_string_free (fnx, TRUE);
409 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
410 g_free (utf8_file_name);
412 syntax = g_strdup_printf ("%s OUTFILE=%s.",
413 de->save_as_portable ? "EXPORT" : "SAVE",
414 ds_cstr (&filename));
416 ds_destroy (&filename);
418 g_free (execute_syntax_string (de, syntax));
423 insert_case (PsppireDataWindow *dw)
425 psppire_data_editor_insert_case (dw->data_editor);
429 on_insert_variable (PsppireDataWindow *dw)
431 psppire_data_editor_insert_variable (dw->data_editor);
436 display_dict (PsppireDataWindow *de)
438 execute_const_syntax_string (de, "DISPLAY DICTIONARY.");
442 sysfile_info (PsppireDataWindow *de)
444 GtkWidget *dialog = psppire_window_file_chooser_dialog (PSPPIRE_WINDOW (de));
446 if ( GTK_RESPONSE_ACCEPT == gtk_dialog_run (GTK_DIALOG (dialog)))
448 struct string filename;
450 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
452 gchar *utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL,
457 ds_init_empty (&filename);
459 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
461 g_free (utf8_file_name);
463 syntax = g_strdup_printf ("SYSFILE INFO %s.", ds_cstr (&filename));
464 g_free (execute_syntax_string (de, syntax));
467 gtk_widget_destroy (dialog);
471 /* PsppireWindow 'pick_filename' callback: prompt for a filename to save as. */
473 data_pick_filename (PsppireWindow *window)
475 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (window);
476 GtkWidget *button_sys;
478 gtk_file_chooser_dialog_new (_("Save"),
480 GTK_FILE_CHOOSER_ACTION_SAVE,
481 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
482 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
485 GtkFileFilter *filter = gtk_file_filter_new ();
486 gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
487 gtk_file_filter_add_pattern (filter, "*.sav");
488 gtk_file_filter_add_pattern (filter, "*.SAV");
489 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
491 filter = gtk_file_filter_new ();
492 gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
493 gtk_file_filter_add_pattern (filter, "*.por");
494 gtk_file_filter_add_pattern (filter, "*.POR");
495 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
497 filter = gtk_file_filter_new ();
498 gtk_file_filter_set_name (filter, _("All Files"));
499 gtk_file_filter_add_pattern (filter, "*");
500 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
503 GtkWidget *button_por;
504 GtkWidget *vbox = gtk_vbox_new (TRUE, 5);
506 gtk_radio_button_new_with_label (NULL, _("System File"));
509 gtk_radio_button_new_with_label
510 (gtk_radio_button_get_group (GTK_RADIO_BUTTON(button_sys)),
513 psppire_box_pack_start_defaults (GTK_BOX (vbox), button_sys);
514 psppire_box_pack_start_defaults (GTK_BOX (vbox), button_por);
516 gtk_widget_show_all (vbox);
518 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), vbox);
521 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
524 switch (gtk_dialog_run (GTK_DIALOG (dialog)))
526 case GTK_RESPONSE_ACCEPT:
531 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog))
534 de->save_as_portable =
535 ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys));
537 if ( ! name_has_suffix (filename->str))
539 if ( de->save_as_portable)
540 g_string_append (filename, ".por");
542 g_string_append (filename, ".sav");
545 psppire_window_set_filename (PSPPIRE_WINDOW (de), filename->str);
547 g_string_free (filename, TRUE);
554 gtk_widget_destroy (dialog);
558 confirm_delete_dataset (PsppireDataWindow *de,
559 const char *old_dataset,
560 const char *new_dataset,
561 const char *existing_dataset)
566 dialog = gtk_message_dialog_new (
567 GTK_WINDOW (de), 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s",
568 _("Delete Existing Dataset?"));
570 gtk_message_dialog_format_secondary_text (
571 GTK_MESSAGE_DIALOG (dialog),
572 _("Renaming \"%s\" to \"%s\" will delete destroy the existing "
573 "dataset named \"%s\". Are you sure that you want to do this?"),
574 old_dataset, new_dataset, existing_dataset);
576 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
577 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
578 GTK_STOCK_DELETE, GTK_RESPONSE_OK,
581 g_object_set (dialog, "icon-name", "psppicon", NULL);
583 result = gtk_dialog_run (GTK_DIALOG (dialog));
585 gtk_widget_destroy (dialog);
587 return result == GTK_RESPONSE_OK;
591 on_rename_dataset (PsppireDataWindow *de)
593 struct dataset *ds = de->dataset;
594 struct session *session = dataset_session (ds);
595 const char *old_name = dataset_name (ds);
596 struct dataset *existing_dataset;
600 prompt = xasprintf (_("Please enter a new name for dataset \"%s\":"),
602 new_name = entry_dialog_run (GTK_WINDOW (de), _("Rename Dataset"), prompt,
606 if (new_name == NULL)
609 existing_dataset = session_lookup_dataset (session, new_name);
610 if (existing_dataset == NULL || existing_dataset == ds
611 || confirm_delete_dataset (de, old_name, new_name,
612 dataset_name (existing_dataset)))
613 g_free (execute_syntax_string (de, g_strdup_printf ("DATASET NAME %s.",
620 on_edit_paste (PsppireDataWindow *de)
622 psppire_data_editor_clip_paste (de->data_editor);
626 on_edit_copy (PsppireDataWindow *de)
628 psppire_data_editor_clip_copy (de->data_editor);
634 on_edit_cut (PsppireDataWindow *de)
636 psppire_data_editor_clip_cut (de->data_editor);
641 status_bar_activate (PsppireDataWindow *de, GtkToggleAction *action)
643 GtkWidget *statusbar = get_widget_assert (de->builder, "status-bar");
645 if ( gtk_toggle_action_get_active (action))
646 gtk_widget_show (statusbar);
648 gtk_widget_hide (statusbar);
653 grid_lines_activate (PsppireDataWindow *de, GtkToggleAction *action)
655 const gboolean grid_visible = gtk_toggle_action_get_active (action);
657 psppire_data_editor_show_grid (de->data_editor, grid_visible);
661 data_view_activate (PsppireDataWindow *de)
663 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
668 variable_view_activate (PsppireDataWindow *de)
670 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
675 fonts_activate (PsppireDataWindow *de)
677 GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (de));
678 PangoFontDescription *current_font;
681 gtk_font_selection_dialog_new (_("Font Selection"));
684 current_font = GTK_WIDGET(de->data_editor)->style->font_desc;
685 font_name = pango_font_description_to_string (current_font);
687 gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name);
691 gtk_window_set_transient_for (GTK_WINDOW (dialog),
692 GTK_WINDOW (toplevel));
694 if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) )
696 const gchar *font = gtk_font_selection_dialog_get_font_name
697 (GTK_FONT_SELECTION_DIALOG (dialog));
699 PangoFontDescription* font_desc =
700 pango_font_description_from_string (font);
702 psppire_data_editor_set_font (de->data_editor, font_desc);
705 gtk_widget_hide (dialog);
710 /* Callback for the value labels action */
712 toggle_value_labels (PsppireDataWindow *de, GtkToggleAction *ta)
714 g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL);
718 toggle_split_window (PsppireDataWindow *de, GtkToggleAction *ta)
720 psppire_data_editor_split_window (de->data_editor,
721 gtk_toggle_action_get_active (ta));
726 file_quit (PsppireDataWindow *de)
728 /* FIXME: Need to be more intelligent here.
729 Give the user the opportunity to save any unsaved data.
736 on_recent_data_select (GtkMenuShell *menushell,
737 PsppireWindow *window)
742 gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
744 file = g_filename_from_uri (uri, NULL, NULL);
748 open_data_window (window, file);
754 on_recent_files_select (GtkMenuShell *menushell, gpointer user_data)
761 gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
763 file = g_filename_from_uri (uri, NULL, NULL);
767 se = psppire_syntax_window_new ();
769 if ( psppire_window_load (PSPPIRE_WINDOW (se), file) )
770 gtk_widget_show (se);
772 gtk_widget_destroy (se);
779 enable_delete_cases (GtkWidget *w, gint case_num, gpointer data)
781 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
783 gtk_action_set_visible (de->delete_cases, case_num != -1);
788 enable_delete_variables (GtkWidget *w, gint var, gpointer data)
790 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
792 gtk_action_set_visible (de->delete_variables, var != -1);
795 /* Callback for when the datasheet/varsheet is selected */
797 on_switch_sheet (GtkNotebook *notebook,
798 GtkNotebookPage *page,
802 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (user_data);
804 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
806 GtkWidget *view_data =
807 gtk_ui_manager_get_widget (uim,"/ui/menubar/view/view_data");
809 GtkWidget *view_variables =
810 gtk_ui_manager_get_widget (uim,"/ui/menubar/view/view_variables");
814 case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
815 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (view_variables),
817 gtk_action_set_sensitive (de->insert_variable, TRUE);
818 gtk_action_set_sensitive (de->insert_case, FALSE);
819 gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE);
821 case PSPPIRE_DATA_EDITOR_DATA_VIEW:
822 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (view_data), TRUE);
823 gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE);
824 gtk_action_set_sensitive (de->insert_case, TRUE);
827 g_assert_not_reached ();
832 update_paste_menuitem (de, page_num);
839 set_unsaved (gpointer w)
841 psppire_window_set_unsaved (PSPPIRE_WINDOW (w));
845 /* Connects the action called ACTION_NAME to HANDLER passing DW as the auxilliary data.
846 Returns a pointer to the action
849 connect_action (PsppireDataWindow *dw, const char *action_name,
852 GtkAction *action = get_action_assert (dw->builder, action_name);
854 g_signal_connect_swapped (action, "activate", handler, dw);
859 /* Initializes as much of a PsppireDataWindow as we can and must before the
860 dataset has been set.
862 In particular, the 'menu' member is required in case the "filename" property
863 is set before the "dataset" property: otherwise PsppireWindow will try to
864 modify the menu as part of the "filename" property_set() function and end up
865 with a Gtk-CRITICAL since 'menu' is NULL. */
867 psppire_data_window_init (PsppireDataWindow *de)
871 de->builder = builder_new ("data-editor.ui");
873 uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
875 PSPPIRE_WINDOW (de)->menu =
876 GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar/windows/windows_minimise_all")->parent);
880 psppire_data_window_finish_init (PsppireDataWindow *de,
883 static const struct dataset_callbacks cbs =
885 set_unsaved, /* changed */
886 transformation_change_callback, /* transformations_changed */
895 GtkWidget *box = gtk_vbox_new (FALSE, 0);
898 dict = psppire_dict_new_from_dict (dataset_dict (ds));
899 de->var_store = psppire_var_store_new (dict);
900 de->data_store = psppire_data_store_new (dict);
901 psppire_data_store_set_reader (de->data_store, NULL);
903 menubar = get_widget_assert (de->builder, "menubar");
904 hb = get_widget_assert (de->builder, "handlebox1");
905 sb = get_widget_assert (de->builder, "status-bar");
908 PSPPIRE_DATA_EDITOR (psppire_data_editor_new (de, de->var_store,
911 g_signal_connect_swapped (de->data_store, "case-changed",
912 G_CALLBACK (set_unsaved), de);
914 g_signal_connect_swapped (de->data_store, "case-inserted",
915 G_CALLBACK (set_unsaved), de);
917 g_signal_connect_swapped (de->data_store, "cases-deleted",
918 G_CALLBACK (set_unsaved), de);
920 dataset_set_callbacks (de->dataset, &cbs, de);
922 connect_help (de->builder);
924 gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
925 gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
926 gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
927 gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
929 gtk_container_add (GTK_CONTAINER (de), box);
931 set_cut_copy_menuitem_sensitivity (de, FALSE);
933 g_signal_connect_swapped (de->data_editor, "data-selection-changed",
934 G_CALLBACK (set_cut_copy_menuitem_sensitivity), de);
937 set_paste_menuitem_sensitivity (de, FALSE);
939 g_signal_connect_swapped (de->data_editor, "data-available-changed",
940 G_CALLBACK (set_paste_menuitem_sensitivity), de);
942 g_signal_connect (dict, "weight-changed",
943 G_CALLBACK (on_weight_change),
946 g_signal_connect (dict, "filter-changed",
947 G_CALLBACK (on_filter_change),
950 g_signal_connect (dict, "split-changed",
951 G_CALLBACK (on_split_change),
955 connect_action (de, "edit_copy", G_CALLBACK (on_edit_copy));
957 connect_action (de, "edit_cut", G_CALLBACK (on_edit_cut));
959 connect_action (de, "file_new_data", G_CALLBACK (create_data_window));
961 connect_action (de, "file_import-text", G_CALLBACK (text_data_import_assistant));
963 connect_action (de, "file_save", G_CALLBACK (psppire_window_save));
965 connect_action (de, "file_open", G_CALLBACK (psppire_window_open));
967 connect_action (de, "file_save_as", G_CALLBACK (psppire_window_save_as));
969 connect_action (de, "rename_dataset", G_CALLBACK (on_rename_dataset));
971 connect_action (de, "file_information_working-file", G_CALLBACK (display_dict));
973 connect_action (de, "file_information_external-file", G_CALLBACK (sysfile_info));
975 connect_action (de, "edit_paste", G_CALLBACK (on_edit_paste));
977 de->insert_case = connect_action (de, "edit_insert-case", G_CALLBACK (insert_case));
979 de->insert_variable = connect_action (de, "action_insert-variable", G_CALLBACK (on_insert_variable));
981 de->invoke_goto_dialog = connect_action (de, "edit_goto-case", G_CALLBACK (goto_case_dialog));
983 g_signal_connect_swapped (get_action_assert (de->builder, "view_value-labels"), "toggled", G_CALLBACK (toggle_value_labels), de);
986 de->delete_cases = get_action_assert (de->builder, "edit_clear-cases");
988 g_signal_connect_swapped (de->delete_cases, "activate", G_CALLBACK (psppire_data_editor_delete_cases), de->data_editor);
990 gtk_action_set_visible (de->delete_cases, FALSE);
995 de->delete_variables = get_action_assert (de->builder, "edit_clear-variables");
997 g_signal_connect_swapped (de->delete_variables, "activate", G_CALLBACK (psppire_data_editor_delete_variables), de->data_editor);
999 gtk_action_set_visible (de->delete_variables, FALSE);
1003 connect_action (de, "data_transpose", G_CALLBACK (transpose_dialog));
1005 connect_action (de, "data_select-cases", G_CALLBACK (select_cases_dialog));
1007 connect_action (de, "data_sort-cases", G_CALLBACK (sort_cases_dialog));
1009 connect_action (de, "data_aggregate", G_CALLBACK (aggregate_dialog));
1011 connect_action (de, "transform_compute", G_CALLBACK (compute_dialog));
1013 connect_action (de, "edit_find", G_CALLBACK (find_dialog));
1015 connect_action (de, "data_split-file", G_CALLBACK (split_file_dialog));
1017 connect_action (de, "data_weight-cases", G_CALLBACK (weight_cases_dialog));
1020 connect_action (de, "utilities_variables", G_CALLBACK (variable_info_dialog));
1022 connect_action (de, "oneway-anova", G_CALLBACK (oneway_anova_dialog));
1024 connect_action (de, "indep-t-test", G_CALLBACK (t_test_independent_samples_dialog));
1026 connect_action (de, "paired-t-test", G_CALLBACK (t_test_paired_samples_dialog));
1028 connect_action (de, "one-sample-t-test", G_CALLBACK (t_test_one_sample_dialog));
1030 connect_action (de, "utilities_comments", G_CALLBACK (comments_dialog));
1032 connect_action (de, "transform_rank", G_CALLBACK (rank_dialog));
1034 connect_action (de, "transform_recode-same", G_CALLBACK (recode_same_dialog));
1036 connect_action (de, "transform_recode-different", G_CALLBACK (recode_different_dialog));
1038 connect_action (de, "analyze_descriptives", G_CALLBACK (descriptives_dialog));
1040 connect_action (de, "analyze_frequencies", G_CALLBACK (frequencies_dialog));
1042 connect_action (de, "crosstabs", G_CALLBACK (crosstabs_dialog));
1044 connect_action (de, "analyze_explore", G_CALLBACK (examine_dialog));
1046 connect_action (de, "linear-regression", G_CALLBACK (regression_dialog));
1048 connect_action (de, "reliability", G_CALLBACK (reliability_dialog));
1050 connect_action (de, "roc-curve", G_CALLBACK (roc_dialog));
1052 connect_action (de, "correlation", G_CALLBACK (correlation_dialog));
1054 connect_action (de, "factor-analysis", G_CALLBACK (factor_dialog));
1056 connect_action (de, "chi-square", G_CALLBACK (chisquare_dialog));
1058 connect_action (de, "binomial", G_CALLBACK (binomial_dialog));
1060 connect_action (de, "k-related-samples", G_CALLBACK (k_related_dialog));
1064 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
1066 GtkWidget *recent_data =
1067 gtk_ui_manager_get_widget (uim,"/ui/menubar/file/file_recent-data");
1069 GtkWidget *recent_files =
1070 gtk_ui_manager_get_widget (uim,"/ui/menubar/file/file_recent-files");
1073 GtkWidget *menu_data = gtk_recent_chooser_menu_new_for_manager (
1074 gtk_recent_manager_get_default ());
1076 GtkWidget *menu_files = gtk_recent_chooser_menu_new_for_manager (
1077 gtk_recent_manager_get_default ());
1080 GtkRecentFilter *filter = gtk_recent_filter_new ();
1082 gtk_recent_filter_add_pattern (filter, "*.sav");
1083 gtk_recent_filter_add_pattern (filter, "*.SAV");
1084 gtk_recent_filter_add_pattern (filter, "*.por");
1085 gtk_recent_filter_add_pattern (filter, "*.POR");
1087 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_data), GTK_RECENT_SORT_MRU);
1089 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_data), filter);
1092 gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu_data);
1095 g_signal_connect (menu_data, "selection-done", G_CALLBACK (on_recent_data_select), de);
1098 GtkRecentFilter *filter = gtk_recent_filter_new ();
1100 gtk_recent_filter_add_pattern (filter, "*.sps");
1101 gtk_recent_filter_add_pattern (filter, "*.SPS");
1103 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_files), GTK_RECENT_SORT_MRU);
1105 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_files), filter);
1108 gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu_files);
1110 g_signal_connect (menu_files, "selection-done", G_CALLBACK (on_recent_files_select), de);
1114 connect_action (de, "file_new_syntax", G_CALLBACK (create_syntax_window));
1117 g_signal_connect (de->data_editor,
1119 G_CALLBACK (enable_delete_cases),
1122 g_signal_connect (de->data_editor,
1123 "variables-selected",
1124 G_CALLBACK (enable_delete_variables),
1128 g_signal_connect (de->data_editor,
1130 G_CALLBACK (on_switch_sheet), de);
1132 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
1133 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
1135 connect_action (de, "view_statusbar", G_CALLBACK (status_bar_activate));
1137 connect_action (de, "view_gridlines", G_CALLBACK (grid_lines_activate));
1139 connect_action (de, "view_data", G_CALLBACK (data_view_activate));
1141 connect_action (de, "view_variables", G_CALLBACK (variable_view_activate));
1143 connect_action (de, "view_fonts", G_CALLBACK (fonts_activate));
1145 connect_action (de, "file_quit", G_CALLBACK (file_quit));
1147 connect_action (de, "transform_run-pending", G_CALLBACK (execute));
1149 connect_action (de, "windows_minimise_all", G_CALLBACK (psppire_window_minimise_all));
1151 g_signal_connect_swapped (get_action_assert (de->builder, "windows_split"), "toggled", G_CALLBACK (toggle_split_window), de);
1154 GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER));
1156 merge_help_menu (uim);
1160 GtkWidget *data_sheet_cases_popup_menu = get_widget_assert (de->builder,
1161 "datasheet-cases-popup");
1163 GtkWidget *var_sheet_variable_popup_menu = get_widget_assert (de->builder,
1164 "varsheet-variable-popup");
1166 GtkWidget *data_sheet_variable_popup_menu = get_widget_assert (de->builder,
1167 "datasheet-variable-popup");
1169 g_signal_connect_swapped (get_action_assert (de->builder, "sort-up"), "activate",
1170 G_CALLBACK (psppire_data_editor_sort_ascending),
1173 g_signal_connect_swapped (get_action_assert (de->builder, "sort-down"), "activate",
1174 G_CALLBACK (psppire_data_editor_sort_descending),
1177 g_object_set (de->data_editor,
1178 "datasheet-column-menu", data_sheet_variable_popup_menu,
1179 "datasheet-row-menu", data_sheet_cases_popup_menu,
1180 "varsheet-row-menu", var_sheet_variable_popup_menu,
1184 gtk_widget_show (GTK_WIDGET (de->data_editor));
1185 gtk_widget_show (box);
1187 ll_push_head (&all_data_windows, &de->ll);
1191 psppire_data_window_dispose (GObject *object)
1193 PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
1195 if (dw->builder != NULL)
1197 g_object_unref (dw->builder);
1203 g_object_unref (dw->var_store);
1204 dw->var_store = NULL;
1209 g_object_unref (dw->data_store);
1210 dw->data_store = NULL;
1213 if (dw->ll.next != NULL)
1215 ll_remove (&dw->ll);
1219 if (G_OBJECT_CLASS (parent_class)->dispose)
1220 G_OBJECT_CLASS (parent_class)->dispose (object);
1224 psppire_data_window_set_property (GObject *object,
1226 const GValue *value,
1229 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1234 psppire_data_window_finish_init (window, g_value_get_pointer (value));
1237 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1243 psppire_data_window_get_property (GObject *object,
1248 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1253 g_value_set_pointer (value, window->dataset);
1256 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1262 psppire_data_window_new (struct dataset *ds)
1266 if (the_session == NULL)
1267 the_session = session_create ();
1271 static int n_datasets;
1274 dataset_name = xasprintf ("DataSet%d", ++n_datasets);
1275 ds = dataset_create (the_session, dataset_name);
1276 free (dataset_name);
1278 assert (dataset_session (ds) == the_session);
1282 psppire_data_window_get_type (),
1283 /* TRANSLATORS: This will form a filename. Please avoid whitespace. */
1284 "description", _("Data Editor"),
1288 if (dataset_name (ds) != NULL)
1289 g_object_set (dw, "id", dataset_name (ds), (void *) NULL);
1295 psppire_data_window_is_empty (PsppireDataWindow *dw)
1297 return psppire_var_store_get_var_cnt (dw->var_store) == 0;
1301 psppire_data_window_iface_init (PsppireWindowIface *iface)
1303 iface->save = save_file;
1304 iface->pick_filename = data_pick_filename;
1305 iface->load = load_file;
1309 psppire_default_data_window (void)
1311 if (ll_is_empty (&all_data_windows))
1312 create_data_window ();
1313 return ll_data (ll_head (&all_data_windows), PsppireDataWindow, ll);
1317 psppire_data_window_set_default (PsppireDataWindow *pdw)
1319 ll_remove (&pdw->ll);
1320 ll_push_head (&all_data_windows, &pdw->ll);
1324 psppire_data_window_undefault (PsppireDataWindow *pdw)
1326 ll_remove (&pdw->ll);
1327 ll_push_tail (&all_data_windows, &pdw->ll);
1331 psppire_data_window_for_dataset (struct dataset *ds)
1333 PsppireDataWindow *pdw;
1335 ll_for_each (pdw, PsppireDataWindow, ll, &all_data_windows)
1336 if (pdw->dataset == ds)
1343 create_data_window (void)
1345 gtk_widget_show (psppire_data_window_new (NULL));
1349 open_data_window (PsppireWindow *victim, const char *file_name)
1353 if (PSPPIRE_IS_DATA_WINDOW (victim)
1354 && psppire_data_window_is_empty (PSPPIRE_DATA_WINDOW (victim)))
1355 window = GTK_WIDGET (victim);
1357 window = psppire_data_window_new (NULL);
1359 psppire_window_load (PSPPIRE_WINDOW (window), file_name);
1360 gtk_widget_show (window);