Set the filename on loading a new file
[pspp-builds.git] / src / ui / gui / psppire-data-window.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2008  Free Software Foundation
3
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.
8
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.
13
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/>. */
16
17 #include <config.h>
18
19 #include <gtk/gtksignal.h>
20 #include <gtk/gtkbox.h>
21 #include <glade/glade.h>
22 #include "helper.h"
23
24 #include "text-data-import-dialog.h"
25
26
27 #include <ui/syntax-gen.h>
28 #include <language/syntax-string-source.h>
29 #include <libpspp/message.h>
30 #include <stdlib.h>
31
32 #include <data/procedure.h>
33
34 #include "psppire-data-window.h"
35 #include "psppire-syntax-window.h"
36
37 #include "about.h"
38
39 #include "goto-case-dialog.h"
40 #include "weight-cases-dialog.h"
41 #include "split-file-dialog.h"
42 #include "transpose-dialog.h"
43 #include "sort-cases-dialog.h"
44 #include "select-cases-dialog.h"
45 #include "compute-dialog.h"
46 #include "find-dialog.h"
47 #include "rank-dialog.h"
48 #include "recode-dialog.h"
49 #include "comments-dialog.h"
50 #include "variable-info-dialog.h"
51 #include "descriptives-dialog.h"
52 #include "crosstabs-dialog.h"
53 #include "frequencies-dialog.h"
54 #include "examine-dialog.h"
55 #include "dict-display.h"
56 #include "regression-dialog.h"
57 #include "oneway-anova-dialog.h"
58 #include "t-test-independent-samples-dialog.h"
59 #include "t-test-one-sample.h"
60 #include "t-test-paired-samples.h"
61
62
63 #include <gettext.h>
64 #define _(msgid) gettext (msgid)
65 #define N_(msgid) msgid
66
67
68
69 static void psppire_data_window_base_finalize (PsppireDataWindowClass *, gpointer);
70 static void psppire_data_window_base_init     (PsppireDataWindowClass *class);
71 static void psppire_data_window_class_init    (PsppireDataWindowClass *class);
72 static void psppire_data_window_init          (PsppireDataWindow      *data_editor);
73
74
75 GType
76 psppire_data_window_get_type (void)
77 {
78   static GType psppire_data_window_type = 0;
79
80   if (!psppire_data_window_type)
81     {
82       static const GTypeInfo psppire_data_window_info =
83       {
84         sizeof (PsppireDataWindowClass),
85         (GBaseInitFunc) psppire_data_window_base_init,
86         (GBaseFinalizeFunc) psppire_data_window_base_finalize,
87         (GClassInitFunc)psppire_data_window_class_init,
88         (GClassFinalizeFunc) NULL,
89         NULL,
90         sizeof (PsppireDataWindow),
91         0,
92         (GInstanceInitFunc) psppire_data_window_init,
93       };
94
95       psppire_data_window_type =
96         g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireDataWindow",
97                                 &psppire_data_window_info, 0);
98     }
99
100   return psppire_data_window_type;
101 }
102
103 static GObjectClass *parent_class ;
104
105 static void
106 psppire_data_window_finalize (GObject *object)
107 {
108   PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (object);
109
110   g_object_unref (de->xml);
111
112   if (G_OBJECT_CLASS (parent_class)->finalize)
113     (*G_OBJECT_CLASS (parent_class)->finalize) (object);
114 }
115
116
117 static void
118 psppire_data_window_class_init (PsppireDataWindowClass *class)
119 {
120   parent_class = g_type_class_peek_parent (class);
121 }
122
123
124 static void
125 psppire_data_window_base_init (PsppireDataWindowClass *class)
126 {
127   GObjectClass *object_class = G_OBJECT_CLASS (class);
128
129   object_class->finalize = psppire_data_window_finalize;
130 }
131
132
133
134 static void
135 psppire_data_window_base_finalize (PsppireDataWindowClass *class,
136                                      gpointer class_data)
137 {
138 }
139
140
141 \f
142
143
144 extern PsppireVarStore *the_var_store;
145 extern struct dataset *the_dataset;
146 extern PsppireDataStore *the_data_store ;
147
148
149 static void
150 update_paste_menuitems (GtkWidget *w, gboolean x, gpointer data)
151 {
152   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
153
154   GtkWidget * edit_paste = get_widget_assert (de->xml, "edit_paste");
155
156   gtk_widget_set_sensitive (edit_paste, x);
157 }
158
159 static void
160 update_cut_copy_menuitems (GtkWidget *w, gboolean x, gpointer data)
161 {
162   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
163
164   GtkWidget * edit_copy = get_widget_assert (de->xml, "edit_copy");
165   GtkWidget * edit_cut = get_widget_assert (de->xml, "edit_cut");
166
167   gtk_widget_set_sensitive (edit_copy, x);
168   gtk_widget_set_sensitive (edit_cut, x);
169 }
170
171 /* Run the EXECUTE command. */
172 static void
173 execute (GtkMenuItem *mi, gpointer data)
174 {
175   struct getl_interface *sss = create_syntax_string_source ("EXECUTE.");
176
177   execute_syntax (sss);
178 }
179
180 static void
181 transformation_change_callback (bool transformations_pending,
182                                 gpointer data)
183 {
184   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
185
186   GtkWidget *menuitem =
187     get_widget_assert (de->xml, "transform_run-pending");
188   GtkWidget *status_label  =
189     get_widget_assert (de->xml, "case-counter-area");
190
191   gtk_widget_set_sensitive (menuitem, transformations_pending);
192
193
194   if ( transformations_pending)
195     gtk_label_set_text (GTK_LABEL (status_label),
196                         _("Transformations Pending"));
197   else
198     gtk_label_set_text (GTK_LABEL (status_label), "");
199 }
200
201 /* Callback for when the dictionary changes its filter variable */
202 static void
203 on_filter_change (GObject *o, gint filter_index, gpointer data)
204 {
205   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
206
207   GtkWidget *filter_status_area =
208     get_widget_assert (de->xml, "filter-use-status-area");
209
210   if ( filter_index == -1 )
211     {
212       gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
213     }
214   else
215     {
216       PsppireVarStore *vs = NULL;
217       struct variable *var ;
218       gchar *text ;
219
220       g_object_get (de->data_editor, "var-store", &vs, NULL);
221
222       var = psppire_dict_get_variable (vs->dict, filter_index);
223
224       text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
225
226       gtk_label_set_text (GTK_LABEL (filter_status_area), text);
227
228       g_free (text);
229     }
230 }
231
232 /* Callback for when the dictionary changes its split variables */
233 static void
234 on_split_change (PsppireDict *dict, gpointer data)
235 {
236   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
237
238   size_t n_split_vars = dict_get_split_cnt (dict->dict);
239
240   GtkWidget *split_status_area =
241     get_widget_assert (de->xml, "split-file-status-area");
242
243   if ( n_split_vars == 0 )
244     {
245       gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
246     }
247   else
248     {
249       gint i;
250       GString *text;
251       const struct variable *const * split_vars =
252         dict_get_split_vars (dict->dict);
253
254       text = g_string_new (_("Split by "));
255
256       for (i = 0 ; i < n_split_vars - 1; ++i )
257         {
258           g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
259         }
260       g_string_append (text, var_get_name (split_vars[i]));
261
262       gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
263
264       g_string_free (text, TRUE);
265     }
266 }
267
268
269
270
271 /* Callback for when the dictionary changes its weights */
272 static void
273 on_weight_change (GObject *o, gint weight_index, gpointer data)
274 {
275   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
276
277   GtkWidget *weight_status_area =
278     get_widget_assert (de->xml, "weight-status-area");
279
280   if ( weight_index == -1 )
281     {
282       gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
283     }
284   else
285     {
286       struct variable *var ;
287       PsppireVarStore *vs = NULL;
288       gchar *text;
289
290       g_object_get (de->data_editor, "var-store", &vs, NULL);
291
292       var = psppire_dict_get_variable (vs->dict, weight_index);
293
294       text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
295
296       gtk_label_set_text (GTK_LABEL (weight_status_area), text);
297
298       g_free (text);
299     }
300 }
301
302 /* Puts FILE_NAME into the recent list.
303    If it's already in the list, it moves it to the top
304 */
305 static void
306 add_most_recent (const char *file_name)
307 {
308 #if RECENT_LISTS_AVAILABLE
309
310   GtkRecentManager *manager = gtk_recent_manager_get_default();
311   gchar *uri = g_filename_to_uri (file_name, NULL, NULL);
312
313   gtk_recent_manager_remove_item (manager, uri, NULL);
314
315   if ( ! gtk_recent_manager_add_item (manager, uri))
316     g_warning ("Could not add item %s to recent list\n",uri);
317
318   g_free (uri);
319 #endif
320 }
321
322 void
323 psppire_data_window_load_file (PsppireDataWindow *de,
324                                     const gchar *file_name)
325 {
326   struct getl_interface *sss;
327   struct string filename;
328
329   ds_init_empty (&filename);
330   syntax_gen_string (&filename, ss_cstr (file_name));
331
332   sss = create_syntax_string_source ("GET FILE=%s.",
333                                      ds_cstr (&filename));
334   ds_destroy (&filename);
335
336   if (execute_syntax (sss) )
337   {
338     psppire_window_set_filename (PSPPIRE_WINDOW (de), file_name);
339     add_most_recent (file_name);
340   }
341
342   psppire_window_set_unsaved (PSPPIRE_WINDOW (de), FALSE);
343   free (de->file_name);
344   de->file_name = g_strdup (file_name);
345 }
346
347
348 /* Callback for the data_open action.
349    Prompts for a filename and opens it */
350 static void
351 open_data_dialog (GtkAction *action, PsppireDataWindow *de)
352 {
353   GtkWidget *dialog =
354     gtk_file_chooser_dialog_new (_("Open"),
355                                  GTK_WINDOW (de),
356                                  GTK_FILE_CHOOSER_ACTION_OPEN,
357                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
358                                  GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
359                                  NULL);
360
361   GtkFileFilter *filter = gtk_file_filter_new ();
362   gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
363   gtk_file_filter_add_pattern (filter, "*.sav");
364   gtk_file_filter_add_pattern (filter, "*.SAV");
365   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
366
367   filter = gtk_file_filter_new ();
368   gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
369   gtk_file_filter_add_pattern (filter, "*.por");
370   gtk_file_filter_add_pattern (filter, "*.POR");
371   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
372
373   filter = gtk_file_filter_new ();
374   gtk_file_filter_set_name (filter, _("All Files"));
375   gtk_file_filter_add_pattern (filter, "*");
376   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
377
378
379   if (de->file_name)
380     {
381       gchar *dir_name = g_path_get_dirname (de->file_name);
382       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
383                                            dir_name);
384       free (dir_name);
385     }
386
387   switch (gtk_dialog_run (GTK_DIALOG (dialog)))
388     {
389     case GTK_RESPONSE_ACCEPT:
390       {
391         g_free (de->file_name);
392         de->file_name =
393           gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
394
395         psppire_data_window_load_file (de, de->file_name);
396       }
397       break;
398     default:
399       break;
400     }
401
402   gtk_widget_destroy (dialog);
403 }
404
405 /* Returns true if NAME has a suffix which might denote a PSPP file */
406 static gboolean
407 name_has_suffix (const gchar *name)
408 {
409   if ( g_str_has_suffix (name, ".sav"))
410     return TRUE;
411   if ( g_str_has_suffix (name, ".SAV"))
412     return TRUE;
413   if ( g_str_has_suffix (name, ".por"))
414     return TRUE;
415   if ( g_str_has_suffix (name, ".POR"))
416     return TRUE;
417
418   return FALSE;
419 }
420
421
422 /* Append SUFFIX to the filename of DE */
423 static void
424 append_filename_suffix (PsppireDataWindow *de, const gchar *suffix)
425 {
426   if ( ! name_has_suffix (de->file_name))
427     {
428       gchar *s = de->file_name;
429       de->file_name = g_strconcat (de->file_name, suffix, NULL);
430       g_free (s);
431     }
432 }
433
434 /* Save DE to file */
435 static void
436 save_file (PsppireDataWindow *de)
437 {
438   struct getl_interface *sss;
439   struct string file_name ;
440
441   g_assert (de->file_name);
442
443   ds_init_empty (&file_name);
444   syntax_gen_string (&file_name, ss_cstr (de->file_name));
445
446   if ( de->save_as_portable )
447     {
448       append_filename_suffix (de, ".por");
449       sss = create_syntax_string_source ("EXPORT OUTFILE=%s.",
450                                          ds_cstr (&file_name));
451     }
452   else
453     {
454       append_filename_suffix (de, ".sav");
455       sss = create_syntax_string_source ("SAVE OUTFILE=%s.",
456                                          ds_cstr (&file_name));
457     }
458
459   ds_destroy (&file_name);
460
461   execute_syntax (sss);
462
463   psppire_window_set_unsaved (PSPPIRE_WINDOW (de), FALSE);
464 }
465
466
467 static void
468 insert_case (GtkAction *action, gpointer data)
469 {
470   PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (data);
471
472   psppire_data_editor_insert_case (dw->data_editor);
473 }
474
475 static void
476 on_insert_variable (GtkAction *action, gpointer data)
477 {
478   PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
479   psppire_data_editor_insert_variable (de);
480 }
481
482
483 /* Callback for data_save_as action. Prompt for a filename and save */
484 static void
485 data_save_as_dialog (GtkAction *action, PsppireDataWindow *de)
486 {
487   GtkWidget *button_sys;
488   GtkWidget *dialog =
489     gtk_file_chooser_dialog_new (_("Save"),
490                                  GTK_WINDOW (de),
491                                  GTK_FILE_CHOOSER_ACTION_SAVE,
492                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
493                                  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
494                                  NULL);
495
496   GtkFileFilter *filter = gtk_file_filter_new ();
497   gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
498   gtk_file_filter_add_pattern (filter, "*.sav");
499   gtk_file_filter_add_pattern (filter, "*.SAV");
500   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
501
502   filter = gtk_file_filter_new ();
503   gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
504   gtk_file_filter_add_pattern (filter, "*.por");
505   gtk_file_filter_add_pattern (filter, "*.POR");
506   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
507
508   filter = gtk_file_filter_new ();
509   gtk_file_filter_set_name (filter, _("All Files"));
510   gtk_file_filter_add_pattern (filter, "*");
511   gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
512
513   {
514     GtkWidget *button_por;
515     GtkWidget *vbox = gtk_vbox_new (TRUE, 5);
516     button_sys =
517       gtk_radio_button_new_with_label (NULL, _("System File"));
518
519     button_por =
520       gtk_radio_button_new_with_label
521       (gtk_radio_button_get_group (GTK_RADIO_BUTTON(button_sys)),
522        _("Portable File"));
523
524     gtk_box_pack_start_defaults (GTK_BOX (vbox), button_sys);
525     gtk_box_pack_start_defaults (GTK_BOX (vbox), button_por);
526
527     gtk_widget_show_all (vbox);
528
529     gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), vbox);
530   }
531
532   switch (gtk_dialog_run (GTK_DIALOG (dialog)))
533     {
534     case GTK_RESPONSE_ACCEPT:
535       {
536         g_free (de->file_name);
537
538         de->file_name =
539           gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
540
541         de->save_as_portable =
542           ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys));
543
544         if ( de->save_as_portable)
545           append_filename_suffix (de, ".por");
546         else
547           append_filename_suffix (de, ".sav");
548
549         save_file (de);
550
551         psppire_window_set_filename (PSPPIRE_WINDOW (de), de->file_name);
552       }
553       break;
554     default:
555       break;
556     }
557
558   gtk_widget_destroy (dialog);
559 }
560
561
562 /* Callback for data_save action.
563    If there's an existing file name, then just save,
564    otherwise prompt for a file name, then save */
565 static void
566 data_save (GtkAction *action, PsppireDataWindow *de)
567 {
568   if (de->file_name)
569     save_file (de);
570   else
571     data_save_as_dialog (action, de);
572 }
573
574
575 /* Callback for data_new action.
576    Performs the NEW FILE command */
577 static void
578 new_file (GtkAction *action, PsppireDataWindow *de)
579 {
580   struct getl_interface *sss =
581     create_syntax_string_source ("NEW FILE.");
582
583   execute_syntax (sss);
584
585   g_free (de->file_name);
586   de->file_name = NULL;
587
588   psppire_window_set_filename (PSPPIRE_WINDOW (de), NULL);
589 }
590
591
592
593 /* Create the GtkActions and connect to their signals */
594 static void
595 register_data_editor_actions (PsppireDataWindow *de)
596 {
597   de->action_data_open =
598     gtk_action_new ("data-open-dialog",
599                     _("Open"),
600                     _("Open a data file"),
601                     "gtk-open");
602
603   g_signal_connect (de->action_data_open, "activate",
604                     G_CALLBACK (open_data_dialog), de);
605
606
607   de->action_data_save = gtk_action_new ("data-save",
608                                             _("Save"),
609                                             _("Save data to file"),
610                                             "gtk-save");
611
612   g_signal_connect (de->action_data_save, "activate",
613                     G_CALLBACK (data_save), de);
614
615
616   de->action_data_save_as = gtk_action_new ("data-save-as-dialog",
617                                             _("Save As"),
618                                             _("Save data to file"),
619                                             "gtk-save");
620
621   g_signal_connect (de->action_data_save_as, "activate",
622                     G_CALLBACK (data_save_as_dialog), de);
623
624   de->action_data_new =
625     gtk_action_new ("data-new",
626                     _("New"),
627                     _("New data file"),
628                     NULL);
629
630   g_signal_connect (de->action_data_new, "activate",
631                     G_CALLBACK (new_file), de);
632
633   de->invoke_text_import_assistant =
634     gtk_action_new ("file_import-text",
635                     _("_Import Text Data"),
636                     _("Import text data file"),
637                     "");
638
639   g_signal_connect (de->invoke_text_import_assistant, "activate",
640                     G_CALLBACK (text_data_import_assistant), de);
641 }
642
643 static void
644 on_edit_paste (GtkAction *a, gpointer data)
645 {
646   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
647
648   psppire_data_editor_clip_paste (de->data_editor);
649 }
650
651 static void
652 on_edit_copy (GtkMenuItem *m, gpointer data)
653 {
654   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
655
656   psppire_data_editor_clip_copy (de->data_editor);
657 }
658
659
660
661 static void
662 on_edit_cut (GtkMenuItem *m, gpointer data)
663 {
664   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
665
666   psppire_data_editor_clip_cut (de->data_editor);
667 }
668
669
670 static void
671 status_bar_activate (GtkCheckMenuItem *menuitem, gpointer data)
672 {
673   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
674   GtkWidget *statusbar = get_widget_assert (de->xml, "status-bar");
675
676   if ( gtk_check_menu_item_get_active (menuitem) )
677     gtk_widget_show (statusbar);
678   else
679     gtk_widget_hide (statusbar);
680 }
681
682
683 static void
684 grid_lines_activate (GtkCheckMenuItem *menuitem, gpointer data)
685 {
686   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
687   const gboolean grid_visible = gtk_check_menu_item_get_active (menuitem);
688
689   psppire_data_editor_show_grid (de->data_editor, grid_visible);
690 }
691
692
693
694 static void
695 data_view_activate (GtkCheckMenuItem *menuitem, gpointer data)
696 {
697   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
698
699   gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
700 }
701
702
703 static void
704 variable_view_activate (GtkCheckMenuItem *menuitem, gpointer data)
705 {
706   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
707
708   gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
709 }
710
711
712 static void
713 fonts_activate (GtkMenuItem *menuitem, gpointer data)
714 {
715   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
716   PangoFontDescription *current_font;
717   gchar *font_name;
718   GtkWidget *dialog =
719     gtk_font_selection_dialog_new (_("Font Selection"));
720
721
722   current_font = GTK_WIDGET(de->data_editor)->style->font_desc;
723   font_name = pango_font_description_to_string (current_font);
724
725   gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name);
726
727   g_free (font_name);
728
729   gtk_window_set_transient_for (GTK_WINDOW (dialog),
730                                 GTK_WINDOW (get_widget_assert (de->xml,
731                                                                "data_editor")));
732   if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) )
733     {
734       const gchar *font = gtk_font_selection_dialog_get_font_name
735         (GTK_FONT_SELECTION_DIALOG (dialog));
736
737       PangoFontDescription* font_desc =
738         pango_font_description_from_string (font);
739
740       psppire_data_editor_set_font (de->data_editor, font_desc);
741     }
742
743   gtk_widget_hide (dialog);
744 }
745
746
747
748 /* Callback for the value labels action */
749 static void
750 toggle_value_labels (GtkToggleAction *ta, gpointer data)
751 {
752   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
753
754   g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL);
755 }
756
757 static void
758 toggle_split_window (GtkToggleAction *ta, gpointer data)
759 {
760   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
761
762   psppire_data_editor_split_window (de->data_editor,
763                                     gtk_toggle_action_get_active (ta));
764 }
765
766
767 static void
768 file_quit (GtkCheckMenuItem *menuitem, gpointer data)
769 {
770   /* FIXME: Need to be more intelligent here.
771      Give the user the opportunity to save any unsaved data.
772   */
773   g_object_unref (the_data_store);
774   gtk_main_quit ();
775 }
776
777
778
779 static GtkWidget *
780 create_data_sheet_variable_popup_menu (PsppireDataWindow *de)
781 {
782   GtkWidget *menu = gtk_menu_new ();
783
784   GtkWidget *sort_ascending =
785     gtk_menu_item_new_with_label (_("Sort Ascending"));
786
787   GtkWidget *sort_descending =
788     gtk_menu_item_new_with_label (_("Sort Descending"));
789
790   GtkWidget *insert_variable =
791     gtk_menu_item_new_with_label (_("Insert Variable"));
792
793   GtkWidget *clear_variable =
794     gtk_menu_item_new_with_label (_("Clear"));
795
796
797   gtk_action_connect_proxy (de->delete_variables,
798                             clear_variable );
799
800
801   gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable);
802
803
804   gtk_menu_shell_append (GTK_MENU_SHELL (menu),
805                          gtk_separator_menu_item_new ());
806
807
808   gtk_menu_shell_append (GTK_MENU_SHELL (menu), clear_variable);
809
810
811   gtk_menu_shell_append (GTK_MENU_SHELL (menu),
812                          gtk_separator_menu_item_new ());
813
814
815   gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_ascending);
816
817
818   g_signal_connect_swapped (G_OBJECT (sort_ascending), "activate",
819                             G_CALLBACK (psppire_data_editor_sort_ascending),
820                             de->data_editor);
821
822   g_signal_connect_swapped (G_OBJECT (sort_descending), "activate",
823                             G_CALLBACK (psppire_data_editor_sort_descending),
824                             de->data_editor);
825
826   g_signal_connect_swapped (G_OBJECT (insert_variable), "activate",
827                             G_CALLBACK (gtk_action_activate),
828                             de->insert_variable);
829
830
831   gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_descending);
832
833   gtk_widget_show_all (menu);
834
835   return menu;
836 }
837
838
839 static GtkWidget *
840 create_data_sheet_cases_popup_menu (PsppireDataWindow *de)
841 {
842   GtkWidget *menu = gtk_menu_new ();
843
844   GtkWidget *insert_case =
845     gtk_menu_item_new_with_label (_("Insert Case"));
846
847   GtkWidget *delete_case =
848     gtk_menu_item_new_with_label (_("Clear"));
849
850
851   gtk_action_connect_proxy (de->delete_cases,
852                             delete_case);
853
854
855   gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_case);
856
857   g_signal_connect_swapped (G_OBJECT (insert_case), "activate",
858                             G_CALLBACK (gtk_action_activate),
859                             de->insert_case);
860
861
862   gtk_menu_shell_append (GTK_MENU_SHELL (menu),
863                          gtk_separator_menu_item_new ());
864
865
866   gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_case);
867
868
869   gtk_widget_show_all (menu);
870
871   return menu;
872 }
873
874
875 static GtkWidget *
876 create_var_sheet_variable_popup_menu (PsppireDataWindow *de)
877 {
878   GtkWidget *menu = gtk_menu_new ();
879
880   GtkWidget *insert_variable =
881     gtk_menu_item_new_with_label (_("Insert Variable"));
882
883   GtkWidget *delete_variable =
884     gtk_menu_item_new_with_label (_("Clear"));
885
886
887   gtk_action_connect_proxy (de->delete_variables,
888                             delete_variable);
889
890
891   gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable);
892
893   g_signal_connect_swapped (G_OBJECT (insert_variable), "activate",
894                             G_CALLBACK (gtk_action_activate),
895                             de->insert_variable);
896
897
898   gtk_menu_shell_append (GTK_MENU_SHELL (menu),
899                          gtk_separator_menu_item_new ());
900
901
902   gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_variable);
903
904
905   gtk_widget_show_all (menu);
906
907   return menu;
908 }
909
910
911 #if RECENT_LISTS_AVAILABLE
912
913 static void
914 on_recent_data_select (GtkMenuShell *menushell,   gpointer user_data)
915 {
916   gchar *file;
917   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (user_data);
918
919   gchar *uri =
920     gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
921
922   file = g_filename_from_uri (uri, NULL, NULL);
923
924   g_free (uri);
925
926   psppire_data_window_load_file (de, file);
927
928   g_free (file);
929 }
930
931 static void
932 on_recent_files_select (GtkMenuShell *menushell,   gpointer user_data)
933 {
934   gchar *file;
935
936   GtkWidget *se ;
937
938   gchar *uri =
939     gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
940
941   file = g_filename_from_uri (uri, NULL, NULL);
942
943   g_free (uri);
944
945   se = psppire_syntax_window_new ();
946
947   psppire_syntax_window_load_from_file (PSPPIRE_SYNTAX_WINDOW (se), file, NULL);
948   gtk_widget_show (se);
949
950   g_free (file);
951 }
952
953 #endif
954
955 static void
956 enable_delete_cases (GtkWidget *w, gint case_num, gpointer data)
957 {
958   PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
959
960   gtk_action_set_visible (de->delete_cases, case_num != -1);
961 }
962
963
964 static void
965 enable_delete_variables (GtkWidget *w, gint var, gpointer data)
966 {
967   PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
968
969   gtk_action_set_visible (de->delete_variables, var != -1);
970 }
971
972 /* Callback for when the datasheet/varsheet is selected */
973 static void
974 on_switch_sheet (GtkNotebook *notebook,
975                 GtkNotebookPage *page,
976                 guint page_num,
977                 gpointer user_data)
978 {
979   PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (user_data);
980
981   GtkWidget *view_data = get_widget_assert (de->xml, "view_data");
982   GtkWidget *view_variables = get_widget_assert (de->xml, "view_variables");
983
984   switch (page_num)
985     {
986     case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
987       gtk_widget_hide (view_variables);
988       gtk_widget_show (view_data);
989       gtk_action_set_sensitive (de->insert_variable, TRUE);
990       gtk_action_set_sensitive (de->insert_case, FALSE);
991       gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE);
992       break;
993     case PSPPIRE_DATA_EDITOR_DATA_VIEW:
994       gtk_widget_show (view_variables);
995       gtk_widget_hide (view_data);
996       gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE);
997       gtk_action_set_sensitive (de->insert_case, TRUE);
998       break;
999     default:
1000       g_assert_not_reached ();
1001       break;
1002     }
1003
1004 #if 0
1005   update_paste_menuitem (de, page_num);
1006 #endif
1007 }
1008
1009
1010 static void
1011 set_unsaved (gpointer w)
1012 {
1013   psppire_window_set_unsaved (PSPPIRE_WINDOW (w), TRUE);
1014 }
1015
1016 static void
1017 psppire_data_window_init (PsppireDataWindow *de)
1018 {
1019   PsppireVarStore *vs;
1020
1021   GtkWidget *menubar;
1022   GtkWidget *hb ;
1023   GtkWidget *sb ;
1024
1025   GtkWidget *box = gtk_vbox_new (FALSE, 0);
1026   de->xml = XML_NEW ("data-editor.glade");
1027
1028   menubar = get_widget_assert (de->xml, "menubar");
1029   hb = get_widget_assert (de->xml, "handlebox1");
1030   sb = get_widget_assert (de->xml, "status-bar");
1031
1032   de->data_editor =
1033     PSPPIRE_DATA_EDITOR (psppire_data_editor_new (the_var_store, the_data_store));
1034
1035   g_signal_connect_swapped (the_data_store, "case-changed",
1036                     G_CALLBACK (set_unsaved), de);
1037
1038   g_signal_connect_swapped (the_data_store, "case-inserted",
1039                     G_CALLBACK (set_unsaved), de);
1040
1041   g_signal_connect_swapped (the_data_store, "cases-deleted",
1042                     G_CALLBACK (set_unsaved), de);
1043
1044   dataset_set_callback (the_dataset, set_unsaved, de);
1045
1046   connect_help (de->xml);
1047
1048   g_object_ref (menubar);
1049   gtk_widget_unparent (menubar);
1050
1051   g_object_ref (hb);
1052   gtk_widget_unparent (hb);
1053
1054   g_object_ref (sb);
1055   gtk_widget_unparent (sb);
1056
1057   gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
1058   gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
1059   gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
1060   gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
1061
1062   gtk_container_add (GTK_CONTAINER (de), box);
1063
1064   g_signal_connect (de->data_editor, "data-selection-changed",
1065                     G_CALLBACK (update_cut_copy_menuitems), de);
1066
1067   g_signal_connect (de->data_editor, "data-available-changed",
1068                     G_CALLBACK (update_paste_menuitems), de);
1069
1070   dataset_add_transform_change_callback (the_dataset,
1071                                          transformation_change_callback,
1072                                          de);
1073
1074
1075   vs = the_var_store;
1076
1077   g_assert(vs); /* Traps a possible bug in w32 build */
1078
1079   g_signal_connect (vs->dict, "weight-changed",
1080                     G_CALLBACK (on_weight_change),
1081                     de);
1082
1083   g_signal_connect (vs->dict, "filter-changed",
1084                     G_CALLBACK (on_filter_change),
1085                     de);
1086
1087   g_signal_connect (vs->dict, "split-changed",
1088                     G_CALLBACK (on_split_change),
1089                     de);
1090
1091
1092   g_signal_connect (get_widget_assert (de->xml, "edit_copy"),
1093                     "activate",
1094                     G_CALLBACK (on_edit_copy), de);
1095
1096   g_signal_connect (get_widget_assert (de->xml, "edit_cut"),
1097                     "activate",
1098                     G_CALLBACK (on_edit_cut), de);
1099
1100
1101   register_data_editor_actions (de);
1102
1103   de->toggle_value_labels =
1104     gtk_toggle_action_new ("toggle-value-labels",
1105                            _("_Labels"),
1106                            _("Show/hide value labels"),
1107                            "pspp-value-labels");
1108
1109   g_signal_connect (de->toggle_value_labels, "toggled",
1110                     G_CALLBACK (toggle_value_labels), de);
1111
1112
1113   gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
1114                             get_widget_assert (de->xml,
1115                                                "togglebutton-value-labels"));
1116
1117
1118   gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
1119                             get_widget_assert (de->xml,
1120                                                "view_value-labels"));
1121
1122
1123
1124   de->delete_cases =
1125     gtk_action_new ("clear-cases",
1126                     _("Clear"),
1127                     _("Delete the cases at the selected position(s)"),
1128                     "pspp-clear-cases");
1129
1130   g_signal_connect_swapped (de->delete_cases, "activate",
1131                     G_CALLBACK (psppire_data_editor_delete_cases),
1132                     de->data_editor);
1133
1134   gtk_action_connect_proxy (de->delete_cases,
1135                             get_widget_assert (de->xml, "edit_clear-cases"));
1136
1137   g_signal_connect (get_widget_assert (de->xml, "edit_paste"), "activate",
1138                     G_CALLBACK (on_edit_paste),
1139                     de);
1140
1141   gtk_action_set_visible (de->delete_cases, FALSE);
1142
1143   de->delete_variables =
1144     gtk_action_new ("clear-variables",
1145                     _("Clear"),
1146                     _("Delete the variables at the selected position(s)"),
1147                     "pspp-clear-variables");
1148
1149   g_signal_connect_swapped (de->delete_variables, "activate",
1150                             G_CALLBACK (psppire_data_editor_delete_variables),
1151                             de->data_editor);
1152
1153   gtk_action_connect_proxy (de->delete_variables,
1154                             get_widget_assert (de->xml, "edit_clear-variables")
1155                             );
1156
1157   gtk_action_set_visible (de->delete_variables, FALSE);
1158
1159   de->insert_variable =
1160     gtk_action_new ("insert-variable",
1161                     _("Insert _Variable"),
1162                     _("Create a new variable at the current position"),
1163                     "pspp-insert-variable");
1164
1165   g_signal_connect (de->insert_variable, "activate",
1166                     G_CALLBACK (on_insert_variable), de->data_editor);
1167
1168
1169   gtk_action_connect_proxy (de->insert_variable,
1170                             get_widget_assert (de->xml, "button-insert-variable")
1171                             );
1172
1173   gtk_action_connect_proxy (de->insert_variable,
1174                             get_widget_assert (de->xml, "edit_insert-variable")
1175                             );
1176
1177
1178   de->insert_case =
1179     gtk_action_new ("insert-case",
1180                     _("Insert Ca_se"),
1181                     _("Create a new case at the current position"),
1182                     "pspp-insert-case");
1183
1184   g_signal_connect (de->insert_case, "activate",
1185                     G_CALLBACK (insert_case), de);
1186
1187
1188   gtk_action_connect_proxy (de->insert_case,
1189                             get_widget_assert (de->xml, "button-insert-case")
1190                             );
1191
1192
1193   gtk_action_connect_proxy (de->insert_case,
1194                             get_widget_assert (de->xml, "edit_insert-case")
1195                             );
1196
1197
1198   de->invoke_goto_dialog =
1199     gtk_action_new ("goto-case-dialog",
1200                     _("_Goto Case"),
1201                     _("Jump to a Case in the Data Sheet"),
1202                     "gtk-jump-to");
1203
1204
1205   gtk_action_connect_proxy (de->invoke_goto_dialog,
1206                             get_widget_assert (de->xml, "button-goto-case")
1207                             );
1208
1209   gtk_action_connect_proxy (de->invoke_goto_dialog,
1210                             get_widget_assert (de->xml, "edit_goto-case")
1211                             );
1212
1213
1214   g_signal_connect (de->invoke_goto_dialog, "activate",
1215                     G_CALLBACK (goto_case_dialog), de);
1216
1217   de->invoke_weight_cases_dialog =
1218     gtk_action_new ("weight-cases-dialog",
1219                     _("_Weights"),
1220                     _("Weight cases by variable"),
1221                     "pspp-weight-cases");
1222
1223   g_signal_connect (de->invoke_weight_cases_dialog, "activate",
1224                     G_CALLBACK (weight_cases_dialog), de);
1225
1226
1227   de->invoke_transpose_dialog =
1228     gtk_action_new ("transpose-dialog",
1229                     _("_Transpose"),
1230                     _("Transpose the cases with the variables"),
1231                     NULL);
1232
1233
1234   g_signal_connect (de->invoke_transpose_dialog, "activate",
1235                     G_CALLBACK (transpose_dialog), de);
1236
1237
1238
1239   de->invoke_split_file_dialog =
1240     gtk_action_new ("split-file-dialog",
1241                     _("S_plit"),
1242                     _("Split the active file"),
1243                     "pspp-split-file");
1244
1245   g_signal_connect (de->invoke_split_file_dialog, "activate",
1246                     G_CALLBACK (split_file_dialog), de);
1247
1248
1249
1250   de->invoke_sort_cases_dialog =
1251     gtk_action_new ("sort-cases-dialog",
1252                     _("_Sort"),
1253                     _("Sort cases in the active file"),
1254                     "pspp-sort-cases");
1255
1256   g_signal_connect (de->invoke_sort_cases_dialog, "activate",
1257                     G_CALLBACK (sort_cases_dialog), de);
1258
1259   de->invoke_select_cases_dialog =
1260     gtk_action_new ("select-cases-dialog",
1261                     _("Select _Cases"),
1262                     _("Select cases from the active file"),
1263                     "pspp-select-cases");
1264
1265   g_signal_connect (de->invoke_select_cases_dialog, "activate",
1266                     G_CALLBACK (select_cases_dialog), de);
1267
1268
1269   de->invoke_compute_dialog =
1270     gtk_action_new ("compute-dialog",
1271                     _("_Compute"),
1272                     _("Compute new values for a variable"),
1273                     "pspp-compute");
1274
1275   g_signal_connect (de->invoke_compute_dialog, "activate",
1276                     G_CALLBACK (compute_dialog), de);
1277
1278   de->invoke_oneway_anova_dialog =
1279     gtk_action_new ("oneway-anova",
1280                     _("Oneway _ANOVA"),
1281                     _("Perform one way analysis of variance"),
1282                     NULL);
1283
1284   g_signal_connect (de->invoke_oneway_anova_dialog, "activate",
1285                     G_CALLBACK (oneway_anova_dialog), de);
1286
1287   de->invoke_t_test_independent_samples_dialog =
1288     gtk_action_new ("t-test-independent-samples",
1289                     _("_Independent Samples T Test"),
1290                     _("Calculate T Test for samples from independent groups"),
1291                     NULL);
1292
1293   g_signal_connect (de->invoke_t_test_independent_samples_dialog, "activate",
1294                     G_CALLBACK (t_test_independent_samples_dialog), de);
1295
1296
1297   de->invoke_t_test_paired_samples_dialog =
1298     gtk_action_new ("t-test-paired-samples",
1299                     _("_Paired Samples T Test"),
1300                     _("Calculate T Test for paired samples"),
1301                     NULL);
1302
1303   g_signal_connect (de->invoke_t_test_paired_samples_dialog, "activate",
1304                     G_CALLBACK (t_test_paired_samples_dialog), de);
1305
1306
1307   de->invoke_t_test_one_sample_dialog =
1308     gtk_action_new ("t-test-one-sample",
1309                     _("One _Sample T Test"),
1310                     _("Calculate T Test for sample from a single distribution"),
1311                     NULL);
1312
1313   g_signal_connect (de->invoke_t_test_one_sample_dialog, "activate",
1314                     G_CALLBACK (t_test_one_sample_dialog), de);
1315
1316
1317   de->invoke_comments_dialog =
1318     gtk_action_new ("commments-dialog",
1319                     _("Data File _Comments"),
1320                     _("Commentary text for the data file"),
1321                     NULL);
1322
1323   g_signal_connect (de->invoke_comments_dialog, "activate",
1324                     G_CALLBACK (comments_dialog), de);
1325
1326   de->invoke_find_dialog  =
1327     gtk_action_new ("find-dialog",
1328                     _("_Find"),
1329                     _("Find Case"),
1330                     "gtk-find");
1331
1332   g_signal_connect (de->invoke_find_dialog, "activate",
1333                     G_CALLBACK (find_dialog), de);
1334
1335
1336   de->invoke_rank_dialog  =
1337     gtk_action_new ("rank-dialog",
1338                     _("Ran_k Cases"),
1339                     _("Rank Cases"),
1340                     "pspp-rank-cases");
1341
1342   g_signal_connect (de->invoke_rank_dialog, "activate",
1343                     G_CALLBACK (rank_dialog), de);
1344
1345
1346   de->invoke_recode_same_dialog  =
1347     gtk_action_new ("recode-same-dialog",
1348                     _("Recode into _Same Variables"),
1349                     _("Recode values into the same Variables"),
1350                     "pspp-recode-same");
1351
1352   g_signal_connect (de->invoke_recode_same_dialog, "activate",
1353                     G_CALLBACK (recode_same_dialog), de);
1354
1355
1356   de->invoke_recode_different_dialog  =
1357     gtk_action_new ("recode-different-dialog",
1358                     _("Recode into _Different Variables"),
1359                     _("Recode values into different Variables"),
1360                     "pspp-recode-different");
1361
1362   g_signal_connect (de->invoke_recode_different_dialog, "activate",
1363                     G_CALLBACK (recode_different_dialog), de);
1364
1365
1366   de->invoke_variable_info_dialog  =
1367     gtk_action_new ("variable-info-dialog",
1368                     _("_Variables"),
1369                     _("Jump to Variable"),
1370                     "pspp-goto-variable");
1371
1372   g_signal_connect (de->invoke_variable_info_dialog, "activate",
1373                     G_CALLBACK (variable_info_dialog), de);
1374
1375   de->invoke_descriptives_dialog =
1376     gtk_action_new ("descriptives-dialog",
1377                     _("_Descriptives"),
1378                     _("Calculate descriptive statistics (mean, variance, ...)"),
1379                     "pspp-descriptives");
1380
1381   g_signal_connect (de->invoke_descriptives_dialog, "activate",
1382                     G_CALLBACK (descriptives_dialog), de);
1383
1384
1385   de->invoke_frequencies_dialog =
1386     gtk_action_new ("frequencies-dialog",
1387                     _("_Frequencies"),
1388                     _("Generate frequency statistics"),
1389                     "pspp-frequencies");
1390
1391   g_signal_connect (de->invoke_frequencies_dialog, "activate",
1392                     G_CALLBACK (frequencies_dialog), de);
1393
1394   de->invoke_crosstabs_dialog =
1395     gtk_action_new ("crosstabs-dialog",
1396                     _("_Crosstabs"),
1397                     _("Generate crosstabulations"),
1398                     "pspp-crosstabs");
1399
1400   g_signal_connect (de->invoke_crosstabs_dialog, "activate",
1401                     G_CALLBACK (crosstabs_dialog), de);
1402
1403
1404   de->invoke_examine_dialog =
1405     gtk_action_new ("examine-dialog",
1406                     _("_Explore"),
1407                     _("Examine Data by Factors"),
1408                     "pspp-examine");
1409
1410   g_signal_connect (de->invoke_examine_dialog, "activate",
1411                     G_CALLBACK (examine_dialog), de);
1412
1413
1414   de->invoke_regression_dialog =
1415     gtk_action_new ("regression-dialog",
1416                     _("Linear _Regression"),
1417                     _("Estimate parameters of the linear model"),
1418                     "pspp-regression");
1419
1420   g_signal_connect (de->invoke_regression_dialog, "activate",
1421                     G_CALLBACK (regression_dialog), de);
1422
1423   g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"),
1424                             "activate",
1425                             G_CALLBACK (gtk_action_activate),
1426                             de->action_data_new);
1427
1428   g_signal_connect_swapped (get_widget_assert (de->xml,"file_open_data"),
1429                             "activate",
1430                             G_CALLBACK (gtk_action_activate),
1431                             de->action_data_open);
1432
1433 #if RECENT_LISTS_AVAILABLE
1434   {
1435     GtkRecentManager *rm = gtk_recent_manager_get_default ();
1436     GtkWidget *recent_data = get_widget_assert (de->xml, "file_recent-data");
1437     GtkWidget *recent_files = get_widget_assert (de->xml, "file_recent-files");
1438     GtkWidget *recent_separator = get_widget_assert (de->xml, "file_separator1");
1439
1440     GtkWidget *menu = gtk_recent_chooser_menu_new_for_manager (rm);
1441
1442     GtkRecentFilter *filter = gtk_recent_filter_new ();
1443
1444     gtk_widget_show (recent_data);
1445     gtk_widget_show (recent_files);
1446     gtk_widget_show (recent_separator);
1447
1448     gtk_recent_filter_add_pattern (filter, "*.sav");
1449     gtk_recent_filter_add_pattern (filter, "*.SAV");
1450
1451     gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
1452
1453     gtk_widget_set_sensitive (recent_data, TRUE);
1454     g_signal_connect (menu, "selection-done",
1455                       G_CALLBACK (on_recent_data_select), de);
1456
1457     gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu);
1458
1459
1460     filter = gtk_recent_filter_new ();
1461     menu = gtk_recent_chooser_menu_new_for_manager (rm);
1462
1463     gtk_recent_filter_add_pattern (filter, "*.sps");
1464     gtk_recent_filter_add_pattern (filter, "*.SPS");
1465
1466     gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
1467
1468     gtk_widget_set_sensitive (recent_files, TRUE);
1469     g_signal_connect (menu, "selection-done",
1470                       G_CALLBACK (on_recent_files_select), de);
1471
1472     gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu);
1473   }
1474 #endif
1475
1476   g_signal_connect (get_widget_assert (de->xml,"file_new_syntax"),
1477                     "activate",
1478                     G_CALLBACK (create_syntax_window),
1479                     NULL);
1480
1481   g_signal_connect (get_widget_assert (de->xml,"file_open_syntax"),
1482                     "activate",
1483                     G_CALLBACK (open_syntax_window),
1484                     de);
1485
1486   g_signal_connect_swapped (get_widget_assert (de->xml,"file_import-text"),
1487                             "activate",
1488                             G_CALLBACK (gtk_action_activate),
1489                             de->invoke_text_import_assistant);
1490
1491   g_signal_connect_swapped (get_widget_assert (de->xml,"file_save"),
1492                             "activate",
1493                             G_CALLBACK (gtk_action_activate),
1494                             de->action_data_save);
1495
1496   g_signal_connect_swapped (get_widget_assert (de->xml,"file_save_as"),
1497                             "activate",
1498                             G_CALLBACK (gtk_action_activate),
1499                             de->action_data_save_as);
1500
1501   gtk_action_connect_proxy (de->invoke_find_dialog,
1502                             get_widget_assert (de->xml, "edit_find")
1503                             );
1504
1505   gtk_action_connect_proxy (de->invoke_find_dialog,
1506                             get_widget_assert (de->xml, "button-find")
1507                             );
1508
1509   gtk_action_connect_proxy (de->invoke_rank_dialog,
1510                             get_widget_assert (de->xml, "transform_rank")
1511                             );
1512
1513   gtk_action_connect_proxy (de->invoke_recode_same_dialog,
1514                             get_widget_assert (de->xml,
1515                                                "transform_recode-same")
1516                             );
1517
1518   gtk_action_connect_proxy (de->invoke_recode_different_dialog,
1519                             get_widget_assert (de->xml,
1520                                                "transform_recode-different")
1521                             );
1522
1523   gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
1524                             get_widget_assert (de->xml, "data_weight-cases")
1525                             );
1526
1527   gtk_action_connect_proxy (de->invoke_transpose_dialog,
1528                             get_widget_assert (de->xml, "data_transpose")
1529                             );
1530
1531   gtk_action_connect_proxy (de->invoke_split_file_dialog,
1532                             get_widget_assert (de->xml, "data_split-file")
1533                             );
1534
1535   gtk_action_connect_proxy (de->invoke_sort_cases_dialog,
1536                             get_widget_assert (de->xml, "data_sort-cases")
1537                             );
1538
1539   gtk_action_connect_proxy (de->invoke_select_cases_dialog,
1540                             get_widget_assert (de->xml, "data_select-cases")
1541                             );
1542
1543   gtk_action_connect_proxy (de->invoke_compute_dialog,
1544                             get_widget_assert (de->xml, "transform_compute")
1545                             );
1546
1547   gtk_action_connect_proxy (de->invoke_t_test_independent_samples_dialog,
1548                             get_widget_assert (de->xml,
1549                                                "indep-t-test")
1550                             );
1551
1552
1553   gtk_action_connect_proxy (de->invoke_t_test_paired_samples_dialog,
1554                             get_widget_assert (de->xml,
1555                                                "paired-t-test")
1556                             );
1557
1558
1559   gtk_action_connect_proxy (de->invoke_t_test_one_sample_dialog,
1560                             get_widget_assert (de->xml,
1561                                                "one-sample-t-test")
1562                             );
1563
1564
1565   gtk_action_connect_proxy (de->invoke_oneway_anova_dialog,
1566                             get_widget_assert (de->xml,
1567                                                "oneway-anova")
1568                             );
1569
1570
1571   gtk_action_connect_proxy (de->invoke_comments_dialog,
1572                             get_widget_assert (de->xml, "utilities_comments")
1573                             );
1574
1575   gtk_action_connect_proxy (de->invoke_variable_info_dialog,
1576                             get_widget_assert (de->xml, "utilities_variables")
1577                             );
1578
1579   gtk_action_connect_proxy (de->invoke_descriptives_dialog,
1580                             get_widget_assert (de->xml, "analyze_descriptives")
1581                             );
1582
1583   gtk_action_connect_proxy (de->invoke_crosstabs_dialog,
1584                             get_widget_assert (de->xml, "crosstabs")
1585                             );
1586
1587   gtk_action_connect_proxy (de->invoke_frequencies_dialog,
1588                             get_widget_assert (de->xml, "analyze_frequencies")
1589                             );
1590
1591
1592   gtk_action_connect_proxy (de->invoke_examine_dialog,
1593                             get_widget_assert (de->xml, "analyze_explore")
1594                             );
1595
1596   gtk_action_connect_proxy (de->invoke_regression_dialog,
1597                             get_widget_assert (de->xml, "linear-regression")
1598                             );
1599
1600   g_signal_connect (get_widget_assert (de->xml,"help_about"),
1601                     "activate",
1602                     G_CALLBACK (about_new),
1603                     de);
1604
1605
1606   g_signal_connect (get_widget_assert (de->xml,"help_reference"),
1607                     "activate",
1608                     G_CALLBACK (reference_manual),
1609                     de);
1610
1611
1612   g_signal_connect (de->data_editor,
1613                     "cases-selected",
1614                     G_CALLBACK (enable_delete_cases),
1615                     de);
1616
1617   g_signal_connect (de->data_editor,
1618                     "variables-selected",
1619                     G_CALLBACK (enable_delete_variables),
1620                     de);
1621
1622
1623   g_signal_connect (GTK_NOTEBOOK (de->data_editor),
1624                     "switch-page",
1625                     G_CALLBACK (on_switch_sheet), de);
1626
1627   gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
1628   gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
1629
1630   g_signal_connect (get_widget_assert (de->xml, "view_statusbar"),
1631                     "activate",
1632                     G_CALLBACK (status_bar_activate), de);
1633
1634
1635   g_signal_connect (get_widget_assert (de->xml, "view_gridlines"),
1636                     "activate",
1637                     G_CALLBACK (grid_lines_activate), de);
1638
1639
1640
1641   g_signal_connect (get_widget_assert (de->xml, "view_data"),
1642                     "activate",
1643                     G_CALLBACK (data_view_activate), de);
1644
1645   g_signal_connect (get_widget_assert (de->xml, "view_variables"),
1646                     "activate",
1647                     G_CALLBACK (variable_view_activate), de);
1648
1649
1650
1651   g_signal_connect (get_widget_assert (de->xml, "view_fonts"),
1652                     "activate",
1653                     G_CALLBACK (fonts_activate), de);
1654
1655
1656
1657
1658   gtk_action_connect_proxy (de->action_data_open,
1659                             get_widget_assert (de->xml, "button-open")
1660                             );
1661
1662   gtk_action_connect_proxy (de->action_data_save,
1663                             get_widget_assert (de->xml, "button-save")
1664                             );
1665
1666   gtk_action_connect_proxy (de->invoke_variable_info_dialog,
1667                             get_widget_assert (de->xml, "button-goto-variable")
1668                             );
1669
1670   gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
1671                             get_widget_assert (de->xml, "button-weight-cases")
1672                             );
1673
1674   gtk_action_connect_proxy (de->invoke_split_file_dialog,
1675                             get_widget_assert (de->xml, "button-split-file")
1676                             );
1677
1678   gtk_action_connect_proxy (de->invoke_select_cases_dialog,
1679                             get_widget_assert (de->xml, "button-select-cases")
1680                             );
1681
1682
1683   g_signal_connect (get_widget_assert (de->xml, "file_quit"),
1684                     "activate",
1685                     G_CALLBACK (file_quit), de);
1686
1687   g_signal_connect (get_widget_assert (de->xml, "transform_run-pending"),
1688                     "activate",
1689                     G_CALLBACK (execute), de);
1690
1691
1692   g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"),
1693                     "activate",
1694                     G_CALLBACK (psppire_window_minimise_all), NULL);
1695
1696   de->toggle_split_window =
1697     gtk_toggle_action_new ("toggle-split-window",
1698                            _("_Split Window"),
1699                            _("Split the window vertically and horizontally"),
1700                            "pspp-split-window");
1701
1702   g_signal_connect (de->toggle_split_window, "toggled",
1703                     G_CALLBACK (toggle_split_window),
1704                     de);
1705
1706   gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window),
1707                             get_widget_assert (de->xml,
1708                                                "windows_split"));
1709
1710   de->data_sheet_variable_popup_menu =
1711     GTK_MENU (create_data_sheet_variable_popup_menu (de));
1712
1713   de->var_sheet_variable_popup_menu =
1714     GTK_MENU (create_var_sheet_variable_popup_menu (de));
1715
1716   de->data_sheet_cases_popup_menu =
1717     GTK_MENU (create_data_sheet_cases_popup_menu (de));
1718
1719   PSPPIRE_WINDOW (de)->menu = GTK_MENU_SHELL (get_widget_assert (de->xml,"Windows_menu"));
1720
1721   g_object_set (de->data_editor,
1722                 "datasheet-column-menu", de->data_sheet_variable_popup_menu,
1723                 "datasheet-row-menu", de->data_sheet_cases_popup_menu,
1724                 "varsheet-row-menu", de->var_sheet_variable_popup_menu,
1725                 NULL);
1726
1727   gtk_widget_show (GTK_WIDGET (de->data_editor));
1728   gtk_widget_show (box);
1729 }
1730
1731
1732 GtkWidget*
1733 psppire_data_window_new (void)
1734 {
1735   return GTK_WIDGET (g_object_new (psppire_data_window_get_type (),
1736                                    "description", _("Data Editor"),
1737                                    NULL));
1738 }
1739