Changeset 115 for trunk/gtk


Ignore:
Timestamp:
Feb 10, 2006, 1:49:10 AM (16 years ago)
Author:
joshe
Message:

Rewrite the drag and drop code to handle multiple files (oops),
as well as being much more robust about misformatted file URIs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/main.c

    r99 r115  
    3636#include <gtk/gtk.h>
    3737#include <glib/gi18n.h>
     38#include <glib/gstdio.h>
    3839
    3940#include "defines.h"
     
    442443        gpointer gdata) {
    443444  struct cbdata *data = gdata;
    444   char prefix[] = "file://";
    445   char *file, *sele, *targ, *type;
    446   int ii;
    447 
     445  char prefix[] = "file:";
     446  char *files, *decoded, *deslashed, *hostless;
     447  int ii, len;
     448  GList *errs;
     449  gboolean gotfile;
     450  struct stat sb;
     451  int prelen = strlen(prefix);
     452
     453#ifdef DND_DEBUG
     454  char *sele = gdk_atom_name(sel->selection);
     455  char *targ = gdk_atom_name(sel->target);
     456  char *type = gdk_atom_name(sel->type);
     457
     458  fprintf(stderr, "dropped file: sel=%s targ=%s type=%s fmt=%i len=%i\n",
     459          sele, targ, type, sel->format, sel->length);
     460  g_free(sele);
     461  g_free(targ);
     462  g_free(type);
     463  if(8 == sel->format) {
     464    for(ii = 0; ii < sel->length; ii++)
     465      fprintf(stderr, "%02X ", sel->data[ii]);
     466    fprintf(stderr, "\n");
     467  }
     468#endif
     469
     470  errs = NULL;
     471  gotfile = FALSE;
    448472  if(gdk_atom_intern("XdndSelection", FALSE) == sel->selection &&
    449      8 == sel->format && (int)sizeof(prefix) - 1 < sel->length &&
    450      0 == strncmp(prefix, sel->data, sizeof(prefix) - 1)) {
    451     file = urldecode(sel->data + (sizeof(prefix) - 1),
    452                      sel->length - (sizeof(prefix) - 1));
    453     if(g_utf8_validate(file, -1, NULL) &&
    454        addtorrent(data->tr, data->wind, file, NULL, FALSE, NULL)) {
    455       g_free(file);
    456       gtk_drag_finish(dc, TRUE, FALSE, time);
     473     8 == sel->format) {
     474    /* split file list on carriage returns and linefeeds */
     475    files = g_new(char, sel->length + 1);
     476    memcpy(files, sel->data, sel->length);
     477    files[sel->length] = '\0';
     478    for(ii = 0; '\0' != files[ii]; ii++)
     479      if('\015' == files[ii] || '\012' == files[ii])
     480        files[ii] = '\0';
     481
     482    /* try to get a usable filename out of the URI supplied and add it */
     483    for(ii = 0; ii < sel->length; ii += len + 1) {
     484      if('\0' == files[ii])
     485        len = 0;
     486      else {
     487        len = strlen(files + ii);
     488        /* de-urlencode the URI */
     489        decoded = urldecode(files + ii, len);
     490        if(g_utf8_validate(decoded, -1, NULL)) {
     491          /* remove the file: prefix */
     492          if(prelen < len && 0 == strncmp(prefix, decoded, prelen)) {
     493            deslashed = decoded + prelen;
     494            /* trim excess / characters from the beginning */
     495            while('/' == deslashed[0] && '/' == deslashed[1])
     496              deslashed++;
     497            /* if the file doesn't exist, the first part might be a hostname */
     498            if(0 > g_stat(deslashed, &sb) &&
     499               NULL != (hostless = strchr(deslashed + 1, '/')) &&
     500               0 == g_stat(hostless, &sb))
     501              deslashed = hostless;
     502            /* finally, try to add it as a torrent */
     503            if(addtorrent(data->tr, data->wind, deslashed, NULL, FALSE, &errs))
     504              gotfile = TRUE;
     505          }
     506        }
     507        g_free(decoded);
     508      }
     509    }
     510
     511    g_free(files);
     512    if(gotfile)
    457513      addedtorrents(data);
    458       return;
     514
     515    /* print any errors */
     516    if(NULL != errs) {
     517      files = joinstrlist(errs, "\n");
     518      errmsg(data->wind, ngettext("Failed to load the torrent file %s",
     519                                  "Failed to load the torrent files:\n%s",
     520                                  g_list_length(errs)), files);
     521      g_list_foreach(errs, (GFunc)g_free, NULL);
     522      g_list_free(errs);
     523      g_free(files);
    459524    }
    460     g_free(file);
    461   } else {
    462     sele = gdk_atom_name(sel->selection);
    463     targ = gdk_atom_name(sel->target);
    464     type = gdk_atom_name(sel->type);
    465     fprintf(stderr, "unhandled drag: sel=%s targ=%s type=%s fmt=%i len=%i\n",
    466             sele, targ, type, sel->format, sel->length);
    467     g_free(sele);
    468     g_free(targ);
    469     g_free(type);
    470     if(8 == sel->format) {
    471       for(ii = 0; ii < sel->length; ii++)
    472         fprintf(stderr, "%02X ", sel->data[ii]);
    473       fprintf(stderr, "\n");
    474     }
    475   }
    476 
    477   gtk_drag_finish(dc, FALSE, FALSE, time);
     525  }
     526
     527  gtk_drag_finish(dc, gotfile, FALSE, time);
    478528}
    479529
Note: See TracChangeset for help on using the changeset viewer.