treewide: Replace <name>_cnt by n_<name>s and <name>_cap by allocated_<name>.
[pspp] / src / ui / gui / psppire-data-window.c
index 6a0d4719c9af2fe644eb7e76f0341979982499b7..ad7e9250f7d404389aefaa0e79bf55e23d2f32d3 100644 (file)
 struct session *the_session;
 struct ll_list all_data_windows = LL_INITIALIZER (all_data_windows);
 
-static void psppire_data_window_class_init    (PsppireDataWindowClass *class);
-static void psppire_data_window_init          (PsppireDataWindow      *data_editor);
-
-
 static void psppire_data_window_iface_init (PsppireWindowIface *iface);
 
 static void psppire_data_window_dispose (GObject *object);
@@ -118,45 +114,10 @@ static void psppire_data_window_get_property (GObject         *object,
                                               GValue          *value,
                                               GParamSpec      *pspec);
 
-GType
-psppire_data_window_get_type (void)
-{
-  static GType psppire_data_window_type = 0;
-
-  if (!psppire_data_window_type)
-    {
-      static const GTypeInfo psppire_data_window_info =
-       {
-         sizeof (PsppireDataWindowClass),
-         NULL,
-         NULL,
-         (GClassInitFunc)psppire_data_window_class_init,
-         (GClassFinalizeFunc) NULL,
-         NULL,
-         sizeof (PsppireDataWindow),
-         0,
-         (GInstanceInitFunc) psppire_data_window_init,
-       };
-
-      static const GInterfaceInfo window_interface_info =
-       {
-         (GInterfaceInitFunc) psppire_data_window_iface_init,
-         NULL,
-         NULL
-       };
-
-      psppire_data_window_type =
-       g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireDataWindow",
-                               &psppire_data_window_info, 0);
 
-
-      g_type_add_interface_static (psppire_data_window_type,
-                                  PSPPIRE_TYPE_WINDOW_MODEL,
-                                  &window_interface_info);
-    }
-
-  return psppire_data_window_type;
-}
+G_DEFINE_TYPE_WITH_CODE (PsppireDataWindow, psppire_data_window, PSPPIRE_TYPE_WINDOW,
+                        G_IMPLEMENT_INTERFACE (PSPPIRE_TYPE_WINDOW_MODEL,
+                                               psppire_data_window_iface_init))
 
 static GObjectClass *parent_class ;
 
@@ -253,7 +214,7 @@ on_split_change (PsppireDict *dict, gpointer data)
 {
   PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
 
-  size_t n_split_vars = dict_get_split_cnt (dict->dict);
+  size_t n_split_vars = dict_get_n_splits (dict->dict);
 
   GtkWidget *split_status_area =
     get_widget_assert (de->builder, "split-file-status-area");
@@ -938,7 +899,7 @@ set_unsaved (gpointer w)
 static void
 enable_save (PsppireDataWindow *dw)
 {
-  gboolean enable = psppire_dict_get_var_cnt (dw->dict) > 0;
+  gboolean enable = psppire_dict_get_n_vars (dw->dict) > 0;
 
   GAction *save_as = g_action_map_lookup_action (G_ACTION_MAP (dw), "save-as");
   GAction *save = g_action_map_lookup_action (G_ACTION_MAP (dw), "save");
@@ -958,9 +919,11 @@ enable_save (PsppireDataWindow *dw)
    modify the menu as part of the "filename" property_set() function and end up
    with a Gtk-CRITICAL since 'menu' is NULL.  */
 static void
-psppire_data_window_init (PsppireDataWindow *de)
+psppire_data_window_init (PsppireDataWindow *dw)
 {
-  de->builder = builder_new ("data-editor.ui");
+  dw->dispose_has_run = FALSE;
+
+  dw->builder = builder_new ("data-editor.ui");
 }
 
 static void
@@ -1071,6 +1034,22 @@ on_cut (PsppireDataWindow *dw)
       SswSheet *sheet = SSW_SHEET (dw->data_editor->data_sheet);
       SswRange sel = *sheet->selection;
 
+      if (ssw_sheet_try_cut (sheet))
+       return;
+
+      if (sel.start_x > sel.end_x)
+       {
+         gint tmp = sel.start_x;
+         sel.start_x = sel.end_x;
+         sel.end_x = tmp;
+       }
+      if (sel.start_y > sel.end_y)
+       {
+         gint tmp = sel.start_y;
+         sel.start_y = sel.end_y;
+         sel.end_y = tmp;
+       }
+         
       GtkClipboard *clip =
        gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (dw)),
                                       GDK_SELECTION_CLIPBOARD);
@@ -1082,32 +1061,41 @@ on_cut (PsppireDataWindow *dw)
          for (x = sel.start_x ; x <= sel.end_x; ++x)
            {
              const struct variable * var = psppire_dict_get_variable (dict, x);
+             gboolean use_value_label = FALSE;
+             g_object_get (dw->data_editor, "value-labels", &use_value_label, NULL);
              gchar *s = psppire_data_store_get_string (dw->data_editor->data_store,
-                                                         y, var, FALSE);
+                                                         y, var, use_value_label);
              g_string_append (str, s);
-             g_string_append (str, "\t");
+              if (x < sel.end_x)
+                g_string_append (str, "\t");
              g_free (s);
            }
-         g_string_append (str, "\n");
+          if (y < sel.end_y)
+            g_string_append (str, "\n");
        }
 
       gtk_clipboard_set_text (clip, str->str, str->len);
       g_string_free (str, TRUE);
 
-      /* Now fill the selected area with SYSMIS */
-      union value sm ;
-      sm.f = SYSMIS;
+      /* Now fill the selected area with SYSMIS or blanks */
       for (x = sel.start_x ; x <= sel.end_x; ++x)
        {
-         const struct variable * var = psppire_dict_get_variable (dict, x);
+         const struct variable *var = psppire_dict_get_variable (dict, x);
+          int width = var_get_width (var);
+          union value sm ;
+          value_init (&sm, width);
+          if (var_is_numeric (var))
+            sm.f = SYSMIS;
+          else
+            memset (sm.s, 0, width);
          for (y = sel.start_y ; y <= sel.end_y; ++y)
            {
              psppire_data_store_set_value (dw->data_editor->data_store,
                                            y,
                                            var, &sm);
            }
+          value_destroy (&sm, width);
        }
-
     }
 }
 
@@ -1230,7 +1218,7 @@ create_file_menu (PsppireDataWindow *dw)
   }
 
   GtkWidget *open = gtk_menu_item_new_with_mnemonic (_("_Open"));
-  connect_action_to_menuitem (G_ACTION_MAP (dw), "open", open, "<Ctrl>O");
+  connect_action_to_menuitem (G_ACTION_MAP (dw), "open", open, "<Primary>O");
 
   GtkWidget *import = gtk_menu_item_new_with_mnemonic (_("_Import Data..."));
   connect_action_to_menuitem (G_ACTION_MAP (dw), "file-import", import, 0);
@@ -1241,10 +1229,10 @@ create_file_menu (PsppireDataWindow *dw)
   gtk_menu_attach (GTK_MENU (menu), gtk_separator_menu_item_new (), 0, 1, 3, 4);
 
   GtkWidget *save = gtk_menu_item_new_with_mnemonic (_("_Save..."));
-  connect_action_to_menuitem (G_ACTION_MAP (dw), "save", save, "<Ctrl>S");
+  connect_action_to_menuitem (G_ACTION_MAP (dw), "save", save, "<Primary>S");
 
   GtkWidget *save_as = gtk_menu_item_new_with_mnemonic (_("Save _As..."));
-  connect_action_to_menuitem (G_ACTION_MAP (dw), "save-as", save_as, "<Shift><Ctrl>S");
+  connect_action_to_menuitem (G_ACTION_MAP (dw), "save-as", save_as, "<Shift><Primary>S");
 
   GtkWidget *rename_dataset = gtk_menu_item_new_with_mnemonic (_("_Rename Dataset..."));
   connect_action_to_menuitem (G_ACTION_MAP (dw), "rename-dataset", rename_dataset, 0);
@@ -1328,7 +1316,7 @@ create_file_menu (PsppireDataWindow *dw)
     gtk_menu_attach (GTK_MENU (menu), quit,     0, 1, 13, 14);
 
     connect_action_to_menuitem (G_ACTION_MAP (g_application_get_default ()),
-                               "quit", quit, "<Ctrl>Q");
+                               "quit", quit, "<Primary>Q");
   }
 
   g_object_set (menuitem, "submenu", menu, NULL);
@@ -1367,6 +1355,8 @@ create_edit_menu (PsppireDataWindow *dw)
 
   {
     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;
@@ -1376,20 +1366,23 @@ create_edit_menu (PsppireDataWindow *dw)
     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,
-                               'X', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+                               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,
-                               'C', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+                               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,
-                               'V', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+                               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;
@@ -1463,8 +1456,6 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
 
   dataset_set_callbacks (de->dataset, &cbs, de);
 
-  connect_help (de->builder);
-
   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);
@@ -1660,14 +1651,14 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
       GtkToolItem *ti = gtk_tool_button_new (NULL, "Open");
       g_signal_connect_swapped (ti, "clicked", G_CALLBACK (psppire_window_open), de);
       gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "file-open-data");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-file-open-data");
     }
 
     {
       GtkToolItem *ti = gtk_tool_button_new (NULL, "Save");
       g_signal_connect_swapped (ti, "clicked", G_CALLBACK (psppire_window_save), de);
       gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "file-save-data");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-file-save-data");
     }
 
     gtk_toolbar_insert (GTK_TOOLBAR (hb), gtk_separator_tool_item_new (), idx++);
@@ -1681,7 +1672,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
                                G_CALLBACK (psppire_dialog_action_activate_null), a);
 
       gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_jump_to_variable, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_variable), "edit-go-to-variable");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_variable), "pspp-edit-go-to-variable");
       gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_jump_to_variable), _("Jump to variable"));
     }
 
@@ -1694,7 +1685,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
                                G_CALLBACK (g_action_activate_null), a);
 
       gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_jump_to_case, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_case), "edit-go-to-case");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_jump_to_case), "pspp-edit-go-to-case");
       gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_jump_to_case), _("Jump to a case in the data sheet"));
     }
 
@@ -1708,7 +1699,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
 
 
       gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_find, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_find), "edit-find");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_find), "pspp-edit-find");
       gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_find), _("Search for values in the data"));
     }
 
@@ -1720,7 +1711,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
                                G_CALLBACK (g_action_activate_null), a);
 
       gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_insert_case, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_case), "edit-insert-case");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_case), "pspp-edit-insert-case");
       gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_insert_case), _("Create a new case at the current position"));
     }
 
@@ -1732,7 +1723,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
                                G_CALLBACK (g_action_activate_null), a);
 
       gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_insert_variable, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_variable), "edit-insert-variable");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_insert_variable), "pspp-edit-insert-variable");
       gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_insert_variable), _("Create a new variable at the current position"));
     }
 
@@ -1746,7 +1737,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
       g_signal_connect_swapped (ti, "clicked",
                                G_CALLBACK (psppire_dialog_action_activate_null), a);
       gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "data-split-file");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-data-split-file");
       gtk_widget_set_tooltip_text (GTK_WIDGET (ti), _("Split the active dataset"));
     }
 
@@ -1758,7 +1749,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
       g_signal_connect_swapped (ti, "clicked",
                                G_CALLBACK (psppire_dialog_action_activate_null), a);
       gtk_toolbar_insert (GTK_TOOLBAR (hb), ti, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "data-weight-cases");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (ti), "pspp-data-weight-cases");
       gtk_widget_set_tooltip_text (GTK_WIDGET (ti), _("Weight cases by variable"));
     }
 
@@ -1769,7 +1760,7 @@ psppire_data_window_finish_init (PsppireDataWindow *de,
       g_signal_connect (de->ti_value_labels_button, "toggled",
                        G_CALLBACK (on_labels_button_toggle), de);
       gtk_toolbar_insert (GTK_TOOLBAR (hb), de->ti_value_labels_button, idx++);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_value_labels_button), "view-value-labels");
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (de->ti_value_labels_button), "pspp-view-value-labels");
       gtk_widget_set_tooltip_text (GTK_WIDGET (de->ti_value_labels_button), _("Show/hide value labels"));
     }
   }
@@ -1798,11 +1789,11 @@ psppire_data_window_dispose (GObject *object)
 {
   PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (object);
 
-  if (dw->builder != NULL)
-    {
-      g_object_unref (dw->builder);
-      dw->builder = NULL;
-    }
+  if (dw->dispose_has_run)
+    return;
+  dw->dispose_has_run = TRUE;
+
+  g_object_unref (dw->builder);
 
   if (dw->dict)
     {
@@ -1816,20 +1807,9 @@ psppire_data_window_dispose (GObject *object)
                                             G_CALLBACK (on_split_change), dw);
 
       g_object_unref (dw->dict);
-      dw->dict = NULL;
     }
 
-  if (dw->data_store)
-    {
-      g_object_unref (dw->data_store);
-      dw->data_store = NULL;
-    }
-
-  if (dw->ll.next != NULL)
-    {
-      ll_remove (&dw->ll);
-      dw->ll.next = NULL;
-    }
+  g_object_unref (dw->data_store);
 
   if (G_OBJECT_CLASS (parent_class)->dispose)
     G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -1852,6 +1832,12 @@ psppire_data_window_finalize (GObject *object)
       dataset_destroy (dataset);
     }
 
+  if (dw->ll.next != NULL)
+    {
+      ll_remove (&dw->ll);
+      dw->ll.next = NULL;
+    }
+
   if (G_OBJECT_CLASS (parent_class)->finalize)
     G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -1934,7 +1920,7 @@ psppire_data_window_new (struct dataset *ds)
 bool
 psppire_data_window_is_empty (PsppireDataWindow *dw)
 {
-  return psppire_dict_get_var_cnt (dw->dict) == 0;
+  return psppire_dict_get_n_vars (dw->dict) == 0;
 }