diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-04-11 08:46:30 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-04-11 08:46:30 +0000 |
commit | c5eb06a5c93791a5cda0592a5b62ccc6d1cc3acb (patch) | |
tree | d62046cf445c7faa182d0286b3f38bbb69360e16 | |
parent | bd44573ff03c4698c126fc1b7d32f0e4b2258ae4 (diff) |
implemented message-to-folder DnD.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@207 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | ChangeLog.ja | 6 | ||||
-rw-r--r-- | src/folderview.c | 174 | ||||
-rw-r--r-- | src/folderview.h | 3 | ||||
-rw-r--r-- | src/gtkutils.c | 30 | ||||
-rw-r--r-- | src/gtkutils.h | 8 |
6 files changed, 151 insertions, 76 deletions
@@ -1,3 +1,9 @@ +2005-04-11 + + * src/gtkutils.[ch] + src/folderview.[ch]: implemented message-to-folder DnD. + Auto-expand and auto-scroll are also implemented. + 2005-04-08 * src/folderview.c: folderview_check_new(): fixed infinite loop bug. diff --git a/ChangeLog.ja b/ChangeLog.ja index 63c34d63..4bd6c235 100644 --- a/ChangeLog.ja +++ b/ChangeLog.ja @@ -1,3 +1,9 @@ +2005-04-11 + + * src/gtkutils.[ch] + src/folderview.[ch]: メッセージからフォルダへの DnD を実装。 + 自動展開と自動スクロールも実装。 + 2005-04-08 * src/folderview.c: folderview_check_new(): 無限ループバグを修正。 diff --git a/src/folderview.c b/src/folderview.c index ff20c966..a5aeb9d9 100644 --- a/src/folderview.c +++ b/src/folderview.c @@ -192,7 +192,6 @@ static void folderview_property_cb (FolderView *folderview, guint action, GtkWidget *widget); -#if 0 static gboolean folderview_drag_motion_cb(GtkWidget *widget, GdkDragContext *context, gint x, @@ -211,7 +210,6 @@ static void folderview_drag_received_cb (GtkWidget *widget, guint info, guint time, FolderView *folderview); -#endif static GtkItemFactoryEntry folderview_mail_popup_entries[] = { @@ -434,21 +432,17 @@ FolderView *folderview_create(void) G_CALLBACK(folderview_popup_close), folderview); /* drop callback */ - gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(treeview), - summary_drag_types, 1, - GDK_ACTION_MOVE|GDK_ACTION_COPY); -#if 0 - gtk_drag_dest_set(ctree, GTK_DEST_DEFAULT_ALL & - ~GTK_DEST_DEFAULT_HIGHLIGHT, - summary_drag_types, 1, + gtk_drag_dest_set(treeview, GTK_DEST_DEFAULT_ALL, summary_drag_types, 1, GDK_ACTION_MOVE | GDK_ACTION_COPY); - g_signal_connect(G_OBJECT(ctree), "drag_motion", - G_CALLBACK(folderview_drag_motion_cb), folderview); - g_signal_connect(G_OBJECT(ctree), "drag_leave", - G_CALLBACK(folderview_drag_leave_cb), folderview); - g_signal_connect(G_OBJECT(ctree), "drag_data_received", - G_CALLBACK(folderview_drag_received_cb), folderview); -#endif + g_signal_connect(G_OBJECT(treeview), "drag-motion", + G_CALLBACK(folderview_drag_motion_cb), + folderview); + g_signal_connect(G_OBJECT(treeview), "drag-leave", + G_CALLBACK(folderview_drag_leave_cb), + folderview); + g_signal_connect(G_OBJECT(treeview), "drag-data-received", + G_CALLBACK(folderview_drag_received_cb), + folderview); folderview->scrolledwin = scrolledwin; folderview->treeview = treeview; @@ -1225,7 +1219,6 @@ static void folderview_insert_item_recursive(FolderView *folderview, if (item->node->children && !item->collapsed) { GtkTreePath *path; - g_print("folderview_insert_item_recursive: expand\n"); path = gtk_tree_model_get_path (GTK_TREE_MODEL(folderview->store), &iter); gtk_tree_view_expand_row(GTK_TREE_VIEW(folderview->treeview), @@ -1238,7 +1231,6 @@ static void folderview_append_folder(FolderView *folderview, Folder *folder) { g_return_if_fail(folder != NULL); - g_print("folderview_append_folder()\n"); folderview_insert_item_recursive (folderview, FOLDER_ITEM(folder->node->data)); } @@ -1535,7 +1527,6 @@ static gboolean folderview_key_pressed(GtkWidget *widget, GdkEventKey *event, switch (event->keyval) { case GDK_Return: - g_print("enter pressed\n"); if (folderview->selected) { folderview_select_row_ref(folderview, folderview->selected); @@ -1543,7 +1534,6 @@ static gboolean folderview_key_pressed(GtkWidget *widget, GdkEventKey *event, return TRUE; break; case GDK_space: - g_print("space pressed\n"); if (folderview->selected) { if (folderview->opened) opened = gtk_tree_row_reference_get_path @@ -1620,7 +1610,6 @@ static void folderview_selection_changed(GtkTreeSelection *selection, gtk_tree_path_free(open_path); gtk_tree_path_free(path); folderview->open_folder = FALSE; - g_print("already opened\n"); return; } gtk_tree_path_free(open_path); @@ -1655,8 +1644,6 @@ static void folderview_row_expanded(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreeIter iter_; gboolean valid; - g_print("expanded\n"); - folderview->open_folder = FALSE; gtk_tree_model_get(GTK_TREE_MODEL(folderview->store), iter, @@ -2348,27 +2335,48 @@ static void folderview_property_cb(FolderView *folderview, guint action, prefs_folder_item_open(item); } -#if 0 -static void folderview_defer_expand_stop(FolderView *folderview) +static gint auto_expand_timeout(gpointer data) { - if (folderview->spring_timer > 0) { - gtk_timeout_remove(folderview->spring_timer); - folderview->spring_timer = 0; + FolderView *folderview = data; + GtkTreeView *treeview = GTK_TREE_VIEW(folderview->treeview); + GtkTreePath *path = NULL; + + gtk_tree_view_get_drag_dest_row(treeview, &path, NULL); + + if (path) { + gtk_tree_view_expand_row(treeview, path, FALSE); + gtk_tree_path_free(path); + folderview->expand_timeout = 0; + + return FALSE; + } else + return TRUE; +} + +static void remove_auto_expand_timeout(FolderView *folderview) +{ + if (folderview->expand_timeout != 0) { + g_source_remove(folderview->expand_timeout); + folderview->expand_timeout = 0; } - folderview->spring_node = NULL; } -static gint folderview_defer_expand(gpointer data) +static gint auto_scroll_timeout(gpointer data) { - FolderView *folderview = (FolderView *)data; + FolderView *folderview = data; - if (folderview->spring_node) { - gtk_ctree_expand(GTK_CTREE(folderview->ctree), - folderview->spring_node); - } - folderview_defer_expand_stop(folderview); + gtkut_tree_view_vertical_autoscroll + (GTK_TREE_VIEW(folderview->treeview)); - return FALSE; + return TRUE; +} + +static void remove_auto_scroll_timeout(FolderView *folderview) +{ + if (folderview->scroll_timeout != 0) { + g_source_remove(folderview->scroll_timeout); + folderview->scroll_timeout = 0; + } } static gboolean folderview_drag_motion_cb(GtkWidget *widget, @@ -2378,39 +2386,45 @@ static gboolean folderview_drag_motion_cb(GtkWidget *widget, guint time, FolderView *folderview) { - gint row, column; - FolderItem *item, *src_item; - GtkCTreeNode *node = NULL; + GtkTreeModel *model = GTK_TREE_MODEL(folderview->store); + GtkTreePath *path = NULL, *prev_path = NULL; + GtkTreeIter iter; + FolderItem *item = NULL, *src_item; gboolean acceptable = FALSE; - if (gtk_clist_get_selection_info - (GTK_CLIST(widget), x - 24, y - 24, &row, &column)) { - node = gtk_ctree_node_nth(GTK_CTREE(widget), row); - item = gtk_ctree_node_get_row_data(GTK_CTREE(widget), node); + if (gtk_tree_view_get_dest_row_at_pos + (GTK_TREE_VIEW(widget), x, y, &path, NULL)) { + gtk_tree_model_get_iter(model, &iter, path); + gtk_tree_model_get(model, &iter, COL_FOLDER_ITEM, &item, -1); src_item = folderview->summaryview->folder_item; if (src_item && src_item != item) acceptable = FOLDER_ITEM_CAN_ADD(item); - } - - if (node != folderview->spring_node) { - folderview_defer_expand_stop(folderview); - if (node && !GTK_CTREE_ROW(node)->expanded && - GTK_CTREE_ROW(node)->children) { - folderview->spring_timer = - gtk_timeout_add(1000, folderview_defer_expand, - folderview); - folderview->spring_node = node; + } else + remove_auto_expand_timeout(folderview); + + gtk_tree_view_get_drag_dest_row(GTK_TREE_VIEW(widget), + &prev_path, NULL); + if (!path || (prev_path && gtk_tree_path_compare(path, prev_path) != 0)) + remove_auto_expand_timeout(folderview); + if (prev_path) + gtk_tree_path_free(prev_path); + + gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(widget), path, + GTK_TREE_VIEW_DROP_INTO_OR_AFTER); + + if (path) { + if (folderview->expand_timeout == 0) { + folderview->expand_timeout = + g_timeout_add(1000, auto_expand_timeout, + folderview); + } else if (folderview->scroll_timeout == 0) { + folderview->scroll_timeout = + g_timeout_add(150, auto_scroll_timeout, + folderview); } } if (acceptable) { - g_signal_handlers_block_by_func - (G_OBJECT(widget), - G_CALLBACK(folderview_selected), folderview); - gtk_ctree_select(GTK_CTREE(widget), node); - g_signal_handlers_unblock_by_func - (G_OBJECT(widget), - G_CALLBACK(folderview_selected), folderview); if ((context->actions & GDK_ACTION_MOVE) != 0) gdk_drag_status(context, GDK_ACTION_MOVE, time); else if ((context->actions & GDK_ACTION_COPY) != 0) @@ -2419,12 +2433,13 @@ static gboolean folderview_drag_motion_cb(GtkWidget *widget, gdk_drag_status(context, GDK_ACTION_LINK, time); else gdk_drag_status(context, 0, time); - } else { - gtk_ctree_select(GTK_CTREE(widget), folderview->opened); + } else gdk_drag_status(context, 0, time); - } - return acceptable; + if (path) + gtk_tree_path_free(path); + + return TRUE; } static void folderview_drag_leave_cb(GtkWidget *widget, @@ -2432,8 +2447,11 @@ static void folderview_drag_leave_cb(GtkWidget *widget, guint time, FolderView *folderview) { - folderview_defer_expand_stop(folderview); - gtk_ctree_select(GTK_CTREE(widget), folderview->opened); + remove_auto_expand_timeout(folderview); + remove_auto_scroll_timeout(folderview); + + gtk_tree_view_set_drag_dest_row + (GTK_TREE_VIEW(widget), NULL, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); } static void folderview_drag_received_cb(GtkWidget *widget, @@ -2445,19 +2463,22 @@ static void folderview_drag_received_cb(GtkWidget *widget, guint time, FolderView *folderview) { - gint row, column; - FolderItem *item, *src_item; - GtkCTreeNode *node; + GtkTreeModel *model = GTK_TREE_MODEL(folderview->store); + GtkTreePath *path = NULL; + GtkTreeIter iter; + FolderItem *item = NULL, *src_item; - folderview_defer_expand_stop(folderview); + remove_auto_expand_timeout(folderview); + remove_auto_scroll_timeout(folderview); - if (gtk_clist_get_selection_info - (GTK_CLIST(widget), x - 24, y - 24, &row, &column) == 0) + if (!gtk_tree_view_get_dest_row_at_pos + (GTK_TREE_VIEW(widget), x, y, &path, NULL)) return; - node = gtk_ctree_node_nth(GTK_CTREE(widget), row); - item = gtk_ctree_node_get_row_data(GTK_CTREE(widget), node); + gtk_tree_model_get_iter(model, &iter, path); + gtk_tree_model_get(model, &iter, COL_FOLDER_ITEM, &item, -1); src_item = folderview->summaryview->folder_item; + if (FOLDER_ITEM_CAN_ADD(item) && src_item && src_item != item) { if ((context->actions & GDK_ACTION_MOVE) != 0) { summary_move_selected_to(folderview->summaryview, item); @@ -2469,8 +2490,9 @@ static void folderview_drag_received_cb(GtkWidget *widget, gtk_drag_finish(context, FALSE, FALSE, time); } else gtk_drag_finish(context, FALSE, FALSE, time); + + gtk_tree_path_free(path); } -#endif static gint folderview_folder_name_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, diff --git a/src/folderview.h b/src/folderview.h index e02e4b26..4205d120 100644 --- a/src/folderview.h +++ b/src/folderview.h @@ -54,6 +54,9 @@ struct _FolderView gboolean open_folder; + guint expand_timeout; + guint scroll_timeout; + GdkColor color_new; GdkColor color_noselect; diff --git a/src/gtkutils.c b/src/gtkutils.c index bf30b9a1..02cb7a36 100644 --- a/src/gtkutils.c +++ b/src/gtkutils.c @@ -478,6 +478,36 @@ gboolean gtkut_tree_view_find_collapsed_parent(GtkTreeView *treeview, return FALSE; } +#define SCROLL_EDGE_SIZE 15 + +/* borrowed from gtktreeview.c */ +void gtkut_tree_view_vertical_autoscroll(GtkTreeView *treeview) +{ + GdkRectangle visible_rect; + gint y, wy; + gint offset; + GtkAdjustment *vadj; + gfloat value; + + gdk_window_get_pointer(gtk_tree_view_get_bin_window(treeview), + NULL, &wy, NULL); + gtk_tree_view_widget_to_tree_coords(treeview, 0, wy, NULL, &y); + + gtk_tree_view_get_visible_rect(treeview, &visible_rect); + + /* see if we are near the edge. */ + offset = y - (visible_rect.y + 2 * SCROLL_EDGE_SIZE); + if (offset > 0) { + offset = y - (visible_rect.y + visible_rect.height - 2 * SCROLL_EDGE_SIZE); + if (offset < 0) + return; + } + + vadj = gtk_tree_view_get_vadjustment(treeview); + value = CLAMP(vadj->value + offset, 0.0, vadj->upper - vadj->page_size); + gtk_adjustment_set_value(vadj, value); +} + void gtkut_combo_set_items(GtkCombo *combo, const gchar *str1, ...) { va_list args; diff --git a/src/gtkutils.h b/src/gtkutils.h index 5e530b29..724d510f 100644 --- a/src/gtkutils.h +++ b/src/gtkutils.h @@ -106,6 +106,8 @@ ComboButton *gtkut_combo_button_create (GtkWidget *button, const gchar *path, gpointer data); +/* CTree functions */ + void gtkut_ctree_node_move_if_on_the_edge (GtkCTree *ctree, GtkCTreeNode *node); @@ -128,6 +130,8 @@ void gtkut_ctree_set_focus_row (GtkCTree *ctree, void gtkut_clist_set_focus_row (GtkCList *clist, gint row); +/* TreeView functions */ + gboolean gtkut_tree_model_next (GtkTreeModel *model, GtkTreeIter *iter); gboolean gtkut_tree_model_find_by_column_data @@ -142,6 +146,8 @@ gboolean gtkut_tree_view_find_collapsed_parent GtkTreeIter *parent, GtkTreeIter *iter); +void gtkut_tree_view_vertical_autoscroll(GtkTreeView *treeview); + void gtkut_combo_set_items (GtkCombo *combo, const gchar *str1, ...); @@ -154,6 +160,8 @@ void gtkut_container_remove (GtkContainer *container, void gtkut_scrolled_window_reset_position (GtkScrolledWindow *window); +/* TextView functions */ + gboolean gtkut_text_buffer_match_string (GtkTextBuffer *buffer, const GtkTextIter *iter, gunichar *wcs, |