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 <ssw-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-independent.h"
73 #include "psppire-dialog-action-k-related.h"
74 #include "psppire-dialog-action-kmeans.h"
75 #include "psppire-dialog-action-logistic.h"
76 #include "psppire-dialog-action-means.h"
77 #include "psppire-dialog-action-oneway.h"
78 #include "psppire-dialog-action-paired.h"
79 #include "psppire-dialog-action-rank.h"
80 #include "psppire-dialog-action-recode-same.h"
81 #include "psppire-dialog-action-recode-different.h"
82 #include "psppire-dialog-action-regression.h"
83 #include "psppire-dialog-action-reliability.h"
84 #include "psppire-dialog-action-roc.h"
85 #include "psppire-dialog-action-runs.h"
86 #include "psppire-dialog-action-scatterplot.h"
87 #include "psppire-dialog-action-select.h"
88 #include "psppire-dialog-action-sort.h"
89 #include "psppire-dialog-action-split.h"
90 #include "psppire-dialog-action-tt1s.h"
91 #include "psppire-dialog-action-two-sample.h"
92 #include "psppire-dialog-action-univariate.h"
93 #include "psppire-dialog-action-var-info.h"
94 #include "psppire-dialog-action-weight.h"
98 #define _(msgid) gettext (msgid)
99 #define N_(msgid) msgid
101 struct session *the_session;
102 struct ll_list all_data_windows = LL_INITIALIZER (all_data_windows);
104 static void psppire_data_window_class_init (PsppireDataWindowClass *class);
105 static void psppire_data_window_init (PsppireDataWindow *data_editor);
108 static void psppire_data_window_iface_init (PsppireWindowIface *iface);
110 static void psppire_data_window_dispose (GObject *object);
111 static void psppire_data_window_finalize (GObject *object);
112 static void psppire_data_window_set_property (GObject *object,
116 static void psppire_data_window_get_property (GObject *object,
122 psppire_data_window_get_type (void)
124 static GType psppire_data_window_type = 0;
126 if (!psppire_data_window_type)
128 static const GTypeInfo psppire_data_window_info =
130 sizeof (PsppireDataWindowClass),
133 (GClassInitFunc)psppire_data_window_class_init,
134 (GClassFinalizeFunc) NULL,
136 sizeof (PsppireDataWindow),
138 (GInstanceInitFunc) psppire_data_window_init,
141 static const GInterfaceInfo window_interface_info =
143 (GInterfaceInitFunc) psppire_data_window_iface_init,
148 psppire_data_window_type =
149 g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireDataWindow",
150 &psppire_data_window_info, 0);
153 g_type_add_interface_static (psppire_data_window_type,
154 PSPPIRE_TYPE_WINDOW_MODEL,
155 &window_interface_info);
158 return psppire_data_window_type;
161 static GObjectClass *parent_class ;
168 psppire_data_window_class_init (PsppireDataWindowClass *class)
170 GObjectClass *object_class = G_OBJECT_CLASS (class);
172 parent_class = g_type_class_peek_parent (class);
174 object_class->dispose = psppire_data_window_dispose;
175 object_class->finalize = psppire_data_window_finalize;
176 object_class->set_property = psppire_data_window_set_property;
177 object_class->get_property = psppire_data_window_get_property;
179 g_object_class_install_property (
180 object_class, PROP_DATASET,
181 g_param_spec_pointer ("dataset", "Dataset",
182 "'struct datset *' represented by the window",
183 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
188 /* Run the EXECUTE command. */
190 execute (PsppireDataWindow *dw)
192 execute_const_syntax_string (dw, "EXECUTE.");
196 transformation_change_callback (bool transformations_pending,
199 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
201 GtkWidget *status_label =
202 get_widget_assert (de->builder, "case-counter-area");
205 GAction *action = g_action_map_lookup_action (G_ACTION_MAP (de),
206 "transform-pending");
208 g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
209 transformations_pending);
212 if (transformations_pending)
213 gtk_label_set_text (GTK_LABEL (status_label),
214 _("Transformations Pending"));
216 gtk_label_set_text (GTK_LABEL (status_label), "");
219 /* Callback for when the dictionary changes its filter variable */
221 on_filter_change (GObject *o, gint filter_index, gpointer data)
223 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
225 GtkWidget *filter_status_area =
226 get_widget_assert (de->builder, "filter-use-status-area");
228 if (filter_index == -1)
230 gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
234 PsppireDict *dict = NULL;
235 struct variable *var ;
238 g_object_get (de->data_editor, "dictionary", &dict, NULL);
240 var = psppire_dict_get_variable (dict, filter_index);
242 text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
244 gtk_label_set_text (GTK_LABEL (filter_status_area), text);
250 /* Callback for when the dictionary changes its split variables */
252 on_split_change (PsppireDict *dict, gpointer data)
254 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
256 size_t n_split_vars = dict_get_split_cnt (dict->dict);
258 GtkWidget *split_status_area =
259 get_widget_assert (de->builder, "split-file-status-area");
261 if (n_split_vars == 0)
263 gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
269 const struct variable *const * split_vars =
270 dict_get_split_vars (dict->dict);
272 text = g_string_new (_("Split by "));
274 for (i = 0 ; i < n_split_vars - 1; ++i)
276 g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
278 g_string_append (text, var_get_name (split_vars[i]));
280 gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
282 g_string_free (text, TRUE);
289 /* Callback for when the dictionary changes its weights */
291 on_weight_change (GObject *o, gint weight_index, gpointer data)
293 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
295 GtkWidget *weight_status_area =
296 get_widget_assert (de->builder, "weight-status-area");
298 if (weight_index == -1)
300 gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
304 struct variable *var ;
305 PsppireDict *dict = NULL;
308 g_object_get (de->data_editor, "dictionary", &dict, NULL);
310 var = psppire_dict_get_variable (dict, weight_index);
312 text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
314 gtk_label_set_text (GTK_LABEL (weight_status_area), text);
322 dump_rm (GtkRecentManager *rm)
324 GList *items = gtk_recent_manager_get_items (rm);
328 g_print ("Recent Items:\n");
329 for (i = items; i; i = i->next)
331 GtkRecentInfo *ri = i->data;
333 g_print ("Item: %s (Mime: %s) (Desc: %s) (URI: %s)\n",
334 gtk_recent_info_get_short_name (ri),
335 gtk_recent_info_get_mime_type (ri),
336 gtk_recent_info_get_description (ri),
337 gtk_recent_info_get_uri (ri)
341 gtk_recent_info_unref (ri);
349 has_suffix (const gchar *name, const gchar *suffix)
351 size_t name_len = strlen (name);
352 size_t suffix_len = strlen (suffix);
353 return (name_len > suffix_len
354 && !c_strcasecmp (&name[name_len - suffix_len], suffix));
358 name_has_por_suffix (const gchar *name)
360 return has_suffix (name, ".por");
364 name_has_sav_suffix (const gchar *name)
366 return has_suffix (name, ".sav") || has_suffix (name, ".zsav");
369 /* Returns true if NAME has a suffix which might denote a PSPP file */
371 name_has_suffix (const gchar *name)
373 return name_has_por_suffix (name) || name_has_sav_suffix (name);
377 load_file (PsppireWindow *de, const gchar *file_name, const char *encoding,
380 const char *mime_type = NULL;
381 gchar *syntax = NULL;
386 gchar *utf8_file_name;
387 struct string filename;
389 utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL, NULL);
391 if (NULL == utf8_file_name)
394 ds_init_empty (&filename);
395 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
397 g_free (utf8_file_name);
399 if (encoding && encoding[0])
400 syntax = g_strdup_printf ("GET FILE=%s ENCODING='%s'.",
401 ds_cstr (&filename), encoding);
403 syntax = g_strdup_printf ("GET FILE=%s.", ds_cstr (&filename));
404 ds_destroy (&filename);
411 ok = execute_syntax (PSPPIRE_DATA_WINDOW (de),
412 lex_reader_for_string (syntax, "UTF-8"));
415 if (ok && syn == NULL)
417 if (name_has_por_suffix (file_name))
418 mime_type = "application/x-spss-por";
419 else if (name_has_sav_suffix (file_name))
420 mime_type = "application/x-spss-sav";
422 add_most_recent (file_name, mime_type, encoding);
429 psppire_data_window_format_to_string (enum PsppireDataWindowFormat format)
431 if (format == PSPPIRE_DATA_WINDOW_SAV)
433 else if (format == PSPPIRE_DATA_WINDOW_ZSAV)
439 /* Save DE to file */
441 save_file (PsppireWindow *w)
443 const gchar *file_name = NULL;
444 gchar *utf8_file_name = NULL;
446 struct string filename ;
447 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (w);
450 file_name = psppire_window_get_filename (w);
452 fnx = g_string_new (file_name);
454 if (! name_has_suffix (fnx->str))
455 g_string_append (fnx, psppire_data_window_format_to_string (de->format));
457 ds_init_empty (&filename);
459 utf8_file_name = g_filename_to_utf8 (fnx->str, -1, NULL, NULL, NULL);
461 g_string_free (fnx, TRUE);
463 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
464 g_free (utf8_file_name);
466 if (de->format == PSPPIRE_DATA_WINDOW_SAV)
467 syntax = g_strdup_printf ("SAVE OUTFILE=%s.", ds_cstr (&filename));
468 else if (de->format == PSPPIRE_DATA_WINDOW_ZSAV)
469 syntax = g_strdup_printf ("SAVE /ZCOMPRESSED /OUTFILE=%s.",
470 ds_cstr (&filename));
472 syntax = g_strdup_printf ("EXPORT OUTFILE=%s.", ds_cstr (&filename));
474 ds_destroy (&filename);
476 g_free (execute_syntax_string (de, syntax));
481 display_dict (PsppireDataWindow *de)
483 execute_const_syntax_string (de, "DISPLAY DICTIONARY.");
487 sysfile_info (PsppireDataWindow *de)
489 GtkWidget *dialog = psppire_window_file_chooser_dialog (PSPPIRE_WINDOW (de));
491 if (GTK_RESPONSE_ACCEPT == gtk_dialog_run (GTK_DIALOG (dialog)))
493 struct string filename;
495 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
496 gchar *utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL,
499 const gchar *encoding = psppire_encoding_selector_get_encoding (
500 gtk_file_chooser_get_extra_widget (GTK_FILE_CHOOSER (dialog)));
504 ds_init_empty (&filename);
506 syntax_gen_string (&filename, ss_cstr (utf8_file_name));
508 g_free (utf8_file_name);
511 syntax = g_strdup_printf ("SYSFILE INFO %s ENCODING='%s'.",
512 ds_cstr (&filename), encoding);
514 syntax = g_strdup_printf ("SYSFILE INFO %s.", ds_cstr (&filename));
515 g_free (execute_syntax_string (de, syntax));
518 gtk_widget_destroy (dialog);
522 /* PsppireWindow 'pick_filename' callback: prompt for a filename to save as. */
524 data_pick_filename (PsppireWindow *window)
526 GtkListStore *list_store;
527 GtkWidget *combo_box;
529 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (window);
530 GtkFileFilter *filter;
532 gtk_file_chooser_dialog_new (_("Save"),
534 GTK_FILE_CHOOSER_ACTION_SAVE,
535 _("Cancel"), GTK_RESPONSE_CANCEL,
536 _("Save"), GTK_RESPONSE_ACCEPT,
539 g_object_set (dialog, "local-only", FALSE, NULL);
541 filter = gtk_file_filter_new ();
542 gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
543 gtk_file_filter_add_mime_type (filter, "application/x-spss-sav");
544 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
546 filter = gtk_file_filter_new ();
547 gtk_file_filter_set_name (filter, _("Compressed System Files (*.zsav)"));
548 gtk_file_filter_add_pattern (filter, "*.zsav");
549 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
551 filter = gtk_file_filter_new ();
552 gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
553 gtk_file_filter_add_mime_type (filter, "application/x-spss-por");
554 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
556 filter = gtk_file_filter_new ();
557 gtk_file_filter_set_name (filter, _("All Files"));
558 gtk_file_filter_add_pattern (filter, "*");
559 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
560 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
563 GtkCellRenderer *cell;
568 list_store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
569 combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (list_store));
571 gtk_list_store_append (list_store, &iter);
572 gtk_list_store_set (list_store, &iter,
573 0, PSPPIRE_DATA_WINDOW_SAV,
576 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter);
578 gtk_list_store_append (list_store, &iter);
579 gtk_list_store_set (list_store, &iter,
580 0, PSPPIRE_DATA_WINDOW_ZSAV,
581 1, _("Compressed System File"),
584 gtk_list_store_append (list_store, &iter);
585 gtk_list_store_set (list_store, &iter,
586 0, PSPPIRE_DATA_WINDOW_POR,
587 1, _("Portable File"),
590 label = gtk_label_new (_("Format:"));
592 cell = gtk_cell_renderer_text_new ();
593 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, FALSE);
594 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo_box), cell,
597 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
598 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
599 gtk_box_pack_start (GTK_BOX (hbox), combo_box, FALSE, FALSE, 0);
600 gtk_widget_show_all (hbox);
602 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), hbox);
605 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
608 switch (gtk_dialog_run (GTK_DIALOG (dialog)))
610 case GTK_RESPONSE_ACCEPT:
615 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog))
621 gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter);
622 gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter,
627 if (! name_has_suffix (filename->str))
628 g_string_append (filename,
629 psppire_data_window_format_to_string (format));
631 psppire_window_set_filename (PSPPIRE_WINDOW (de), filename->str);
633 g_string_free (filename, TRUE);
640 gtk_widget_destroy (dialog);
644 confirm_delete_dataset (PsppireDataWindow *de,
645 const char *old_dataset,
646 const char *new_dataset,
647 const char *existing_dataset)
652 dialog = gtk_message_dialog_new (
653 GTK_WINDOW (de), 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s",
654 _("Delete Existing Dataset?"));
656 gtk_message_dialog_format_secondary_text (
657 GTK_MESSAGE_DIALOG (dialog),
658 _("Renaming \"%s\" to \"%s\" will destroy the existing "
659 "dataset named \"%s\". Are you sure that you want to do this?"),
660 old_dataset, new_dataset, existing_dataset);
662 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
663 _("Cancel"), GTK_RESPONSE_CANCEL,
664 _("Delete"), GTK_RESPONSE_OK,
667 g_object_set (dialog, "icon-name", "pspp", NULL);
669 result = gtk_dialog_run (GTK_DIALOG (dialog));
671 gtk_widget_destroy (dialog);
673 return result == GTK_RESPONSE_OK;
677 on_rename_dataset (PsppireDataWindow *de)
679 struct dataset *ds = de->dataset;
680 struct session *session = dataset_session (ds);
681 const char *old_name = dataset_name (ds);
682 struct dataset *existing_dataset;
686 prompt = xasprintf (_("Please enter a new name for dataset \"%s\":"),
688 new_name = entry_dialog_run (GTK_WINDOW (de), _("Rename Dataset"), prompt,
692 if (new_name == NULL)
695 existing_dataset = session_lookup_dataset (session, new_name);
696 if (existing_dataset == NULL || existing_dataset == ds
697 || confirm_delete_dataset (de, old_name, new_name,
698 dataset_name (existing_dataset)))
699 g_free (execute_syntax_string (de, g_strdup_printf ("DATASET NAME %s.",
707 status_bar_activate (GAction *action, GVariant *param, PsppireDataWindow *de)
709 GtkWidget *statusbar = get_widget_assert (de->builder, "status-bar");
711 GVariant *state = g_action_get_state (action);
712 const gboolean visible = g_variant_get_boolean (state);
713 g_action_change_state (action, g_variant_new_boolean (!visible));
715 gtk_widget_set_visible (statusbar, !visible);
720 grid_lines_activate (GAction *action, GVariant *param, PsppireDataWindow *de)
722 GVariant *state = g_action_get_state (action);
723 const gboolean grid_visible = g_variant_get_boolean (state);
724 g_action_change_state (action, g_variant_new_boolean (!grid_visible));
726 psppire_data_editor_show_grid (de->data_editor, !grid_visible);
731 on_switch_page (GtkNotebook *notebook, GtkWidget *page, guint pn, gpointer ud)
733 PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (ud);
735 GAction *action = g_action_map_lookup_action (G_ACTION_MAP (de), "view_dv");
740 g_action_change_state (action, g_variant_new_string ("DATA"));
741 gtk_widget_show (GTK_WIDGET (de->ti_insert_case));
742 gtk_widget_show (GTK_WIDGET (de->ti_jump_to_case));
743 gtk_widget_show (GTK_WIDGET (de->ti_find));
745 gtk_widget_show (GTK_WIDGET (de->mi_go_to_case));
746 gtk_widget_show (GTK_WIDGET (de->mi_insert_case));
747 gtk_widget_show (GTK_WIDGET (de->mi_find));
748 gtk_widget_show (GTK_WIDGET (de->mi_find_separator));
749 gtk_widget_show (GTK_WIDGET (de->mi_clear_cases));
754 g_action_change_state (action, g_variant_new_string ("VARS"));
755 gtk_widget_hide (GTK_WIDGET (de->ti_insert_case));
756 gtk_widget_hide (GTK_WIDGET (de->ti_jump_to_case));
757 gtk_widget_hide (GTK_WIDGET (de->ti_find));
759 gtk_widget_hide (GTK_WIDGET (de->mi_go_to_case));
760 gtk_widget_hide (GTK_WIDGET (de->mi_insert_case));
761 gtk_widget_hide (GTK_WIDGET (de->mi_find));
762 gtk_widget_hide (GTK_WIDGET (de->mi_find_separator));
763 gtk_widget_hide (GTK_WIDGET (de->mi_clear_cases));
771 activate_change_view (GAction *action, GVariant *param, PsppireDataWindow *de)
773 g_action_change_state (action, param);
774 GVariant *new_state = g_action_get_state (action);
776 const gchar *what = g_variant_get_string (new_state, NULL);
777 if (0 == g_strcmp0 (what, "DATA"))
779 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
781 else if (0 == g_strcmp0 (what, "VARS"))
783 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
790 fonts_activate (PsppireDataWindow *de)
792 GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (de));
793 GtkWidget *dialog = gtk_font_chooser_dialog_new (NULL, GTK_WINDOW (toplevel));
794 GtkStyleContext *style = gtk_widget_get_style_context (GTK_WIDGET(de->data_editor));
795 const PangoFontDescription *current_font ;
797 gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, "font", ¤t_font, NULL);
799 gtk_font_chooser_set_font_desc (GTK_FONT_CHOOSER (dialog), current_font);
801 gtk_window_set_transient_for (GTK_WINDOW (dialog),
802 GTK_WINDOW (toplevel));
804 if (GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)))
806 PangoFontDescription* font_desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (dialog));
808 psppire_data_editor_set_font (de->data_editor, font_desc);
811 gtk_widget_hide (dialog);
816 /* Callback for the value labels action */
819 value_labels_activate (GAction *action, GVariant *param, PsppireDataWindow *de)
821 GVariant *v = g_action_get_state (action);
822 gboolean labels_active = g_variant_get_boolean (v);
823 g_action_change_state (action, g_variant_new_boolean (!labels_active));
825 GVariant *new_state = g_action_get_state (action);
826 labels_active = g_variant_get_boolean (new_state);
827 g_object_set (de->data_editor, "value-labels", labels_active, NULL);
829 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (de->ti_value_labels_button),
834 on_labels_button_toggle (GtkToggleToolButton *ttb, PsppireDataWindow *de)
836 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "value_labels");
838 gboolean labels_active = gtk_toggle_tool_button_get_active (ttb);
840 g_action_change_state (a, g_variant_new_boolean (labels_active));
842 GVariant *new_state = g_action_get_state (a);
843 labels_active = g_variant_get_boolean (new_state);
844 g_object_set (de->data_editor, "value-labels", labels_active, NULL);
848 on_recent_data_select (GtkMenuShell *menushell,
849 PsppireWindow *window)
854 gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
856 file = g_filename_from_uri (uri, NULL, NULL);
860 open_data_window (window, file, NULL, NULL);
866 charset_from_mime_type (const char *mime_type)
872 if (mime_type == NULL)
875 charset = c_strcasestr (mime_type, "charset=");
883 /* Parse a "quoted-string" as defined by RFC 822. */
884 for (p++; *p != '\0' && *p != '"'; p++)
887 ds_put_byte (&s, *p);
888 else if (*++p != '\0')
889 ds_put_byte (&s, *p);
894 /* Parse a "token" as defined by RFC 2045. */
895 while (*p > 32 && *p < 127 && strchr ("()<>@,;:\\\"/[]?=", *p) == NULL)
896 ds_put_byte (&s, *p++);
898 if (!ds_is_empty (&s))
899 return ds_steal_cstr (&s);
906 on_recent_files_select (GtkMenuShell *menushell, gpointer user_data)
913 /* Get the file name and its encoding. */
914 item = gtk_recent_chooser_get_current_item (GTK_RECENT_CHOOSER (menushell));
915 file = g_filename_from_uri (gtk_recent_info_get_uri (item), NULL, NULL);
916 encoding = charset_from_mime_type (gtk_recent_info_get_mime_type (item));
917 gtk_recent_info_unref (item);
919 se = psppire_syntax_window_new (encoding);
921 if (psppire_window_load (PSPPIRE_WINDOW (se), file, encoding, NULL))
922 gtk_widget_show (se);
924 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 *dw)
963 dw->dispose_has_run = FALSE;
965 dw->builder = builder_new ("data-editor.ui");
969 file_import (PsppireDataWindow *dw)
971 GtkWidget *w = psppire_import_assistant_new (GTK_WINDOW (dw));
972 PsppireImportAssistant *asst = PSPPIRE_IMPORT_ASSISTANT (w);
973 gtk_widget_show_all (w);
975 int response = psppire_import_assistant_run (asst);
979 case GTK_RESPONSE_APPLY:
981 gchar *fn = g_path_get_basename (asst->file_name);
982 open_data_window (PSPPIRE_WINDOW (dw), fn, NULL, psppire_import_assistant_generate_syntax (asst));
986 case PSPPIRE_RESPONSE_PASTE:
987 free (paste_syntax_to_window (psppire_import_assistant_generate_syntax (asst)));
993 gtk_widget_destroy (GTK_WIDGET (asst));
999 connect_dialog_action (GType type, PsppireDataWindow *de)
1001 GAction *act = g_object_new (type,
1005 g_action_map_add_action (G_ACTION_MAP (de), act);
1009 g_action_activate_null (GAction *a)
1011 g_action_activate (a, NULL);
1015 connect_action_to_menuitem (GActionMap *map, const gchar *action_name, GtkWidget *w, const gchar *accel)
1017 GAction *a = g_action_map_lookup_action (map, action_name);
1020 g_error ("Action \"%s\" not found in map", action_name);
1024 GtkApplication *app = GTK_APPLICATION (g_application_get_default());
1026 /* First set the label for the accellerator so that it appears
1028 GtkWidget *child = gtk_bin_get_child (GTK_BIN (w));
1030 GdkModifierType modifier;
1031 gtk_accelerator_parse (accel, &key, &modifier);
1032 gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), key, modifier);
1034 /* Now tell the application that it must do something when that
1035 key combination is pressed */
1036 const gchar *accels[2];
1040 gchar *detailed_action_name = NULL;
1041 if (GTK_IS_WINDOW (map))
1042 detailed_action_name = g_strdup_printf ("win.%s", action_name);
1043 else if (GTK_IS_APPLICATION (map))
1044 detailed_action_name = g_strdup_printf ("app.%s", action_name);
1046 gtk_application_set_accels_for_action (app,
1047 detailed_action_name,
1049 free (detailed_action_name);
1052 g_signal_connect_swapped (w, "activate", G_CALLBACK (g_action_activate_null), a);
1057 on_realize (PsppireDataWindow *dw)
1059 gtk_notebook_set_current_page (GTK_NOTEBOOK (dw->data_editor), 1);
1064 on_cut (PsppireDataWindow *dw)
1066 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
1067 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1069 PsppireDict *dict = NULL;
1070 g_object_get (dw->data_editor, "dictionary", &dict, NULL);
1073 SswSheet *sheet = SSW_SHEET (dw->data_editor->data_sheet);
1074 SswRange sel = *sheet->selection;
1076 if (ssw_sheet_try_cut (sheet))
1079 if (sel.start_x > sel.end_x)
1081 gint tmp = sel.start_x;
1082 sel.start_x = sel.end_x;
1085 if (sel.start_y > sel.end_y)
1087 gint tmp = sel.start_y;
1088 sel.start_y = sel.end_y;
1092 GtkClipboard *clip =
1093 gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
1094 GDK_SELECTION_CLIPBOARD);
1096 /* Save the selected area to a string */
1097 GString *str = g_string_new ("");
1098 for (y = sel.start_y ; y <= sel.end_y; ++y)
1100 for (x = sel.start_x ; x <= sel.end_x; ++x)
1102 const struct variable * var = psppire_dict_get_variable (dict, x);
1103 gboolean use_value_label = FALSE;
1104 g_object_get (dw->data_editor, "value-labels", &use_value_label, NULL);
1105 gchar *s = psppire_data_store_get_string (dw->data_editor->data_store,
1106 y, var, use_value_label);
1107 g_string_append (str, s);
1109 g_string_append (str, "\t");
1113 g_string_append (str, "\n");
1116 gtk_clipboard_set_text (clip, str->str, str->len);
1117 g_string_free (str, TRUE);
1119 /* Now fill the selected area with SYSMIS or blanks */
1120 for (x = sel.start_x ; x <= sel.end_x; ++x)
1122 const struct variable *var = psppire_dict_get_variable (dict, x);
1123 int width = var_get_width (var);
1125 value_init (&sm, width);
1126 if (var_is_numeric (var))
1129 memset (sm.s, 0, width);
1130 for (y = sel.start_y ; y <= sel.end_y; ++y)
1132 psppire_data_store_set_value (dw->data_editor->data_store,
1136 value_destroy (&sm, width);
1142 on_copy (PsppireDataWindow *dw)
1144 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
1145 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1147 GtkClipboard *clip =
1148 gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
1149 GDK_SELECTION_CLIPBOARD);
1151 ssw_sheet_set_clip (SSW_SHEET (dw->data_editor->data_sheet), clip);
1156 on_paste (PsppireDataWindow *dw)
1158 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (dw->data_editor));
1159 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1161 psppire_data_editor_paste (dw->data_editor);
1166 on_clear_cases (PsppireDataWindow *dw)
1168 PsppireDataEditor *de = dw->data_editor;
1169 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
1170 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1172 SswRange *range = SSW_SHEET(de->data_sheet)->selection;
1173 g_return_if_fail (range->start_y >= 0);
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);
1196 insert_variable (PsppireDataWindow *dw)
1198 PsppireDataEditor *de = dw->data_editor;
1199 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
1201 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1203 SswRange *range = SSW_SHEET(de->data_sheet)->selection;
1204 psppire_data_editor_insert_new_variable_at_posn (de, range->start_x);
1208 SswRange *range = SSW_SHEET(de->var_sheet)->selection;
1209 PsppireDict *dict = NULL;
1210 g_object_get (de->var_sheet, "data-model", &dict, NULL);
1211 psppire_dict_insert_variable (dict, range->start_y, NULL);
1212 gtk_widget_queue_draw (GTK_WIDGET (de->var_sheet));
1217 insert_case_at_row (PsppireDataWindow *dw)
1219 PsppireDataEditor *de = dw->data_editor;
1220 SswRange *range = SSW_SHEET(de->data_sheet)->selection;
1221 psppire_data_editor_insert_new_case_at_posn (de, range->start_y);
1225 goto_case (PsppireDataWindow *dw)
1227 PsppireDataEditor *de = dw->data_editor;
1228 int p = gtk_notebook_get_current_page (GTK_NOTEBOOK (de));
1229 if (p == PSPPIRE_DATA_EDITOR_DATA_VIEW)
1231 goto_case_dialog (PSPPIRE_DATA_SHEET (de->data_sheet));
1236 create_file_menu (PsppireDataWindow *dw)
1238 GtkWidget *menuitem = gtk_menu_item_new_with_mnemonic (_("_File"));
1239 GtkWidget *menu = gtk_menu_new ();
1242 GtkWidget *new = gtk_menu_item_new_with_mnemonic (_("_New"));
1243 gtk_menu_attach (GTK_MENU (menu), new, 0, 1, 0, 1);
1245 GtkWidget *new_menu = gtk_menu_new ();
1247 g_object_set (new, "submenu", new_menu, NULL);
1249 GtkWidget *syntax = gtk_menu_item_new_with_mnemonic (_("_Syntax"));
1250 connect_action_to_menuitem (G_ACTION_MAP (g_application_get_default ()), "new-syntax", syntax, 0);
1252 GtkWidget *data = gtk_menu_item_new_with_mnemonic (_("_Data"));
1253 connect_action_to_menuitem (G_ACTION_MAP (g_application_get_default ()), "new-data", data, 0);
1255 gtk_menu_attach (GTK_MENU (new_menu), syntax, 0, 1, 0, 1);
1256 gtk_menu_attach (GTK_MENU (new_menu), data, 0, 1, 1, 2);
1259 GtkWidget *open = gtk_menu_item_new_with_mnemonic (_("_Open"));
1260 connect_action_to_menuitem (G_ACTION_MAP (dw), "open", open, "<Primary>O");
1262 GtkWidget *import = gtk_menu_item_new_with_mnemonic (_("_Import Data..."));
1263 connect_action_to_menuitem (G_ACTION_MAP (dw), "file-import", import, 0);
1265 gtk_menu_attach (GTK_MENU (menu), open, 0, 1, 1, 2);
1266 gtk_menu_attach (GTK_MENU (menu), import, 0, 1, 2, 3);
1268 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 3, 4);
1270 GtkWidget *save = gtk_menu_item_new_with_mnemonic (_("_Save..."));
1271 connect_action_to_menuitem (G_ACTION_MAP (dw), "save", save, "<Primary>S");
1273 GtkWidget *save_as = gtk_menu_item_new_with_mnemonic (_("Save _As..."));
1274 connect_action_to_menuitem (G_ACTION_MAP (dw), "save-as", save_as, "<Shift><Primary>S");
1276 GtkWidget *rename_dataset = gtk_menu_item_new_with_mnemonic (_("_Rename Dataset..."));
1277 connect_action_to_menuitem (G_ACTION_MAP (dw), "rename-dataset", rename_dataset, 0);
1280 gtk_menu_attach (GTK_MENU (menu), save, 0, 1, 4, 5);
1281 gtk_menu_attach (GTK_MENU (menu), save_as, 0, 1, 5, 6);
1282 gtk_menu_attach (GTK_MENU (menu), rename_dataset, 0, 1, 6, 7);
1284 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 7, 8);
1287 GtkWidget *display_data = gtk_menu_item_new_with_mnemonic (_("_Display Data File Information"));
1288 gtk_menu_attach (GTK_MENU (menu), display_data, 0, 1, 8, 9);
1290 GtkWidget *dd_menu = gtk_menu_new ();
1292 g_object_set (display_data, "submenu", dd_menu, NULL);
1294 GtkWidget *working_file = gtk_menu_item_new_with_mnemonic (_("Working File"));
1295 connect_action_to_menuitem (G_ACTION_MAP (dw), "info-working", working_file, 0);
1296 GtkWidget *external_file = gtk_menu_item_new_with_mnemonic (_("_External File..."));
1297 connect_action_to_menuitem (G_ACTION_MAP (dw), "info-external", external_file, 0);
1299 gtk_menu_attach (GTK_MENU (dd_menu), working_file, 0, 1, 0, 1);
1300 gtk_menu_attach (GTK_MENU (dd_menu), external_file, 0, 1, 1, 2);
1303 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 9, 10);
1306 GtkWidget *mi_data = gtk_menu_item_new_with_mnemonic (_("_Recently Used Data"));
1307 GtkWidget *mi_files = gtk_menu_item_new_with_mnemonic (_("Recently Used _Files"));
1309 GtkWidget *menu_data = gtk_recent_chooser_menu_new_for_manager (
1310 gtk_recent_manager_get_default ());
1312 GtkWidget *menu_files = gtk_recent_chooser_menu_new_for_manager (
1313 gtk_recent_manager_get_default ());
1315 gtk_menu_attach (GTK_MENU (menu), mi_data, 0, 1, 10, 11);
1316 gtk_menu_attach (GTK_MENU (menu), mi_files, 0, 1, 11, 12);
1318 g_object_set (menu_data, "show-tips", TRUE, NULL);
1319 g_object_set (menu_files, "show-tips", TRUE, NULL);
1321 g_object_set (mi_data, "submenu", menu_data, NULL);
1322 g_object_set (mi_files, "submenu", menu_files, NULL);
1325 GtkRecentFilter *filter = gtk_recent_filter_new ();
1327 gtk_recent_filter_add_mime_type (filter, "application/x-spss-sav");
1328 gtk_recent_filter_add_mime_type (filter, "application/x-spss-por");
1330 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_data), GTK_RECENT_SORT_MRU);
1332 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_data), filter);
1335 g_signal_connect (menu_data, "selection-done", G_CALLBACK (on_recent_data_select), dw);
1338 GtkRecentFilter *filter = gtk_recent_filter_new ();
1340 gtk_recent_filter_add_pattern (filter, "*.sps");
1341 gtk_recent_filter_add_pattern (filter, "*.SPS");
1343 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu_files), GTK_RECENT_SORT_MRU);
1345 gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu_files), filter);
1348 g_signal_connect (menu_files, "selection-done", G_CALLBACK (on_recent_files_select), dw);
1351 gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 12, 13);
1354 GtkWidget *quit = gtk_menu_item_new_with_mnemonic (_("_Quit"));
1355 gtk_menu_attach (GTK_MENU (menu), quit, 0, 1, 13, 14);
1357 connect_action_to_menuitem (G_ACTION_MAP (g_application_get_default ()),
1358 "quit", quit, "<Primary>Q");
1361 g_object_set (menuitem, "submenu", menu, NULL);
1362 gtk_widget_show_all (menuitem);
1369 create_edit_menu (PsppireDataWindow *dw)
1372 GtkWidget *menuitem = gtk_menu_item_new_with_mnemonic (_("_Edit"));
1374 GtkWidget *menu = gtk_menu_new ();
1376 dw->mi_insert_var = gtk_menu_item_new_with_mnemonic (_("_Insert Variable"));
1377 dw->mi_insert_case = gtk_menu_item_new_with_mnemonic (_("_Insert Case"));
1378 GtkWidget *go_to_variable = gtk_menu_item_new_with_mnemonic (_("_Go To Variable..."));
1379 dw->mi_go_to_case = gtk_menu_item_new_with_mnemonic (_("_Go To Case..."));
1381 gtk_menu_attach (GTK_MENU (menu), dw->mi_insert_var, 0, 1, i, i + 1); ++i;
1382 gtk_menu_attach (GTK_MENU (menu), dw->mi_insert_case, 0, 1, i, i + 1); ++i;
1384 g_signal_connect_swapped (dw->mi_insert_case, "activate", G_CALLBACK (insert_case_at_row), dw);
1385 g_signal_connect_swapped (dw->mi_go_to_case, "activate", G_CALLBACK (goto_case), dw);
1386 g_signal_connect_swapped (dw->mi_insert_var, "activate", G_CALLBACK (insert_variable), dw);
1388 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (dw), "PsppireDialogActionVarInfo");
1390 g_signal_connect_swapped (go_to_variable, "activate", G_CALLBACK (psppire_dialog_action_activate_null), a);
1392 gtk_menu_attach (GTK_MENU (menu), go_to_variable, 0, 1, i, i + 1); ++i;
1393 gtk_menu_attach (GTK_MENU (menu), dw->mi_go_to_case, 0, 1, i, i + 1); ++i;
1396 GtkAccelGroup *ag = gtk_accel_group_new ();
1398 GdkModifierType modifier;
1400 dw->mi_edit_separator = gtk_separator_menu_item_new ();
1401 gtk_menu_attach (GTK_MENU (menu), dw->mi_edit_separator, 0, 1, i, i + 1); ++i;
1403 dw->mi_cut = gtk_menu_item_new_with_mnemonic (_("Cu_t"));
1404 gtk_menu_attach (GTK_MENU (menu), dw->mi_cut, 0, 1, i, i + 1); ++i;
1405 g_signal_connect_swapped (dw->mi_cut, "activate", G_CALLBACK (on_cut), dw);
1407 gtk_window_add_accel_group (GTK_WINDOW (dw), ag);
1408 gtk_accelerator_parse ("<Primary>X", &key, &modifier);
1409 gtk_widget_add_accelerator (dw->mi_cut, "activate", ag,
1410 key, modifier, 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_accelerator_parse ("<Primary>C", &key, &modifier);
1416 gtk_widget_add_accelerator (dw->mi_copy, "activate", ag,
1417 key, modifier, GTK_ACCEL_VISIBLE);
1419 dw->mi_paste = gtk_menu_item_new_with_mnemonic (_("_Paste"));
1420 gtk_menu_attach (GTK_MENU (menu), dw->mi_paste, 0, 1, i, i + 1); ++i;
1421 g_signal_connect_swapped (dw->mi_paste, "activate", G_CALLBACK (on_paste), dw);
1422 gtk_accelerator_parse ("<Primary>V", &key, &modifier);
1423 gtk_widget_add_accelerator (dw->mi_paste, "activate", ag,
1424 key, modifier, GTK_ACCEL_VISIBLE);
1426 dw->mi_clear_variables = gtk_menu_item_new_with_mnemonic (_("Clear _Variables"));
1427 gtk_menu_attach (GTK_MENU (menu), dw->mi_clear_variables, 0, 1, i, i + 1); ++i;
1428 g_signal_connect_swapped (dw->mi_clear_variables, "activate", G_CALLBACK (on_clear_variables), dw);
1430 dw->mi_clear_cases = gtk_menu_item_new_with_mnemonic (_("Cl_ear Cases"));
1431 gtk_menu_attach (GTK_MENU (menu), dw->mi_clear_cases, 0, 1, i, i + 1); ++i;
1432 g_signal_connect_swapped (dw->mi_clear_cases, "activate", G_CALLBACK (on_clear_cases), dw);
1433 g_object_unref (ag);
1437 dw->mi_find_separator = gtk_separator_menu_item_new ();
1438 gtk_menu_attach (GTK_MENU (menu), dw->mi_find_separator, 0, 1, i, i + 1); ++i;
1440 dw->mi_find = gtk_menu_item_new_with_mnemonic (_("_Find..."));
1441 g_signal_connect_swapped (dw->mi_find, "activate", G_CALLBACK (find_dialog), dw);
1442 gtk_menu_attach (GTK_MENU (menu), dw->mi_find, 0, 1, i, i + 1); ++i;
1446 dw->mi_options = gtk_menu_item_new_with_mnemonic (_("_Options..."));
1447 g_signal_connect_swapped (dw->mi_options, "activate",
1448 G_CALLBACK (options_dialog), dw);
1449 gtk_menu_attach (GTK_MENU (menu), dw->mi_options, 0, 1, i, i + 1); ++i;
1452 g_object_set (menuitem, "submenu", menu, NULL);
1454 gtk_widget_show_all (menuitem);
1460 psppire_data_window_finish_init (PsppireDataWindow *de,
1463 static const struct dataset_callbacks cbs =
1465 set_unsaved, /* changed */
1466 transformation_change_callback, /* transformations_changed */
1473 GtkWidget *box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1476 de->dict = psppire_dict_new_from_dict (dataset_dict (ds));
1477 de->data_store = psppire_data_store_new (de->dict);
1478 psppire_data_store_set_reader (de->data_store, NULL);
1480 GObject *menu = get_object_assert (de->builder, "data-editor-menu", G_TYPE_MENU);
1481 menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (menu));
1482 gtk_widget_show (menubar);
1484 hb = gtk_toolbar_new ();
1485 sb = get_widget_assert (de->builder, "status-bar");
1488 PSPPIRE_DATA_EDITOR (psppire_data_editor_new (de->dict, de->data_store));
1490 g_signal_connect (de, "realize",
1491 G_CALLBACK (on_realize), de);
1493 g_signal_connect_swapped (de->data_store, "case-changed",
1494 G_CALLBACK (set_unsaved), de);
1496 dataset_set_callbacks (de->dataset, &cbs, de);
1498 gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
1499 gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
1500 gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
1501 gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
1503 gtk_container_add (GTK_CONTAINER (de), box);
1505 g_signal_connect (de->dict, "weight-changed",
1506 G_CALLBACK (on_weight_change),
1509 g_signal_connect (de->dict, "filter-changed",
1510 G_CALLBACK (on_filter_change),
1513 g_signal_connect (de->dict, "split-changed",
1514 G_CALLBACK (on_split_change),
1517 g_signal_connect_swapped (de->dict, "items-changed",
1518 G_CALLBACK (enable_save), de);
1519 g_signal_connect_swapped (de->dict, "variable-inserted",
1520 G_CALLBACK (enable_save), de);
1521 g_signal_connect_swapped (de->dict, "variable-deleted",
1522 G_CALLBACK (enable_save), de);
1525 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SORT, de);
1526 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SPLIT, de);
1527 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_FLIP, de);
1528 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_AGGREGATE, de);
1529 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_WEIGHT, de);
1531 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_COMPUTE, de);
1532 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_COUNT, de);
1533 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_AUTORECODE, de);
1534 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RANK, de);
1535 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SELECT, de);
1536 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RECODE_SAME, de);
1537 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RECODE_DIFFERENT, de);
1540 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_DESCRIPTIVES, de);
1541 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_FREQUENCIES, de);
1542 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_EXAMINE, de);
1543 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_CROSSTABS, de);
1545 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_INDEP_SAMPS, de);
1546 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_PAIRED, de);
1548 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_MEANS, de);
1549 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_TT1S, de);
1551 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_ONEWAY, de);
1552 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_UNIVARIATE, de);
1553 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_KMEANS, de);
1554 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_FACTOR, de);
1555 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_CORRELATION, de);
1556 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RELIABILITY, de);
1557 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_REGRESSION, de);
1558 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_LOGISTIC, de);
1559 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_ROC, de);
1561 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_COMMENTS, de);
1562 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_VAR_INFO, de);
1564 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_BARCHART, de);
1565 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT, de);
1566 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM, de);
1568 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_CHISQUARE, de);
1569 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_BINOMIAL, de);
1570 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_RUNS, de);
1571 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_1SKS, de);
1572 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_TWO_SAMPLE, de);
1573 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_K_RELATED, de);
1574 connect_dialog_action (PSPPIRE_TYPE_DIALOG_ACTION_K_INDEPENDENT, de);
1577 GSimpleAction *file_import_action = g_simple_action_new ("file-import", NULL);
1578 g_signal_connect_swapped (file_import_action, "activate", G_CALLBACK (file_import), de);
1579 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (file_import_action));
1583 GSimpleAction *save = g_simple_action_new ("save", NULL);
1584 g_signal_connect_swapped (save, "activate", G_CALLBACK (psppire_window_save), de);
1585 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (save));
1589 GSimpleAction *open = g_simple_action_new ("open", NULL);
1590 g_signal_connect_swapped (open, "activate", G_CALLBACK (psppire_window_open), de);
1591 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (open));
1595 GSimpleAction *save_as = g_simple_action_new ("save-as", NULL);
1596 g_signal_connect_swapped (save_as, "activate", G_CALLBACK (psppire_window_save_as), de);
1597 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (save_as));
1601 GSimpleAction *rename_dataset_act = g_simple_action_new ("rename-dataset", NULL);
1602 g_signal_connect_swapped (rename_dataset_act, "activate",
1603 G_CALLBACK (on_rename_dataset), de);
1604 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (rename_dataset_act));
1608 GSimpleAction *info_working = g_simple_action_new ("info-working", NULL);
1609 g_signal_connect_swapped (info_working, "activate", G_CALLBACK (display_dict), de);
1610 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (info_working));
1613 GSimpleAction *info_external = g_simple_action_new ("info-external", NULL);
1614 g_signal_connect_swapped (info_external, "activate", G_CALLBACK (sysfile_info), de);
1615 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (info_external));
1619 GSimpleAction *act_statusbar = g_simple_action_new_stateful ("statusbar", NULL, g_variant_new_boolean (TRUE));
1620 g_signal_connect (act_statusbar, "activate", G_CALLBACK (status_bar_activate), de);
1621 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_statusbar));
1625 GSimpleAction *act_gridlines = g_simple_action_new_stateful ("gridlines", NULL, g_variant_new_boolean (TRUE));
1626 g_signal_connect (act_gridlines, "activate", G_CALLBACK (grid_lines_activate), de);
1627 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_gridlines));
1632 GSimpleAction *act_view_data = g_simple_action_new_stateful ("view_dv", G_VARIANT_TYPE_STRING,
1633 g_variant_new_string ("DATA"));
1634 g_signal_connect (act_view_data, "activate", G_CALLBACK (activate_change_view), de);
1635 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_view_data));
1639 GSimpleAction *act_fonts = g_simple_action_new ("fonts", NULL);
1640 g_signal_connect_swapped (act_fonts, "activate", G_CALLBACK (fonts_activate), de);
1641 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_fonts));
1645 GSimpleAction *act_value_labels =
1646 g_simple_action_new_stateful ("value_labels", NULL,
1647 g_variant_new_boolean (FALSE));
1648 g_signal_connect (act_value_labels, "activate", G_CALLBACK (value_labels_activate), de);
1649 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_value_labels));
1653 GSimpleAction *act_transform_pending = g_simple_action_new ("transform-pending", NULL);
1654 g_signal_connect_swapped (act_transform_pending, "activate", G_CALLBACK (execute), de);
1655 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_transform_pending));
1659 GSimpleAction *act_jump_to_variable = g_simple_action_new ("jump-to-variable", NULL);
1660 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_jump_to_variable));
1664 GSimpleAction *act_insert_variable = g_simple_action_new ("insert-variable", NULL);
1665 g_signal_connect_swapped (act_insert_variable, "activate", G_CALLBACK (insert_variable), de);
1666 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_insert_variable));
1670 GSimpleAction *act_jump_to_case = g_simple_action_new ("jump-to-case", NULL);
1671 g_signal_connect_swapped (act_jump_to_case, "activate", G_CALLBACK (goto_case), de);
1672 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_jump_to_case));
1676 GSimpleAction *act_insert_case = g_simple_action_new ("insert-case", NULL);
1677 g_signal_connect_swapped (act_insert_case, "activate", G_CALLBACK (insert_case_at_row), de);
1678 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (act_insert_case));
1682 GSimpleAction *find = g_simple_action_new ("find", NULL);
1683 g_signal_connect_swapped (find, "activate", G_CALLBACK (find_dialog), de);
1684 g_action_map_add_action (G_ACTION_MAP (de), G_ACTION (find));
1690 GtkToolItem *ti = gtk_tool_button_new (NULL, "Open");
1691 g_signal_connect_swapped (ti, "clicked", G_CALLBACK (psppire_window_open), de);
1692 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1693 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-file-open-data");
1697 GtkToolItem *ti = gtk_tool_button_new (NULL, "Save");
1698 g_signal_connect_swapped (ti, "clicked", G_CALLBACK (psppire_window_save), de);
1699 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1700 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-file-save-data");
1703 gtk_toolbar_insert (GTK_TOOLBAR (hb), gtk_separator_tool_item_new (), idx++);
1706 de->ti_jump_to_variable = gtk_tool_button_new (NULL, "Goto Var");
1708 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "PsppireDialogActionVarInfo");
1710 g_signal_connect_swapped (de->ti_jump_to_variable, "clicked",
1711 G_CALLBACK (psppire_dialog_action_activate_null), a);
1713 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_jump_to_variable, idx++);
1714 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_variable), "pspp-edit-go-to-variable");
1715 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_jump_to_variable), _("Jump to variable"));
1719 de->ti_jump_to_case = gtk_tool_button_new (NULL, "Jump to Case");
1721 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "jump-to-case");
1723 g_signal_connect_swapped (de->ti_jump_to_case, "clicked",
1724 G_CALLBACK (g_action_activate_null), a);
1726 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_jump_to_case, idx++);
1727 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_case), "pspp-edit-go-to-case");
1728 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_jump_to_case), _("Jump to a case in the data sheet"));
1732 de->ti_find = gtk_tool_button_new (NULL, "Find");
1734 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "find");
1736 g_signal_connect_swapped (de->ti_find, "clicked",
1737 G_CALLBACK (g_action_activate_null), a);
1740 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_find, idx++);
1741 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_find), "pspp-edit-find");
1742 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_find), _("Search for values in the data"));
1746 de->ti_insert_case = gtk_tool_button_new (NULL, "Create Case");
1747 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "insert-case");
1749 g_signal_connect_swapped (de->ti_insert_case, "clicked",
1750 G_CALLBACK (g_action_activate_null), a);
1752 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_insert_case, idx++);
1753 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_case), "pspp-edit-insert-case");
1754 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_insert_case), _("Create a new case at the current position"));
1758 de->ti_insert_variable = gtk_tool_button_new (NULL, "Create Variable");
1759 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de), "insert-variable");
1761 g_signal_connect_swapped (de->ti_insert_variable, "clicked",
1762 G_CALLBACK (g_action_activate_null), a);
1764 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_insert_variable, idx++);
1765 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_variable), "pspp-edit-insert-variable");
1766 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_insert_variable), _("Create a new variable at the current position"));
1769 gtk_toolbar_insert (GTK_TOOLBAR (hb), gtk_separator_tool_item_new (), idx++);
1772 GtkToolItem *ti = gtk_tool_button_new (NULL, "Split");
1773 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de),
1774 "PsppireDialogActionSplit");
1776 g_signal_connect_swapped (ti, "clicked",
1777 G_CALLBACK (psppire_dialog_action_activate_null), a);
1778 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1779 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-data-split-file");
1780 gtk_widget_set_tooltip_text (GTK_WIDGET (ti), _("Split the active dataset"));
1784 GtkToolItem *ti = gtk_tool_button_new (NULL, "Weight");
1785 GAction *a = g_action_map_lookup_action (G_ACTION_MAP (de),
1786 "PsppireDialogActionWeight");
1788 g_signal_connect_swapped (ti, "clicked",
1789 G_CALLBACK (psppire_dialog_action_activate_null), a);
1790 gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
1791 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-data-weight-cases");
1792 gtk_widget_set_tooltip_text (GTK_WIDGET (ti), _("Weight cases by variable"));
1796 de->ti_value_labels_button = gtk_toggle_tool_button_new ();
1797 gtk_tool_button_set_label (GTK_TOOL_BUTTON (de->ti_value_labels_button),
1799 g_signal_connect (de->ti_value_labels_button, "toggled",
1800 G_CALLBACK (on_labels_button_toggle), de);
1801 gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_value_labels_button, idx++);
1802 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_value_labels_button), "pspp-view-value-labels");
1803 gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_value_labels_button), _("Show/hide value labels"));
1808 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
1809 gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
1811 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), create_file_menu (de), 0);
1812 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), create_edit_menu (de), 1);
1813 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), create_windows_menu (GTK_WINDOW (de)));
1814 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), create_help_menu (GTK_WINDOW (de)));
1816 g_signal_connect (de->data_editor, "switch-page",
1817 G_CALLBACK (on_switch_page), de);
1819 gtk_widget_show (GTK_WIDGET (de->data_editor));
1820 gtk_widget_show_all (box);
1822 ll_push_head (&all_data_windows, &de->ll);
1827 psppire_data_window_dispose (GObject *object)
1829 PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
1831 if (dw->dispose_has_run)
1833 dw->dispose_has_run = TRUE;
1835 g_object_unref (dw->builder);
1839 g_signal_handlers_disconnect_by_func (dw->dict,
1840 G_CALLBACK (enable_save), dw);
1841 g_signal_handlers_disconnect_by_func (dw->dict,
1842 G_CALLBACK (on_weight_change), dw);
1843 g_signal_handlers_disconnect_by_func (dw->dict,
1844 G_CALLBACK (on_filter_change), dw);
1845 g_signal_handlers_disconnect_by_func (dw->dict,
1846 G_CALLBACK (on_split_change), dw);
1848 g_object_unref (dw->dict);
1851 g_object_unref (dw->data_store);
1853 if (G_OBJECT_CLASS (parent_class)->dispose)
1854 G_OBJECT_CLASS (parent_class)->dispose (object);
1858 psppire_data_window_finalize (GObject *object)
1860 PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
1864 struct dataset *dataset = dw->dataset;
1865 struct session *session = dataset_session (dataset);
1869 dataset_set_callbacks (dataset, NULL, NULL);
1870 session_set_active_dataset (session, NULL);
1871 dataset_destroy (dataset);
1874 if (dw->ll.next != NULL)
1876 ll_remove (&dw->ll);
1880 if (G_OBJECT_CLASS (parent_class)->finalize)
1881 G_OBJECT_CLASS (parent_class)->finalize (object);
1885 psppire_data_window_set_property (GObject *object,
1887 const GValue *value,
1890 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1895 psppire_data_window_finish_init (window, g_value_get_pointer (value));
1898 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1904 psppire_data_window_get_property (GObject *object,
1909 PsppireDataWindow *window = PSPPIRE_DATA_WINDOW (object);
1914 g_value_set_pointer (value, window->dataset);
1917 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1925 psppire_data_window_new (struct dataset *ds)
1929 if (the_session == NULL)
1930 the_session = session_create (NULL);
1934 char *dataset_name = session_generate_dataset_name (the_session);
1935 ds = dataset_create (the_session, dataset_name);
1936 free (dataset_name);
1938 assert (dataset_session (ds) == the_session);
1942 psppire_data_window_get_type (),
1943 "description", _("Data Editor"),
1947 if (dataset_name (ds) != NULL)
1948 g_object_set (dw, "id", dataset_name (ds), (void *) NULL);
1951 GApplication *app = g_application_get_default ();
1952 gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (dw));
1960 psppire_data_window_is_empty (PsppireDataWindow *dw)
1962 return psppire_dict_get_var_cnt (dw->dict) == 0;
1967 psppire_data_window_iface_init (PsppireWindowIface *iface)
1969 iface->save = save_file;
1970 iface->pick_filename = data_pick_filename;
1971 iface->load = load_file;
1978 psppire_default_data_window (void)
1980 if (ll_is_empty (&all_data_windows))
1981 create_data_window ();
1982 return ll_data (ll_head (&all_data_windows), PsppireDataWindow, ll);
1988 psppire_data_window_set_default (PsppireDataWindow *pdw)
1990 ll_remove (&pdw->ll);
1991 ll_push_head (&all_data_windows, &pdw->ll);
1995 psppire_data_window_undefault (PsppireDataWindow *pdw)
1997 ll_remove (&pdw->ll);
1998 ll_push_tail (&all_data_windows, &pdw->ll);
2004 psppire_data_window_for_dataset (struct dataset *ds)
2006 PsppireDataWindow *pdw;
2008 ll_for_each (pdw, PsppireDataWindow, ll, &all_data_windows)
2009 if (pdw->dataset == ds)
2016 psppire_data_window_for_data_store (PsppireDataStore *data_store)
2018 PsppireDataWindow *pdw;
2020 ll_for_each (pdw, PsppireDataWindow, ll, &all_data_windows)
2021 if (pdw->data_store == data_store)
2028 create_data_window (void)
2030 GtkWidget *w = psppire_data_window_new (NULL);
2032 gtk_widget_show (w);
2034 return GTK_WINDOW (w);
2038 open_data_window (PsppireWindow *victim, const char *file_name,
2039 const char *encoding, gpointer hint)
2043 if (PSPPIRE_IS_DATA_WINDOW (victim)
2044 && psppire_data_window_is_empty (PSPPIRE_DATA_WINDOW (victim)))
2046 window = GTK_WIDGET (victim);
2049 window = psppire_data_window_new (NULL);
2051 psppire_window_load (PSPPIRE_WINDOW (window), file_name, encoding, hint);
2052 return GTK_WINDOW (window);