static void on_response(GtkDialog* dlg, gint id, FmProgressDisplay* data) { /* cancel the job */ if(id == GTK_RESPONSE_CANCEL || id == GTK_RESPONSE_DELETE_EVENT) { if(data->job) { fm_job_cancel(FM_JOB(data->job)); if(id != GTK_RESPONSE_CANCEL) fm_progress_display_destroy(data); } } else if(id == GTK_RESPONSE_CLOSE) fm_progress_display_destroy(data); }
/** * fm_file_ops_job_run_with_progress * @parent: parent window to show dialog over it * @job: (transfer full): job descriptor to run * * Runs the file operation job with a progress dialog. * The returned data structure will be freed in idle handler automatically * when it's not needed anymore. * * NOTE: INCONSISTENCY: it takes a reference from job * * Before 0.1.15 this call had different arguments. * * Return value: (transfer none): progress data; not usable; caller should not free it either. * * Since: 0.1.0 */ FmProgressDisplay* fm_file_ops_job_run_with_progress(GtkWindow* parent, FmFileOpsJob* job) { FmProgressDisplay* data; g_return_val_if_fail(job != NULL, NULL); data = g_slice_new0(FmProgressDisplay); data->job = job; if(parent) data->parent = g_object_ref(parent); data->delay_timeout = gdk_threads_add_timeout(SHOW_DLG_DELAY, on_show_dlg, data); g_signal_connect(job, "ask", G_CALLBACK(on_ask), data); g_signal_connect(job, "ask-rename", G_CALLBACK(on_ask_rename), data); g_signal_connect(job, "error", G_CALLBACK(on_error), data); g_signal_connect(job, "prepared", G_CALLBACK(on_prepared), data); g_signal_connect(job, "cur-file", G_CALLBACK(on_cur_file), data); g_signal_connect(job, "percent", G_CALLBACK(on_percent), data); g_signal_connect(job, "finished", G_CALLBACK(on_finished), data); g_signal_connect(job, "cancelled", G_CALLBACK(on_cancelled), data); if (!fm_job_run_async(FM_JOB(job))) { fm_progress_display_destroy(data); return NULL; } return data; }
static void on_progress_dialog_destroy(gpointer user_data, GObject* dlg) { FmProgressDisplay* data = (FmProgressDisplay*)user_data; data->dlg = NULL; /* it's destroying right now, don't destroy it again */ g_object_unref(data->error_buf); /* these will be not unref if no dlg */ g_object_unref(data->bold_tag); fm_progress_display_destroy(data); }
static void on_response(GtkDialog* dlg, gint id, FmProgressDisplay* data) { /* cancel the job */ if(id == GTK_RESPONSE_CANCEL) { fm_job_cancel(FM_JOB(data->job)); if (data->suspended) { fm_job_resume(FM_JOB(data->job)); data->suspended = FALSE; } } else if(id == GTK_RESPONSE_CLOSE || id == GTK_RESPONSE_DELETE_EVENT) fm_progress_display_destroy(data); else if (id == 1 && data->suspend) { if (data->suspended) { data->suspended = FALSE; fm_job_resume(FM_JOB(data->job)); gtk_button_set_label(data->suspend, _("_Pause")); gtk_button_set_image(data->suspend, gtk_image_new_from_stock(GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_BUTTON)); } else if (fm_job_pause(FM_JOB(data->job))) { data->suspended = TRUE; gtk_button_set_label(data->suspend, _("_Resume")); gtk_button_set_image(data->suspend, gtk_image_new_from_stock(GTK_STOCK_MEDIA_FORWARD, GTK_ICON_SIZE_BUTTON)); } else g_warning("FmJob failed to pause"); } }
static void on_finished (FmFileOpsJob *job, FmProgressDisplay *data) { GtkWidget *parent; if (data->update_timeout) { g_source_remove (data->update_timeout); data->update_timeout = 0; } parent = data->parent; if (data->dlg) { // errors happened if (data->has_error && data->dlg) { gtk_label_set_text (GTK_LABEL (data->current), ""); gtk_label_set_text (GTK_LABEL (data->remaining_time), "00:00:00"); gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dlg), GTK_RESPONSE_CANCEL, FALSE); gtk_dialog_add_button (GTK_DIALOG (data->dlg), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); gtk_image_set_from_stock (GTK_IMAGE (data->icon), GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); gtk_widget_show (data->msg); if (fm_job_is_cancelled (FM_JOB (data->job))) { gtk_label_set_text (GTK_LABEL (data->msg), _("The file operation is cancelled and there are some errors.")); gtk_window_set_title (GTK_WINDOW (data->dlg), _("Cancelled")); } else { gtk_label_set_text (GTK_LABEL (data->msg), _("The file operation is finished, but there are some errors.")); gtk_window_set_title (GTK_WINDOW (data->dlg), _("Finished")); } } else fm_progress_display_destroy (data); g_debug ("file operation is finished!"); } else fm_progress_display_destroy (data); /* sepcial handling for trash * FIXME_pcm: need to refactor this to use a more elegant way later. */ if (job->type == FM_FILE_OP_TRASH) { FmPathList *unsupported = (FmPathList*)g_object_get_data (G_OBJECT (job), "trash-unsupported"); // some files cannot be trashed because underlying filesystems don't support it. // delete them instead if (unsupported) { if (fm_yes_no (GTK_WINDOW (parent), NULL, _("Some files cannot be moved to trash can because " "the underlying file systems don't support this operation.\n" "Do you want to delete them instead?"), TRUE)) { FmJob *job = fm_file_ops_job_new (FM_FILE_OP_DELETE, unsupported); fm_file_ops_job_run_with_progress (GTK_WINDOW (data->parent), (FmFileOpsJob*) job); } } } }
static void on_finished(FmFileOpsJob* job, FmProgressDisplay* data) { GtkWindow* parent = NULL; /* preserve pointers that fm_progress_display_destroy() will unreference as they may be requested by trash support below */ if(data->parent) parent = g_object_ref(data->parent); g_object_ref(job); if(data->dlg) { /* errors happened */ if(data->has_error) { gtk_label_set_text(data->current, ""); gtk_label_set_text(data->remaining_time, "00:00:00"); gtk_dialog_set_response_sensitive(data->dlg, GTK_RESPONSE_CANCEL, FALSE); gtk_dialog_add_button(data->dlg, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); gtk_image_set_from_stock(data->icon, GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); gtk_widget_show(GTK_WIDGET(data->msg)); if(fm_job_is_cancelled(FM_JOB(job))) { gtk_label_set_text(data->msg, _("The file operation is cancelled and there are some errors.")); gtk_window_set_title(GTK_WINDOW(data->dlg), _("Cancelled")); } else { gtk_label_set_text(data->msg, _("The file operation is finished, but there are some errors.")); gtk_window_set_title(GTK_WINDOW(data->dlg), _("Finished")); } } else fm_progress_display_destroy(data); g_debug("file operation is finished!"); } else fm_progress_display_destroy(data); /* if it's not destroyed yet then it will be destroyed with dialog window */ /* sepcial handling for trash * FIXME: need to refactor this to use a more elegant way later. */ if(job->type == FM_FILE_OP_TRASH) /* FIXME: direct access to job struct! */ { FmPathList* unsupported = (FmPathList*)g_object_get_data(G_OBJECT(job), "trash-unsupported"); /* some files cannot be trashed because underlying filesystems don't support it. */ g_object_unref(job); if(unsupported) /* delete them instead */ { /* FIXME: parent window might be already destroyed! */ if(fm_yes_no(parent, NULL, _("Some files cannot be moved to trash can because " "the underlying file systems don't support this operation.\n" "Do you want to delete them instead?"), TRUE)) { job = fm_file_ops_job_new(FM_FILE_OP_DELETE, unsupported); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ } } } else g_object_unref(job); if(parent) g_object_unref(parent); }
static void on_cancelled(FmFileOpsJob* job, FmProgressDisplay* data) { fm_progress_display_destroy(data); g_debug("file operation is cancelled!"); }