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