Commit 38d84fb3 authored by Pavel Cisler's avatar Pavel Cisler Committed by Pavel Cisler

Move more code from nautilus-icon-dnd.c to the common nautilus-drag.c. Add

2000-06-02  Pavel Cisler <pavel@eazel.com>

	* libnautilus-extensions/nautilus-drag.c:
	* libnautilus-extensions/nautilus-drag.h:
	(add_one_gnome_icon_list), (add_one_uri_list),
	(nautilus_drag_drag_data_get):
	Move more code from nautilus-icon-dnd.c to the common
	nautilus-drag.c. Add a common nautilus_drag_drag_data_get
	function that gets passed iterators and assembles selection
	data.

	* libnautilus-extensions/nautilus-gtk-extensions.c:
	* libnautilus-extensions/nautilus-gtk-extensions.h:
	(nautilus_gtk_marshal_NONE__POINTER_INT_INT_INT):
	Added more marshalling glue. One day there will be enough
	for everyone.

	* libnautilus-extensions/nautilus-icon-dnd.c:
	(nautilus_icon_container_each_selected_icon):
	(icon_get_data_binder), (each_icon_get_data_binder),
	(drag_data_get_callback):
	Iterators and binders to support the NautilusIconContainer
	flavor of nautilus_drag_drag_data_get.

	* libnautilus-extensions/nautilus-list.c:
	* libnautilus-extensions/nautilus-list.h:
	* src/file-manager/fm-list-view.c:
	(nautilus_list_initialize_class), (nautilus_list_initialize),
	(nautilus_list_drag_begin), (nautilus_list_drag_end),
	(nautilus_list_drag_leave), (nautilus_list_drag_motion),
	(nautilus_list_drag_data_received), (nautilus_list_set_selection),
	(nautilus_list_each_selected_row),
	(row_get_data_binder), (each_icon_get_data_binder),
	(fm_list_drag_data_get), (create_list):
	Hookup fm_list_drag_data_get to support drags originating from the
	list view. Connect the drag_data_get to fm_list_view and
	handle it there.

	* libnautilus-extensions/nautilus-list.c:
	* src/file-manager/fm-list-view.c:
	(nautilus_list_initialize_class), (fm_list_handle_dropped_icons):
	Fix an improperly marshalled signal.
parent 8cef10fd
2000-06-02 Pavel Cisler <pavel@eazel.com>
* libnautilus-extensions/nautilus-drag.c:
* libnautilus-extensions/nautilus-drag.h:
(add_one_gnome_icon_list), (add_one_uri_list),
(nautilus_drag_drag_data_get):
Move more code from nautilus-icon-dnd.c to the common
nautilus-drag.c. Add a common nautilus_drag_drag_data_get
function that gets passed iterators and assembles selection
data.
* libnautilus-extensions/nautilus-gtk-extensions.c:
* libnautilus-extensions/nautilus-gtk-extensions.h:
(nautilus_gtk_marshal_NONE__POINTER_INT_INT_INT):
Added more marshalling glue. One day there will be enough
for everyone.
* libnautilus-extensions/nautilus-icon-dnd.c:
(nautilus_icon_container_each_selected_icon):
(icon_get_data_binder), (each_icon_get_data_binder),
(drag_data_get_callback):
Iterators and binders to support the NautilusIconContainer
flavor of nautilus_drag_drag_data_get.
* libnautilus-extensions/nautilus-list.c:
* libnautilus-extensions/nautilus-list.h:
* src/file-manager/fm-list-view.c:
(nautilus_list_initialize_class), (nautilus_list_initialize),
(nautilus_list_drag_begin), (nautilus_list_drag_end),
(nautilus_list_drag_leave), (nautilus_list_drag_motion),
(nautilus_list_drag_data_received), (nautilus_list_set_selection),
(nautilus_list_each_selected_row),
(row_get_data_binder), (each_icon_get_data_binder),
(fm_list_drag_data_get), (create_list):
Hookup fm_list_drag_data_get to support drags originating from the
list view. Connect the drag_data_get to fm_list_view and
handle it there.
* libnautilus-extensions/nautilus-list.c:
* src/file-manager/fm-list-view.c:
(nautilus_list_initialize_class), (fm_list_handle_dropped_icons):
Fix an improperly marshalled signal.
2000-06-02 Ramiro Estrugo <ramiro@eazel.com>
* components/history/nautilus-history-view.c: (main):
......
......@@ -241,3 +241,72 @@ nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
return TRUE;
}
/* Encode a "special/x-gnome-icon-list" selection.
Along with the URIs of the dragged files, this encodes
the location and size of each icon relative to the cursor.
*/
static void
add_one_gnome_icon_list(const char *uri, int x, int y, int w, int h,
gpointer data)
{
GString *result = (GString *)data;
char *s;
s = g_strdup_printf ("%s\r%d:%d:%hu:%hu\r\n",
uri, x, y, w, h);
g_string_append (result, s);
g_free (s);
}
/* Encode a "text/uri-list" selection. */
static void
add_one_uri_list(const char *uri, int x, int y, int w, int h,
gpointer data)
{
GString *result = (GString *)data;
g_string_append (result, uri);
g_string_append (result, "\r\n");
}
/* Common function for drag_data_get_callback calls.
* Returns FALSE if it doesn't handle drag data
*/
gboolean
nautilus_drag_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 time,
gpointer container_context,
NautilusDragEachSelectedItemIterator each_selected_item_iterator)
{
GString *result;
if (info != NAUTILUS_ICON_DND_GNOME_ICON_LIST && info != NAUTILUS_ICON_DND_URI_LIST) {
/* don't know how to handle */
return FALSE;
}
result = g_string_new (NULL);
switch (info) {
case NAUTILUS_ICON_DND_GNOME_ICON_LIST:
each_selected_item_iterator (add_one_gnome_icon_list, container_context, result);
break;
case NAUTILUS_ICON_DND_URI_LIST:
each_selected_item_iterator (add_one_uri_list, container_context, result);
break;
default:
g_assert_not_reached ();
}
gtk_selection_data_set (selection_data,
selection_data->target,
8, result->str, result->len);
return TRUE;
}
......@@ -77,13 +77,19 @@ typedef struct {
#define NAUTILUS_ICON_DND_BGIMAGE_TYPE "property/bgimage"
#define NAUTILUS_ICON_DND_KEYWORD_TYPE "property/keyword"
void
nautilus_drag_init (NautilusDragInfo *drag_info,
const GtkTargetEntry *drag_types, int drag_type_count,
GdkBitmap *stipple);
typedef void (* NautilusDragEachSelectedItemDataGet) (const char *url,
int x, int y, int w, int h,
gpointer data);
typedef void (* NautilusDragEachSelectedItemIterator) (NautilusDragEachSelectedItemDataGet iteratee,
gpointer iterator_context,
gpointer data);
void
nautilus_drag_finalize (NautilusDragInfo *drag_info);
void nautilus_drag_init (NautilusDragInfo *drag_info,
const GtkTargetEntry *drag_types,
int drag_type_count,
GdkBitmap *stipple);
void nautilus_drag_finalize (NautilusDragInfo *drag_info);
DragSelectionItem *nautilus_drag_selection_item_new (void);
......@@ -97,4 +103,12 @@ gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item,
gboolean nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
const GList *items);
gboolean nautilus_drag_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 time,
gpointer container_context,
NautilusDragEachSelectedItemIterator each_selected_item_iterator);
#endif
......@@ -303,6 +303,21 @@ nautilus_gtk_marshal_NONE__INT_INT_INT (GtkObject *object,
func_data);
}
void
nautilus_gtk_marshal_NONE__POINTER_INT_INT_INT (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args)
{
(* (void (*)(GtkObject *, gpointer, int, int, int, gpointer)) func)
(object,
GTK_VALUE_POINTER (args[0]),
GTK_VALUE_INT (args[1]),
GTK_VALUE_INT (args[2]),
GTK_VALUE_INT (args[3]),
func_data);
}
void
nautilus_gtk_marshal_NONE__POINTER_POINTER_INT_INT_INT (GtkObject *object,
GtkSignalFunc func,
......
......@@ -110,6 +110,10 @@ void nautilus_gtk_marshal_NONE__POINTER_POINTER_INT_INT_INT
GtkSignalFunc func,
gpointer func_data,
GtkArg *args);
void nautilus_gtk_marshal_NONE__POINTER_INT_INT_INT (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args);
void nautilus_gtk_marshal_NONE__POINTER_POINTER_POINTER (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
......
......@@ -25,6 +25,7 @@
Andy Hertzfeld <andy@eazel.com>
*/
#include <config.h>
#include "nautilus-icon-dnd.h"
......@@ -180,101 +181,96 @@ set_shadow_position (GnomeCanvasItem *shadow,
}
/* Source-side handling of the drag. */
/* Source-side handling of the drag. */
/* Encode a "special/x-gnome-icon-list" selection.
Along with the URIs of the dragged files, this encodes
the location and size of each icon relative to the cursor.
*/
static void
set_gnome_icon_list_selection (NautilusIconContainer *container,
GtkSelectionData *selection_data)
/* iteration glue struct */
typedef struct {
gpointer iterator_context;
NautilusDragEachSelectedItemDataGet iteratee;
gpointer iteratee_data;
} IconGetDataBinderContext;
static gboolean
icon_get_data_binder (NautilusIcon *icon, gpointer data)
{
NautilusIconContainerDetails *details;
GList *p;
GString *data;
IconGetDataBinderContext *context;
ArtDRect world_rect;
ArtIRect window_rect;
char *uri;
NautilusIconContainer *container;
details = container->details;
context = (IconGetDataBinderContext *)data;
data = g_string_new (NULL);
for (p = details->icons; p != NULL; p = p->next) {
NautilusIcon *icon;
ArtDRect world_rect;
ArtIRect window_rect;
char *uri;
char *s;
g_assert (NAUTILUS_IS_ICON_CONTAINER (context->iterator_context));
icon = p->data;
if (!icon->is_selected) {
continue;
}
container = NAUTILUS_ICON_CONTAINER (context->iterator_context);
nautilus_icon_canvas_item_get_icon_rectangle
(icon->item, &world_rect);
nautilus_gnome_canvas_world_to_window_rectangle
(GNOME_CANVAS (container), &world_rect, &window_rect);
uri = nautilus_icon_container_get_icon_uri (container, icon);
nautilus_icon_canvas_item_get_icon_rectangle
(icon->item, &world_rect);
nautilus_gnome_canvas_world_to_window_rectangle
(GNOME_CANVAS (container), &world_rect, &window_rect);
if (uri == NULL) {
g_warning ("no URI for one of the dragged items");
} else {
s = g_strdup_printf ("%s\r%d:%d:%hu:%hu\r\n",
uri,
(int) (window_rect.x0 - details->dnd_info->drag_info.start_x),
(int) (window_rect.y0 - details->dnd_info->drag_info.start_y),
window_rect.x1 - window_rect.x0,
window_rect.y1 - window_rect.y0);
g_free (uri);
g_string_append (data, s);
g_free (s);
}
uri = nautilus_icon_container_get_icon_uri (container, icon);
if (uri == NULL) {
g_warning ("no URI for one of the iterated icons");
return TRUE;
}
gtk_selection_data_set (selection_data,
selection_data->target,
8, data->str, data->len);
/* pass the uri, mouse-relative x/y and icon width/height */
context->iteratee (uri,
(int) (window_rect.x0 - container->details->dnd_info->drag_info.start_x),
(int) (window_rect.y0 - container->details->dnd_info->drag_info.start_y),
window_rect.x1 - window_rect.x0,
window_rect.y1 - window_rect.y0,
context->iteratee_data);
g_string_free (data, TRUE);
g_free (uri);
return TRUE;
}
/* Encode a "text/uri-list" selection. */
/* Iterate over each selected icon in a NautilusIconContainer,
* calling each_function on each.
*/
static void
set_uri_list_selection (NautilusIconContainer *container,
GtkSelectionData *selection_data)
nautilus_icon_container_each_selected_icon (NautilusIconContainer *container,
gboolean (*each_function) (NautilusIcon *, gpointer), gpointer data)
{
NautilusIconContainerDetails *details;
GList *p;
char *uri;
GString *data;
details = container->details;
data = g_string_new (NULL);
for (p = details->icons; p != NULL; p = p->next) {
NautilusIcon *icon;
NautilusIcon *icon;
for (p = container->details->icons; p != NULL; p = p->next) {
icon = p->data;
if (!icon->is_selected)
if (!icon->is_selected) {
continue;
uri = nautilus_icon_container_get_icon_uri (container, icon);
g_string_append (data, uri);
g_free (uri);
g_string_append (data, "\r\n");
}
if (!each_function (icon, data)) {
return;
}
}
}
gtk_selection_data_set (selection_data,
selection_data->target,
8, data->str, data->len);
/* Adaptor function used with nautilus_icon_container_each_selected_icon
* to help iterate over all selected items, passing uris, x,y,w and h
* values to the iteratee
*/
static void
each_icon_get_data_binder (NautilusDragEachSelectedItemDataGet iteratee,
gpointer iterator_context, gpointer data)
{
IconGetDataBinderContext context;
NautilusIconContainer *container;
g_string_free (data, TRUE);
g_assert (NAUTILUS_IS_ICON_CONTAINER (iterator_context));
container = NAUTILUS_ICON_CONTAINER (iterator_context);
context.iterator_context = iterator_context;
context.iteratee = iteratee;
context.iteratee_data = data;
nautilus_icon_container_each_selected_icon (container, icon_get_data_binder, &context);
}
/* Called when the data for drag&drop is needed */
static void
drag_data_get_callback (GtkWidget *widget,
GdkDragContext *context,
......@@ -283,26 +279,20 @@ drag_data_get_callback (GtkWidget *widget,
guint32 time,
gpointer data)
{
NautilusIconContainer *container;
g_return_if_fail (widget != NULL);
g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (widget));
g_assert (widget != NULL);
g_assert (NAUTILUS_IS_ICON_CONTAINER (widget));
g_return_if_fail (context != NULL);
container = NAUTILUS_ICON_CONTAINER (widget);
switch (info) {
case NAUTILUS_ICON_DND_GNOME_ICON_LIST:
set_gnome_icon_list_selection (container, selection_data);
break;
case NAUTILUS_ICON_DND_URI_LIST:
set_uri_list_selection (container, selection_data);
break;
default:
g_assert_not_reached ();
}
/* Call common function from nautilus-drag that set's up
* the selection data in the right format. Pass it means to
* iterate all the selected icons.
*/
nautilus_drag_drag_data_get (widget, context, selection_data,
info, time, widget, each_icon_get_data_binder);
}
/* Target-side handling of the drag. */
......
......@@ -42,6 +42,7 @@ typedef struct {
GnomeCanvasItem *shadow;
} NautilusIconDndInfo;
void nautilus_icon_dnd_init (NautilusIconContainer *container,
GdkBitmap *stipple);
void nautilus_icon_dnd_fini (NautilusIconContainer *container);
......
......@@ -85,7 +85,7 @@ struct NautilusListDetails
/* Drag state */
NautilusDragInfo *drag_info;
/* Delayed selection information */
int dnd_select_pending;
guint dnd_select_pending_state;
......@@ -195,11 +195,6 @@ static void nautilus_list_drag_begin (GtkWidget *w
GdkDragContext *context);
static void nautilus_list_drag_end (GtkWidget *widget,
GdkDragContext *context);
static void nautilus_list_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *data,
guint info,
guint time);
static void nautilus_list_drag_leave (GtkWidget *widget,
GdkDragContext *context,
guint time);
......@@ -354,8 +349,8 @@ nautilus_list_initialize_class (NautilusListClass *klass)
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (NautilusListClass, handle_dropped_icons),
nautilus_gtk_marshal_NONE__INT_INT_INT,
GTK_TYPE_NONE, 3,
nautilus_gtk_marshal_NONE__POINTER_INT_INT_INT,
GTK_TYPE_NONE, 4,
GTK_TYPE_POINTER,
GTK_TYPE_INT,
GTK_TYPE_INT,
......@@ -414,7 +409,6 @@ nautilus_list_initialize_class (NautilusListClass *klass)
widget_class->motion_notify_event = nautilus_list_motion;
widget_class->drag_begin = nautilus_list_drag_begin;
widget_class->drag_end = nautilus_list_drag_end;
widget_class->drag_data_get = nautilus_list_drag_data_get;
widget_class->drag_leave = nautilus_list_drag_leave;
widget_class->drag_motion = nautilus_list_drag_motion;
widget_class->drag_drop = nautilus_list_drag_drop;
......@@ -2351,14 +2345,15 @@ nautilus_list_column_resize_track_end (GtkWidget *widget, int column)
clist->drag_pos = -1;
}
/* We override the drag_begin signal to do nothing */
static void
nautilus_list_drag_begin (GtkWidget *widget, GdkDragContext *context)
{
/* nothing */
NautilusList *list;
g_assert (NAUTILUS_IS_LIST (widget));
list = NAUTILUS_LIST (widget);
}
/* We override the drag_end signal to do nothing */
static void
nautilus_list_drag_end (GtkWidget *widget, GdkDragContext *context)
{
......@@ -2369,18 +2364,8 @@ nautilus_list_drag_end (GtkWidget *widget, GdkDragContext *context)
nautilus_drag_destroy_selection_list (list->details->selection_list);
list->details->selection_list = NULL;
/* nothing */
}
/* We override the drag_data_get signal to do nothing */
static void
nautilus_list_drag_data_get (GtkWidget *widget, GdkDragContext *context,
GtkSelectionData *data, guint info, guint time)
{
/* nothing */
}
/* We override the drag_leave signal to do nothing */
static void
nautilus_list_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time)
{
......@@ -2390,11 +2375,8 @@ nautilus_list_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time
list = NAUTILUS_LIST (widget);
list->details->got_drop_data_type = FALSE;
/* nothing */
}
/* We override the drag_motion signal to do nothing */
static gboolean
nautilus_list_drag_motion (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint time)
......@@ -2404,17 +2386,9 @@ nautilus_list_drag_motion (GtkWidget *widget, GdkDragContext *context,
g_assert (NAUTILUS_IS_LIST (widget));
list = NAUTILUS_LIST (widget);
if (!list->details->drag_info->got_drop_data_type) {
gtk_drag_get_data (widget, context,
GPOINTER_TO_INT (context->targets->data),
time);
}
return TRUE;
}
/* We override the drag_drop signal to do nothing */
static gboolean
nautilus_list_drag_drop (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint time)
......@@ -2445,7 +2419,6 @@ nautilus_list_drag_drop (GtkWidget *widget, GdkDragContext *context,
return FALSE;
}
/* We override the drag_data_received signal to accept colors. */
static void
nautilus_list_drag_data_received (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, GtkSelectionData *data,
......@@ -2463,7 +2436,7 @@ nautilus_list_drag_data_received (GtkWidget *widget, GdkDragContext *context,
list->details->data_type = info;
break;
case NAUTILUS_ICON_DND_COLOR:
/* FIXME: cache the data here and use it in drag_drop */
/* FIXME: cache the data here and use it in nautilus_list_drag_drop */
nautilus_background_receive_dropped_color
(nautilus_get_widget_background (widget),
widget, x, y, data);
......@@ -2598,6 +2571,25 @@ nautilus_list_set_selection (NautilusList *list, GList *selection)
}
}
void
nautilus_list_each_selected_row (NautilusList *list, NautilusEachRowFunction function,
gpointer data)
{
GtkCListRow *row;
GList *p;
g_assert (NAUTILUS_IS_LIST (list));
for (p = GTK_CLIST (list)->row_list; p != NULL; p = p->next) {
row = p->data;
if (row->state != GTK_STATE_SELECTED)
continue;
if (!function(row, data))
return;
}
}
/* Workaround for a bug in GtkCList's insert_row.
* It sets the focus row to 0 if there is exactly one row,
* even if there was no focus on entry.
......
......@@ -115,6 +115,8 @@ struct NautilusListClass {
void (* handle_dropped_icons) (GtkWidget *widget, GList *icons, int x, int y, int action);
};
typedef gboolean (* NautilusEachRowFunction) (GtkCListRow *, gpointer);
GtkType nautilus_list_get_type (void);
GtkWidget *nautilus_list_new_with_titles (int columns,
const char * const *titles);
......@@ -136,5 +138,8 @@ void nautilus_list_select_row (NautilusList *list,
int row);
GtkCListRow *nautilus_list_row_at (NautilusList *list,
int y);
void nautilus_list_each_selected_row (NautilusList *list,
NautilusEachRowFunction function,
gpointer data);
#endif /* NAUTILUS_LIST_H */
......@@ -241,3 +241,72 @@ nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
return TRUE;
}
/* Encode a "special/x-gnome-icon-list" selection.
Along with the URIs of the dragged files, this encodes
the location and size of each icon relative to the cursor.
*/
static void
add_one_gnome_icon_list(const char *uri, int x, int y, int w, int h,
gpointer data)
{
GString *result = (GString *)data;
char *s;
s = g_strdup_printf ("%s\r%d:%d:%hu:%hu\r\n",
uri, x, y, w, h);
g_string_append (result, s);
g_free (s);
}
/* Encode a "text/uri-list" selection. */
static void
add_one_uri_list(const char *uri, int x, int y, int w, int h,
gpointer data)
{
GString *result = (GString *)data;
g_string_append (result, uri);
g_string_append (result, "\r\n");
}
/* Common function for drag_data_get_callback calls.
* Returns FALSE if it doesn't handle drag data
*/
gboolean
nautilus_drag_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 time,
gpointer container_context,
NautilusDragEachSelectedItemIterator each_selected_item_iterator)
{
GString *result;
if (info != NAUTILUS_ICON_DND_GNOME_ICON_LIST && info != NAUTILUS_ICON_DND_URI_LIST) {
/* don't know how to handle */
return FALSE;
}
result = g_string_new (NULL);
switch (info) {
case NAUTILUS_ICON_DND_GNOME_ICON_LIST:
each_selected_item_iterator (add_one_gnome_icon_list, container_context, result);
break;
case NAUTILUS_ICON_DND_URI_LIST:
each_selected_item_iterator (add_one_uri_list, container_context, result);
break;
default:
g_assert_not_reached ();
}
gtk_selection_data_set (selection_data,
selection_data->target,
8, result->str, result->len);
return TRUE;
}
......@@ -77,13 +77,19 @@ typedef struct {
#define NAUTILUS_ICON_DND_BGIMAGE_TYPE "property/bgimage"
#define NAUTILUS_ICON_DND_KEYWORD_TYPE "property/keyword"
void
nautilus_drag_init (NautilusDragInfo *drag_info,
const GtkTargetEntry *drag_types, int drag_type_count,
GdkBitmap *stipple);
typedef void (* NautilusDragEachSelectedItemDataGet) (const char *url,
int x, int y, int w, int h,
gpointer data);
typedef void (* NautilusDragEachSelectedItemIterator) (NautilusDragEachSelectedItemDataGet iteratee,
gpointer iterator_context,
gpointer data);
void
nautilus_drag_finalize (NautilusDragInfo *drag_info);
void nautilus_drag_init (NautilusDragInfo *drag_info,
const GtkTargetEntry *drag_types,
int drag_type_count,
GdkBitmap *stipple);