Added drag and drop support in icon view

This commit is contained in:
Pierre Pronchery 2008-01-22 11:06:02 +00:00
parent 8c995cc650
commit da35e3137f
3 changed files with 112 additions and 1 deletions

View File

@ -1165,8 +1165,10 @@ void browser_select_all(Browser * browser)
}
/* browser_set_location */
static char * _location_real_path(char const * path);
static int _location_directory(Browser * browser, char * path);
void browser_set_location(Browser * browser, char const * path)
{
char * realpath = NULL;
@ -1233,12 +1235,14 @@ static int _location_directory(Browser * browser, char * path)
}
/* browser_set_view */
static void _view_details(Browser * browser);
#if GTK_CHECK_VERSION(2, 6, 0)
static void _view_icons(Browser * browser);
static void _view_list(Browser * browser);
static void _view_thumbnails(Browser * browser);
#endif
void browser_set_view(Browser * browser, BrowserView view)
{
switch(view)
@ -1262,6 +1266,7 @@ void browser_set_view(Browser * browser, BrowserView view)
static void _details_column_text(GtkTreeView * view, char const * title,
int id, int sort);
static void _view_details(Browser * browser)
{
GtkTreeSelection * treesel;
@ -1339,6 +1344,7 @@ static void _details_column_text(GtkTreeView * view, char const * title, int id,
#if GTK_CHECK_VERSION(2, 6, 0)
static void _view_icon_view(Browser * browser);
static void _view_icons(Browser * browser)
{
#if GTK_CHECK_VERSION(2, 8, 0)
@ -1379,6 +1385,13 @@ static void _view_icon_view(Browser * browser)
GtkTreeSelection * treesel;
GList * sel = NULL;
GList * p;
#if GTK_CHECK_VERSION(2, 8, 0)
GtkTargetEntry targets[] =
{
{ "deforaos_browser_dnd", GTK_TARGET_SAME_APP, 0 }
};
size_t targets_cnt = sizeof(targets) / sizeof(*targets);
#endif
if(browser->iconview != NULL)
{
@ -1414,12 +1427,26 @@ static void _view_icon_view(Browser * browser)
gtk_icon_view_set_column_spacing(GTK_ICON_VIEW(browser->iconview), 4);
gtk_icon_view_set_row_spacing(GTK_ICON_VIEW(browser->iconview), 4);
gtk_icon_view_set_spacing(GTK_ICON_VIEW(browser->iconview), 4);
#if GTK_CHECK_VERSION(2, 8, 0)
gtk_icon_view_enable_model_drag_source(GTK_ICON_VIEW(browser->iconview),
GDK_BUTTON1_MASK, targets, targets_cnt,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
gtk_icon_view_enable_model_drag_dest(GTK_ICON_VIEW(browser->iconview),
targets, targets_cnt,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
#endif
g_signal_connect(G_OBJECT(browser->iconview), "item-activated",
G_CALLBACK(on_icon_default), browser);
g_signal_connect(G_OBJECT(browser->iconview), "button-press-event",
G_CALLBACK(on_view_press), browser);
g_signal_connect(G_OBJECT(browser->iconview), "popup-menu",
G_CALLBACK(on_view_popup), browser);
#if GTK_CHECK_VERSION(2, 8, 0)
g_signal_connect(G_OBJECT(browser->iconview), "drag-data-get",
G_CALLBACK(on_view_drag_data_get), browser);
g_signal_connect(G_OBJECT(browser->iconview), "drag-data-received",
G_CALLBACK(on_view_drag_data_received), browser);
#endif
gtk_container_add(GTK_CONTAINER(browser->scrolled), browser->iconview);
}

View File

@ -126,7 +126,6 @@ static GList * _copy_selection(Browser * browser)
void on_edit_cut(GtkMenuItem * menuitem, gpointer data)
{
Browser * browser = data;
GList * p;
g_list_foreach(browser->selection, (GFunc)free, NULL);
g_list_free(browser->selection);
@ -784,6 +783,83 @@ void on_filename_edited(GtkCellRendererText * renderer, gchar * arg1,
}
#if GTK_CHECK_VERSION(2, 8, 0)
/* on_view_drag_data_get */
void on_view_drag_data_get(GtkWidget * widget, GdkDragContext * dc,
GtkSelectionData * seldata, guint info, guint time,
gpointer data)
/* XXX could be more optimal */
{
Browser * browser = data;
GList * selection;
GList * s;
size_t len;
unsigned char * p;
selection = _copy_selection(browser);
seldata->data = NULL;
seldata->length = 0;
for(s = selection; s != NULL; s = s->next)
{
len = strlen(s->data) + 1;
if((p = realloc(seldata->data, seldata->length + len)) == NULL)
continue;
seldata->data = p;
memcpy(&p[seldata->length], s->data, len);
seldata->length += len;
}
g_list_foreach(selection, (GFunc)free, NULL);
g_list_free(selection);
}
/* on_view_drag_data_received */
void on_view_drag_data_received(GtkWidget * widget, GdkDragContext * context,
gint x, gint y, GtkSelectionData * seldata, guint info,
guint time, gpointer data)
/* FIXME - may not be an icon view
* - icon view may not be supported (< 2.6)
* - not fully checking if the source matches */
{
Browser * browser = data;
GtkTreePath * path;
GtkTreeIter iter;
char * p;
size_t i;
GList * selection = NULL;
#ifdef DEBUG
GList * s;
#endif
if(seldata->data == NULL || seldata->length == 0)
return;
path = gtk_icon_view_get_path_at_pos(GTK_ICON_VIEW(browser->iconview),
x, y);
if(path == NULL)
return; /* FIXME then use the current directory */
gtk_tree_model_get_iter(GTK_TREE_MODEL(browser->store), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(browser->store), &iter, BR_COL_PATH,
&p, -1);
for(i = 0; i < seldata->length; i += strlen(&seldata->data[i]) + 1)
selection = g_list_append(selection, &seldata->data[i]);
selection = g_list_append(selection, p);
#ifdef DEBUG
fprintf(stderr, "%s%s%s%s%s", "DEBUG: ",
context->suggested_action == GDK_ACTION_COPY ? "copying"
: "moving", " to \"", p, "\":\n");
for(s = selection; s != NULL; s = s->next)
fprintf(stderr, "DEBUG: \"%s\"\n", (char*)s->data);
#else
if(context->suggested_action == GDK_ACTION_COPY)
_exec(browser, "copy", "-ir", selection);
else if(context->suggested_action == GDK_ACTION_MOVE)
_exec(browser, "move", "-i", selection);
#endif
g_list_free(selection);
}
#endif
/* on_view_popup */
gboolean on_view_popup(GtkWidget * widget, gpointer data)
{

View File

@ -72,6 +72,14 @@ void on_icon_default(GtkIconView * view, GtkTreePath * path, gpointer data);
#endif
void on_filename_edited(GtkCellRendererText * renderer, gchar * arg1,
gchar * arg2, gpointer data);
#if GTK_CHECK_VERSION(2, 8, 0)
void on_view_drag_data_get(GtkWidget * widget, GdkDragContext * dc,
GtkSelectionData * seldata, guint info, guint time,
gpointer data);
void on_view_drag_data_received(GtkWidget * widget, GdkDragContext * context,
gint x, gint y, GtkSelectionData * seldata, guint info,
guint time, gpointer data);
#endif
gboolean on_view_popup(GtkWidget * widget, gpointer data);
gboolean on_view_press(GtkWidget * widget, GdkEventButton * event,
gpointer data);