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