mirror of
https://github.com/transmission/transmission
synced 2024-12-31 20:16:57 +00:00
(trunk gtk) #2197: Adding a torrent from a browser sometimes doesn't work
This commit is contained in:
parent
b2b7409138
commit
6e10ee3baa
6 changed files with 170 additions and 100 deletions
|
@ -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;
|
||||
|
|
50
gtk/main.c
50
gtk/main.c
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
|
140
gtk/tr-core.c
140
gtk/tr-core.c
|
@ -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,
|
||||
|
|
|
@ -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* );
|
||||
|
||||
|
|
54
gtk/util.c
54
gtk/util.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue