[patch] link drag-and-drop to tabs
Christian Persch <[email protected]>
| Newsgroups | gmane.comp.web.galeon.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, in galeon 1 you could drag-and-drop a link from the current tab to another tab or create a new tab by dragging an url to the empty space on the tab notebook. The patch below re-implements this feature for galeon 2. Beware: this is my first attempt at messing with galeon, so the patch just might be horribly wrong. It seems to work fine, though. Patch is against current CVS. diff -urN galeon-cvs/ChangeLog galeon-modified/ChangeLog --- galeon-cvs/ChangeLog 2003-03-08 22:09:42.000000000 +0100 +++ galeon-modified/ChangeLog 2003-03-08 23:08:44.000000000 +0100 @@ -1,3 +1,12 @@ +2003-03-08 Christian Persch <[email protected]> + + * utils/galeon-dnd.[ch] (galeon_dnd_uri_list_extract_uris): imported + from epiphany + * src/galeon-window.c (galeon_window_tab_drag_data_received_cb), + (galeon_window_notebook_drag_data_received_cb), (setup_notebook), + (galeon_window_add_tab): reimplemented the "url drag-and-drop to tabs" + feature from galeon1. Code adapted from galeon 1. + 2003-03-08 Tommi Komulainen <[email protected]> * src/galeon-tab.c: Check for is_active before updating window diff -urN galeon-cvs/src/galeon-window.c galeon-modified/src/galeon-window.c --- galeon-cvs/src/galeon-window.c 2003-03-08 22:09:41.000000000 +0100 +++ galeon-modified/src/galeon-window.c 2003-03-08 22:45:54.000000000 +0100 @@ -43,6 +43,8 @@ #include "bookmarks-editor-dockable.h" #include "window-recent-history-menu.h" #include "galeon-embed-prefs.h" +#include "galeon-dnd.h" +#include "galeon-tab.h" #include <stdlib.h> #include <string.h> @@ -225,12 +227,29 @@ const char *url, const char *title, GaleonWindow *w); +static void +galeon_window_tab_drag_data_received_cb (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, GtkSelectionData *selection_data, + guint info, guint time, GaleonEmbed *embed); + +static void +galeon_window_notebook_drag_data_received_cb (GtkWidget* widget, GdkDragContext *context, + gint x, gint y, GtkSelectionData *selection_data, + guint info, guint time, GaleonWindow *window); + /* static class variables */ static GdkColor _galeon_window_loading_tab_color; static GdkColor _galeon_window_new_tab_color; static GObjectClass *parent_class = NULL; +static GtkTargetEntry url_drag_types [] = +{ + { GALEON_DND_URI_LIST_TYPE, 0, GALEON_DND_URI_LIST }, + { GALEON_DND_TEXT_TYPE, 0, GALEON_DND_TEXT }, + { GALEON_DND_URL_TYPE, 0, GALEON_DND_URL } +}; + MAKE_GET_TYPE_IFACE (galeon_window, "GaleonWindow", GaleonWindow, galeon_window_class_init, galeon_window_init, BONOBO_TYPE_WINDOW, galeon_window_gb_location_source_init, GB_TYPE_LOCATION_SOURCE); @@ -436,6 +455,16 @@ G_CALLBACK (galeon_window_tab_detached_cb), window); + /* Setup drag-and-drop target */ + g_signal_connect (G_OBJECT(notebook), "drag_data_received", + G_CALLBACK(galeon_window_notebook_drag_data_received_cb), + window); + gtk_drag_dest_set (GTK_WIDGET(notebook), GTK_DEST_DEFAULT_MOTION | + GTK_DEST_DEFAULT_DROP, + url_drag_types,G_N_ELEMENTS(url_drag_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE | + GDK_ACTION_LINK | GDK_ACTION_ASK); + gtk_widget_show (GTK_WIDGET (notebook)); return notebook; @@ -1232,6 +1261,7 @@ gboolean jump_to) { GtkWidget *widget; + GtkWidget *tab_label; g_return_if_fail (IS_GALEON_WINDOW (window)); g_return_if_fail (IS_GALEON_TAB (tab)); @@ -1244,6 +1274,15 @@ widget, GUL_NOTEBOOK_INSERT_GROUPED, jump_to); + + /* Set up drag-and-drop target */ + tab_label = gtk_notebook_get_tab_label(window->priv->notebook,widget); + g_signal_connect (G_OBJECT(tab_label), "drag_data_received", + G_CALLBACK(galeon_window_tab_drag_data_received_cb),widget); + gtk_drag_dest_set (tab_label, GTK_DEST_DEFAULT_ALL, + url_drag_types,G_N_ELEMENTS(url_drag_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE | + GDK_ACTION_LINK | GDK_ACTION_ASK); } void @@ -2162,3 +2201,83 @@ galeon_window_update_control (window, TitleControl); } } + +static void +galeon_window_tab_drag_data_received_cb (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, GtkSelectionData *selection_data, + guint info, guint time, GaleonEmbed *embed) +{ + char *data = selection_data->data; + const char *url; + GList *uris; + + if (selection_data->length <= 0 || selection_data->data == NULL) + return; + + switch (info) + { + case GALEON_DND_URI_LIST: + uris = galeon_dnd_uri_list_extract_uris (data); + g_return_val_if_fail (uris != NULL, NULL); + url = (const char *)uris->data; + galeon_embed_load_url(embed,url); + /* maybe we should populate the forward history with the remaining uris? */ + g_list_foreach (uris, (GFunc)g_free, NULL); + g_list_free (uris); + break; + case GALEON_DND_TEXT: + case GALEON_DND_URL: + galeon_embed_load_url(embed,data); + break; + default: + /* shouldn't happen */ + g_warning ("unexpected dnd type %u\n", info); + break; + } +} + +/** + * galeon_window_notebook_drag_data_received_cb: handles drops on the empty space + * in the notebook widget + */ +static void +galeon_window_notebook_drag_data_received_cb (GtkWidget* widget, GdkDragContext *context, + gint x, gint y, GtkSelectionData *selection_data, + guint info, guint time, GaleonWindow *window) +{ + char *data = selection_data->data; + const char *url; + GList *uris; + GaleonTab *tab; + + if (selection_data->length <= 0 || selection_data->data == NULL) + return; + + tab = galeon_window_get_active_tab (window); + + switch (info) + { + case GALEON_DND_URI_LIST: + uris = galeon_dnd_uri_list_extract_uris (data); + g_return_val_if_fail (uris != NULL, NULL); + url = (const char *)uris->data; + galeon_shell_new_tab (galeon_shell, window, tab, url, + GALEON_NEW_TAB_APPEND | + GALEON_NEW_TAB_IN_EXISTING_WINDOW); + /* maybe we should populate the forward history with the remaining uris? */ + g_list_foreach (uris, (GFunc)g_free, NULL); + g_list_free (uris); + break; + case GALEON_DND_TEXT: + case GALEON_DND_URL: + galeon_shell_new_tab (galeon_shell, window, tab, data, + GALEON_NEW_TAB_APPEND | + GALEON_NEW_TAB_IN_EXISTING_WINDOW); + break; + default: + /* shouldn't happen */ + g_warning ("unexpected dnd type %u\n", info); + break; + } + +} diff -urN galeon-cvs/utils/galeon-dnd.c galeon-modified/utils/galeon-dnd.c --- galeon-cvs/utils/galeon-dnd.c 2003-03-08 22:09:42.000000000 +0100 +++ galeon-modified/utils/galeon-dnd.c 2003-03-08 22:38:07.000000000 +0100 @@ -19,6 +19,7 @@ #include "galeon-dnd.h" #include <gtk/gtkselection.h> +#include <string.h> static GtkTargetEntry url_drag_types [] = { @@ -98,3 +99,53 @@ G_N_ELEMENTS (url_drag_types), GDK_ACTION_COPY); } + +GList * +galeon_dnd_uri_list_extract_uris (const char *uri_list) +{ + /* Note that this is mostly very stolen from old libgnome/gnome-mime.c */ + + const gchar *p, *q; + gchar *retval; + GList *result = NULL; + + g_return_val_if_fail (uri_list != NULL, NULL); + + p = uri_list; + + /* We don't actually try to validate the URI according to RFC + * 2396, or even check for allowed characters - we just ignore + * comments and trim whitespace off the ends. We also + * allow LF delimination as well as the specified CRLF. + */ + while (p != NULL) { + if (*p != '#') { + while (g_ascii_isspace (*p)) + p++; + + q = p; + while ((*q != '\0') + && (*q != '\n') + && (*q != '\r')) + q++; + + if (q > p) { + q--; + while (q > p + && g_ascii_isspace (*q)) + q--; + + retval = g_malloc (q - p + 2); + strncpy (retval, p, q - p + 1); + retval[q - p + 1] = '\0'; + + result = g_list_prepend (result, retval); + } + } + p = strchr (p, '\n'); + if (p != NULL) + p++; + } + + return g_list_reverse (result); +} diff -urN galeon-cvs/utils/galeon-dnd.h galeon-modified/utils/galeon-dnd.h --- galeon-cvs/utils/galeon-dnd.h 2003-03-08 22:09:42.000000000 +0100 +++ galeon-modified/utils/galeon-dnd.h 2003-03-08 22:28:27.000000000 +0100 @@ -54,5 +54,6 @@ void galeon_dnd_url_drag_source_set (GtkWidget *widget); +GList *galeon_dnd_uri_list_extract_uris (const char *uri_list); G_END_DECLS ------------------------------------------------------- This SF.net email is sponsored by: Etnus, makers of TotalView, The debugger for complex code. Debugging C/C++ programs can leave you feeling lost and disoriented. TotalView can help you find your way. Available on major UNIX and Linux platforms. Try it free. www.etnus.com