forked from AuroraMiddleware/gtk
fix bug in here where prev pointer was set to the wrong thing
2001-01-30 Havoc Pennington <hp@redhat.com> * gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in here where prev pointer was set to the wrong thing * gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function (gtk_tree_path_is_descendant): new function * gtk/gtkliststore.c (gtk_list_store_iter_n_children): return cached length (gtk_list_store_get_iter): don't modify iter if we can't get the path. * gtk/gtkliststore.h (struct _GtkListStore): cache the length * gtk/gtktreednd.h: add virtual function row_drop_possible() to GtkTreeDragDest * gtk/gtktreestore.c (copy_node_data): fix varargs type error that was causing segfault * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next pointer to NULL * gtk/gtktreestore.c (gtk_tree_store_append): fix memleak * gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter on returning FALSE (gtk_list_store_iter_children): ditto (gtk_list_store_iter_nth_child): ditto (gtk_list_store_iter_nth_child): ditto (gtk_list_store_iter_parent): ditto * gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail on iter->user_data != NULL instead of silently accepting it. (gtk_tree_store_iter_next): ditto. Also, don't modify iter unless we are returning TRUE. (gtk_tree_store_iter_children): ditto (gtk_tree_store_iter_nth_child): ditto (gtk_tree_store_iter_parent): ditto (gtk_tree_store_insert): remove handling of parent->user_data == NULL, replace with parent == NULL * gtk/gtktreemodel.c (inserted_callback): put some fixes in here, and a comment explaining things * gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest interface support to GtkTreeStore. * gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return FALSE if no prev, fix * gtk/gtktreeview.c (set_source_row): use a row reference (set_dest_row): use a row reference
This commit is contained in:
parent
a8e3c2058d
commit
5cd2993201
55
ChangeLog
55
ChangeLog
@ -1,3 +1,58 @@
|
|||||||
|
2001-01-30 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in
|
||||||
|
here where prev pointer was set to the wrong thing
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function
|
||||||
|
(gtk_tree_path_is_descendant): new function
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_n_children): return
|
||||||
|
cached length
|
||||||
|
(gtk_list_store_get_iter): don't modify iter if we can't get the
|
||||||
|
path.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.h (struct _GtkListStore): cache the length
|
||||||
|
|
||||||
|
* gtk/gtktreednd.h: add virtual function row_drop_possible() to
|
||||||
|
GtkTreeDragDest
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (copy_node_data): fix varargs type error that
|
||||||
|
was causing segfault
|
||||||
|
|
||||||
|
* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next
|
||||||
|
pointer to NULL
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_append): fix memleak
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter
|
||||||
|
on returning FALSE
|
||||||
|
(gtk_list_store_iter_children): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_parent): ditto
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail
|
||||||
|
on iter->user_data != NULL instead of silently accepting it.
|
||||||
|
(gtk_tree_store_iter_next): ditto. Also, don't modify iter unless
|
||||||
|
we are returning TRUE.
|
||||||
|
(gtk_tree_store_iter_children): ditto
|
||||||
|
(gtk_tree_store_iter_nth_child): ditto
|
||||||
|
(gtk_tree_store_iter_parent): ditto
|
||||||
|
(gtk_tree_store_insert): remove handling of parent->user_data ==
|
||||||
|
NULL, replace with parent == NULL
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (inserted_callback): put some fixes in here,
|
||||||
|
and a comment explaining things
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest
|
||||||
|
interface support to GtkTreeStore.
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return
|
||||||
|
FALSE if no prev, fix
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (set_source_row): use a row reference
|
||||||
|
(set_dest_row): use a row reference
|
||||||
|
|
||||||
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
||||||
|
@ -1,3 +1,58 @@
|
|||||||
|
2001-01-30 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in
|
||||||
|
here where prev pointer was set to the wrong thing
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function
|
||||||
|
(gtk_tree_path_is_descendant): new function
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_n_children): return
|
||||||
|
cached length
|
||||||
|
(gtk_list_store_get_iter): don't modify iter if we can't get the
|
||||||
|
path.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.h (struct _GtkListStore): cache the length
|
||||||
|
|
||||||
|
* gtk/gtktreednd.h: add virtual function row_drop_possible() to
|
||||||
|
GtkTreeDragDest
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (copy_node_data): fix varargs type error that
|
||||||
|
was causing segfault
|
||||||
|
|
||||||
|
* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next
|
||||||
|
pointer to NULL
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_append): fix memleak
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter
|
||||||
|
on returning FALSE
|
||||||
|
(gtk_list_store_iter_children): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_parent): ditto
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail
|
||||||
|
on iter->user_data != NULL instead of silently accepting it.
|
||||||
|
(gtk_tree_store_iter_next): ditto. Also, don't modify iter unless
|
||||||
|
we are returning TRUE.
|
||||||
|
(gtk_tree_store_iter_children): ditto
|
||||||
|
(gtk_tree_store_iter_nth_child): ditto
|
||||||
|
(gtk_tree_store_iter_parent): ditto
|
||||||
|
(gtk_tree_store_insert): remove handling of parent->user_data ==
|
||||||
|
NULL, replace with parent == NULL
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (inserted_callback): put some fixes in here,
|
||||||
|
and a comment explaining things
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest
|
||||||
|
interface support to GtkTreeStore.
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return
|
||||||
|
FALSE if no prev, fix
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (set_source_row): use a row reference
|
||||||
|
(set_dest_row): use a row reference
|
||||||
|
|
||||||
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
||||||
|
@ -1,3 +1,58 @@
|
|||||||
|
2001-01-30 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in
|
||||||
|
here where prev pointer was set to the wrong thing
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function
|
||||||
|
(gtk_tree_path_is_descendant): new function
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_n_children): return
|
||||||
|
cached length
|
||||||
|
(gtk_list_store_get_iter): don't modify iter if we can't get the
|
||||||
|
path.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.h (struct _GtkListStore): cache the length
|
||||||
|
|
||||||
|
* gtk/gtktreednd.h: add virtual function row_drop_possible() to
|
||||||
|
GtkTreeDragDest
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (copy_node_data): fix varargs type error that
|
||||||
|
was causing segfault
|
||||||
|
|
||||||
|
* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next
|
||||||
|
pointer to NULL
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_append): fix memleak
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter
|
||||||
|
on returning FALSE
|
||||||
|
(gtk_list_store_iter_children): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_parent): ditto
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail
|
||||||
|
on iter->user_data != NULL instead of silently accepting it.
|
||||||
|
(gtk_tree_store_iter_next): ditto. Also, don't modify iter unless
|
||||||
|
we are returning TRUE.
|
||||||
|
(gtk_tree_store_iter_children): ditto
|
||||||
|
(gtk_tree_store_iter_nth_child): ditto
|
||||||
|
(gtk_tree_store_iter_parent): ditto
|
||||||
|
(gtk_tree_store_insert): remove handling of parent->user_data ==
|
||||||
|
NULL, replace with parent == NULL
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (inserted_callback): put some fixes in here,
|
||||||
|
and a comment explaining things
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest
|
||||||
|
interface support to GtkTreeStore.
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return
|
||||||
|
FALSE if no prev, fix
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (set_source_row): use a row reference
|
||||||
|
(set_dest_row): use a row reference
|
||||||
|
|
||||||
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
||||||
|
@ -1,3 +1,58 @@
|
|||||||
|
2001-01-30 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in
|
||||||
|
here where prev pointer was set to the wrong thing
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function
|
||||||
|
(gtk_tree_path_is_descendant): new function
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_n_children): return
|
||||||
|
cached length
|
||||||
|
(gtk_list_store_get_iter): don't modify iter if we can't get the
|
||||||
|
path.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.h (struct _GtkListStore): cache the length
|
||||||
|
|
||||||
|
* gtk/gtktreednd.h: add virtual function row_drop_possible() to
|
||||||
|
GtkTreeDragDest
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (copy_node_data): fix varargs type error that
|
||||||
|
was causing segfault
|
||||||
|
|
||||||
|
* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next
|
||||||
|
pointer to NULL
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_append): fix memleak
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter
|
||||||
|
on returning FALSE
|
||||||
|
(gtk_list_store_iter_children): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_parent): ditto
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail
|
||||||
|
on iter->user_data != NULL instead of silently accepting it.
|
||||||
|
(gtk_tree_store_iter_next): ditto. Also, don't modify iter unless
|
||||||
|
we are returning TRUE.
|
||||||
|
(gtk_tree_store_iter_children): ditto
|
||||||
|
(gtk_tree_store_iter_nth_child): ditto
|
||||||
|
(gtk_tree_store_iter_parent): ditto
|
||||||
|
(gtk_tree_store_insert): remove handling of parent->user_data ==
|
||||||
|
NULL, replace with parent == NULL
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (inserted_callback): put some fixes in here,
|
||||||
|
and a comment explaining things
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest
|
||||||
|
interface support to GtkTreeStore.
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return
|
||||||
|
FALSE if no prev, fix
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (set_source_row): use a row reference
|
||||||
|
(set_dest_row): use a row reference
|
||||||
|
|
||||||
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
||||||
|
@ -1,3 +1,58 @@
|
|||||||
|
2001-01-30 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in
|
||||||
|
here where prev pointer was set to the wrong thing
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function
|
||||||
|
(gtk_tree_path_is_descendant): new function
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_n_children): return
|
||||||
|
cached length
|
||||||
|
(gtk_list_store_get_iter): don't modify iter if we can't get the
|
||||||
|
path.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.h (struct _GtkListStore): cache the length
|
||||||
|
|
||||||
|
* gtk/gtktreednd.h: add virtual function row_drop_possible() to
|
||||||
|
GtkTreeDragDest
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (copy_node_data): fix varargs type error that
|
||||||
|
was causing segfault
|
||||||
|
|
||||||
|
* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next
|
||||||
|
pointer to NULL
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_append): fix memleak
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter
|
||||||
|
on returning FALSE
|
||||||
|
(gtk_list_store_iter_children): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_parent): ditto
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail
|
||||||
|
on iter->user_data != NULL instead of silently accepting it.
|
||||||
|
(gtk_tree_store_iter_next): ditto. Also, don't modify iter unless
|
||||||
|
we are returning TRUE.
|
||||||
|
(gtk_tree_store_iter_children): ditto
|
||||||
|
(gtk_tree_store_iter_nth_child): ditto
|
||||||
|
(gtk_tree_store_iter_parent): ditto
|
||||||
|
(gtk_tree_store_insert): remove handling of parent->user_data ==
|
||||||
|
NULL, replace with parent == NULL
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (inserted_callback): put some fixes in here,
|
||||||
|
and a comment explaining things
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest
|
||||||
|
interface support to GtkTreeStore.
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return
|
||||||
|
FALSE if no prev, fix
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (set_source_row): use a row reference
|
||||||
|
(set_dest_row): use a row reference
|
||||||
|
|
||||||
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
||||||
|
@ -1,3 +1,58 @@
|
|||||||
|
2001-01-30 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in
|
||||||
|
here where prev pointer was set to the wrong thing
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function
|
||||||
|
(gtk_tree_path_is_descendant): new function
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_n_children): return
|
||||||
|
cached length
|
||||||
|
(gtk_list_store_get_iter): don't modify iter if we can't get the
|
||||||
|
path.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.h (struct _GtkListStore): cache the length
|
||||||
|
|
||||||
|
* gtk/gtktreednd.h: add virtual function row_drop_possible() to
|
||||||
|
GtkTreeDragDest
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (copy_node_data): fix varargs type error that
|
||||||
|
was causing segfault
|
||||||
|
|
||||||
|
* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next
|
||||||
|
pointer to NULL
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_append): fix memleak
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter
|
||||||
|
on returning FALSE
|
||||||
|
(gtk_list_store_iter_children): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_parent): ditto
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail
|
||||||
|
on iter->user_data != NULL instead of silently accepting it.
|
||||||
|
(gtk_tree_store_iter_next): ditto. Also, don't modify iter unless
|
||||||
|
we are returning TRUE.
|
||||||
|
(gtk_tree_store_iter_children): ditto
|
||||||
|
(gtk_tree_store_iter_nth_child): ditto
|
||||||
|
(gtk_tree_store_iter_parent): ditto
|
||||||
|
(gtk_tree_store_insert): remove handling of parent->user_data ==
|
||||||
|
NULL, replace with parent == NULL
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (inserted_callback): put some fixes in here,
|
||||||
|
and a comment explaining things
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest
|
||||||
|
interface support to GtkTreeStore.
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return
|
||||||
|
FALSE if no prev, fix
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (set_source_row): use a row reference
|
||||||
|
(set_dest_row): use a row reference
|
||||||
|
|
||||||
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
||||||
|
@ -1,3 +1,58 @@
|
|||||||
|
2001-01-30 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_insert_before): fix bug in
|
||||||
|
here where prev pointer was set to the wrong thing
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_is_ancestor): new function
|
||||||
|
(gtk_tree_path_is_descendant): new function
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_n_children): return
|
||||||
|
cached length
|
||||||
|
(gtk_list_store_get_iter): don't modify iter if we can't get the
|
||||||
|
path.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.h (struct _GtkListStore): cache the length
|
||||||
|
|
||||||
|
* gtk/gtktreednd.h: add virtual function row_drop_possible() to
|
||||||
|
GtkTreeDragDest
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (copy_node_data): fix varargs type error that
|
||||||
|
was causing segfault
|
||||||
|
|
||||||
|
* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_copy): set next
|
||||||
|
pointer to NULL
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_append): fix memleak
|
||||||
|
|
||||||
|
* gtk/gtkliststore.c (gtk_list_store_iter_next): don't modify iter
|
||||||
|
on returning FALSE
|
||||||
|
(gtk_list_store_iter_children): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_nth_child): ditto
|
||||||
|
(gtk_list_store_iter_parent): ditto
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c (gtk_tree_store_get_path): g_return_if_fail
|
||||||
|
on iter->user_data != NULL instead of silently accepting it.
|
||||||
|
(gtk_tree_store_iter_next): ditto. Also, don't modify iter unless
|
||||||
|
we are returning TRUE.
|
||||||
|
(gtk_tree_store_iter_children): ditto
|
||||||
|
(gtk_tree_store_iter_nth_child): ditto
|
||||||
|
(gtk_tree_store_iter_parent): ditto
|
||||||
|
(gtk_tree_store_insert): remove handling of parent->user_data ==
|
||||||
|
NULL, replace with parent == NULL
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (inserted_callback): put some fixes in here,
|
||||||
|
and a comment explaining things
|
||||||
|
|
||||||
|
* gtk/gtktreestore.c: add GtkTreeDragSource/GtkTreeDragDest
|
||||||
|
interface support to GtkTreeStore.
|
||||||
|
|
||||||
|
* gtk/gtktreemodel.c (gtk_tree_path_prev): didn't properly return
|
||||||
|
FALSE if no prev, fix
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (set_source_row): use a row reference
|
||||||
|
(set_dest_row): use a row reference
|
||||||
|
|
||||||
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
Sat Jan 27 15:52:02 2001 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
* gtk/gtktreeselection.c (gtk_tree_selection_unselect_iter): Fix
|
||||||
|
@ -80,7 +80,20 @@ static gboolean gtk_list_store_drag_data_get (GtkTreeDragSource *drag_sourc
|
|||||||
static gboolean gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
static gboolean gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
||||||
GtkTreePath *dest,
|
GtkTreePath *dest,
|
||||||
GtkSelectionData *selection_data);
|
GtkSelectionData *selection_data);
|
||||||
|
static gboolean gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreeModel *src_model,
|
||||||
|
GtkTreePath *src_path,
|
||||||
|
GtkTreePath *dest_path);
|
||||||
|
static void
|
||||||
|
validate_list_store (GtkListStore *list_store)
|
||||||
|
{
|
||||||
|
if (gtk_debug_flags & GTK_DEBUG_TREE)
|
||||||
|
{
|
||||||
|
g_assert (g_slist_length (list_store->root) == list_store->length);
|
||||||
|
|
||||||
|
g_assert (g_slist_last (list_store->root) == list_store->tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GtkType
|
GtkType
|
||||||
gtk_list_store_get_type (void)
|
gtk_list_store_get_type (void)
|
||||||
@ -210,6 +223,7 @@ static void
|
|||||||
gtk_list_store_drag_dest_init (GtkTreeDragDestIface *iface)
|
gtk_list_store_drag_dest_init (GtkTreeDragDestIface *iface)
|
||||||
{
|
{
|
||||||
iface->drag_data_received = gtk_list_store_drag_data_received;
|
iface->drag_data_received = gtk_list_store_drag_data_received;
|
||||||
|
iface->row_drop_possible = gtk_list_store_row_drop_possible;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -218,6 +232,7 @@ gtk_list_store_init (GtkListStore *list_store)
|
|||||||
list_store->root = NULL;
|
list_store->root = NULL;
|
||||||
list_store->tail = NULL;
|
list_store->tail = NULL;
|
||||||
list_store->stamp = g_random_int ();
|
list_store->stamp = g_random_int ();
|
||||||
|
list_store->length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkListStore *
|
GtkListStore *
|
||||||
@ -323,14 +338,26 @@ gtk_list_store_get_iter (GtkTreeModel *tree_model,
|
|||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
GtkTreePath *path)
|
GtkTreePath *path)
|
||||||
{
|
{
|
||||||
|
GSList *list;
|
||||||
|
gint i;
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
|
g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
|
||||||
g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
|
g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
|
||||||
|
|
||||||
|
i = gtk_tree_path_get_indices (path)[0];
|
||||||
|
|
||||||
|
if (i >= GTK_LIST_STORE (tree_model)->length)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
list = g_slist_nth (G_SLIST (GTK_LIST_STORE (tree_model)->root),
|
||||||
|
i);
|
||||||
|
|
||||||
|
/* If this fails, list_store->length has gotten mangled. */
|
||||||
|
g_assert (list);
|
||||||
|
|
||||||
iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
|
iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
|
||||||
iter->user_data = g_slist_nth (G_SLIST (GTK_LIST_STORE (tree_model)->root),
|
iter->user_data = list;
|
||||||
gtk_tree_path_get_indices (path)[0]);
|
return TRUE;
|
||||||
|
|
||||||
return iter->user_data != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkTreePath *
|
static GtkTreePath *
|
||||||
@ -391,9 +418,13 @@ gtk_list_store_iter_next (GtkTreeModel *tree_model,
|
|||||||
g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
|
g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
|
||||||
g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, FALSE);
|
g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, FALSE);
|
||||||
|
|
||||||
iter->user_data = G_SLIST (iter->user_data)->next;
|
if (G_SLIST (iter->user_data)->next)
|
||||||
|
{
|
||||||
return (iter->user_data != NULL);
|
iter->user_data = G_SLIST (iter->user_data)->next;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -401,18 +432,22 @@ gtk_list_store_iter_children (GtkTreeModel *tree_model,
|
|||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
GtkTreeIter *parent)
|
GtkTreeIter *parent)
|
||||||
{
|
{
|
||||||
|
/* this is a list, nodes have no children */
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
return FALSE;
|
||||||
iter->stamp = 0;
|
|
||||||
iter->user_data = NULL;
|
/* but if parent == NULL we return the list itself as children of the
|
||||||
return FALSE;
|
* "root"
|
||||||
}
|
*/
|
||||||
else
|
|
||||||
|
if (GTK_LIST_STORE (tree_model)->root)
|
||||||
{
|
{
|
||||||
iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
|
iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
|
||||||
iter->user_data = GTK_LIST_STORE (tree_model)->root;
|
iter->user_data = GTK_LIST_STORE (tree_model)->root;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -427,9 +462,9 @@ gtk_list_store_iter_n_children (GtkTreeModel *tree_model,
|
|||||||
GtkTreeIter *iter)
|
GtkTreeIter *iter)
|
||||||
{
|
{
|
||||||
if (iter == NULL)
|
if (iter == NULL)
|
||||||
return g_slist_length (G_SLIST (GTK_LIST_STORE (tree_model)->root));
|
return GTK_LIST_STORE (tree_model)->length;
|
||||||
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -438,24 +473,23 @@ gtk_list_store_iter_nth_child (GtkTreeModel *tree_model,
|
|||||||
GtkTreeIter *parent,
|
GtkTreeIter *parent,
|
||||||
gint n)
|
gint n)
|
||||||
{
|
{
|
||||||
|
GSList *child;
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
|
g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
child = g_slist_nth (G_SLIST (GTK_LIST_STORE (tree_model)->root), n);
|
||||||
|
|
||||||
|
if (child)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (iter->stamp == GTK_LIST_STORE (tree_model)->stamp, FALSE);
|
iter->user_data = child;
|
||||||
iter->stamp = 0;
|
iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
|
||||||
iter->user_data = NULL;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iter->user_data = g_slist_nth (G_SLIST (GTK_LIST_STORE (tree_model)->root), n);
|
|
||||||
if (iter->user_data)
|
|
||||||
iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
|
|
||||||
else
|
else
|
||||||
iter->stamp = 0;
|
return FALSE;
|
||||||
|
|
||||||
return (iter->user_data != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -463,9 +497,6 @@ gtk_list_store_iter_parent (GtkTreeModel *tree_model,
|
|||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
GtkTreeIter *child)
|
GtkTreeIter *child)
|
||||||
{
|
{
|
||||||
iter->stamp = 0;
|
|
||||||
iter->user_data = NULL;
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,11 +705,12 @@ remove_link_saving_prev (GSList *list,
|
|||||||
if (tmp == link)
|
if (tmp == link)
|
||||||
{
|
{
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->next = tmp->next;
|
prev->next = link->next;
|
||||||
if (list == tmp)
|
|
||||||
|
if (list == link)
|
||||||
list = list->next;
|
list = list->next;
|
||||||
|
|
||||||
tmp->next = NULL;
|
link->next = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,6 +741,8 @@ gtk_list_store_remove_silently (GtkListStore *list_store,
|
|||||||
list_store->root = remove_link_saving_prev (G_SLIST (list_store->root),
|
list_store->root = remove_link_saving_prev (G_SLIST (list_store->root),
|
||||||
G_SLIST (iter->user_data),
|
G_SLIST (iter->user_data),
|
||||||
&prev);
|
&prev);
|
||||||
|
|
||||||
|
list_store->length -= 1;
|
||||||
|
|
||||||
if (iter->user_data == list_store->tail)
|
if (iter->user_data == list_store->tail)
|
||||||
list_store->tail = prev;
|
list_store->tail = prev;
|
||||||
@ -725,13 +759,16 @@ gtk_list_store_remove (GtkListStore *list_store,
|
|||||||
|
|
||||||
g_return_if_fail (list_store != NULL);
|
g_return_if_fail (list_store != NULL);
|
||||||
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
|
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
|
||||||
g_return_if_fail (iter->user_data != NULL);
|
g_return_if_fail (iter->user_data != NULL);
|
||||||
|
|
||||||
|
|
||||||
path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
|
path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
|
||||||
|
|
||||||
|
validate_list_store (list_store);
|
||||||
|
|
||||||
gtk_list_store_remove_silently (list_store, iter, path);
|
gtk_list_store_remove_silently (list_store, iter, path);
|
||||||
|
|
||||||
|
validate_list_store (list_store);
|
||||||
|
|
||||||
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
|
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
|
||||||
"deleted",
|
"deleted",
|
||||||
path);
|
path);
|
||||||
@ -753,6 +790,8 @@ insert_after (GtkListStore *list_store,
|
|||||||
/* if list was the tail, the new node is the new tail */
|
/* if list was the tail, the new node is the new tail */
|
||||||
if (sibling == list_store->tail)
|
if (sibling == list_store->tail)
|
||||||
list_store->tail = new_list;
|
list_store->tail = new_list;
|
||||||
|
|
||||||
|
list_store->length += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -789,6 +828,8 @@ gtk_list_store_insert (GtkListStore *list_store,
|
|||||||
|
|
||||||
iter->stamp = list_store->stamp;
|
iter->stamp = list_store->stamp;
|
||||||
iter->user_data = new_list;
|
iter->user_data = new_list;
|
||||||
|
|
||||||
|
validate_list_store (list_store);
|
||||||
|
|
||||||
path = gtk_tree_path_new ();
|
path = gtk_tree_path_new ();
|
||||||
gtk_tree_path_append_index (path, position);
|
gtk_tree_path_append_index (path, position);
|
||||||
@ -819,7 +860,8 @@ gtk_list_store_insert_before (GtkListStore *list_store,
|
|||||||
|
|
||||||
new_list = g_slist_alloc ();
|
new_list = g_slist_alloc ();
|
||||||
|
|
||||||
prev = list = list_store->root;
|
prev = NULL;
|
||||||
|
list = list_store->root;
|
||||||
while (list && list != sibling->user_data)
|
while (list && list != sibling->user_data)
|
||||||
{
|
{
|
||||||
prev = list;
|
prev = list;
|
||||||
@ -854,6 +896,10 @@ gtk_list_store_insert_before (GtkListStore *list_store,
|
|||||||
|
|
||||||
iter->stamp = list_store->stamp;
|
iter->stamp = list_store->stamp;
|
||||||
iter->user_data = new_list;
|
iter->user_data = new_list;
|
||||||
|
|
||||||
|
list_store->length += 1;
|
||||||
|
|
||||||
|
validate_list_store (list_store);
|
||||||
|
|
||||||
path = gtk_tree_path_new ();
|
path = gtk_tree_path_new ();
|
||||||
gtk_tree_path_append_index (path, i);
|
gtk_tree_path_append_index (path, i);
|
||||||
@ -895,6 +941,8 @@ gtk_list_store_insert_after (GtkListStore *list_store,
|
|||||||
|
|
||||||
iter->stamp = list_store->stamp;
|
iter->stamp = list_store->stamp;
|
||||||
iter->user_data = new_list;
|
iter->user_data = new_list;
|
||||||
|
|
||||||
|
validate_list_store (list_store);
|
||||||
|
|
||||||
path = gtk_tree_path_new ();
|
path = gtk_tree_path_new ();
|
||||||
gtk_tree_path_append_index (path, i);
|
gtk_tree_path_append_index (path, i);
|
||||||
@ -923,6 +971,10 @@ gtk_list_store_prepend (GtkListStore *list_store,
|
|||||||
G_SLIST (iter->user_data)->next = G_SLIST (list_store->root);
|
G_SLIST (iter->user_data)->next = G_SLIST (list_store->root);
|
||||||
list_store->root = iter->user_data;
|
list_store->root = iter->user_data;
|
||||||
|
|
||||||
|
list_store->length += 1;
|
||||||
|
|
||||||
|
validate_list_store (list_store);
|
||||||
|
|
||||||
path = gtk_tree_path_new ();
|
path = gtk_tree_path_new ();
|
||||||
gtk_tree_path_append_index (path, 0);
|
gtk_tree_path_append_index (path, 0);
|
||||||
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
|
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
|
||||||
@ -951,6 +1003,10 @@ gtk_list_store_append (GtkListStore *list_store,
|
|||||||
list_store->root = iter->user_data;
|
list_store->root = iter->user_data;
|
||||||
|
|
||||||
list_store->tail = iter->user_data;
|
list_store->tail = iter->user_data;
|
||||||
|
|
||||||
|
list_store->length += 1;
|
||||||
|
|
||||||
|
validate_list_store (list_store);
|
||||||
|
|
||||||
path = gtk_tree_path_new ();
|
path = gtk_tree_path_new ();
|
||||||
gtk_tree_path_append_index (path, i);
|
gtk_tree_path_append_index (path, i);
|
||||||
@ -1037,7 +1093,10 @@ gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
|||||||
if (!gtk_tree_model_get_iter (src_model,
|
if (!gtk_tree_model_get_iter (src_model,
|
||||||
&src_iter,
|
&src_iter,
|
||||||
src_path))
|
src_path))
|
||||||
goto out;
|
{
|
||||||
|
g_print ("can't get source path as iter\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the path to insert _after_ (dest is the path to insert _before_) */
|
/* Get the path to insert _after_ (dest is the path to insert _before_) */
|
||||||
prev = gtk_tree_path_copy (dest);
|
prev = gtk_tree_path_copy (dest);
|
||||||
@ -1051,6 +1110,8 @@ gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
|||||||
&dest_iter);
|
&dest_iter);
|
||||||
|
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
|
|
||||||
|
g_print ("prepending to list\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1063,7 +1124,11 @@ gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
|||||||
&dest_iter,
|
&dest_iter,
|
||||||
&tmp_iter);
|
&tmp_iter);
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
|
|
||||||
|
g_print ("inserting into list\n");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
g_print ("can't get iter to insert after\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_tree_path_free (prev);
|
gtk_tree_path_free (prev);
|
||||||
@ -1111,6 +1176,7 @@ gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
|||||||
/* FIXME maybe add some data targets eventually, or handle text
|
/* FIXME maybe add some data targets eventually, or handle text
|
||||||
* targets in the simple case.
|
* targets in the simple case.
|
||||||
*/
|
*/
|
||||||
|
g_print ("not accepting target\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -1120,3 +1186,29 @@ gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
|||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreeModel *src_model,
|
||||||
|
GtkTreePath *src_path,
|
||||||
|
GtkTreePath *dest_path)
|
||||||
|
{
|
||||||
|
gint *indices;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_LIST_STORE (drag_dest), FALSE);
|
||||||
|
|
||||||
|
if (src_model != GTK_TREE_MODEL (drag_dest))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (gtk_tree_path_get_depth (dest_path) != 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* can drop before any existing node, or before one past any existing. */
|
||||||
|
|
||||||
|
indices = gtk_tree_path_get_indices (dest_path);
|
||||||
|
|
||||||
|
if (indices[0] <= GTK_LIST_STORE (drag_dest)->length)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
@ -45,6 +45,7 @@ struct _GtkListStore
|
|||||||
GSList *tail;
|
GSList *tail;
|
||||||
gint n_columns;
|
gint n_columns;
|
||||||
GType *column_headers;
|
GType *column_headers;
|
||||||
|
gint length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkListStoreClass
|
struct _GtkListStoreClass
|
||||||
|
@ -239,9 +239,12 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list,
|
|||||||
GType type)
|
GType type)
|
||||||
{
|
{
|
||||||
GtkTreeDataList *new_list;
|
GtkTreeDataList *new_list;
|
||||||
|
|
||||||
|
g_return_val_if_fail (list != NULL, NULL);
|
||||||
|
|
||||||
new_list = _gtk_tree_data_list_alloc ();
|
new_list = _gtk_tree_data_list_alloc ();
|
||||||
|
new_list->next = NULL;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case G_TYPE_UINT:
|
case G_TYPE_UINT:
|
||||||
@ -279,3 +282,6 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list,
|
|||||||
|
|
||||||
return new_list;
|
return new_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +155,38 @@ gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest *drag_dest,
|
|||||||
return (* iface->drag_data_received) (drag_dest, dest, selection_data);
|
return (* iface->drag_data_received) (drag_dest, dest, selection_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_tree_drag_dest_drop_possible:
|
||||||
|
* @drag_dest: a #GtkTreeDragDest
|
||||||
|
* @src_model: #GtkTreeModel being dragged from
|
||||||
|
* @src_path: row being dragged
|
||||||
|
* @dest_path: destination row
|
||||||
|
*
|
||||||
|
* Determines whether a drop is possible before the given @dest_path,
|
||||||
|
* at the same depth as @dest_path. i.e., can we drop @src_model such
|
||||||
|
* that it now resides at @dest_path. @dest_path does not have to
|
||||||
|
* exist; the return value will almost certainly be %FALSE if the
|
||||||
|
* parent of @dest_path doesn't exist, though.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if a drop is possible before @dest_path
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gtk_tree_drag_dest_row_drop_possible (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreeModel *src_model,
|
||||||
|
GtkTreePath *src_path,
|
||||||
|
GtkTreePath *dest_path)
|
||||||
|
{
|
||||||
|
GtkTreeDragDestIface *iface = GTK_TREE_DRAG_DEST_GET_IFACE (drag_dest);
|
||||||
|
|
||||||
|
g_return_val_if_fail (iface->row_drop_possible != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_TREE_MODEL (src_model), FALSE);
|
||||||
|
g_return_val_if_fail (src_path != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (dest_path != NULL, FALSE);
|
||||||
|
|
||||||
|
return (* iface->row_drop_possible) (drag_dest, src_model, src_path, dest_path);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct _TreeRowData TreeRowData;
|
typedef struct _TreeRowData TreeRowData;
|
||||||
|
|
||||||
struct _TreeRowData
|
struct _TreeRowData
|
||||||
|
@ -41,11 +41,11 @@ struct _GtkTreeDragSourceIface
|
|||||||
|
|
||||||
/* VTable - not signals */
|
/* VTable - not signals */
|
||||||
|
|
||||||
gboolean (* drag_data_get) (GtkTreeDragSource *dragsource,
|
gboolean (* drag_data_get) (GtkTreeDragSource *drag_source,
|
||||||
GtkTreePath *path,
|
GtkTreePath *path,
|
||||||
GtkSelectionData *selection_data);
|
GtkSelectionData *selection_data);
|
||||||
|
|
||||||
gboolean (* drag_data_delete) (GtkTreeDragSource *dragsource,
|
gboolean (* drag_data_delete) (GtkTreeDragSource *drag_source,
|
||||||
GtkTreePath *path);
|
GtkTreePath *path);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,10 +76,14 @@ struct _GtkTreeDragDestIface
|
|||||||
|
|
||||||
/* VTable - not signals */
|
/* VTable - not signals */
|
||||||
|
|
||||||
gboolean (* drag_data_received) (GtkTreeDragDest *dragdest,
|
gboolean (* drag_data_received) (GtkTreeDragDest *drag_dest,
|
||||||
GtkTreePath *dest,
|
GtkTreePath *dest,
|
||||||
GtkSelectionData *selection_data);
|
GtkSelectionData *selection_data);
|
||||||
|
|
||||||
|
gboolean (* row_drop_possible) (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreeModel *src_model,
|
||||||
|
GtkTreePath *src_path,
|
||||||
|
GtkTreePath *dest_path);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gtk_tree_drag_dest_get_type (void) G_GNUC_CONST;
|
GType gtk_tree_drag_dest_get_type (void) G_GNUC_CONST;
|
||||||
@ -91,6 +95,12 @@ gboolean gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest *drag_dest,
|
|||||||
GtkTreePath *dest,
|
GtkTreePath *dest,
|
||||||
GtkSelectionData *selection_data);
|
GtkSelectionData *selection_data);
|
||||||
|
|
||||||
|
/* Returns TRUE if we can drop before path; path may not exist. */
|
||||||
|
gboolean gtk_tree_drag_dest_row_drop_possible (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreeModel *src_model,
|
||||||
|
GtkTreePath *src_path,
|
||||||
|
GtkTreePath *dest_path);
|
||||||
|
|
||||||
/* The selection data would normally have target type GTK_TREE_MODEL_ROW in this
|
/* The selection data would normally have target type GTK_TREE_MODEL_ROW in this
|
||||||
* case. If the target is wrong these functions return FALSE.
|
* case. If the target is wrong these functions return FALSE.
|
||||||
*/
|
*/
|
||||||
|
@ -322,6 +322,73 @@ gtk_tree_path_compare (const GtkTreePath *a,
|
|||||||
return (a->depth < b->depth?1:-1);
|
return (a->depth < b->depth?1:-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_tree_path_is_ancestor:
|
||||||
|
* @path: a #GtkTreePath
|
||||||
|
* @descendant: another #GtkTreePath
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if @descendant is contained inside @path
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gtk_tree_path_is_ancestor (GtkTreePath *path,
|
||||||
|
GtkTreePath *descendant)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (path != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (descendant != NULL, FALSE);
|
||||||
|
|
||||||
|
/* can't be an ancestor if we're deeper */
|
||||||
|
if (path->depth >= descendant->depth)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < path->depth)
|
||||||
|
{
|
||||||
|
if (path->indices[i] != descendant->indices[i])
|
||||||
|
return FALSE;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_tree_path_is_descendant:
|
||||||
|
* @path: a #GtkTreePath
|
||||||
|
* @ancestor: another #GtkTreePath
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if @ancestor contains @path somewhere below it
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gtk_tree_path_is_descendant (GtkTreePath *path,
|
||||||
|
GtkTreePath *ancestor)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (path != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (ancestor != NULL, FALSE);
|
||||||
|
|
||||||
|
/* can't be a descendant if we're shallower in the tree */
|
||||||
|
if (path->depth <= ancestor->depth)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < ancestor->depth)
|
||||||
|
{
|
||||||
|
if (path->indices[i] != ancestor->indices[i])
|
||||||
|
return FALSE;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_tree_path_next:
|
* gtk_tree_path_next:
|
||||||
* @path: A #GtkTreePath.
|
* @path: A #GtkTreePath.
|
||||||
@ -350,10 +417,10 @@ gtk_tree_path_prev (GtkTreePath *path)
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (path != NULL, FALSE);
|
g_return_val_if_fail (path != NULL, FALSE);
|
||||||
|
|
||||||
if (path->indices[path->depth] == 0)
|
if (path->indices[path->depth - 1] == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
path->indices[path->depth - 1] --;
|
path->indices[path->depth - 1] -= 1;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -437,6 +504,15 @@ inserted_callback (GtkTreeModel *tree_model,
|
|||||||
RowRefList *refs = data;
|
RowRefList *refs = data;
|
||||||
GSList *tmp_list;
|
GSList *tmp_list;
|
||||||
|
|
||||||
|
/* This function corrects the path stored in the reference to
|
||||||
|
* account for an insertion. Note that it's called _after_ the insertion
|
||||||
|
* with the path to the newly-inserted row. Which means that
|
||||||
|
* the inserted path is in a different "coordinate system" than
|
||||||
|
* the old path (e.g. if the inserted path was just before the old path,
|
||||||
|
* then inserted path and old path will be the same, and old path must be
|
||||||
|
* moved down one).
|
||||||
|
*/
|
||||||
|
|
||||||
tmp_list = refs->list;
|
tmp_list = refs->list;
|
||||||
|
|
||||||
while (tmp_list != NULL)
|
while (tmp_list != NULL)
|
||||||
@ -449,40 +525,21 @@ inserted_callback (GtkTreeModel *tree_model,
|
|||||||
|
|
||||||
if (reference->path)
|
if (reference->path)
|
||||||
{
|
{
|
||||||
gint i;
|
|
||||||
gint depth = gtk_tree_path_get_depth (path);
|
gint depth = gtk_tree_path_get_depth (path);
|
||||||
gint *indices = gtk_tree_path_get_indices (path);
|
|
||||||
gint ref_depth = gtk_tree_path_get_depth (reference->path);
|
gint ref_depth = gtk_tree_path_get_depth (reference->path);
|
||||||
gint *ref_indices = gtk_tree_path_get_indices (reference->path);
|
|
||||||
|
if (ref_depth >= depth)
|
||||||
for (i = 0; i < depth && i < ref_depth; i++)
|
|
||||||
{
|
{
|
||||||
if (indices[i] < ref_indices[i])
|
gint *indices = gtk_tree_path_get_indices (path);
|
||||||
{
|
gint *ref_indices = gtk_tree_path_get_indices (reference->path);
|
||||||
/* inserted node was before the referenced row;
|
gint i;
|
||||||
* move referenced path down 1
|
|
||||||
*/
|
|
||||||
ref_indices[i] += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (indices[i] > ref_indices[i])
|
|
||||||
{
|
|
||||||
/* inserted node was past the referenced row */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (i == depth - 1)
|
|
||||||
{
|
|
||||||
/* referenced row or its parent was inserted, this
|
|
||||||
* is possible if you create the path and row reference
|
|
||||||
* before you actually insert the row.
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we didn't break out of the for loop, the inserted path
|
/* This is the depth that might affect us. */
|
||||||
* was a child of the referenced path
|
i = depth - 1;
|
||||||
*/
|
|
||||||
|
if (indices[i] <= ref_indices[i])
|
||||||
|
ref_indices[i] += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_list = g_slist_next (tmp_list);
|
tmp_list = g_slist_next (tmp_list);
|
||||||
@ -497,6 +554,17 @@ deleted_callback (GtkTreeModel *tree_model,
|
|||||||
RowRefList *refs = data;
|
RowRefList *refs = data;
|
||||||
GSList *tmp_list;
|
GSList *tmp_list;
|
||||||
|
|
||||||
|
/* This function corrects the path stored in the reference to
|
||||||
|
* account for an deletion. Note that it's called _after_ the
|
||||||
|
* deletion with the old path of the just-deleted row. Which means
|
||||||
|
* that the deleted path is the same now-defunct "coordinate system"
|
||||||
|
* as the path saved in the reference, which is what we want to fix.
|
||||||
|
*
|
||||||
|
* Note that this is different from the situation in "inserted," so
|
||||||
|
* while you might think you can cut-and-paste between these
|
||||||
|
* functions, it's not going to work. ;-)
|
||||||
|
*/
|
||||||
|
|
||||||
tmp_list = refs->list;
|
tmp_list = refs->list;
|
||||||
|
|
||||||
while (tmp_list != NULL)
|
while (tmp_list != NULL)
|
||||||
@ -509,41 +577,29 @@ deleted_callback (GtkTreeModel *tree_model,
|
|||||||
|
|
||||||
if (reference->path)
|
if (reference->path)
|
||||||
{
|
{
|
||||||
gint i;
|
|
||||||
gint depth = gtk_tree_path_get_depth (path);
|
gint depth = gtk_tree_path_get_depth (path);
|
||||||
gint *indices = gtk_tree_path_get_indices (path);
|
|
||||||
gint ref_depth = gtk_tree_path_get_depth (reference->path);
|
gint ref_depth = gtk_tree_path_get_depth (reference->path);
|
||||||
gint *ref_indices = gtk_tree_path_get_indices (reference->path);
|
|
||||||
|
|
||||||
for (i = 0; i < depth && i < ref_depth; i++)
|
if (ref_depth >= depth)
|
||||||
{
|
{
|
||||||
|
/* Need to adjust path upward */
|
||||||
|
gint *indices = gtk_tree_path_get_indices (path);
|
||||||
|
gint *ref_indices = gtk_tree_path_get_indices (reference->path);
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
i = depth - 1;
|
||||||
if (indices[i] < ref_indices[i])
|
if (indices[i] < ref_indices[i])
|
||||||
|
ref_indices[i] -= 1;
|
||||||
|
else if (indices[i] == ref_indices[i])
|
||||||
{
|
{
|
||||||
/* deleted node was before the referenced row;
|
/* the referenced node itself, or its parent, was
|
||||||
* move referenced path up 1
|
* deleted, mark invalid
|
||||||
*/
|
|
||||||
ref_indices[i] -= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (indices[i] > ref_indices[i])
|
|
||||||
{
|
|
||||||
/* deleted node is past the referenced row */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (i == depth - 1)
|
|
||||||
{
|
|
||||||
/* referenced row or its parent was deleted, mark it
|
|
||||||
* invalid
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gtk_tree_path_free (reference->path);
|
gtk_tree_path_free (reference->path);
|
||||||
reference->path = NULL;
|
reference->path = NULL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we didn't break out of the for loop, the deleted path
|
|
||||||
* was a child of the referenced path
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_list = g_slist_next (tmp_list);
|
tmp_list = g_slist_next (tmp_list);
|
||||||
@ -722,7 +778,6 @@ gtk_tree_iter_free (GtkTreeIter *iter)
|
|||||||
g_return_if_fail (iter != NULL);
|
g_return_if_fail (iter != NULL);
|
||||||
|
|
||||||
g_free (iter);
|
g_free (iter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,6 +134,11 @@ gboolean gtk_tree_path_prev (GtkTreePath *path);
|
|||||||
gboolean gtk_tree_path_up (GtkTreePath *path);
|
gboolean gtk_tree_path_up (GtkTreePath *path);
|
||||||
void gtk_tree_path_down (GtkTreePath *path);
|
void gtk_tree_path_down (GtkTreePath *path);
|
||||||
|
|
||||||
|
gboolean gtk_tree_path_is_ancestor (GtkTreePath *path,
|
||||||
|
GtkTreePath *descendant);
|
||||||
|
gboolean gtk_tree_path_is_descendant (GtkTreePath *path,
|
||||||
|
GtkTreePath *ancestor);
|
||||||
|
|
||||||
/* Row reference (an object that tracks model changes so it refers to the
|
/* Row reference (an object that tracks model changes so it refers to the
|
||||||
* same row always; a path refers to a position, not a fixed row)
|
* same row always; a path refers to a position, not a fixed row)
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "gtktreemodel.h"
|
#include "gtktreemodel.h"
|
||||||
#include "gtktreestore.h"
|
#include "gtktreestore.h"
|
||||||
#include "gtktreedatalist.h"
|
#include "gtktreedatalist.h"
|
||||||
|
#include "gtktreednd.h"
|
||||||
#include "gtksignal.h"
|
#include "gtksignal.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gobject/gvaluecollector.h>
|
#include <gobject/gvaluecollector.h>
|
||||||
@ -40,6 +41,8 @@ static guint tree_store_signals[LAST_SIGNAL] = { 0 };
|
|||||||
static void gtk_tree_store_init (GtkTreeStore *tree_store);
|
static void gtk_tree_store_init (GtkTreeStore *tree_store);
|
||||||
static void gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class);
|
static void gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class);
|
||||||
static void gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
|
static void gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
|
||||||
|
static void gtk_tree_store_drag_source_init(GtkTreeDragSourceIface *iface);
|
||||||
|
static void gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface);
|
||||||
static guint gtk_tree_store_get_flags (GtkTreeModel *tree_model);
|
static guint gtk_tree_store_get_flags (GtkTreeModel *tree_model);
|
||||||
static gint gtk_tree_store_get_n_columns (GtkTreeModel *tree_model);
|
static gint gtk_tree_store_get_n_columns (GtkTreeModel *tree_model);
|
||||||
static GType gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
|
static GType gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
|
||||||
@ -68,6 +71,32 @@ static gboolean gtk_tree_store_iter_parent (GtkTreeModel *tree_mode
|
|||||||
GtkTreeIter *child);
|
GtkTreeIter *child);
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
|
||||||
|
GtkTreePath *path);
|
||||||
|
static gboolean gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
|
||||||
|
GtkTreePath *path,
|
||||||
|
GtkSelectionData *selection_data);
|
||||||
|
static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreePath *dest,
|
||||||
|
GtkSelectionData *selection_data);
|
||||||
|
static gboolean gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreeModel *src_model,
|
||||||
|
GtkTreePath *src_path,
|
||||||
|
GtkTreePath *dest_path);
|
||||||
|
|
||||||
|
static void validate_gnode (GNode *node);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
validate_tree (GtkTreeStore *tree_store)
|
||||||
|
{
|
||||||
|
if (gtk_debug_flags & GTK_DEBUG_TREE)
|
||||||
|
{
|
||||||
|
g_assert (G_NODE (tree_store->root)->parent == NULL);
|
||||||
|
|
||||||
|
validate_gnode (G_NODE (tree_store->root));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GtkType
|
GtkType
|
||||||
gtk_tree_store_get_type (void)
|
gtk_tree_store_get_type (void)
|
||||||
{
|
{
|
||||||
@ -95,10 +124,34 @@ gtk_tree_store_get_type (void)
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const GInterfaceInfo drag_source_info =
|
||||||
|
{
|
||||||
|
(GInterfaceInitFunc) gtk_tree_store_drag_source_init,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GInterfaceInfo drag_dest_info =
|
||||||
|
{
|
||||||
|
(GInterfaceInitFunc) gtk_tree_store_drag_dest_init,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
tree_store_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
|
tree_store_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
|
||||||
|
|
||||||
g_type_add_interface_static (tree_store_type,
|
g_type_add_interface_static (tree_store_type,
|
||||||
GTK_TYPE_TREE_MODEL,
|
GTK_TYPE_TREE_MODEL,
|
||||||
&tree_model_info);
|
&tree_model_info);
|
||||||
|
|
||||||
|
g_type_add_interface_static (tree_store_type,
|
||||||
|
GTK_TYPE_TREE_DRAG_SOURCE,
|
||||||
|
&drag_source_info);
|
||||||
|
g_type_add_interface_static (tree_store_type,
|
||||||
|
GTK_TYPE_TREE_DRAG_DEST,
|
||||||
|
&drag_dest_info);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree_store_type;
|
return tree_store_type;
|
||||||
@ -164,6 +217,20 @@ gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
|
|||||||
iface->iter_parent = gtk_tree_store_iter_parent;
|
iface->iter_parent = gtk_tree_store_iter_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface)
|
||||||
|
{
|
||||||
|
iface->drag_data_delete = gtk_tree_store_drag_data_delete;
|
||||||
|
iface->drag_data_get = gtk_tree_store_drag_data_get;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface)
|
||||||
|
{
|
||||||
|
iface->drag_data_received = gtk_tree_store_drag_data_received;
|
||||||
|
iface->row_drop_possible = gtk_tree_store_row_drop_possible;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_tree_store_init (GtkTreeStore *tree_store)
|
gtk_tree_store_init (GtkTreeStore *tree_store)
|
||||||
{
|
{
|
||||||
@ -242,7 +309,7 @@ gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
|
|||||||
|
|
||||||
/* fulfill the GtkTreeModel requirements */
|
/* fulfill the GtkTreeModel requirements */
|
||||||
/* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node. However,
|
/* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node. However,
|
||||||
* it is not visible to the tree or to the user., and the path "1" refers to the
|
* it is not visible to the tree or to the user., and the path "0" refers to the
|
||||||
* first child of GtkTreeStore::root.
|
* first child of GtkTreeStore::root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -281,13 +348,13 @@ gtk_tree_store_get_path (GtkTreeModel *tree_model,
|
|||||||
GtkTreePath *retval;
|
GtkTreePath *retval;
|
||||||
GNode *tmp_node;
|
GNode *tmp_node;
|
||||||
gint i = 0;
|
gint i = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (tree_model != NULL, NULL);
|
g_return_val_if_fail (tree_model != NULL, NULL);
|
||||||
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
|
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
|
||||||
g_return_val_if_fail (iter != NULL, NULL);
|
g_return_val_if_fail (iter != NULL, NULL);
|
||||||
|
g_return_val_if_fail (iter->user_data != NULL, NULL);
|
||||||
|
|
||||||
if (iter->user_data == NULL)
|
validate_tree ((GtkTreeStore*)tree_model);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
g_assert (G_NODE (iter->user_data)->parent != NULL);
|
g_assert (G_NODE (iter->user_data)->parent != NULL);
|
||||||
|
|
||||||
@ -299,7 +366,8 @@ gtk_tree_store_get_path (GtkTreeModel *tree_model,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GtkTreeIter tmp_iter = *iter;
|
GtkTreeIter tmp_iter = *iter;
|
||||||
tmp_iter.user_data = G_NODE (tmp_iter.user_data)->parent;
|
|
||||||
|
tmp_iter.user_data = G_NODE (iter->user_data)->parent;
|
||||||
|
|
||||||
retval = gtk_tree_store_get_path (tree_model,
|
retval = gtk_tree_store_get_path (tree_model,
|
||||||
&tmp_iter);
|
&tmp_iter);
|
||||||
@ -372,12 +440,15 @@ static gboolean
|
|||||||
gtk_tree_store_iter_next (GtkTreeModel *tree_model,
|
gtk_tree_store_iter_next (GtkTreeModel *tree_model,
|
||||||
GtkTreeIter *iter)
|
GtkTreeIter *iter)
|
||||||
{
|
{
|
||||||
if (iter->user_data == NULL)
|
g_return_val_if_fail (iter->user_data != NULL, FALSE);
|
||||||
|
|
||||||
|
if (G_NODE (iter->user_data)->next)
|
||||||
|
{
|
||||||
|
iter->user_data = G_NODE (iter->user_data)->next;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
iter->user_data = G_NODE (iter->user_data)->next;
|
|
||||||
|
|
||||||
return (iter->user_data != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -385,13 +456,23 @@ gtk_tree_store_iter_children (GtkTreeModel *tree_model,
|
|||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
GtkTreeIter *parent)
|
GtkTreeIter *parent)
|
||||||
{
|
{
|
||||||
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
|
GNode *children;
|
||||||
if (parent)
|
|
||||||
iter->user_data = G_NODE (parent->user_data)->children;
|
|
||||||
else
|
|
||||||
iter->user_data = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
|
|
||||||
|
|
||||||
return iter->user_data != NULL;
|
g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
children = G_NODE (parent->user_data)->children;
|
||||||
|
else
|
||||||
|
children = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
|
||||||
|
|
||||||
|
if (children)
|
||||||
|
{
|
||||||
|
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
|
||||||
|
iter->user_data = children;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -401,6 +482,7 @@ gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
|
|||||||
g_return_val_if_fail (tree_model != NULL, FALSE);
|
g_return_val_if_fail (tree_model != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
|
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
|
||||||
g_return_val_if_fail (iter != NULL, FALSE);
|
g_return_val_if_fail (iter != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (iter->user_data != NULL, FALSE);
|
||||||
|
|
||||||
return G_NODE (iter->user_data)->children != NULL;
|
return G_NODE (iter->user_data)->children != NULL;
|
||||||
}
|
}
|
||||||
@ -414,11 +496,14 @@ gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
|
|||||||
|
|
||||||
g_return_val_if_fail (tree_model != NULL, 0);
|
g_return_val_if_fail (tree_model != NULL, 0);
|
||||||
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
|
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
|
||||||
|
g_return_val_if_fail (iter != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (iter->user_data != NULL, FALSE);
|
||||||
|
|
||||||
if (iter == NULL)
|
if (iter == NULL)
|
||||||
node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
|
node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
|
||||||
else
|
else
|
||||||
node = G_NODE (iter->user_data)->children;
|
node = G_NODE (iter->user_data)->children;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
@ -435,24 +520,27 @@ gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
|
|||||||
gint n)
|
gint n)
|
||||||
{
|
{
|
||||||
GNode *parent_node;
|
GNode *parent_node;
|
||||||
|
GNode *child;
|
||||||
|
|
||||||
g_return_val_if_fail (tree_model != NULL, FALSE);
|
g_return_val_if_fail (tree_model != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
|
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
|
||||||
g_return_val_if_fail (iter != NULL, FALSE);
|
g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
|
||||||
|
|
||||||
if (parent == NULL)
|
if (parent == NULL)
|
||||||
parent_node = GTK_TREE_STORE (tree_model)->root;
|
parent_node = GTK_TREE_STORE (tree_model)->root;
|
||||||
else
|
else
|
||||||
parent_node = parent->user_data;
|
parent_node = parent->user_data;
|
||||||
|
|
||||||
iter->user_data = g_node_nth_child (parent_node, n);
|
child = g_node_nth_child (parent_node, n);
|
||||||
|
|
||||||
if (iter->user_data == NULL)
|
if (child)
|
||||||
iter->stamp = 0;
|
{
|
||||||
|
iter->user_data = child;
|
||||||
|
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
|
return FALSE;
|
||||||
|
|
||||||
return (iter->user_data != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -460,19 +548,23 @@ gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
|
|||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
GtkTreeIter *child)
|
GtkTreeIter *child)
|
||||||
{
|
{
|
||||||
g_assert (G_NODE (child->user_data)->parent != NULL);
|
GNode *parent;
|
||||||
|
|
||||||
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
|
g_return_val_if_fail (iter != NULL, FALSE);
|
||||||
iter->user_data = G_NODE (child->user_data)->parent;
|
g_return_val_if_fail (iter->user_data != NULL, FALSE);
|
||||||
|
|
||||||
if (iter->user_data == GTK_TREE_STORE (tree_model)->root)
|
parent = G_NODE (child->user_data)->parent;
|
||||||
|
|
||||||
|
g_assert (parent != NULL);
|
||||||
|
|
||||||
|
if (parent != GTK_TREE_STORE (tree_model)->root)
|
||||||
{
|
{
|
||||||
iter->stamp = 0;
|
iter->user_data = parent;
|
||||||
iter->user_data = NULL;
|
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -708,22 +800,27 @@ gtk_tree_store_insert (GtkTreeStore *model,
|
|||||||
gint position)
|
gint position)
|
||||||
{
|
{
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
|
GNode *parent_node;
|
||||||
|
|
||||||
g_return_if_fail (model != NULL);
|
g_return_if_fail (model != NULL);
|
||||||
g_return_if_fail (GTK_IS_TREE_STORE (model));
|
g_return_if_fail (GTK_IS_TREE_STORE (model));
|
||||||
|
|
||||||
if (parent->user_data == NULL)
|
if (parent)
|
||||||
parent->user_data = model->root;
|
parent_node = parent->user_data;
|
||||||
|
else
|
||||||
|
parent_node = model->root;
|
||||||
|
|
||||||
iter->stamp = model->stamp;
|
iter->stamp = model->stamp;
|
||||||
iter->user_data = g_node_new (NULL);
|
iter->user_data = g_node_new (NULL);
|
||||||
g_node_insert (G_NODE (parent->user_data), position, G_NODE (iter->user_data));
|
g_node_insert (parent_node, position, G_NODE (iter->user_data));
|
||||||
|
|
||||||
path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
|
path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
|
||||||
gtk_signal_emit_by_name (GTK_OBJECT (model),
|
gtk_signal_emit_by_name (GTK_OBJECT (model),
|
||||||
"inserted",
|
"inserted",
|
||||||
path, iter);
|
path, iter);
|
||||||
gtk_tree_path_free (path);
|
gtk_tree_path_free (path);
|
||||||
|
|
||||||
|
validate_tree ((GtkTreeStore*)model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -733,7 +830,7 @@ gtk_tree_store_insert_before (GtkTreeStore *model,
|
|||||||
GtkTreeIter *sibling)
|
GtkTreeIter *sibling)
|
||||||
{
|
{
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
GNode *parent_node = NULL;
|
GNode *parent_node = NULL;
|
||||||
GNode *new_node;
|
GNode *new_node;
|
||||||
|
|
||||||
g_return_if_fail (model != NULL);
|
g_return_if_fail (model != NULL);
|
||||||
@ -767,6 +864,8 @@ gtk_tree_store_insert_before (GtkTreeStore *model,
|
|||||||
"inserted",
|
"inserted",
|
||||||
path, iter);
|
path, iter);
|
||||||
gtk_tree_path_free (path);
|
gtk_tree_path_free (path);
|
||||||
|
|
||||||
|
validate_tree ((GtkTreeStore*)model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -811,6 +910,8 @@ gtk_tree_store_insert_after (GtkTreeStore *model,
|
|||||||
"inserted",
|
"inserted",
|
||||||
path, iter);
|
path, iter);
|
||||||
gtk_tree_path_free (path);
|
gtk_tree_path_free (path);
|
||||||
|
|
||||||
|
validate_tree ((GtkTreeStore*)model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -861,6 +962,8 @@ gtk_tree_store_prepend (GtkTreeStore *model,
|
|||||||
{
|
{
|
||||||
gtk_tree_store_insert_after (model, iter, parent, NULL);
|
gtk_tree_store_insert_after (model, iter, parent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate_tree ((GtkTreeStore*)model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -873,19 +976,19 @@ gtk_tree_store_append (GtkTreeStore *model,
|
|||||||
g_return_if_fail (model != NULL);
|
g_return_if_fail (model != NULL);
|
||||||
g_return_if_fail (GTK_IS_TREE_STORE (model));
|
g_return_if_fail (GTK_IS_TREE_STORE (model));
|
||||||
g_return_if_fail (iter != NULL);
|
g_return_if_fail (iter != NULL);
|
||||||
|
|
||||||
if (parent == NULL)
|
if (parent == NULL)
|
||||||
parent_node = model->root;
|
parent_node = model->root;
|
||||||
else
|
else
|
||||||
parent_node = parent->user_data;
|
parent_node = parent->user_data;
|
||||||
|
|
||||||
iter->stamp = model->stamp;
|
|
||||||
iter->user_data = g_node_new (NULL);
|
|
||||||
|
|
||||||
if (parent_node->children == NULL)
|
if (parent_node->children == NULL)
|
||||||
{
|
{
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
|
|
||||||
|
iter->stamp = model->stamp;
|
||||||
|
iter->user_data = g_node_new (NULL);
|
||||||
|
|
||||||
g_node_append (parent_node, G_NODE (iter->user_data));
|
g_node_append (parent_node, G_NODE (iter->user_data));
|
||||||
|
|
||||||
if (parent_node != model->root)
|
if (parent_node != model->root)
|
||||||
@ -901,6 +1004,7 @@ gtk_tree_store_append (GtkTreeStore *model,
|
|||||||
{
|
{
|
||||||
path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
|
path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_signal_emit_by_name (GTK_OBJECT (model),
|
gtk_signal_emit_by_name (GTK_OBJECT (model),
|
||||||
"inserted",
|
"inserted",
|
||||||
path,
|
path,
|
||||||
@ -911,6 +1015,8 @@ gtk_tree_store_append (GtkTreeStore *model,
|
|||||||
{
|
{
|
||||||
gtk_tree_store_insert_before (model, iter, parent, NULL);
|
gtk_tree_store_insert_before (model, iter, parent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate_tree ((GtkTreeStore*)model);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -938,3 +1044,309 @@ gtk_tree_store_iter_depth (GtkTreeStore *model,
|
|||||||
|
|
||||||
return g_node_depth (G_NODE (iter->user_data)) - 1;
|
return g_node_depth (G_NODE (iter->user_data)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DND */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
|
||||||
|
GtkTreePath *path)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
|
||||||
|
|
||||||
|
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
|
||||||
|
&iter,
|
||||||
|
path))
|
||||||
|
{
|
||||||
|
g_print ("data_delete deleting tree row\n");
|
||||||
|
gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
|
||||||
|
&iter);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_print ("data_delete path not in tree\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
|
||||||
|
GtkTreePath *path,
|
||||||
|
GtkSelectionData *selection_data)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
|
||||||
|
|
||||||
|
/* Note that we don't need to handle the GTK_TREE_MODEL_ROW
|
||||||
|
* target, because the default handler does it for us, but
|
||||||
|
* we do anyway for the convenience of someone maybe overriding the
|
||||||
|
* default handler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (gtk_selection_data_set_tree_row (selection_data,
|
||||||
|
GTK_TREE_MODEL (drag_source),
|
||||||
|
path))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME handle text targets at least. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_node_data (GtkTreeStore *tree_store,
|
||||||
|
GtkTreeIter *src_iter,
|
||||||
|
GtkTreeIter *dest_iter)
|
||||||
|
{
|
||||||
|
GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
|
||||||
|
GtkTreeDataList *copy_head = NULL;
|
||||||
|
GtkTreeDataList *copy_prev = NULL;
|
||||||
|
GtkTreeDataList *copy_iter = NULL;
|
||||||
|
gint col;
|
||||||
|
|
||||||
|
col = 0;
|
||||||
|
while (dl)
|
||||||
|
{
|
||||||
|
copy_iter = _gtk_tree_data_list_node_copy (dl,
|
||||||
|
tree_store->column_headers[col]);
|
||||||
|
|
||||||
|
g_print ("copied col %d type %s\n", col,
|
||||||
|
g_type_name (tree_store->column_headers[col]));
|
||||||
|
|
||||||
|
if (copy_head == NULL)
|
||||||
|
copy_head = copy_iter;
|
||||||
|
|
||||||
|
if (copy_prev)
|
||||||
|
copy_prev->next = copy_iter;
|
||||||
|
|
||||||
|
copy_prev = copy_iter;
|
||||||
|
|
||||||
|
dl = dl->next;
|
||||||
|
++col;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_NODE (dest_iter->user_data)->data = copy_head;
|
||||||
|
|
||||||
|
gtk_signal_emit_by_name (GTK_OBJECT (tree_store),
|
||||||
|
"changed",
|
||||||
|
NULL, dest_iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recursive_node_copy (GtkTreeStore *tree_store,
|
||||||
|
GtkTreeIter *src_iter,
|
||||||
|
GtkTreeIter *dest_iter)
|
||||||
|
{
|
||||||
|
GtkTreeIter child;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
|
||||||
|
model = GTK_TREE_MODEL (tree_store);
|
||||||
|
|
||||||
|
copy_node_data (tree_store, src_iter, dest_iter);
|
||||||
|
|
||||||
|
if (gtk_tree_model_iter_children (model,
|
||||||
|
&child,
|
||||||
|
src_iter))
|
||||||
|
{
|
||||||
|
/* Need to create children and recurse. Note our
|
||||||
|
* dependence on persistent iterators here.
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
GtkTreeIter copy;
|
||||||
|
|
||||||
|
/* Gee, a really slow algorithm... ;-) FIXME */
|
||||||
|
gtk_tree_store_append (tree_store,
|
||||||
|
©,
|
||||||
|
dest_iter);
|
||||||
|
|
||||||
|
recursive_node_copy (tree_store, &child, ©);
|
||||||
|
}
|
||||||
|
while (gtk_tree_model_iter_next (model, &child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreePath *dest,
|
||||||
|
GtkSelectionData *selection_data)
|
||||||
|
{
|
||||||
|
GtkTreeModel *tree_model;
|
||||||
|
GtkTreeStore *tree_store;
|
||||||
|
GtkTreeModel *src_model = NULL;
|
||||||
|
GtkTreePath *src_path = NULL;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
|
||||||
|
|
||||||
|
tree_model = GTK_TREE_MODEL (drag_dest);
|
||||||
|
tree_store = GTK_TREE_STORE (drag_dest);
|
||||||
|
|
||||||
|
validate_tree (tree_store);
|
||||||
|
|
||||||
|
if (gtk_selection_data_get_tree_row (selection_data,
|
||||||
|
&src_model,
|
||||||
|
&src_path) &&
|
||||||
|
src_model == tree_model)
|
||||||
|
{
|
||||||
|
/* Copy the given row to a new position */
|
||||||
|
GtkTreeIter src_iter;
|
||||||
|
GtkTreeIter dest_iter;
|
||||||
|
GtkTreePath *prev;
|
||||||
|
|
||||||
|
if (!gtk_tree_model_get_iter (src_model,
|
||||||
|
&src_iter,
|
||||||
|
src_path))
|
||||||
|
{
|
||||||
|
g_print ("can't get source path as iter\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the path to insert _after_ (dest is the path to insert _before_) */
|
||||||
|
prev = gtk_tree_path_copy (dest);
|
||||||
|
|
||||||
|
if (!gtk_tree_path_prev (prev))
|
||||||
|
{
|
||||||
|
GtkTreeIter dest_parent;
|
||||||
|
GtkTreePath *parent;
|
||||||
|
GtkTreeIter *dest_parent_p;
|
||||||
|
|
||||||
|
/* dest was the first spot at the current depth; which means
|
||||||
|
* we are supposed to prepend.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Get the parent, NULL if parent is the root */
|
||||||
|
dest_parent_p = NULL;
|
||||||
|
parent = gtk_tree_path_copy (dest);
|
||||||
|
if (gtk_tree_path_up (parent))
|
||||||
|
{
|
||||||
|
gtk_tree_model_get_iter (tree_model,
|
||||||
|
&dest_parent,
|
||||||
|
parent);
|
||||||
|
dest_parent_p = &dest_parent;
|
||||||
|
}
|
||||||
|
gtk_tree_path_free (parent);
|
||||||
|
parent = NULL;
|
||||||
|
|
||||||
|
gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
|
||||||
|
&dest_iter,
|
||||||
|
dest_parent_p);
|
||||||
|
|
||||||
|
retval = TRUE;
|
||||||
|
|
||||||
|
g_print ("prepending to tree\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
|
||||||
|
&dest_iter,
|
||||||
|
prev))
|
||||||
|
{
|
||||||
|
GtkTreeIter tmp_iter = dest_iter;
|
||||||
|
gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
|
||||||
|
&dest_iter,
|
||||||
|
NULL,
|
||||||
|
&tmp_iter);
|
||||||
|
retval = TRUE;
|
||||||
|
|
||||||
|
g_print ("inserting into tree\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_print ("can't get iter to insert after\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_tree_path_free (prev);
|
||||||
|
|
||||||
|
/* If we succeeded in creating dest_iter, walk src_iter tree branch,
|
||||||
|
* duplicating it below dest_iter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
recursive_node_copy (tree_store,
|
||||||
|
&src_iter,
|
||||||
|
&dest_iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME maybe add some data targets eventually, or handle text
|
||||||
|
* targets in the simple case.
|
||||||
|
*/
|
||||||
|
g_print ("not accepting target\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
if (src_path)
|
||||||
|
gtk_tree_path_free (src_path);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
|
||||||
|
GtkTreeModel *src_model,
|
||||||
|
GtkTreePath *src_path,
|
||||||
|
GtkTreePath *dest_path)
|
||||||
|
{
|
||||||
|
/* can only drag to ourselves */
|
||||||
|
if (src_model != GTK_TREE_MODEL (drag_dest))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Can't drop into ourself. */
|
||||||
|
if (gtk_tree_path_is_ancestor (src_path,
|
||||||
|
dest_path))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Can't drop if dest_path's parent doesn't exist */
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkTreePath *tmp = gtk_tree_path_copy (dest_path);
|
||||||
|
|
||||||
|
/* if we can't go up, we know the parent exists, the root
|
||||||
|
* always exists.
|
||||||
|
*/
|
||||||
|
if (gtk_tree_path_up (tmp))
|
||||||
|
{
|
||||||
|
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
|
||||||
|
&iter, tmp))
|
||||||
|
{
|
||||||
|
if (tmp)
|
||||||
|
gtk_tree_path_free (tmp);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp)
|
||||||
|
gtk_tree_path_free (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can otherwise drop anywhere. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
validate_gnode (GNode* node)
|
||||||
|
{
|
||||||
|
GNode *iter;
|
||||||
|
|
||||||
|
iter = node->children;
|
||||||
|
while (iter != NULL)
|
||||||
|
{
|
||||||
|
g_assert (iter->parent == node);
|
||||||
|
if (iter->prev)
|
||||||
|
g_assert (iter->prev->next == iter);
|
||||||
|
validate_gnode (iter);
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4787,37 +4787,71 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view,
|
|||||||
|
|
||||||
/* Drag-and-drop */
|
/* Drag-and-drop */
|
||||||
|
|
||||||
void
|
static void
|
||||||
set_source_row (GdkDragContext *context,
|
set_source_row (GdkDragContext *context,
|
||||||
|
GtkTreeModel *model,
|
||||||
GtkTreePath *source_row)
|
GtkTreePath *source_row)
|
||||||
{
|
{
|
||||||
g_object_set_data_full (G_OBJECT (context),
|
g_object_set_data_full (G_OBJECT (context),
|
||||||
"gtk-tree-view-source-row",
|
"gtk-tree-view-source-row",
|
||||||
source_row ? gtk_tree_path_copy (source_row) : NULL,
|
source_row ? gtk_tree_row_reference_new (model, source_row) : NULL,
|
||||||
(GDestroyNotify) (source_row ? gtk_tree_path_free : NULL));
|
(GDestroyNotify) (source_row ? gtk_tree_row_reference_free : NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkTreePath*
|
static GtkTreePath*
|
||||||
get_source_row (GdkDragContext *context)
|
get_source_row (GdkDragContext *context)
|
||||||
{
|
{
|
||||||
return g_object_get_data (G_OBJECT (context), "gtk-tree-view-source-row");
|
GtkTreeRowReference *ref =
|
||||||
|
g_object_get_data (G_OBJECT (context), "gtk-tree-view-source-row");
|
||||||
|
|
||||||
|
if (ref)
|
||||||
|
return gtk_tree_row_reference_get_path (ref);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
set_dest_row (GdkDragContext *context,
|
set_dest_row (GdkDragContext *context,
|
||||||
|
GtkTreeModel *model,
|
||||||
GtkTreePath *dest_row)
|
GtkTreePath *dest_row)
|
||||||
{
|
{
|
||||||
g_object_set_data_full (G_OBJECT (context),
|
g_object_set_data_full (G_OBJECT (context),
|
||||||
"gtk-tree-view-dest-row",
|
"gtk-tree-view-dest-row",
|
||||||
dest_row ? gtk_tree_path_copy (dest_row) : NULL,
|
dest_row ? gtk_tree_row_reference_new (model, dest_row) : NULL,
|
||||||
(GDestroyNotify) (dest_row ? gtk_tree_path_free : NULL));
|
(GDestroyNotify) (dest_row ? gtk_tree_row_reference_free : NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkTreePath*
|
static GtkTreePath*
|
||||||
get_dest_row (GdkDragContext *context)
|
get_dest_row (GdkDragContext *context)
|
||||||
{
|
{
|
||||||
return g_object_get_data (G_OBJECT (context), "gtk-tree-view-dest-row");
|
GtkTreeRowReference *ref =
|
||||||
|
g_object_get_data (G_OBJECT (context), "gtk-tree-view-dest-row");
|
||||||
|
|
||||||
|
if (ref)
|
||||||
|
return gtk_tree_row_reference_get_path (ref);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get/set whether drag_motion requested the drag data and
|
||||||
|
* drag_data_received should thus not actually insert the data,
|
||||||
|
* since the data doesn't result from a drop.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
set_status_pending (GdkDragContext *context,
|
||||||
|
GdkDragAction suggested_action)
|
||||||
|
{
|
||||||
|
g_object_set_data (G_OBJECT (context),
|
||||||
|
"gtk-tree-view-status-pending",
|
||||||
|
GINT_TO_POINTER (suggested_action));
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkDragAction
|
||||||
|
get_status_pending (GdkDragContext *context)
|
||||||
|
{
|
||||||
|
return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (context),
|
||||||
|
"gtk-tree-view-status-pending"));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _TreeViewDragInfo TreeViewDragInfo;
|
typedef struct _TreeViewDragInfo TreeViewDragInfo;
|
||||||
@ -5234,6 +5268,7 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
|
|||||||
GtkTreePath *path = NULL;
|
GtkTreePath *path = NULL;
|
||||||
gint button;
|
gint button;
|
||||||
gint cell_x, cell_y;
|
gint cell_x, cell_y;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
|
||||||
di = get_info (tree_view);
|
di = get_info (tree_view);
|
||||||
|
|
||||||
@ -5242,12 +5277,17 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
|
|||||||
|
|
||||||
if (tree_view->priv->pressed_button < 0)
|
if (tree_view->priv->pressed_button < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!gtk_drag_check_threshold (GTK_WIDGET (tree_view),
|
if (!gtk_drag_check_threshold (GTK_WIDGET (tree_view),
|
||||||
tree_view->priv->press_start_x,
|
tree_view->priv->press_start_x,
|
||||||
tree_view->priv->press_start_y,
|
tree_view->priv->press_start_y,
|
||||||
event->x, event->y))
|
event->x, event->y))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
model = gtk_tree_view_get_model (tree_view);
|
||||||
|
|
||||||
|
if (model == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
button = tree_view->priv->pressed_button;
|
button = tree_view->priv->pressed_button;
|
||||||
tree_view->priv->pressed_button = -1;
|
tree_view->priv->pressed_button = -1;
|
||||||
@ -5297,7 +5337,7 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
|
|||||||
gdk_pixmap_unref (row_pix);
|
gdk_pixmap_unref (row_pix);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_source_row (context, path);
|
set_source_row (context, model, path);
|
||||||
gtk_tree_path_free (path);
|
gtk_tree_path_free (path);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -5357,7 +5397,7 @@ gtk_tree_view_drag_data_get (GtkWidget *widget,
|
|||||||
gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model),
|
gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model),
|
||||||
source_row,
|
source_row,
|
||||||
selection_data))
|
selection_data))
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
/* If drag_data_get does nothing, try providing row data. */
|
/* If drag_data_get does nothing, try providing row data. */
|
||||||
if (selection_data->target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
|
if (selection_data->target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
|
||||||
@ -5366,6 +5406,9 @@ gtk_tree_view_drag_data_get (GtkWidget *widget,
|
|||||||
model,
|
model,
|
||||||
source_row);
|
source_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
gtk_tree_path_free (source_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5378,13 +5421,14 @@ check_model_dnd (GtkTreeModel *model,
|
|||||||
{
|
{
|
||||||
g_warning ("You must override the default '%s' handler "
|
g_warning ("You must override the default '%s' handler "
|
||||||
"on GtkTreeView when using models that don't support "
|
"on GtkTreeView when using models that don't support "
|
||||||
"the %s interface. The simplest way to do this "
|
"the %s interface and enabling drag-and-drop. The simplest way to do this "
|
||||||
"is to connect to '%s' and call "
|
"is to connect to '%s' and call "
|
||||||
"gtk_signal_emit_stop_by_name() in your signal handler to prevent "
|
"gtk_signal_emit_stop_by_name() in your signal handler to prevent "
|
||||||
"the default handler from running. Look at the source code "
|
"the default handler from running. Look at the source code "
|
||||||
"for the default handler in gtktreeview.c to get an idea what "
|
"for the default handler in gtktreeview.c to get an idea what "
|
||||||
"your handler should do. (gtktreeview.c is in the GTK source "
|
"your handler should do. (gtktreeview.c is in the GTK source "
|
||||||
"code.)",
|
"code.) If you're using GTK from a language other than C, "
|
||||||
|
"there may be a more natural way to override default handlers, e.g. via derivation.",
|
||||||
signal, g_type_name (required_iface), signal);
|
signal, g_type_name (required_iface), signal);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -5404,6 +5448,8 @@ gtk_tree_view_drag_data_delete (GtkWidget *widget,
|
|||||||
tree_view = GTK_TREE_VIEW (widget);
|
tree_view = GTK_TREE_VIEW (widget);
|
||||||
model = gtk_tree_view_get_model (tree_view);
|
model = gtk_tree_view_get_model (tree_view);
|
||||||
|
|
||||||
|
g_print ("data_delete\n");
|
||||||
|
|
||||||
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_SOURCE, "drag_data_delete"))
|
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_SOURCE, "drag_data_delete"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -5414,11 +5460,15 @@ gtk_tree_view_drag_data_delete (GtkWidget *widget,
|
|||||||
|
|
||||||
source_row = get_source_row (context);
|
source_row = get_source_row (context);
|
||||||
|
|
||||||
|
if (source_row == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (model),
|
gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (model),
|
||||||
source_row);
|
source_row);
|
||||||
|
|
||||||
set_source_row (context, NULL);
|
gtk_tree_path_free (source_row);
|
||||||
|
|
||||||
|
set_source_row (context, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -5488,7 +5538,8 @@ set_destination_row (GtkTreeView *tree_view,
|
|||||||
GdkDragContext *context,
|
GdkDragContext *context,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
GdkDragAction *suggested_action)
|
GdkDragAction *suggested_action,
|
||||||
|
GdkAtom *target)
|
||||||
{
|
{
|
||||||
GtkTreePath *path = NULL;
|
GtkTreePath *path = NULL;
|
||||||
GtkTreeViewDropPosition pos;
|
GtkTreeViewDropPosition pos;
|
||||||
@ -5498,6 +5549,7 @@ set_destination_row (GtkTreeView *tree_view,
|
|||||||
GtkTreePath *old_dest_path = NULL;
|
GtkTreePath *old_dest_path = NULL;
|
||||||
|
|
||||||
*suggested_action = 0;
|
*suggested_action = 0;
|
||||||
|
*target = GDK_NONE;
|
||||||
|
|
||||||
widget = GTK_WIDGET (tree_view);
|
widget = GTK_WIDGET (tree_view);
|
||||||
|
|
||||||
@ -5520,8 +5572,8 @@ set_destination_row (GtkTreeView *tree_view,
|
|||||||
return FALSE; /* no longer a drop site */
|
return FALSE; /* no longer a drop site */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't take this target */
|
*target = gtk_drag_dest_find_target (widget, context, di->dest_target_list);
|
||||||
if (gtk_drag_dest_find_target (widget, context, di->dest_target_list) == GDK_NONE)
|
if (*target == GDK_NONE)
|
||||||
{
|
{
|
||||||
g_print ("bad target, not accepting\n");
|
g_print ("bad target, not accepting\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -5608,12 +5660,13 @@ gtk_tree_view_drag_motion (GtkWidget *widget,
|
|||||||
GtkTreeViewDropPosition pos;
|
GtkTreeViewDropPosition pos;
|
||||||
GtkTreeView *tree_view;
|
GtkTreeView *tree_view;
|
||||||
GdkDragAction suggested_action = 0;
|
GdkDragAction suggested_action = 0;
|
||||||
|
GdkAtom target;
|
||||||
|
|
||||||
tree_view = GTK_TREE_VIEW (widget);
|
tree_view = GTK_TREE_VIEW (widget);
|
||||||
|
|
||||||
g_print ("motion\n");
|
g_print ("motion\n");
|
||||||
|
|
||||||
if (!set_destination_row (tree_view, context, x, y, &suggested_action))
|
if (!set_destination_row (tree_view, context, x, y, &suggested_action, &target))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
ensure_scroll_timeout (tree_view);
|
ensure_scroll_timeout (tree_view);
|
||||||
@ -5633,11 +5686,24 @@ gtk_tree_view_drag_motion (GtkWidget *widget,
|
|||||||
pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE))
|
pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE))
|
||||||
{
|
{
|
||||||
tree_view->priv->open_dest_timeout =
|
tree_view->priv->open_dest_timeout =
|
||||||
gtk_timeout_add (250, open_row_timeout, tree_view);
|
gtk_timeout_add (500, open_row_timeout, tree_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("status\n");
|
if (target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
|
||||||
gdk_drag_status (context, suggested_action, time);
|
{
|
||||||
|
/* Request data so we can use the source row when
|
||||||
|
* determining whether to accept the drop
|
||||||
|
*/
|
||||||
|
set_status_pending (context, suggested_action);
|
||||||
|
g_print ("motion requesting the drop data\n");
|
||||||
|
gtk_drag_get_data (widget, context, target, time);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_status_pending (context, 0);
|
||||||
|
g_print ("motion sending positive status\n");
|
||||||
|
gdk_drag_status (context, suggested_action, time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path)
|
if (path)
|
||||||
@ -5646,6 +5712,36 @@ gtk_tree_view_drag_motion (GtkWidget *widget,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GtkTreePath*
|
||||||
|
get_logical_dest_row (GtkTreeView *tree_view)
|
||||||
|
|
||||||
|
{
|
||||||
|
/* adjust path to point to the row the drop goes in front of */
|
||||||
|
GtkTreePath *path = NULL;
|
||||||
|
GtkTreeViewDropPosition pos;
|
||||||
|
|
||||||
|
gtk_tree_view_get_drag_dest_row (tree_view, &path, &pos);
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pos == GTK_TREE_VIEW_DROP_BEFORE)
|
||||||
|
; /* do nothing */
|
||||||
|
else if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE ||
|
||||||
|
pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER)
|
||||||
|
{
|
||||||
|
/* get first child, drop before it */
|
||||||
|
gtk_tree_path_append_index (path, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_assert (pos == GTK_TREE_VIEW_DROP_AFTER);
|
||||||
|
gtk_tree_path_next (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_tree_view_drag_drop (GtkWidget *widget,
|
gtk_tree_view_drag_drop (GtkWidget *widget,
|
||||||
GdkDragContext *context,
|
GdkDragContext *context,
|
||||||
@ -5653,9 +5749,8 @@ gtk_tree_view_drag_drop (GtkWidget *widget,
|
|||||||
gint y,
|
gint y,
|
||||||
guint time)
|
guint time)
|
||||||
{
|
{
|
||||||
GtkTreePath *path = NULL;
|
|
||||||
GtkTreeViewDropPosition pos;
|
|
||||||
GtkTreeView *tree_view;
|
GtkTreeView *tree_view;
|
||||||
|
GtkTreePath *path;
|
||||||
GdkDragAction suggested_action = 0;
|
GdkDragAction suggested_action = 0;
|
||||||
GdkAtom target = GDK_NONE;
|
GdkAtom target = GDK_NONE;
|
||||||
TreeViewDragInfo *di;
|
TreeViewDragInfo *di;
|
||||||
@ -5669,30 +5764,30 @@ gtk_tree_view_drag_drop (GtkWidget *widget,
|
|||||||
|
|
||||||
remove_scroll_timeout (GTK_TREE_VIEW (widget));
|
remove_scroll_timeout (GTK_TREE_VIEW (widget));
|
||||||
remove_open_timeout (GTK_TREE_VIEW (widget));
|
remove_open_timeout (GTK_TREE_VIEW (widget));
|
||||||
|
|
||||||
di = get_info (tree_view);
|
di = get_info (tree_view);
|
||||||
|
|
||||||
if (di == NULL)
|
if (di == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag_drop"))
|
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag_drop"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!set_destination_row (tree_view, context, x, y, &suggested_action))
|
if (!set_destination_row (tree_view, context, x, y, &suggested_action, &target))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
gtk_tree_view_get_drag_dest_row (tree_view, &path, &pos);
|
path = get_logical_dest_row (tree_view);
|
||||||
|
|
||||||
if (path != NULL && di->dest_target_list)
|
if (target != GDK_NONE && path != NULL)
|
||||||
{
|
{
|
||||||
target = gtk_drag_dest_find_target (widget, context, di->dest_target_list);
|
g_print ("have target\n");
|
||||||
|
|
||||||
if (target != GDK_NONE)
|
/* in case a motion had requested drag data, change things so we
|
||||||
{
|
* treat drag data receives as a drop.
|
||||||
g_print ("have target\n");
|
*/
|
||||||
|
set_status_pending (context, 0);
|
||||||
set_dest_row (context, path);
|
|
||||||
}
|
set_dest_row (context, model, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path)
|
if (path)
|
||||||
@ -5722,11 +5817,13 @@ gtk_tree_view_drag_data_received (GtkWidget *widget,
|
|||||||
guint info,
|
guint info,
|
||||||
guint time)
|
guint time)
|
||||||
{
|
{
|
||||||
|
GtkTreePath *path;
|
||||||
TreeViewDragInfo *di;
|
TreeViewDragInfo *di;
|
||||||
gboolean accepted = FALSE;
|
gboolean accepted = FALSE;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
GtkTreeView *tree_view;
|
GtkTreeView *tree_view;
|
||||||
GtkTreePath *dest_row;
|
GtkTreePath *dest_row;
|
||||||
|
GdkDragAction suggested_action;
|
||||||
|
|
||||||
tree_view = GTK_TREE_VIEW (widget);
|
tree_view = GTK_TREE_VIEW (widget);
|
||||||
|
|
||||||
@ -5742,6 +5839,58 @@ gtk_tree_view_drag_data_received (GtkWidget *widget,
|
|||||||
if (di == NULL)
|
if (di == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
suggested_action = get_status_pending (context);
|
||||||
|
|
||||||
|
if (suggested_action)
|
||||||
|
{
|
||||||
|
/* We are getting this data due to a request in drag_motion,
|
||||||
|
* rather than due to a request in drag_drop, so we are just
|
||||||
|
* supposed to call drag_status, not actually paste in the
|
||||||
|
* data.
|
||||||
|
*/
|
||||||
|
path = get_logical_dest_row (tree_view);
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
suggested_action = 0;
|
||||||
|
|
||||||
|
if (suggested_action)
|
||||||
|
{
|
||||||
|
GtkTreeModel *src_model = NULL;
|
||||||
|
GtkTreePath *src_path = NULL;
|
||||||
|
|
||||||
|
if (!gtk_selection_data_get_tree_row (selection_data,
|
||||||
|
&src_model,
|
||||||
|
&src_path))
|
||||||
|
suggested_action = 0;
|
||||||
|
|
||||||
|
if (suggested_action)
|
||||||
|
{
|
||||||
|
if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
|
||||||
|
src_model,
|
||||||
|
src_path,
|
||||||
|
path))
|
||||||
|
suggested_action = 0;
|
||||||
|
|
||||||
|
gtk_tree_path_free (src_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("suggested action %d in drag_data_received\n", suggested_action);
|
||||||
|
|
||||||
|
gdk_drag_status (context, suggested_action, time);
|
||||||
|
|
||||||
|
if (path)
|
||||||
|
gtk_tree_path_free (path);
|
||||||
|
|
||||||
|
/* If you can't drop, remove user drop indicator until the next motion */
|
||||||
|
if (suggested_action == 0)
|
||||||
|
gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
|
||||||
|
NULL,
|
||||||
|
GTK_TREE_VIEW_DROP_BEFORE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dest_row = get_dest_row (context);
|
dest_row = get_dest_row (context);
|
||||||
|
|
||||||
if (dest_row == NULL)
|
if (dest_row == NULL)
|
||||||
@ -5753,16 +5902,17 @@ gtk_tree_view_drag_data_received (GtkWidget *widget,
|
|||||||
dest_row,
|
dest_row,
|
||||||
selection_data))
|
selection_data))
|
||||||
accepted = TRUE;
|
accepted = TRUE;
|
||||||
|
|
||||||
|
|
||||||
/* Don't clear drop_row, we may need it in drag_data_delete */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_print ("accepted: %d\n", accepted);
|
||||||
|
|
||||||
gtk_drag_finish (context,
|
gtk_drag_finish (context,
|
||||||
accepted,
|
accepted,
|
||||||
(context->action == GDK_ACTION_MOVE),
|
(context->action == GDK_ACTION_MOVE),
|
||||||
time);
|
time);
|
||||||
g_print ("accepted: %d\n", accepted);
|
|
||||||
|
gtk_tree_path_free (dest_row);
|
||||||
|
|
||||||
|
/* drop dest_row */
|
||||||
|
set_dest_row (context, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,9 +194,9 @@ void gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view);
|
|||||||
void gtk_tree_view_set_drag_dest_row (GtkTreeView *tree_view,
|
void gtk_tree_view_set_drag_dest_row (GtkTreeView *tree_view,
|
||||||
GtkTreePath *path,
|
GtkTreePath *path,
|
||||||
GtkTreeViewDropPosition pos);
|
GtkTreeViewDropPosition pos);
|
||||||
void gtk_tree_view_get_drag_dest_row (GtkTreeView *tree_view,
|
void gtk_tree_view_get_drag_dest_row (GtkTreeView *tree_view,
|
||||||
GtkTreePath **path,
|
GtkTreePath **path,
|
||||||
GtkTreeViewDropPosition *pos);
|
GtkTreeViewDropPosition *pos);
|
||||||
gboolean gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view,
|
gboolean gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view,
|
||||||
gint drag_x,
|
gint drag_x,
|
||||||
gint drag_y,
|
gint drag_y,
|
||||||
|
Loading…
Reference in New Issue
Block a user