/* * This file Copyright (C) Mnemosyne LLC * * This file is licensed by the GPL version 2. Works owned by the * Transmission project are granted a special exemption to clause 2 (b) * so that the bulk of its code can remain under the MIT license. * This exemption does not extend to derived works not owned by * the Transmission project. * * $Id$ */ #include #include #include #include "conf.h" /* gtr_pref_string_get */ #include "hig.h" #include "relocate.h" #include "util.h" #define DATA_KEY "gtr-relocate-data" static char * previousLocation = NULL; struct relocate_dialog_data { int done; bool do_move; TrCore * core; GSList * torrent_ids; GtkWidget * message_dialog; GtkWidget * chooser_dialog; }; static void data_free (gpointer gdata) { struct relocate_dialog_data * data = gdata; g_slist_free (data->torrent_ids); g_free (data); } /*** **** ***/ static void startMovingNextTorrent (struct relocate_dialog_data * data) { char * str; const int id = GPOINTER_TO_INT (data->torrent_ids->data); tr_torrent * tor = gtr_core_find_torrent (data->core, id); if (tor != NULL) tr_torrentSetLocation (tor, previousLocation, data->do_move, NULL, &data->done); data->torrent_ids = g_slist_delete_link (data->torrent_ids, data->torrent_ids); str = g_strdup_printf (_("Moving \"%s\""), tr_torrentName (tor)); gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (data->message_dialog), str); g_free (str); } /* every once in awhile, check to see if the move is done. * if so, delete the dialog */ static gboolean onTimer (gpointer gdata) { struct relocate_dialog_data * data = gdata; const int done = data->done; if (done == TR_LOC_ERROR) { const int flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT; GtkWidget * w = gtk_message_dialog_new (GTK_WINDOW (data->message_dialog), flags, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", _("Couldn't move torrent")); gtk_dialog_run (GTK_DIALOG (w)); gtk_widget_destroy (GTK_WIDGET (data->message_dialog)); return FALSE; } else if (done == TR_LOC_DONE) { if (data->torrent_ids != NULL) { startMovingNextTorrent (data); } else { gtk_widget_destroy (GTK_WIDGET (data->chooser_dialog)); return FALSE; } } return TRUE; /* keep looping */ } static void onResponse (GtkDialog * dialog, int response, gpointer unused UNUSED) { if (response == GTK_RESPONSE_APPLY) { GtkWidget * w; GObject * d = G_OBJECT (dialog); struct relocate_dialog_data * data = g_object_get_data (d, DATA_KEY); GtkFileChooser * chooser = g_object_get_data (d, "chooser"); GtkToggleButton * move_tb = g_object_get_data (d, "move_rb"); char * location = gtk_file_chooser_get_filename (chooser); data->do_move = gtk_toggle_button_get_active (move_tb); /* pop up a dialog saying that the work is in progress */ w = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (w), _("This may take a moment…")); gtk_dialog_set_response_sensitive (GTK_DIALOG (w), GTK_RESPONSE_CLOSE, FALSE); gtk_widget_show (w); /* remember this location so that it can be the default next time */ g_free (previousLocation); previousLocation = location; /* start the move and periodically check its status */ data->message_dialog = w; data->done = TR_LOC_DONE; onTimer (data); gdk_threads_add_timeout_seconds (1, onTimer, data); } else { gtk_widget_destroy (GTK_WIDGET (dialog)); } } GtkWidget* gtr_relocate_dialog_new (GtkWindow * parent, TrCore * core, GSList * torrent_ids) { guint row; GtkWidget * w; GtkWidget * d; GtkWidget * t; struct relocate_dialog_data * data; d = gtk_dialog_new_with_buttons (_("Set Torrent Location"), parent, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL); gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_CANCEL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (d), GTK_RESPONSE_APPLY, GTK_RESPONSE_CANCEL, -1); g_signal_connect (d, "response", G_CALLBACK (onResponse), NULL); row = 0; t = hig_workarea_create (); hig_workarea_add_section_title (t, &row, _("Location")); if (previousLocation == NULL) previousLocation = g_strdup (gtr_pref_string_get (TR_PREFS_KEY_DOWNLOAD_DIR)); w = gtk_file_chooser_button_new (_("Set Torrent Location"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w), previousLocation); g_object_set_data (G_OBJECT (d), "chooser", w); hig_workarea_add_row (t, &row, _("Torrent _location:"), w, NULL); w = gtk_radio_button_new_with_mnemonic (NULL, _("_Move from the current folder")); g_object_set_data (G_OBJECT (d), "move_rb", w); hig_workarea_add_wide_control (t, &row, w); w = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (w), _("Local data is _already there")); hig_workarea_add_wide_control (t, &row, w); gtr_dialog_set_content (GTK_DIALOG (d), t); data = g_new0 (struct relocate_dialog_data, 1); data->core = core; data->torrent_ids = torrent_ids; data->chooser_dialog = d; g_object_set_data_full (G_OBJECT (d), DATA_KEY, data, data_free); return d; }