diff --git a/autogen.sh b/autogen.sh index eeb2583c5..d3aa02e70 100755 --- a/autogen.sh +++ b/autogen.sh @@ -34,8 +34,3 @@ fi cd $ORIGDIR || exit $? -if test -z "$AUTOGEN_SUBDIR_MODE"; then - $srcdir/configure --enable-maintainer-mode $AUTOGEN_CONFIGURE_ARGS "$@" || exit $? - echo - echo "Now type 'make' to compile $PROJECT." -fi diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 7e9601730..a8fe77457 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -14,6 +14,7 @@ AM_CFLAGS = \ noinst_HEADERS = \ actions.h \ conf.h \ + details.h \ dialogs.h \ hig.h \ io.h \ @@ -23,11 +24,10 @@ noinst_HEADERS = \ logo.h \ makemeta-ui.h \ msgwin.h \ - open.h \ + open-dialog.h \ stats.h \ sexy-icon-entry.h \ torrent-cell-renderer.h \ - torrent-inspector.h \ tr_core.h \ tr_icon.h \ tr_prefs.h \ @@ -41,6 +41,7 @@ bin_PROGRAMS = transmission transmission_SOURCES = \ actions.c \ conf.c \ + details.c \ dialogs.c \ file-list.c \ hig.c \ @@ -49,11 +50,10 @@ transmission_SOURCES = \ main.c \ makemeta-ui.c \ msgwin.c \ - open.c \ + open-dialog.c \ sexy-icon-entry.c \ stats.c \ torrent-cell-renderer.c \ - torrent-inspector.c \ tr_core.c \ tr_icon.c \ tr_prefs.c \ diff --git a/gtk/actions.c b/gtk/actions.c index 62c1781ed..77b825b2d 100644 --- a/gtk/actions.c +++ b/gtk/actions.c @@ -15,7 +15,6 @@ #include #include #include "conf.h" -#include "torrent-inspector.h" #include "tr_core.h" #include "tr_prefs.h" #include "lock.h" @@ -115,7 +114,7 @@ static GtkActionEntry entries[] = { "pause-torrent", GTK_STOCK_MEDIA_PAUSE, N_("_Pause"), "P", NULL, G_CALLBACK(action_cb) }, { "remove-torrent", GTK_STOCK_REMOVE, - N_("_Remove"), "Delete", NULL, G_CALLBACK(action_cb) }, + N_("_Remove"), "Delete", NULL, G_CALLBACK(action_cb) }, { "new-torrent", GTK_STOCK_NEW, N_("_New..."), NULL, N_("Create a new torrent"), G_CALLBACK(action_cb) }, diff --git a/gtk/torrent-inspector.c b/gtk/details.c similarity index 99% rename from gtk/torrent-inspector.c rename to gtk/details.c index e7b746b31..62599b0c9 100644 --- a/gtk/torrent-inspector.c +++ b/gtk/details.c @@ -19,10 +19,10 @@ #include #include "actions.h" +#include "details.h" #include "file-list.h" #include "tr_torrent.h" #include "hig.h" -#include "torrent-inspector.h" #include "util.h" #define UPDATE_INTERVAL_MSEC 2000 diff --git a/gtk/torrent-inspector.h b/gtk/details.h similarity index 100% rename from gtk/torrent-inspector.h rename to gtk/details.h diff --git a/gtk/dialogs.c b/gtk/dialogs.c index 717233c1c..15b48b6aa 100644 --- a/gtk/dialogs.c +++ b/gtk/dialogs.c @@ -274,3 +274,105 @@ askquit( TrCore * core, gtk_widget_show_all( wind ); } + +/*** +**** +***/ + +struct DeleteData +{ + GtkWidget * delete_files_tb; + GList * torrents; + TrCore * core; +}; + +static void +deleteDownloadedToggled( GtkToggleButton * tb, gpointer warn ) +{ + GtkWidget * w = GTK_WIDGET( warn ); + + if( gtk_toggle_button_get_active( tb ) ) + gtk_widget_show( w ); + else + gtk_widget_hide( w ); +} + +static void +deleteResponse( GtkDialog * dialog, gint response, gpointer gdata ) +{ + struct DeleteData * data = gdata; + const int del = response == GTK_RESPONSE_YES; + const int deleteFiles = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->delete_files_tb ) ); + GList * l; + + for( l=data->torrents; l!=NULL; l=l->next ) + { + TrTorrent * gtor = TR_TORRENT( l->data ); + + if( del ) + tr_core_remove_torrent( data->core, gtor, deleteFiles ); + else + g_object_unref( G_OBJECT( gtor ) ); + } + + gtk_widget_destroy( GTK_WIDGET( dialog ) ); + g_list_free( data->torrents ); + g_free( data ); +} + +void +confirmDelete( GtkWindow * parent, + TrCore * core, + GList * torrents ) +{ + char buf[1024]; + GtkWidget * t; + GtkWidget * d; + GtkWidget * w; + GtkWidget * warn; + struct DeleteData * dd = g_new0( struct DeleteData, 1 ); + + dd->core = core; + dd->torrents = torrents; + + d = gtk_dialog_new_with_buttons( _( "Remove Torrent" ), + parent, + GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR, + GTK_STOCK_NO, GTK_RESPONSE_NO, + GTK_STOCK_YES, GTK_RESPONSE_YES, + NULL ); + g_signal_connect( d, "response", G_CALLBACK( deleteResponse ), dd ); + + t = gtk_table_new( 3, 2, FALSE ); + gtk_container_set_border_width( GTK_CONTAINER( t ), GUI_PAD_BIG ); + gtk_table_set_col_spacing( GTK_TABLE( t ), 0, GUI_PAD_BIG ); + gtk_table_set_row_spacings( GTK_TABLE( t ), GUI_PAD_BIG ); + + w = gtk_image_new_from_stock( GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG ); + gtk_table_attach( GTK_TABLE( t ), w, 0, 1, 0, 3, GTK_FILL, GTK_FILL, 0, 0 ); + gtk_widget_show( w ); + + g_snprintf( buf, sizeof(buf), "%s", _( "Remove the selected torrent(s)?" ) ); + w = gtk_label_new( buf ); + gtk_misc_set_alignment( GTK_MISC( w ), 0.0, 0.5 ); + gtk_label_set_use_markup( GTK_LABEL( w ), TRUE ); + gtk_table_attach( GTK_TABLE( t ), w, 1, 2, 0, 1, GTK_FILL, 0, 0, 0 ); + gtk_widget_show( w ); + + g_snprintf( buf, sizeof( buf ), "%s", + _( "All downloaded files for this torrent will be deleted!" ) ); + warn = gtk_label_new( buf ); + gtk_label_set_use_markup( GTK_LABEL( warn ), TRUE ); + gtk_table_attach( GTK_TABLE( t ), warn, 1, 2, 2, 3, GTK_FILL, 0, 0, 0 ); + + w = gtk_check_button_new_with_mnemonic( _( "Delete _downloaded files" ) ); + dd->delete_files_tb = w; + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), FALSE ); + gtk_table_attach( GTK_TABLE( t ), w, 1, 2, 1, 2, GTK_FILL, 0, 0, 0 ); + g_signal_connect( w, "toggled", G_CALLBACK(deleteDownloadedToggled), warn ); + gtk_widget_show( w ); + + gtk_widget_show( t ); + gtk_container_add( GTK_CONTAINER( GTK_DIALOG( d )->vbox ), t ); + gtk_widget_show( d ); +} diff --git a/gtk/dialogs.h b/gtk/dialogs.h index 95b9def00..e2aadcef1 100644 --- a/gtk/dialogs.h +++ b/gtk/dialogs.h @@ -35,4 +35,6 @@ void promptfordir( GtkWindow* parent, TrCore*, GList* filenames, tr_ctor* ); /* 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 confirmDelete( GtkWindow * parent, TrCore * core, GList * torrents ); + #endif /* TG_PREFS_H */ diff --git a/gtk/main.c b/gtk/main.c index e81cf28d1..f1894cef4 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -43,13 +43,13 @@ #include "actions.h" #include "conf.h" +#include "details.h" #include "dialogs.h" #include "ipc.h" #include "makemeta-ui.h" #include "msgwin.h" -#include "open.h" +#include "open-dialog.h" #include "stats.h" -#include "torrent-inspector.h" #include "tr_core.h" #include "tr_icon.h" #include "tr_prefs.h" @@ -154,8 +154,6 @@ static void prefschanged( TrCore * core, const char * key, gpointer data ); static gboolean updatemodel(gpointer gdata); -static GList * -getselection( struct cbdata * cbdata ); static void setupsighandlers(void); @@ -853,35 +851,6 @@ updatemodel(gpointer gdata) { return TRUE; } -/* returns a GList of GtkTreeRowReferences to each selected row */ -static GList * -getselection( struct cbdata * cbdata ) -{ - GList * rows = NULL; - - if( NULL != cbdata->wind ) - { - GList * l; - GtkTreeSelection *s = tr_window_get_selection(cbdata->wind); - GtkTreeModel * filter_model; - GtkTreeModel * store_model; - rows = gtk_tree_selection_get_selected_rows( s, &filter_model ); - store_model = gtk_tree_model_filter_get_model( - GTK_TREE_MODEL_FILTER( filter_model ) ); - for( l=rows; l!=NULL; l=l->next ) - { - GtkTreePath * path = gtk_tree_model_filter_convert_path_to_child_path( - GTK_TREE_MODEL_FILTER( filter_model ), l->data ); - GtkTreeRowReference * ref = gtk_tree_row_reference_new( store_model, path ); - gtk_tree_path_free( path ); - gtk_tree_path_free( l->data ); - l->data = ref; - } - } - - return rows; -} - static void about ( GtkWindow * parent ) { @@ -935,6 +904,18 @@ stopTorrentForeach (GtkTreeModel * model, g_object_unref( G_OBJECT( tor ) ); } +static void +accumulateSelectedTorrents( GtkTreeModel * model, + GtkTreePath * path UNUSED, + GtkTreeIter * iter, + gpointer gdata ) +{ + GList ** data = ( GList** ) gdata; + TrTorrent * tor = NULL; + gtk_tree_model_get( model, iter, MC_TORRENT, &tor, -1 ); + *data = g_list_append( *data, tor ); +} + static void updateTrackerForeach (GtkTreeModel * model, GtkTreePath * path UNUSED, @@ -1054,22 +1035,11 @@ doAction ( const char * action_name, gpointer user_data ) } else if (!strcmp (action_name, "remove-torrent")) { - /* this modifies the model's contents, so can't use foreach */ - GList *l, *sel = getselection( data ); - GtkTreeModel *model = tr_core_model( data->core ); - gtk_tree_selection_unselect_all( tr_window_get_selection( data->wind) ); - for( l=sel; l!=NULL; l=l->next ) - { - GtkTreeIter iter; - GtkTreeRowReference * reference = l->data; - GtkTreePath * path = gtk_tree_row_reference_get_path( reference ); - gtk_tree_model_get_iter( model, &iter, path ); - tr_core_delete_torrent( data->core, &iter ); - gtk_tree_path_free( path ); - gtk_tree_row_reference_free( reference ); - changed = TRUE; - } - g_list_free( sel ); + GList * l = NULL; + GtkTreeSelection * s = tr_window_get_selection(data->wind); + gtk_tree_selection_selected_foreach( s, accumulateSelectedTorrents, &l ); + if( l != NULL ) + confirmDelete( data->wind, data->core, l ); } else if (!strcmp (action_name, "close")) { diff --git a/gtk/open.c b/gtk/open-dialog.c similarity index 99% rename from gtk/open.c rename to gtk/open-dialog.c index 5426bed59..db2f770fa 100644 --- a/gtk/open.c +++ b/gtk/open-dialog.c @@ -15,7 +15,7 @@ #include #include "file-list.h" #include "hig.h" -#include "open.h" +#include "open-dialog.h" struct OpenData { diff --git a/gtk/open.h b/gtk/open-dialog.h similarity index 100% rename from gtk/open.h rename to gtk/open-dialog.h diff --git a/gtk/tr_core.c b/gtk/tr_core.c index f103dc40b..5623de458 100644 --- a/gtk/tr_core.c +++ b/gtk/tr_core.c @@ -571,6 +571,48 @@ tr_core_delete_torrent( TrCore * self, GtkTreeIter * iter ) g_object_unref( G_OBJECT( tor ) ); } +static gboolean +findTorrentInModel( TrCore * core, const TrTorrent * gtor, GtkTreeIter * setme ) +{ + int match = 0; + GtkTreeIter iter; + GtkTreeModel * model = tr_core_model( core ); + + if( gtk_tree_model_iter_children( model, &iter, NULL ) ) do + { + TrTorrent * tmp; + gtk_tree_model_get( model, &iter, MC_TORRENT, &tmp, -1 ); + match = tmp == gtor; + g_object_unref( G_OBJECT( tmp ) ); + } + while( !match && gtk_tree_model_iter_next( model, &iter ) ); + + if( match ) + *setme = iter; + + return match; +} + +void +tr_core_remove_torrent( TrCore * self, TrTorrent * gtor, int deleteFiles ) +{ + GtkTreeIter iter; + GtkTreeModel * model = tr_core_model( self ); + + /* remove from the gui */ + if( findTorrentInModel( self, gtor, &iter ) ) + gtk_list_store_remove( GTK_LIST_STORE( model ), &iter ); + + /* maybe delete the downloaded files */ + if( deleteFiles ) + tr_torrent_delete_files( gtor ); + + /* delete the torrent */ + tr_torrentRemoveSaved( tr_torrent_handle( gtor ) ); + g_object_unref( G_OBJECT( gtor ) ); +} + + /*** **** ***/ diff --git a/gtk/tr_core.h b/gtk/tr_core.h index e136ff57f..3e3e625a7 100644 --- a/gtk/tr_core.h +++ b/gtk/tr_core.h @@ -140,6 +140,8 @@ void tr_core_torrents_added( TrCore * self ); void tr_core_delete_torrent( TrCore * self, GtkTreeIter * iter ); +void tr_core_remove_torrent( TrCore * self, TrTorrent * gtor, int deleteFiles ); + /* update the model with current torrent status */ void tr_core_update( TrCore * self ); diff --git a/gtk/tr_torrent.c b/gtk/tr_torrent.c index de0227661..8c2ca2870 100644 --- a/gtk/tr_torrent.c +++ b/gtk/tr_torrent.c @@ -22,11 +22,13 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ +#include #include #include #include #include +#include #include @@ -285,3 +287,24 @@ tr_torrent_status_str ( TrTorrent * gtor ) return top; } + +void +tr_torrent_delete_files( TrTorrent * gtor ) +{ + int i; + const tr_info * info = tr_torrent_info( gtor ); + const char * stop = tr_torrentGetFolder( tr_torrent_handle( gtor ) ); + + for( i=0; info && ifileCount; ++i ) + { + char * file = g_build_filename( stop, info->files[i].name, NULL ); + while( strcmp( stop, file ) && strlen(stop) < strlen(file) ) + { + char * swap = g_path_get_dirname( file ); + g_unlink( file ); + g_free( file ); + file = swap; + } + g_free( file ); + } +} diff --git a/gtk/tr_torrent.h b/gtk/tr_torrent.h index 0a7cf7a5c..23e8c9915 100644 --- a/gtk/tr_torrent.h +++ b/gtk/tr_torrent.h @@ -76,6 +76,9 @@ tr_torrent_stop( TrTorrent * tor ); char* tr_torrent_status_str ( TrTorrent * tor ); +void +tr_torrent_delete_files( TrTorrent * tor ); + void tr_torrent_check_seeding_cap ( TrTorrent* ); void diff --git a/po/POTFILES.in b/po/POTFILES.in index 4fbd3e820..0ee9e55a7 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,6 +2,7 @@ gtk/transmission.desktop.in gtk/actions.c gtk/conf.c +gtk/details.c gtk/dialogs.c gtk/file-list.c gtk/hig.c @@ -10,10 +11,9 @@ gtk/ipc.c gtk/main.c gtk/makemeta-ui.c gtk/msgwin.c -gtk/open.c +gtk/open-dialog.c gtk/stats.c gtk/torrent-cell-renderer.c -gtk/torrent-inspector.c gtk/tr_core.c gtk/tr_icon.c gtk/tr_prefs.c