Merge remote-tracking branch 'origin/master' into gtk3
[pspp] / src / ui / gui / psppire-data-sheet.c
index a69a41aa8e1fb067756d3aafe15ce79f92209cb3..dfb7382da5263bb62e2b535a6cdacbcac09662b5 100644 (file)
@@ -337,13 +337,15 @@ on_data_column_editing_started (GtkCellRenderer *cell,
   if (var_has_value_labels (var) && GTK_IS_COMBO_BOX (editable))
     {
       const struct val_labs *labels = var_get_value_labels (var);
-      const struct val_lab *vl;
+      const struct val_lab **vls = val_labs_sorted (labels);
+      size_t n_vls = val_labs_count (labels);
       GtkListStore *list_store;
+      int i;
 
       list_store = gtk_list_store_new (1, G_TYPE_STRING);
-      for (vl = val_labs_first (labels); vl != NULL;
-           vl = val_labs_next (labels, vl))
+      for (i = 0; i < n_vls; ++i)
         {
+          const struct val_lab *vl = vls[i];
           GtkTreeIter iter;
 
           gtk_list_store_append (list_store, &iter);
@@ -351,6 +353,7 @@ on_data_column_editing_started (GtkCellRenderer *cell,
                               0, val_lab_get_label (vl),
                               -1);
         }
+      free (vls);
 
       gtk_combo_box_set_model (GTK_COMBO_BOX (editable),
                                GTK_TREE_MODEL (list_store));
@@ -1203,6 +1206,13 @@ psppire_data_sheet_dispose (GObject *object)
 {
   PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (object);
 
+  if (data_sheet->clip != NULL && data_sheet->on_owner_change_signal != 0)
+    {
+      g_signal_handler_disconnect (data_sheet->clip,
+                                   data_sheet->on_owner_change_signal);
+      data_sheet->on_owner_change_signal = 0;
+    }
+
   if (data_sheet->dispose_has_run)
     return;
 
@@ -1221,14 +1231,19 @@ psppire_data_sheet_dispose (GObject *object)
 static void
 psppire_data_sheet_map (GtkWidget *widget)
 {
-  GtkClipboard *clip;
+  PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (widget);
 
   GTK_WIDGET_CLASS (psppire_data_sheet_parent_class)->map (widget);
 
-  clip = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
-  g_signal_connect (clip, "owner-change", G_CALLBACK (on_owner_change),
-                    widget);
-  on_owner_change (clip, NULL, widget);
+  data_sheet->clip = gtk_widget_get_clipboard (widget,
+                                               GDK_SELECTION_CLIPBOARD);
+  if (data_sheet->on_owner_change_signal)
+    g_signal_handler_disconnect (data_sheet->clip,
+                                 data_sheet->on_owner_change_signal);
+  data_sheet->on_owner_change_signal
+    = g_signal_connect (data_sheet->clip, "owner-change",
+                        G_CALLBACK (on_owner_change), widget);
+  on_owner_change (data_sheet->clip, NULL, widget);
 }
 
 static void
@@ -1690,6 +1705,7 @@ psppire_data_sheet_init (PsppireDataSheet *obj)
 
   obj->scroll_to_bottom_signal = 0;
   obj->scroll_to_right_signal = 0;
+  obj->on_owner_change_signal = 0;
   obj->new_variable_column = NULL;
   obj->container = NULL;
 
@@ -1893,6 +1909,7 @@ on_variable_display_width_changed (PsppireDict *dict, int dict_index,
 
 static void
 on_variable_changed (PsppireDict *dict, int dict_index,
+                    guint what, const struct variable *oldvar,
                      PsppireDataSheet *data_sheet)
 {
   PsppireDataStore *data_store = psppire_data_sheet_get_data_store (data_sheet);
@@ -1905,11 +1922,16 @@ on_variable_changed (PsppireDict *dict, int dict_index,
   g_return_if_fail (data_sheet->data_store != NULL);
   g_return_if_fail (dict == data_sheet->data_store->dict);
 
+
+  if (what & VAR_TRAIT_DISPLAY_WIDTH)
+    on_variable_display_width_changed (dict, dict_index, data_sheet);
+
   column = psppire_data_sheet_find_column_for_variable (data_sheet,
                                                         dict_index);
   if (column == NULL)
     return;
 
+
   var = psppire_dict_get_variable (data_store->dict, dict_index);
   g_return_if_fail (var != NULL);
 
@@ -2029,9 +2051,6 @@ psppire_data_sheet_set_data_store (PsppireDataSheet *data_sheet,
       g_signal_connect (data_store->dict, "variable-changed",
                         G_CALLBACK (on_variable_changed),
                         data_sheet);
-      g_signal_connect (data_store->dict, "variable-display-width-changed",
-                        G_CALLBACK (on_variable_display_width_changed),
-                        data_sheet);
       g_signal_connect (data_store->dict, "variable-inserted",
                         G_CALLBACK (on_variable_inserted), data_sheet);
       g_signal_connect (data_store->dict, "variable-deleted",
@@ -2289,7 +2308,7 @@ psppire_data_sheet_clipboard_set (GtkSelectionData *selection_data,
       g_assert_not_reached ();
     }
 
-  gtk_selection_data_set (selection_data, selection_data->target,
+  gtk_selection_data_set (selection_data, gtk_selection_data_get_target (selection_data),
                          8,
                          (const guchar *) string->str, string->len);
 
@@ -2396,8 +2415,6 @@ psppire_data_sheet_update_primary_selection (PsppireDataSheet *data_sheet,
   clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_PRIMARY);
   g_return_if_fail (clipboard != NULL);
 
-  printf ("owns_primary_selection=%d should_own=%d\n",
-          data_sheet->owns_primary_selection, should_own);
   if (data_sheet->owns_primary_selection && !should_own)
     {
       data_sheet->owns_primary_selection = FALSE;
@@ -2424,13 +2441,13 @@ psppire_data_sheet_clip_received_cb (GtkClipboard *clipboard,
   gint first_column;
   char *c;
 
-  if ( sd->length < 0 )
+  if ( gtk_selection_data_get_length (sd) < 0 )
     return;
 
-  if ( sd->type != gdk_atom_intern ("UTF8_STRING", FALSE))
+  if ( gtk_selection_data_get_data_type (sd) != gdk_atom_intern ("UTF8_STRING", FALSE))
     return;
 
-  c = (char *) sd->data;
+  c = (char *) gtk_selection_data_get_data (sd);
 
   /* Get the starting selected position in the data sheet.  (Possibly we should
      only paste into the selected range if it's larger than one cell?) */
@@ -2444,14 +2461,14 @@ psppire_data_sheet_clip_received_cb (GtkClipboard *clipboard,
   g_return_if_fail (next_row >= 0);
   g_return_if_fail (next_column >= 0);
 
-  while (count < sd->length)
+  while (count < gtk_selection_data_get_length (sd))
     {
       gint row = next_row;
       gint column = next_column;
       struct variable *var;
       char *s = c;
 
-      while (*c != '\t' && *c != '\n' && count < sd->length)
+      while (*c != '\t' && *c != '\n' && count < gtk_selection_data_get_length (sd))
         {
           c++;
           count++;
@@ -2476,23 +2493,40 @@ psppire_data_sheet_clip_received_cb (GtkClipboard *clipboard,
 }
 
 static void
-on_owner_change (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data)
+psppire_data_sheet_targets_received_cb (GtkClipboard *clipboard,
+                                        GdkAtom *atoms,
+                                        gint n_atoms,
+                                        gpointer data)
 {
-  PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (data);
-  gboolean compatible_target = FALSE;
-  GtkAction *action;
+  GtkAction *action = GTK_ACTION (data);
+  gboolean compatible_target;
   gint i;
 
+  compatible_target = FALSE;
   for (i = 0; i < G_N_ELEMENTS (targets); i++)
     {
-      GdkAtom atom = gdk_atom_intern (targets[i].target, TRUE);
-      if (gtk_clipboard_wait_is_target_available (clip, atom))
-        {
-          compatible_target = TRUE;
-          break;
-        }
+      GdkAtom target = gdk_atom_intern (targets[i].target, TRUE);
+      gint j;
+
+      for (j = 0; j < n_atoms; j++)
+        if (target == atoms[j])
+          {
+            compatible_target = TRUE;
+            break;
+          }
     }
 
-  action = get_action_assert (data_sheet->builder, "edit_paste");
   gtk_action_set_sensitive (action, compatible_target);
+  g_object_unref (action);
+}
+
+static void
+on_owner_change (GtkClipboard *clip, GdkEventOwnerChange *event, gpointer data)
+{
+  PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (data);
+  GtkAction *action = get_action_assert (data_sheet->builder, "edit_paste");
+
+  g_object_ref (action);
+  gtk_clipboard_request_targets (clip, psppire_data_sheet_targets_received_cb,
+                                 action);
 }