(gtk) #769: when removing a torrent, prompt for confirmation if (a) the torrent is incomplete, (b) the torrent is connected to peers, (c) the user is also deleting the downloaded files.
This commit is contained in:
parent
1df3d8d844
commit
0cebab1247
|
@ -110,8 +110,8 @@ static GtkActionEntry entries[] =
|
||||||
N_("_Verify Local Data"), NULL, NULL, G_CALLBACK(action_cb) },
|
N_("_Verify Local Data"), NULL, NULL, G_CALLBACK(action_cb) },
|
||||||
{ "pause-torrent", GTK_STOCK_MEDIA_PAUSE,
|
{ "pause-torrent", GTK_STOCK_MEDIA_PAUSE,
|
||||||
N_("_Pause"), "<control>P", NULL, G_CALLBACK(action_cb) },
|
N_("_Pause"), "<control>P", NULL, G_CALLBACK(action_cb) },
|
||||||
{ "close-torrent", GTK_STOCK_CLOSE, NULL, "Delete", NULL, G_CALLBACK(action_cb) },
|
{ "remove-torrent", GTK_STOCK_REMOVE, NULL, "Delete", NULL, G_CALLBACK(action_cb) },
|
||||||
{ "delete-torrent", GTK_STOCK_DELETE, N_("_Delete Files and Close"), "<control>Delete", NULL, G_CALLBACK(action_cb) },
|
{ "delete-torrent", GTK_STOCK_DELETE, N_("_Delete Files and Remove"), "<control>Delete", NULL, G_CALLBACK(action_cb) },
|
||||||
{ "new-torrent", GTK_STOCK_NEW, N_("_New..."), NULL,
|
{ "new-torrent", GTK_STOCK_NEW, N_("_New..."), NULL,
|
||||||
N_("Create a new torrent"),
|
N_("Create a new torrent"),
|
||||||
G_CALLBACK(action_cb) },
|
G_CALLBACK(action_cb) },
|
||||||
|
|
|
@ -292,58 +292,98 @@ struct DeleteData
|
||||||
gboolean delete_files;
|
gboolean delete_files;
|
||||||
GList * torrents;
|
GList * torrents;
|
||||||
TrCore * core;
|
TrCore * core;
|
||||||
|
int busyCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
removeTorrents( struct DeleteData * data )
|
||||||
|
{
|
||||||
|
GList * 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
removeResponse( GtkDialog * dialog, gint response, gpointer gdata )
|
removeResponse( GtkDialog * dialog, gint response, gpointer gdata )
|
||||||
{
|
{
|
||||||
struct DeleteData * data = gdata;
|
struct DeleteData * data = gdata;
|
||||||
const int doRemove = response == GTK_RESPONSE_ACCEPT;
|
|
||||||
const int doDelete = data->delete_files;
|
|
||||||
GList * l;
|
|
||||||
|
|
||||||
for( l=data->torrents; l!=NULL; l=l->next )
|
if( response == GTK_RESPONSE_ACCEPT )
|
||||||
{
|
removeTorrents( data );
|
||||||
TrTorrent * gtor = TR_TORRENT( l->data );
|
|
||||||
|
|
||||||
if( doRemove )
|
|
||||||
tr_core_remove_torrent( data->core, gtor, doDelete );
|
|
||||||
else
|
else
|
||||||
g_object_unref( G_OBJECT( gtor ) );
|
g_list_foreach( data->torrents, (GFunc)g_object_unref, NULL );
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy( GTK_WIDGET( dialog ) );
|
gtk_widget_destroy( GTK_WIDGET( dialog ) );
|
||||||
g_list_free( data->torrents );
|
|
||||||
g_free( data );
|
g_free( data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tabulateTorrents( gpointer gtor, gpointer gdata )
|
||||||
|
{
|
||||||
|
struct DeleteData * data = gdata;
|
||||||
|
const tr_stat * stat = tr_torrent_stat( gtor );
|
||||||
|
|
||||||
|
if( stat->leftUntilDone || stat->peersConnected )
|
||||||
|
++data->busyCount;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
confirmDelete( GtkWindow * parent,
|
confirmRemove( GtkWindow * parent,
|
||||||
TrCore * core,
|
TrCore * core,
|
||||||
GList * torrents )
|
GList * torrents,
|
||||||
|
gboolean delete_files )
|
||||||
{
|
{
|
||||||
GtkWidget * d;
|
GtkWidget * d;
|
||||||
char text[128];
|
struct DeleteData * dd;
|
||||||
struct DeleteData * dd = g_new0( struct DeleteData, 1 );
|
const int count = g_list_length( torrents );
|
||||||
|
const char * primary_text;
|
||||||
|
const char * secondary_text;
|
||||||
|
|
||||||
|
if( !count )
|
||||||
|
return;
|
||||||
|
|
||||||
|
dd = g_new0( struct DeleteData, 1 );
|
||||||
dd->core = core;
|
dd->core = core;
|
||||||
dd->torrents = torrents;
|
dd->torrents = torrents;
|
||||||
dd->delete_files = TRUE;
|
dd->delete_files = delete_files;
|
||||||
|
|
||||||
|
g_list_foreach( torrents, tabulateTorrents, dd );
|
||||||
|
|
||||||
|
if( !dd->busyCount && !delete_files ) /* don't prompt boring torrents */
|
||||||
|
{
|
||||||
|
removeTorrents( dd );
|
||||||
|
g_free( dd );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !delete_files )
|
||||||
|
primary_text = ngettext( "Remove torrent?", "Remove torrents?", count );
|
||||||
|
else
|
||||||
|
primary_text = ngettext( "Delete this torrent's downloaded files?",
|
||||||
|
"Delete these torrents' downloaded files?",
|
||||||
|
count );
|
||||||
|
|
||||||
|
if( dd->busyCount > 1 )
|
||||||
|
secondary_text = _( "Some of these torrents are incomplete or connected to peers." );
|
||||||
|
else if( dd->busyCount == 0 )
|
||||||
|
secondary_text = NULL;
|
||||||
|
else
|
||||||
|
secondary_text = ngettext( "This torrent is incomplete or connected to peers.",
|
||||||
|
"One of these torrents is incomplete or connected to peers.",
|
||||||
|
count );
|
||||||
|
|
||||||
g_snprintf( text, sizeof( text ),
|
|
||||||
ngettext( "Delete torrent?",
|
|
||||||
"Delete torrents?",
|
|
||||||
g_list_length( torrents ) ) );
|
|
||||||
d = gtk_message_dialog_new_with_markup( parent,
|
d = gtk_message_dialog_new_with_markup( parent,
|
||||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
GTK_MESSAGE_WARNING,
|
( delete_files ? GTK_MESSAGE_WARNING : GTK_MESSAGE_QUESTION ),
|
||||||
GTK_BUTTONS_NONE,
|
GTK_BUTTONS_NONE,
|
||||||
"<b>%s</b>", text );
|
"<b>%s</b>", primary_text );
|
||||||
gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( d ),
|
if( secondary_text )
|
||||||
_( "This removes the torrent and deletes the downloaded files!" ) );
|
gtk_message_dialog_format_secondary_markup( GTK_MESSAGE_DIALOG( d ), secondary_text );
|
||||||
gtk_dialog_add_buttons( GTK_DIALOG( d ),
|
gtk_dialog_add_buttons( GTK_DIALOG( d ),
|
||||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
|
(delete_files ? GTK_STOCK_DELETE : GTK_STOCK_REMOVE), GTK_RESPONSE_ACCEPT,
|
||||||
NULL );
|
NULL );
|
||||||
gtk_dialog_set_default_response( GTK_DIALOG ( d ),
|
gtk_dialog_set_default_response( GTK_DIALOG ( d ),
|
||||||
GTK_RESPONSE_CANCEL );
|
GTK_RESPONSE_CANCEL );
|
||||||
|
|
|
@ -38,6 +38,9 @@ GtkWidget* promptfordir( GtkWindow * parent,
|
||||||
/* prompt if the user wants to quit, calls func with cbdata if they do */
|
/* 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 askquit( TrCore*, GtkWindow* parent, callbackfunc_t func, void* cbdata );
|
||||||
|
|
||||||
void confirmDelete( GtkWindow * parent, TrCore * core, GList * torrents );
|
void confirmRemove( GtkWindow * parent,
|
||||||
|
TrCore * core,
|
||||||
|
GList * gtorrents,
|
||||||
|
gboolean doDelete );
|
||||||
|
|
||||||
#endif /* TG_PREFS_H */
|
#endif /* TG_PREFS_H */
|
||||||
|
|
27
gtk/main.c
27
gtk/main.c
|
@ -199,7 +199,7 @@ refreshTorrentActions( GtkTreeSelection * s )
|
||||||
gtk_tree_selection_selected_foreach( s, accumulateStatusForeach, &counts );
|
gtk_tree_selection_selected_foreach( s, accumulateStatusForeach, &counts );
|
||||||
action_sensitize( "pause-torrent", counts.activeCount!=0 );
|
action_sensitize( "pause-torrent", counts.activeCount!=0 );
|
||||||
action_sensitize( "start-torrent", counts.inactiveCount!=0 );
|
action_sensitize( "start-torrent", counts.inactiveCount!=0 );
|
||||||
action_sensitize( "close-torrent", counts.totalCount!=0 );
|
action_sensitize( "remove-torrent", counts.totalCount!=0 );
|
||||||
action_sensitize( "delete-torrent", counts.totalCount!=0 );
|
action_sensitize( "delete-torrent", counts.totalCount!=0 );
|
||||||
action_sensitize( "verify-torrent", counts.totalCount!=0 );
|
action_sensitize( "verify-torrent", counts.totalCount!=0 );
|
||||||
action_sensitize( "show-torrent-details", counts.totalCount==1 );
|
action_sensitize( "show-torrent-details", counts.totalCount==1 );
|
||||||
|
@ -1037,27 +1037,14 @@ accumulateSelectedTorrents( GtkTreeModel * model,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
closeSelectedForeach( gpointer gtor, gpointer gdata )
|
removeSelected( struct cbdata * data, gboolean delete_files )
|
||||||
{
|
|
||||||
struct cbdata * data = gdata;
|
|
||||||
tr_core_remove_torrent( data->core, gtor, FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
closeSelected( struct cbdata * data, gboolean doDelete )
|
|
||||||
{
|
{
|
||||||
GList * l = NULL;
|
GList * l = NULL;
|
||||||
GtkTreeSelection * s = tr_window_get_selection( data->wind );
|
GtkTreeSelection * s = tr_window_get_selection( data->wind );
|
||||||
gtk_tree_selection_selected_foreach( s, accumulateSelectedTorrents, &l );
|
gtk_tree_selection_selected_foreach( s, accumulateSelectedTorrents, &l );
|
||||||
gtk_tree_selection_unselect_all( s );
|
gtk_tree_selection_unselect_all( s );
|
||||||
if( l ) {
|
if( l )
|
||||||
if( doDelete )
|
confirmRemove( data->wind, data->core, l, delete_files );
|
||||||
confirmDelete( data->wind, data->core, l );
|
|
||||||
else {
|
|
||||||
g_list_foreach( l, closeSelectedForeach, data );
|
|
||||||
g_list_free( l );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1111,13 +1098,13 @@ doAction ( const char * action_name, gpointer user_data )
|
||||||
tr_core_handle( data->core ) );
|
tr_core_handle( data->core ) );
|
||||||
gtk_widget_show_all( w );
|
gtk_widget_show_all( w );
|
||||||
}
|
}
|
||||||
else if( !strcmp( action_name, "close-torrent" ) )
|
else if( !strcmp( action_name, "remove-torrent" ) )
|
||||||
{
|
{
|
||||||
closeSelected( data, FALSE );
|
removeSelected( data, FALSE );
|
||||||
}
|
}
|
||||||
else if( !strcmp( action_name, "delete-torrent" ) )
|
else if( !strcmp( action_name, "delete-torrent" ) )
|
||||||
{
|
{
|
||||||
closeSelected( data, TRUE );
|
removeSelected( data, TRUE );
|
||||||
}
|
}
|
||||||
else if (!strcmp (action_name, "close"))
|
else if (!strcmp (action_name, "close"))
|
||||||
{
|
{
|
||||||
|
|
6
gtk/ui.h
6
gtk/ui.h
|
@ -10,7 +10,7 @@ const char * fallback_ui_file =
|
||||||
" <menuitem action='pause-torrent'/>\n"
|
" <menuitem action='pause-torrent'/>\n"
|
||||||
" <menuitem action='verify-torrent'/>\n"
|
" <menuitem action='verify-torrent'/>\n"
|
||||||
" <menuitem action='show-torrent-details'/>\n"
|
" <menuitem action='show-torrent-details'/>\n"
|
||||||
" <menuitem action='close-torrent'/>\n"
|
" <menuitem action='remove-torrent'/>\n"
|
||||||
" <menuitem action='delete-torrent'/>\n"
|
" <menuitem action='delete-torrent'/>\n"
|
||||||
" <separator/>\n"
|
" <separator/>\n"
|
||||||
" <menuitem action='close'/>\n"
|
" <menuitem action='close'/>\n"
|
||||||
|
@ -49,7 +49,7 @@ const char * fallback_ui_file =
|
||||||
" <toolitem action='open-torrent-toolbar'/>\n"
|
" <toolitem action='open-torrent-toolbar'/>\n"
|
||||||
" <toolitem action='start-torrent'/>\n"
|
" <toolitem action='start-torrent'/>\n"
|
||||||
" <toolitem action='pause-torrent'/>\n"
|
" <toolitem action='pause-torrent'/>\n"
|
||||||
" <toolitem action='close-torrent'/>\n"
|
" <toolitem action='remove-torrent'/>\n"
|
||||||
" <separator/>\n"
|
" <separator/>\n"
|
||||||
" <toolitem action='show-torrent-details'/>\n"
|
" <toolitem action='show-torrent-details'/>\n"
|
||||||
" </toolbar>\n"
|
" </toolbar>\n"
|
||||||
|
@ -62,7 +62,7 @@ const char * fallback_ui_file =
|
||||||
" <menuitem action='verify-torrent'/>\n"
|
" <menuitem action='verify-torrent'/>\n"
|
||||||
" <menuitem action='update-tracker'/>\n"
|
" <menuitem action='update-tracker'/>\n"
|
||||||
" <separator/>\n"
|
" <separator/>\n"
|
||||||
" <menuitem action='close-torrent'/>\n"
|
" <menuitem action='remove-torrent'/>\n"
|
||||||
" <menuitem action='delete-torrent'/>\n"
|
" <menuitem action='delete-torrent'/>\n"
|
||||||
" </popup>\n"
|
" </popup>\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
Loading…
Reference in New Issue