Move torrent adding from callback in main.c to functions on TrCore.

This commit is contained in:
Josh Elsasser 2007-05-24 02:50:28 +00:00
parent 78ec2e2551
commit dfffdd17e4
9 changed files with 261 additions and 110 deletions

View File

@ -46,9 +46,10 @@
#define STRIPROOT( path ) \
( g_path_is_absolute( (path) ) ? g_path_skip_root( (path) ) : (path) )
struct addcb {
add_torrents_func_t addfunc;
void *data;
struct addcb
{
GtkWidget * widget;
TrCore * core;
gboolean autostart;
gboolean usingaltdir;
GtkFileChooser *altdir;
@ -57,8 +58,8 @@ struct addcb {
struct dirdata
{
add_torrents_func_t addfunc;
void * cbdata;
GtkWidget * widget;
TrCore * core;
GList * files;
enum tr_torrent_action action;
gboolean paused;
@ -100,6 +101,8 @@ struct infowind
} inf;
};
static void
addwindnocore( gpointer gdata, GObject * core );
static void
autoclick(GtkWidget *widget, gpointer gdata);
static void
@ -110,13 +113,15 @@ static GtkWidget *
makeinfotab( TrTorrent * tor, struct infowind * iw );
static void
infoupdate( struct infowind * iw, int force );
void
static void
fmtpeercount( GtkLabel * label, int count );
static void
promptdirnocore( gpointer gdata, GObject * core );
static void
promptresp( GtkWidget * widget, gint resp, gpointer data );
static void
quitresp( GtkWidget * widget, gint resp, gpointer data );
GtkWidget *
static GtkWidget *
makefilestab( TrTorrent * tor, GtkTreeModel ** modelret );
static void
stylekludge( GObject * obj, GParamSpec * spec, gpointer data );
@ -136,7 +141,8 @@ updateprogress( GtkTreeModel * model, GtkTreeIter * parent,
uint64_t total, float * progress );
void
makeaddwind(GtkWindow *parent, add_torrents_func_t addfunc, void *cbdata) {
makeaddwind( GtkWindow * parent, TrCore * core )
{
GtkWidget *wind = gtk_file_chooser_dialog_new(_("Add a Torrent"), parent,
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
@ -153,13 +159,15 @@ makeaddwind(GtkWindow *parent, add_torrents_func_t addfunc, void *cbdata) {
_("Choose a download directory"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
const char * pref;
data->addfunc = addfunc;
data->data = cbdata;
data->widget = wind;
data->core = core;
data->autostart = TRUE;
data->usingaltdir = FALSE;
data->altdir = GTK_FILE_CHOOSER(getdir);
data->altbox = GTK_BUTTON_BOX(bbox);
g_object_weak_ref( G_OBJECT( core ), addwindnocore, data );
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_EDGE);
gtk_box_pack_start_defaults(GTK_BOX(bbox), dircheck);
gtk_box_pack_start_defaults(GTK_BOX(bbox), getdir);
@ -194,6 +202,18 @@ makeaddwind(GtkWindow *parent, add_torrents_func_t addfunc, void *cbdata) {
gtk_widget_show_all(wind);
}
void
addwindnocore( gpointer gdata, GObject * core SHUTUP )
{
struct addcb * data = gdata;
/* prevent the response callback from trying to remove the weak
reference which no longer exists */
data->core = NULL;
gtk_dialog_response( GTK_DIALOG( data->widget ), GTK_RESPONSE_NONE );
}
static void
autoclick(GtkWidget *widget, gpointer gdata) {
struct addcb *data = gdata;
@ -222,16 +242,34 @@ addresp(GtkWidget *widget, gint resp, gpointer gdata) {
if(data->usingaltdir)
dir = gtk_file_chooser_get_filename(data->altdir);
files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget));
stupidgtk = NULL;
for(ii = files; NULL != ii; ii = ii->next)
stupidgtk = g_list_append(stupidgtk, ii->data);
action = toraddaction( tr_prefs_get( PREF_ID_ADDSTD ) );
data->addfunc( data->data, NULL, stupidgtk, dir,
action, !data->autostart );
if(NULL != dir)
g_free(dir);
if( NULL == dir )
{
stupidgtk = NULL;
for( ii = files; NULL != ii; ii = ii->next )
{
stupidgtk = g_list_append( stupidgtk, ii->data );
}
tr_core_add_list( data->core, stupidgtk, action, !data->autostart );
freestrlist(stupidgtk);
}
else
{
for( ii = files; NULL != ii; ii = ii->next )
{
tr_core_add_dir( data->core, ii->data, dir,
action, !data->autostart );
g_free( ii->data );
}
g_free( dir );
}
tr_core_torrents_added( data->core );
g_slist_free(files);
freestrlist(stupidgtk);
}
if( NULL != data->core )
{
g_object_weak_unref( G_OBJECT( data->core ), addwindnocore, data );
}
g_free( data );
@ -507,19 +545,20 @@ fmtpeercount( GtkLabel * label, int count )
}
void
promptfordir( GtkWindow * parent, add_torrents_func_t addfunc, void *cbdata,
GList * files, enum tr_torrent_action act, gboolean paused )
promptfordir( GtkWindow * parent, TrCore * core, GList * files,
enum tr_torrent_action act, gboolean paused )
{
struct dirdata * stuff;
GtkWidget * wind;
stuff = g_new( struct dirdata, 1 );
stuff->addfunc = addfunc;
stuff->cbdata = cbdata;
stuff->core = core;
stuff->files = dupstrlist( files );
stuff->action = act;
stuff->paused = paused;
g_object_weak_ref( G_OBJECT( core ), promptdirnocore, stuff );
wind = gtk_file_chooser_dialog_new( _("Choose a directory"), parent,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@ -530,17 +569,32 @@ promptfordir( GtkWindow * parent, add_torrents_func_t addfunc, void *cbdata,
gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( wind ),
getdownloaddir() );
stuff->widget = wind;
g_signal_connect( G_OBJECT( wind ), "response",
G_CALLBACK( promptresp ), stuff );
gtk_widget_show_all(wind);
}
void
promptdirnocore( gpointer gdata, GObject * core SHUTUP )
{
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;
char * dir;
GList * ii;
stuff = data;
@ -549,11 +603,20 @@ promptresp( GtkWidget * widget, gint resp, gpointer data )
dir = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( widget ) );
/* it seems that we will always get a directory */
g_assert( NULL != dir );
stuff->addfunc( stuff->cbdata, NULL, stuff->files, dir,
stuff->action, stuff->paused );
for( ii = g_list_first( stuff->files ); NULL != ii; ii = ii->next )
{
tr_core_add_dir( stuff->core, ii->data, dir,
stuff->action, stuff->paused );
}
tr_core_torrents_added( stuff->core );
g_free( dir );
}
if( NULL != stuff->core )
{
g_object_weak_unref( G_OBJECT( stuff->core ), promptdirnocore, stuff );
}
freestrlist( stuff->files );
g_free( stuff );
gtk_widget_destroy( widget );

View File

@ -25,12 +25,13 @@
#ifndef TG_PREFS_H
#define TG_PREFS_H
#include "tr_core.h"
#include "tr_torrent.h"
#include "util.h"
/* show the "add a torrent" dialog */
void
makeaddwind(GtkWindow *parent, add_torrents_func_t addfunc, void *cbdata);
makeaddwind( GtkWindow * parent, TrCore * core );
/* show the info window for a torrent */
void
@ -39,8 +40,8 @@ makeinfowind( GtkWindow * parent, GtkTreeModel * model, GtkTreePath * path,
/* prompt for a download directory for torrents, then add them */
void
promptfordir( GtkWindow * parent, add_torrents_func_t addfunc, void *cbdata,
GList * files, enum tr_torrent_action act, gboolean paused );
promptfordir( GtkWindow * parent, TrCore * core, GList * files,
enum tr_torrent_action act, gboolean paused );
/* prompt if the user wants to quit, calls func with cbdata if they do */
void

View File

@ -40,6 +40,7 @@
#include "conf.h"
#include "io.h"
#include "ipc.h"
#include "tr_core.h"
#include "tr_prefs.h"
#include "util.h"
@ -58,7 +59,7 @@ enum contype { CON_SERV, CON_CLIENT };
struct constate_serv {
void *wind;
add_torrents_func_t addfunc;
gpointer core;
callbackfunc_t quitfunc;
void *cbdata;
};
@ -141,7 +142,7 @@ static const struct handlerdef gl_funcs_client[] = {
static char *gl_sockpath = NULL;
void
ipc_socket_setup( void * parent, add_torrents_func_t addfunc,
ipc_socket_setup( void * parent, TrCore * core,
callbackfunc_t quitfunc, void * cbdata )
{
struct constate *con;
@ -153,10 +154,12 @@ ipc_socket_setup( void * parent, add_torrents_func_t addfunc,
con->funcs = gl_funcs_serv;
con->type = CON_SERV;
con->u.serv.wind = parent;
con->u.serv.addfunc = addfunc;
con->u.serv.core = core;
con->u.serv.quitfunc = quitfunc;
con->u.serv.cbdata = cbdata;
g_object_add_weak_pointer( G_OBJECT( core ), &con->u.serv.core );
serv_bind(con);
}
@ -460,19 +463,21 @@ srv_vers( struct constate * con, const char * name SHUTUP, benc_val_t * val )
static void
srv_addfile(struct constate *con, const char *name SHUTUP, benc_val_t *val) {
struct constate_serv *srv = &con->u.serv;
GList *files;
int ii;
if( NULL == srv->core )
{
return;
}
if(TYPE_LIST == val->type) {
files = NULL;
for(ii = 0; ii < val->val.l.count; ii++)
if(TYPE_STR == val->val.l.vals[ii].type &&
/* XXX somehow escape invalid utf-8 */
g_utf8_validate(val->val.l.vals[ii].val.s.s, -1, NULL))
files = g_list_append(files, val->val.l.vals[ii].val.s.s);
srv->addfunc( srv->cbdata, NULL, files, NULL,
toraddaction( tr_prefs_get( PREF_ID_ADDIPC ) ), FALSE );
g_list_free(files);
tr_core_add( TR_CORE( srv->core ), val->val.l.vals[ii].val.s.s,
toraddaction( tr_prefs_get( PREF_ID_ADDIPC ) ), FALSE );
tr_core_torrents_added( TR_CORE( srv->core ) );
}
}

View File

@ -25,10 +25,11 @@
#ifndef TG_IPC_H
#define TG_IPC_H
#include "tr_core.h"
#include "util.h"
void
ipc_socket_setup( void * wind, add_torrents_func_t addfunc,
ipc_socket_setup( void * wind, TrCore * core,
callbackfunc_t quitfunc, void * cbdata );
gboolean

View File

@ -168,6 +168,8 @@ static void
coreerr( TrCore * core, enum tr_core_err code, const char * msg,
gpointer gdata );
static void
coreprompt( TrCore *, GList *, enum tr_torrent_action, gboolean, gpointer );
static void
readinitialprefs( struct cbdata * cbdata );
static void
prefschanged( GtkWidget * widget, int id, gpointer data );
@ -184,9 +186,6 @@ getselection( struct cbdata * cbdata );
static void
handleaction( struct cbdata *data, int action );
static void
addtorrents(void *vdata, void *state, GList *files,
const char *dir, enum tr_torrent_action act, gboolean paused);
static void
safepipe(void);
static void
@ -372,7 +371,8 @@ gtksetup( int * argc, char *** argv )
static void
appsetup( TrWindow * wind, benc_val_t * state, GList * args, gboolean paused )
{
struct cbdata * cbdata;
struct cbdata * cbdata;
enum tr_torrent_action action;
/* fill out cbdata */
cbdata = g_new0( struct cbdata, 1 );
@ -385,26 +385,36 @@ appsetup( TrWindow * wind, benc_val_t * state, GList * args, gboolean paused )
cbdata->closing = FALSE;
cbdata->errqueue = NULL;
/* set up error message handler */
/* set up core handlers */
g_signal_connect( cbdata->core, "error", G_CALLBACK( coreerr ), cbdata );
g_signal_connect( cbdata->core, "directory-prompt",
G_CALLBACK( coreprompt ), cbdata );
/* apply a few prefs */
readinitialprefs( cbdata );
/* add torrents from command-line and saved state */
if( NULL != state )
{
tr_core_load( cbdata->core, state, paused );
}
if( NULL != args )
{
action = toraddaction( tr_prefs_get( PREF_ID_ADDIPC ) );
tr_core_add_list( cbdata->core, args, action, paused );
}
tr_core_torrents_added( cbdata->core );
/* set up the ipc socket */
ipc_socket_setup( GTK_WINDOW( wind ), cbdata->core, wannaquit, cbdata );
/* set up main window */
winsetup( cbdata, wind );
/* add torrents from command-line and saved state */
addtorrents( cbdata, state, args, NULL,
toraddaction( tr_prefs_get( PREF_ID_ADDIPC ) ), paused );
/* start model update timer */
cbdata->timer = g_timeout_add( UPDATE_INTERVAL, updatemodel, cbdata );
updatemodel( cbdata );
/* set up the ipc socket now that we're ready to get torrents from it */
ipc_socket_setup( GTK_WINDOW( wind ), addtorrents, wannaquit, cbdata );
/* show the window */
tr_window_show( wind );
}
@ -598,6 +608,7 @@ gotdrag(GtkWidget *widget SHUTUP, GdkDragContext *dc, gint x SHUTUP,
struct stat sb;
int prelen = strlen(prefix);
GList *paths, *freeables;
enum tr_torrent_action action;
#ifdef DND_DEBUG
char *sele = gdk_atom_name(sel->selection);
@ -660,8 +671,9 @@ gotdrag(GtkWidget *widget SHUTUP, GdkDragContext *dc, gint x SHUTUP,
/* try to add any torrents we found */
if( NULL != paths )
{
addtorrents( data, NULL, paths, NULL,
toraddaction( tr_prefs_get( PREF_ID_ADDSTD ) ), FALSE );
action = toraddaction( tr_prefs_get( PREF_ID_ADDSTD ) );
tr_core_add_list( data->core, paths, action, FALSE );
tr_core_torrents_added( data->core );
}
freestrlist(freeables);
g_free(files);
@ -720,6 +732,15 @@ coreerr( TrCore * core SHUTUP, enum tr_core_err code, const char * msg,
g_assert_not_reached();
}
void
coreprompt( TrCore * core, GList * paths, enum tr_torrent_action act,
gboolean paused, gpointer gdata )
{
struct cbdata * cbdata = gdata;
promptfordir( cbdata->wind, core, paths, act, paused );
}
static void
readinitialprefs( struct cbdata * cbdata )
{
@ -899,7 +920,7 @@ handleaction( struct cbdata * data, int act )
switch( act )
{
case ACT_OPEN:
makeaddwind( data->wind, addtorrents, data );
makeaddwind( data->wind, data->core );
return;
case ACT_PREF:
if( NULL != data->prefs )
@ -1004,50 +1025,6 @@ handleaction( struct cbdata * data, int act )
}
}
static void
addtorrents( void * vdata, void * state, GList * files, const char * dir,
enum tr_torrent_action act, gboolean paused )
{
struct cbdata *data = vdata;
const char * pref;
int added;
added = 0;
if( NULL != state )
{
added += tr_core_load( data->core, state, paused );
}
if(NULL != files) {
if( NULL == dir )
{
pref = tr_prefs_get( PREF_ID_ASKDIR );
if( NULL != pref && strbool( pref ) )
{
promptfordir( data->wind, addtorrents, data, files, act, paused );
files = NULL;
}
dir = getdownloaddir();
}
for( files = g_list_first( files ); NULL != files; files = files->next )
{
if( tr_core_add_torrent( data->core, files->data, dir, act, paused ) )
{
added++;
}
}
}
tr_core_torrents_added( data->core );
if( 0 < added )
{
updatemodel(data);
tr_core_save( data->core );
}
}
static void
safepipe(void) {
struct sigaction sa;

View File

@ -35,6 +35,7 @@
#include "conf.h"
#include "tr_core.h"
#include "tr_prefs.h"
#include "tr_torrent.h"
#include "util.h"
@ -45,6 +46,9 @@ tr_core_class_init( gpointer g_class, gpointer g_class_data );
static void
tr_core_marshal_err( GClosure * closure, GValue * ret, guint count,
const GValue * vals, gpointer hint, gpointer marshal );
void
tr_core_marshal_prompt( GClosure * closure, GValue * ret, guint count,
const GValue * vals, gpointer hint, gpointer marshal );
static void
tr_core_dispose( GObject * obj );
static int
@ -96,6 +100,14 @@ tr_core_class_init( gpointer g_class, gpointer g_class_data SHUTUP )
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
tr_core_marshal_err, G_TYPE_NONE,
2, G_TYPE_INT, G_TYPE_STRING );
core_class = TR_CORE_CLASS( g_class );
core_class->promptsig = g_signal_new( "directory-prompt",
G_TYPE_FROM_CLASS( g_class ),
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
tr_core_marshal_prompt, G_TYPE_NONE,
3, G_TYPE_POINTER, G_TYPE_INT,
G_TYPE_BOOLEAN );
}
void
@ -103,8 +115,8 @@ tr_core_marshal_err( GClosure * closure, GValue * ret SHUTUP, guint count,
const GValue * vals, gpointer hint SHUTUP,
gpointer marshal )
{
typedef void (*TRMarshalErr) ( gpointer, enum tr_core_err, const char *,
gpointer );
typedef void (*TRMarshalErr)
( gpointer, enum tr_core_err, const char *, gpointer );
TRMarshalErr callback;
GCClosure * cclosure = (GCClosure*) closure;
enum tr_core_err errcode;
@ -123,6 +135,33 @@ tr_core_marshal_err( GClosure * closure, GValue * ret SHUTUP, guint count,
callback( inst, errcode, errstr, gdata );
}
void
tr_core_marshal_prompt( GClosure * closure, GValue * ret SHUTUP, guint count,
const GValue * vals, gpointer hint SHUTUP,
gpointer marshal )
{
typedef void (*TRMarshalPrompt)
( gpointer, GList *, enum tr_torrent_action, gboolean, gpointer );
TRMarshalPrompt callback;
GCClosure * cclosure = (GCClosure*) closure;
GList * paths;
enum tr_torrent_action action;
gboolean paused;
gpointer inst, gdata;
g_return_if_fail( 4 == count );
inst = g_value_peek_pointer( vals );
paths = g_value_get_pointer( vals + 1 );
action = g_value_get_int( vals + 2 );
paused = g_value_get_boolean( vals + 3 );
gdata = closure->data;
callback = (TRMarshalPrompt) ( NULL == marshal ?
cclosure->callback : marshal );
callback( inst, paths, action, paused, gdata );
}
void
tr_core_init( GTypeInstance * instance, gpointer g_class SHUTUP )
{
@ -468,8 +507,24 @@ tr_core_load( TrCore * self, benc_val_t * state, gboolean forcepaused )
}
gboolean
tr_core_add_torrent( TrCore * self, const char * path, const char * dir,
enum tr_torrent_action act, gboolean paused )
tr_core_add( TrCore * self, const char * path, enum tr_torrent_action act,
gboolean paused )
{
GList * list;
int ret;
TR_IS_CORE( self );
list = g_list_append( NULL, (void *) path );
ret = tr_core_add_list( self, list, act, paused );
g_list_free( list );
return 1 == ret;
}
gboolean
tr_core_add_dir( TrCore * self, const char * path, const char * dir,
enum tr_torrent_action act, gboolean paused )
{
TrTorrent * tor;
char * errstr;
@ -491,11 +546,46 @@ tr_core_add_torrent( TrCore * self, const char * path, const char * dir,
return TRUE;
}
int
tr_core_add_list( TrCore * self, GList * paths, enum tr_torrent_action act,
gboolean paused )
{
TrCoreClass * class;
const char * pref;
int count;
TR_IS_CORE( self );
pref = tr_prefs_get( PREF_ID_ASKDIR );
if( NULL != pref && strbool( pref ) )
{
class = g_type_class_peek( TR_CORE_TYPE );
g_signal_emit( self, class->promptsig, 0, paths, act, paused );
return 0;
}
pref = getdownloaddir();
count = 0;
paths = g_list_first( paths );
while( NULL != paths )
{
if( tr_core_add_dir( self, paths->data, pref, act, paused ) )
{
count++;
}
paths = paths->next;
}
return count;
}
void
tr_core_torrents_added( TrCore * self )
{
TR_IS_CORE( self );
tr_core_update( self );
tr_core_save( self );
tr_core_errsig( self, TR_CORE_ERR_NO_MORE_TORRENTS, NULL );
}

View File

@ -71,6 +71,10 @@ struct _TrCoreClass
/* "error" signal:
void handler( TrCore *, enum tr_core_err, const char *, gpointer ) */
int errsig;
/* "directory-prompt" signal:
void handler( TrCore *, GList *, enum tr_torrent_action, gboolean,
gpointer ) */
int promptsig;
};
enum tr_core_err
@ -112,12 +116,25 @@ tr_core_save( TrCore * self );
int
tr_core_load( TrCore * self, benc_val_t * state, gboolean forcepaused );
/* Add a torrent. May trigger "error" signal with TR_CORE_ERR_ADD_TORRENT */
gboolean
tr_core_add_torrent( TrCore * self, const char * path, const char * dir,
enum tr_torrent_action act, gboolean paused );
/* Any the tr_core_add functions below may trigger an "error" signal
with TR_CORE_ERR_ADD_TORRENT */
/* Trigger "error" signal with TR_CORE_ERR_NO_MORE_TORRENTS */
/* Add the torrent at the given path */
gboolean
tr_core_add( TrCore * self, const char * path, enum tr_torrent_action act,
gboolean paused );
/* Add the torrent at the given path with the given download directory */
gboolean
tr_core_add_dir( TrCore * self, const char * path, const char * dir,
enum tr_torrent_action act, gboolean paused );
/* Add a list of torrents with the given paths */
int
tr_core_add_list( TrCore * self, GList * paths, enum tr_torrent_action act,
gboolean paused );
/* Save state, update model, and signal the end of a torrent cluster */
void
tr_core_torrents_added( TrCore * self );

View File

@ -38,9 +38,6 @@
/* XXX this shouldn't be here */
enum tr_torrent_action { TR_TOR_LEAVE, TR_TOR_COPY, TR_TOR_MOVE };
typedef void (*add_torrents_func_t)(void*,void*,GList*,const char*,
enum tr_torrent_action,gboolean);
/* return number of items in array */
#define ALEN( a ) ( ( signed )( sizeof(a) / sizeof( (a)[0] ) ) )

View File

@ -1,6 +1,6 @@
# $Id$
TMPCFLAGS = -g -Wall -W -O3 -funroll-loops -D_FILE_OFFSET_BITS=64 \
TMPCFLAGS = -g -Wall -W -O0 -funroll-loops -D_FILE_OFFSET_BITS=64 \
-D_LARGEFILE_SOURCE -D_GNU_SOURCE \
-DSYS_$(shell echo $(SYSTEM) | tr a-z A-Z)
TMPCXXFLAGS = $(TMPCFLAGS)