(trunk gtk) rewrite the main window's drag-and-drop handler s.t. it's GTK+ 3 compliant

This commit is contained in:
Charles Kerr 2010-08-02 22:31:31 +00:00
parent 5182600179
commit 36064b8120
5 changed files with 65 additions and 193 deletions

View File

@ -200,18 +200,6 @@ static void winsetup( struct cbdata * cbdata,
static void wannaquit( gpointer vdata );
static void setupdrag( GtkWidget * widget,
struct cbdata *data );
static void gotdrag( GtkWidget * widget,
GdkDragContext * dc,
gint x,
gint y,
GtkSelectionData *sel,
guint info,
guint time,
gpointer gdata );
static void coreerr( TrCore *, guint, const char *, struct cbdata * );
static void onAddTorrent( TrCore *,
@ -862,10 +850,54 @@ rowChangedCB( GtkTreeModel * model UNUSED,
}
static void
winsetup( struct cbdata * cbdata,
TrWindow * wind )
on_drag_data_received( GtkWidget * widget UNUSED,
GdkDragContext * drag_context,
gint x UNUSED,
gint y UNUSED,
GtkSelectionData * selection_data,
guint info UNUSED,
guint time_,
gpointer gdata )
{
GtkTreeModel * model;
int i;
gboolean success = FALSE;
GSList * filenames = NULL;
struct cbdata * data = gdata;
char ** uris = gtk_selection_data_get_uris( selection_data );
/* try to add the filename URIs... */
for( i=0; uris && uris[i]; ++i )
{
const char * uri = uris[i];
char * filename = g_filename_from_uri( uri, NULL, NULL );
if( filename && g_file_test( filename, G_FILE_TEST_EXISTS ) )
{
filenames = g_slist_append( filenames, g_strdup( filename ) );
success = TRUE;
}
else if( tr_urlIsValid( uri ) )
{
tr_core_add_from_url( data->core, uri );
success = TRUE;
}
}
if( filenames )
tr_core_add_list_defaults( data->core, g_slist_reverse( filenames ), TRUE );
tr_core_torrents_added( data->core );
gtk_drag_finish( drag_context, success, FALSE, time_ );
/* cleanup */
g_strfreev( uris );
}
static void
winsetup( struct cbdata * cbdata, TrWindow * wind )
{
GtkWidget * w;
GtkTreeModel * model;
GtkTreeSelection * sel;
g_assert( NULL == cbdata->wind );
@ -879,7 +911,11 @@ winsetup( struct cbdata * cbdata,
g_signal_connect( wind, "delete-event", G_CALLBACK( winclose ), cbdata );
refreshActions( cbdata );
setupdrag( GTK_WIDGET( wind ), cbdata );
/* register to handle URIs that get dragged onto our main window */
w = GTK_WIDGET( wind );
gtk_drag_dest_set( w, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY );
gtk_drag_dest_add_uri_targets( w );
g_signal_connect( w, "drag-data-received", G_CALLBACK(on_drag_data_received), cbdata );
}
static gboolean
@ -995,103 +1031,6 @@ wannaquit( gpointer vdata )
g_thread_create( sessionCloseThreadFunc, vdata, TRUE, NULL );
}
static void
gotdrag( GtkWidget * widget UNUSED,
GdkDragContext * dc,
gint x UNUSED,
gint y UNUSED,
GtkSelectionData * sel,
guint info UNUSED,
guint time,
gpointer gdata )
{
struct cbdata * data = gdata;
GSList * paths = NULL;
GSList * freeme = NULL;
#if 0
int i;
char * sele = gdk_atom_name( sel->selection );
char * targ = gdk_atom_name( sel->target );
char * type = gdk_atom_name( sel->type );
g_message( "dropped file: sel=%s targ=%s type=%s fmt=%i len=%i",
sele, targ, type, sel->format, sel->length );
g_free( sele );
g_free( targ );
g_free( type );
if( sel->format == 8 )
{
for( i = 0; i < sel->length; ++i )
fprintf( stderr, "%02X ", sel->data[i] );
fprintf( stderr, "\n" );
}
#endif
if( ( sel->format == 8 )
&& ( sel->selection == gdk_atom_intern( "XdndSelection", FALSE ) ) )
{
int i;
char * str = g_strndup( (char*)sel->data, sel->length );
gchar ** files = g_strsplit_set( str, "\r\n", -1 );
for( i = 0; files && files[i]; ++i )
{
char * filename;
if( !*files[i] ) /* empty filename... */
continue;
/* decode the filename */
filename = decode_uri( files[i] );
freeme = g_slist_prepend( freeme, filename );
if( !g_utf8_validate( filename, -1, NULL ) )
continue;
/* walk past "file://", if present */
if( g_str_has_prefix( filename, "file:" ) ) {
filename += 5;
while( g_str_has_prefix( filename, "//" ) )
++filename;
}
if( g_file_test( filename, G_FILE_TEST_EXISTS ) )
paths = g_slist_prepend( paths, g_strdup( filename ) );
else
tr_core_add_from_url( data->core, filename );
}
/* try to add any torrents we found */
if( paths )
{
paths = g_slist_reverse( paths );
tr_core_add_list_defaults( data->core, paths, TRUE );
tr_core_torrents_added( data->core );
}
freestrlist( freeme );
g_strfreev( files );
g_free( str );
}
gtk_drag_finish( dc, ( NULL != paths ), FALSE, time );
}
static void
setupdrag( GtkWidget * widget,
struct cbdata *data )
{
GtkTargetEntry targets[] = {
{ (char*)"STRING", 0, 0 },
{ (char*)"text/plain", 0, 0 },
{ (char*)"text/uri-list", 0, 0 },
};
g_signal_connect( widget, "drag_data_received", G_CALLBACK(
gotdrag ), data );
gtk_drag_dest_set( widget, GTK_DEST_DEFAULT_ALL, targets,
G_N_ELEMENTS( targets ), GDK_ACTION_COPY | GDK_ACTION_MOVE );
}
static void
flushAddTorrentErrors( GtkWindow * window,
const char * primary,

View File

@ -381,14 +381,15 @@ getDefaultSavePath( void )
static void
on_drag_data_received( GtkWidget * widget UNUSED,
GdkDragContext * drag_context UNUSED,
GdkDragContext * drag_context,
gint x UNUSED,
gint y UNUSED,
GtkSelectionData * selection_data,
guint info UNUSED,
guint time UNUSED,
guint time_,
gpointer user_data )
{
gboolean success = FALSE;
MakeMetaUI * ui = user_data;
char ** uris = gtk_selection_data_get_uris( selection_data );
@ -402,18 +403,21 @@ on_drag_data_received( GtkWidget * widget UNUSED,
/* a directory was dragged onto the dialog... */
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( ui->folder_radio ), TRUE );
gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( ui->folder_chooser ), filename );
success = TRUE;
}
else if( g_file_test( filename, G_FILE_TEST_IS_REGULAR ) )
{
/* a file was dragged on to the dialog... */
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( ui->file_radio ), TRUE );
gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( ui->file_chooser ), filename );
success = TRUE;
}
g_free( filename );
}
g_strfreev( uris );
gtk_drag_finish( drag_context, success, FALSE, time_ );
}
GtkWidget*

View File

@ -1209,10 +1209,15 @@ tr_core_add_list( TrCore * core,
GSList * l;
for( l = torrentFiles; l != NULL; l = l->next )
add_filename( core, l->data, doStart, doPrompt, doNotify );
{
char * filename = l->data;
add_filename( core, filename, doStart, doPrompt, doNotify );
g_free( filename );
}
tr_core_torrents_added( core );
freestrlist( torrentFiles );
g_slist_free( torrentFiles );
}
void

View File

@ -252,69 +252,6 @@ gtr_mkdir_with_parents( const char * path, int mode )
#endif
}
GSList *
dupstrlist( GSList * l )
{
GSList * ret = NULL;
for( ; l != NULL; l = l->next )
ret = g_slist_prepend( ret, g_strdup( l->data ) );
return g_slist_reverse( ret );
}
char *
joinstrlist( GSList *list,
char * sep )
{
GSList * l;
GString *gstr = g_string_new ( NULL );
for( l = list; l != NULL; l = l->next )
{
g_string_append ( gstr, (char*)l->data );
if( l->next != NULL )
g_string_append ( gstr, ( sep ) );
}
return g_string_free ( gstr, FALSE );
}
void
freestrlist( GSList *list )
{
g_slist_foreach ( list, (GFunc)g_free, NULL );
g_slist_free ( list );
}
char *
decode_uri( const char * uri )
{
gboolean in_query = FALSE;
char * ret = g_new( char, strlen( uri ) + 1 );
char * out = ret;
for( ; uri && *uri; )
{
char ch = *uri;
if( ch == '?' )
in_query = TRUE;
else if( ch == '+' && in_query )
ch = ' ';
else if( ch == '%' && isxdigit( (unsigned char)uri[1] )
&& isxdigit( (unsigned char)uri[2] ) )
{
char buf[3] = { uri[1], uri[2], '\0' };
ch = (char) g_ascii_strtoull( buf, NULL, 16 );
uri += 2;
}
++uri;
*out++ = ch;
}
*out = '\0';
return ret;
}
/* pattern-matching text; ie, legaltorrents.com */
char*
gtr_get_host_from_url( const char * url )

View File

@ -91,19 +91,6 @@ gboolean gtr_is_magnet_link( const char * str );
gboolean gtr_is_hex_hashcode( const char * str );
/* create a copy of a GSList of strings, this dups the actual strings too */
GSList * dupstrlist( GSList * list );
/* joins a GSList of strings into one string using an optional separator */
char * joinstrlist( GSList *list, char * sep );
/* free a GSList of strings */
void freestrlist( GSList *list );
/* decodes a string that has been urlencoded */
char * decode_uri( const char * uri );
/***
****
***/