(gtk) try to iron out the remaining "add torrent" issues reported by wereHamster and Lacrocivous
This commit is contained in:
parent
ac21d3280c
commit
0437c5f33e
160
gtk/dialogs.c
160
gtk/dialogs.c
|
@ -33,152 +33,6 @@
|
|||
#include "tr-core.h"
|
||||
#include "tr-prefs.h"
|
||||
|
||||
struct dirdata
|
||||
{
|
||||
GtkWidget * widget;
|
||||
TrCore * core;
|
||||
GList * files;
|
||||
tr_ctor * ctor;
|
||||
};
|
||||
|
||||
static void
|
||||
promptdirnocore( gpointer gdata, GObject * core UNUSED )
|
||||
{
|
||||
struct dirdata * stuff = gdata;
|
||||
|
||||
/* prevent the response callback from trying to remove the weak
|
||||
reference which no longer exists */
|
||||
stuff->core = NULL;
|
||||
|
||||
gtk_dialog_response( GTK_DIALOG( stuff->widget ), GTK_RESPONSE_NONE );
|
||||
}
|
||||
|
||||
static void
|
||||
promptresp( GtkWidget * widget, gint resp, gpointer data )
|
||||
{
|
||||
struct dirdata * stuff;
|
||||
|
||||
stuff = data;
|
||||
|
||||
if( GTK_RESPONSE_ACCEPT == resp )
|
||||
{
|
||||
char * dir;
|
||||
GList * l;
|
||||
|
||||
/* update the destination */
|
||||
dir = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( widget ) );
|
||||
tr_ctorSetDestination( stuff->ctor, TR_FORCE, dir );
|
||||
g_free( dir );
|
||||
|
||||
/* if there's metainfo in the ctor already, use it */
|
||||
if( !tr_ctorGetMetainfo( stuff->ctor, NULL ) )
|
||||
tr_core_add_ctor( stuff->core, stuff->ctor );
|
||||
|
||||
/* if there's a list of files, use them too */
|
||||
for( l=stuff->files; l!=NULL; l=l->next )
|
||||
if( !tr_ctorSetMetainfoFromFile( stuff->ctor, l->data ) )
|
||||
tr_core_add_ctor( stuff->core, stuff->ctor );
|
||||
}
|
||||
|
||||
if( stuff->core )
|
||||
g_object_weak_unref( G_OBJECT( stuff->core ), promptdirnocore, stuff );
|
||||
|
||||
gtk_widget_destroy( widget );
|
||||
freestrlist( stuff->files );
|
||||
tr_ctorFree( stuff->ctor );
|
||||
g_free( stuff );
|
||||
}
|
||||
|
||||
void
|
||||
fmtpeercount( GtkLabel * label, int count )
|
||||
{
|
||||
char str[16];
|
||||
|
||||
if( 0 > count )
|
||||
{
|
||||
gtk_label_set_text( label, "?" );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_snprintf( str, sizeof str, "%i", count );
|
||||
gtk_label_set_text( label, str );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deleteToggled( GtkToggleButton * tb, gpointer ctor )
|
||||
{
|
||||
tr_ctorSetDeleteSource( ctor, gtk_toggle_button_get_active( tb ) );
|
||||
}
|
||||
|
||||
static void
|
||||
startToggled( GtkToggleButton * tb, gpointer ctor )
|
||||
{
|
||||
tr_ctorSetPaused( ctor, TR_FORCE, !gtk_toggle_button_get_active( tb ) );
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
promptfordir( GtkWindow * parent, TrCore * core, GList * files, tr_ctor * ctor )
|
||||
{
|
||||
uint8_t flag = 0;
|
||||
const char * str;
|
||||
struct dirdata * stuff;
|
||||
GtkWidget * wind;
|
||||
GtkWidget * v;
|
||||
GtkWidget * w;
|
||||
|
||||
stuff = g_new0( struct dirdata, 1 );
|
||||
stuff->core = core;
|
||||
stuff->ctor = ctor;
|
||||
stuff->files = dupstrlist( files );
|
||||
|
||||
g_object_weak_ref( G_OBJECT( core ), promptdirnocore, stuff );
|
||||
|
||||
wind = gtk_file_chooser_dialog_new( _("Destination folder"), parent,
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
NULL );
|
||||
gtk_dialog_set_alternative_button_order( GTK_DIALOG( wind ),
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
GTK_RESPONSE_CANCEL,
|
||||
-1 );
|
||||
gtk_file_chooser_set_local_only( GTK_FILE_CHOOSER( wind ), TRUE );
|
||||
gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER( wind ), FALSE );
|
||||
if( tr_ctorGetDestination( ctor, TR_FORCE, &str ) )
|
||||
g_assert_not_reached( );
|
||||
if( !gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( wind ), str ) )
|
||||
g_warning( "couldn't set destination '%s'", str );
|
||||
|
||||
v = gtk_vbox_new( FALSE, GUI_PAD );
|
||||
|
||||
flag = 0;
|
||||
w = gtk_check_button_new_with_mnemonic( _( "_Trash original torrent files" ) );
|
||||
g_signal_connect( w, "toggled", G_CALLBACK( deleteToggled ), ctor );
|
||||
if( tr_ctorGetDeleteSource( ctor, &flag ) )
|
||||
g_assert_not_reached( );
|
||||
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), flag );
|
||||
gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 );
|
||||
|
||||
flag = 1;
|
||||
w = gtk_check_button_new_with_mnemonic( _( "_Start when added" ) );
|
||||
g_signal_connect( w, "toggled", G_CALLBACK( startToggled ), ctor );
|
||||
if( tr_ctorGetPaused( ctor, TR_FORCE, &flag ) )
|
||||
g_assert_not_reached( );
|
||||
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), !flag );
|
||||
gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 );
|
||||
|
||||
gtk_file_chooser_set_extra_widget( GTK_FILE_CHOOSER( wind ), v );
|
||||
|
||||
stuff->widget = wind;
|
||||
|
||||
g_signal_connect( G_OBJECT( wind ), "response",
|
||||
G_CALLBACK( promptresp ), stuff );
|
||||
|
||||
gtk_widget_show_all( wind );
|
||||
return wind;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
@ -287,17 +141,17 @@ askquit( TrCore * core,
|
|||
struct DeleteData
|
||||
{
|
||||
gboolean delete_files;
|
||||
GList * torrents;
|
||||
GSList * torrents;
|
||||
TrCore * core;
|
||||
};
|
||||
|
||||
static void
|
||||
removeTorrents( struct DeleteData * data )
|
||||
{
|
||||
GList * l;
|
||||
GSList * l;
|
||||
for( l=data->torrents; l!=NULL; l=l->next )
|
||||
tr_core_remove_torrent( data->core, l->data, data->delete_files );
|
||||
g_list_free( data->torrents );
|
||||
g_slist_free( data->torrents );
|
||||
}
|
||||
|
||||
|
||||
|
@ -309,7 +163,7 @@ removeResponse( GtkDialog * dialog, gint response, gpointer gdata )
|
|||
if( response == GTK_RESPONSE_ACCEPT )
|
||||
removeTorrents( data );
|
||||
else
|
||||
g_list_foreach( data->torrents, (GFunc)g_object_unref, NULL );
|
||||
g_slist_foreach( data->torrents, (GFunc)g_object_unref, NULL );
|
||||
|
||||
gtk_widget_destroy( GTK_WIDGET( dialog ) );
|
||||
g_free( data );
|
||||
|
@ -327,13 +181,13 @@ countBusyTorrents( gpointer gtor, gpointer busyCount )
|
|||
void
|
||||
confirmRemove( GtkWindow * parent,
|
||||
TrCore * core,
|
||||
GList * torrents,
|
||||
GSList * torrents,
|
||||
gboolean delete_files )
|
||||
{
|
||||
GtkWidget * d;
|
||||
struct DeleteData * dd;
|
||||
int busyCount;
|
||||
const int count = g_list_length( torrents );
|
||||
const int count = g_slist_length( torrents );
|
||||
const char * primary_text;
|
||||
const char * secondary_text;
|
||||
|
||||
|
@ -346,7 +200,7 @@ confirmRemove( GtkWindow * parent,
|
|||
dd->delete_files = delete_files;
|
||||
|
||||
busyCount = 0;
|
||||
g_list_foreach( torrents, countBusyTorrents, &busyCount );
|
||||
g_slist_foreach( torrents, countBusyTorrents, &busyCount );
|
||||
|
||||
if( !busyCount && !delete_files ) /* don't prompt boring torrents */
|
||||
{
|
||||
|
|
|
@ -29,18 +29,12 @@
|
|||
#include "tr-torrent.h"
|
||||
#include "util.h"
|
||||
|
||||
/* prompt for a download folder for torrents, then add them */
|
||||
GtkWidget* promptfordir( GtkWindow * parent,
|
||||
TrCore * core,
|
||||
GList * filenames,
|
||||
tr_ctor * ctor );
|
||||
|
||||
/* prompt if the user wants to quit, calls func with cbdata if they do */
|
||||
void askquit( TrCore*, GtkWindow* parent, callbackfunc_t func, void* cbdata );
|
||||
|
||||
void confirmRemove( GtkWindow * parent,
|
||||
TrCore * core,
|
||||
GList * gtorrents,
|
||||
GSList * gtorrents,
|
||||
gboolean doDelete );
|
||||
|
||||
#endif /* TG_PREFS_H */
|
||||
|
|
22
gtk/ipc.c
22
gtk/ipc.c
|
@ -72,7 +72,7 @@ struct constate_client
|
|||
{
|
||||
GMainLoop * loop;
|
||||
enum ipc_msg msg;
|
||||
GList * files;
|
||||
GSList * files;
|
||||
gboolean * succeeded;
|
||||
unsigned int msgid;
|
||||
};
|
||||
|
@ -162,7 +162,7 @@ static void
|
|||
client_sendmsg( struct constate * con )
|
||||
{
|
||||
struct constate_client * cli = &con->u.client;
|
||||
GList * ii;
|
||||
GSList * ii;
|
||||
uint8_t * buf;
|
||||
size_t size;
|
||||
tr_benc packet, * val;
|
||||
|
@ -173,7 +173,7 @@ client_sendmsg( struct constate * con )
|
|||
case IPC_MSG_ADDMANYFILES:
|
||||
val = ipc_initval( con->ipc, cli->msg, -1, &packet, TYPE_LIST );
|
||||
if( NULL == val ||
|
||||
tr_bencListReserve( val, g_list_length( cli->files ) ) )
|
||||
tr_bencListReserve( val, g_slist_length( cli->files ) ) )
|
||||
{
|
||||
perror( "malloc" );
|
||||
destroycon( con );
|
||||
|
@ -186,7 +186,7 @@ client_sendmsg( struct constate * con )
|
|||
buf = ipc_mkval( &packet, &size );
|
||||
saved = errno;
|
||||
tr_bencFree( &packet );
|
||||
g_list_free( cli->files );
|
||||
g_slist_free( cli->files );
|
||||
cli->files = NULL;
|
||||
break;
|
||||
case IPC_MSG_QUIT:
|
||||
|
@ -298,7 +298,7 @@ client_connect(char *path, struct constate *con) {
|
|||
}
|
||||
|
||||
static gboolean
|
||||
blocking_client( enum ipc_msg msgid, GList * files )
|
||||
blocking_client( enum ipc_msg msgid, GSList * files )
|
||||
{
|
||||
|
||||
struct constate *con;
|
||||
|
@ -347,7 +347,7 @@ blocking_client( enum ipc_msg msgid, GList * files )
|
|||
}
|
||||
|
||||
gboolean
|
||||
ipc_sendfiles_blocking( GList * files )
|
||||
ipc_sendfiles_blocking( GSList * files )
|
||||
{
|
||||
return blocking_client( IPC_MSG_ADDMANYFILES, files );
|
||||
}
|
||||
|
@ -498,8 +498,7 @@ smsg_add( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, void * arg )
|
|||
struct constate_serv * srv = &con->u.serv;
|
||||
tr_benc * path;
|
||||
int ii;
|
||||
tr_ctor * ctor;
|
||||
GList * list = NULL;
|
||||
GSList * list = NULL;
|
||||
|
||||
if( NULL == val || TYPE_LIST != val->type )
|
||||
{
|
||||
|
@ -507,8 +506,6 @@ smsg_add( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, void * arg )
|
|||
return;
|
||||
}
|
||||
|
||||
ctor = tr_ctorNew( srv->core );
|
||||
|
||||
for( ii = 0; ii < val->val.l.count; ii++ )
|
||||
{
|
||||
path = val->val.l.vals + ii;
|
||||
|
@ -516,12 +513,13 @@ smsg_add( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, void * arg )
|
|||
/* XXX somehow escape invalid utf-8 */
|
||||
g_utf8_validate( path->val.s.s, path->val.s.i, NULL ) )
|
||||
{
|
||||
list = g_list_append( list, g_strndup( path->val.s.s, path->val.s.i ) );
|
||||
list = g_slist_prepend( list, g_strndup( path->val.s.s, path->val.s.i ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( list ) {
|
||||
tr_core_add_list( srv->core, list, ctor );
|
||||
list = g_slist_reverse( list );
|
||||
tr_core_add_list( srv->core, list, FALSE );
|
||||
tr_core_torrents_added( TR_CORE( srv->core ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ void
|
|||
ipc_socket_setup( GtkWindow * wind, TrCore * core );
|
||||
|
||||
gboolean
|
||||
ipc_sendfiles_blocking( GList * files );
|
||||
ipc_sendfiles_blocking( GSList * files );
|
||||
|
||||
gboolean
|
||||
ipc_sendquit_blocking( void );
|
||||
|
|
97
gtk/main.c
97
gtk/main.c
|
@ -112,7 +112,7 @@ struct cbdata
|
|||
TrCore * core;
|
||||
GtkWidget * msgwin;
|
||||
GtkWidget * prefs;
|
||||
GList * errqueue;
|
||||
GSList * errqueue;
|
||||
GHashTable * tor2details;
|
||||
GHashTable * details2tor;
|
||||
};
|
||||
|
@ -122,9 +122,9 @@ struct cbdata
|
|||
static GtkUIManager * myUIManager = NULL;
|
||||
|
||||
static gboolean
|
||||
sendremote( GList * files, gboolean sendquit );
|
||||
sendremote( GSList * files, gboolean sendquit );
|
||||
static void
|
||||
appsetup( TrWindow * wind, GList * args,
|
||||
appsetup( TrWindow * wind, GSList * args,
|
||||
struct cbdata *,
|
||||
gboolean paused, gboolean minimized );
|
||||
static void
|
||||
|
@ -141,7 +141,7 @@ static void
|
|||
coreerr( TrCore * core, enum tr_core_err code, const char * msg,
|
||||
gpointer gdata );
|
||||
static void
|
||||
coreprompt( TrCore *, GList *, gpointer, gpointer );
|
||||
onAddTorrent( TrCore *, tr_ctor *, gpointer );
|
||||
static void
|
||||
prefschanged( TrCore * core, const char * key, gpointer data );
|
||||
static gboolean
|
||||
|
@ -256,7 +256,7 @@ main( int argc, char ** argv )
|
|||
{
|
||||
char * err;
|
||||
struct cbdata * cbdata;
|
||||
GList * argfiles;
|
||||
GSList * argfiles;
|
||||
GError * gerr;
|
||||
gboolean didinit = FALSE;
|
||||
gboolean didlock = FALSE;
|
||||
|
@ -335,7 +335,7 @@ main( int argc, char ** argv )
|
|||
}
|
||||
|
||||
static gboolean
|
||||
sendremote( GList * files, gboolean sendquit )
|
||||
sendremote( GSList * files, gboolean sendquit )
|
||||
{
|
||||
const gboolean didlock = cf_lock( NULL );
|
||||
|
||||
|
@ -351,7 +351,7 @@ sendremote( GList * files, gboolean sendquit )
|
|||
}
|
||||
|
||||
static void
|
||||
appsetup( TrWindow * wind, GList * args,
|
||||
appsetup( TrWindow * wind, GSList * torrentFiles,
|
||||
struct cbdata * cbdata,
|
||||
gboolean forcepause, gboolean minimized )
|
||||
{
|
||||
|
@ -369,8 +369,8 @@ appsetup( TrWindow * wind, GList * args,
|
|||
|
||||
/* set up core handlers */
|
||||
g_signal_connect( cbdata->core, "error", G_CALLBACK( coreerr ), cbdata );
|
||||
g_signal_connect( cbdata->core, "destination-prompt",
|
||||
G_CALLBACK( coreprompt ), cbdata );
|
||||
g_signal_connect( cbdata->core, "add-torrent-prompt",
|
||||
G_CALLBACK( onAddTorrent ), cbdata );
|
||||
g_signal_connect_swapped( cbdata->core, "quit",
|
||||
G_CALLBACK( wannaquit ), cbdata );
|
||||
g_signal_connect( cbdata->core, "prefs-changed",
|
||||
|
@ -378,14 +378,8 @@ appsetup( TrWindow * wind, GList * args,
|
|||
|
||||
/* add torrents from command-line and saved state */
|
||||
tr_core_load( cbdata->core, forcepause );
|
||||
|
||||
if( NULL != args )
|
||||
{
|
||||
tr_ctor * ctor = tr_ctorNew( tr_core_handle( cbdata->core ) );
|
||||
if( forcepause )
|
||||
tr_ctorSetPaused( ctor, TR_FORCE, TRUE );
|
||||
tr_core_add_list( cbdata->core, args, ctor );
|
||||
}
|
||||
tr_core_add_list( cbdata->core, torrentFiles, forcepause );
|
||||
torrentFiles = NULL;
|
||||
tr_core_torrents_added( cbdata->core );
|
||||
|
||||
/* set up the ipc socket */
|
||||
|
@ -545,8 +539,8 @@ quitThreadFunc( gpointer gdata )
|
|||
if( cbdata->icon )
|
||||
g_object_unref( cbdata->icon );
|
||||
if( cbdata->errqueue ) {
|
||||
g_list_foreach( cbdata->errqueue, (GFunc)g_free, NULL );
|
||||
g_list_free( cbdata->errqueue );
|
||||
g_slist_foreach( cbdata->errqueue, (GFunc)g_free, NULL );
|
||||
g_slist_free( cbdata->errqueue );
|
||||
}
|
||||
|
||||
g_hash_table_destroy( cbdata->details2tor );
|
||||
|
@ -637,8 +631,8 @@ gotdrag( GtkWidget * widget UNUSED,
|
|||
gpointer gdata )
|
||||
{
|
||||
struct cbdata * data = gdata;
|
||||
GList * paths = NULL;
|
||||
GList * freeme = NULL;
|
||||
GSList * paths = NULL;
|
||||
GSList * freeme = NULL;
|
||||
|
||||
#if 0
|
||||
int i;
|
||||
|
@ -672,7 +666,7 @@ gotdrag( GtkWidget * widget UNUSED,
|
|||
|
||||
/* decode the filename */
|
||||
filename = decode_uri( files[i] );
|
||||
freeme = g_list_prepend( freeme, filename );
|
||||
freeme = g_slist_prepend( freeme, filename );
|
||||
if( !g_utf8_validate( filename, -1, NULL ) )
|
||||
continue;
|
||||
|
||||
|
@ -693,17 +687,15 @@ gotdrag( GtkWidget * widget UNUSED,
|
|||
|
||||
/* finally, add it to the list of torrents to try adding */
|
||||
if( g_file_test( filename, G_FILE_TEST_EXISTS ) )
|
||||
paths = g_list_prepend( paths, filename );
|
||||
paths = g_slist_prepend( paths, g_strdup( filename ) );
|
||||
}
|
||||
|
||||
/* try to add any torrents we found */
|
||||
if( paths != NULL )
|
||||
if( paths )
|
||||
{
|
||||
tr_ctor * ctor = tr_ctorNew( tr_core_handle( data->core ) );
|
||||
paths = g_list_reverse( paths );
|
||||
tr_core_add_list( data->core, paths, ctor );
|
||||
paths = g_slist_reverse( paths );
|
||||
tr_core_add_list( data->core, paths, FALSE );
|
||||
tr_core_torrents_added( data->core );
|
||||
g_list_free( paths );
|
||||
}
|
||||
|
||||
freestrlist( freeme );
|
||||
|
@ -738,20 +730,20 @@ coreerr( TrCore * core UNUSED, enum tr_core_err code, const char * msg,
|
|||
switch( code )
|
||||
{
|
||||
case TR_CORE_ERR_ADD_TORRENT:
|
||||
cbdata->errqueue = g_list_append( cbdata->errqueue,
|
||||
g_strdup( msg ) );
|
||||
cbdata->errqueue = g_slist_append( cbdata->errqueue,
|
||||
g_strdup( msg ) );
|
||||
return;
|
||||
case TR_CORE_ERR_NO_MORE_TORRENTS:
|
||||
if( NULL != cbdata->errqueue )
|
||||
if( cbdata->errqueue )
|
||||
{
|
||||
joined = joinstrlist( cbdata->errqueue, "\n" );
|
||||
errmsg( cbdata->wind,
|
||||
ngettext( "Failed to load torrent file: %s",
|
||||
"Failed to load torrent files: %s",
|
||||
g_list_length( cbdata->errqueue ) ),
|
||||
g_slist_length( cbdata->errqueue ) ),
|
||||
joined );
|
||||
g_list_foreach( cbdata->errqueue, (GFunc) g_free, NULL );
|
||||
g_list_free( cbdata->errqueue );
|
||||
g_slist_foreach( cbdata->errqueue, (GFunc) g_free, NULL );
|
||||
g_slist_free( cbdata->errqueue );
|
||||
cbdata->errqueue = NULL;
|
||||
g_free( joined );
|
||||
}
|
||||
|
@ -776,29 +768,13 @@ on_main_window_focus_in( GtkWidget * widget UNUSED,
|
|||
#endif
|
||||
|
||||
static void
|
||||
coreprompt( TrCore * core,
|
||||
GList * paths,
|
||||
gpointer ctor,
|
||||
gpointer gdata )
|
||||
onAddTorrent( TrCore * core, tr_ctor * ctor, gpointer gdata )
|
||||
{
|
||||
struct cbdata * cbdata = gdata;
|
||||
const int len = g_list_length( paths );
|
||||
GtkWidget * w;
|
||||
|
||||
if( len > 1 )
|
||||
w = promptfordir( cbdata->wind, core, paths, ctor );
|
||||
else {
|
||||
if( len == 1 )
|
||||
tr_ctorSetMetainfoFromFile( ctor, paths->data );
|
||||
w = makeaddwind( cbdata->wind, core, ctor );
|
||||
}
|
||||
|
||||
GtkWidget * w = openSingleTorrentDialog( cbdata->wind, core, ctor );
|
||||
#if GTK_CHECK_VERSION(2,8,0)
|
||||
if( w )
|
||||
if( cbdata->wind )
|
||||
gtk_window_set_urgency_hint( GTK_WINDOW( w ), TRUE );
|
||||
g_signal_connect( w, "focus-in-event",
|
||||
G_CALLBACK(on_main_window_focus_in), cbdata );
|
||||
g_signal_connect( w, "focus-in-event", G_CALLBACK(on_main_window_focus_in), cbdata );
|
||||
gtk_window_set_urgency_hint( cbdata->wind, TRUE );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -999,21 +975,23 @@ accumulateSelectedTorrents( GtkTreeModel * model,
|
|||
GtkTreeIter * iter,
|
||||
gpointer gdata )
|
||||
{
|
||||
GList ** data = ( GList** ) gdata;
|
||||
GSList ** data = ( GSList** ) gdata;
|
||||
TrTorrent * tor = NULL;
|
||||
gtk_tree_model_get( model, iter, MC_TORRENT, &tor, -1 );
|
||||
*data = g_list_append( *data, tor );
|
||||
*data = g_slist_prepend( *data, tor );
|
||||
}
|
||||
|
||||
static void
|
||||
removeSelected( struct cbdata * data, gboolean delete_files )
|
||||
{
|
||||
GList * l = NULL;
|
||||
GSList * l = NULL;
|
||||
GtkTreeSelection * s = tr_window_get_selection( data->wind );
|
||||
gtk_tree_selection_selected_foreach( s, accumulateSelectedTorrents, &l );
|
||||
gtk_tree_selection_unselect_all( s );
|
||||
if( l )
|
||||
if( l ) {
|
||||
l = g_slist_reverse( l );
|
||||
confirmRemove( data->wind, data->core, l, delete_files );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1024,8 +1002,7 @@ doAction ( const char * action_name, gpointer user_data )
|
|||
|
||||
if ( !strcmp (action_name, "open-torrent-menu") || !strcmp( action_name, "open-torrent-toolbar" ))
|
||||
{
|
||||
tr_core_add_list( data->core, NULL,
|
||||
tr_ctorNew( tr_core_handle( data->core ) ) );
|
||||
openDialog( data->wind, data->core );
|
||||
}
|
||||
else if (!strcmp (action_name, "show-stats"))
|
||||
{
|
||||
|
|
|
@ -126,9 +126,9 @@ destinationChanged( GtkFileChooserButton * b, gpointer gdata )
|
|||
****/
|
||||
|
||||
GtkWidget*
|
||||
makeaddwind( GtkWindow * parent,
|
||||
TrCore * core,
|
||||
tr_ctor * ctor )
|
||||
openSingleTorrentDialog( GtkWindow * parent,
|
||||
TrCore * core,
|
||||
tr_ctor * ctor )
|
||||
{
|
||||
int row;
|
||||
int col;
|
||||
|
@ -240,3 +240,42 @@ makeaddwind( GtkWindow * parent,
|
|||
gtk_widget_show_all( d );
|
||||
return d;
|
||||
}
|
||||
|
||||
/****
|
||||
*****
|
||||
****/
|
||||
|
||||
static void
|
||||
onOpenDialogResponse( GtkDialog * dialog, int response, gpointer core )
|
||||
{
|
||||
if( response == GTK_RESPONSE_ACCEPT )
|
||||
{
|
||||
GSList * l = gtk_file_chooser_get_filenames( GTK_FILE_CHOOSER( dialog ) );
|
||||
tr_core_add_list( core, l, FALSE );
|
||||
}
|
||||
|
||||
gtk_widget_destroy( GTK_WIDGET( dialog ) );
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
openDialog( GtkWindow * parent,
|
||||
TrCore * core )
|
||||
{
|
||||
GtkWidget * w;
|
||||
|
||||
w = gtk_file_chooser_dialog_new( _( "Select Torrents" ), parent,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
NULL );
|
||||
gtk_dialog_set_alternative_button_order( GTK_DIALOG( w ),
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
GTK_RESPONSE_CANCEL,
|
||||
-1 );
|
||||
gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER( w ), TRUE );
|
||||
|
||||
g_signal_connect( w, "response", G_CALLBACK(onOpenDialogResponse), core );
|
||||
|
||||
gtk_widget_show( w );
|
||||
return w;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
#include <gtk/gtkwindow.h>
|
||||
#include "tr-core.h"
|
||||
|
||||
GtkWidget* makeaddwind( GtkWindow * parent,
|
||||
TrCore * core,
|
||||
tr_ctor * ctor );
|
||||
/* This dialog assumes ownership of the ctor */
|
||||
GtkWidget* openSingleTorrentDialog( GtkWindow * parent,
|
||||
TrCore * core,
|
||||
tr_ctor * ctor );
|
||||
|
||||
GtkWidget* openDialog( GtkWindow * parent,
|
||||
TrCore * core );
|
||||
|
||||
#endif /* TR_GTK_OPEN_DIALOG */
|
||||
|
|
|
@ -45,7 +45,7 @@ struct TrCorePrivate
|
|||
GFileMonitor * monitor;
|
||||
gulong monitor_tag;
|
||||
char * monitor_path;
|
||||
GList * monitor_files;
|
||||
GSList * monitor_files;
|
||||
guint monitor_idle_tag;
|
||||
#endif
|
||||
GtkTreeModel * model;
|
||||
|
@ -83,22 +83,20 @@ tr_core_marshal_prompt( GClosure * closure, GValue * ret UNUSED,
|
|||
guint count, const GValue * vals,
|
||||
gpointer hint UNUSED, gpointer marshal )
|
||||
{
|
||||
typedef void (*TRMarshalPrompt)( gpointer, GList *, gpointer, gpointer );
|
||||
typedef void (*TRMarshalPrompt)( gpointer, tr_ctor *, gpointer );
|
||||
TRMarshalPrompt callback;
|
||||
GCClosure * cclosure = (GCClosure*) closure;
|
||||
GList * paths;
|
||||
gpointer ctor;
|
||||
gpointer inst, gdata;
|
||||
|
||||
g_return_if_fail( count == 3 );
|
||||
g_return_if_fail( count == 2 );
|
||||
|
||||
inst = g_value_peek_pointer( vals );
|
||||
paths = g_value_peek_pointer( vals + 1 );
|
||||
ctor = g_value_peek_pointer( vals + 2 );
|
||||
ctor = g_value_peek_pointer( vals + 1 );
|
||||
gdata = closure->data;
|
||||
|
||||
callback = (TRMarshalPrompt)( marshal ? marshal : cclosure->callback );
|
||||
callback( inst, paths, ctor, gdata );
|
||||
callback( inst, ctor, gdata );
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -141,11 +139,11 @@ tr_core_class_init( gpointer g_class, gpointer g_class_data UNUSED )
|
|||
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
||||
tr_core_marshal_err, G_TYPE_NONE,
|
||||
2, G_TYPE_INT, G_TYPE_STRING );
|
||||
core_class->promptsig = g_signal_new( "destination-prompt",
|
||||
core_class->promptsig = g_signal_new( "add-torrent-prompt",
|
||||
G_TYPE_FROM_CLASS( g_class ),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
||||
tr_core_marshal_prompt, G_TYPE_NONE,
|
||||
2, G_TYPE_POINTER, G_TYPE_POINTER );
|
||||
1, G_TYPE_POINTER );
|
||||
core_class->quitsig = g_signal_new( "quit", G_TYPE_FROM_CLASS( g_class ),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
|
@ -311,13 +309,8 @@ tr_core_apply_defaults( tr_ctor * ctor )
|
|||
static gboolean
|
||||
watchFolderIdle( gpointer gcore )
|
||||
{
|
||||
TrCore * core;
|
||||
tr_ctor * ctor;
|
||||
|
||||
/* add these files */
|
||||
core = TR_CORE( gcore );
|
||||
ctor = tr_ctorNew( core->priv->handle );
|
||||
tr_core_add_list( core, core->priv->monitor_files, ctor );
|
||||
TrCore * core = TR_CORE( gcore );
|
||||
tr_core_add_list( core, core->priv->monitor_files, FALSE );
|
||||
|
||||
/* cleanup */
|
||||
core->priv->monitor_files = NULL;
|
||||
|
@ -334,8 +327,8 @@ maybeAddTorrent( TrCore * core, const char * filename )
|
|||
{
|
||||
struct TrCorePrivate * p = core->priv;
|
||||
|
||||
if( !g_list_find_custom( p->monitor_files, filename, (GCompareFunc)strcmp ) )
|
||||
p->monitor_files = g_list_append( p->monitor_files, g_strdup( filename ) );
|
||||
if( !g_slist_find_custom( p->monitor_files, filename, (GCompareFunc)strcmp ) )
|
||||
p->monitor_files = g_slist_append( p->monitor_files, g_strdup( filename ) );
|
||||
if( !p->monitor_idle_tag )
|
||||
p->monitor_idle_tag = g_timeout_add( 1000, watchFolderIdle, core );
|
||||
}
|
||||
|
@ -625,10 +618,9 @@ tr_core_load( TrCore * self, gboolean forcePaused )
|
|||
}
|
||||
|
||||
static void
|
||||
tr_core_errsig( TrCore * self, enum tr_core_err type, const char * msg )
|
||||
tr_core_errsig( TrCore * core, enum tr_core_err type, const char * msg )
|
||||
{
|
||||
TrCoreClass * class = g_type_class_peek( TR_CORE_TYPE );
|
||||
g_signal_emit( self, class->errsig, 0, type, msg );
|
||||
g_signal_emit( core, TR_CORE_GET_CLASS(core)->errsig, 0, type, msg );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -645,27 +637,37 @@ tr_core_add_ctor( TrCore * self, tr_ctor * ctor )
|
|||
tr_core_errsig( self, TR_CORE_ERR_ADD_TORRENT, errstr );
|
||||
g_free( errstr );
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
tr_ctorFree( ctor );
|
||||
}
|
||||
|
||||
void
|
||||
tr_core_add_list( TrCore * self,
|
||||
GList * paths,
|
||||
tr_ctor * ctor )
|
||||
tr_core_add_list( TrCore * core,
|
||||
GSList * torrentFiles,
|
||||
gboolean forcePaused )
|
||||
{
|
||||
tr_core_apply_defaults( ctor );
|
||||
if( torrentFiles && !isDisposed( core ) )
|
||||
{
|
||||
GSList * l;
|
||||
const gboolean doPrompt = pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
|
||||
|
||||
if( pref_flag_get( PREF_KEY_OPTIONS_PROMPT ) )
|
||||
{
|
||||
TrCoreClass * class = g_type_class_peek( TR_CORE_TYPE );
|
||||
g_signal_emit( self, class->promptsig, 0, paths, ctor );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( ; paths; paths=paths->next )
|
||||
if( !tr_ctorSetMetainfoFromFile( ctor, paths->data ) )
|
||||
tr_core_add_ctor( self, ctor );
|
||||
tr_ctorFree( ctor );
|
||||
for( l=torrentFiles; l!=NULL; l=l->next )
|
||||
{
|
||||
tr_ctor * ctor = tr_ctorNew( core->priv->handle );
|
||||
tr_core_apply_defaults( ctor );
|
||||
if( forcePaused )
|
||||
tr_ctorSetPaused( ctor, TR_FORCE, TRUE );
|
||||
if( tr_ctorSetMetainfoFromFile( ctor, l->data ) )
|
||||
tr_ctorFree( ctor );
|
||||
else if( doPrompt )
|
||||
g_signal_emit( core, TR_CORE_GET_CLASS(core)->promptsig, 0, ctor );
|
||||
else
|
||||
tr_core_add_ctor( core, ctor );
|
||||
}
|
||||
}
|
||||
|
||||
freestrlist( torrentFiles );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -793,10 +795,9 @@ tr_core_update( TrCore * self )
|
|||
}
|
||||
|
||||
void
|
||||
tr_core_quit( TrCore * self )
|
||||
tr_core_quit( TrCore * core )
|
||||
{
|
||||
TrCoreClass * class = g_type_class_peek( TR_CORE_TYPE );
|
||||
g_signal_emit( self, class->quitsig, 0 );
|
||||
g_signal_emit( core, TR_CORE_GET_CLASS(core)->quitsig, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -804,11 +805,10 @@ tr_core_quit( TrCore * self )
|
|||
**/
|
||||
|
||||
static void
|
||||
commitPrefsChange( TrCore * self, const char * key )
|
||||
commitPrefsChange( TrCore * core, const char * key )
|
||||
{
|
||||
TrCoreClass * class = g_type_class_peek( TR_CORE_TYPE );
|
||||
pref_save( NULL );
|
||||
g_signal_emit( self, class->prefsig, 0, key );
|
||||
g_signal_emit( core, TR_CORE_GET_CLASS(core)->prefsig, 0, key );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -65,8 +65,9 @@ typedef struct TrCoreClass
|
|||
void handler( TrCore *, enum tr_core_err, const char *, gpointer ) */
|
||||
int errsig;
|
||||
|
||||
/* "destination-prompt" signal:
|
||||
void handler( TrCore *, GList *, gpointer ctor, gpointer userData ) */
|
||||
/* "add-torrent-prompt" signal:
|
||||
void handler( TrCore *, gpointer ctor, gpointer userData )
|
||||
The handler assumes ownership of ctor and must free when done */
|
||||
int promptsig;
|
||||
|
||||
/* "quit" signal:
|
||||
|
@ -110,18 +111,22 @@ int tr_core_load( TrCore * self, gboolean forcepaused );
|
|||
|
||||
/**
|
||||
* Add a torrent.
|
||||
* This function assumes ownership of ctor
|
||||
*
|
||||
* May trigger an "error" signal with TR_CORE_ERR_ADD_TORRENT
|
||||
* Caller must free the ctor.
|
||||
*/
|
||||
void tr_core_add_ctor( TrCore * self, tr_ctor * ctor );
|
||||
|
||||
/**
|
||||
* Add a list of torrents.
|
||||
* This function assumes ownership of torrentFiles
|
||||
*
|
||||
* May pop up dialogs for each torrent if that preference is enabled.
|
||||
* May trigger one or more "error" signals with TR_CORE_ERR_ADD_TORRENT
|
||||
*/
|
||||
void tr_core_add_list( TrCore * self,
|
||||
GList * torrentFiles,
|
||||
tr_ctor * ctor );
|
||||
void tr_core_add_list( TrCore * self,
|
||||
GSList * torrentFiles,
|
||||
gboolean forcePaused );
|
||||
|
||||
/**
|
||||
* Add a torrent.
|
||||
|
|
19
gtk/tr-io.c
19
gtk/tr-io.c
|
@ -49,7 +49,7 @@ struct iosource {
|
|||
char *inbuf;
|
||||
size_t inused;
|
||||
size_t inmax;
|
||||
GList *outbufs;
|
||||
GSList *outbufs;
|
||||
unsigned int lastid;
|
||||
};
|
||||
|
||||
|
@ -183,7 +183,7 @@ io_write(struct iosource *io) {
|
|||
}
|
||||
|
||||
if(buf->off >= buf->len) {
|
||||
io->outbufs = g_list_remove(io->outbufs, buf);
|
||||
io->outbufs = g_slist_remove(io->outbufs, buf);
|
||||
if(NULL == io->outbufs)
|
||||
g_source_remove_poll((GSource*)io, &io->outfd);
|
||||
if(NULL != io->sent)
|
||||
|
@ -220,13 +220,12 @@ static void
|
|||
io_finalize(GSource *source UNUSED) {
|
||||
struct iosource *io = (struct iosource*)source;
|
||||
|
||||
if(NULL != io->outbufs) {
|
||||
g_list_foreach(io->outbufs, (GFunc)freeoutbuf, NULL);
|
||||
g_list_free(io->outbufs);
|
||||
}
|
||||
g_slist_foreach(io->outbufs, (GFunc)freeoutbuf, NULL);
|
||||
g_slist_free(io->outbufs);
|
||||
g_free(io->inbuf);
|
||||
|
||||
if(NULL != io->inbuf)
|
||||
g_free(io->inbuf);
|
||||
io->outbufs = NULL;
|
||||
io->inbuf = NULL;
|
||||
}
|
||||
|
||||
static GSourceFuncs sourcefuncs = {
|
||||
|
@ -325,9 +324,9 @@ io_send_keepdata(GSource *source, void *data, size_t len) {
|
|||
buf->id = io->lastid;
|
||||
|
||||
if(NULL != io->outbufs)
|
||||
io->outbufs = g_list_append(io->outbufs, buf);
|
||||
io->outbufs = g_slist_append(io->outbufs, buf);
|
||||
else {
|
||||
io->outbufs = g_list_append(io->outbufs, buf);
|
||||
io->outbufs = g_slist_append(io->outbufs, buf);
|
||||
g_source_add_poll(source, &io->outfd);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdlib.h> /* free() */
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <third-party/miniupnp/miniwget.h>
|
||||
|
|
63
gtk/util.c
63
gtk/util.c
|
@ -187,19 +187,19 @@ mkdir_p( const char * path, mode_t mode )
|
|||
#endif
|
||||
}
|
||||
|
||||
GList *
|
||||
dupstrlist( GList * l )
|
||||
GSList *
|
||||
dupstrlist( GSList * l )
|
||||
{
|
||||
GList * ret = NULL;
|
||||
GSList * ret = NULL;
|
||||
for( ; l!=NULL; l=l->next )
|
||||
ret = g_list_prepend( ret, g_strdup( l->data ) );
|
||||
return g_list_reverse( ret );
|
||||
ret = g_slist_prepend( ret, g_strdup( l->data ) );
|
||||
return g_slist_reverse( ret );
|
||||
}
|
||||
|
||||
char *
|
||||
joinstrlist(GList *list, char *sep)
|
||||
joinstrlist(GSList *list, char *sep)
|
||||
{
|
||||
GList *l;
|
||||
GSList *l;
|
||||
GString *gstr = g_string_new (NULL);
|
||||
for (l=list; l!=NULL; l=l->next) {
|
||||
g_string_append (gstr, (char*)l->data);
|
||||
|
@ -210,10 +210,10 @@ joinstrlist(GList *list, char *sep)
|
|||
}
|
||||
|
||||
void
|
||||
freestrlist(GList *list)
|
||||
freestrlist(GSList *list)
|
||||
{
|
||||
g_list_foreach (list, (GFunc)g_free, NULL);
|
||||
g_list_free (list);
|
||||
g_slist_foreach (list, (GFunc)g_free, NULL);
|
||||
g_slist_free (list);
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -225,11 +225,11 @@ decode_uri( const char * uri )
|
|||
return ret;
|
||||
}
|
||||
|
||||
GList *
|
||||
GSList *
|
||||
checkfilenames( int argc, char **argv )
|
||||
{
|
||||
int i;
|
||||
GList * ret = NULL;
|
||||
GSList * ret = NULL;
|
||||
char * pwd = g_get_current_dir( );
|
||||
|
||||
for( i=0; i<argc; ++i )
|
||||
|
@ -239,13 +239,13 @@ checkfilenames( int argc, char **argv )
|
|||
: g_build_filename( pwd, argv[i], NULL );
|
||||
|
||||
if( g_file_test( filename, G_FILE_TEST_EXISTS ) )
|
||||
ret = g_list_append( ret, filename );
|
||||
ret = g_slist_prepend( ret, filename );
|
||||
else
|
||||
g_free( filename );
|
||||
}
|
||||
|
||||
g_free( pwd );
|
||||
return ret;
|
||||
return g_slist_reverse( ret );
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -294,19 +294,18 @@ sizingmagic( GtkWindow * wind,
|
|||
}
|
||||
|
||||
static void
|
||||
errcb(GtkWidget *widget, int resp UNUSED, gpointer data) {
|
||||
GList *funcdata;
|
||||
callbackfunc_t func;
|
||||
onErrorResponse(GtkWidget * dialog, int resp UNUSED, gpointer glist)
|
||||
{
|
||||
GSList * list = glist;
|
||||
if( list )
|
||||
{
|
||||
callbackfunc_t func = list->data;
|
||||
gpointer user_data = list->next->data;
|
||||
func( user_data );
|
||||
g_slist_free( list );
|
||||
}
|
||||
|
||||
if(NULL != data) {
|
||||
funcdata = g_list_first(data);
|
||||
func = (callbackfunc_t) funcdata->data;
|
||||
data = funcdata->next->data;
|
||||
func(data);
|
||||
g_list_free(funcdata);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(widget);
|
||||
gtk_widget_destroy( dialog );
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
|
@ -315,7 +314,7 @@ verrmsg_full( GtkWindow * wind, callbackfunc_t func, void * data,
|
|||
{
|
||||
GtkWidget *dialog;
|
||||
char *msg;
|
||||
GList *funcdata;
|
||||
GSList *funcdata = NULL;
|
||||
|
||||
msg = g_strdup_vprintf(format, ap);
|
||||
|
||||
|
@ -327,11 +326,11 @@ verrmsg_full( GtkWindow * wind, callbackfunc_t func, void * data,
|
|||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", msg);
|
||||
|
||||
if(NULL == func)
|
||||
funcdata = NULL;
|
||||
else
|
||||
funcdata = g_list_append(g_list_append(NULL, (void *) func), data);
|
||||
g_signal_connect(dialog, "response", G_CALLBACK(errcb), funcdata);
|
||||
if( func ) {
|
||||
funcdata = g_slist_append( funcdata, (gpointer)func );
|
||||
funcdata = g_slist_append( funcdata, data );
|
||||
}
|
||||
g_signal_connect(dialog, "response", G_CALLBACK(onErrorResponse), funcdata);
|
||||
g_free(msg);
|
||||
|
||||
return dialog;
|
||||
|
|
16
gtk/util.h
16
gtk/util.h
|
@ -59,24 +59,24 @@ rfc822date (guint64 epoch_msec);
|
|||
gboolean
|
||||
mkdir_p(const char *name, mode_t mode);
|
||||
|
||||
/* create a copy of a GList of strings, this dups the actual strings too */
|
||||
GList *
|
||||
dupstrlist( GList * list );
|
||||
/* create a copy of a GSList of strings, this dups the actual strings too */
|
||||
GSList *
|
||||
dupstrlist( GSList * list );
|
||||
|
||||
/* joins a GList of strings into one string using an optional separator */
|
||||
/* joins a GSList of strings into one string using an optional separator */
|
||||
char *
|
||||
joinstrlist(GList *list, char *sep);
|
||||
joinstrlist(GSList *list, char *sep);
|
||||
|
||||
/* free a GList of strings */
|
||||
/* free a GSList of strings */
|
||||
void
|
||||
freestrlist(GList *list);
|
||||
freestrlist(GSList *list);
|
||||
|
||||
/* decodes a string that has been urlencoded */
|
||||
char *
|
||||
decode_uri( const char * uri );
|
||||
|
||||
/* return a list of cleaned-up paths, with invalid directories removed */
|
||||
GList *
|
||||
GSList *
|
||||
checkfilenames( int argc, char ** argv );
|
||||
|
||||
/* retrieve the global download directory */
|
||||
|
|
Loading…
Reference in New Issue