aha! ok... lots of stuff here...

1. now xdnd works to apps:
   tested:
     gmc
     mozilla
     xmms
     ee
2. dnd works bewteen e17 views too

3. cleaned up a little (the uri format was a little wrong)

4. notice fixme's - yes we need to have ways of copying and moving etc. files.
   efm did this - imho right. right mouse drag always pops up a menu asking
   what you want to do. left mosue drag always moves. current shift+left
   copies. we can add ctrl+left links etc. - but these shoudl eventually
   be configurable. i think this will keep everyone happy.


SVN revision: 5756
This commit is contained in:
Carsten Haitzler 2001-12-08 06:34:06 +00:00
parent c300cb9506
commit 3e72ecf27a
5 changed files with 261 additions and 178 deletions

View File

@ -80,21 +80,24 @@ e_icon_up_cb(void *_data, Evas _e, Evas_Object _o, int _b, int _x, int _y)
ic = _data;
if (ic->view->drag.started)
{
int x, y;
ic->state.clicked = 0;
ic->state.just_selected = 0;
e_icon_update_state(ic);
ecore_window_no_ignore(ic->view->drag.win);
ecore_window_destroy(ic->view->drag.win);
ic->view->drag.started = 0;
if(e->mods & ECORE_EVENT_KEY_MODIFIER_SHIFT)
ic->view->drag.drop_mode = E_DND_COPY;
else
ic->view->drag.drop_mode = E_DND_MOVE;
/* FIXME: if button use is right mouse then do an ask */
/* Handle dnd motion(drop) - dragging==0 */
ecore_window_dnd_handle_motion( ic->view->win.base,
_x - ic->view->drag.offset.x,
_y - ic->view->drag.offset.y,
0);
ecore_pointer_xy_get(&x, &y);
ecore_window_dnd_handle_motion(ic->view->win.base, x, y, 0);
ecore_window_dnd_finished();
D_RETURN;
}
if (_b == 1)
@ -361,6 +364,9 @@ e_icon_move_cb(void *_data, Evas _e, Evas_Object _o, int _b, int _x, int _y)
ecore_pixmap_free(mask);
/* Initiate dnd */
ecore_dnd_set_mode_copy();
ecore_dnd_set_data(ic->view->win.base);
ecore_dnd_own_selection(ic->view->win.base);
ic->view->drag.started = 1;
@ -383,6 +389,7 @@ e_icon_move_cb(void *_data, Evas _e, Evas_Object _o, int _b, int _x, int _y)
ic->view->drag.drop_mode = E_DND_MOVE;
/* Handle dnd motion - dragging==1 */
ecore_pointer_xy_get(&x, &y);
ecore_window_dnd_handle_motion( ic->view->win.base, x, y, 1);
}

View File

@ -56,47 +56,46 @@ e_util_glob_matches(char *str, char *glob)
/*
* Function to take a URL of the form
* file://hostname/dir1/dir2/file
* file://dir1/dir2/file
*
* Test that 'file://' exists.
* Test that hostname matches passed value
* Test that 'file:' exists.
* Return a pointer to /dir1/...
*
* todo:
* - dir or filename which matches hostname will
* fool the hostname match
* - file://dir1/dir2/file is also legal but rejected by
* this presently
*/
char *
e_util_de_url_and_verify( const char *fi, const char *hostn )
e_util_de_url_and_verify(const char *fi)
{
char *wk;
D_ENTER;
char *wk;
wk = strstr( fi, "file://" );
/* Valid URL contains "file://" */
if( !wk )
D_RETURN_ (NULL);
/* Need some form of hostname to continue */
if( !hostn )
D_RETURN_ (NULL);
/* Do we contain hostname? */
wk = strstr( fi, hostn );
/* Hostname mismatch, reject file */
if( !wk )
D_RETURN_ (NULL);
/* Local file name starts after "hostname" */
wk = strchr( wk, '/' );
if( !wk )
D_RETURN_ (NULL);
D_RETURN( wk );
D_ENTER;
wk = strstr( fi, "file:" );
/* Valid URL contains "file:" */
if( !wk )
D_RETURN_ (NULL);
/* Need some form of hostname to continue */
/* if( !hostn )
* D_RETURN_ (NULL);
*/
/* Do we contain hostname? */
/* wk = strstr( fi, hostn );
*/
/* Hostname mismatch, reject file */
/* if( !wk )
* D_RETURN_ (NULL);
*/
/* Local file name starts after "hostname" */
wk = strchr( wk, '/' );
if ( !wk )
D_RETURN_(NULL);
printf("returning %s\n", wk);
D_RETURN_(wk);
}

View File

@ -7,7 +7,7 @@ void e_util_set_env(char *variable, char *content);
char *e_util_get_user_home(void);
void *e_util_memdup(void *data, int size);
int e_util_glob_matches(char *str, char *glob);
char *e_util_de_url_and_verify( const char *fi, const char *hostn );
char *e_util_de_url_and_verify(const char *fi);
#define e_strdup(__dest, __var) \
{ \

View File

@ -1697,9 +1697,30 @@ e_view_find_by_monitor_id(int id)
D_RETURN_(NULL);
}
E_View *
e_view_find_by_window(Window win)
{
Evas_List l;
D_ENTER;
for (l = views; l; l = l->next)
{
E_View *v;
v = l->data;
if (v->win.base == win)
D_RETURN_(v);
}
D_RETURN_(NULL);
}
void
e_view_close_all(void)
{
D_ENTER;
while (views)
{
E_View *v;
@ -1707,6 +1728,8 @@ e_view_close_all(void)
v = views->data;
e_object_unref(E_OBJECT(v));
}
D_RETURN;
}
static void
@ -2458,7 +2481,6 @@ e_view_bg_change(E_View *v, char *file)
D_ENTER;
printf("change %s\n", file);
if (!(!strcmp(file, ".e_background.bg.db"))) return;
sprintf(buf, "background_reload:%s", v->dir);
ecore_add_event_timer(buf, 0.5, e_view_bg_reload_timeout, 0, v);
@ -2473,7 +2495,6 @@ e_view_bg_add(E_View *v, char *file)
D_ENTER;
printf("change %s\n", file);
if (!(!strcmp(file, ".e_background.bg.db"))) return;
sprintf(buf, "%s/%s", v->dir, file);
if (!strcmp(buf, v->bg_file)) D_RETURN;
@ -2531,9 +2552,6 @@ e_view_init(void)
D_RETURN;
}
/*
* send the dnd data to the target app
*
@ -2552,17 +2570,28 @@ e_dnd_data_request(Ecore_Event * ev)
* } Ecore_Event_Dnd_Data_Request;
*/
Evas_List l;
char hostname[PATH_MAX];
D_ENTER;
/* Need hostname for URL (file://hostname/...) */
if(gethostname( hostname, PATH_MAX))
{
/* failed... Default to 'localhost' */
strcpy( hostname, "localhost");
}
/* nooo nooo noo - never encode host names in url's -
* file:/path/blah is local only - secondly.. why encode
* url's with hosts? e17 only handles local files in the
* fs - so why use url styles at all? NB - in my testing
* in efm all the other apps didnt use the file:/host/blah
* url formatting... so i think we want to do what everyone
* else does here
*/
/* this is o evil it's not funny - gethostbyname? you know
* your window manager) could get hung here for minutes doing
* this lookup? bad bad bad.
*
* if(gethostname( hostname, PATH_MAX))
* {
* strcpy( hostname, "localhost");
* }
*/
e = ev->event;
for (l = views; l; l = l->next)
{
@ -2579,45 +2608,102 @@ e_dnd_data_request(Ecore_Event * ev)
v = l->data;
if (e->win == v->win.base)
{
for (ll = v->icons; ll; ll = ll->next)
{
E_Icon *ic;
ic = ll->data;
if (ic->state.selected)
{
int ic_size;
/* Size = 'file://' + 3 strings + host delimiter '/' and '\r\n' end. */
ic_size = 7 + strlen(hostname) + strlen(v->dir) + strlen(ic->file)+3;
size += ic_size;
REALLOC(data, char, size);
sprintf( data+idx, "file://%s%s/%s\r\n", hostname, v->dir, ic->file);
idx += ic_size;
}
}
if(v->drag.drop_mode == E_DND_COPY)
ecore_dnd_set_mode_copy();
else
ecore_dnd_set_mode_move();
ecore_dnd_set_data(e->win);
ecore_dnd_send_data(
e->source_win, e->win,
data, size,
e->destination_atom,
/* uri-list, not plain-text */
0
);
if (e->uri_list)
{
int first = 1;
for (ll = v->icons; ll; ll = ll->next)
{
E_Icon *ic;
ic = ll->data;
if (ic->state.selected)
{
int ic_size;
ic_size = 5 + strlen(v->dir) + 1 + strlen(ic->file) + 2;
size += ic_size;
REALLOC(data, char, size);
if (first)
{
sprintf(data + idx, "file:%s/%s", v->dir, ic->file);
first = 0;
}
else
sprintf(data + idx, "\r\nfile:%s/%s\r\n", v->dir, ic->file);
idx += ic_size;
}
}
ecore_dnd_send_data(e->source_win, e->win,
data, strlen(data),
e->destination_atom,
DND_TYPE_URI_LIST);
}
else if (e->plain_text)
{
int first = 1;
for (ll = v->icons; ll; ll = ll->next)
{
E_Icon *ic;
ic = ll->data;
if (ic->state.selected)
{
int ic_size;
ic_size = strlen(v->dir) + 1 + strlen(ic->file) + 1;
size += ic_size;
REALLOC(data, char, size);
if (first)
{
sprintf(data + idx, "%s/%s", v->dir, ic->file);
first = 0;
}
else
sprintf(data + idx, "\n%s/%s", v->dir, ic->file);
idx += ic_size;
}
}
ecore_dnd_send_data(e->source_win, e->win,
data, strlen(data),
e->destination_atom,
DND_TYPE_PLAIN_TEXT);
}
else /* if (e->moz_url)*/
{
FREE(data);
data = NULL;
for (ll = v->icons; ll; ll = ll->next)
{
E_Icon *ic;
ic = ll->data;
if (ic->state.selected)
{
char buf[16384];
sprintf(buf, "file:%s/%s", v->dir, ic->file);
data = strdup(buf);
size = strlen(data);
break;
}
}
if (data)
{
ecore_dnd_send_data(e->source_win, e->win,
data, size,
e->destination_atom,
DND_TYPE_NETSCAPE_URL);
}
}
IF_FREE(data);
D_RETURN;
}
FREE(data);
}
D_RETURN;
}
@ -2645,8 +2731,8 @@ e_dnd_drop_end(Ecore_Event * ev)
v = l->data;
if (e->win == v->win.base)
{
ecore_window_dnd_finished();
e_dnd_drop_request_free();
e_dnd_drop_request_free();
D_RETURN;
}
}
@ -2654,7 +2740,6 @@ e_dnd_drop_end(Ecore_Event * ev)
}
static void
e_dnd_drop_position(Ecore_Event * ev)
{
@ -2678,24 +2763,23 @@ e_dnd_drop_position(Ecore_Event * ev)
v = l->data;
if (e->win == v->win.base)
{
if( e->win != e->source_win )
{
/* send XdndStatus */
ecore_window_dnd_send_status_ok(v->win.base, e->source_win,
v->location.x, v->location.y,
v->size.w, v->size.h
);
}
/* todo - cache window extents, don't send again within these extents. */
if( e->win != e->source_win )
{
/* send XdndStatus */
ecore_window_dnd_send_status_ok(v->win.base, e->source_win,
v->location.x, v->location.y,
v->size.w, v->size.h
);
}
/* todo - cache window extents, don't send again within these extents. */
D_RETURN;
}
}
D_RETURN;
}
static void
e_dnd_drop(Ecore_Event * ev)
{
@ -2718,20 +2802,18 @@ e_dnd_drop(Ecore_Event * ev)
v = l->data;
if (e->win == v->win.base)
{
/* Dropped! Handle data */
e_dnd_handle_drop( v, dnd_pending_mode );
ecore_window_dnd_finished();
e_dnd_drop_request_free();
/* Dropped! Handle data */
e_dnd_handle_drop (v, dnd_pending_mode);
ecore_window_dnd_send_finished(v->win.base, e->source_win);
e_dnd_drop_request_free();
D_RETURN;
}
}
D_RETURN;
}
static void
e_dnd_drop_request(Ecore_Event * ev)
{
@ -2758,7 +2840,7 @@ e_dnd_drop_request(Ecore_Event * ev)
if (e->win == v->win.base)
{
/* if it exists, we already have the data... */
if( !dnd_files )
if ((!dnd_files ) && (e->num_files > 0))
{
int i;
@ -2770,29 +2852,33 @@ e_dnd_drop_request(Ecore_Event * ev)
dnd_num_files = e->num_files;
if( e->copy )
dnd_pending_mode = E_DND_COPY;
else if( e->move )
dnd_pending_mode = E_DND_MOVE;
else if( e->link )
dnd_pending_mode = E_DND_LINK;
else
dnd_pending_mode = E_DND_ASK;
/* if the dnd source is e itself then dont use the event mode */
if (e_view_find_by_window(e->source_win))
{
E_View *vv;
v = e_view_find_by_window(e->source_win);
dnd_pending_mode = v->drag.drop_mode;
}
else
{
if( e->copy )
dnd_pending_mode = E_DND_COPY;
else if( e->move )
dnd_pending_mode = E_DND_MOVE;
else if( e->link )
dnd_pending_mode = E_DND_LINK;
else
dnd_pending_mode = E_DND_ASK;
}
}
/*
printf( "drop-req %d-[c%dm%dl%d]--%s--\n", e->num_files,
e->copy, e->move, e->link,
e->num_files ? e->files[0] : "None"
);
*/
D_RETURN;
}
}
D_RETURN;
}
static void
e_dnd_drop_request_free(void)
{
@ -2812,60 +2898,50 @@ e_dnd_drop_request_free(void)
D_RETURN;
}
static void
e_dnd_handle_drop( E_View *v, E_dnd_enum dnd_pending_mode )
{
char hostname[PATH_MAX];
int in, out;
char *filename;
D_ENTER;
/* Need hostname for URL (file://hostname/...) */
if(gethostname( hostname, PATH_MAX))
{
/* failed... Default to 'localhost' */
strcpy( hostname, "localhost");
}
/* Make space for destination in file list */
dnd_num_files++;
REALLOC_PTR(dnd_files, dnd_num_files);
dnd_files[dnd_num_files-1] = NULL;
/* Verify files are local, convert to non-URL */
for( in=0, out=0; in<dnd_num_files-1; in++ )
{
filename = e_util_de_url_and_verify( dnd_files[in], hostname );
/* Need a overlap safe copy here, like memmove() */
if( filename )
memmove( dnd_files[out++], filename, strlen(filename)+1 );
}
/* Append destination for efsd */
if( dnd_files[out] )
FREE( dnd_files[out] );
dnd_files[out++] = strdup( v->dir );
switch( dnd_pending_mode )
{
case E_DND_COPY:
/* Copy files */
efsd_copy( e_fs_get_connection(), out, dnd_files,
efsd_ops(0) );
break;
case E_DND_MOVE:
efsd_move( e_fs_get_connection(), out, dnd_files,
efsd_ops(0) );
break;
default:
/* nothing yet */
break;
}
int in, out;
char *filename;
D_ENTER;
/* Make space for destination in file list */
dnd_num_files++;
REALLOC_PTR(dnd_files, dnd_num_files);
dnd_files[dnd_num_files-1] = NULL;
/* Verify files are local, convert to non-URL */
for(in = 0, out = 0; in < dnd_num_files - 1; in++)
{
filename = e_util_de_url_and_verify( dnd_files[in]);
/* Need a overlap safe copy here, like memmove() */
if( filename )
memmove(dnd_files[out++], filename, strlen(filename) + 1);
}
/* Append destination for efsd */
if ( dnd_files[out] )
FREE( dnd_files[out] );
dnd_files[out++] = strdup( v->dir );
switch( dnd_pending_mode )
{
case E_DND_COPY:
/* Copy files */
efsd_copy( e_fs_get_connection(), out, dnd_files,
efsd_ops(0) );
break;
case E_DND_MOVE:
efsd_move( e_fs_get_connection(), out, dnd_files,
efsd_ops(0) );
break;
default:
/* nothing yet */
break;
}
D_RETURN;
}

View File

@ -202,6 +202,7 @@ void e_view_file_deleted(int id, char *file);
void e_view_file_changed(int id, char *file);
void e_view_file_moved(int id, char *file);
E_View *e_view_find_by_monitor_id(int id);
E_View *e_view_find_by_window(Window win);
/**
* e_view_new - Creates a new view object