aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog27
-rw-r--r--lib/ephy-dnd.c95
-rw-r--r--lib/ephy-dnd.h7
-rw-r--r--lib/ephy-marshal.list1
-rw-r--r--lib/widgets/ephy-tree-model-sort.c59
-rw-r--r--src/bookmarks/ephy-bookmarks-editor.c79
-rw-r--r--src/bookmarks/ephy-node-view.c157
-rw-r--r--src/bookmarks/ephy-node-view.h11
-rw-r--r--src/ephy-favicon-action.c14
-rwxr-xr-xsrc/history-dialog.c15
-rwxr-xr-xsrc/toolbar.c8
11 files changed, 372 insertions, 101 deletions
diff --git a/ChangeLog b/ChangeLog
index 0032990e9..e652a2872 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,32 @@
2003-03-29 Marco Pesenti Gritti <marco@it.gnome.org>
+ * lib/ephy-dnd.c: (add_one_node), (ephy_dnd_drag_data_get),
+ (ephy_dnd_node_list_extract_nodes):
+ * lib/ephy-dnd.h:
+ * lib/ephy-marshal.list:
+ * lib/widgets/ephy-tree-model-sort.c: (each_node_get_data_binder),
+ (ephy_tree_model_sort_multi_drag_data_get):
+ * src/bookmarks/ephy-bookmarks-editor.c: (cmd_rename),
+ (cmd_select_all), (ephy_bookmarks_editor_show_popup_cb),
+ (keyword_node_show_popup_cb), (node_dropped_cb),
+ (ephy_bookmarks_editor_construct),
+ (ephy_bookmarks_editor_update_menu):
+ * src/bookmarks/ephy-node-view.c: (ephy_node_view_class_init),
+ (ephy_node_view_button_press_cb), (ephy_node_view_has_focus),
+ (get_node_from_path), (drag_motion_cb), (drag_drop_cb),
+ (drag_data_received_cb), (ephy_node_view_enable_drag_dest),
+ (ephy_node_view_enable_drag_source):
+ * src/bookmarks/ephy-node-view.h:
+ * src/ephy-favicon-action.c: (connect_proxy):
+ * src/history-dialog.c: (history_dialog_setup_view):
+ * src/toolbar.c: (toolbar_get_action_name):
+
+ Make dnd code smarter, so it can support more than
+ just urls types.
+ Implement drag of bookmarks on topics in bme. What a pain !
+
+2003-03-29 Marco Pesenti Gritti <marco@it.gnome.org>
+
* src/bookmarks/ephy-topic-action.c: (create_tool_item),
(menu_deactivate_cb), (menu_activate_cb), (build_topics_menu),
(button_press_cb), (ephy_topic_action_set_property),
diff --git a/lib/ephy-dnd.c b/lib/ephy-dnd.c
index 7dfd1f272..ef39f37f0 100644
--- a/lib/ephy-dnd.c
+++ b/lib/ephy-dnd.c
@@ -17,25 +17,13 @@
*/
#include "ephy-dnd.h"
+#include "ephy-string.h"
+#include "ephy-node.h"
#include <gtk/gtkselection.h>
#include <gtk/gtktreeview.h>
#include <string.h>
-typedef enum {
- EPHY_DND_URI_LIST,
- EPHY_DND_TEXT,
- EPHY_DND_URL
-} EphyIconDndTargetType;
-
-static GtkTargetEntry url_drag_types [] =
-{
- { EPHY_DND_URI_LIST_TYPE, 0, EPHY_DND_URI_LIST },
- { EPHY_DND_TEXT_TYPE, 0, EPHY_DND_TEXT },
- { EPHY_DND_URL_TYPE, 0, EPHY_DND_URL }
-};
-static int n_url_drag_types = G_N_ELEMENTS (url_drag_types);
-
/* Encode a "_NETSCAPE_URL_" selection.
* As far as I can tell, Netscape is expecting a single
* URL to be returned. I cannot discover a way to construct
@@ -64,6 +52,17 @@ add_one_uri (const char *uri, int x, int y, int w, int h, gpointer data)
g_string_append (result, "\r\n");
}
+static void
+add_one_node (const char *uri, int x, int y, int w, int h, gpointer data)
+{
+ GString *result;
+
+ result = (GString *) data;
+
+ g_string_append (result, uri);
+ g_string_append (result, ";");
+}
+
gboolean
ephy_dnd_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
@@ -73,21 +72,32 @@ ephy_dnd_drag_data_get (GtkWidget *widget,
gpointer container_context,
EphyDragEachSelectedItemIterator each_selected_item_iterator)
{
- GString *result;
+ GString *result = NULL;
+ GdkAtom target;
+
+ target = selection_data->target;
- switch (info) {
- case EPHY_DND_URI_LIST:
- case EPHY_DND_TEXT:
+ if (target == gdk_atom_intern (EPHY_DND_URI_LIST_TYPE, FALSE) ||
+ target == gdk_atom_intern (EPHY_DND_TEXT_TYPE, FALSE))
+ {
result = g_string_new (NULL);
(* each_selected_item_iterator) (add_one_uri, container_context, result);
- break;
- case EPHY_DND_URL:
+ }
+ else if (target == gdk_atom_intern (EPHY_DND_URL_TYPE, FALSE))
+ {
result = g_string_new (NULL);
(* each_selected_item_iterator) (add_one_netscape_url, container_context, result);
- break;
- default:
- return FALSE;
- }
+ }
+ else if (target == gdk_atom_intern (EPHY_DND_TOPIC_TYPE, FALSE) ||
+ target == gdk_atom_intern (EPHY_DND_BOOKMARK_TYPE, FALSE))
+ {
+ result = g_string_new (NULL);
+ (* each_selected_item_iterator) (add_one_node, container_context, result);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
gtk_selection_data_set (selection_data,
selection_data->target,
@@ -96,23 +106,30 @@ ephy_dnd_drag_data_get (GtkWidget *widget,
return TRUE;
}
-void
-ephy_dnd_url_drag_source_set (GtkWidget *widget)
+GList *
+ephy_dnd_node_list_extract_nodes (const char *node_list)
{
- gtk_drag_source_set (widget,
- GDK_BUTTON1_MASK,
- url_drag_types,
- n_url_drag_types,
- GDK_ACTION_COPY);
-}
+ GList *result = NULL;
+ char **nodes;
+ int i;
-void
-ephy_dnd_enable_model_drag_source (GtkWidget *treeview)
-{
- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (treeview),
- GDK_BUTTON1_MASK,
- url_drag_types, n_url_drag_types,
- GDK_ACTION_COPY);
+ nodes = g_strsplit (node_list, ";", -1);
+
+ for (i = 0; nodes[i] != NULL; i++)
+ {
+ gulong id;
+
+ if (ephy_str_to_int (nodes[i], &id))
+ {
+ EphyNode *node;
+
+ node = ephy_node_get_from_id (id);
+ g_return_val_if_fail (node != NULL, NULL);
+ result = g_list_append (result, node);
+ }
+ }
+
+ return result;
}
GList *
diff --git a/lib/ephy-dnd.h b/lib/ephy-dnd.h
index c1756713f..afeb4704d 100644
--- a/lib/ephy-dnd.h
+++ b/lib/ephy-dnd.h
@@ -29,7 +29,8 @@ G_BEGIN_DECLS
#define EPHY_DND_URI_LIST_TYPE "text/uri-list"
#define EPHY_DND_TEXT_TYPE "text/plain"
#define EPHY_DND_URL_TYPE "_NETSCAPE_URL"
-#define EPHY_DND_TOPIC_TYPE "ephy_topic"
+#define EPHY_DND_TOPIC_TYPE "ephy_topic_node"
+#define EPHY_DND_BOOKMARK_TYPE "ephy_bookmark_node"
typedef void (* EphyDragEachSelectedItemDataGet) (const char *url,
int x, int y, int w, int h,
@@ -47,9 +48,7 @@ gboolean ephy_dnd_drag_data_get (GtkWidget *widget,
gpointer container_context,
EphyDragEachSelectedItemIterator each_selected_item_iterator);
-void ephy_dnd_url_drag_source_set (GtkWidget *widget);
-
-void ephy_dnd_enable_model_drag_source (GtkWidget *treeview);
+GList *ephy_dnd_node_list_extract_nodes (const char *node_list);
GList *ephy_dnd_uri_list_extract_uris (const char *uri_list);
diff --git a/lib/ephy-marshal.list b/lib/ephy-marshal.list
index 9082cae25..1d6c352cf 100644
--- a/lib/ephy-marshal.list
+++ b/lib/ephy-marshal.list
@@ -1,6 +1,7 @@
VOID:VOID
VOID:STRING
VOID:OBJECT
+VOID:OBJECT, POINTER
VOID:OBJECT,OBJECT,INT
VOID:OBJECT,STRING,INT
VOID:OBJECT,INT
diff --git a/lib/widgets/ephy-tree-model-sort.c b/lib/widgets/ephy-tree-model-sort.c
index 41369afd9..bc32131f3 100644
--- a/lib/widgets/ephy-tree-model-sort.c
+++ b/lib/widgets/ephy-tree-model-sort.c
@@ -19,6 +19,7 @@
*/
#include <gtk/gtkmarshal.h>
+#include <gtk/gtktreednd.h>
#include <string.h>
#include "ephy-node.h"
@@ -236,17 +237,47 @@ each_url_get_data_binder (EphyDragEachSelectedItemDataGet iteratee,
}
}
+static void
+each_node_get_data_binder (EphyDragEachSelectedItemDataGet iteratee,
+ gpointer iterator_context, gpointer data)
+{
+ gpointer *context = (gpointer *) iterator_context;
+ GList *path_list = (GList *) (context[0]);
+ GList *i;
+ GtkTreeModel *model = GTK_TREE_MODEL (context[1]);
+
+ for (i = path_list; i != NULL; i = i->next)
+ {
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_row_reference_get_path (i->data);
+ EphyNode *node = NULL;
+ char *value;
+
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ g_signal_emit (G_OBJECT (model),
+ ephy_tree_model_sort_signals[NODE_FROM_ITER],
+ 0, &iter, &node);
+ if (node == NULL)
+ return;
+
+ value = g_strdup_printf ("%ld", ephy_node_get_id (node));
+ iteratee (value, -1, -1, -1, -1, data);
+ g_free (value);
+ }
+}
+
static gboolean
ephy_tree_model_sort_multi_drag_data_get (EggTreeMultiDragSource *drag_source,
GList *path_list,
guint info,
GtkSelectionData *selection_data)
{
- EphyTreeModelSort *ms = EPHY_TREE_MODEL_SORT (drag_source);
+ GdkAtom target;
- /* FIXME use the target type here, not property_id */
+ target = selection_data->target;
- if (ms->priv->drag_property_id != -1)
+ if (target == gdk_atom_intern (EPHY_DND_BOOKMARK_TYPE, FALSE) ||
+ target == gdk_atom_intern (EPHY_DND_TOPIC_TYPE, FALSE))
{
gpointer icontext[2];
@@ -254,26 +285,18 @@ ephy_tree_model_sort_multi_drag_data_get (EggTreeMultiDragSource *drag_source,
icontext[1] = drag_source;
ephy_dnd_drag_data_get (NULL, NULL, selection_data,
- info, 0, &icontext, each_url_get_data_binder);
+ info, 0, &icontext, each_node_get_data_binder);
+
}
else
{
- GtkTreeIter iter;
- GtkTreePath *path = gtk_tree_row_reference_get_path (path_list->data);
- EphyNode *node = NULL;
- char *data;
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path);
- g_signal_emit (G_OBJECT (drag_source),
- ephy_tree_model_sort_signals[NODE_FROM_ITER],
- 0, &iter, &node);
+ gpointer icontext[2];
- /* FIXME free */
- data = g_strdup_printf ("%ld", ephy_node_get_id (node));
+ icontext[0] = path_list;
+ icontext[1] = drag_source;
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8, data, strlen (data));
+ ephy_dnd_drag_data_get (NULL, NULL, selection_data,
+ info, 0, &icontext, each_url_get_data_binder);
}
return TRUE;
diff --git a/src/bookmarks/ephy-bookmarks-editor.c b/src/bookmarks/ephy-bookmarks-editor.c
index a10168987..7f9a983bd 100644
--- a/src/bookmarks/ephy-bookmarks-editor.c
+++ b/src/bookmarks/ephy-bookmarks-editor.c
@@ -41,6 +41,28 @@
#include "popup-commands.h"
#include "ephy-state.h"
+static GtkTargetEntry topic_drag_dest_types [] =
+{
+ { EPHY_DND_BOOKMARK_TYPE, 0, 0 }
+};
+
+static int n_topic_drag_dest_types = G_N_ELEMENTS (topic_drag_dest_types);
+
+static GtkTargetEntry bmk_drag_types [] =
+{
+ { EPHY_DND_URI_LIST_TYPE, 0, 0 },
+ { EPHY_DND_TEXT_TYPE, 0, 1 },
+ { EPHY_DND_URL_TYPE, 0, 2 },
+ { EPHY_DND_BOOKMARK_TYPE, 0, 3 }
+};
+static int n_bmk_drag_types = G_N_ELEMENTS (bmk_drag_types);
+
+static GtkTargetEntry topic_drag_types [] =
+{
+ { EPHY_DND_TOPIC_TYPE, 0, 0 }
+};
+static int n_topic_drag_types = G_N_ELEMENTS (topic_drag_types);
+
static void ephy_bookmarks_editor_class_init (EphyBookmarksEditorClass *klass);
static void ephy_bookmarks_editor_init (EphyBookmarksEditor *editor);
static void ephy_bookmarks_editor_finalize (GObject *object);
@@ -61,7 +83,7 @@ static void cmd_open_bookmarks_in_tabs (EggAction *action,
EphyBookmarksEditor *editor);
static void cmd_open_bookmarks_in_browser (EggAction *action,
EphyBookmarksEditor *editor);
-static void cmd_delete (EggAction *action,
+static void cmd_delete (EggAction *action,
EphyBookmarksEditor *editor);
static void cmd_bookmark_properties (EggAction *action,
EphyBookmarksEditor *editor);
@@ -99,12 +121,6 @@ enum
PROP_BOOKMARKS
};
-static GtkTargetEntry topic_drag_types [] =
-{
- { EPHY_DND_TOPIC_TYPE, 0, 0 }
-};
-static int n_topic_drag_types = G_N_ELEMENTS (topic_drag_types);
-
static GObjectClass *parent_class = NULL;
static EggActionGroupEntry ephy_bookmark_popup_entries [] = {
@@ -124,7 +140,7 @@ static EggActionGroupEntry ephy_bookmark_popup_entries [] = {
{ "Cut", N_("Cu_t"), GTK_STOCK_CUT, "<control>X",
NULL, G_CALLBACK (cmd_cut), NULL },
-
+
{ "Copy", N_("_Copy"), GTK_STOCK_COPY, "<control>C",
NULL, G_CALLBACK (cmd_copy), NULL },
@@ -170,7 +186,7 @@ cmd_close (EggAction *action,
static void
cmd_rename (EggAction *action,
EphyBookmarksEditor *editor)
-{
+{
if (ephy_node_view_has_focus (editor->priv->bm_view))
{
ephy_node_view_edit (editor->priv->bm_view);
@@ -335,7 +351,7 @@ cmd_select_all (EggAction *action,
{
gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
}
- else if (ephy_node_view_has_focus (editor->priv->bm_view))
+ else if (ephy_node_view_has_focus (editor->priv->bm_view))
{
ephy_node_view_select_all (editor->priv->bm_view);
}
@@ -470,12 +486,12 @@ ephy_bookmarks_editor_show_popup_cb (GtkWidget *view,
EphyBookmarksEditor *editor)
{
GtkWidget *widget;
-
+
widget = egg_menu_merge_get_widget (editor->priv->ui_merge,
"/popups/EphyBookmarkEditorPopup");
gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL, 2,
gtk_get_current_event_time ());
-}
+}
static void
ephy_bookmarks_editor_node_activated_cb (GtkWidget *view,
@@ -559,7 +575,7 @@ keyword_node_show_popup_cb (GtkWidget *view, EphyBookmarksEditor *editor)
GtkWidget *widget;
widget = egg_menu_merge_get_widget (editor->priv->ui_merge,
- "/popups/EphyBookmarkKeywordPopup");
+ "/popups/EphyBookmarkKeywordPopup");
gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL, 2,
gtk_get_current_event_time ());
}
@@ -639,6 +655,22 @@ delete_event_cb (EphyBookmarksEditor *editor)
}
static void
+node_dropped_cb (EphyNodeView *view, EphyNode *node,
+ GList *nodes, EphyBookmarksEditor *editor)
+{
+ GList *l;
+
+ g_return_if_fail (EPHY_IS_NODE (node));
+
+ for (l = nodes; l != NULL; l = l->next)
+ {
+ EphyNode *bmk = EPHY_NODE (l->data);
+
+ ephy_bookmarks_set_keyword (editor->priv->bookmarks, node, bmk);
+ }
+}
+
+static void
ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor)
{
GtkWidget *hbox, *vbox;
@@ -692,7 +724,7 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor)
gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
gtk_container_add (GTK_CONTAINER (editor->priv->menu_dock), hbox);
gtk_widget_show (hbox);
-
+
g_assert (editor->priv->bookmarks);
node = ephy_bookmarks_get_keywords (editor->priv->bookmarks);
@@ -703,6 +735,9 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor)
topic_drag_types,
n_topic_drag_types,
-1);
+ ephy_node_view_enable_drag_dest (key_view,
+ topic_drag_dest_types,
+ n_topic_drag_dest_types);
ephy_node_view_set_browse_mode (key_view);
ephy_node_view_add_column (key_view, _("Topics"),
EPHY_TREE_MODEL_NODE_COL_KEYWORD, TRUE, TRUE);
@@ -722,7 +757,11 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor)
"show_popup",
G_CALLBACK (keyword_node_show_popup_cb),
editor);
-
+ g_signal_connect (G_OBJECT (key_view),
+ "node_dropped",
+ G_CALLBACK (node_dropped_cb),
+ editor);
+
vbox = gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (hbox),
vbox, TRUE, TRUE, 0);
@@ -738,7 +777,10 @@ ephy_bookmarks_editor_construct (EphyBookmarksEditor *editor)
/* Bookmarks View */
bm_view = ephy_node_view_new (node, editor->priv->bookmarks_filter);
ephy_node_view_set_hinted (bm_view, TRUE);
- ephy_node_view_enable_drag_source (bm_view, NULL, 0, EPHY_NODE_BMK_PROP_LOCATION);
+ ephy_node_view_enable_drag_source (bm_view,
+ bmk_drag_types,
+ n_bmk_drag_types,
+ EPHY_NODE_BMK_PROP_LOCATION);
ephy_node_view_add_icon_column (bm_view, EPHY_TREE_MODEL_NODE_COL_ICON);
ephy_node_view_add_column (bm_view, _("Title"),
EPHY_TREE_MODEL_NODE_COL_BOOKMARK, TRUE, TRUE);
@@ -869,10 +911,10 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor,
EggAction *action;
EggActionGroup *action_group;
GList *selection;
-
+
g_return_if_fail (editor != NULL);
g_return_if_fail (node != NULL);
-
+
priority = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY);
if (priority == EPHY_BOOKMARKS_KEYWORD_ALL_PRIORITY ||
@@ -897,4 +939,3 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor,
action = egg_action_group_get_action (action_group, "Delete");
g_object_set (action, "sensitive", !delete, NULL);
}
-
diff --git a/src/bookmarks/ephy-node-view.c b/src/bookmarks/ephy-node-view.c
index 382daa045..62f44b7df 100644
--- a/src/bookmarks/ephy-node-view.c
+++ b/src/bookmarks/ephy-node-view.c
@@ -32,6 +32,7 @@
#include "ephy-tree-model-sort.h"
#include "eggtreemultidnd.h"
#include "ephy-dnd.h"
+#include "ephy-marshal.h"
#include "string.h"
static void ephy_node_view_class_init (EphyNodeViewClass *klass);
@@ -62,12 +63,15 @@ struct EphyNodeViewPrivate
GtkWidget *treeview;
EphyTreeModelNodeColumn default_sort_column_id;
+
+ GtkTargetList *drag_targets;
};
enum
{
NODE_ACTIVATED,
NODE_SELECTED,
+ NODE_DROPPED,
SHOW_POPUP,
LAST_SIGNAL
};
@@ -158,6 +162,17 @@ ephy_node_view_class_init (EphyNodeViewClass *klass)
G_TYPE_NONE,
1,
EPHY_TYPE_NODE);
+ ephy_node_view_signals[NODE_DROPPED] =
+ g_signal_new ("node_dropped",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EphyNodeViewClass, node_dropped),
+ NULL, NULL,
+ ephy_marshal_VOID__OBJECT_POINTER,
+ G_TYPE_NONE,
+ 2,
+ EPHY_TYPE_NODE,
+ G_TYPE_POINTER);
ephy_node_view_signals[SHOW_POPUP] =
g_signal_new ("show_popup",
G_OBJECT_CLASS_TYPE (object_class),
@@ -262,7 +277,7 @@ ephy_node_view_button_press_cb (GtkTreeView *treeview,
{
GtkTreePath *path;
GtkTreeSelection *selection;
-
+
if (event->button == 3)
{
g_signal_emit (G_OBJECT (view), ephy_node_view_signals[SHOW_POPUP], 0);
@@ -673,10 +688,10 @@ ephy_node_view_has_focus (EphyNodeView *view)
{
GtkWidget *window;
GtkWidget *focused_widget;
-
+
window = gtk_widget_get_toplevel (view->priv->treeview);
focused_widget = gtk_window_get_focus (GTK_WINDOW(window));
-
+
if (view->priv->treeview == focused_widget)
{
return TRUE;
@@ -742,6 +757,127 @@ ephy_node_view_select_node (EphyNodeView *view,
gtk_tree_path_free (path);
}
+static EphyNode *
+get_node_from_path (EphyNodeView *view, GtkTreePath *path)
+{
+ EphyNode *node;
+ GtkTreeIter iter, iter2;
+
+ gtk_tree_model_get_iter (view->priv->sortmodel, &iter, path);
+ gtk_tree_model_sort_convert_iter_to_child_iter
+ (GTK_TREE_MODEL_SORT (view->priv->sortmodel), &iter2, &iter);
+ egg_tree_model_filter_convert_iter_to_child_iter
+ (EGG_TREE_MODEL_FILTER (view->priv->filtermodel), &iter, &iter2);
+ node = ephy_tree_model_node_node_from_iter (view->priv->nodemodel, &iter);
+
+ return node;
+}
+
+static gboolean
+drag_motion_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ EphyNodeView *view)
+{
+ GtkTreePath *path = NULL;
+ GtkTreeViewDropPosition pos;
+
+ g_signal_stop_emission_by_name (widget, "drag_motion");
+
+ if (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
+ x, y, &path, &pos))
+ {
+ gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), path,
+ GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gdk_drag_status (context, context->suggested_action, time);
+ }
+}
+
+static gboolean
+drag_drop_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ EphyNodeView *view)
+{
+ GdkAtom target;
+
+ target = gtk_drag_dest_find_target (widget, context,
+ view->priv->drag_targets);
+
+ if (target != GDK_NONE)
+ {
+ gtk_drag_get_data (widget, context, target, time);
+ }
+
+ g_signal_stop_emission_by_name (widget, "drag_drop");
+
+ return TRUE;
+}
+
+static gboolean
+drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EphyNodeView *view)
+{
+ GtkTreePath *path = NULL;
+ GtkTreeViewDropPosition pos;
+
+ g_signal_stop_emission_by_name (widget, "drag_data_received");
+
+ if (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
+ x, y, &path, &pos))
+ {
+ EphyNode *node;
+ GList *src_nodes;
+
+ node = get_node_from_path (view, path);
+
+ src_nodes = ephy_dnd_node_list_extract_nodes
+ (selection_data->data);
+
+ g_signal_emit (G_OBJECT (view),
+ ephy_node_view_signals[NODE_DROPPED], 0,
+ node, src_nodes);
+
+ g_list_free (src_nodes);
+ }
+
+ return TRUE;
+}
+
+void
+ephy_node_view_enable_drag_dest (EphyNodeView *view,
+ GtkTargetEntry *types,
+ int n_types)
+{
+ GtkWidget *treeview;
+
+ g_return_if_fail (view != NULL);
+
+ treeview = view->priv->treeview;
+
+ gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (treeview),
+ types, n_types,
+ GDK_ACTION_COPY);
+ view->priv->drag_targets = gtk_target_list_new (types, n_types);
+
+ g_signal_connect (treeview, "drag_data_received",
+ G_CALLBACK (drag_data_received_cb), view);
+ g_signal_connect (treeview, "drag_drop",
+ G_CALLBACK (drag_drop_cb), view);
+ g_signal_connect (treeview, "drag_motion",
+ G_CALLBACK (drag_motion_cb), view);
+}
+
void
ephy_node_view_enable_drag_source (EphyNodeView *view,
GtkTargetEntry *types,
@@ -756,17 +892,10 @@ ephy_node_view_enable_drag_source (EphyNodeView *view,
egg_tree_multi_drag_add_drag_support (GTK_TREE_VIEW (treeview));
- if (types == NULL)
- {
- ephy_dnd_enable_model_drag_source (GTK_WIDGET (treeview));
- }
- else
- {
- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (treeview),
- GDK_BUTTON1_MASK,
- types, n_types,
- GDK_ACTION_COPY);
- }
+ gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (treeview),
+ GDK_BUTTON1_MASK,
+ types, n_types,
+ GDK_ACTION_COPY);
ephy_tree_model_sort_set_drag_property (EPHY_TREE_MODEL_SORT (view->priv->sortmodel),
prop_id);
diff --git a/src/bookmarks/ephy-node-view.h b/src/bookmarks/ephy-node-view.h
index ee404d159..08b5757e0 100644
--- a/src/bookmarks/ephy-node-view.h
+++ b/src/bookmarks/ephy-node-view.h
@@ -49,9 +49,10 @@ typedef struct
{
GtkScrolledWindowClass parent;
- void (*node_activated) (EphyNodeView *view, EphyNode *node);
- void (*node_selected) (EphyNodeView *view, EphyNode *node);
- void (*show_popup) (EphyNodeView *view);
+ void (*node_activated) (EphyNodeView *view, EphyNode *node);
+ void (*node_selected) (EphyNodeView *view, EphyNode *node);
+ void (*node_dropped) (EphyNodeView *view, EphyNode *node, GList *nodes);
+ void (*show_popup) (EphyNodeView *view);
} EphyNodeViewClass;
GType ephy_node_view_get_type (void);
@@ -88,6 +89,10 @@ void ephy_node_view_enable_drag_source (EphyNodeView *view,
int n_types,
guint prop_id);
+void ephy_node_view_enable_drag_dest (EphyNodeView *view,
+ GtkTargetEntry *types,
+ int n_types);
+
void ephy_node_view_set_hinted (EphyNodeView *view,
gboolean hinted);
diff --git a/src/ephy-favicon-action.c b/src/ephy-favicon-action.c
index d2f6fd9b1..4fa4a510a 100644
--- a/src/ephy-favicon-action.c
+++ b/src/ephy-favicon-action.c
@@ -25,6 +25,14 @@
#include "ephy-shell.h"
#include "ephy-debug.h"
+static GtkTargetEntry url_drag_types [] =
+{
+ { EPHY_DND_URI_LIST_TYPE, 0, 0 },
+ { EPHY_DND_TEXT_TYPE, 0, 1 },
+ { EPHY_DND_URL_TYPE, 0, 2 }
+};
+static int n_url_drag_types = G_N_ELEMENTS (url_drag_types);
+
struct EphyFaviconActionPrivate
{
EphyWindow *window;
@@ -156,7 +164,11 @@ ephy_favicon_action_sync_icon (EggAction *action, GParamSpec *pspec,
static void
connect_proxy (EggAction *action, GtkWidget *proxy)
{
- ephy_dnd_url_drag_source_set (proxy);
+ gtk_drag_source_set (proxy,
+ GDK_BUTTON1_MASK,
+ url_drag_types,
+ n_url_drag_types,
+ GDK_ACTION_COPY);
ephy_favicon_action_sync_icon (action, NULL, proxy);
g_signal_connect (proxy,
"drag_data_get",
diff --git a/src/history-dialog.c b/src/history-dialog.c
index a8c1221fa..14224523c 100755
--- a/src/history-dialog.c
+++ b/src/history-dialog.c
@@ -35,6 +35,14 @@
#include <gtk/gtkcellrenderertext.h>
#include <bonobo/bonobo-i18n.h>
+static GtkTargetEntry url_drag_types [] =
+{
+ { EPHY_DND_URI_LIST_TYPE, 0, 0 },
+ { EPHY_DND_TEXT_TYPE, 0, 1 },
+ { EPHY_DND_URL_TYPE, 0, 2 }
+};
+static int n_url_drag_types = G_N_ELEMENTS (url_drag_types);
+
#define CONF_HISTORY_SEARCH_TEXT "/apps/epiphany/history/search_text"
#define CONF_HISTORY_SEARCH_TIME "/apps/epiphany/history/search_time"
@@ -290,7 +298,10 @@ history_dialog_setup_view (HistoryDialog *dialog)
GTK_TREE_MODEL (dialog->priv->sortmodel));
egg_tree_multi_drag_add_drag_support (GTK_TREE_VIEW (dialog->priv->treeview));
- ephy_dnd_enable_model_drag_source (GTK_WIDGET (dialog->priv->treeview));
+ gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (dialog->priv->treeview),
+ GDK_BUTTON1_MASK,
+ url_drag_types, n_url_drag_types,
+ GDK_ACTION_COPY);
add_column (dialog, _("Title"), EPHY_HISTORY_MODEL_COL_TITLE);
add_column (dialog, _("Location"), EPHY_HISTORY_MODEL_COL_LOCATION);
@@ -300,7 +311,7 @@ history_dialog_setup_view (HistoryDialog *dialog)
"row_activated",
G_CALLBACK (history_view_row_activated_cb),
dialog);
-
+
g_signal_connect (gtk_tree_view_get_selection (dialog->priv->treeview),
"changed",
G_CALLBACK (history_view_selection_changed_cb),
diff --git a/src/toolbar.c b/src/toolbar.c
index 76e992e7f..1f5e41cc0 100755
--- a/src/toolbar.c
+++ b/src/toolbar.c
@@ -147,7 +147,13 @@ toolbar_get_action_name (EphyEditableToolbar *etoolbar,
if (drag_type && (strcmp (drag_type, EPHY_DND_TOPIC_TYPE) == 0))
{
- res = g_strdup_printf ("GoTopicId%s", data);
+ GList *nodes;
+ int id;
+
+ nodes = ephy_dnd_node_list_extract_nodes (data);
+ id = ephy_node_get_id (EPHY_NODE (nodes->data));
+ res = g_strdup_printf ("GoTopicId%d", id);
+ g_list_free (nodes);
}
else if (drag_type && (strcmp (drag_type, EPHY_DND_URL_TYPE) == 0))
{