summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Rietveld <kris@gtk.org>2002-11-18 19:33:28 +0000
committerKristian Rietveld <kristian@src.gnome.org>2002-11-18 19:33:28 +0000
commitb977d5af8fe25c58120abe4ab5a966fcd53b4d6f (patch)
tree04ec9ff675317ef6bdbc14dc39701670f3f78b58
parentd95f3da34d041fcdc5ad540814c34e22bf50d573 (diff)
downloadgtk+-b977d5af8fe25c58120abe4ab5a966fcd53b4d6f.tar.gz
modify and free tmp instead of path ... (patch from #97927).
Mon Nov 18 20:42:27 2002 Kristian Rietveld <kris@gtk.org> * gtk/gtktreeview.c (gtk_tree_view_expand_to_path): modify and free tmp instead of path ... (patch from #97927). Mon Nov 18 20:31:20 2002 Kristian Rietveld <kris@gtk.org> * gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_start_editing): only _set_text if celltext->text is not NULL. (#97815, reported and testcase provided by Vitaly Tishkov). Mon Nov 18 20:28:28 2002 Kristian Rietveld <kris@gtk.org> * gtk/gtktreeselection.c (gtk_tree_selection_real_modify_range): also update the anchor_path, makes behaviour consistent with the other selection modification functions. (#96801, reported and testcase provided by Vitaly Tishkov). Mon Nov 18 20:17:56 2002 Kristian Rietveld <kris@gtk.org> Hrm, this fixes up lots of mistakes in my swap/move code ... Some of these mistakes where pointed out by Vitaly Tishkov in bugs #97403, #97404, #97412, #97618. * gtktreestore.[ch]: gtk_tree_store_move is now private, use gtk_tree_store_move_{before,after} instead now. Lots of fixes (more like a rewrite :) in the _move and _swap functions. * gtkliststore.[ch]: likewise.
-rw-r--r--ChangeLog30
-rw-r--r--ChangeLog.pre-2-1030
-rw-r--r--ChangeLog.pre-2-230
-rw-r--r--ChangeLog.pre-2-430
-rw-r--r--ChangeLog.pre-2-630
-rw-r--r--ChangeLog.pre-2-830
-rw-r--r--gtk/gtkcellrenderertext.c3
-rw-r--r--gtk/gtkliststore.c216
-rw-r--r--gtk/gtkliststore.h7
-rw-r--r--gtk/gtktreeselection.c15
-rw-r--r--gtk/gtktreestore.c414
-rw-r--r--gtk/gtktreestore.h7
-rw-r--r--gtk/gtktreeview.c6
13 files changed, 712 insertions, 136 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e862a8b4b..4605dcba00 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+Mon Nov 18 20:42:27 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeview.c (gtk_tree_view_expand_to_path): modify and
+ free tmp instead of path ... (patch from #97927).
+
+Mon Nov 18 20:31:20 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_start_editing):
+ only _set_text if celltext->text is not NULL. (#97815, reported
+ and testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:28:28 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeselection.c (gtk_tree_selection_real_modify_range):
+ also update the anchor_path, makes behaviour consistent with the
+ other selection modification functions. (#96801, reported and
+ testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:17:56 2002 Kristian Rietveld <kris@gtk.org>
+
+ Hrm, this fixes up lots of mistakes in my swap/move code ... Some
+ of these mistakes where pointed out by Vitaly Tishkov in bugs
+ #97403, #97404, #97412, #97618.
+
+ * gtktreestore.[ch]: gtk_tree_store_move is now private, use
+ gtk_tree_store_move_{before,after} instead now. Lots of fixes
+ (more like a rewrite :) in the _move and _swap functions.
+
+ * gtkliststore.[ch]: likewise.
+
2002-11-18 Abigail Brady <morwen@evilmagic.org>
* gtk/gtkimmodule.c: (_gtk_im_module_list): Sort the list of Input
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 4e862a8b4b..4605dcba00 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,33 @@
+Mon Nov 18 20:42:27 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeview.c (gtk_tree_view_expand_to_path): modify and
+ free tmp instead of path ... (patch from #97927).
+
+Mon Nov 18 20:31:20 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_start_editing):
+ only _set_text if celltext->text is not NULL. (#97815, reported
+ and testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:28:28 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeselection.c (gtk_tree_selection_real_modify_range):
+ also update the anchor_path, makes behaviour consistent with the
+ other selection modification functions. (#96801, reported and
+ testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:17:56 2002 Kristian Rietveld <kris@gtk.org>
+
+ Hrm, this fixes up lots of mistakes in my swap/move code ... Some
+ of these mistakes where pointed out by Vitaly Tishkov in bugs
+ #97403, #97404, #97412, #97618.
+
+ * gtktreestore.[ch]: gtk_tree_store_move is now private, use
+ gtk_tree_store_move_{before,after} instead now. Lots of fixes
+ (more like a rewrite :) in the _move and _swap functions.
+
+ * gtkliststore.[ch]: likewise.
+
2002-11-18 Abigail Brady <morwen@evilmagic.org>
* gtk/gtkimmodule.c: (_gtk_im_module_list): Sort the list of Input
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 4e862a8b4b..4605dcba00 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,33 @@
+Mon Nov 18 20:42:27 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeview.c (gtk_tree_view_expand_to_path): modify and
+ free tmp instead of path ... (patch from #97927).
+
+Mon Nov 18 20:31:20 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_start_editing):
+ only _set_text if celltext->text is not NULL. (#97815, reported
+ and testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:28:28 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeselection.c (gtk_tree_selection_real_modify_range):
+ also update the anchor_path, makes behaviour consistent with the
+ other selection modification functions. (#96801, reported and
+ testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:17:56 2002 Kristian Rietveld <kris@gtk.org>
+
+ Hrm, this fixes up lots of mistakes in my swap/move code ... Some
+ of these mistakes where pointed out by Vitaly Tishkov in bugs
+ #97403, #97404, #97412, #97618.
+
+ * gtktreestore.[ch]: gtk_tree_store_move is now private, use
+ gtk_tree_store_move_{before,after} instead now. Lots of fixes
+ (more like a rewrite :) in the _move and _swap functions.
+
+ * gtkliststore.[ch]: likewise.
+
2002-11-18 Abigail Brady <morwen@evilmagic.org>
* gtk/gtkimmodule.c: (_gtk_im_module_list): Sort the list of Input
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 4e862a8b4b..4605dcba00 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,33 @@
+Mon Nov 18 20:42:27 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeview.c (gtk_tree_view_expand_to_path): modify and
+ free tmp instead of path ... (patch from #97927).
+
+Mon Nov 18 20:31:20 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_start_editing):
+ only _set_text if celltext->text is not NULL. (#97815, reported
+ and testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:28:28 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeselection.c (gtk_tree_selection_real_modify_range):
+ also update the anchor_path, makes behaviour consistent with the
+ other selection modification functions. (#96801, reported and
+ testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:17:56 2002 Kristian Rietveld <kris@gtk.org>
+
+ Hrm, this fixes up lots of mistakes in my swap/move code ... Some
+ of these mistakes where pointed out by Vitaly Tishkov in bugs
+ #97403, #97404, #97412, #97618.
+
+ * gtktreestore.[ch]: gtk_tree_store_move is now private, use
+ gtk_tree_store_move_{before,after} instead now. Lots of fixes
+ (more like a rewrite :) in the _move and _swap functions.
+
+ * gtkliststore.[ch]: likewise.
+
2002-11-18 Abigail Brady <morwen@evilmagic.org>
* gtk/gtkimmodule.c: (_gtk_im_module_list): Sort the list of Input
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 4e862a8b4b..4605dcba00 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,33 @@
+Mon Nov 18 20:42:27 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeview.c (gtk_tree_view_expand_to_path): modify and
+ free tmp instead of path ... (patch from #97927).
+
+Mon Nov 18 20:31:20 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_start_editing):
+ only _set_text if celltext->text is not NULL. (#97815, reported
+ and testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:28:28 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeselection.c (gtk_tree_selection_real_modify_range):
+ also update the anchor_path, makes behaviour consistent with the
+ other selection modification functions. (#96801, reported and
+ testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:17:56 2002 Kristian Rietveld <kris@gtk.org>
+
+ Hrm, this fixes up lots of mistakes in my swap/move code ... Some
+ of these mistakes where pointed out by Vitaly Tishkov in bugs
+ #97403, #97404, #97412, #97618.
+
+ * gtktreestore.[ch]: gtk_tree_store_move is now private, use
+ gtk_tree_store_move_{before,after} instead now. Lots of fixes
+ (more like a rewrite :) in the _move and _swap functions.
+
+ * gtkliststore.[ch]: likewise.
+
2002-11-18 Abigail Brady <morwen@evilmagic.org>
* gtk/gtkimmodule.c: (_gtk_im_module_list): Sort the list of Input
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 4e862a8b4b..4605dcba00 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,33 @@
+Mon Nov 18 20:42:27 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeview.c (gtk_tree_view_expand_to_path): modify and
+ free tmp instead of path ... (patch from #97927).
+
+Mon Nov 18 20:31:20 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_start_editing):
+ only _set_text if celltext->text is not NULL. (#97815, reported
+ and testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:28:28 2002 Kristian Rietveld <kris@gtk.org>
+
+ * gtk/gtktreeselection.c (gtk_tree_selection_real_modify_range):
+ also update the anchor_path, makes behaviour consistent with the
+ other selection modification functions. (#96801, reported and
+ testcase provided by Vitaly Tishkov).
+
+Mon Nov 18 20:17:56 2002 Kristian Rietveld <kris@gtk.org>
+
+ Hrm, this fixes up lots of mistakes in my swap/move code ... Some
+ of these mistakes where pointed out by Vitaly Tishkov in bugs
+ #97403, #97404, #97412, #97618.
+
+ * gtktreestore.[ch]: gtk_tree_store_move is now private, use
+ gtk_tree_store_move_{before,after} instead now. Lots of fixes
+ (more like a rewrite :) in the _move and _swap functions.
+
+ * gtkliststore.[ch]: likewise.
+
2002-11-18 Abigail Brady <morwen@evilmagic.org>
* gtk/gtkimmodule.c: (_gtk_im_module_list): Sort the list of Input
diff --git a/gtk/gtkcellrenderertext.c b/gtk/gtkcellrenderertext.c
index 8fa5b41cef..a7490317a0 100644
--- a/gtk/gtkcellrenderertext.c
+++ b/gtk/gtkcellrenderertext.c
@@ -1371,7 +1371,8 @@ gtk_cell_renderer_text_start_editing (GtkCellRenderer *cell,
"has_frame", FALSE,
NULL);
- gtk_entry_set_text (GTK_ENTRY (entry), celltext->text);
+ if (celltext->text)
+ gtk_entry_set_text (GTK_ENTRY (entry), celltext->text);
g_object_set_data_full (G_OBJECT (entry), GTK_CELL_RENDERER_TEXT_PATH, g_strdup (path), g_free);
gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c
index 6ea0c9f8e7..538cbe67c2 100644
--- a/gtk/gtkliststore.c
+++ b/gtk/gtkliststore.c
@@ -109,6 +109,11 @@ static void gtk_list_store_set_default_sort_func (GtkTreeSortable *so
GtkDestroyNotify destroy);
static gboolean gtk_list_store_has_default_sort_func (GtkTreeSortable *sortable);
+static void gtk_list_store_move (GtkListStore *store,
+ GtkTreeIter *iter,
+ GtkTreeIter *path,
+ gboolean before);
+
static GObjectClass *parent_class = NULL;
@@ -1717,7 +1722,7 @@ gtk_list_store_swap (GtkListStore *store,
a_count++;
}
- if (a->user_data == store->root)
+ if (b->user_data == store->root)
prev_b = NULL;
else
{
@@ -1765,32 +1770,77 @@ gtk_list_store_swap (GtkListStore *store,
g_free (order);
}
-/**
- * gtk_list_store_move:
- * @store: A #GtkTreeStore.
- * @iter: A #GtkTreeIter.
- * @position: A #GtkTreePath.
- *
- * Moves @iter in @store to the position before @position. Note that this
- * function only works with unsorted stores.
- **/
-void
+static void
gtk_list_store_move (GtkListStore *store,
GtkTreeIter *iter,
- GtkTreePath *position)
+ GtkTreeIter *position,
+ gboolean before)
{
- GSList *i, *prev = NULL, *new_prev = NULL;
- gint old_pos = 0, j = 0, *order;
- GtkTreePath *path;
+ GtkTreeIter dst_a;
+ GSList *i, *a, *prev = NULL, *tmp;
+ gint new_pos = 0, old_pos = 0, j = 0, *order;
+ GtkTreePath *path, *pos_path = NULL;
g_return_if_fail (GTK_IS_LIST_STORE (store));
g_return_if_fail (!GTK_LIST_STORE_IS_SORTED (store));
g_return_if_fail (VALID_ITER (iter, store));
- g_return_if_fail (position != NULL);
+ if (position)
+ g_return_if_fail (VALID_ITER (position, store));
- if (gtk_tree_path_get_depth (position) != 1)
- return;
+ /* lots of sanity checks */
+ if (position)
+ {
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
+ pos_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), position);
+
+ if (gtk_tree_path_get_depth (pos_path) != 1)
+ goto free_paths_and_out;
+
+ /* if before:
+ * moving the iter before path or "path + 1" doesn't make sense
+ * else
+ * moving the iter before path or "path - 1" doesn't make sense
+ */
+ if (!gtk_tree_path_compare (path, pos_path))
+ goto free_paths_and_out;
+
+ if (before)
+ gtk_tree_path_next (path);
+ else
+ gtk_tree_path_prev (path);
+
+ if (!gtk_tree_path_compare (path, pos_path))
+ goto free_paths_and_out;
+
+ gtk_tree_path_free (path);
+ }
+ /* getting destination iters */
+ if (before && position)
+ {
+ if (gtk_tree_path_get_indices (pos_path)[0] > 0)
+ {
+ gtk_tree_path_prev (pos_path);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &dst_a, pos_path))
+ a = G_SLIST (dst_a.user_data);
+ else
+ a = NULL;
+ gtk_tree_path_next (pos_path);
+ }
+ else
+ a = NULL;
+ }
+ else if (before && !position)
+ a = NULL;
+ else /* !before */
+ {
+ if (position)
+ a = G_SLIST (position->user_data);
+ else
+ a = NULL;
+ }
+
+ /* getting the old prev node */
if (iter->user_data == store->root)
prev = NULL;
else
@@ -1805,54 +1855,126 @@ gtk_list_store_move (GtkListStore *store,
old_pos++;
}
- if (old_pos == gtk_tree_path_get_indices (position)[0])
- return;
-
- if (gtk_tree_path_get_indices (position)[0] == 0)
- new_prev = NULL;
- else
- {
- for (i = store->root; i; i = i->next, j++)
- if (j == gtk_tree_path_get_indices (position)[0] - 1)
- {
- new_prev = i;
- break;
- }
- }
-
+ /* remove node */
if (!prev)
store->root = G_SLIST (iter->user_data)->next;
else
prev->next = G_SLIST (iter->user_data)->next;
- if (!new_prev)
+ /* and reinsert it */
+ if (a)
{
- G_SLIST (iter->user_data)->next = store->root;
+ tmp = a->next;
+
+ a->next = G_SLIST (iter->user_data);
+ a->next->next = tmp;
+ }
+ else if (!a && !before)
+ {
+ tmp = G_SLIST (store->root);
+
store->root = G_SLIST (iter->user_data);
+ G_SLIST (store->root)->next = tmp;
}
- else
+ else if (!a && before)
{
- G_SLIST (iter->user_data)->next = new_prev->next;
- new_prev->next = G_SLIST (iter->user_data);
+ G_SLIST (store->tail)->next = G_SLIST (iter->user_data);
+ G_SLIST (iter->user_data)->next = NULL;
+ store->tail = iter->user_data;
}
/* emit signal */
+ if (position)
+ new_pos = gtk_tree_path_get_indices (pos_path)[0];
+ else if (before)
+ new_pos = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) - 1;
+ else
+ new_pos = 0;
+
+ if (new_pos > old_pos)
+ {
+ if (before)
+ new_pos--;
+ }
+ else
+ {
+ if (!before)
+ new_pos++;
+ }
+
order = g_new (gint, store->length);
- for (j = 0; j < store->length; j++)
- if (j < old_pos)
- order[j] = j;
- else if (j >= old_pos && j < gtk_tree_path_get_indices (position)[0])
- order[j] = j + 1;
- else if (j == gtk_tree_path_get_indices (position)[0])
- order[j] = old_pos;
- else
- order[j] = j;
+ if (new_pos > old_pos)
+ {
+ for (j = 0; j < store->length; j++)
+ if (j < old_pos)
+ order[j] = j;
+ else if (j >= old_pos && j < new_pos)
+ order[j] = j + 1;
+ else if (j == new_pos)
+ order[j] = old_pos;
+ else
+ order[j] = j;
+ }
+ else
+ {
+ for (j = 0; j < store->length; j++)
+ if (j == new_pos)
+ order[j] = old_pos;
+ else if (j > new_pos && j <= old_pos)
+ order[j] = j - 1;
+ else
+ order[j] = j;
+ }
path = gtk_tree_path_new ();
gtk_tree_model_rows_reordered (GTK_TREE_MODEL (store),
path, NULL, order);
gtk_tree_path_free (path);
+ if (position)
+ gtk_tree_path_free (pos_path);
g_free (order);
+
+ return;
+
+free_paths_and_out:
+ gtk_tree_path_free (path);
+ gtk_tree_path_free (pos_path);
+}
+
+/**
+ * gtk_list_store_move_before:
+ * @store: A #GtkListStore.
+ * @iter: A #GtkTreeIter.
+ * @position: A #GtkTreeIter, or %NULL.
+ *
+ * Moves @iter in @store to the position before @position. Note that this
+ * function only works with unsorted stores. If @position is %NULL, @iter
+ * will be moved to the end of the list.
+ **/
+void
+gtk_list_store_move_before (GtkListStore *store,
+ GtkTreeIter *iter,
+ GtkTreeIter *position)
+{
+ gtk_list_store_move (store, iter, position, TRUE);
+}
+
+/**
+ * gtk_list_store_move_after:
+ * @store: A #GtkListStore.
+ * @iter: A #GtkTreeIter.
+ * @position: A #GtkTreeIter, or %NULL.
+ *
+ * Moves @iter in @store to the position after @position. Note that this
+ * function only works with unsorted stores. If @position is %NULL, @iter
+ * will be moved to the start of the list.
+ **/
+void
+gtk_list_store_move_after (GtkListStore *store,
+ GtkTreeIter *iter,
+ GtkTreeIter *position)
+{
+ gtk_list_store_move (store, iter, position, FALSE);
}
/* Sorting */
diff --git a/gtk/gtkliststore.h b/gtk/gtkliststore.h
index 25787e2bae..bb17678aa0 100644
--- a/gtk/gtkliststore.h
+++ b/gtk/gtkliststore.h
@@ -113,9 +113,12 @@ void gtk_list_store_reorder (GtkListStore *store,
void gtk_list_store_swap (GtkListStore *store,
GtkTreeIter *a,
GtkTreeIter *b);
-void gtk_list_store_move (GtkListStore *store,
+void gtk_list_store_move_after (GtkListStore *store,
GtkTreeIter *iter,
- GtkTreePath *position);
+ GtkTreeIter *position);
+void gtk_list_store_move_before (GtkListStore *store,
+ GtkTreeIter *iter,
+ GtkTreeIter *position);
#ifdef __cplusplus
diff --git a/gtk/gtktreeselection.c b/gtk/gtktreeselection.c
index d0239b5891..38d943ebfc 100644
--- a/gtk/gtktreeselection.c
+++ b/gtk/gtktreeselection.c
@@ -1147,6 +1147,7 @@ gtk_tree_selection_real_modify_range (GtkTreeSelection *selection,
{
GtkRBNode *start_node, *end_node;
GtkRBTree *start_tree, *end_tree;
+ GtkTreePath *anchor_path;
gboolean dirty = FALSE;
switch (gtk_tree_path_compare (start_path, end_path))
@@ -1160,6 +1161,7 @@ gtk_tree_selection_real_modify_range (GtkTreeSelection *selection,
start_path,
&end_tree,
&end_node);
+ anchor_path = end_path;
break;
case 0:
_gtk_tree_view_find_node (selection->tree_view,
@@ -1168,6 +1170,7 @@ gtk_tree_selection_real_modify_range (GtkTreeSelection *selection,
&start_node);
end_tree = start_tree;
end_node = start_node;
+ anchor_path = start_path;
break;
case -1:
_gtk_tree_view_find_node (selection->tree_view,
@@ -1178,12 +1181,24 @@ gtk_tree_selection_real_modify_range (GtkTreeSelection *selection,
end_path,
&end_tree,
&end_node);
+ anchor_path = start_path;
break;
}
g_return_val_if_fail (start_node != NULL, FALSE);
g_return_val_if_fail (end_node != NULL, FALSE);
+ if (anchor_path)
+ {
+ if (selection->tree_view->priv->anchor)
+ gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+
+ selection->tree_view->priv->anchor =
+ gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view),
+ selection->tree_view->priv->model,
+ anchor_path);
+ }
+
do
{
dirty |= gtk_tree_selection_real_select_node (selection, start_tree, start_node, (mode == RANGE_SELECT)?TRUE:FALSE);
diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c
index e2304e965d..a3f56cd64f 100644
--- a/gtk/gtktreestore.c
+++ b/gtk/gtktreestore.c
@@ -111,6 +111,11 @@ static gboolean gtk_tree_store_has_default_sort_func (GtkTreeSortable *
static void validate_gnode (GNode *node);
+static void gtk_tree_store_move (GtkTreeStore *tree_store,
+ GtkTreeIter *iter,
+ GtkTreeIter *position,
+ gboolean before);
+
static GObjectClass *parent_class = NULL;
@@ -1978,6 +1983,7 @@ gtk_tree_store_swap (GtkTreeStore *tree_store,
GtkTreeIter *b)
{
GNode *tmp, *node_a, *node_b, *parent_node;
+ GNode *a_prev, *a_next, *b_prev, *b_next;
gint i, a_count, b_count, length, *order;
GtkTreePath *path_a, *path_b;
GtkTreeIter parent;
@@ -2015,8 +2021,26 @@ gtk_tree_store_swap (GtkTreeStore *tree_store,
gtk_tree_path_free (path_b);
+ /* old links which we have to keep around */
+ a_prev = node_a->prev;
+ a_next = node_a->next;
+
+ b_prev = node_b->prev;
+ b_next = node_b->next;
+
+ /* fix up links if the nodes are next to eachother */
+ if (a_prev == node_b)
+ a_prev = node_a;
+ if (a_next == node_b)
+ a_next = node_a;
+
+ if (b_prev == node_a)
+ b_prev = node_b;
+ if (b_next == node_a)
+ b_next = node_b;
+
/* counting nodes */
- tmp = parent_node;
+ tmp = parent_node->children;
i = a_count = b_count = 0;
while (tmp)
{
@@ -2031,29 +2055,27 @@ gtk_tree_store_swap (GtkTreeStore *tree_store,
length = i;
/* hacking the tree */
- if (!node_a->prev)
+ if (!a_prev)
parent_node->children = node_b;
else
- node_a->prev->next = node_b;
+ a_prev->next = node_b;
- if (!node_b->prev)
+ if (a_next)
+ a_next->prev = node_b;
+
+ if (!b_prev)
parent_node->children = node_a;
else
- node_b->prev->next = node_a;
-
- if (node_a->next)
- node_a->next->prev = node_b;
+ b_prev->next = node_a;
- if (node_b->next)
- node_b->next->prev = node_a;
+ if (b_next)
+ b_next->prev = node_a;
- tmp = node_a->next;
- node_a->next = node_b->next;
- node_b->next = tmp;
+ node_a->prev = b_prev;
+ node_a->next = b_next;
- tmp = node_a->prev;
- node_a->prev = node_b->prev;
- node_b->prev = tmp;
+ node_b->prev = a_prev;
+ node_b->next = a_next;
/* emit signal */
order = g_new (gint, length);
@@ -2071,74 +2093,168 @@ gtk_tree_store_swap (GtkTreeStore *tree_store,
g_free (order);
}
-/**
- * gtk_tree_store_move:
- * @tree_store: A #GtkTreeStore.
- * @iter: A #GtkTreeIter.
- * @position: A #GtkTreePath.
- *
- * Moves @iter in @tree_store to the position before @position. @iter and
- * @position should be in the same level. Note that this function only
- * works with unsorted stores.
- **/
-void
+/* WARNING: this function is *incredibly* fragily. Please smashtest after
+ * making changes here.
+ * -Kris
+ */
+static void
gtk_tree_store_move (GtkTreeStore *tree_store,
- GtkTreeIter *iter,
- GtkTreePath *position)
+ GtkTreeIter *iter,
+ GtkTreeIter *position,
+ gboolean before)
{
- GNode *tmp, *new_prev, *new_next, *old_prev, *old_next;
+ GNode *parent, *node, *a, *b, *tmp, *tmp_a, *tmp_b;
gint old_pos, new_pos, length, i, *order;
- GtkTreePath *path, *tmppath;
- GtkTreeIter parent, new_iter;
+ GtkTreePath *path = NULL, *tmppath, *pos_path = NULL;
+ GtkTreeIter parent_iter, dst_a, dst_b;
+ gint depth = 0;
+ gboolean handle_b = TRUE;
g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
g_return_if_fail (!GTK_TREE_STORE_IS_SORTED (tree_store));
g_return_if_fail (VALID_ITER (iter, tree_store));
- g_return_if_fail (position != NULL);
+ if (position)
+ g_return_if_fail (VALID_ITER (position, tree_store));
+
+ a = b = NULL;
/* sanity checks */
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
+ if (position)
+ {
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
+ pos_path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store),
+ position);
+
+ /* if before:
+ * moving the iter before path or "path + 1" doesn't make sense
+ * else
+ * moving the iter before path or "path - 1" doesn't make sense
+ */
+ if (!gtk_tree_path_compare (path, pos_path))
+ goto free_paths_and_out;
+
+ if (before)
+ gtk_tree_path_next (path);
+ else
+ gtk_tree_path_prev (path);
+
+ if (!gtk_tree_path_compare (path, pos_path))
+ goto free_paths_and_out;
+
+ if (before)
+ gtk_tree_path_prev (path);
+ else
+ gtk_tree_path_next (path);
+
+ if (gtk_tree_path_get_depth (path) != gtk_tree_path_get_depth (pos_path))
+ {
+ g_warning ("Given childs are not in the same level\n");
+
+ goto free_paths_and_out;
+ }
+
+ tmppath = gtk_tree_path_copy (pos_path);
+ gtk_tree_path_up (path);
+ gtk_tree_path_up (tmppath);
+
+ if (gtk_tree_path_get_depth (path) > 0 &&
+ gtk_tree_path_compare (path, tmppath))
+ {
+ g_warning ("Given childs are not in the same level\n");
+
+ gtk_tree_path_free (tmppath);
+ goto free_paths_and_out;
+ }
- if (!gtk_tree_path_compare (path, position))
+ gtk_tree_path_free (tmppath);
+ }
+
+ if (!path)
{
- gtk_tree_path_free (path);
- return;
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
+ gtk_tree_path_up (path);
}
- if (gtk_tree_path_get_depth (path) != gtk_tree_path_get_depth (position))
+ depth = gtk_tree_path_get_depth (path);
+
+ if (depth)
{
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_store), &parent_iter, path);
gtk_tree_path_free (path);
- g_warning ("Given childs are not in the same level\n");
- return;
+ parent = G_NODE (parent_iter.user_data);
}
+ else
+ parent = G_NODE (tree_store->root);
- tmppath = gtk_tree_path_copy (position);
- gtk_tree_path_up (path);
- gtk_tree_path_up (tmppath);
+ /* yes, I know that this can be done shorter, but I'm doing it this way
+ * so the code is also maintainable
+ */
- if (gtk_tree_path_compare (path, tmppath))
+ if (before && position)
{
- gtk_tree_path_free (path);
- gtk_tree_path_free (tmppath);
+ b = G_NODE (position->user_data);
- g_warning ("Given childs are not in the same level\n");
- return;
- }
+ if (gtk_tree_path_get_indices (pos_path)[gtk_tree_path_get_depth (pos_path) - 1] > 0)
+ {
+ gtk_tree_path_prev (pos_path);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_store), &dst_a, pos_path))
+ a = G_NODE (dst_a.user_data);
+ else
+ a = NULL;
+ gtk_tree_path_next (pos_path);
+ }
- gtk_tree_path_free (tmppath);
- gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_store), &parent, path);
+ /* if b is NULL, a is NULL too -- we are at the beginning of the list
+ * yes and we leak memory here ...
+ */
+ g_return_if_fail (b);
+ }
+ else if (before && !position)
+ {
+ /* move before without position is appending */
+ a = NULL;
+ b = NULL;
+ }
+ else /* !before */
+ {
+ if (position)
+ a = G_NODE (position->user_data);
+ else
+ a = NULL;
- gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_store), &new_iter, position);
+ if (position)
+ {
+ gtk_tree_path_next (pos_path);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_store), &dst_b, pos_path))
+ b = G_NODE (dst_b.user_data);
+ else
+ b = NULL;
+ gtk_tree_path_prev (pos_path);
+ }
+ else
+ {
+ /* move after without position is prepending */
+ if (depth)
+ gtk_tree_model_iter_children (GTK_TREE_MODEL (tree_store), &dst_b,
+ &parent_iter);
+ else
+ gtk_tree_model_iter_children (GTK_TREE_MODEL (tree_store), &dst_b,
+ NULL);
- new_prev = G_NODE (new_iter.user_data)->prev;
- new_next = G_NODE (new_iter.user_data);
+ b = G_NODE (dst_b.user_data);
+ }
- old_prev = G_NODE (iter->user_data)->prev;
- old_next = G_NODE (iter->user_data)->next;
+ /* if a is NULL, a is NULL too -- we are at the end of the list
+ * yes and we leak memory here ...
+ */
+ if (position)
+ g_return_if_fail (a);
+ }
/* counting nodes */
- tmp = G_NODE (parent.user_data);
+ tmp = parent->children;
+
length = old_pos = 0;
while (tmp)
{
@@ -2149,44 +2265,180 @@ gtk_tree_store_move (GtkTreeStore *tree_store,
length++;
}
- /* hacking the tree */
- if (!old_prev)
- G_NODE (parent.user_data)->children = old_next;
+ /* remove node from list */
+ node = G_NODE (iter->user_data);
+ tmp_a = node->prev;
+ tmp_b = node->next;
+
+ if (tmp_a)
+ tmp_a->next = tmp_b;
else
- old_prev->next = old_next;
+ parent->children = tmp_b;
- if (old_next)
- old_next->prev = old_prev;
+ if (tmp_b)
+ tmp_b->prev = tmp_a;
- if (!new_prev)
- G_NODE (parent.user_data)->children = iter->user_data;
- else
- new_prev->next = iter->user_data;
+ /* and reinsert the node */
+ if (a)
+ {
+ tmp = a->next;
+
+ a->next = node;
+ node->next = tmp;
+ node->prev = a;
+ }
+ else if (!a && !before)
+ {
+ tmp = parent->children;
+
+ node->prev = NULL;
+ parent->children = node;
+
+ node->next = tmp;
+ tmp->prev = node;
+
+ handle_b = FALSE;
+ }
+ else if (!a && before)
+ {
+ if (!position)
+ {
+ node->parent = NULL;
+ node->next = node->prev = NULL;
- if (new_next)
- new_next->prev = iter->user_data;
+ /* before with sibling = NULL appends */
+ g_node_insert_before (parent, NULL, node);
+ }
+ else
+ {
+ node->parent = NULL;
+ node->next = node->prev = NULL;
- G_NODE (iter->user_data)->prev = new_prev;
- G_NODE (iter->user_data)->next = new_next;
+ /* after with sibling = NULL prepends */
+ g_node_insert_after (parent, NULL, node);
+ }
+ }
+
+ if (handle_b)
+ {
+ if (b)
+ {
+ tmp = b->prev;
+
+ b->prev = node;
+ node->prev = tmp;
+ node->next = b;
+ }
+ else if (!(!a && before)) /* !a && before is completely handled above */
+ node->next = NULL;
+ }
/* emit signal */
- new_pos = gtk_tree_path_get_indices (position)[gtk_tree_path_get_depth (position)-1];
+ if (position)
+ new_pos = gtk_tree_path_get_indices (pos_path)[gtk_tree_path_get_depth (pos_path)-1];
+ else if (before)
+ {
+ if (depth)
+ new_pos = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree_store),
+ &parent_iter) - 1;
+ else
+ new_pos = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree_store),
+ NULL) - 1;
+ }
+ else
+ new_pos = 0;
+
+ if (new_pos > old_pos)
+ {
+ if (before && position)
+ new_pos--;
+ }
+ else
+ {
+ if (!before && position)
+ new_pos++;
+ }
+
order = g_new (gint, length);
- for (i = 0; i < length; i++)
- if (i < old_pos)
- order[i] = i;
- else if (i >= old_pos && i < new_pos)
- order[i] = i + 1;
- else if (i == new_pos)
- order[i] = old_pos;
- else
- order[i] = i;
+ if (new_pos > old_pos)
+ {
+ for (i = 0; i < length; i++)
+ if (i < old_pos)
+ order[i] = i;
+ else if (i >= old_pos && i < new_pos)
+ order[i] = i + 1;
+ else if (i == new_pos)
+ order[i] = old_pos;
+ else
+ order[i] = i;
+ }
+ else
+ {
+ for (i = 0; i < length; i++)
+ if (i == new_pos)
+ order[i] = old_pos;
+ else if (i > new_pos && i <= old_pos)
+ order[i] = i - 1;
+ else
+ order[i] = i;
+ }
path = gtk_tree_path_new ();
gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
path, NULL, order);
+
+ for (i = 0; i < length; i++)
+ g_print ("%2d ", order[i]);
+ g_print ("\n");
+
gtk_tree_path_free (path);
+ if (position)
+ gtk_tree_path_free (pos_path);
g_free (order);
+
+ return;
+
+free_paths_and_out:
+ gtk_tree_path_free (path);
+ gtk_tree_path_free (pos_path);
+}
+
+/**
+ * gtk_tree_store_move_before:
+ * @tree_store: A #GtkTreeStore.
+ * @iter: A #GtkTreeIter.
+ * @position: A #GtkTreeIter or %NULL.
+ *
+ * Moves @iter in @tree_store to the position before @position. @iter and
+ * @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.
+ **/
+void
+gtk_tree_store_move_before (GtkTreeStore *tree_store,
+ GtkTreeIter *iter,
+ GtkTreeIter *position)
+{
+ gtk_tree_store_move (tree_store, iter, position, TRUE);
+}
+
+/**
+ * gtk_tree_store_move_after:
+ * @tree_store: A #GtkTreeStore.
+ * @iter: A #GtkTreeIter.
+ * @position: A #GtkTreeIter.
+ *
+ * Moves @iter in @tree_store to the position after @position. @iter and
+ * @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.
+ **/
+void
+gtk_tree_store_move_after (GtkTreeStore *tree_store,
+ GtkTreeIter *iter,
+ GtkTreeIter *position)
+{
+ gtk_tree_store_move (tree_store, iter, position, FALSE);
}
/* Sorting */
diff --git a/gtk/gtktreestore.h b/gtk/gtktreestore.h
index d8a5f9d297..ed6b50263e 100644
--- a/gtk/gtktreestore.h
+++ b/gtk/gtktreestore.h
@@ -123,9 +123,12 @@ void gtk_tree_store_reorder (GtkTreeStore *tree_store,
void gtk_tree_store_swap (GtkTreeStore *tree_store,
GtkTreeIter *a,
GtkTreeIter *b);
-void gtk_tree_store_move (GtkTreeStore *tree_store,
+void gtk_tree_store_move_before (GtkTreeStore *tree_store,
GtkTreeIter *iter,
- GtkTreePath *position);
+ GtkTreeIter *position);
+void gtk_tree_store_move_after (GtkTreeStore *tree_store,
+ GtkTreeIter *iter,
+ GtkTreeIter *position);
#ifdef __cplusplus
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 831bf705cb..8ebf772f19 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -8946,11 +8946,11 @@ gtk_tree_view_expand_to_path (GtkTreeView *tree_view,
for (i = 0; i < depth; i++)
{
- gtk_tree_path_append_index (path, indices[i]);
- gtk_tree_view_expand_row (tree_view, path, FALSE);
+ gtk_tree_path_append_index (tmp, indices[i]);
+ gtk_tree_view_expand_row (tree_view, tmp, FALSE);
}
- gtk_tree_path_free (path);
+ gtk_tree_path_free (tmp);
}
/* FIXME the bool return values for expand_row and collapse_row are