(trunk gtk) #2197: Adding a torrent from a browser sometimes doesn't work

This commit is contained in:
Charles Kerr 2009-06-11 14:51:21 +00:00
parent b2b7409138
commit 6e10ee3baa
6 changed files with 170 additions and 100 deletions

View File

@ -264,6 +264,7 @@ addSingleTorrentDialog( GtkWindow * parent,
GtkWidget * d;
GtkWidget * t;
GtkWidget * l;
GtkWidget * source_chooser;
struct AddData * data;
uint8_t flag;
GSList * list;
@ -316,14 +317,11 @@ addSingleTorrentDialog( GtkWindow * parent,
++col;
w = gtk_file_chooser_button_new( _( "Select Source File" ),
GTK_FILE_CHOOSER_ACTION_OPEN );
source_chooser = w;
gtk_table_attach( GTK_TABLE(
t ), w, col, col + 1, row, row + 1, ~0, 0, 0, 0 );
gtk_label_set_mnemonic_widget( GTK_LABEL( l ), w );
addTorrentFilters( GTK_FILE_CHOOSER( w ) );
if( data->filename )
if( !gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( w ),
data->filename ) )
g_warning( "couldn't select '%s'", data->filename );
g_signal_connect( w, "selection-changed",
G_CALLBACK( sourceChanged ), data );
@ -387,6 +385,14 @@ addSingleTorrentDialog( GtkWindow * parent,
t ), w, col, col + 2, row, row + 1, GTK_FILL, 0,
0, 0 );
/* trigger sourceChanged, either directly or indirectly,
* so that it creates the tor/gtor objects */
w = source_chooser;
if( data->filename )
gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( w ), data->filename );
else
sourceChanged( GTK_FILE_CHOOSER_BUTTON( w ), data );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( d )->vbox ), t, TRUE, TRUE, 0 );
gtk_widget_show_all( d );
return d;

View File

@ -331,7 +331,6 @@ main( int argc,
char ** argv )
{
char * err = NULL;
struct cbdata * cbdata;
GSList * argfiles;
GError * gerr;
gboolean didinit = FALSE;
@ -358,8 +357,6 @@ main( int argc,
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
cbdata = g_new0( struct cbdata, 1 );
/* bind the gettext domain */
setlocale( LC_ALL, "" );
bindtextdomain( domain, TRANSMISSIONLOCALEDIR );
@ -392,39 +389,51 @@ main( int argc,
tr_notify_init( );
didinit = cf_init( configDir, NULL ); /* must come before actions_init */
myUIManager = gtk_ui_manager_new ( );
actions_init ( myUIManager, cbdata );
gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, NULL );
gtk_ui_manager_ensure_update ( myUIManager );
gtk_window_set_default_icon_name ( MY_NAME );
setupsighandlers( ); /* set up handlers for fatal signals */
/* either get a lockfile s.t. this is the one instance of
* transmission that's running, OR if there are files to
* be added, delegate that to the running instance via dbus */
didlock = cf_lock( &tr_state, &err );
argfiles = checkfilenames( argc - 1, argv + 1 );
if( !didlock && argfiles )
{
/* We have torrents to add but there's another copy of Transmsision
* running... chances are we've been invoked from a browser, etc.
* So send the files over to the "real" copy of Transmission, and
* if that goes well, then our work is done. */
GSList * l;
gboolean delegated = FALSE;
for( l = argfiles; l; l = l->next )
delegated |= gtr_dbus_add_torrent( l->data );
if( delegated )
err = NULL;
if( delegated ) {
g_slist_foreach( argfiles, (GFunc)g_free, NULL );
g_slist_free( argfiles );
argfiles = NULL;
if( err ) {
g_free( err );
err = NULL;
}
}
}
else if( ( !didlock ) && ( tr_state == TR_LOCKFILE_ELOCK ) )
{
/* There's already another copy of Transmission running,
* so tell it to present its window to the user */
gtr_dbus_present_window( );
err = NULL;
}
if( didlock && ( didinit || cf_init( configDir, &err ) ) )
{
/* No other copy of Transmission running...
* so we're going to be the primary. */
const char * str;
GtkWindow * win;
tr_session * session;
struct cbdata * cbdata = g_new0( struct cbdata, 1 );
/* ensure the directories are created */
if(( str = pref_string_get( PREF_KEY_DIR_WATCH )))
@ -438,6 +447,13 @@ main( int argc,
pref_int_set( TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( session ) );
cbdata->core = tr_core_new( session );
/* init the ui manager */
myUIManager = gtk_ui_manager_new ( );
actions_init ( myUIManager, cbdata );
gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, NULL );
gtk_ui_manager_ensure_update ( myUIManager );
gtk_window_set_default_icon_name ( MY_NAME );
/* create main window now to be a parent to any error dialogs */
win = GTK_WINDOW( tr_window_new( myUIManager, cbdata->core ) );
g_signal_connect( win, "size-allocate", G_CALLBACK( onMainWindowSizeAllocated ), cbdata );
@ -893,7 +909,8 @@ on_main_window_focus_in( GtkWidget * widget UNUSED,
{
struct cbdata * cbdata = gdata;
gtk_window_set_urgency_hint( GTK_WINDOW( cbdata->wind ), FALSE );
if( cbdata->wind )
gtk_window_set_urgency_hint( GTK_WINDOW( cbdata->wind ), FALSE );
}
#endif
@ -909,7 +926,8 @@ onAddTorrent( TrCore * core,
#if GTK_CHECK_VERSION( 2, 8, 0 )
g_signal_connect( w, "focus-in-event",
G_CALLBACK( on_main_window_focus_in ), cbdata );
gtk_window_set_urgency_hint( cbdata->wind, TRUE );
if( cbdata->wind )
gtk_window_set_urgency_hint( cbdata->wind, TRUE );
#endif
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node>
<interface name="com.transmissionbt.Transmission">
<method name="AddFile">
<method name="AddMetainfo">
<arg type="b" name="handled" direction="out"/>
<arg type="s" name="filename" direction="in"/>
<arg type="s" name="metainfo" direction="in"/>
</method>
<method name="PresentWindow">
<arg type="b" name="handled" direction="out"/>

View File

@ -852,75 +852,103 @@ tr_core_errsig( TrCore * core,
g_signal_emit( core, TR_CORE_GET_CLASS( core )->errsig, 0, type, msg );
}
static void
add_filename( TrCore * core,
const char * filename,
gboolean doStart,
gboolean doPrompt )
static int
add_ctor( TrCore * core, tr_ctor * ctor, gboolean doPrompt )
{
tr_info inf;
int err = tr_torrentParse( ctor, &inf );
switch( err )
{
case TR_EINVALID:
break;
case TR_EDUPLICATE:
g_message( "it's a duplicate" );
/* don't complain about .torrent files in the watch directory
* that have already been added... that gets annoying and we
* don't want to be nagging users to clean up their watch dirs */
if( !tr_ctorGetSourceFile(ctor) || !core->priv->adding_from_watch_dir )
tr_core_errsig( core, err, inf.name );
tr_metainfoFree( &inf );
break;
default:
if( doPrompt )
g_signal_emit( core, TR_CORE_GET_CLASS( core )->promptsig, 0, ctor );
else {
tr_session * session = tr_core_session( core );
TrTorrent * gtor = tr_torrent_new_ctor( session, ctor, &err );
g_message( "creating a gtorrent" );
if( !err )
tr_core_add_torrent( core, gtor );
}
tr_metainfoFree( &inf );
break;
}
return err;
}
/* invoked remotely via dbus. */
gboolean
tr_core_add_metainfo( TrCore * core,
const char * base64_metainfo,
gboolean * setme_success,
GError ** gerr UNUSED )
{
tr_session * session = tr_core_session( core );
if( !session )
{
*setme_success = FALSE;
}
else
{
int err;
int file_length;
tr_ctor * ctor;
char * file_contents;
gboolean do_prompt = pref_flag_get( PREF_KEY_OPTIONS_PROMPT );
ctor = tr_ctorNew( session );
tr_core_apply_defaults( ctor );
file_contents = tr_base64_decode( base64_metainfo, -1, &file_length );
err = tr_ctorSetMetainfo( ctor, (const uint8_t*)file_contents, file_length );
if( !err )
err = add_ctor( core, ctor, do_prompt );
tr_free( file_contents );
tr_core_torrents_added( core );
*setme_success = TRUE;
}
return TRUE;
}
static void
add_filename( TrCore * core,
const char * filename,
gboolean doStart,
gboolean doPrompt )
{
tr_session * session = tr_core_session( core );
if( filename && session )
{
int err;
tr_ctor * ctor = tr_ctorNew( session );
tr_core_apply_defaults( ctor );
tr_ctorSetPaused( ctor, TR_FORCE, !doStart );
tr_ctorSetMetainfoFromFile( ctor, filename );
if( tr_ctorSetMetainfoFromFile( ctor, filename ) )
{
err = add_ctor( core, ctor, doPrompt );
if( err == TR_EINVALID )
tr_core_errsig( core, TR_EINVALID, filename );
tr_ctorFree( ctor );
}
else
{
tr_info inf;
int err = tr_torrentParse( ctor, &inf );
switch( err )
{
case TR_EINVALID:
tr_core_errsig( core, err, filename );
break;
case TR_EDUPLICATE:
/* don't complain about .torrent files in the watch directory
* that have already been added... that gets annoying and we
* don't want to be naggign users to clean up their watch dirs */
if( !core->priv->adding_from_watch_dir )
tr_core_errsig( core, err, inf.name );
tr_metainfoFree( &inf );
break;
default:
if( doPrompt )
g_signal_emit( core, TR_CORE_GET_CLASS( core )->promptsig, 0, ctor );
else {
TrTorrent * gtor = tr_torrent_new_ctor( session, ctor, &err );
if( err )
tr_core_errsig( core, err, filename );
else
tr_core_add_torrent( core, gtor );
}
tr_metainfoFree( &inf );
break;
}
}
}
}
gboolean
tr_core_add_file( TrCore * core,
const char * filename,
gboolean * success,
GError ** err UNUSED )
{
add_filename( core, filename,
pref_flag_get( PREF_KEY_START ),
pref_flag_get( PREF_KEY_OPTIONS_PROMPT ) );
*success = TRUE;
return TRUE;
}
gboolean
tr_core_present_window( TrCore * core UNUSED,
gboolean * success,

View File

@ -140,8 +140,12 @@ void tr_core_add_list( TrCore * self,
tr_core_add_list( c, l, PREF_FLAG_DEFAULT, PREF_FLAG_DEFAULT )
/** Add a torrent. */
gboolean tr_core_add_file( TrCore*, const char * filename, gboolean * setme_success, GError ** err );
/** @brief Add a torrent. */
gboolean tr_core_add_metainfo( TrCore * core,
const char * base64_metainfo,
gboolean * setme_success,
GError ** err );
/** Add a torrent. */
void tr_core_add_torrent( TrCore*, TrTorrent* );

View File

@ -581,29 +581,43 @@ gtr_open_file( const char * path )
gboolean
gtr_dbus_add_torrent( const char * filename )
{
static gboolean success = FALSE;
/* FIXME: why is this static? */
static gboolean success = FALSE;
#ifdef HAVE_DBUS_GLIB
DBusGProxy * proxy = NULL;
GError * err = NULL;
DBusGProxy * proxy = NULL;
GError * err = NULL;
DBusGConnection * conn;
if( ( conn = dbus_g_bus_get( DBUS_BUS_SESSION, &err ) ) )
proxy = dbus_g_proxy_new_for_name ( conn, VALUE_SERVICE_NAME,
VALUE_SERVICE_OBJECT_PATH,
VALUE_SERVICE_INTERFACE );
else if( err )
g_message( "err: %s", err->message );
if( proxy )
dbus_g_proxy_call( proxy, "AddFile", &err,
G_TYPE_STRING, filename,
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &success,
G_TYPE_INVALID );
if( err )
g_message( "err: %s", err->message );
char * file_contents;
gsize file_length;
if( g_file_get_contents( filename, &file_contents, &file_length, NULL ) )
{
char * b64 = tr_base64_encode( file_contents, file_length, NULL );
if(( conn = dbus_g_bus_get( DBUS_BUS_SESSION, &err )))
proxy = dbus_g_proxy_new_for_name (conn, VALUE_SERVICE_NAME,
VALUE_SERVICE_OBJECT_PATH,
VALUE_SERVICE_INTERFACE );
else if( err )
g_message( "err: %s", err->message );
if( proxy )
dbus_g_proxy_call( proxy, "AddMetainfo", &err,
G_TYPE_STRING, b64,
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &success,
G_TYPE_INVALID );
if( err )
g_message( "err: %s", err->message );
if( proxy )
g_object_unref( proxy );
if( conn )
dbus_g_connection_unref( conn );
tr_free( b64 );
g_free( file_contents );
}
else g_message( "couldn't read %s", filename );
g_object_unref( proxy );
dbus_g_connection_unref( conn );
#endif
return success;
}