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