/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* * Libbrasero-burn * Copyright (C) Philippe Rouquier 2005-2009 * * Libbrasero-burn is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * The Libbrasero-burn authors hereby grant permission for non-GPL compatible * GStreamer plugins to be used and distributed together with GStreamer * and Libbrasero-burn. This permission is above and beyond the permissions granted * by the GPL license by which Libbrasero-burn is covered. If you modify this code * you may extend this exception to your version of the code, but you are not * obligated to do so. If you do not wish to do so, delete this exception * statement from your version. * * Libbrasero-burn is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to: * The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301, USA. */ #include #include #include #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include "brasero-burn-dialog.h" #include "brasero-session-cfg.h" #include "brasero-session-helper.h" #include "burn-basics.h" #include "burn-debug.h" #include "brasero-progress.h" #include "brasero-cover.h" #include "brasero-track-type-private.h" #include "brasero-tags.h" #include "brasero-session.h" #include "brasero-track-image.h" #include "brasero-medium.h" #include "brasero-drive.h" #include "brasero-misc.h" #include "brasero-pk.h" G_DEFINE_TYPE (BraseroBurnDialog, brasero_burn_dialog, GTK_TYPE_DIALOG); static void brasero_burn_dialog_cancel_clicked_cb (GtkWidget *button, BraseroBurnDialog *dialog); typedef struct BraseroBurnDialogPrivate BraseroBurnDialogPrivate; struct BraseroBurnDialogPrivate { BraseroBurn *burn; BraseroBurnSession *session; /* This is to remember some settins after ejection */ BraseroTrackType input; BraseroMedia media; GtkWidget *progress; GtkWidget *header; GtkWidget *cancel; GtkWidget *image; /* for our final statistics */ GTimer *total_time; gint64 total_size; GSList *rates; GMainLoop *loop; gint wait_ready_state_id; GCancellable *cancel_plugin; gchar *initial_title; gchar *initial_icon; guint num_copies; guint is_writing:1; guint is_creating_image:1; }; #define BRASERO_BURN_DIALOG_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_BURN_DIALOG, BraseroBurnDialogPrivate)) #define TIMEOUT 10000 static void brasero_burn_dialog_update_media (BraseroBurnDialog *dialog) { BraseroBurnDialogPrivate *priv; BraseroMedia media; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (brasero_burn_session_is_dest_file (priv->session)) media = BRASERO_MEDIUM_FILE; else if (!brasero_track_type_get_has_medium (&priv->input)) media = brasero_burn_session_get_dest_media (priv->session); else { BraseroMedium *medium; medium = brasero_burn_session_get_src_medium (priv->session); if (!medium) media = brasero_burn_session_get_dest_media (BRASERO_BURN_SESSION (priv->session)); else media = brasero_medium_get_status (medium); } priv->media = media; } static void brasero_burn_dialog_notify_daemon_close (NotifyNotification *notification, BraseroBurnDialog *dialog) { g_object_unref (notification); } static gboolean brasero_burn_dialog_notify_daemon (BraseroBurnDialog *dialog, const char *message) { NotifyNotification *notification; GError *error = NULL; gboolean result; if (!notify_is_initted ()) { notify_init (_("Brasero notification")); } notification = notify_notification_new (message, NULL, GTK_STOCK_CDROM); if (!notification) return FALSE; g_signal_connect (notification, "closed", G_CALLBACK (brasero_burn_dialog_notify_daemon_close), dialog); notify_notification_set_timeout (notification, 10000); notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL); notify_notification_set_hint_string (notification, "desktop-entry", "brasero"); result = notify_notification_show (notification, &error); if (error) { g_warning ("Error showing notification"); g_error_free (error); } return result; } static GtkWidget * brasero_burn_dialog_create_message (BraseroBurnDialog *dialog, GtkMessageType type, GtkButtonsType buttons, const gchar *main_message) { const gchar *icon_name; GtkWidget *message; icon_name = gtk_window_get_icon_name (GTK_WINDOW (dialog)); message = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_DESTROY_WITH_PARENT| GTK_DIALOG_MODAL, type, buttons, "%s", main_message); gtk_window_set_icon_name (GTK_WINDOW (message), icon_name); return message; } static gchar * brasero_burn_dialog_create_dialog_title_for_action (BraseroBurnDialog *dialog, const gchar *action, gint percent) { gchar *tmp; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (priv->initial_title) action = priv->initial_title; if (percent >= 0 && percent <= 100) { /* Translators: This string is used in the title bar %s is the action currently performed */ tmp = g_strdup_printf (_("%s (%i%% Done)"), action, percent); } else /* Translators: This string is used in the title bar %s is the action currently performed */ tmp = g_strdup (action); return tmp; } static void brasero_burn_dialog_update_title (BraseroBurnDialog *dialog, BraseroTrackType *input) { gchar *title = NULL; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (priv->media == BRASERO_MEDIUM_FILE) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Creating Image"), -1); else if (priv->media & BRASERO_MEDIUM_DVD) { if (!brasero_track_type_get_has_medium (input)) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Burning DVD"), -1); else title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Copying DVD"), -1); } else if (priv->media & BRASERO_MEDIUM_CD) { if (!brasero_track_type_get_has_medium (input)) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Burning CD"), -1); else title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Copying CD"), -1); } else { if (!brasero_track_type_get_has_medium (input)) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Burning Disc"), -1); else title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Copying Disc"), -1); } if (title) { gtk_window_set_title (GTK_WINDOW (dialog), title); g_free (title); } } /** * NOTE: if input is DISC then media is the media input */ static void brasero_burn_dialog_update_info (BraseroBurnDialog *dialog, BraseroTrackType *input, gboolean dummy) { gchar *header = NULL; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (priv->media == BRASERO_MEDIUM_FILE) { /* we are creating an image to the hard drive */ gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "iso-image-new", GTK_ICON_SIZE_DIALOG); header = g_strdup_printf ("%s", _("Creating image")); } else if (priv->media & BRASERO_MEDIUM_DVD) { if (brasero_track_type_get_has_stream (input) && BRASERO_STREAM_FORMAT_HAS_VIDEO (input->subtype.stream_format)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of video DVD burning")); else header = g_strdup_printf ("%s", _("Burning video DVD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical-video-new", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_data (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of data DVD burning")); else header = g_strdup_printf ("%s", _("Burning data DVD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical-data-new", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_image (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of image to DVD burning")); else header = g_strdup_printf ("%s", _("Burning image to DVD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_medium (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of data DVD copying")); else header = g_strdup_printf ("%s", _("Copying data DVD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical-copy", GTK_ICON_SIZE_DIALOG); } } else if (priv->media & BRASERO_MEDIUM_CD) { if (brasero_track_type_get_has_stream (input) && BRASERO_STREAM_FORMAT_HAS_VIDEO (input->subtype.stream_format)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of (S)VCD burning")); else header = g_strdup_printf ("%s", _("Burning (S)VCD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "drive-removable-media", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_stream (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of audio CD burning")); else header = g_strdup_printf ("%s", _("Burning audio CD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical-audio-new", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_data (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of data CD burning")); else header = g_strdup_printf ("%s", _("Burning data CD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical-data-new", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_medium (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of CD copying")); else header = g_strdup_printf ("%s", _("Copying CD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical-copy", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_image (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of image to CD burning")); else header = g_strdup_printf ("%s", _("Burning image to CD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "media-optical", GTK_ICON_SIZE_DIALOG); } } else { if (brasero_track_type_get_has_stream (input) && BRASERO_STREAM_FORMAT_HAS_VIDEO (input->subtype.stream_format)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of video disc burning")); else header = g_strdup_printf ("%s", _("Burning video disc")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "drive-removable-media", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_stream (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of audio CD burning")); else header = g_strdup_printf ("%s", _("Burning audio CD")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "drive-removable-media", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_data (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of data disc burning")); else header = g_strdup_printf ("%s", _("Burning data disc")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "drive-removable-media", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_medium (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of disc copying")); else header = g_strdup_printf ("%s", _("Copying disc")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "drive-removable-media", GTK_ICON_SIZE_DIALOG); } else if (brasero_track_type_get_has_image (input)) { if (dummy) header = g_strdup_printf ("%s", _("Simulation of image to disc burning")); else header = g_strdup_printf ("%s", _("Burning image to disc")); gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "drive-removable-media", GTK_ICON_SIZE_DIALOG); } } gtk_label_set_text (GTK_LABEL (priv->header), header); gtk_label_set_use_markup (GTK_LABEL (priv->header), TRUE); g_free (header); } static void brasero_burn_dialog_wait_for_insertion_cb (BraseroDrive *drive, BraseroMedium *medium, GtkDialog *message) { /* we might have a dialog waiting for the * insertion of a disc if so close it */ gtk_dialog_response (GTK_DIALOG (message), GTK_RESPONSE_OK); } static gint brasero_burn_dialog_wait_for_insertion (BraseroBurnDialog *dialog, BraseroDrive *drive, const gchar *main_message, const gchar *secondary_message, gboolean sound_clue) { gint result; gulong added_id; GtkWidget *message; gboolean hide = FALSE; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) { gtk_widget_show (GTK_WIDGET (dialog)); hide = TRUE; } g_timer_stop (priv->total_time); if (secondary_message) { message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_WARNING, GTK_BUTTONS_CANCEL, main_message); if (secondary_message) gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s", secondary_message); } else { gchar *string; message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_WARNING, GTK_BUTTONS_CANCEL, NULL); string = g_strdup_printf ("%s", main_message); gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (message), string); g_free (string); } /* connect to signals to be warned when media is inserted */ added_id = g_signal_connect_after (drive, "medium-added", G_CALLBACK (brasero_burn_dialog_wait_for_insertion_cb), message); if (sound_clue) { gtk_widget_show (GTK_WIDGET (message)); ca_gtk_play_for_widget (GTK_WIDGET (message), 0, CA_PROP_EVENT_ID, "complete-media-burn", CA_PROP_EVENT_DESCRIPTION, main_message, NULL); } result = gtk_dialog_run (GTK_DIALOG (message)); g_signal_handler_disconnect (drive, added_id); gtk_widget_destroy (message); if (hide) gtk_widget_hide (GTK_WIDGET (dialog)); g_timer_continue (priv->total_time); return result; } static gchar * brasero_burn_dialog_get_media_type_string (BraseroBurn *burn, BraseroMedia type, gboolean insert) { gchar *message = NULL; if (type & BRASERO_MEDIUM_HAS_DATA) { if (!insert) { if (type & BRASERO_MEDIUM_REWRITABLE) message = g_strdup (_("Please replace the disc with a rewritable disc holding data.")); else message = g_strdup (_("Please replace the disc with a disc holding data.")); } else { if (type & BRASERO_MEDIUM_REWRITABLE) message = g_strdup (_("Please insert a rewritable disc holding data.")); else message = g_strdup (_("Please insert a disc holding data.")); } } else if (type & BRASERO_MEDIUM_WRITABLE) { gint64 isosize = 0; brasero_burn_status (burn, NULL, &isosize, NULL, NULL); if ((type & BRASERO_MEDIUM_CD) && !(type & BRASERO_MEDIUM_DVD)) { if (!insert) { if (isosize > 0) message = g_strdup_printf (_("Please replace the disc with a writable CD with at least %i MiB of free space."), (int) (isosize / 1048576)); else message = g_strdup (_("Please replace the disc with a writable CD.")); } else { if (isosize > 0) message = g_strdup_printf (_("Please insert a writable CD with at least %i MiB of free space."), (int) (isosize / 1048576)); else message = g_strdup (_("Please insert a writable CD.")); } } else if (!(type & BRASERO_MEDIUM_CD) && (type & BRASERO_MEDIUM_DVD)) { if (!insert) { if (isosize > 0) message = g_strdup_printf (_("Please replace the disc with a writable DVD with at least %i MiB of free space."), (int) (isosize / 1048576)); else message = g_strdup (_("Please replace the disc with a writable DVD.")); } else { if (isosize > 0) message = g_strdup_printf (_("Please insert a writable DVD with at least %i MiB of free space."), (int) (isosize / 1048576)); else message = g_strdup (_("Please insert a writable DVD.")); } } else if (!insert) { if (isosize) message = g_strdup_printf (_("Please replace the disc with a writable CD or DVD with at least %i MiB of free space."), (int) (isosize / 1048576)); else message = g_strdup (_("Please replace the disc with a writable CD or DVD.")); } else { if (isosize) message = g_strdup_printf (_("Please insert a writable CD or DVD with at least %i MiB of free space."), (int) (isosize / 1048576)); else message = g_strdup (_("Please insert a writable CD or DVD.")); } } return message; } static BraseroBurnResult brasero_burn_dialog_insert_disc_cb (BraseroBurn *burn, BraseroDrive *drive, BraseroBurnError error, BraseroMedia type, BraseroBurnDialog *dialog) { gint result; gchar *drive_name; BraseroBurnDialogPrivate *priv; gchar *main_message = NULL, *secondary_message = NULL; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (drive) drive_name = brasero_drive_get_display_name (drive); else drive_name = NULL; if (error == BRASERO_BURN_WARNING_INSERT_AFTER_COPY) { secondary_message = g_strdup (_("An image of the disc has been created on your hard drive." "\nBurning will begin as soon as a writable disc is inserted.")); main_message = brasero_burn_dialog_get_media_type_string (burn, type, FALSE); } else if (error == BRASERO_BURN_WARNING_CHECKSUM) { secondary_message = g_strdup (_("A data integrity test will begin as soon as the disc is inserted.")); main_message = g_strdup (_("Please re-insert the disc in the CD/DVD burner.")); } else if (error == BRASERO_BURN_ERROR_DRIVE_BUSY) { /* Translators: %s is the name of a drive */ main_message = g_strdup_printf (_("\"%s\" is busy."), drive_name); secondary_message = g_strdup_printf ("%s.", _("Make sure another application is not using it")); } else if (error == BRASERO_BURN_ERROR_MEDIUM_NONE) { secondary_message = g_strdup_printf (_("There is no disc in \"%s\"."), drive_name); main_message = brasero_burn_dialog_get_media_type_string (burn, type, TRUE); } else if (error == BRASERO_BURN_ERROR_MEDIUM_INVALID) { secondary_message = g_strdup_printf (_("The disc in \"%s\" is not supported."), drive_name); main_message = brasero_burn_dialog_get_media_type_string (burn, type, TRUE); } else if (error == BRASERO_BURN_ERROR_MEDIUM_NOT_REWRITABLE) { secondary_message = g_strdup_printf (_("The disc in \"%s\" is not rewritable."), drive_name); main_message = brasero_burn_dialog_get_media_type_string (burn, type, FALSE); } else if (error == BRASERO_BURN_ERROR_MEDIUM_NO_DATA) { secondary_message = g_strdup_printf (_("The disc in \"%s\" is empty."), drive_name); main_message = brasero_burn_dialog_get_media_type_string (burn, type, FALSE); } else if (error == BRASERO_BURN_ERROR_MEDIUM_NOT_WRITABLE) { secondary_message = g_strdup_printf (_("The disc in \"%s\" is not writable."), drive_name); main_message = brasero_burn_dialog_get_media_type_string (burn, type, FALSE); } else if (error == BRASERO_BURN_ERROR_MEDIUM_SPACE) { secondary_message = g_strdup_printf (_("Not enough space available on the disc in \"%s\"."), drive_name); main_message = brasero_burn_dialog_get_media_type_string (burn, type, FALSE); } else if (error == BRASERO_BURN_ERROR_NONE) { main_message = brasero_burn_dialog_get_media_type_string (burn, type, TRUE); secondary_message = NULL; } else if (error == BRASERO_BURN_ERROR_MEDIUM_NEED_RELOADING) { secondary_message = g_strdup_printf (_("The disc in \"%s\" needs to be reloaded."), drive_name); main_message = g_strdup (_("Please eject the disc and reload it.")); } g_free (drive_name); result = brasero_burn_dialog_wait_for_insertion (dialog, drive, main_message, secondary_message, FALSE); g_free (main_message); g_free (secondary_message); if (result != GTK_RESPONSE_OK) return BRASERO_BURN_CANCEL; brasero_burn_dialog_update_media (dialog); brasero_burn_dialog_update_title (dialog, &priv->input); brasero_burn_dialog_update_info (dialog, &priv->input, (brasero_burn_session_get_flags (priv->session) & BRASERO_BURN_FLAG_DUMMY) != 0); return BRASERO_BURN_OK; } static BraseroBurnResult brasero_burn_dialog_image_error (BraseroBurn *burn, GError *error, gboolean is_temporary, BraseroBurnDialog *dialog) { gint result; gchar *path; gchar *string; GtkWidget *message; gboolean hide = FALSE; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) { gtk_widget_show (GTK_WIDGET (dialog)); hide = TRUE; } g_timer_stop (priv->total_time); string = g_strdup_printf ("%s. %s", is_temporary? _("A file could not be created at the location specified for temporary files"): _("The image could not be created at the specified location"), _("Do you want to specify another location for this session or retry with the current location?")); message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, string); g_free (string); if (error && error->code == BRASERO_BURN_ERROR_DISK_SPACE) gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s.\n%s.", error->message, _("You may want to free some space on the disc and retry")); else gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s.", error->message); gtk_dialog_add_buttons (GTK_DIALOG (message), _("_Keep Current Location"), GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("_Change Location"), GTK_RESPONSE_ACCEPT, NULL); result = gtk_dialog_run (GTK_DIALOG (message)); gtk_widget_destroy (message); if (hide) gtk_widget_hide (GTK_WIDGET (dialog)); if (result == GTK_RESPONSE_OK) { g_timer_continue (priv->total_time); return BRASERO_BURN_OK; } if (result != GTK_RESPONSE_ACCEPT) { g_timer_continue (priv->total_time); return BRASERO_BURN_CANCEL; } /* Show a GtkFileChooserDialog */ if (!is_temporary) { gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (message), TRUE); message = gtk_file_chooser_dialog_new (_("Location for Image File"), GTK_WINDOW (dialog), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); } else message = gtk_file_chooser_dialog_new (_("Location for Temporary Files"), GTK_WINDOW (dialog), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (message), TRUE); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (message), g_get_home_dir ()); result = gtk_dialog_run (GTK_DIALOG (message)); if (result != GTK_RESPONSE_OK) { gtk_widget_destroy (message); g_timer_continue (priv->total_time); return BRASERO_BURN_CANCEL; } path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (message)); gtk_widget_destroy (message); if (!is_temporary) { BraseroImageFormat format; gchar *image = NULL; gchar *toc = NULL; format = brasero_burn_session_get_output_format (priv->session); brasero_burn_session_get_output (priv->session, &image, &toc); if (toc) { gchar *name; name = g_path_get_basename (toc); g_free (toc); toc = g_build_filename (path, name, NULL); BRASERO_BURN_LOG ("New toc location %s", toc); } if (image) { gchar *name; name = g_path_get_basename (image); g_free (image); image = g_build_filename (path, name, NULL); BRASERO_BURN_LOG ("New image location %s", toc); } brasero_burn_session_set_image_output_full (priv->session, format, image, toc); } else brasero_burn_session_set_tmpdir (priv->session, path); g_free (path); g_timer_continue (priv->total_time); return BRASERO_BURN_OK; } static BraseroBurnResult brasero_burn_dialog_loss_warnings_cb (BraseroBurnDialog *dialog, const gchar *main_message, const gchar *secondary_message, const gchar *button_text, const gchar *button_icon, const gchar *second_button_text, const gchar *second_button_icon) { gint result; GtkWidget *button; GtkWidget *message; gboolean hide = FALSE; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) { gtk_widget_show (GTK_WIDGET (dialog)); hide = TRUE; } g_timer_stop (priv->total_time); message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, main_message); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s", secondary_message); if (second_button_text) { button = gtk_dialog_add_button (GTK_DIALOG (message), second_button_text, GTK_RESPONSE_YES); if (second_button_icon) gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_icon_name (second_button_icon, GTK_ICON_SIZE_BUTTON)); } button = gtk_dialog_add_button (GTK_DIALOG (message), _("_Replace Disc"), GTK_RESPONSE_ACCEPT); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON)); gtk_dialog_add_button (GTK_DIALOG (message), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); button = gtk_dialog_add_button (GTK_DIALOG (message), button_text, GTK_RESPONSE_OK); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_icon_name (button_icon, GTK_ICON_SIZE_BUTTON)); result = gtk_dialog_run (GTK_DIALOG (message)); gtk_widget_destroy (message); if (hide) gtk_widget_hide (GTK_WIDGET (dialog)); g_timer_continue (priv->total_time); if (result == GTK_RESPONSE_YES) return BRASERO_BURN_RETRY; if (result == GTK_RESPONSE_ACCEPT) return BRASERO_BURN_NEED_RELOAD; if (result != GTK_RESPONSE_OK) return BRASERO_BURN_CANCEL; return BRASERO_BURN_OK; } static BraseroBurnResult brasero_burn_dialog_data_loss_cb (BraseroBurn *burn, BraseroBurnDialog *dialog) { return brasero_burn_dialog_loss_warnings_cb (dialog, _("Do you really want to blank the current disc?"), _("The disc in the drive holds data."), /* Translators: Blank is a verb here */ _("_Blank Disc"), "media-optical-blank", NULL, NULL); } static BraseroBurnResult brasero_burn_dialog_previous_session_loss_cb (BraseroBurn *burn, BraseroBurnDialog *dialog) { gchar *secondary; BraseroBurnResult result; secondary = g_strdup_printf ("%s\n%s", _("If you import them you will be able to see and use them once the current selection of files is burned."), _("If you don't, they will be invisible (though still readable).")); result = brasero_burn_dialog_loss_warnings_cb (dialog, _("There are files already burned on this disc. Would you like to import them?"), secondary, _("_Import"), NULL, _("Only _Append"), NULL); g_free (secondary); return result; } static BraseroBurnResult brasero_burn_dialog_audio_to_appendable_cb (BraseroBurn *burn, BraseroBurnDialog *dialog) { gchar *secondary; BraseroBurnResult result; secondary = g_strdup_printf ("%s\n%s", _("CD-RW audio discs may not play correctly in older CD players and CD-Text won't be written."), _("Do you want to continue anyway?")); result = brasero_burn_dialog_loss_warnings_cb (dialog, _("Appending audio tracks to a CD is not advised."), secondary, _("_Continue"), "media-optical-burn", NULL, NULL); g_free (secondary); return result; } static BraseroBurnResult brasero_burn_dialog_rewritable_cb (BraseroBurn *burn, BraseroBurnDialog *dialog) { gchar *secondary; BraseroBurnResult result; secondary = g_strdup_printf ("%s\n%s", _("CD-RW audio discs may not play correctly in older CD players."), _("Do you want to continue anyway?")); result = brasero_burn_dialog_loss_warnings_cb (dialog, _("Recording audio tracks on a rewritable disc is not advised."), secondary, _("_Continue"), "media-optical-burn", NULL, NULL); g_free (secondary); return result; } static void brasero_burn_dialog_wait_for_ejection_cb (BraseroDrive *drive, BraseroMedium *medium, GtkDialog *message) { /* we might have a dialog waiting for the * insertion of a disc if so close it */ gtk_dialog_response (GTK_DIALOG (message), GTK_RESPONSE_OK); } static BraseroBurnResult brasero_burn_dialog_eject_failure_cb (BraseroBurn *burn, BraseroDrive *drive, BraseroBurnDialog *dialog) { gint result; gchar *name; gchar *string; gint removal_id; GtkWidget *message; gboolean hide = FALSE; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) { gtk_widget_show (GTK_WIDGET (dialog)); hide = TRUE; } g_timer_stop (priv->total_time); name = brasero_drive_get_display_name (drive); /* Translators: %s is the name of a drive */ string = g_strdup_printf (_("Please eject the disc from \"%s\" manually."), name); g_free (name); message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, string); g_free (string); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), _("The disc could not be ejected though it needs to be removed for the current operation to continue.")); gtk_dialog_add_button (GTK_DIALOG (message), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); /* connect to signals to be warned when media is removed */ removal_id = g_signal_connect_after (drive, "medium-removed", G_CALLBACK (brasero_burn_dialog_wait_for_ejection_cb), message); result = gtk_dialog_run (GTK_DIALOG (message)); g_signal_handler_disconnect (drive, removal_id); gtk_widget_destroy (message); if (hide) gtk_widget_hide (GTK_WIDGET (dialog)); g_timer_continue (priv->total_time); if (result == GTK_RESPONSE_ACCEPT) return BRASERO_BURN_OK; return BRASERO_BURN_CANCEL; } static BraseroBurnResult brasero_burn_dialog_continue_question (BraseroBurnDialog *dialog, const gchar *primary_message, const gchar *secondary_message, const gchar *button_message) { gint result; GtkWidget *button; GtkWidget *message; gboolean hide = FALSE; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) { gtk_widget_show (GTK_WIDGET (dialog)); hide = TRUE; } g_timer_stop (priv->total_time); message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, primary_message); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s", secondary_message); gtk_dialog_add_button (GTK_DIALOG (message), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); button = gtk_dialog_add_button (GTK_DIALOG (message), button_message, GTK_RESPONSE_OK); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_OK, GTK_ICON_SIZE_BUTTON)); result = gtk_dialog_run (GTK_DIALOG (message)); gtk_widget_destroy (message); if (hide) gtk_widget_hide (GTK_WIDGET (dialog)); g_timer_continue (priv->total_time); if (result != GTK_RESPONSE_OK) return BRASERO_BURN_CANCEL; return BRASERO_BURN_OK; } static BraseroBurnResult brasero_burn_dialog_blank_failure_cb (BraseroBurn *burn, BraseroBurnDialog *dialog) { return brasero_burn_dialog_continue_question (dialog, _("Do you want to replace the disc and continue?"), _("The currently inserted disc could not be blanked."), _("_Replace Disc")); } static BraseroBurnResult brasero_burn_dialog_disable_joliet_cb (BraseroBurn *burn, BraseroBurnDialog *dialog) { return brasero_burn_dialog_continue_question (dialog, _("Do you want to continue with full Windows compatibility disabled?"), _("Some files don't have a suitable name for a fully Windows-compatible CD."), _("C_ontinue")); } static void brasero_burn_dialog_update_title_writing_progress (BraseroBurnDialog *dialog, BraseroTrackType *input, BraseroMedia media, guint percent) { gchar *title = NULL; gchar *icon_name; guint remains; /* This is used only when actually writing to a disc */ if (media == BRASERO_MEDIUM_FILE) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Creating Image"), percent); else if (media & BRASERO_MEDIUM_DVD) { if (brasero_track_type_get_has_medium (input)) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Copying DVD"), percent); else title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Burning DVD"), percent); } else if (media & BRASERO_MEDIUM_CD) { if (brasero_track_type_get_has_medium (input)) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Copying CD"), percent); else title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Burning CD"), percent); } else { if (brasero_track_type_get_has_medium (input)) title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Copying Disc"), percent); else title = brasero_burn_dialog_create_dialog_title_for_action (dialog, _("Burning Disc"), percent); } gtk_window_set_title (GTK_WINDOW (dialog), title); g_free (title); /* also update the icon */ remains = percent % 5; if (remains > 3) percent += 5 - remains; else percent -= remains; if (percent < 0 || percent > 100) return; icon_name = g_strdup_printf ("brasero-disc-%02i", percent); gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name); g_free (icon_name); } static void brasero_burn_dialog_progress_changed_real (BraseroBurnDialog *dialog, gint64 written, gint64 isosize, gint64 rate, gdouble overall_progress, gdouble task_progress, glong remaining, BraseroMedia media) { gint mb_isosize = -1; gint mb_written = -1; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (written >= 0) mb_written = (gint) (written / 1048576); if (isosize > 0) mb_isosize = (gint) (isosize / 1048576); if (task_progress >= 0.0 && priv->is_writing) brasero_burn_dialog_update_title_writing_progress (dialog, &priv->input, media, (guint) (task_progress * 100.0)); brasero_burn_progress_set_status (BRASERO_BURN_PROGRESS (priv->progress), media, overall_progress, task_progress, remaining, mb_isosize, mb_written, rate); if (rate > 0 && priv->is_writing) priv->rates = g_slist_prepend (priv->rates, GINT_TO_POINTER ((gint) rate)); } static void brasero_burn_dialog_progress_changed_cb (BraseroBurn *burn, gdouble overall_progress, gdouble task_progress, glong remaining, BraseroBurnDialog *dialog) { BraseroMedia media = BRASERO_MEDIUM_NONE; BraseroBurnDialogPrivate *priv; goffset isosize = -1; goffset written = -1; guint64 rate = -1; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); brasero_burn_status (priv->burn, &media, &isosize, &written, &rate); brasero_burn_dialog_progress_changed_real (dialog, written, isosize, rate, overall_progress, task_progress, remaining, media); if ((priv->is_writing || priv->is_creating_image) && isosize > 0) priv->total_size = isosize; } static void brasero_burn_dialog_action_changed_real (BraseroBurnDialog *dialog, BraseroBurnAction action, const gchar *string) { BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); brasero_burn_progress_set_action (BRASERO_BURN_PROGRESS (priv->progress), action, string); } static void brasero_burn_dialog_action_changed_cb (BraseroBurn *burn, BraseroBurnAction action, BraseroBurnDialog *dialog) { BraseroBurnDialogPrivate *priv; gchar *string = NULL; gboolean is_writing; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); is_writing = (action == BRASERO_BURN_ACTION_RECORDING || action == BRASERO_BURN_ACTION_DRIVE_COPY || action == BRASERO_BURN_ACTION_RECORDING_CD_TEXT || action == BRASERO_BURN_ACTION_LEADIN || action == BRASERO_BURN_ACTION_LEADOUT || action == BRASERO_BURN_ACTION_FIXATING); if (action == BRASERO_BURN_ACTION_START_RECORDING || (priv->is_writing && !is_writing)) { BraseroMedia media = BRASERO_MEDIUM_NONE; brasero_burn_status (burn, &media, NULL, NULL, NULL); } priv->is_creating_image = (action == BRASERO_BURN_ACTION_CREATING_IMAGE); priv->is_writing = is_writing; brasero_burn_get_action_string (priv->burn, action, &string); brasero_burn_dialog_action_changed_real (dialog, action, string); g_free (string); } static gboolean brasero_burn_dialog_dummy_success_timeout (gpointer data) { GtkDialog *dialog = data; gtk_dialog_response (dialog, GTK_RESPONSE_OK); return FALSE; } static BraseroBurnResult brasero_burn_dialog_dummy_success_cb (BraseroBurn *burn, BraseroBurnDialog *dialog) { BraseroBurnDialogPrivate *priv; GtkResponseType answer; GtkWidget *message; GtkWidget *button; gboolean hide; gint id; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (!gtk_widget_get_mapped (GTK_WIDGET (dialog))) { gtk_widget_show (GTK_WIDGET (dialog)); hide = TRUE; } else hide = FALSE; g_timer_stop (priv->total_time); message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, _("The simulation was successful.")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), _("Real disc burning will take place in 10 seconds.")); button = gtk_dialog_add_button (GTK_DIALOG (message), _("Burn _Now"), GTK_RESPONSE_OK); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_icon_name ("media-optical-burn", GTK_ICON_SIZE_BUTTON)); id = g_timeout_add_seconds (10, brasero_burn_dialog_dummy_success_timeout, message); gtk_widget_show (GTK_WIDGET (dialog)); gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE); gtk_widget_show (GTK_WIDGET (message)); ca_gtk_play_for_widget (GTK_WIDGET (message), 0, CA_PROP_EVENT_ID, "complete-media-burn-test", CA_PROP_EVENT_DESCRIPTION, _("The simulation was successful."), NULL); answer = gtk_dialog_run (GTK_DIALOG (message)); gtk_widget_destroy (message); gtk_window_set_urgency_hint (GTK_WINDOW (dialog), FALSE); if (hide) gtk_widget_hide (GTK_WIDGET (dialog)); g_timer_continue (priv->total_time); if (answer == GTK_RESPONSE_OK) { if (priv->initial_icon) gtk_window_set_icon_name (GTK_WINDOW (dialog), priv->initial_icon); else gtk_window_set_icon_name (GTK_WINDOW (dialog), "brasero-00.png"); brasero_burn_dialog_update_info (dialog, &priv->input, FALSE); brasero_burn_dialog_update_title (dialog, &priv->input); if (id) g_source_remove (id); return BRASERO_BURN_OK; } if (id) g_source_remove (id); return BRASERO_BURN_CANCEL; } static void brasero_burn_dialog_activity_start (BraseroBurnDialog *dialog) { GdkCursor *cursor; GdkWindow *window; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); window = gtk_widget_get_window (GTK_WIDGET (dialog)); if (window) { cursor = gdk_cursor_new (GDK_WATCH); gdk_window_set_cursor (window, cursor); g_object_unref (cursor); } gtk_button_set_use_stock (GTK_BUTTON (priv->cancel), TRUE); gtk_button_set_label (GTK_BUTTON (priv->cancel), GTK_STOCK_CANCEL); gtk_window_set_urgency_hint (GTK_WINDOW (dialog), FALSE); g_signal_connect (priv->cancel, "clicked", G_CALLBACK (brasero_burn_dialog_cancel_clicked_cb), dialog); /* Reset or set the speed info */ g_object_set (priv->progress, "show-info", TRUE, NULL); brasero_burn_progress_set_status (BRASERO_BURN_PROGRESS (priv->progress), FALSE, 0.0, 0.0, -1, -1, -1, -1); } static void brasero_burn_dialog_activity_stop (BraseroBurnDialog *dialog, const gchar *message) { gchar *markup; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (dialog)), NULL); markup = g_strdup_printf ("%s", message); gtk_label_set_text (GTK_LABEL (priv->header), markup); gtk_label_set_use_markup (GTK_LABEL (priv->header), TRUE); g_free (markup); gtk_button_set_use_stock (GTK_BUTTON (priv->cancel), TRUE); gtk_button_set_label (GTK_BUTTON (priv->cancel), GTK_STOCK_CLOSE); g_signal_handlers_disconnect_by_func (priv->cancel, brasero_burn_dialog_cancel_clicked_cb, dialog); brasero_burn_progress_set_status (BRASERO_BURN_PROGRESS (priv->progress), FALSE, 1.0, 1.0, -1, -1, -1, -1); /* Restore title */ if (priv->initial_title) gtk_window_set_title (GTK_WINDOW (dialog), priv->initial_title); else brasero_burn_dialog_update_title (dialog, &priv->input); /* Restore icon */ if (priv->initial_icon) gtk_window_set_icon_name (GTK_WINDOW (dialog), priv->initial_icon); gtk_widget_show (GTK_WIDGET (dialog)); gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE); } static BraseroBurnResult brasero_burn_dialog_install_missing_cb (BraseroBurn *burn, BraseroPluginErrorType type, const gchar *detail, gpointer user_data) { BraseroBurnDialogPrivate *priv = BRASERO_BURN_DIALOG_PRIVATE (user_data); GCancellable *cancel; BraseroPK *package; GdkWindow *window; gboolean res; int xid = 0; gtk_widget_set_sensitive (GTK_WIDGET (user_data), FALSE); /* Get the xid */ window = gtk_widget_get_window (user_data); xid = gdk_x11_window_get_xid (window); package = brasero_pk_new (); cancel = g_cancellable_new (); priv->cancel_plugin = cancel; switch (type) { case BRASERO_PLUGIN_ERROR_MISSING_APP: res = brasero_pk_install_missing_app (package, detail, xid, cancel); break; case BRASERO_PLUGIN_ERROR_MISSING_LIBRARY: res = brasero_pk_install_missing_library (package, detail, xid, cancel); break; case BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN: res = brasero_pk_install_gstreamer_plugin (package, detail, xid, cancel); break; default: res = FALSE; break; } if (package) { g_object_unref (package); package = NULL; } gtk_widget_set_sensitive (GTK_WIDGET (user_data), TRUE); if (g_cancellable_is_cancelled (cancel)) { g_object_unref (cancel); return BRASERO_BURN_CANCEL; } priv->cancel_plugin = NULL; g_object_unref (cancel); if (!res) return BRASERO_BURN_ERR; return BRASERO_BURN_RETRY; } static BraseroBurnResult brasero_burn_dialog_setup_session (BraseroBurnDialog *dialog, GError **error) { BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); brasero_burn_session_start (priv->session); priv->burn = brasero_burn_new (); g_signal_connect (priv->burn, "install-missing", G_CALLBACK (brasero_burn_dialog_install_missing_cb), dialog); g_signal_connect (priv->burn, "insert-media", G_CALLBACK (brasero_burn_dialog_insert_disc_cb), dialog); g_signal_connect (priv->burn, "blank-failure", G_CALLBACK (brasero_burn_dialog_blank_failure_cb), dialog); g_signal_connect (priv->burn, "eject-failure", G_CALLBACK (brasero_burn_dialog_eject_failure_cb), dialog); g_signal_connect (priv->burn, "location-request", G_CALLBACK (brasero_burn_dialog_image_error), dialog); g_signal_connect (priv->burn, "warn-data-loss", G_CALLBACK (brasero_burn_dialog_data_loss_cb), dialog); g_signal_connect (priv->burn, "warn-previous-session-loss", G_CALLBACK (brasero_burn_dialog_previous_session_loss_cb), dialog); g_signal_connect (priv->burn, "warn-audio-to-appendable", G_CALLBACK (brasero_burn_dialog_audio_to_appendable_cb), dialog); g_signal_connect (priv->burn, "warn-rewritable", G_CALLBACK (brasero_burn_dialog_rewritable_cb), dialog); g_signal_connect (priv->burn, "disable-joliet", G_CALLBACK (brasero_burn_dialog_disable_joliet_cb), dialog); g_signal_connect (priv->burn, "progress-changed", G_CALLBACK (brasero_burn_dialog_progress_changed_cb), dialog); g_signal_connect (priv->burn, "action-changed", G_CALLBACK (brasero_burn_dialog_action_changed_cb), dialog); g_signal_connect (priv->burn, "dummy-success", G_CALLBACK (brasero_burn_dialog_dummy_success_cb), dialog); brasero_burn_progress_set_status (BRASERO_BURN_PROGRESS (priv->progress), FALSE, 0.0, -1.0, -1, -1, -1, -1); brasero_burn_progress_set_action (BRASERO_BURN_PROGRESS (priv->progress), BRASERO_BURN_ACTION_NONE, NULL); g_timer_continue (priv->total_time); return BRASERO_BURN_OK; } static void brasero_burn_dialog_save_log (BraseroBurnDialog *dialog) { GError *error; gchar *contents; gchar *path = NULL; GtkWidget *chooser; GtkResponseType answer; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); chooser = gtk_file_chooser_dialog_new (_("Save Current Session"), GTK_WINDOW (dialog), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_window_set_icon_name (GTK_WINDOW (chooser), gtk_window_get_icon_name (GTK_WINDOW (dialog))); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), g_get_home_dir ()); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (chooser), "brasero-session.log"); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (chooser), TRUE); gtk_widget_show (chooser); answer = gtk_dialog_run (GTK_DIALOG (chooser)); if (answer != GTK_RESPONSE_OK) { gtk_widget_destroy (chooser); return; } path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); gtk_widget_destroy (chooser); if (!path) return; if (path && *path == '\0') { g_free (path); return; } error = NULL; if (!g_file_get_contents (brasero_burn_session_get_log_path (priv->session), &contents, NULL, &error)) { g_warning ("Error while saving log file: %s\n", error? error->message:"none"); g_error_free (error); g_free (path); return; } g_file_set_contents (path, contents, -1, NULL); g_free (contents); g_free (path); } static void brasero_burn_dialog_notify_error (BraseroBurnDialog *dialog, GError *error) { gchar *secondary; GtkWidget *button; GtkWidget *message; GtkResponseType response; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); /* Restore title */ if (priv->initial_title) gtk_window_set_title (GTK_WINDOW (dialog), priv->initial_title); /* Restore icon */ if (priv->initial_icon) gtk_window_set_icon_name (GTK_WINDOW (dialog), priv->initial_icon); if (error) { secondary = g_strdup (error->message); g_error_free (error); } else secondary = g_strdup (_("An unknown error occurred.")); if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) gtk_widget_show (GTK_WIDGET (dialog)); message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, _("Error while burning.")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s", secondary); g_free (secondary); button = gtk_dialog_add_button (GTK_DIALOG (message), _("_Save Log"), GTK_RESPONSE_OK); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_BUTTON)); gtk_dialog_add_button (GTK_DIALOG (message), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); brasero_burn_dialog_notify_daemon (dialog, _("Error while burning.")); response = gtk_dialog_run (GTK_DIALOG (message)); while (response == GTK_RESPONSE_OK) { brasero_burn_dialog_save_log (dialog); response = gtk_dialog_run (GTK_DIALOG (message)); } gtk_widget_destroy (message); } static gchar * brasero_burn_dialog_get_success_message (BraseroBurnDialog *dialog) { BraseroBurnDialogPrivate *priv; BraseroDrive *drive; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); drive = brasero_burn_session_get_burner (priv->session); if (brasero_track_type_get_has_stream (&priv->input)) { if (!brasero_drive_is_fake (drive)) { if (BRASERO_STREAM_FORMAT_HAS_VIDEO (brasero_track_type_get_stream_format (&priv->input))) { if (priv->media & BRASERO_MEDIUM_DVD) return g_strdup (_("Video DVD successfully burned")); return g_strdup (_("(S)VCD successfully burned")); } else return g_strdup (_("Audio CD successfully burned")); } return g_strdup (_("Image successfully created")); } else if (brasero_track_type_get_has_medium (&priv->input)) { if (!brasero_drive_is_fake (drive)) { if (priv->media & BRASERO_MEDIUM_DVD) return g_strdup (_("DVD successfully copied")); else return g_strdup (_("CD successfully copied")); } else { if (priv->media & BRASERO_MEDIUM_DVD) return g_strdup (_("Image of DVD successfully created")); else return g_strdup (_("Image of CD successfully created")); } } else if (brasero_track_type_get_has_image (&priv->input)) { if (!brasero_drive_is_fake (drive)) { if (priv->media & BRASERO_MEDIUM_DVD) return g_strdup (_("Image successfully burned to DVD")); else return g_strdup (_("Image successfully burned to CD")); } } else if (brasero_track_type_get_has_data (&priv->input)) { if (!brasero_drive_is_fake (drive)) { if (priv->media & BRASERO_MEDIUM_DVD) return g_strdup (_("Data DVD successfully burned")); else return g_strdup (_("Data CD successfully burned")); } return g_strdup (_("Image successfully created")); } return NULL; } static void brasero_burn_dialog_update_session_info (BraseroBurnDialog *dialog) { gint64 rate; gchar *primary = NULL; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); primary = brasero_burn_dialog_get_success_message (dialog); brasero_burn_dialog_activity_stop (dialog, primary); g_free (primary); /* show total required time and average speed */ rate = 0; if (priv->rates) { int num = 0; GSList *iter; for (iter = priv->rates; iter; iter = iter->next) { rate += GPOINTER_TO_INT (iter->data); num ++; } rate /= num; } brasero_burn_progress_display_session_info (BRASERO_BURN_PROGRESS (priv->progress), g_timer_elapsed (priv->total_time, NULL), rate, priv->media, priv->total_size); } static gboolean brasero_burn_dialog_notify_copy_finished (BraseroBurnDialog *dialog, GError *error) { gulong added_id; BraseroDrive *drive; GtkWidget *message; gchar *main_message; GtkResponseType response; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); brasero_burn_dialog_update_session_info (dialog); if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) gtk_widget_show (GTK_WIDGET (dialog)); main_message = g_strdup_printf (_("Copy #%i has been burned successfully."), priv->num_copies ++); message = brasero_burn_dialog_create_message (dialog, GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, main_message); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s", _("Another copy will start as soon as you insert a new writable disc. If you do not want to burn another copy, press \"Cancel\".")); /* connect to signals to be warned when media is inserted */ drive = brasero_burn_session_get_burner (priv->session); added_id = g_signal_connect_after (drive, "medium-added", G_CALLBACK (brasero_burn_dialog_wait_for_insertion_cb), message); gtk_widget_show (GTK_WIDGET (message)); ca_gtk_play_for_widget (GTK_WIDGET (message), 0, CA_PROP_EVENT_ID, "complete-media-burn", CA_PROP_EVENT_DESCRIPTION, main_message, NULL); brasero_burn_dialog_notify_daemon (dialog, main_message); g_free (main_message); response = gtk_dialog_run (GTK_DIALOG (message)); g_signal_handler_disconnect (drive, added_id); gtk_widget_destroy (message); return (response == GTK_RESPONSE_OK); } static gboolean brasero_burn_dialog_success_run (BraseroBurnDialog *dialog) { gint answer; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); answer = gtk_dialog_run (GTK_DIALOG (dialog)); if (answer == GTK_RESPONSE_CLOSE) { GtkWidget *window; window = brasero_session_edit_cover (priv->session, GTK_WIDGET (dialog)); /* This strange hack is a way to workaround #568358. * At one point we'll need to hide the dialog which means it * will anwer with a GTK_RESPONSE_NONE */ while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_NONE) gtk_widget_show (GTK_WIDGET (dialog)); gtk_widget_destroy (window); return FALSE; } return (answer == GTK_RESPONSE_OK); } static gboolean brasero_burn_dialog_notify_success (BraseroBurnDialog *dialog) { gboolean res; gchar *primary = NULL; BraseroBurnDialogPrivate *priv; GtkWidget *create_cover = NULL; GtkWidget *make_another = NULL; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); brasero_burn_dialog_update_session_info (dialog); /* Don't show the "Make _More Copies" button if: * - we wrote to a file * - we wrote a merged session * - we were not already asked for a series of copy */ if (!priv->num_copies && !brasero_burn_session_is_dest_file (priv->session) && !(brasero_burn_session_get_flags (priv->session) & BRASERO_BURN_FLAG_MERGE)) { /* Useful button but it shouldn't be used for images */ make_another = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Make _More Copies"), GTK_RESPONSE_OK); } if (brasero_track_type_get_has_stream (&priv->input) || (brasero_track_type_get_has_medium (&priv->input) && (brasero_track_type_get_medium_type (&priv->input) & BRASERO_MEDIUM_HAS_AUDIO))) { /* since we succeed offer the possibility to create cover if that's an audio disc */ create_cover = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Create Co_ver"), GTK_RESPONSE_CLOSE); } primary = brasero_burn_dialog_get_success_message (dialog); gtk_widget_show(GTK_WIDGET(dialog)); ca_gtk_play_for_widget(GTK_WIDGET(dialog), 0, CA_PROP_EVENT_ID, "complete-media-burn", CA_PROP_EVENT_DESCRIPTION, primary, NULL); brasero_burn_dialog_notify_daemon (dialog, primary); g_free (primary); res = brasero_burn_dialog_success_run (dialog); if (make_another) gtk_widget_destroy (make_another); if (create_cover) gtk_widget_destroy (create_cover); return res; } static void brasero_burn_dialog_add_track_to_recent (BraseroTrack *track) { gchar *uri = NULL; GtkRecentManager *recent; BraseroImageFormat format; gchar *groups [] = { "brasero", NULL }; gchar *mimes [] = { "application/x-cd-image", "application/x-cue", "application/x-toc", "application/x-cdrdao-toc" }; GtkRecentData recent_data = { NULL, NULL, NULL, "brasero", "brasero -p %u", groups, FALSE }; if (!BRASERO_IS_TRACK_IMAGE (track)) return; format = brasero_track_image_get_format (BRASERO_TRACK_IMAGE (track)); if (format == BRASERO_IMAGE_FORMAT_NONE) return; /* Add it to recent file manager */ switch (format) { case BRASERO_IMAGE_FORMAT_BIN: recent_data.mime_type = mimes [0]; uri = brasero_track_image_get_source (BRASERO_TRACK_IMAGE (track), TRUE); break; case BRASERO_IMAGE_FORMAT_CUE: recent_data.mime_type = mimes [1]; uri = brasero_track_image_get_toc_source (BRASERO_TRACK_IMAGE (track), TRUE); break; case BRASERO_IMAGE_FORMAT_CLONE: recent_data.mime_type = mimes [2]; uri = brasero_track_image_get_toc_source (BRASERO_TRACK_IMAGE (track), TRUE); break; case BRASERO_IMAGE_FORMAT_CDRDAO: recent_data.mime_type = mimes [3]; uri = brasero_track_image_get_toc_source (BRASERO_TRACK_IMAGE (track), TRUE); break; default: break; } if (!uri) return; recent = gtk_recent_manager_get_default (); gtk_recent_manager_add_full (recent, uri, &recent_data); g_free (uri); } static gboolean brasero_burn_dialog_end_session (BraseroBurnDialog *dialog, BraseroBurnResult result, GError *error) { gboolean retry = FALSE; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); g_timer_stop (priv->total_time); if (result == BRASERO_BURN_CANCEL) { /* nothing to do */ } else if (error || result != BRASERO_BURN_OK) { brasero_burn_dialog_notify_error (dialog, error); } else if (priv->num_copies) { retry = brasero_burn_dialog_notify_copy_finished (dialog, error); if (!retry) brasero_burn_dialog_notify_success (dialog); } else { /* see if an image was created. If so, add it to GtkRecent. */ if (brasero_burn_session_is_dest_file (priv->session)) { GSList *tracks; tracks = brasero_burn_session_get_tracks (priv->session); for (; tracks; tracks = tracks->next) { BraseroTrack *track; track = tracks->data; brasero_burn_dialog_add_track_to_recent (track); } } retry = brasero_burn_dialog_notify_success (dialog); priv->num_copies = retry * 2; } if (priv->burn) { g_object_unref (priv->burn); priv->burn = NULL; } if (priv->rates) { g_slist_free (priv->rates); priv->rates = NULL; } return retry; } static BraseroBurnResult brasero_burn_dialog_record_spanned_session (BraseroBurnDialog *dialog, GError **error) { BraseroDrive *burner; BraseroTrackType *type; gchar *success_message; BraseroBurnResult result; BraseroBurnDialogPrivate *priv; gchar *secondary_message = NULL; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); burner = brasero_burn_session_get_burner (priv->session); /* Get the messages now as they can change */ type = brasero_track_type_new (); brasero_burn_session_get_input_type (priv->session, type); success_message = brasero_burn_dialog_get_success_message (dialog); if (brasero_track_type_get_has_data (type)) { secondary_message = g_strdup_printf ("%s.\n%s.", success_message, _("There are some files left to burn")); g_free (success_message); } else if (brasero_track_type_get_has_stream (type)) { if (BRASERO_STREAM_FORMAT_HAS_VIDEO (brasero_track_type_get_stream_format (type))) secondary_message = g_strdup_printf ("%s.\n%s.", success_message, _("There are some more videos left to burn")); else secondary_message = g_strdup_printf ("%s.\n%s.", success_message, _("There are some more songs left to burn")); g_free (success_message); } else secondary_message = success_message; brasero_track_type_free (type); do { gint res; result = brasero_burn_record (priv->burn, priv->session, error); if (result != BRASERO_BURN_OK) { g_free (secondary_message); return result; } /* See if we have more data to burn and ask for a new medium */ result = brasero_session_span_again (BRASERO_SESSION_SPAN (priv->session)); if (result == BRASERO_BURN_OK) break; res = brasero_burn_dialog_wait_for_insertion (dialog, burner, _("Please insert a writable CD or DVD."), secondary_message, TRUE); if (res != GTK_RESPONSE_OK) { g_free (secondary_message); return BRASERO_BURN_CANCEL; } result = brasero_session_span_next (BRASERO_SESSION_SPAN (priv->session)); while (result == BRASERO_BURN_ERR) { brasero_drive_eject (burner, FALSE, NULL); res = brasero_burn_dialog_wait_for_insertion (dialog, burner, _("Please insert a writable CD or DVD."), _("Not enough space available on the disc"), FALSE); if (res != GTK_RESPONSE_OK) { g_free (secondary_message); return BRASERO_BURN_CANCEL; } result = brasero_session_span_next (BRASERO_SESSION_SPAN (priv->session)); } } while (result == BRASERO_BURN_RETRY); g_free (secondary_message); brasero_session_span_stop (BRASERO_SESSION_SPAN (priv->session)); return result; } static BraseroBurnResult brasero_burn_dialog_record_session (BraseroBurnDialog *dialog) { gboolean retry; GError *error = NULL; BraseroBurnResult result; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); /* Update info */ brasero_burn_dialog_update_info (dialog, &priv->input, (brasero_burn_session_get_flags (priv->session) & BRASERO_BURN_FLAG_DUMMY) != 0); brasero_burn_dialog_update_title (dialog, &priv->input); /* Start the recording session */ brasero_burn_dialog_activity_start (dialog); result = brasero_burn_dialog_setup_session (dialog, &error); if (result != BRASERO_BURN_OK) return result; if (BRASERO_IS_SESSION_SPAN (priv->session)) result = brasero_burn_dialog_record_spanned_session (dialog, &error); else result = brasero_burn_record (priv->burn, priv->session, &error); retry = brasero_burn_dialog_end_session (dialog, result, error); if (result == BRASERO_BURN_RETRY) return result; if (retry) return BRASERO_BURN_RETRY; return BRASERO_BURN_OK; } static gboolean brasero_burn_dialog_wait_for_ready_state_cb (BraseroBurnDialog *dialog) { BraseroBurnDialogPrivate *priv; BraseroStatus *status; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); status = brasero_status_new (); brasero_burn_session_get_status (priv->session, status); if (brasero_status_get_result (status) == BRASERO_BURN_NOT_READY || brasero_status_get_result (status) == BRASERO_BURN_RUNNING) { gdouble progress; gchar *action; action = brasero_status_get_current_action (status); brasero_burn_dialog_action_changed_real (dialog, BRASERO_BURN_ACTION_GETTING_SIZE, action); g_free (action); progress = brasero_status_get_progress (status); brasero_burn_dialog_progress_changed_real (dialog, 0, 0, 0, progress, progress, -1.0, priv->media); g_object_unref (status); /* Continue */ return TRUE; } if (priv->loop) g_main_loop_quit (priv->loop); priv->wait_ready_state_id = 0; g_object_unref (status); return FALSE; } static gboolean brasero_burn_dialog_wait_for_ready_state (BraseroBurnDialog *dialog) { BraseroBurnDialogPrivate *priv; BraseroBurnResult result; BraseroStatus *status; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); status = brasero_status_new (); result = brasero_burn_session_get_status (priv->session, status); if (result == BRASERO_BURN_NOT_READY || result == BRASERO_BURN_RUNNING) { GMainLoop *loop; loop = g_main_loop_new (NULL, FALSE); priv->loop = loop; priv->wait_ready_state_id = g_timeout_add_seconds (1, (GSourceFunc) brasero_burn_dialog_wait_for_ready_state_cb, dialog); g_main_loop_run (loop); priv->loop = NULL; if (priv->wait_ready_state_id) { g_source_remove (priv->wait_ready_state_id); priv->wait_ready_state_id = 0; } g_main_loop_unref (loop); /* Get the final status */ result = brasero_burn_session_get_status (priv->session, status); } g_object_unref (status); return (result == BRASERO_BURN_OK); } static gboolean brasero_burn_dialog_run_real (BraseroBurnDialog *dialog, BraseroBurnSession *session) { BraseroBurnResult result; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); g_object_ref (session); priv->session = session; /* update what we should display */ brasero_burn_session_get_input_type (session, &priv->input); brasero_burn_dialog_update_media (dialog); /* show it early */ gtk_widget_show (GTK_WIDGET (dialog)); /* wait for ready state */ if (!brasero_burn_dialog_wait_for_ready_state (dialog)) return FALSE; /* disable autoconfiguration */ if (BRASERO_IS_SESSION_CFG (priv->session)) brasero_session_cfg_disable (BRASERO_SESSION_CFG (priv->session)); priv->total_time = g_timer_new (); g_timer_stop (priv->total_time); priv->initial_title = g_strdup (gtk_window_get_title (GTK_WINDOW (dialog))); priv->initial_icon = g_strdup (gtk_window_get_icon_name (GTK_WINDOW (dialog))); do { if (!gtk_widget_get_visible (GTK_WIDGET (dialog))) gtk_widget_show (GTK_WIDGET (dialog)); result = brasero_burn_dialog_record_session (dialog); } while (result == BRASERO_BURN_RETRY); if (priv->initial_title) { g_free (priv->initial_title); priv->initial_title = NULL; } if (priv->initial_icon) { g_free (priv->initial_icon); priv->initial_icon = NULL; } g_timer_destroy (priv->total_time); priv->total_time = NULL; priv->session = NULL; g_object_unref (session); /* re-enable autoconfiguration */ if (BRASERO_IS_SESSION_CFG (priv->session)) brasero_session_cfg_enable (BRASERO_SESSION_CFG (priv->session)); return (result == BRASERO_BURN_OK); } /** * brasero_burn_dialog_run_multi: * @dialog: a #BraseroBurnDialog * @session: a #BraseroBurnSession * * Start burning the contents of @session. Once a disc is burnt, a dialog * will be shown to the user and wait for a new insertion before starting to burn * again. * * Return value: a #gboolean. TRUE if the operation was successfully carried out, FALSE otherwise. **/ gboolean brasero_burn_dialog_run_multi (BraseroBurnDialog *dialog, BraseroBurnSession *session) { BraseroBurnResult result; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); priv->num_copies = 1; result = brasero_burn_dialog_run_real (dialog, session); return (result == BRASERO_BURN_OK); } /** * brasero_burn_dialog_run: * @dialog: a #BraseroBurnDialog * @session: a #BraseroBurnSession * * Start burning the contents of @session. * * Return value: a #gboolean. TRUE if the operation was successfully carried out, FALSE otherwise. **/ gboolean brasero_burn_dialog_run (BraseroBurnDialog *dialog, BraseroBurnSession *session) { BraseroBurnResult result; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); priv->num_copies = 0; result = brasero_burn_dialog_run_real (dialog, session); return (result == BRASERO_BURN_OK); } static gboolean brasero_burn_dialog_cancel_dialog (BraseroBurnDialog *toplevel) { gint result; GtkWidget *button; GtkWidget *message; message = brasero_burn_dialog_create_message (toplevel, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, _("Do you really want to quit?")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), _("Interrupting the process may make disc unusable.")); button = gtk_dialog_add_button (GTK_DIALOG (message), _("C_ontinue Burning"), GTK_RESPONSE_OK); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_OK, GTK_ICON_SIZE_BUTTON)); button = gtk_dialog_add_button (GTK_DIALOG (message), _("_Cancel Burning"), GTK_RESPONSE_CANCEL); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON)); result = gtk_dialog_run (GTK_DIALOG (message)); gtk_widget_destroy (message); return (result != GTK_RESPONSE_OK); } /** * brasero_burn_dialog_cancel: * @dialog: a #BraseroBurnDialog * @force_cancellation: a #gboolean * * Cancel the ongoing operation run by @dialog; if @force_cancellation is FALSE then it can * happen that the operation won't be cancelled if there is a risk to make a disc unusable. * * Return value: a #gboolean. TRUE if it was sucessfully cancelled, FALSE otherwise. **/ gboolean brasero_burn_dialog_cancel (BraseroBurnDialog *dialog, gboolean force_cancellation) { BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (dialog); if (priv->loop) { g_main_loop_quit (priv->loop); return TRUE; } if (!priv->burn) return TRUE; if (brasero_burn_cancel (priv->burn, (force_cancellation == TRUE)) == BRASERO_BURN_DANGEROUS) { if (!brasero_burn_dialog_cancel_dialog (dialog)) return FALSE; brasero_burn_cancel (priv->burn, FALSE); } return TRUE; } static void brasero_burn_dialog_cancel_clicked_cb (GtkWidget *button, BraseroBurnDialog *dialog) { /* a burning is ongoing cancel it */ brasero_burn_dialog_cancel (dialog, FALSE); } static void brasero_burn_dialog_init (BraseroBurnDialog * obj) { GtkWidget *box; GtkWidget *vbox; GtkWidget *alignment; BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (obj); gtk_window_set_default_size (GTK_WINDOW (obj), 500, 0); alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); gtk_widget_show (alignment); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 8, 6, 6); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (obj))), alignment, TRUE, TRUE, 0); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (alignment), vbox); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_widget_show (box); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 0); priv->header = gtk_label_new (NULL); gtk_widget_show (priv->header); gtk_misc_set_alignment (GTK_MISC (priv->header), 0.0, 0.5); gtk_misc_set_padding (GTK_MISC (priv->header), 0, 18); gtk_box_pack_start (GTK_BOX (box), priv->header, FALSE, TRUE, 0); priv->image = gtk_image_new (); gtk_misc_set_alignment (GTK_MISC (priv->image), 1.0, 0.5); gtk_widget_show (priv->image); gtk_box_pack_start (GTK_BOX (box), priv->image, TRUE, TRUE, 0); priv->progress = brasero_burn_progress_new (); gtk_widget_show (priv->progress); gtk_box_pack_start (GTK_BOX (vbox), priv->progress, FALSE, TRUE, 0); /* buttons */ priv->cancel = gtk_dialog_add_button (GTK_DIALOG (obj), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); } static void brasero_burn_dialog_finalize (GObject * object) { BraseroBurnDialogPrivate *priv; priv = BRASERO_BURN_DIALOG_PRIVATE (object); if (priv->wait_ready_state_id) { g_source_remove (priv->wait_ready_state_id); priv->wait_ready_state_id = 0; } if (priv->cancel_plugin) { g_cancellable_cancel (priv->cancel_plugin); priv->cancel_plugin = NULL; } if (priv->initial_title) { g_free (priv->initial_title); priv->initial_title = NULL; } if (priv->initial_icon) { g_free (priv->initial_icon); priv->initial_icon = NULL; } if (priv->burn) { brasero_burn_cancel (priv->burn, TRUE); g_object_unref (priv->burn); priv->burn = NULL; } if (priv->session) { g_object_unref (priv->session); priv->session = NULL; } if (priv->total_time) { g_timer_destroy (priv->total_time); priv->total_time = NULL; } if (priv->rates) { g_slist_free (priv->rates); priv->rates = NULL; } G_OBJECT_CLASS (brasero_burn_dialog_parent_class)->finalize (object); } static void brasero_burn_dialog_class_init (BraseroBurnDialogClass * klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (BraseroBurnDialogPrivate)); object_class->finalize = brasero_burn_dialog_finalize; } /** * brasero_burn_dialog_new: * * Creates a new #BraseroBurnDialog object * * Return value: a #GtkWidget. Unref when it is not needed anymore. **/ GtkWidget * brasero_burn_dialog_new (void) { BraseroBurnDialog *obj; obj = BRASERO_BURN_DIALOG (g_object_new (BRASERO_TYPE_BURN_DIALOG, NULL)); return GTK_WIDGET (obj); }