2 * This file Copyright (C) 2009-2010 Mnemosyne LLC
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
10 * $Id: relocate.c 11280 2010-10-01 13:33:39Z charles $
13 #include <libtransmission/transmission.h>
15 #include <glib/gi18n.h>
18 #include "conf.h" /* pref_string_get */
23 #define DATA_KEY "gtr-relocate-data"
25 static char * previousLocation
= NULL
;
27 struct relocate_dialog_data
33 GtkWidget
* message_dialog
;
34 GtkWidget
* chooser_dialog
;
38 data_free( gpointer gdata
)
40 struct relocate_dialog_data
* data
= gdata
;
41 g_slist_free( data
->torrent_ids
);
50 startMovingNextTorrent( struct relocate_dialog_data
* data
)
53 const int id
= GPOINTER_TO_INT( data
->torrent_ids
->data
);
55 tr_session
* session
= tr_core_session( data
->core
);
57 tr_torrent
* tor
= tr_torrentFindFromId( session
, id
);
59 tr_torrentSetLocation( tor
, previousLocation
, data
->do_move
, NULL
, &data
->done
);
61 data
->torrent_ids
= g_slist_delete_link( data
->torrent_ids
,
64 str
= g_strdup_printf( _( "Moving \"%s\"" ), tr_torrentInfo(tor
)->name
);
65 gtk_message_dialog_set_markup( GTK_MESSAGE_DIALOG( data
->message_dialog
), str
);
69 /* every once in awhile, check to see if the move is done.
70 * if so, delete the dialog */
72 onTimer( gpointer gdata
)
74 struct relocate_dialog_data
* data
= gdata
;
75 const int done
= data
->done
;
77 if( done
== TR_LOC_ERROR
)
79 const int flags
= GTK_DIALOG_MODAL
80 | GTK_DIALOG_DESTROY_WITH_PARENT
;
81 GtkWidget
* w
= gtk_message_dialog_new( GTK_WINDOW( data
->message_dialog
),
86 _( "Couldn't move torrent" ) );
87 gtk_dialog_run( GTK_DIALOG( w
) );
88 gtk_widget_destroy( GTK_WIDGET( data
->message_dialog
) );
91 else if( done
== TR_LOC_DONE
)
93 if( data
->torrent_ids
!= NULL
)
95 startMovingNextTorrent( data
);
99 gtk_widget_destroy( GTK_WIDGET( data
->chooser_dialog
) );
104 return TRUE
; /* keep looping */
108 onResponse( GtkDialog
* dialog
, int response
, gpointer unused UNUSED
)
110 if( response
== GTK_RESPONSE_APPLY
)
113 GObject
* d
= G_OBJECT( dialog
);
114 struct relocate_dialog_data
* data
= g_object_get_data( d
, DATA_KEY
);
115 GtkFileChooser
* chooser
= g_object_get_data( d
, "chooser" );
116 GtkToggleButton
* move_tb
= g_object_get_data( d
, "move_rb" );
117 char * location
= gtk_file_chooser_get_filename( chooser
);
119 data
->do_move
= gtk_toggle_button_get_active( move_tb
);
121 /* pop up a dialog saying that the work is in progress */
122 w
= gtk_message_dialog_new( GTK_WINDOW( dialog
),
123 GTK_DIALOG_DESTROY_WITH_PARENT
| GTK_DIALOG_MODAL
,
127 gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( w
), _( "This may take a moment..." ) );
128 gtk_dialog_set_response_sensitive( GTK_DIALOG( w
), GTK_RESPONSE_CLOSE
, FALSE
);
129 gtk_widget_show( w
);
131 /* remember this location so that it can be the default next time */
132 g_free( previousLocation
);
133 previousLocation
= location
;
135 /* start the move and periodically check its status */
136 data
->message_dialog
= w
;
137 data
->done
= TR_LOC_DONE
;
139 gtr_timeout_add_seconds( 1, onTimer
, data
);
143 gtk_widget_destroy( GTK_WIDGET( dialog
) );
148 gtr_relocate_dialog_new( GtkWindow
* parent
,
150 GSList
* torrent_ids
)
156 struct relocate_dialog_data
* data
;
158 d
= gtk_dialog_new_with_buttons( _( "Set Torrent Location" ), parent
,
159 GTK_DIALOG_DESTROY_WITH_PARENT
|
161 GTK_DIALOG_NO_SEPARATOR
,
162 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
163 GTK_STOCK_APPLY
, GTK_RESPONSE_APPLY
,
165 gtk_dialog_set_default_response( GTK_DIALOG( d
),
166 GTK_RESPONSE_CANCEL
);
167 gtk_dialog_set_alternative_button_order( GTK_DIALOG( d
),
171 g_signal_connect( d
, "response", G_CALLBACK( onResponse
), NULL
);
174 t
= hig_workarea_create( );
175 hig_workarea_add_section_title( t
, &row
, _( "Location" ) );
177 if( previousLocation
== NULL
)
178 previousLocation
= g_strdup( pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR
) );
179 w
= gtk_file_chooser_button_new( _( "Set Torrent Location" ), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
);
180 gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( w
), previousLocation
);
181 g_object_set_data( G_OBJECT( d
), "chooser", w
);
182 hig_workarea_add_row( t
, &row
, _( "Torrent _location:" ), w
, NULL
);
183 w
= gtk_radio_button_new_with_mnemonic( NULL
, _( "_Move from the current folder" ) );
184 g_object_set_data( G_OBJECT( d
), "move_rb", w
);
185 hig_workarea_add_wide_control( t
, &row
, w
);
186 w
= gtk_radio_button_new_with_mnemonic_from_widget( GTK_RADIO_BUTTON( w
), _( "Local data is _already there" ) );
187 hig_workarea_add_wide_control( t
, &row
, w
);
188 hig_workarea_finish( t
, &row
);
189 gtk_widget_show_all( t
);
190 gtk_box_pack_start( GTK_BOX( GTK_DIALOG( d
)->vbox
), t
, TRUE
, TRUE
, 0 );
192 data
= g_new0( struct relocate_dialog_data
, 1 );
194 data
->torrent_ids
= torrent_ids
;
195 data
->chooser_dialog
= d
;
196 g_object_set_data_full( G_OBJECT( d
), DATA_KEY
, data
, data_free
);