Implement addfiles-detailed message.

This commit is contained in:
Josh Elsasser
2007-05-24 10:37:07 +00:00
parent 02aa6305ac
commit 04a175665b
8 changed files with 236 additions and 7 deletions

View File

@@ -61,6 +61,8 @@ struct dirdata
GtkWidget * widget;
TrCore * core;
GList * files;
uint8_t * data;
size_t size;
enum tr_torrent_action action;
gboolean paused;
};
@@ -545,15 +547,24 @@ fmtpeercount( GtkLabel * label, int count )
}
void
promptfordir( GtkWindow * parent, TrCore * core, GList * files,
enum tr_torrent_action act, gboolean paused )
promptfordir( GtkWindow * parent, TrCore * core, GList * files, uint8_t * data,
size_t size, enum tr_torrent_action act, gboolean paused )
{
struct dirdata * stuff;
GtkWidget * wind;
stuff = g_new( struct dirdata, 1 );
stuff = g_new0( struct dirdata, 1 );
stuff->core = core;
stuff->files = dupstrlist( files );
if( NULL != files )
{
stuff->files = dupstrlist( files );
}
if( NULL != data )
{
stuff->data = g_new( uint8_t, size );
memcpy( stuff->data, data, size );
stuff->size = size;
}
stuff->action = act;
stuff->paused = paused;
@@ -608,6 +619,11 @@ promptresp( GtkWidget * widget, gint resp, gpointer data )
tr_core_add_dir( stuff->core, ii->data, dir,
stuff->action, stuff->paused );
}
if( NULL != stuff->data )
{
tr_core_add_data_dir( stuff->core, stuff->data, stuff->size, dir,
stuff->paused );
}
tr_core_torrents_added( stuff->core );
g_free( dir );
}
@@ -618,6 +634,7 @@ promptresp( GtkWidget * widget, gint resp, gpointer data )
}
freestrlist( stuff->files );
g_free( stuff->data );
g_free( stuff );
gtk_widget_destroy( widget );
}

View File

@@ -40,8 +40,8 @@ makeinfowind( GtkWindow * parent, GtkTreeModel * model, GtkTreePath * path,
/* prompt for a download directory for torrents, then add them */
void
promptfordir( GtkWindow * parent, TrCore * core, GList * files,
enum tr_torrent_action act, gboolean paused );
promptfordir( GtkWindow * parent, TrCore * core, GList * files, uint8_t * data,
size_t size, enum tr_torrent_action act, gboolean paused );
/* prompt if the user wants to quit, calls func with cbdata if they do */
void

View File

@@ -103,6 +103,8 @@ cli_io_sent(GSource *source, unsigned int id, void *vdata);
static void
smsg_add( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg );
static void
smsg_addone( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg );
static void
smsg_quit( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg );
static void
smsg_info( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg );
@@ -142,6 +144,7 @@ ipc_socket_setup( GtkWindow * parent, TrCore * core )
con->msgs = ipc_initmsgs();
if( NULL == con->msgs ||
0 > ipc_addmsg( con->msgs, IPC_MSG_ADDMANYFILES, smsg_add ) ||
0 > ipc_addmsg( con->msgs, IPC_MSG_ADDONEFILE, smsg_addone ) ||
0 > ipc_addmsg( con->msgs, IPC_MSG_GETINFO, smsg_info ) ||
0 > ipc_addmsg( con->msgs, IPC_MSG_GETINFOALL, smsg_infoall ) ||
0 > ipc_addmsg( con->msgs, IPC_MSG_GETSTAT, smsg_info ) ||
@@ -550,6 +553,69 @@ smsg_add( enum ipc_msg id SHUTUP, benc_val_t * val, int64_t tag, void * arg )
simpleresp( con, tag, IPC_MSG_OK );
}
static void
smsg_addone( enum ipc_msg id SHUTUP, benc_val_t * val, int64_t tag,
void * arg )
{
struct constate * con = arg;
struct constate_serv * srv = &con->u.serv;
enum tr_torrent_action action;
benc_val_t * file, * data, * dir, * start;
gboolean paused;
if( NULL == val || TYPE_DICT != val->type )
{
simpleresp( con, tag, IPC_MSG_NOTSUP );
return;
}
file = tr_bencDictFind( val, "file" );
data = tr_bencDictFind( val, "data" );
dir = tr_bencDictFind( val, "directory" );
start = tr_bencDictFind( val, "autostart" );
if( ( NULL != file && TYPE_STR != file->type ) ||
( NULL != data && TYPE_STR != data->type ) ||
( NULL != dir && TYPE_STR != dir->type ) ||
( NULL != start && TYPE_INT != start->type ) )
{
simpleresp( con, tag, IPC_MSG_NOTSUP );
return;
}
action = toraddaction( tr_prefs_get( PREF_ID_ADDIPC ) );
paused = ( NULL == start || start->val.i ? FALSE : TRUE );
if( NULL != file )
{
if( NULL == dir )
{
tr_core_add( srv->core, file->val.s.s, action, paused );
}
else
{
tr_core_add_dir( srv->core, file->val.s.s, dir->val.s.s,
action, paused );
}
}
else
{
if( NULL == dir )
{
tr_core_add_data( srv->core, data->val.s.s, data->val.s.i,
paused );
}
else
{
tr_core_add_data_dir( srv->core, data->val.s.s, data->val.s.i,
dir->val.s.s, paused );
}
}
tr_core_torrents_added( TR_CORE( srv->core ) );
/* XXX should send info response back with torrent ids */
simpleresp( con, tag, IPC_MSG_OK );
}
static void
smsg_quit( enum ipc_msg id SHUTUP, benc_val_t * val SHUTUP, int64_t tag SHUTUP,
void * arg SHUTUP )

View File

@@ -170,6 +170,8 @@ coreerr( TrCore * core, enum tr_core_err code, const char * msg,
static void
coreprompt( TrCore *, GList *, enum tr_torrent_action, gboolean, gpointer );
static void
corepromptdata( TrCore *, uint8_t *, size_t, gboolean, gpointer );
static void
readinitialprefs( struct cbdata * cbdata );
static void
prefschanged( GtkWidget * widget, int id, gpointer data );
@@ -389,6 +391,8 @@ appsetup( TrWindow * wind, benc_val_t * state, GList * args, gboolean paused )
g_signal_connect( cbdata->core, "error", G_CALLBACK( coreerr ), cbdata );
g_signal_connect( cbdata->core, "directory-prompt",
G_CALLBACK( coreprompt ), cbdata );
g_signal_connect( cbdata->core, "directory-prompt-data",
G_CALLBACK( corepromptdata ), cbdata );
g_signal_connect_swapped( cbdata->core, "quit",
G_CALLBACK( wannaquit ), cbdata );
@@ -740,7 +744,16 @@ coreprompt( TrCore * core, GList * paths, enum tr_torrent_action act,
{
struct cbdata * cbdata = gdata;
promptfordir( cbdata->wind, core, paths, act, paused );
promptfordir( cbdata->wind, core, paths, NULL, 0, act, paused );
}
void
corepromptdata( TrCore * core, uint8_t * data, size_t size,
gboolean paused, gpointer gdata )
{
struct cbdata * cbdata = gdata;
promptfordir( cbdata->wind, core, NULL, data, size, TR_TOR_LEAVE, paused );
}
static void

View File

@@ -49,6 +49,9 @@ tr_core_marshal_err( GClosure * closure, GValue * ret, guint count,
void
tr_core_marshal_prompt( GClosure * closure, GValue * ret, guint count,
const GValue * vals, gpointer hint, gpointer marshal );
void
tr_core_marshal_data( GClosure * closure, GValue * ret, guint count,
const GValue * vals, gpointer hint, gpointer marshal );
static void
tr_core_dispose( GObject * obj );
static int
@@ -109,6 +112,14 @@ tr_core_class_init( gpointer g_class, gpointer g_class_data SHUTUP )
3, G_TYPE_POINTER, G_TYPE_INT,
G_TYPE_BOOLEAN );
core_class = TR_CORE_CLASS( g_class );
core_class->promptdatasig = g_signal_new( "directory-prompt-data",
G_TYPE_FROM_CLASS( g_class ),
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
tr_core_marshal_data,
G_TYPE_NONE, 3, G_TYPE_STRING,
G_TYPE_UINT, G_TYPE_BOOLEAN );
core_class = TR_CORE_CLASS( g_class );
core_class->quitsig = g_signal_new( "quit", G_TYPE_FROM_CLASS( g_class ),
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
@@ -168,6 +179,33 @@ tr_core_marshal_prompt( GClosure * closure, GValue * ret SHUTUP, guint count,
callback( inst, paths, action, paused, gdata );
}
void
tr_core_marshal_data( GClosure * closure, GValue * ret SHUTUP, guint count,
const GValue * vals, gpointer hint SHUTUP,
gpointer marshal )
{
typedef void (*TRMarshalPrompt)
( gpointer, uint8_t *, size_t, gboolean, gpointer );
TRMarshalPrompt callback;
GCClosure * cclosure = (GCClosure*) closure;
uint8_t * data;
size_t size;
gboolean paused;
gpointer inst, gdata;
g_return_if_fail( 4 == count );
inst = g_value_peek_pointer( vals );
data = (char *) g_value_get_string( vals + 1 );
size = g_value_get_uint( vals + 2 );
paused = g_value_get_boolean( vals + 3 );
gdata = closure->data;
callback = (TRMarshalPrompt) ( NULL == marshal ?
cclosure->callback : marshal );
callback( inst, data, size, paused, gdata );
}
void
tr_core_init( GTypeInstance * instance, gpointer g_class SHUTUP )
{
@@ -583,6 +621,50 @@ tr_core_add_list( TrCore * self, GList * paths, enum tr_torrent_action act,
return count;
}
gboolean
tr_core_add_data( TrCore * self, uint8_t * data, size_t size, gboolean paused )
{
TrCoreClass * class;
const char * pref;
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->promptdatasig, 0, data, size, paused );
return FALSE;
}
return tr_core_add_data_dir( self, data, size, getdownloaddir(), paused );
}
gboolean
tr_core_add_data_dir( TrCore * self, uint8_t * data, size_t size,
const char * dir, gboolean paused )
{
TrTorrent * tor;
char * errstr;
TR_IS_CORE( self );
errstr = NULL;
tor = tr_torrent_new_with_data( self->handle, data, size, dir,
paused, &errstr );
if( NULL == tor )
{
tr_core_errsig( self, TR_CORE_ERR_ADD_TORRENT, errstr );
g_free( errstr );
return FALSE;
}
g_assert( NULL == errstr );
tr_core_insert( self, tor );
return TRUE;
}
void
tr_core_torrents_added( TrCore * self )
{

View File

@@ -76,6 +76,9 @@ struct _TrCoreClass
void handler( TrCore *, GList *, enum tr_torrent_action, gboolean,
gpointer ) */
int promptsig;
/* "directory-prompt-data" signal:
void handler( TrCore *, uint8_t *, size_t, gboolean, gpointer ) */
int promptdatasig;
/* "quit" signal:
void handler( TrCore *, gpointer ) */
int quitsig;
@@ -138,6 +141,15 @@ int
tr_core_add_list( TrCore * self, GList * paths, enum tr_torrent_action act,
gboolean paused );
/* Add the torrent data in the given buffer */
gboolean
tr_core_add_data( TrCore * self, uint8_t * data, size_t size, gboolean paused );
/* Add the torrent data in the given buffer with the given download directory */
gboolean
tr_core_add_data_dir( TrCore * self, uint8_t * data, size_t size,
const char * dir, gboolean paused );
/* Save state, update model, and signal the end of a torrent cluster */
void
tr_core_torrents_added( TrCore * self );

View File

@@ -372,6 +372,41 @@ tr_torrent_new( tr_handle_t * back, const char *torrent, const char *dir,
return ret;
}
TrTorrent *
tr_torrent_new_with_data( tr_handle_t * back, uint8_t * data, size_t size,
const char * dir, gboolean paused, char ** err )
{
tr_torrent_t * handle;
int errcode;
g_assert( NULL != dir );
*err = NULL;
errcode = -1;
handle = tr_torrentInitData( back, data, size, NULL, TR_FLAG_SAVE,
&errcode );
if( NULL == handle )
{
switch( errcode )
{
case TR_EINVALID:
*err = g_strdup( _("not a valid torrent file") );
break;
case TR_EDUPLICATE:
*err = g_strdup( _("torrent is already open") );
break;
default:
*err = g_strdup( "" );
break;
}
return NULL;
}
return maketorrent( handle, dir, paused );
}
TrTorrent *
tr_torrent_new_with_state( tr_handle_t * back, benc_val_t * state,
gboolean forcedpause, char ** err )

View File

@@ -90,6 +90,10 @@ TrTorrent *
tr_torrent_new( tr_handle_t * handle, const char * path, const char * dir,
enum tr_torrent_action act, gboolean paused, char ** err);
TrTorrent *
tr_torrent_new_with_data( tr_handle_t * handle, uint8_t * data, size_t size,
const char * dir, gboolean paused, char ** err );
TrTorrent *
tr_torrent_new_with_state( tr_handle_t * handle, benc_val_t * state,
gboolean forcepaused, char ** err );