1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014,
3 2016, 2017 Free Software Foundation
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "data/dataset.h"
24 #include "data/session.h"
25 #include "language/lexer/lexer.h"
26 #include "libpspp/message.h"
27 #include "libpspp/str.h"
28 #include "ui/gui/builder-wrapper.h"
29 #include "ui/gui/entry-dialog.h"
30 #include "ui/gui/executor.h"
31 #include "ui/gui/help-menu.h"
32 #include "ui/gui/helper.h"
33 #include "ui/gui/helper.h"
34 #include "ui/gui/psppire-import-assistant.h"
35 #include "ui/gui/psppire-data-window.h"
36 #include "ui/gui/psppire-data-editor.h"
37 #include "ui/gui/psppire-dialog-action.h"
38 #include "ui/gui/psppire-encoding-selector.h"
39 #include "ui/gui/psppire-syntax-window.h"
40 #include "ui/gui/psppire-window.h"
41 #include "ui/gui/windows-menu.h"
42 #include "ui/gui/goto-case-dialog.h"
43 #include "ui/gui/psppire.h"
44 #include "ui/syntax-gen.h"
46 #include "gl/c-strcase.h"
47 #include "gl/c-strcasestr.h"
48 #include "gl/xvasprintf.h"
50 #include "ui/gui/efficient-sheet/jmd-sheet.h"
52 #include "find-dialog.h"
53 #include "options-dialog.h"
54 #include "psppire-dialog-action-1sks.h"
55 #include "psppire-dialog-action-aggregate.h"
56 #include "psppire-dialog-action-autorecode.h"
57 #include "psppire-dialog-action-barchart.h"
58 #include "psppire-dialog-action-binomial.h"
59 #include "psppire-dialog-action-chisquare.h"
60 #include "psppire-dialog-action-comments.h"
61 #include "psppire-dialog-action-compute.h"
62 #include "psppire-dialog-action-correlation.h"
63 #include "psppire-dialog-action-count.h"
64 #include "psppire-dialog-action-crosstabs.h"
65 #include "psppire-dialog-action-descriptives.h"
66 #include "psppire-dialog-action-examine.h"
67 #include "psppire-dialog-action-factor.h"
68 #include "psppire-dialog-action-flip.h"
69 #include "psppire-dialog-action-frequencies.h"
70 #include "psppire-dialog-action-histogram.h"
71 #include "psppire-dialog-action-indep-samps.h"
72 #include "psppire-dialog-action-k-related.h"
73 #include "psppire-dialog-action-kmeans.h"
74 #include "psppire-dialog-action-logistic.h"
75 #include "psppire-dialog-action-means.h"
76 #include "psppire-dialog-action-oneway.h"
77 #include "psppire-dialog-action-paired.h"
78 #include "psppire-dialog-action-rank.h"
79 #include "psppire-dialog-action-recode-same.h"
80 #include "psppire-dialog-action-recode-different.h"
81 #include "psppire-dialog-action-regression.h"
82 #include "psppire-dialog-action-reliability.h"
83 #include "psppire-dialog-action-roc.h"
84 #include "psppire-dialog-action-runs.h"
85 #include "psppire-dialog-action-scatterplot.h"
86 #include "psppire-dialog-action-select.h"
87 #include "psppire-dialog-action-sort.h"
88 #include "psppire-dialog-action-split.h"
89 #include "psppire-dialog-action-tt1s.h"
90 #include "psppire-dialog-action-two-sample.h"
91 #include "psppire-dialog-action-univariate.h"
92 #include "psppire-dialog-action-var-info.h"
93 #include "psppire-dialog-action-weight.h"
97 #define _(msgid) gettext (msgid)
98 #define N_(msgid) msgid
100 struct session *the_session;
101 struct ll_list all_data_windows = LL_INITIALIZER (all_data_windows);
103 static void psppire_data_window_class_init (PsppireDataWindowClass *class);
104 static void psppire_data_window_init (PsppireDataWindow *data_editor);
107 static void psppire_data_window_iface_init (PsppireWindowIface *iface);
109 static void psppire_data_window_dispose (GObject *object);
110 static void psppire_data_window_finalize (GObject *object);
111 static void psppire_data_window_set_property (GObject *object,
115 static void psppire_data_window_get_property (GObject *object,
121 psppire_data_window_get_type (void)
123 static GType psppire_data_window_type = 0;
125 if (!psppire_data_window_type)
127 static const GTypeInfo psppire_data_window_info =
129 sizeof (PsppireDataWindowClass),
132 (GClassInitFunc)psppire_data_window_class_init,
133 (GClassFinalizeFunc) NULL,
135 sizeof (PsppireDataWindow),
137 (GInstanceInitFunc) psppire_data_window_init,
140 static const GInterfaceInfo window_interface_info =
142 (GInterfaceInitFunc) psppire_data_window_iface_init,
147 psppire_data_window_type =
148 g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireDataWindow",
149 &psppire_data_window_info, 0);
152 g_type_add_interface_static (psppire_data_window_type,
153 PSPPIRE_TYPE_WINDOW_MODEL,
154 &window_interface_info);
157 return psppire_data_window_type;
160 static GObjectClass *parent_class ;
167 psppire_data_window_class_init (PsppireDataWindowClass *class)
169 GObjectClass *object_class = G_OBJECT_CLASS (class);
171 parent_class = g_type_class_peek_parent (class);
173 object_class->dispose = psppire_data_window_dispose;
174 object_class->finalize = psppire_data_window_finalize;
175 object_class->set_property = psppire_data_window_set_property;
176 object_class->get_property = psppire_data_window_get_property;
178 g_object_class_install_property (
179 object_class, PROP_DATASET,
180 g_param_spec_pointer ("dataset", "Dataset",
181 "'struct datset *' represented by the window",
182 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
187 /* Run the EXECUTE command. */
189 execute (PsppireDataWindow *dw)
191 execute_const_syntax_string (dw, "EXECUTE.");
195 transformation_change_callback (bool transformations_pending,
198 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
200 GtkWidget *status_label =
201 get_widget_assert (de->builder, "case-counter-area");
204 GAction *action = g_action_map_lookup_action (G_ACTION_MAP (de),
205 "transform-pending");
207 g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
208 transformations_pending);
211 if ( transformations_pending)
212 gtk_label_set_text (GTK_LABEL (status_label),
213 _("Transformations Pending"));
215 gtk_label_set_text (GTK_LABEL (status_label), "");
218 /* Callback for when the dictionary changes its filter variable */
220 on_filter_change (GObject *o, gint filter_index, gpointer data)
222 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
224 GtkWidget *filter_status_area =
225 get_widget_assert (de->builder, "filter-use-status-area");
227 if ( filter_index == -1 )
229 gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
233 PsppireDict *dict = NULL;
234 struct variable *var ;
237 g_object_get (de->data_editor, "dictionary", &dict, NULL);
239 var = psppire_dict_get_variable (dict, filter_index);
241 text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
243 gtk_label_set_text (GTK_LABEL (filter_status_area), text);
249 /* Callback for when the dictionary changes its split variables */
251 on_split_change (PsppireDict *dict, gpointer data)
253 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
255 size_t n_split_vars = dict_get_split_cnt (dict->dict);
257 GtkWidget *split_status_area =
258 get_widget_assert (de->builder, "split-file-status-area");
260 if ( n_split_vars == 0 )
262 gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
268 const struct variable *const * split_vars =
269 dict_get_split_vars (dict->dict);
271 text = g_string_new (_("Split by "));
273 for (i = 0 ; i < n_split_vars - 1; ++i )
275 g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
277 g_string_append (text, var_get_name (split_vars[i]));
279 gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
281 g_string_free (text, TRUE);
288 /* Callback for when the dictionary changes its weights */
290 on_weight_change (GObject *o, gint weight_index, gpointer data)
292 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
294 GtkWidget *weight_status_area =
295 get_widget_assert (de->builder, "weight-status-area");
297 if ( weight_index == -1 )
299 gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
303 struct variable *var ;
304 PsppireDict *dict = NULL;
307 g_object_get (de->data_editor, "dictionary", &dict, NULL);
309 var = psppire_dict_get_variable (dict, weight_index);
311 text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
313 gtk_label_set_text (GTK_LABEL (weight_status_area), text);
321 dump_rm (GtkRecentManager *rm)
323 GList *items = gtk_recent_manager_get_items (rm);
327 g_print ("Recent Items:\n");
328 for (i = items; i; i = i->next)
330 GtkRecentInfo *ri = i->data;
332 g_print ("Item: %s (Mime: %s) (Desc: %s) (URI: %s)\n",
333 gtk_recent_info_get_short_name (ri),
334 gtk_recent_info_get_mime_type (ri),
335 gtk_recent_info_get_description (ri),
336 gtk_recent_info_get_uri (ri)
340 gtk_recent_info_unref (ri);
348 has_suffix (const gchar *name, const gchar *suffix)
350 size_t name_len = strlen (name);
351 size_t suffix_len = strlen (suffix);
352 return (name_len > suffix_len
353 && !c_strcasecmp (&name[name_len - suffix_len], suffix));
357 name_has_por_suffix (const gchar *name)
359 return has_suffix (name, ".por");
363 name_has_sav_suffix (const gchar *name)
365 return has_suffix (name, ".sav") || has_suffix (name, ".zsav");
368 /* Returns true if NAME has a suffix which might denote a PSPP file */
370 name_has_suffix (const gchar *name)
372 return name_has_por_suffix (name) || name_has_sav_suffix (name);
376 load_file (PsppireWindow *de, const gchar *file_name, const char *encoding,
379 const char *mime_type = NULL;
380 gchar *syntax = NULL;
385 gchar *utf8_file_name;
386 struct string filename;
388 utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL, NULL);
390 if (NULL == utf8_file_name)
393 ds_init_empty (&filename);
394 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
396 g_free (utf8_file_name);
398 if (encoding && encoding[0])
399 syntax = g_strdup_printf ("GET FILE=%s ENCODING='%s'.",
400 ds_cstr (&filename), encoding);
402 syntax = g_strdup_printf ("GET FILE=%s.", ds_cstr (&filename));
403 ds_destroy (&filename);
410 ok = execute_syntax (PSPPIRE_DATA_WINDOW (de),
411 lex_reader_for_string (syntax, "UTF-8"));
414 if (ok && syn == NULL)
416 if (name_has_por_suffix (file_name))
417 mime_type = "application/x-spss-por";
418 else if (name_has_sav_suffix (file_name))
419 mime_type = "application/x-spss-sav";
421 add_most_recent (file_name, mime_type, encoding);
428 psppire_data_window_format_to_string (enum PsppireDataWindowFormat format)
430 if (format == PSPPIRE_DATA_WINDOW_SAV)
432 else if (format == PSPPIRE_DATA_WINDOW_ZSAV)
438 /* Save DE to file */
440 save_file (PsppireWindow *w)
442 const gchar *file_name = NULL;
443 gchar *utf8_file_name = NULL;
445 struct string filename ;
446 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (w);
449 file_name = psppire_window_get_filename (w);
451 fnx = g_string_new (file_name);
453 if ( ! name_has_suffix (fnx->str))
454 g_string_append (fnx, psppire_data_window_format_to_string (de->format));
456 ds_init_empty (&filename);
458 utf8_file_name = g_filename_to_utf8 (fnx->str, -1, NULL, NULL, NULL);
460 g_string_free (fnx, TRUE);
462 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
463 g_free (utf8_file_name);
465 if (de->format == PSPPIRE_DATA_WINDOW_SAV)
466 syntax = g_strdup_printf ("SAVE OUTFILE=%s.", ds_cstr (&filename));
467 else if (de->format == PSPPIRE_DATA_WINDOW_ZSAV)
468 syntax = g_strdup_printf ("SAVE /ZCOMPRESSED /OUTFILE=%s.",
469 ds_cstr (&filename));
471 syntax = g_strdup_printf ("EXPORT OUTFILE=%s.", ds_cstr (&filename));
473 ds_destroy (&filename);
475 g_free (execute_syntax_string (de, syntax));
480 display_dict (PsppireDataWindow *de)
482 execute_const_syntax_string (de, "DISPLAY DICTIONARY.");
486 sysfile_info (PsppireDataWindow *de)
488 GtkWidget *dialog = psppire_window_file_chooser_dialog (PSPPIRE_WINDOW (de));
490 if ( GTK_RESPONSE_ACCEPT == gtk_dialog_run (GTK_DIALOG (dialog)))
492 struct string filename;
494 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
495 gchar *utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL,
498 const gchar *encoding = psppire_encoding_selector_get_encoding (
499 gtk_file_chooser_get_extra_widget (GTK_FILE_CHOOSER (dialog)));
503 ds_init_empty (&filename);
505 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
507 g_free (utf8_file_name);
510 syntax = g_strdup_printf ("SYSFILE INFO %s ENCODING='%s'.",
511 ds_cstr (&filename), encoding);
513 syntax = g_strdup_printf ("SYSFILE INFO %s.", ds_cstr (&filename));
514 g_free (execute_syntax_string (de, syntax));
517 gtk_widget_destroy (dialog);
521 /* PsppireWindow 'pick_filename' callback: prompt for a filename to save as. */
523 data_pick_filename (PsppireWindow *window)
525 GtkListStore *list_store;
526 GtkWidget *combo_box;
528 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (window);
529 GtkFileFilter *filter;
531 gtk_file_chooser_dialog_new (_("Save"),
533 GTK_FILE_CHOOSER_ACTION_SAVE,
534 _("Cancel"), GTK_RESPONSE_CANCEL,
535 _("Save"), GTK_RESPONSE_ACCEPT,
538 g_object_set (dialog, "local-only", FALSE, NULL);
540 filter = gtk_file_filter_new ();
541 gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
542 gtk_file_filter_add_mime_type (filter, "application/x-spss-sav");
543 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
545 filter = gtk_file_filter_new ();
546 gtk_file_filter_set_name (filter, _("Compressed System Files (*.zsav)"));
547 gtk_file_filter_add_pattern (filter, "*.zsav");
548 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
550 filter = gtk_file_filter_new ();
551 gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
552 gtk_file_filter_add_mime_type (filter, "application/x-spss-por");
553 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
555 filter = gtk_file_filter_new ();
556 gtk_file_filter_set_name (filter, _("All Files"));
557 gtk_file_filter_add_pattern (filter, "*");
558 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
559 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
562 GtkCellRenderer *cell;
567 list_store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
568 combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (list_store));
570 gtk_list_store_append (list_store, &iter);
571 gtk_list_store_set (list_store, &iter,
572 0, PSPPIRE_DATA_WINDOW_SAV,
575 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter);
577 gtk_list_store_append (list_store, &iter);
578 gtk_list_store_set (list_store, &iter,
579 0, PSPPIRE_DATA_WINDOW_ZSAV,
580 1, _("Compressed System File"),
583 gtk_list_store_append (list_store, &iter);
584 gtk_list_store_set (list_store, &iter,
585 0, PSPPIRE_DATA_WINDOW_POR,
586 1, _("Portable File"),
589 label = gtk_label_new (_("Format:"));
591 cell = gtk_cell_renderer_text_new ();
592 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, FALSE);
593 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo_box), cell,
596 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
597 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
598 gtk_box_pack_start (GTK_BOX (hbox), combo_box, FALSE, FALSE, 0);
599 gtk_widget_show_all (hbox);
601 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), hbox);
604 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
607 switch (gtk_dialog_run (GTK_DIALOG (dialog)))
609 case GTK_RESPONSE_ACCEPT:
614 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog))
620 gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter);
621 gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter,
626 if ( ! name_has_suffix (filename->str))
627 g_string_append (filename,
628 psppire_data_window_format_to_string (format));
630 psppire_window_set_filename (PSPPIRE_WINDOW (de), filename->str);
632 g_string_free (filename, TRUE);
639 gtk_widget_destroy (dialog);
643 confirm_delete_dataset (PsppireDataWindow *de,
644 const char *old_dataset,
645 const char *new_dataset,
646 const char *existing_dataset)
651 dialog = gtk_message_dialog_new (
652 GTK_WINDOW (de), 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s",
653 _("Delete Existing Dataset?"));
655 gtk_message_dialog_format_secondary_text (
656 GTK_MESSAGE_DIALOG (dialog),
657 _("Renaming \"%s\" to \"%s\" will destroy the existing "
658 "dataset named \"%s\". Are you sure that you want to do this?"),
659 old_dataset, new_dataset, existing_dataset);
661 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
662 _("Cancel"), GTK_RESPONSE_CANCEL,
663 _("Delete"), GTK_RESPONSE_OK,
666 g_object_set (dialog, "icon-name", "pspp", NULL);
668 result = gtk_dialog_run (GTK_DIALOG (dialog));
670 gtk_widget_destroy (dialog);
672 return result == GTK_RESPONSE_OK;
676 on_rename_dataset (PsppireDataWindow *de)
678 struct dataset *ds = de->dataset;
679 struct session *session = dataset_session (ds);
680 const char *old_name = dataset_name (ds);
681 struct dataset *existing_dataset;
685 prompt = xasprintf (_("Please enter a new name for dataset \"%s\":"),
687 new_name = entry_dialog_run (GTK_WINDOW (de), _("Rename Dataset"), prompt,
691 if (new_name == NULL)
694 existing_dataset = session_lookup_dataset (session, new_name);
695 if (existing_dataset == NULL || existing_dataset == ds
696 || confirm_delete_dataset (de, old_name, new_name,
697 dataset_name (existing_dataset)))
698 g_free (execute_syntax_string (de, g_strdup_printf ("DATASET NAME %s.",
706 status_bar_activate (GAction *action, GVariant *param, PsppireDataWindow *de)
708 GtkWidget *statusbar = get_widget_assert (de->builder, "status-bar");
710 GVariant *state = g_action_get_state (action);
711 const gboolean visible = g_variant_get_boolean (state);
712 g_action_change_state (action, g_variant_new_boolean (!visible));
714 gtk_widget_set_visible (statusbar, !visible);
719 grid_lines_activate (GAction *action, GVariant *param, PsppireDataWindow *de)
721 GVariant *state = g_action_get_state (action);
722 const gboolean grid_visible = g_variant_get_boolean (state);
723 g_action_change_state (action, g_variant_new_boolean (!grid_visible));
725 psppire_data_editor_show_grid (de->data_editor, !grid_visible);
730 on_switch_page (GtkNotebook *notebook, GtkWidget *page, guint pn, gpointer ud)
732 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (ud);
734 GAction *action = g_action_map_lookup_action (G_ACTION_MAP (de), "view_dv");
739 g_action_change_state (action, g_variant_new_string ("DATA"));
740 gtk_widget_show (GTK_WIDGET (de->ti_insert_case));
741 gtk_widget_show (GTK_WIDGET (de->ti_jump_to_case));
742 gtk_widget_show (GTK_WIDGET (de->ti_find));
744 gtk_widget_show (GTK_WIDGET (de->mi_go_to_case));
745 gtk_widget_show (GTK_WIDGET (de->mi_insert_case));
746 gtk_widget_show (GTK_WIDGET (de->mi_find));
747 gtk_widget_show (GTK_WIDGET (de->mi_find_separator));
748 gtk_widget_show (GTK_WIDGET (de->mi_clear_cases));
753 g_action_change_state (action, g_variant_new_string ("VARS"));
754 gtk_widget_hide (GTK_WIDGET (de->ti_insert_case));
755 gtk_widget_hide (GTK_WIDGET (de->ti_jump_to_case));
756 gtk_widget_hide (GTK_WIDGET (de->ti_find));
758 gtk_widget_hide (GTK_WIDGET (de->mi_go_to_case));
759 gtk_widget_hide (GTK_WIDGET (de->mi_insert_case));
760 gtk_widget_hide (GTK_WIDGET (de->mi_find));
761 gtk_widget_hide (GTK_WIDGET (de->mi_find_separator));
762 gtk_widget_hide (GTK_WIDGET (de->mi_clear_cases));
770 activate_change_view (GAction *action, GVariant *param, PsppireDataWindow *de)
772 g_action_change_state (action, param);
773 GVariant *new_state = g_action_get_state (action);
775 const gchar *what = g_variant_get_string (new_state, NULL);
776 if (0 == g_strcmp0 (what, "DATA"))
778 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
780 else if (0 == g_strcmp0 (what, "VARS"))
782 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
789 fonts_activate (PsppireDataWindow *de)
791 GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (de));
792 GtkWidget *dialog = gtk_font_chooser_dialog_new (NULL, GTK_WINDOW (toplevel));
793 GtkStyleContext *style = gtk_widget_get_style_context (GTK_WIDGET(de->data_editor));
794 const PangoFontDescription *current_font ;
796 gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, "font", ¤t_font, NULL);
798 gtk_font_chooser_set_font_desc (GTK_FONT_CHOOSER (dialog), current_font);
800 gtk_window_set_transient_for (GTK_WINDOW (dialog),
801 GTK_WINDOW (toplevel));
803 if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) )
805 PangoFontDescription* font_desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (dialog));
807 psppire_data_editor_set_font (de->data_editor, font_desc);
810 gtk_widget_hide (dialog);
815 /* Callback for the value labels action */
818 value_labels_activate (GAction *action, GVariant *param, PsppireDataWindow *de)
820 GVariant *v = g_action_get_state (action);
821 gboolean labels_active = g_variant_get_boolean (v);
822 g_action_change_state (action, g_variant_new_boolean (!labels_active));
824 GVariant *new_state = g_action_get_state (action);
825 labels_active = g_variant_get_boolean (new_state);
826 g_object_set (de->data_editor, "value-labels", labels_active, NULL);
828 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (de->ti_value_labels_button),
833 on_labels_button_toggle (GtkToggleToolButton *ttb, PsppireDataWindow *de)
835 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "value_labels");
837 gboolean labels_active = gtk_toggle_tool_button_get_active (ttb);
839 g_action_change_state (a, g_variant_new_boolean (labels_active));
841 GVariant *new_state = g_action_get_state (a);
842 labels_active = g_variant_get_boolean (new_state);
843 g_object_set (de->data_editor, "value-labels", labels_active, NULL);
847 on_recent_data_select (GtkMenuShell *menushell,
848 PsppireWindow *window)
853 gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
855 file = g_filename_from_uri (uri, NULL, NULL);
859 open_data_window (window, file, NULL, NULL);
865 charset_from_mime_type (const char *mime_type)
871 if (mime_type == NULL)
874 charset = c_strcasestr (mime_type, "charset=");
882 /* Parse a "quoted-string" as defined by RFC 822. */
883 for (p++; *p != '\0' && *p != '"'; p++)
886 ds_put_byte (&s, *p);
887 else if (*++p != '\0')
888 ds_put_byte (&s, *p);
893 /* Parse a "token" as defined by RFC 2045. */
894 while (*p > 32 && *p < 127 && strchr ("()<>@,;:\\\"/[]?=", *p) == NULL)
895 ds_put_byte (&s, *p++);
897 if (!ds_is_empty (&s))
898 return ds_steal_cstr (&s);
905 on_recent_files_select (GtkMenuShell *menushell, gpointer user_data)
912 /* Get the file name and its encoding. */
913 item = gtk_recent_chooser_get_current_item (GTK_RECENT_CHOOSER (menushell));
914 file = g_filename_from_uri (gtk_recent_info_get_uri (item), NULL, NULL);
915 encoding = charset_from_mime_type (gtk_recent_info_get_mime_type (item));
916 gtk_recent_info_unref (item);
918 se = psppire_syntax_window_new (encoding);
922 if ( psppire_window_load (PSPPIRE_WINDOW (se), file, encoding, NULL) )
923 gtk_widget_show (se);
925 gtk_widget_destroy (se);
931 set_unsaved (gpointer w)
933 psppire_window_set_unsaved (PSPPIRE_WINDOW (w));
937 /* Only a data file with at least one variable can be saved. */
939 enable_save (PsppireDataWindow *dw)
941 gboolean enable = psppire_dict_get_var_cnt (dw->dict) > 0;
943 GAction *save_as = g_action_map_lookup_action (G_ACTION_MAP (dw), "save-as");
944 GAction *save = g_action_map_lookup_action (G_ACTION_MAP (dw), "save");
947 g_object_set (save, "enabled", enable, NULL);
950 g_object_set (save_as, "enabled", enable, NULL);
953 /* Initializes as much of a PsppireDataWindow as we can and must before the
954 dataset has been set.
956 In particular, the 'menu' member is required in case the "filename" property
957 is set before the "dataset" property: otherwise PsppireWindow will try to
958 modify the menu as part of the "filename" property_set() function and end up
959 with a Gtk-CRITICAL since 'menu' is NULL. */
961 psppire_data_window_init (PsppireDataWindow *de)
963 de->builder = builder_new ("data-editor.ui");
967 file_import (PsppireDataWindow *dw)
969 GtkWidget *w = psppire_import_assistant_new (GTK_WINDOW (dw));
970 PsppireImportAssistant *asst = PSPPIRE_IMPORT_ASSISTANT (w);
971 gtk_widget_show_all (w);
973 asst->main_loop = g_main_loop_new (NULL, TRUE);
974 g_main_loop_run (asst->main_loop);
975 g_main_loop_unref (asst->main_loop);
977 if (!asst->file_name)
980 switch (asst->response)
982 case GTK_RESPONSE_APPLY:
984 gchar *fn = g_path_get_basename (asst->file_name);
985 open_data_window (PSPPIRE_WINDOW (dw), fn, NULL, psppire_import_assistant_generate_syntax (asst));
989 case PSPPIRE_RESPONSE_PASTE:
990 free (paste_syntax_to_window (psppire_import_assistant_generate_syntax (asst)));
997 gtk_widget_destroy (GTK_WIDGET (asst));
1003 connect_dialog_action (GType type, PsppireDataWindow *de)
1005 GAction *act = g_object_new (type,
1009 g_action_map_add_action (G_ACTION_MAP (de), act);
1013 g_action_activate_null (GAction *a)
1015 g_action_activate (a, NULL);
1019 connect_action_to_menuitem (GActionMap *map, const gchar *action_name, GtkWidget *w, const gchar *accel)
1021 GAction *a = g_action_map_lookup_action (map, action_name);
1024 g_error ("Action \"%s\" not found in map", action_name);
1028 GtkApplication *app = GTK_APPLICATION (g_application_get_default());
1030 /* First set the label for the accellerator so that it appears
1032 GtkWidget *child = gtk_bin_get_child (GTK_BIN (w));
1034 GdkModifierType modifier;
1035 gtk_accelerator_parse (accel, &key, &modifier);
1036 gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), key, modifier);
1038 /* Now tell the application that it must do something when that
1039 key combination is pressed */
1040 const gchar *accels[2];
1044 gchar *detailed_action_name = NULL;
1045 if (GTK_IS_WINDOW (map))
1046 detailed_action_name = g_strdup_printf ("win.%s", action_name);
1047 else if (GTK_IS_APPLICATION (map))
1048 detailed_action_name = g_strdup_printf ("app.%s", action_name);
1050 gtk_application_set_accels_for_action (app,
1051 detailed_action_name,
1053 free (detailed_action_name);
1056 g_signal_connect_swapped (w, "activate", G_CALLBACK (g_action_activate_null), a);
1061 set_data_page (PsppireDataWindow *dw)
1063 gtk_notebook_set_current_page (GTK_NOTEBOOK (dw->data_editor), 1);
1064 gtk_notebook_set_current_page (GTK_NOTEBOOK (dw->data_editor), 0);
1069 on_cut (PsppireDataWindow *dw)
1071 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
1072 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1074 PsppireDict *dict = NULL;
1075 g_object_get (dw->data_editor, "dictionary", &dict, NULL);
1078 JmdSheet *sheet = JMD_SHEET (dw->data_editor->data_sheet);
1079 JmdRange sel = *sheet->selection;
1081 GtkClipboard *clip =
1082 gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
1083 GDK_SELECTION_CLIPBOARD);
1085 /* Save the selected area to a string */
1086 GString *str = g_string_new ("");
1087 for (y = sel.start_y ; y <= sel.end_y; ++y)
1089 for (x = sel.start_x ; x <= sel.end_x; ++x)
1091 const struct variable * var = psppire_dict_get_variable (dict, x);
1092 gchar *s = psppire_data_store_get_string (dw->data_editor->data_store,
1094 g_string_append (str, s);
1095 g_string_append (str, "\t");
1098 g_string_append (str, "\n");
1101 gtk_clipboard_set_text (clip, str->str, str->len);
1102 g_string_free (str, TRUE);
1104 /* Now fill the selected area with SYSMIS */
1107 for (x = sel.start_x ; x <= sel.end_x; ++x)
1109 const struct variable * var = psppire_dict_get_variable (dict, x);
1110 for (y = sel.start_y ; y <= sel.end_y; ++y)
1112 psppire_data_store_set_value (dw->data_editor->data_store,
1124 on_copy (PsppireDataWindow *dw)
1126 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
1127 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1129 GtkClipboard *clip =
1130 gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
1131 GDK_SELECTION_CLIPBOARD);
1133 jmd_sheet_set_clip (JMD_SHEET (dw->data_editor->data_sheet), clip);
1139 trf (GtkClipboard *clip,
1145 for (i = 0; i < n_atoms; ++i)
1147 g_print ("%s\n", gdk_atom_name (atoms[i]));
1152 on_paste (PsppireDataWindow *dw)
1154 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
1155 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1157 GtkClipboard *clip =
1158 gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
1159 GDK_SELECTION_CLIPBOARD);
1161 gtk_clipboard_request_targets (clip, trf, dw);
1167 on_clear_cases (PsppireDataWindow *dw)
1169 PsppireDataEditor *de = dw->data_editor;
1170 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
1171 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1173 JmdRange *range = JMD_SHEET(de->data_sheet)->selection;
1174 psppire_data_store_delete_cases (de->data_store, range->start_y,
1175 range->end_y - range->start_y + 1);
1176 gtk_widget_queue_draw (GTK_WIDGET (de->data_sheet));
1181 on_clear_variables (PsppireDataWindow *dw)
1183 PsppireDataEditor *de = dw->data_editor;
1184 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
1185 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1187 psppire_data_editor_data_delete_variables (de);
1191 psppire_data_editor_var_delete_variables (de);
1198 insert_variable (PsppireDataWindow *dw)
1200 PsppireDataEditor *de = dw->data_editor;
1201 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
1203 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1205 JmdRange *range = JMD_SHEET(de->data_sheet)->selection;
1206 psppire_data_editor_insert_new_variable_at_posn (de, range->start_x);
1210 JmdRange *range = JMD_SHEET(de->var_sheet)->selection;
1211 psppire_data_editor_insert_new_variable_at_posn (de, range->start_y);
1218 insert_case_at_row (PsppireDataWindow *dw)
1220 PsppireDataEditor *de = dw->data_editor;
1221 JmdRange *range = JMD_SHEET(de->data_sheet)->selection;
1222 psppire_data_editor_insert_new_case_at_posn (de, range->start_y);
1227 goto_case (PsppireDataWindow *dw)
1229 PsppireDataEditor *de = dw->data_editor;
1230 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
1231 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1233 goto_case_dialog (JMD_SHEET (de->data_sheet));
1239 create_file_menu (PsppireDataWindow *dw)
1241 GtkWidget *menuitem = gtk_menu_item_new_with_mnemonic (_("_File"));
1242 GtkWidget *menu = gtk_menu_new ();
1245 GtkWidget *new = gtk_menu_item_new_with_mnemonic (_("_New"));
1246 gtk_menu_attach (GTK_MENU (menu), new, 0, 1, 0, 1);
1248 GtkWidget *new_menu = gtk_menu_new ();
1250 g_object_set (new, "submenu", new_menu, NULL);
1252 GtkWidget *syntax = gtk_menu_item_new_with_mnemonic (_("_Syntax"));
1253 connect_action_to_menuitem (G_ACTION_MAP (g_application_get_default ()), "new-syntax", syntax, 0);
1255 GtkWidget *data = gtk_menu_item_new_with_mnemonic (_("_Data"));
1256 connect_action_to_menuitem (G_ACTION_MAP (g_application_get_default ()), "new-data", data, 0);
1258 gtk_menu_attach (GTK_MENU (new_menu), syntax, 0, 1, 0, 1);
1259 gtk_menu_attach (GTK_MENU (new_menu), data, 0, 1, 1, 2);
1262 GtkWidget *open = gtk_menu_item_new_with_mnemonic (_("_Open"));
1263 connect_action_to_menuitem (G_ACTION_MAP (dw), "open", open, "<Ctrl>O");
1265 GtkWidget *import = gtk_menu_item_new_with_mnemonic (_("_Import Data..."));
1266 connect_action_to_menuitem (G_ACTION_MAP (dw), "file-import", import, 0);
1268 gtk_menu_attach (GTK_MENU (menu), open, 0, 1, 1, 2);
1269 gtk_menu_attach (GTK_MENU (menu), import, 0, 1, 2, 3);
1271 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 3, 4);
1273 GtkWidget *save = gtk_menu_item_new_with_mnemonic (_("_Save..."));
1274 connect_action_to_menuitem (G_ACTION_MAP (dw), "save", save, "<Ctrl>S");
1276 GtkWidget *save_as = gtk_menu_item_new_with_mnemonic (_("Save _As..."));
1277 connect_action_to_menuitem (G_ACTION_MAP (dw), "save-as", save_as, "<Shift><Ctrl>S");
1279 GtkWidget *rename_dataset = gtk_menu_item_new_with_mnemonic (_("_Rename Dataset..."));
1280 connect_action_to_menuitem (G_ACTION_MAP (dw), "rename-dataset", rename_dataset, 0);
1283 gtk_menu_attach (GTK_MENU (menu), save, 0, 1, 4, 5);
1284 gtk_menu_attach (GTK_MENU (menu), save_as, 0, 1, 5, 6);
1285 gtk_menu_attach (GTK_MENU (menu), rename_dataset, 0, 1, 6, 7);
1287 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 7, 8);
1290 GtkWidget *display_data = gtk_menu_item_new_with_mnemonic (_("_Display Data File Information"));
1291 gtk_menu_attach (GTK_MENU (menu), display_data, 0, 1, 8, 9);
1293 GtkWidget *dd_menu = gtk_menu_new ();
1295 g_object_set (display_data, "submenu", dd_menu, NULL);
1297 GtkWidget *working_file = gtk_menu_item_new_with_mnemonic (_("Working File"));
1298 connect_action_to_menuitem (G_ACTION_MAP (dw), "info-working", working_file, 0);
1299 GtkWidget *external_file = gtk_menu_item_new_with_mnemonic (_("_External File..."));
1300 connect_action_to_menuitem (G_ACTION_MAP (dw), "info-external", external_file, 0);
1302 gtk_menu_attach (GTK_MENU (dd_menu), working_file, 0, 1, 0, 1);
1303 gtk_menu_attach (GTK_MENU (dd_menu), external_file, 0, 1, 1, 2);
1306 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 9, 10);
1309 GtkWidget *mi_data = gtk_menu_item_new_with_mnemonic (_("_Recently Used Data"));
1310 GtkWidget *mi_files = gtk_menu_item_new_with_mnemonic (_("Recently Used _Files"));
1312 GtkWidget *menu_data = gtk_recent_chooser_menu_new_for_manager (
1313 gtk_recent_manager_get_default ());
1315 GtkWidget *menu_files = gtk_recent_chooser_menu_new_for_manager (
1316 gtk_recent_manager_get_default ());
1318 gtk_menu_attach (GTK_MENU (menu), mi_data, 0, 1, 10, 11);
1319 gtk_menu_attach (GTK_MENU (menu), mi_files, 0, 1, 11, 12);
1321 g_object_set (menu_data, "show-tips", TRUE, NULL);
1322 g_object_set (menu_files, "show-tips", TRUE, NULL);
1324 g_object_set (mi_data, "submenu", menu_data, NULL);
1325 g_object_set (mi_files, "submenu", menu_files, NULL);
1328 GtkRecentFilter *filter = gtk_recent_filter_new ();
1330 gtk_recent_filter_add_mime_type (filter, "application/x-spss-sav");
1331 gtk_recent_filter_add_mime_type (filter, "application/x-spss-por");
1333 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_data), GTK_RECENT_SORT_MRU);
1335 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_data), filter);
1338 g_signal_connect (menu_data, "selection-done", G_CALLBACK (on_recent_data_select), dw);
1341 GtkRecentFilter *filter = gtk_recent_filter_new ();
1343 gtk_recent_filter_add_pattern (filter, "*.sps");
1344 gtk_recent_filter_add_pattern (filter, "*.SPS");
1346 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_files), GTK_RECENT_SORT_MRU);
1348 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_files), filter);
1351 g_signal_connect (menu_files, "selection-done", G_CALLBACK (on_recent_files_select), dw);
1354 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 12, 13);
1357 GtkWidget *quit = gtk_menu_item_new_with_mnemonic (_("_Quit"));
1358 gtk_menu_attach (GTK_MENU (menu), quit, 0, 1, 13, 14);
1360 connect_action_to_menuitem (G_ACTION_MAP (g_application_get_default ()),
1361 "quit", quit, "<Ctrl>Q");
1364 g_object_set (menuitem, "submenu", menu, NULL);
1365 gtk_widget_show_all (menuitem);
1372 create_edit_menu (PsppireDataWindow *dw)
1375 GtkWidget *menuitem = gtk_menu_item_new_with_mnemonic (_("_Edit"));
1377 GtkWidget *menu = gtk_menu_new ();
1379 dw->mi_insert_var = gtk_menu_item_new_with_mnemonic (_("_Insert Variable"));
1380 dw->mi_insert_case = gtk_menu_item_new_with_mnemonic (_("_Insert Case"));
1381 GtkWidget *go_to_variable = gtk_menu_item_new_with_mnemonic (_("_Go To Variable..."));
1382 dw->mi_go_to_case = gtk_menu_item_new_with_mnemonic (_("_Go To Case..."));
1384 gtk_menu_attach (GTK_MENU (menu), dw->mi_insert_var, 0, 1, i, i + 1); ++i;
1385 gtk_menu_attach (GTK_MENU (menu), dw->mi_insert_case, 0, 1, i, i + 1); ++i;
1387 g_signal_connect_swapped (dw->mi_insert_case, "activate", G_CALLBACK (insert_case_at_row), dw);
1388 g_signal_connect_swapped (dw->mi_go_to_case, "activate", G_CALLBACK (goto_case), dw);
1389 g_signal_connect_swapped (dw->mi_insert_var, "activate", G_CALLBACK (insert_variable), dw);
1391 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (dw), "PsppireDialogActionVarInfo");
1393 g_signal_connect_swapped (go_to_variable, "activate", G_CALLBACK (psppire_dialog_action_activate_null), a);
1395 gtk_menu_attach (GTK_MENU (menu), go_to_variable, 0, 1, i, i + 1); ++i;
1396 gtk_menu_attach (GTK_MENU (menu), dw->mi_go_to_case, 0, 1, i, i + 1); ++i;
1399 GtkAccelGroup *ag = gtk_accel_group_new ();
1401 dw->mi_edit_separator = gtk_separator_menu_item_new ();
1402 gtk_menu_attach (GTK_MENU (menu), dw->mi_edit_separator, 0, 1, i, i + 1); ++i;
1404 dw->mi_cut = gtk_menu_item_new_with_mnemonic (_("Cu_t"));
1405 gtk_menu_attach (GTK_MENU (menu), dw->mi_cut, 0, 1, i, i + 1); ++i;
1406 g_signal_connect_swapped (dw->mi_cut, "activate", G_CALLBACK (on_cut), dw);
1408 gtk_window_add_accel_group (GTK_WINDOW (dw), ag);
1409 gtk_widget_add_accelerator (dw->mi_cut, "activate", ag,
1410 'X', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1412 dw->mi_copy = gtk_menu_item_new_with_mnemonic (_("_Copy"));
1413 gtk_menu_attach (GTK_MENU (menu), dw->mi_copy, 0, 1, i, i + 1); ++i;
1414 g_signal_connect_swapped (dw->mi_copy, "activate", G_CALLBACK (on_copy), dw);
1415 gtk_widget_add_accelerator (dw->mi_copy, "activate", ag,
1416 'C', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1418 dw->mi_paste = gtk_menu_item_new_with_mnemonic (_("_Paste"));
1419 gtk_menu_attach (GTK_MENU (menu), dw->mi_paste, 0, 1, i, i + 1); ++i;
1420 g_signal_connect_swapped (dw->mi_paste, "activate", G_CALLBACK (on_paste), dw);
1421 gtk_widget_add_accelerator (dw->mi_paste, "activate", ag,
1422 'V', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
1424 dw->mi_clear_variables = gtk_menu_item_new_with_mnemonic (_("Clear _Variables"));
1425 gtk_menu_attach (GTK_MENU (menu), dw->mi_clear_variables, 0, 1, i, i + 1); ++i;
1426 g_signal_connect_swapped (dw->mi_clear_variables, "activate", G_CALLBACK (on_clear_variables), dw);
1428 dw->mi_clear_cases = gtk_menu_item_new_with_mnemonic (_("Cl_ear Cases"));
1429 gtk_menu_attach (GTK_MENU (menu), dw->mi_clear_cases, 0, 1, i, i + 1); ++i;
1430 g_signal_connect_swapped (dw->mi_clear_cases, "activate", G_CALLBACK (on_clear_cases), dw);
1434 dw->mi_find_separator = gtk_separator_menu_item_new ();
1435 gtk_menu_attach (GTK_MENU (menu), dw->mi_find_separator, 0, 1, i, i + 1); ++i;
1437 dw->mi_find = gtk_menu_item_new_with_mnemonic (_("_Find..."));
1438 g_signal_connect_swapped (dw->mi_find, "activate", G_CALLBACK (find_dialog), dw);
1439 gtk_menu_attach (GTK_MENU (menu), dw->mi_find, 0, 1, i, i + 1); ++i;
1443 dw->mi_options = gtk_menu_item_new_with_mnemonic (_("_Options..."));
1444 g_signal_connect_swapped (dw->mi_options, "activate",
1445 G_CALLBACK (options_dialog), dw);
1446 gtk_menu_attach (GTK_MENU (menu), dw->mi_options, 0, 1, i, i + 1); ++i;
1449 g_object_set (menuitem, "submenu", menu, NULL);
1451 gtk_widget_show_all (menuitem);
1457 psppire_data_window_finish_init (PsppireDataWindow *de,
1460 static const struct dataset_callbacks cbs =
1462 set_unsaved, /* changed */
1463 transformation_change_callback, /* transformations_changed */
1470 GtkWidget *box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1473 de->dict = psppire_dict_new_from_dict (dataset_dict (ds));
1474 de->data_store = psppire_data_store_new (de->dict);
1475 psppire_data_store_set_reader (de->data_store, NULL);
1477 GObject *menu = get_object_assert (de->builder, "data-editor-menu", G_TYPE_MENU);
1478 menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (menu));
1479 gtk_widget_show (menubar);
1481 hb = gtk_toolbar_new ();
1482 sb = get_widget_assert (de->builder, "status-bar");
1485 PSPPIRE_DATA_EDITOR (psppire_data_editor_new (de->dict, de->data_store));
1487 g_signal_connect (de, "realize",
1488 G_CALLBACK (set_data_page), de);
1490 g_signal_connect_swapped (de->data_store, "case-changed",
1491 G_CALLBACK (set_unsaved), de);
1493 dataset_set_callbacks (de->dataset, &cbs, de);
1495 connect_help (de->builder);
1497 gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
1498 gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
1499 gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
1500 gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
1502 gtk_container_add (GTK_CONTAINER (de), box);
1504 g_signal_connect (de->dict, "weight-changed",
1505 G_CALLBACK (on_weight_change),
1508 g_signal_connect (de->dict, "filter-changed",
1509 G_CALLBACK (on_filter_change),
1512 g_signal_connect (de->dict, "split-changed",
1513 G_CALLBACK (on_split_change),
1516 g_signal_connect_swapped (de->dict, "items-changed",
1517 G_CALLBACK (enable_save), de);
1518 g_signal_connect_swapped (de->dict, "variable-inserted",
1519 G_CALLBACK (enable_save), de);
1520 g_signal_connect_swapped (de->dict, "variable-deleted",
1521 G_CALLBACK (enable_save), de);
1524 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SORT, de);
1525 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SPLIT, de);
1526 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_FLIP, de);
1527 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_AGGREGATE, de);
1528 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_WEIGHT, de);
1530 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_COMPUTE, de);
1531 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_COUNT, de);
1532 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_AUTORECODE, de);
1533 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RANK, de);
1534 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SELECT, de);
1535 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RECODE_SAME, de);
1536 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RECODE_DIFFERENT, de);
1539 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_DESCRIPTIVES, de);
1540 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES, de);
1541 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_EXAMINE, de);
1542 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS, de);
1544 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_INDEP_SAMPS, de);
1545 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_PAIRED, de);
1547 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_MEANS, de);
1548 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_TT1S, de);
1550 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_ONEWAY, de);
1551 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_UNIVARIATE, de);
1552 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_KMEANS, de);
1553 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_FACTOR, de);
1554 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_CORRELATION, de);
1555 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RELIABILITY, de);
1556 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_REGRESSION, de);
1557 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_LOGISTIC, de);
1558 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_ROC, de);
1560 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_COMMENTS, de);
1561 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_VAR_INFO, de);
1563 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_BARCHART, de);
1564 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT, de);
1565 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM, de);
1567 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_CHISQUARE, de);
1568 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL, de);
1569 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RUNS, de);
1570 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_1SKS, de);
1571 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_TWO_SAMPLE, de);
1572 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_K_RELATED, de);
1575 GSimpleAction *file_import_action = g_simple_action_new ("file-import", NULL);
1576 g_signal_connect_swapped (file_import_action, "activate", G_CALLBACK (file_import), de);
1577 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (file_import_action));
1581 GSimpleAction *save = g_simple_action_new ("save", NULL);
1582 g_signal_connect_swapped (save, "activate", G_CALLBACK (psppire_window_save), de);
1583 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (save));
1587 GSimpleAction *open = g_simple_action_new ("open", NULL);
1588 g_signal_connect_swapped (open, "activate", G_CALLBACK (psppire_window_open), de);
1589 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (open));
1593 GSimpleAction *save_as = g_simple_action_new ("save-as", NULL);
1594 g_signal_connect_swapped (save_as, "activate", G_CALLBACK (psppire_window_save_as), de);
1595 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (save_as));
1599 GSimpleAction *rename_dataset_act = g_simple_action_new ("rename-dataset", NULL);
1600 g_signal_connect_swapped (rename_dataset_act, "activate",
1601 G_CALLBACK (on_rename_dataset), de);
1602 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (rename_dataset_act));
1606 GSimpleAction *info_working = g_simple_action_new ("info-working", NULL);
1607 g_signal_connect_swapped (info_working, "activate", G_CALLBACK (display_dict), de);
1608 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (info_working));
1611 GSimpleAction *info_external = g_simple_action_new ("info-external", NULL);
1612 g_signal_connect_swapped (info_external, "activate", G_CALLBACK (sysfile_info), de);
1613 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (info_external));
1617 GSimpleAction *act_statusbar = g_simple_action_new_stateful ("statusbar", NULL, g_variant_new_boolean (TRUE));
1618 g_signal_connect (act_statusbar, "activate", G_CALLBACK (status_bar_activate), de);
1619 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_statusbar));
1623 GSimpleAction *act_gridlines = g_simple_action_new_stateful ("gridlines", NULL, g_variant_new_boolean (TRUE));
1624 g_signal_connect (act_gridlines, "activate", G_CALLBACK (grid_lines_activate), de);
1625 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_gridlines));
1630 GSimpleAction *act_view_data = g_simple_action_new_stateful ("view_dv", G_VARIANT_TYPE_STRING,
1631 g_variant_new_string ("DATA"));
1632 g_signal_connect (act_view_data, "activate", G_CALLBACK (activate_change_view), de);
1633 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_view_data));
1637 GSimpleAction *act_fonts = g_simple_action_new ("fonts", NULL);
1638 g_signal_connect_swapped (act_fonts, "activate", G_CALLBACK (fonts_activate), de);
1639 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_fonts));
1643 GSimpleAction *act_value_labels =
1644 g_simple_action_new_stateful ("value_labels", NULL,
1645 g_variant_new_boolean (FALSE));
1646 g_signal_connect (act_value_labels, "activate", G_CALLBACK (value_labels_activate), de);
1647 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_value_labels));
1651 GSimpleAction *act_transform_pending = g_simple_action_new ("transform-pending", NULL);
1652 g_signal_connect_swapped (act_transform_pending, "activate", G_CALLBACK (execute), de);
1653 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_transform_pending));
1657 GSimpleAction *act_jump_to_variable = g_simple_action_new ("jump-to-variable", NULL);
1658 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_jump_to_variable));
1662 GSimpleAction *act_insert_variable = g_simple_action_new ("insert-variable", NULL);
1663 g_signal_connect_swapped (act_insert_variable, "activate", G_CALLBACK (insert_variable), de);
1664 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_insert_variable));
1668 GSimpleAction *act_jump_to_case = g_simple_action_new ("jump-to-case", NULL);
1669 g_signal_connect_swapped (act_jump_to_case, "activate", G_CALLBACK (goto_case), de);
1670 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_jump_to_case));
1674 GSimpleAction *act_insert_case = g_simple_action_new ("insert-case", NULL);
1675 g_signal_connect_swapped (act_insert_case, "activate", G_CALLBACK (insert_case_at_row), de);
1676 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_insert_case));
1680 GSimpleAction *find = g_simple_action_new ("find", NULL);
1681 g_signal_connect_swapped (find, "activate", G_CALLBACK (find_dialog), de);
1682 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (find));
1688 GtkToolItem *ti = gtk_tool_button_new (NULL, "Open");
1689 g_signal_connect_swapped (ti, "clicked", G_CALLBACK (psppire_window_open), de);
1690 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1691 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "file-open-data");
1695 GtkToolItem *ti = gtk_tool_button_new (NULL, "Save");
1696 g_signal_connect_swapped (ti, "clicked", G_CALLBACK (psppire_window_save), de);
1697 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1698 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "file-save-data");
1701 gtk_toolbar_insert (GTK_TOOLBAR (hb), gtk_separator_tool_item_new (), idx++);
1704 de->ti_jump_to_variable = gtk_tool_button_new (NULL, "Goto Var");
1706 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "PsppireDialogActionVarInfo");
1708 g_signal_connect_swapped (de->ti_jump_to_variable, "clicked",
1709 G_CALLBACK (psppire_dialog_action_activate_null), a);
1711 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_jump_to_variable, idx++);
1712 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_variable), "edit-go-to-variable");
1713 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_jump_to_variable), _("Jump to variable"));
1717 de->ti_jump_to_case = gtk_tool_button_new (NULL, "Jump to Case");
1719 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "jump-to-case");
1721 g_signal_connect_swapped (de->ti_jump_to_case, "clicked",
1722 G_CALLBACK (g_action_activate_null), a);
1724 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_jump_to_case, idx++);
1725 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_case), "edit-go-to-case");
1726 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_jump_to_case), _("Jump to a case in the data sheet"));
1730 de->ti_find = gtk_tool_button_new (NULL, "Find");
1732 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "find");
1734 g_signal_connect_swapped (de->ti_find, "clicked",
1735 G_CALLBACK (g_action_activate_null), a);
1738 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_find, idx++);
1739 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_find), "edit-find");
1740 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_find), _("Search for values in the data"));
1744 de->ti_insert_case = gtk_tool_button_new (NULL, "Create Case");
1745 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "insert-case");
1747 g_signal_connect_swapped (de->ti_insert_case, "clicked",
1748 G_CALLBACK (g_action_activate_null), a);
1750 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_insert_case, idx++);
1751 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_case), "edit-insert-case");
1752 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_insert_case), _("Create a new case at the current position"));
1756 de->ti_insert_variable = gtk_tool_button_new (NULL, "Create Variable");
1757 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "insert-variable");
1759 g_signal_connect_swapped (de->ti_insert_variable, "clicked",
1760 G_CALLBACK (g_action_activate_null), a);
1762 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_insert_variable, idx++);
1763 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_variable), "edit-insert-variable");
1764 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_insert_variable), _("Create a new variable at the current position"));
1767 gtk_toolbar_insert (GTK_TOOLBAR (hb), gtk_separator_tool_item_new (), idx++);
1770 GtkToolItem *ti = gtk_tool_button_new (NULL, "Split");
1771 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de),
1772 "PsppireDialogActionSplit");
1774 g_signal_connect_swapped (ti, "clicked",
1775 G_CALLBACK (psppire_dialog_action_activate_null), a);
1776 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1777 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "data-split-file");
1778 gtk_widget_set_tooltip_text (GTK_WIDGET (ti), _("Split the active dataset"));
1782 GtkToolItem *ti = gtk_tool_button_new (NULL, "Weight");
1783 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de),
1784 "PsppireDialogActionWeight");
1786 g_signal_connect_swapped (ti, "clicked",
1787 G_CALLBACK (psppire_dialog_action_activate_null), a);
1788 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1789 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "data-weight-cases");
1790 gtk_widget_set_tooltip_text (GTK_WIDGET (ti), _("Weight cases by variable"));
1794 de->ti_value_labels_button = gtk_toggle_tool_button_new ();
1795 gtk_tool_button_set_label (GTK_TOOL_BUTTON (de->ti_value_labels_button),
1797 g_signal_connect (de->ti_value_labels_button, "toggled",
1798 G_CALLBACK (on_labels_button_toggle), de);
1799 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_value_labels_button, idx++);
1800 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_value_labels_button), "view-value-labels");
1801 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_value_labels_button), _("Show/hide value labels"));
1806 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
1807 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
1809 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), create_file_menu (de), 0);
1810 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), create_edit_menu (de), 1);
1811 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), create_windows_menu (GTK_WINDOW (de)));
1812 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), create_help_menu (GTK_WINDOW (de)));
1814 g_signal_connect (de->data_editor, "switch-page",
1815 G_CALLBACK (on_switch_page), de);
1817 gtk_widget_show (GTK_WIDGET (de->data_editor));
1818 gtk_widget_show_all (box);
1820 ll_push_head (&all_data_windows, &de->ll);
1825 psppire_data_window_dispose (GObject *object)
1827 PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
1829 if (dw->builder != NULL)
1831 g_object_unref (dw->builder);
1837 g_signal_handlers_disconnect_by_func (dw->dict,
1838 G_CALLBACK (enable_save), dw);
1839 g_signal_handlers_disconnect_by_func (dw->dict,
1840 G_CALLBACK (on_weight_change), dw);
1841 g_signal_handlers_disconnect_by_func (dw->dict,
1842 G_CALLBACK (on_filter_change), dw);
1843 g_signal_handlers_disconnect_by_func (dw->dict,
1844 G_CALLBACK (on_split_change), dw);
1846 g_object_unref (dw->dict);
1852 g_object_unref (dw->data_store);
1853 dw->data_store = NULL;
1856 if (dw->ll.next != NULL)
1858 ll_remove (&dw->ll);
1862 if (G_OBJECT_CLASS (parent_class)->dispose)
1863 G_OBJECT_CLASS (parent_class)->dispose (object);
1867 psppire_data_window_finalize (GObject *object)
1869 PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
1873 struct dataset *dataset = dw->dataset;
1874 struct session *session = dataset_session (dataset);
1878 dataset_set_callbacks (dataset, NULL, NULL);
1879 session_set_active_dataset (session, NULL);
1880 dataset_destroy (dataset);
1883 if (G_OBJECT_CLASS (parent_class)->finalize)
1884 G_OBJECT_CLASS (parent_class)->finalize (object);
1888 psppire_data_window_set_property (GObject *object,
1890 const GValue *value,
1893 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1898 psppire_data_window_finish_init (window, g_value_get_pointer (value));
1901 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1907 psppire_data_window_get_property (GObject *object,
1912 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1917 g_value_set_pointer (value, window->dataset);
1920 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1928 psppire_data_window_new (struct dataset *ds)
1932 if (the_session == NULL)
1933 the_session = session_create (NULL);
1937 char *dataset_name = session_generate_dataset_name (the_session);
1938 ds = dataset_create (the_session, dataset_name);
1939 free (dataset_name);
1941 assert (dataset_session (ds) == the_session);
1945 psppire_data_window_get_type (),
1946 "description", _("Data Editor"),
1950 if (dataset_name (ds) != NULL)
1951 g_object_set (dw, "id", dataset_name (ds), (void *) NULL);
1954 GApplication *app = g_application_get_default ();
1955 gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (dw));
1963 psppire_data_window_is_empty (PsppireDataWindow *dw)
1965 return psppire_dict_get_var_cnt (dw->dict) == 0;
1970 psppire_data_window_iface_init (PsppireWindowIface *iface)
1972 iface->save = save_file;
1973 iface->pick_filename = data_pick_filename;
1974 iface->load = load_file;
1981 psppire_default_data_window (void)
1983 if (ll_is_empty (&all_data_windows))
1984 create_data_window ();
1985 return ll_data (ll_head (&all_data_windows), PsppireDataWindow, ll);
1991 psppire_data_window_set_default (PsppireDataWindow *pdw)
1993 ll_remove (&pdw->ll);
1994 ll_push_head (&all_data_windows, &pdw->ll);
1998 psppire_data_window_undefault (PsppireDataWindow *pdw)
2000 ll_remove (&pdw->ll);
2001 ll_push_tail (&all_data_windows, &pdw->ll);
2007 psppire_data_window_for_dataset (struct dataset *ds)
2009 PsppireDataWindow *pdw;
2011 ll_for_each (pdw, PsppireDataWindow, ll, &all_data_windows)
2012 if (pdw->dataset == ds)
2019 psppire_data_window_for_data_store (PsppireDataStore *data_store)
2021 PsppireDataWindow *pdw;
2023 ll_for_each (pdw, PsppireDataWindow, ll, &all_data_windows)
2024 if (pdw->data_store == data_store)
2031 create_data_window (void)
2033 GtkWidget *w = psppire_data_window_new (NULL);
2035 gtk_widget_show (w);
2037 return GTK_WINDOW (w);
2041 open_data_window (PsppireWindow *victim, const char *file_name,
2042 const char *encoding, gpointer hint)
2046 if (PSPPIRE_IS_DATA_WINDOW (victim)
2047 && psppire_data_window_is_empty (PSPPIRE_DATA_WINDOW (victim)))
2049 window = GTK_WIDGET (victim);
2050 gtk_widget_hide (GTK_WIDGET (PSPPIRE_DATA_WINDOW (window)->data_editor));
2053 window = psppire_data_window_new (NULL);
2055 psppire_window_load (PSPPIRE_WINDOW (window), file_name, encoding, hint);
2056 gtk_widget_show_all (window);
2057 return GTK_WINDOW (window);