(gtk) try to iron out the remaining "add torrent" issues reported by wereHamster and Lacrocivous

This commit is contained in:
Charles Kerr 2008-03-18 01:22:11 +00:00
parent ac21d3280c
commit 0437c5f33e
13 changed files with 207 additions and 337 deletions

View File

@ -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 */
{

View File

@ -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 */

View File

@ -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 ) );
}

View File

@ -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 );

View File

@ -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"))
{

View File

@ -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;
}

View File

@ -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 */

View File

@ -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

View File

@ -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.

View File

@ -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);
}

View File

@ -10,6 +10,7 @@
* $Id$
*/
#include <stdlib.h> /* free() */
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <third-party/miniupnp/miniwget.h>

View File

@ -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;

View File

@ -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 */