+ GtkWidget *menu = gtk_menu_new ();
+
+ dw->mi_insert_var = gtk_menu_item_new_with_mnemonic (_("_Insert Variable"));
+ dw->mi_insert_case = gtk_menu_item_new_with_mnemonic (_("_Insert Case"));
+ GtkWidget *go_to_variable = gtk_menu_item_new_with_mnemonic (_("_Go To Variable..."));
+ dw->mi_go_to_case = gtk_menu_item_new_with_mnemonic (_("_Go To Case..."));
+
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_insert_var, 0, 1, i, i + 1); ++i;
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_insert_case, 0, 1, i, i + 1); ++i;
+
+ g_signal_connect_swapped (dw->mi_insert_case, "activate", G_CALLBACK (insert_case_at_row), dw);
+ g_signal_connect_swapped (dw->mi_go_to_case, "activate", G_CALLBACK (goto_case), dw);
+ g_signal_connect_swapped (dw->mi_insert_var, "activate", G_CALLBACK (insert_variable), dw);
+
+ GAction *a = g_action_map_lookup_action (G_ACTION_MAP (dw), "PsppireDialogActionVarInfo");
+ g_assert (a);
+ g_signal_connect_swapped (go_to_variable, "activate", G_CALLBACK (psppire_dialog_action_activate_null), a);
+
+ gtk_menu_attach (GTK_MENU (menu), go_to_variable, 0, 1, i, i + 1); ++i;
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_go_to_case, 0, 1, i, i + 1); ++i;
+
+ {
+ GtkAccelGroup *ag = gtk_accel_group_new ();
+ guint key;
+ GdkModifierType modifier;
+
+ dw->mi_edit_separator = gtk_separator_menu_item_new ();
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_edit_separator, 0, 1, i, i + 1); ++i;
+
+ dw->mi_cut = gtk_menu_item_new_with_mnemonic (_("Cu_t"));
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_cut, 0, 1, i, i + 1); ++i;
+ g_signal_connect_swapped (dw->mi_cut, "activate", G_CALLBACK (on_cut), dw);
+
+ gtk_window_add_accel_group (GTK_WINDOW (dw), ag);
+ gtk_accelerator_parse ("<Primary>X", &key, &modifier);
+ gtk_widget_add_accelerator (dw->mi_cut, "activate", ag,
+ key, modifier, GTK_ACCEL_VISIBLE);
+
+ dw->mi_copy = gtk_menu_item_new_with_mnemonic (_("_Copy"));
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_copy, 0, 1, i, i + 1); ++i;
+ g_signal_connect_swapped (dw->mi_copy, "activate", G_CALLBACK (on_copy), dw);
+ gtk_accelerator_parse ("<Primary>C", &key, &modifier);
+ gtk_widget_add_accelerator (dw->mi_copy, "activate", ag,
+ key, modifier, GTK_ACCEL_VISIBLE);
+
+ dw->mi_paste = gtk_menu_item_new_with_mnemonic (_("_Paste"));
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_paste, 0, 1, i, i + 1); ++i;
+ g_signal_connect_swapped (dw->mi_paste, "activate", G_CALLBACK (on_paste), dw);
+ gtk_accelerator_parse ("<Primary>V", &key, &modifier);
+ gtk_widget_add_accelerator (dw->mi_paste, "activate", ag,
+ key, modifier, GTK_ACCEL_VISIBLE);
+
+ dw->mi_clear_variables = gtk_menu_item_new_with_mnemonic (_("Clear _Variables"));
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_clear_variables, 0, 1, i, i + 1); ++i;
+ g_signal_connect_swapped (dw->mi_clear_variables, "activate", G_CALLBACK (on_clear_variables), dw);
+
+ dw->mi_clear_cases = gtk_menu_item_new_with_mnemonic (_("Cl_ear Cases"));
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_clear_cases, 0, 1, i, i + 1); ++i;
+ g_signal_connect_swapped (dw->mi_clear_cases, "activate", G_CALLBACK (on_clear_cases), dw);
+ g_object_unref (ag);
+ }
+
+ {
+ dw->mi_find_separator = gtk_separator_menu_item_new ();
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_find_separator, 0, 1, i, i + 1); ++i;
+
+ dw->mi_find = gtk_menu_item_new_with_mnemonic (_("_Find..."));
+ g_signal_connect_swapped (dw->mi_find, "activate", G_CALLBACK (find_dialog), dw);
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_find, 0, 1, i, i + 1); ++i;
+ }
+
+ {
+ dw->mi_options = gtk_menu_item_new_with_mnemonic (_("_Options..."));
+ g_signal_connect_swapped (dw->mi_options, "activate",
+ G_CALLBACK (options_dialog), dw);
+ gtk_menu_attach (GTK_MENU (menu), dw->mi_options, 0, 1, i, i + 1); ++i;
+ }
+
+ g_object_set (menuitem, "submenu", menu, NULL);
+
+ gtk_widget_show_all (menuitem);
+
+ return menuitem;
+}
+
+static void
+psppire_data_window_finish_init (PsppireDataWindow *de,
+ struct dataset *ds)
+{
+ static const struct dataset_callbacks cbs =
+ {
+ set_unsaved, /* changed */
+ transformation_change_callback, /* transformations_changed */
+ };
+
+ GtkWidget *menubar;
+ GtkWidget *hb ;
+ GtkWidget *sb ;
+
+ GtkWidget *box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+
+ de->dataset = ds;
+ de->dict = psppire_dict_new_from_dict (dataset_dict (ds));
+ de->data_store = psppire_data_store_new (de->dict);
+ psppire_data_store_set_reader (de->data_store, NULL);
+
+ GObject *menu = get_object_assert (de->builder, "data-editor-menu", G_TYPE_MENU);
+ menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (menu));
+ gtk_widget_show (menubar);
+
+ hb = gtk_toolbar_new ();
+ sb = get_widget_assert (de->builder, "status-bar");
+
+ de->data_editor =
+ PSPPIRE_DATA_EDITOR (psppire_data_editor_new (de->dict, de->data_store));
+
+ g_signal_connect (de, "realize",
+ G_CALLBACK (on_realize), de);
+
+ g_signal_connect_swapped (de->data_store, "case-changed",
+ G_CALLBACK (set_unsaved), de);
+
+ dataset_set_callbacks (de->dataset, &cbs, de);
+
+ gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
+
+ gtk_container_add (GTK_CONTAINER (de), box);
+
+ g_signal_connect (de->dict, "weight-changed",
+ G_CALLBACK (on_weight_change),