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