diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2009-08-04 22:29:26 +0200 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2009-08-04 22:29:26 +0200 |
commit | 8e2e95f37a8509c7cbc7b85a61ab7b53f9d7b9d3 (patch) | |
tree | b31ddc98a4af3041e9c94737510adf419e8c5dcc | |
parent | fbbbd7436a347595e925c5ba8b69e8875b5c73bc (diff) |
fixed drag and drop from filemanagers
-rw-r--r-- | callbacks.c | 31 | ||||
-rw-r--r-- | gtkplaylist.c | 59 | ||||
-rw-r--r-- | gtkplaylist.h | 3 | ||||
-rw-r--r-- | playlist.c | 87 |
4 files changed, 153 insertions, 27 deletions
diff --git a/callbacks.c b/callbacks.c index 2a148fe4..c38e82b9 100644 --- a/callbacks.c +++ b/callbacks.c @@ -360,6 +360,9 @@ on_playlist_drag_drop (GtkWidget *widget, { if (drag_context->targets) { GdkAtom target_type = GDK_POINTER_TO_ATOM (g_list_nth_data (drag_context->targets, TARGET_SAMEWIDGET)); + if (!target_type) { + return FALSE; + } gtk_drag_get_data (widget, drag_context, target_type, time); return TRUE; } @@ -413,35 +416,9 @@ on_playlist_drag_data_received (GtkWidget *widget, gpointer user_data) { gchar *ptr=(char*)data->data; -// printf ("target type: %d\n", target_type); if (target_type == 0) { // uris if (!strncmp(ptr,"file:///",8)) { - //printf ("data: %s\n", ptr); - // this happens when dropped from file manager - // parse, and try to add to playlist - const gchar *p = ptr; - while (*p) { - const gchar *pe = p+1; - while (*pe && *pe > ' ') { - pe++; - } - if (pe - p < 4096 && pe - p > 7) { - char fname[(int)(pe - p)]; - strncpy (fname, p, pe - p); - fname[pe - p] = 0; - if (ps_add_dir (fname+7)) { - ps_add_file (fname+7); - } - } - p = pe; - // skip whitespace - while (*p && *p <= ' ') { - p++; - } - } - gtkps_setup_scrollbar (); - draw_playlist (widget, 0, 0, widget->allocation.width, widget->allocation.height); - gtkps_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height); + gtkps_handle_fm_drag_drop (y, ptr, data->length); } } else if (target_type == 1) { diff --git a/gtkplaylist.c b/gtkplaylist.c index 497833e8..ead402ac 100644 --- a/gtkplaylist.c +++ b/gtkplaylist.c @@ -921,3 +921,62 @@ gtkps_handle_drag_drop (int drop_y, uint32_t *d, int length) { playlist_tail = tail; } } + +void +strcopy_special (char *dest, const char *src, int len) { + while (len > 0) { + if (len >= 3 && !strncmp (src, "\%20", 3)) { + *dest = ' '; + dest++; + src += 3; + len -= 3; + } + else { + *dest++ = *src++; + len--; + } + } + *dest = 0; +} + +void +gtkps_handle_fm_drag_drop (int drop_y, void *ptr, int length) { + int drop_row = drop_y / rowheight + scrollpos; + playItem_t *drop_before = ps_get_for_idx (drop_row); + playItem_t *after = NULL; + if (drop_before) { + after = drop_before->prev; + } + //printf ("data: %s\n", ptr); + // this happens when dropped from file manager + // parse, and try to add to playlist + const gchar *p = ptr; + while (*p) { + const gchar *pe = p+1; + while (*pe && *pe > ' ') { + pe++; + } + if (pe - p < 4096 && pe - p > 7) { + char fname[(int)(pe - p)]; + strcopy_special (fname, p, pe-p); + //strncpy (fname, p, pe - p); + //fname[pe - p] = 0; + playItem_t *inserted = ps_insert_dir (after, fname + 7); + if (!inserted) { + inserted = ps_insert_file (after, fname + 7); + } + if (inserted) { + after = inserted; + } + } + p = pe; + // skip whitespace + while (*p && *p <= ' ') { + p++; + } + } + gtkps_setup_scrollbar (); + GtkWidget *widget = lookup_widget (mainwin, "playlist"); + draw_playlist (widget, 0, 0, widget->allocation.width, widget->allocation.height); + gtkps_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height); +} diff --git a/gtkplaylist.h b/gtkplaylist.h index cd0b9938..12e0b23c 100644 --- a/gtkplaylist.h +++ b/gtkplaylist.h @@ -85,4 +85,7 @@ gtkps_track_dragdrop (int y); void gtkps_handle_drag_drop (int drop_y, uint32_t *d, int length); +void +gtkps_handle_fm_drag_drop (int drop_y, void *ptr, int length); + #endif @@ -352,14 +352,91 @@ ps_add_cue (const char *cuename) { playItem_t * ps_insert_file (playItem_t *after, const char *fname) { + if (!fname) { + return NULL; + } + // detect codec + codec_t *codec = NULL; + const char *eol = fname + strlen (fname) - 1; + while (eol > fname && *eol != '.') { + eol--; + } + eol++; + + // match by codec + codec_t *codecs[] = { + &cdumb, &cvorbis, &cflac, &cgme, &cmp3, &csid, NULL + }; + for (int i = 0; codecs[i]; i++) { + if (codecs[i]->getexts && codecs[i]->insert) { + const char **exts = codecs[i]->getexts (); + if (exts) { + for (int e = 0; exts[e]; e++) { + if (!strcasecmp (exts[e], eol)) { + playItem_t *inserted = NULL; + if ((inserted = codecs[i]->insert (after, fname)) != NULL) { + return inserted; + } + } + } + } + } + } + return NULL; } playItem_t * ps_insert_dir (playItem_t *after, const char *dirname) { + struct stat buf; + lstat (dirname, &buf); + if (S_ISLNK(buf.st_mode)) { + return NULL; + } + struct dirent **namelist = NULL; + int n; + + n = scandir (dirname, &namelist, NULL, alphasort); + if (n < 0) + { + if (namelist) + free (namelist); + return NULL; // not a dir or no read access + } + else + { + int i; + for (i = 0; i < n; i++) + { + // no hidden files + if (namelist[i]->d_name[0] != '.') + { + char fullname[1024]; + strcpy (fullname, dirname); + strncat (fullname, "/", 1024); + strncat (fullname, namelist[i]->d_name, 1024); + playItem_t *inserted = ps_insert_dir (after, fullname); + if (!inserted) { + inserted = ps_insert_file (after, fullname); + } + if (inserted) { + after = inserted; + } + } + free (namelist[i]); + } + free (namelist); + } + return after; } int ps_add_file (const char *fname) { + if (ps_insert_file (playlist_tail, fname)) { + return 0; + } + return -1; +// {{{ original ps_add_file +#if 0 if (!fname) { return -1; } @@ -393,10 +470,18 @@ ps_add_file (const char *fname) { } return -1; +#endif +// }}} } int ps_add_dir (const char *dirname) { + if (ps_insert_dir (playlist_tail, dirname)) { + return 0; + } + return -1; +// {{{ original ps_add_dir code +#if 0 struct stat buf; lstat (dirname, &buf); if (S_ISLNK(buf.st_mode)) { @@ -433,6 +518,8 @@ ps_add_dir (const char *dirname) { free (namelist); } return 0; +#endif +// }}} } int |