diff --git a/src/icons.c b/src/icons.c index 7bacd80a7..730c8f4ee 100644 --- a/src/icons.c +++ b/src/icons.c @@ -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); } diff --git a/src/util.c b/src/util.c index 1af51862b..13f735e63 100644 --- a/src/util.c +++ b/src/util.c @@ -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); } diff --git a/src/util.h b/src/util.h index ff33c1077..fc51f6489 100644 --- a/src/util.h +++ b/src/util.h @@ -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) \ { \ diff --git a/src/view.c b/src/view.c index fb0ad5f57..dfb2b5b25 100644 --- a/src/view.c +++ b/src/view.c @@ -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; indir ); - - 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; } diff --git a/src/view.h b/src/view.h index 3e4fbcdc1..4d3b935a9 100644 --- a/src/view.h +++ b/src/view.h @@ -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