]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreestore.c
Fixes #136082 and #135265, patch by Morten Welinder.
[~andy/gtk] / gtk / gtktreestore.c
index a3f56cd64fa876eaf26054ce01844b1108cc9007..6f7bf8c84a2eef87fe585dc50796b3a74515a25f 100644 (file)
@@ -17,6 +17,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <config.h>
 #include <string.h>
 #include <gobject/gvaluecollector.h>
 #include "gtktreemodel.h"
@@ -74,6 +75,8 @@ static void gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
 
 
 /* DND interfaces */
+static gboolean real_gtk_tree_store_row_draggable   (GtkTreeDragSource *drag_source,
+                                                  GtkTreePath       *path);
 static gboolean gtk_tree_store_drag_data_delete   (GtkTreeDragSource *drag_source,
                                                   GtkTreePath       *path);
 static gboolean gtk_tree_store_drag_data_get      (GtkTreeDragSource *drag_source,
@@ -231,6 +234,7 @@ gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
 static void
 gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface)
 {
+  iface->row_draggable = real_gtk_tree_store_row_draggable;
   iface->drag_data_delete = gtk_tree_store_drag_data_delete;
   iface->drag_data_get = gtk_tree_store_drag_data_get;
 }
@@ -275,7 +279,10 @@ gtk_tree_store_init (GtkTreeStore *tree_store)
  * @Varargs: all #GType types for the columns, from first to last
  *
  * Creates a new tree store as with @n_columns columns each of the types passed
- * in.  As an example, <literal>gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING,
+ * in.  Note that only types derived from standard GObject fundamental types 
+ * are supported. 
+ *
+ * As an example, <literal>gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING,
  * GDK_TYPE_PIXBUF);</literal> will create a new #GtkTreeStore with three columns, of type
  * <type>int</type>, <type>string</type> and #GdkPixbuf respectively.
  *
@@ -444,7 +451,10 @@ gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
 static gboolean
 node_free (GNode *node, gpointer data)
 {
-  _gtk_tree_data_list_free (node->data, (GType*)data);
+  if (node->data)
+    _gtk_tree_data_list_free (node->data, (GType*)data);
+  node->data = NULL;
+
   return FALSE;
 }
 
@@ -708,7 +718,7 @@ gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
   gint i = 0;
 
   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
-  g_return_val_if_fail (iter == NULL || iter->user_data != NULL, FALSE);
+  g_return_val_if_fail (iter == NULL || iter->user_data != NULL, 0);
 
   if (iter == NULL)
     node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
@@ -836,6 +846,8 @@ gtk_tree_store_real_set_value (GtkTreeStore *tree_store,
          retval = TRUE;
          if (converted)
            g_value_unset (&real_value);
+          if (sort && GTK_TREE_STORE_IS_SORTED (tree_store))
+            gtk_tree_store_sort_iter_changed (tree_store, iter, old_column);
          return retval;
        }
 
@@ -1065,8 +1077,8 @@ gtk_tree_store_remove (GtkTreeStore *tree_store,
   next_node = G_NODE (iter->user_data)->next;
 
   if (G_NODE (iter->user_data)->data)
-    _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
-                             tree_store->column_headers);
+    g_node_traverse (G_NODE (iter->user_data), G_POST_ORDER, G_TRAVERSE_ALL,
+                    -1, node_free, tree_store->column_headers);
 
   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
   g_node_destroy (G_NODE (iter->user_data));
@@ -1537,6 +1549,8 @@ gtk_tree_store_iter_is_valid_helper (GtkTreeIter *iter,
  * Checks if the given iter is a valid iter for this #GtkTreeStore.
  *
  * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
+ *
+ * Since: 2.2
  **/
 gboolean
 gtk_tree_store_iter_is_valid (GtkTreeStore *tree_store,
@@ -1554,6 +1568,12 @@ gtk_tree_store_iter_is_valid (GtkTreeStore *tree_store,
 /* DND */
 
 
+static gboolean real_gtk_tree_store_row_draggable (GtkTreeDragSource *drag_source,
+                                                   GtkTreePath       *path)
+{
+  return TRUE;
+}
+               
 static gboolean
 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
                                  GtkTreePath       *path)
@@ -1735,7 +1755,7 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
           gtk_tree_path_free (parent);
           parent = NULL;
 
-          gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
+          gtk_tree_store_prepend (tree_store,
                                   &dest_iter,
                                   dest_parent_p);
 
@@ -1743,36 +1763,17 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
         }
       else
         {
-          if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
-                                       &dest_iter,
-                                       prev))
+          if (gtk_tree_model_get_iter (tree_model, &dest_iter, prev))
             {
               GtkTreeIter tmp_iter = dest_iter;
 
-             if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_model), "gtk-tree-model-drop-append")))
-               {
-                 GtkTreeIter parent;
-
-                 if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (tree_model), &parent, &tmp_iter))
-                   gtk_tree_store_append (GTK_TREE_STORE (tree_model),
-                                          &dest_iter, &parent);
-                 else
-                   gtk_tree_store_append (GTK_TREE_STORE (tree_model),
-                                          &dest_iter, NULL);
-               }
-             else
-               gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
-                                            &dest_iter,
-                                            NULL,
-                                            &tmp_iter);
-              retval = TRUE;
+              gtk_tree_store_insert_after (tree_store, &dest_iter, NULL,
+                                           &tmp_iter);
 
+              retval = TRUE;
             }
         }
 
-      g_object_set_data (G_OBJECT (tree_model), "gtk-tree-model-drop-append",
-                        NULL);
-
       gtk_tree_path_free (prev);
 
       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
@@ -1891,11 +1892,15 @@ gtk_tree_store_reorder_func (gconstpointer a,
  * gtk_tree_store_reorder:
  * @tree_store: A #GtkTreeStore.
  * @parent: A #GtkTreeIter.
- * @new_order: An integer array indication the new order for the list.
+ * @new_order: an array of integers mapping the new position of each child
+ *      to its old position before the re-ordering,
+ *      i.e. @new_order<literal>[newpos] = oldpos</literal>.
  *
  * Reorders the children of @parent in @tree_store to follow the order
  * indicated by @new_order. Note that this function only works with
  * unsorted stores.
+ *
+ * Since: 2.2
  **/
 void
 gtk_tree_store_reorder (GtkTreeStore *tree_store,
@@ -1931,7 +1936,7 @@ gtk_tree_store_reorder (GtkTreeStore *tree_store,
   node = level;
   for (i = 0; i < length; i++)
     {
-      sort_array[i].offset = new_order[i];
+      sort_array[new_order[i]].offset = i;
       sort_array[i].node = node;
 
       node = node->next;
@@ -1976,6 +1981,8 @@ gtk_tree_store_reorder (GtkTreeStore *tree_store,
  *
  * Swaps @a and @b in the same level of @tree_store. Note that this function
  * only works with unsorted stores.
+ *
+ * Since: 2.2
  **/
 void
 gtk_tree_store_swap (GtkTreeStore *tree_store,
@@ -2093,7 +2100,7 @@ gtk_tree_store_swap (GtkTreeStore *tree_store,
   g_free (order);
 }
 
-/* WARNING: this function is *incredibly* fragily. Please smashtest after
+/* WARNING: this function is *incredibly* fragile. Please smashtest after
  * making changes here.
  *     -Kris
  */
@@ -2317,6 +2324,8 @@ gtk_tree_store_move (GtkTreeStore *tree_store,
          /* after with sibling = NULL prepends */
          g_node_insert_after (parent, NULL, node);
        }
+
+      handle_b = FALSE;
     }
 
   if (handle_b)
@@ -2383,13 +2392,13 @@ gtk_tree_store_move (GtkTreeStore *tree_store,
          order[i] = i;
     }
 
-  path = gtk_tree_path_new ();
-  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
-                                path, NULL, order);
+  if (depth)
+    path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), &parent_iter);
+  else
+    path = gtk_tree_path_new ();
 
-  for (i = 0; i < length; i++)
-    g_print ("%2d ", order[i]);
-  g_print ("\n");
+  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
+                                path, &parent_iter, order);
 
   gtk_tree_path_free (path);
   if (position)
@@ -2413,6 +2422,8 @@ free_paths_and_out:
  * @position should be in the same level. Note that this function only
  * works with unsorted stores. If @position is %NULL, @iter will be
  * moved to the end of the level.
+ *
+ * Since: 2.2
  **/
 void
 gtk_tree_store_move_before (GtkTreeStore *tree_store,
@@ -2432,6 +2443,8 @@ gtk_tree_store_move_before (GtkTreeStore *tree_store,
  * @position should be in the same level. Note that this function only
  * works with unsorted stores. If @position is %NULL, @iter will be moved
  * to the start of the level.
+ *
+ * Since: 2.2
  **/
 void
 gtk_tree_store_move_after (GtkTreeStore *tree_store,
@@ -2512,7 +2525,12 @@ gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
 
   node = parent->children;
   if (node == NULL || node->next == NULL)
-    return;
+    {
+      if (recurse && node && node->children)
+        gtk_tree_store_sort_helper (tree_store, node, TRUE);
+
+      return;
+    }
 
   g_assert (GTK_TREE_STORE_IS_SORTED (tree_store));
 
@@ -2791,7 +2809,7 @@ gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
 
   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
 
-  if (tree_store->sort_column_id == -1)
+  if (tree_store->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
     return FALSE;
 
   if (sort_column_id)
@@ -2816,7 +2834,7 @@ gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
       (tree_store->order == order))
     return;
 
-  if (sort_column_id != -1)
+  if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
     {
       GtkTreeDataSortHeader *header = NULL;
 
@@ -2834,9 +2852,9 @@ gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
   tree_store->sort_column_id = sort_column_id;
   tree_store->order = order;
 
-  gtk_tree_store_sort (tree_store);
-
   gtk_tree_sortable_sort_column_changed (sortable);
+
+  gtk_tree_store_sort (tree_store);
 }
 
 static void
@@ -2883,6 +2901,9 @@ gtk_tree_store_set_sort_func (GtkTreeSortable        *sortable,
   header->func = func;
   header->data = data;
   header->destroy = destroy;
+
+  if (tree_store->sort_column_id == sort_column_id)
+    gtk_tree_store_sort (tree_store);
 }
 
 static void
@@ -2906,6 +2927,9 @@ gtk_tree_store_set_default_sort_func (GtkTreeSortable        *sortable,
   tree_store->default_sort_func = func;
   tree_store->default_sort_data = data;
   tree_store->default_sort_destroy = destroy;
+
+  if (tree_store->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
+    gtk_tree_store_sort (tree_store);
 }
 
 static gboolean
@@ -2933,6 +2957,3 @@ validate_gnode (GNode* node)
       iter = iter->next;
     }
 }
-
-
-