16e8a8a016bfaa674e9b59bd19f0b3f4cb683b1a
[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 static void
1009 psppire_data_window_init (PsppireDataWindow *de)
1010 {
1011   PsppireVarStore *vs;
1012
1013   GtkWidget *menubar;
1014   GtkWidget *hb ;
1015   GtkWidget *sb ;
1016
1017   GtkWidget *box = gtk_vbox_new (FALSE, 0);
1018   de->xml = XML_NEW ("data-editor.glade");
1019
1020   menubar = get_widget_assert (de->xml, "menubar");
1021   hb = get_widget_assert (de->xml, "handlebox1");
1022   sb = get_widget_assert (de->xml, "status-bar");
1023
1024   de->data_editor =
1025     PSPPIRE_DATA_EDITOR (psppire_data_editor_new (the_var_store, the_data_store));
1026
1027   connect_help (de->xml);
1028
1029   g_object_ref (menubar);
1030   gtk_widget_unparent (menubar);
1031
1032   g_object_ref (hb);
1033   gtk_widget_unparent (hb);
1034
1035   g_object_ref (sb);
1036   gtk_widget_unparent (sb);
1037
1038   gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
1039   gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
1040   gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
1041   gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
1042
1043   gtk_container_add (GTK_CONTAINER (de), box);
1044
1045   g_signal_connect (de->data_editor, "data-selection-changed",
1046                     G_CALLBACK (update_cut_copy_menuitems), de);
1047
1048   g_signal_connect (de->data_editor, "data-available-changed",
1049                     G_CALLBACK (update_paste_menuitems), de);
1050
1051   dataset_add_transform_change_callback (the_dataset,
1052                                          transformation_change_callback,
1053                                          de);
1054
1055
1056   vs = the_var_store;
1057
1058   g_assert(vs); /* Traps a possible bug in w32 build */
1059
1060   g_signal_connect (vs->dict, "weight-changed",
1061                     G_CALLBACK (on_weight_change),
1062                     de);
1063
1064   g_signal_connect (vs->dict, "filter-changed",
1065                     G_CALLBACK (on_filter_change),
1066                     de);
1067
1068   g_signal_connect (vs->dict, "split-changed",
1069                     G_CALLBACK (on_split_change),
1070                     de);
1071
1072
1073   g_signal_connect (get_widget_assert (de->xml, "edit_copy"),
1074                     "activate",
1075                     G_CALLBACK (on_edit_copy), de);
1076
1077   g_signal_connect (get_widget_assert (de->xml, "edit_cut"),
1078                     "activate",
1079                     G_CALLBACK (on_edit_cut), de);
1080
1081
1082   register_data_editor_actions (de);
1083
1084   de->toggle_value_labels =
1085     gtk_toggle_action_new ("toggle-value-labels",
1086                            _("_Labels"),
1087                            _("Show/hide value labels"),
1088                            "pspp-value-labels");
1089
1090   g_signal_connect (de->toggle_value_labels, "toggled",
1091                     G_CALLBACK (toggle_value_labels), de);
1092
1093
1094   gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
1095                             get_widget_assert (de->xml,
1096                                                "togglebutton-value-labels"));
1097
1098
1099   gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
1100                             get_widget_assert (de->xml,
1101                                                "view_value-labels"));
1102
1103
1104
1105   de->delete_cases =
1106     gtk_action_new ("clear-cases",
1107                     _("Clear"),
1108                     _("Delete the cases at the selected position(s)"),
1109                     "pspp-clear-cases");
1110
1111   g_signal_connect_swapped (de->delete_cases, "activate",
1112                     G_CALLBACK (psppire_data_editor_delete_cases),
1113                     de->data_editor);
1114
1115   gtk_action_connect_proxy (de->delete_cases,
1116                             get_widget_assert (de->xml, "edit_clear-cases"));
1117
1118   g_signal_connect (get_widget_assert (de->xml, "edit_paste"), "activate",
1119                     G_CALLBACK (on_edit_paste),
1120                     de);
1121
1122   gtk_action_set_visible (de->delete_cases, FALSE);
1123
1124   de->delete_variables =
1125     gtk_action_new ("clear-variables",
1126                     _("Clear"),
1127                     _("Delete the variables at the selected position(s)"),
1128                     "pspp-clear-variables");
1129
1130   g_signal_connect_swapped (de->delete_variables, "activate",
1131                             G_CALLBACK (psppire_data_editor_delete_variables),
1132                             de->data_editor);
1133
1134   gtk_action_connect_proxy (de->delete_variables,
1135                             get_widget_assert (de->xml, "edit_clear-variables")
1136                             );
1137
1138   gtk_action_set_visible (de->delete_variables, FALSE);
1139
1140   de->insert_variable =
1141     gtk_action_new ("insert-variable",
1142                     _("Insert _Variable"),
1143                     _("Create a new variable at the current position"),
1144                     "pspp-insert-variable");
1145
1146   g_signal_connect (de->insert_variable, "activate",
1147                     G_CALLBACK (on_insert_variable), de->data_editor);
1148
1149
1150   gtk_action_connect_proxy (de->insert_variable,
1151                             get_widget_assert (de->xml, "button-insert-variable")
1152                             );
1153
1154   gtk_action_connect_proxy (de->insert_variable,
1155                             get_widget_assert (de->xml, "edit_insert-variable")
1156                             );
1157
1158
1159   de->insert_case =
1160     gtk_action_new ("insert-case",
1161                     _("Insert Ca_se"),
1162                     _("Create a new case at the current position"),
1163                     "pspp-insert-case");
1164
1165   g_signal_connect (de->insert_case, "activate",
1166                     G_CALLBACK (insert_case), de);
1167
1168
1169   gtk_action_connect_proxy (de->insert_case,
1170                             get_widget_assert (de->xml, "button-insert-case")
1171                             );
1172
1173
1174   gtk_action_connect_proxy (de->insert_case,
1175                             get_widget_assert (de->xml, "edit_insert-case")
1176                             );
1177
1178
1179   de->invoke_goto_dialog =
1180     gtk_action_new ("goto-case-dialog",
1181                     _("_Goto Case"),
1182                     _("Jump to a Case in the Data Sheet"),
1183                     "gtk-jump-to");
1184
1185
1186   gtk_action_connect_proxy (de->invoke_goto_dialog,
1187                             get_widget_assert (de->xml, "button-goto-case")
1188                             );
1189
1190   gtk_action_connect_proxy (de->invoke_goto_dialog,
1191                             get_widget_assert (de->xml, "edit_goto-case")
1192                             );
1193
1194
1195   g_signal_connect (de->invoke_goto_dialog, "activate",
1196                     G_CALLBACK (goto_case_dialog), de);
1197
1198   de->invoke_weight_cases_dialog =
1199     gtk_action_new ("weight-cases-dialog",
1200                     _("_Weights"),
1201                     _("Weight cases by variable"),
1202                     "pspp-weight-cases");
1203
1204   g_signal_connect (de->invoke_weight_cases_dialog, "activate",
1205                     G_CALLBACK (weight_cases_dialog), de);
1206
1207
1208   de->invoke_transpose_dialog =
1209     gtk_action_new ("transpose-dialog",
1210                     _("_Transpose"),
1211                     _("Transpose the cases with the variables"),
1212                     NULL);
1213
1214
1215   g_signal_connect (de->invoke_transpose_dialog, "activate",
1216                     G_CALLBACK (transpose_dialog), de);
1217
1218
1219
1220   de->invoke_split_file_dialog =
1221     gtk_action_new ("split-file-dialog",
1222                     _("S_plit"),
1223                     _("Split the active file"),
1224                     "pspp-split-file");
1225
1226   g_signal_connect (de->invoke_split_file_dialog, "activate",
1227                     G_CALLBACK (split_file_dialog), de);
1228
1229
1230
1231   de->invoke_sort_cases_dialog =
1232     gtk_action_new ("sort-cases-dialog",
1233                     _("_Sort"),
1234                     _("Sort cases in the active file"),
1235                     "pspp-sort-cases");
1236
1237   g_signal_connect (de->invoke_sort_cases_dialog, "activate",
1238                     G_CALLBACK (sort_cases_dialog), de);
1239
1240   de->invoke_select_cases_dialog =
1241     gtk_action_new ("select-cases-dialog",
1242                     _("Select _Cases"),
1243                     _("Select cases from the active file"),
1244                     "pspp-select-cases");
1245
1246   g_signal_connect (de->invoke_select_cases_dialog, "activate",
1247                     G_CALLBACK (select_cases_dialog), de);
1248
1249
1250   de->invoke_compute_dialog =
1251     gtk_action_new ("compute-dialog",
1252                     _("_Compute"),
1253                     _("Compute new values for a variable"),
1254                     "pspp-compute");
1255
1256   g_signal_connect (de->invoke_compute_dialog, "activate",
1257                     G_CALLBACK (compute_dialog), de);
1258
1259   de->invoke_oneway_anova_dialog =
1260     gtk_action_new ("oneway-anova",
1261                     _("Oneway _ANOVA"),
1262                     _("Perform one way analysis of variance"),
1263                     NULL);
1264
1265   g_signal_connect (de->invoke_oneway_anova_dialog, "activate",
1266                     G_CALLBACK (oneway_anova_dialog), de);
1267
1268   de->invoke_t_test_independent_samples_dialog =
1269     gtk_action_new ("t-test-independent-samples",
1270                     _("_Independent Samples T Test"),
1271                     _("Calculate T Test for samples from independent groups"),
1272                     NULL);
1273
1274   g_signal_connect (de->invoke_t_test_independent_samples_dialog, "activate",
1275                     G_CALLBACK (t_test_independent_samples_dialog), de);
1276
1277
1278   de->invoke_t_test_paired_samples_dialog =
1279     gtk_action_new ("t-test-paired-samples",
1280                     _("_Paired Samples T Test"),
1281                     _("Calculate T Test for paired samples"),
1282                     NULL);
1283
1284   g_signal_connect (de->invoke_t_test_paired_samples_dialog, "activate",
1285                     G_CALLBACK (t_test_paired_samples_dialog), de);
1286
1287
1288   de->invoke_t_test_one_sample_dialog =
1289     gtk_action_new ("t-test-one-sample",
1290                     _("One _Sample T Test"),
1291                     _("Calculate T Test for sample from a single distribution"),
1292                     NULL);
1293
1294   g_signal_connect (de->invoke_t_test_one_sample_dialog, "activate",
1295                     G_CALLBACK (t_test_one_sample_dialog), de);
1296
1297
1298   de->invoke_comments_dialog =
1299     gtk_action_new ("commments-dialog",
1300                     _("Data File _Comments"),
1301                     _("Commentary text for the data file"),
1302                     NULL);
1303
1304   g_signal_connect (de->invoke_comments_dialog, "activate",
1305                     G_CALLBACK (comments_dialog), de);
1306
1307   de->invoke_find_dialog  =
1308     gtk_action_new ("find-dialog",
1309                     _("_Find"),
1310                     _("Find Case"),
1311                     "gtk-find");
1312
1313   g_signal_connect (de->invoke_find_dialog, "activate",
1314                     G_CALLBACK (find_dialog), de);
1315
1316
1317   de->invoke_rank_dialog  =
1318     gtk_action_new ("rank-dialog",
1319                     _("Ran_k Cases"),
1320                     _("Rank Cases"),
1321                     "pspp-rank-cases");
1322
1323   g_signal_connect (de->invoke_rank_dialog, "activate",
1324                     G_CALLBACK (rank_dialog), de);
1325
1326
1327   de->invoke_recode_same_dialog  =
1328     gtk_action_new ("recode-same-dialog",
1329                     _("Recode into _Same Variables"),
1330                     _("Recode values into the same Variables"),
1331                     "pspp-recode-same");
1332
1333   g_signal_connect (de->invoke_recode_same_dialog, "activate",
1334                     G_CALLBACK (recode_same_dialog), de);
1335
1336
1337   de->invoke_recode_different_dialog  =
1338     gtk_action_new ("recode-different-dialog",
1339                     _("Recode into _Different Variables"),
1340                     _("Recode values into different Variables"),
1341                     "pspp-recode-different");
1342
1343   g_signal_connect (de->invoke_recode_different_dialog, "activate",
1344                     G_CALLBACK (recode_different_dialog), de);
1345
1346
1347   de->invoke_variable_info_dialog  =
1348     gtk_action_new ("variable-info-dialog",
1349                     _("_Variables"),
1350                     _("Jump to Variable"),
1351                     "pspp-goto-variable");
1352
1353   g_signal_connect (de->invoke_variable_info_dialog, "activate",
1354                     G_CALLBACK (variable_info_dialog), de);
1355
1356   de->invoke_descriptives_dialog =
1357     gtk_action_new ("descriptives-dialog",
1358                     _("_Descriptives"),
1359                     _("Calculate descriptive statistics (mean, variance, ...)"),
1360                     "pspp-descriptives");
1361
1362   g_signal_connect (de->invoke_descriptives_dialog, "activate",
1363                     G_CALLBACK (descriptives_dialog), de);
1364
1365
1366   de->invoke_frequencies_dialog =
1367     gtk_action_new ("frequencies-dialog",
1368                     _("_Frequencies"),
1369                     _("Generate frequency statistics"),
1370                     "pspp-frequencies");
1371
1372   g_signal_connect (de->invoke_frequencies_dialog, "activate",
1373                     G_CALLBACK (frequencies_dialog), de);
1374
1375   de->invoke_crosstabs_dialog =
1376     gtk_action_new ("crosstabs-dialog",
1377                     _("_Crosstabs"),
1378                     _("Generate crosstabulations"),
1379                     "pspp-crosstabs");
1380
1381   g_signal_connect (de->invoke_crosstabs_dialog, "activate",
1382                     G_CALLBACK (crosstabs_dialog), de);
1383
1384
1385   de->invoke_examine_dialog =
1386     gtk_action_new ("examine-dialog",
1387                     _("_Explore"),
1388                     _("Examine Data by Factors"),
1389                     "pspp-examine");
1390
1391   g_signal_connect (de->invoke_examine_dialog, "activate",
1392                     G_CALLBACK (examine_dialog), de);
1393
1394
1395   de->invoke_regression_dialog =
1396     gtk_action_new ("regression-dialog",
1397                     _("Linear _Regression"),
1398                     _("Estimate parameters of the linear model"),
1399                     "pspp-regression");
1400
1401   g_signal_connect (de->invoke_regression_dialog, "activate",
1402                     G_CALLBACK (regression_dialog), de);
1403
1404   g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"),
1405                             "activate",
1406                             G_CALLBACK (gtk_action_activate),
1407                             de->action_data_new);
1408
1409   g_signal_connect_swapped (get_widget_assert (de->xml,"file_open_data"),
1410                             "activate",
1411                             G_CALLBACK (gtk_action_activate),
1412                             de->action_data_open);
1413
1414 #if RECENT_LISTS_AVAILABLE
1415   {
1416     GtkRecentManager *rm = gtk_recent_manager_get_default ();
1417     GtkWidget *recent_data = get_widget_assert (de->xml, "file_recent-data");
1418     GtkWidget *recent_files = get_widget_assert (de->xml, "file_recent-files");
1419     GtkWidget *recent_separator = get_widget_assert (de->xml, "file_separator1");
1420
1421     GtkWidget *menu = gtk_recent_chooser_menu_new_for_manager (rm);
1422
1423     GtkRecentFilter *filter = gtk_recent_filter_new ();
1424
1425     gtk_widget_show (recent_data);
1426     gtk_widget_show (recent_files);
1427     gtk_widget_show (recent_separator);
1428
1429     gtk_recent_filter_add_pattern (filter, "*.sav");
1430     gtk_recent_filter_add_pattern (filter, "*.SAV");
1431
1432     gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
1433
1434     gtk_widget_set_sensitive (recent_data, TRUE);
1435     g_signal_connect (menu, "selection-done",
1436                       G_CALLBACK (on_recent_data_select), de);
1437
1438     gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu);
1439
1440
1441     filter = gtk_recent_filter_new ();
1442     menu = gtk_recent_chooser_menu_new_for_manager (rm);
1443
1444     gtk_recent_filter_add_pattern (filter, "*.sps");
1445     gtk_recent_filter_add_pattern (filter, "*.SPS");
1446
1447     gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
1448
1449     gtk_widget_set_sensitive (recent_files, TRUE);
1450     g_signal_connect (menu, "selection-done",
1451                       G_CALLBACK (on_recent_files_select), de);
1452
1453     gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu);
1454   }
1455 #endif
1456
1457   g_signal_connect (get_widget_assert (de->xml,"file_new_syntax"),
1458                     "activate",
1459                     G_CALLBACK (create_syntax_window),
1460                     NULL);
1461
1462   g_signal_connect (get_widget_assert (de->xml,"file_open_syntax"),
1463                     "activate",
1464                     G_CALLBACK (open_syntax_window),
1465                     de);
1466
1467   g_signal_connect_swapped (get_widget_assert (de->xml,"file_import-text"),
1468                             "activate",
1469                             G_CALLBACK (gtk_action_activate),
1470                             de->invoke_text_import_assistant);
1471
1472   g_signal_connect_swapped (get_widget_assert (de->xml,"file_save"),
1473                             "activate",
1474                             G_CALLBACK (gtk_action_activate),
1475                             de->action_data_save);
1476
1477   g_signal_connect_swapped (get_widget_assert (de->xml,"file_save_as"),
1478                             "activate",
1479                             G_CALLBACK (gtk_action_activate),
1480                             de->action_data_save_as);
1481
1482   gtk_action_connect_proxy (de->invoke_find_dialog,
1483                             get_widget_assert (de->xml, "edit_find")
1484                             );
1485
1486   gtk_action_connect_proxy (de->invoke_find_dialog,
1487                             get_widget_assert (de->xml, "button-find")
1488                             );
1489
1490   gtk_action_connect_proxy (de->invoke_rank_dialog,
1491                             get_widget_assert (de->xml, "transform_rank")
1492                             );
1493
1494   gtk_action_connect_proxy (de->invoke_recode_same_dialog,
1495                             get_widget_assert (de->xml,
1496                                                "transform_recode-same")
1497                             );
1498
1499   gtk_action_connect_proxy (de->invoke_recode_different_dialog,
1500                             get_widget_assert (de->xml,
1501                                                "transform_recode-different")
1502                             );
1503
1504   gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
1505                             get_widget_assert (de->xml, "data_weight-cases")
1506                             );
1507
1508   gtk_action_connect_proxy (de->invoke_transpose_dialog,
1509                             get_widget_assert (de->xml, "data_transpose")
1510                             );
1511
1512   gtk_action_connect_proxy (de->invoke_split_file_dialog,
1513                             get_widget_assert (de->xml, "data_split-file")
1514                             );
1515
1516   gtk_action_connect_proxy (de->invoke_sort_cases_dialog,
1517                             get_widget_assert (de->xml, "data_sort-cases")
1518                             );
1519
1520   gtk_action_connect_proxy (de->invoke_select_cases_dialog,
1521                             get_widget_assert (de->xml, "data_select-cases")
1522                             );
1523
1524   gtk_action_connect_proxy (de->invoke_compute_dialog,
1525                             get_widget_assert (de->xml, "transform_compute")
1526                             );
1527
1528   gtk_action_connect_proxy (de->invoke_t_test_independent_samples_dialog,
1529                             get_widget_assert (de->xml,
1530                                                "indep-t-test")
1531                             );
1532
1533
1534   gtk_action_connect_proxy (de->invoke_t_test_paired_samples_dialog,
1535                             get_widget_assert (de->xml,
1536                                                "paired-t-test")
1537                             );
1538
1539
1540   gtk_action_connect_proxy (de->invoke_t_test_one_sample_dialog,
1541                             get_widget_assert (de->xml,
1542                                                "one-sample-t-test")
1543                             );
1544
1545
1546   gtk_action_connect_proxy (de->invoke_oneway_anova_dialog,
1547                             get_widget_assert (de->xml,
1548                                                "oneway-anova")
1549                             );
1550
1551
1552   gtk_action_connect_proxy (de->invoke_comments_dialog,
1553                             get_widget_assert (de->xml, "utilities_comments")
1554                             );
1555
1556   gtk_action_connect_proxy (de->invoke_variable_info_dialog,
1557                             get_widget_assert (de->xml, "utilities_variables")
1558                             );
1559
1560   gtk_action_connect_proxy (de->invoke_descriptives_dialog,
1561                             get_widget_assert (de->xml, "analyze_descriptives")
1562                             );
1563
1564   gtk_action_connect_proxy (de->invoke_crosstabs_dialog,
1565                             get_widget_assert (de->xml, "crosstabs")
1566                             );
1567
1568   gtk_action_connect_proxy (de->invoke_frequencies_dialog,
1569                             get_widget_assert (de->xml, "analyze_frequencies")
1570                             );
1571
1572
1573   gtk_action_connect_proxy (de->invoke_examine_dialog,
1574                             get_widget_assert (de->xml, "analyze_explore")
1575                             );
1576
1577   gtk_action_connect_proxy (de->invoke_regression_dialog,
1578                             get_widget_assert (de->xml, "linear-regression")
1579                             );
1580
1581   g_signal_connect (get_widget_assert (de->xml,"help_about"),
1582                     "activate",
1583                     G_CALLBACK (about_new),
1584                     de);
1585
1586
1587   g_signal_connect (get_widget_assert (de->xml,"help_reference"),
1588                     "activate",
1589                     G_CALLBACK (reference_manual),
1590                     de);
1591
1592
1593   g_signal_connect (de->data_editor,
1594                     "cases-selected",
1595                     G_CALLBACK (enable_delete_cases),
1596                     de);
1597
1598   g_signal_connect (de->data_editor,
1599                     "variables-selected",
1600                     G_CALLBACK (enable_delete_variables),
1601                     de);
1602
1603
1604   g_signal_connect (GTK_NOTEBOOK (de->data_editor),
1605                     "switch-page",
1606                     G_CALLBACK (on_switch_sheet), de);
1607
1608   gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
1609   gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
1610
1611   g_signal_connect (get_widget_assert (de->xml, "view_statusbar"),
1612                     "activate",
1613                     G_CALLBACK (status_bar_activate), de);
1614
1615
1616   g_signal_connect (get_widget_assert (de->xml, "view_gridlines"),
1617                     "activate",
1618                     G_CALLBACK (grid_lines_activate), de);
1619
1620
1621
1622   g_signal_connect (get_widget_assert (de->xml, "view_data"),
1623                     "activate",
1624                     G_CALLBACK (data_view_activate), de);
1625
1626   g_signal_connect (get_widget_assert (de->xml, "view_variables"),
1627                     "activate",
1628                     G_CALLBACK (variable_view_activate), de);
1629
1630
1631
1632   g_signal_connect (get_widget_assert (de->xml, "view_fonts"),
1633                     "activate",
1634                     G_CALLBACK (fonts_activate), de);
1635
1636
1637
1638
1639   gtk_action_connect_proxy (de->action_data_open,
1640                             get_widget_assert (de->xml, "button-open")
1641                             );
1642
1643   gtk_action_connect_proxy (de->action_data_save,
1644                             get_widget_assert (de->xml, "button-save")
1645                             );
1646
1647   gtk_action_connect_proxy (de->invoke_variable_info_dialog,
1648                             get_widget_assert (de->xml, "button-goto-variable")
1649                             );
1650
1651   gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
1652                             get_widget_assert (de->xml, "button-weight-cases")
1653                             );
1654
1655   gtk_action_connect_proxy (de->invoke_split_file_dialog,
1656                             get_widget_assert (de->xml, "button-split-file")
1657                             );
1658
1659   gtk_action_connect_proxy (de->invoke_select_cases_dialog,
1660                             get_widget_assert (de->xml, "button-select-cases")
1661                             );
1662
1663
1664   g_signal_connect (get_widget_assert (de->xml, "file_quit"),
1665                     "activate",
1666                     G_CALLBACK (file_quit), de);
1667
1668   g_signal_connect (get_widget_assert (de->xml, "transform_run-pending"),
1669                     "activate",
1670                     G_CALLBACK (execute), de);
1671
1672
1673   g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"),
1674                     "activate",
1675                     G_CALLBACK (psppire_window_minimise_all), NULL);
1676
1677   de->toggle_split_window =
1678     gtk_toggle_action_new ("toggle-split-window",
1679                            _("_Split Window"),
1680                            _("Split the window vertically and horizontally"),
1681                            "pspp-split-window");
1682
1683   g_signal_connect (de->toggle_split_window, "toggled",
1684                     G_CALLBACK (toggle_split_window),
1685                     de);
1686
1687   gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window),
1688                             get_widget_assert (de->xml,
1689                                                "windows_split"));
1690
1691   de->data_sheet_variable_popup_menu =
1692     GTK_MENU (create_data_sheet_variable_popup_menu (de));
1693
1694   de->var_sheet_variable_popup_menu =
1695     GTK_MENU (create_var_sheet_variable_popup_menu (de));
1696
1697   de->data_sheet_cases_popup_menu =
1698     GTK_MENU (create_data_sheet_cases_popup_menu (de));
1699
1700   PSPPIRE_WINDOW (de)->menu = GTK_MENU_SHELL (get_widget_assert (de->xml,"Windows_menu"));
1701
1702   g_object_set (de->data_editor,
1703                 "datasheet-column-menu", de->data_sheet_variable_popup_menu,
1704                 "datasheet-row-menu", de->data_sheet_cases_popup_menu,
1705                 "varsheet-row-menu", de->var_sheet_variable_popup_menu,
1706                 NULL);
1707
1708   gtk_widget_show (GTK_WIDGET (de->data_editor));
1709   gtk_widget_show (box);
1710 }
1711
1712
1713 GtkWidget*
1714 psppire_data_window_new (void)
1715 {
1716   return GTK_WIDGET (g_object_new (psppire_data_window_get_type (),
1717                                    "usage", PSPPIRE_WINDOW_USAGE_DATA,
1718                                    NULL));
1719 }
1720