[brasero] Integrated previous changes so that now a data or an audio project can be written across several med
- From: Philippe Rouquier <philippr src gnome org>
- To: svn-commits-list gnome org
- Subject: [brasero] Integrated previous changes so that now a data or an audio project can be written across several med
- Date: Sun, 17 May 2009 12:25:57 -0400 (EDT)
commit 5f9ac14a6723049cfeca8a9ae314ca413d0e25f2
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date: Sat May 16 20:45:07 2009 +0200
Integrated previous changes so that now a data or an audio project can be written across several media
---
libbrasero-burn/brasero-burn-dialog.c | 231 ++++++++++++++-------
libbrasero-burn/brasero-burn-options.c | 49 ++++-
libbrasero-burn/brasero-data-project.c | 77 +++++++-
libbrasero-burn/brasero-data-project.h | 8 +-
libbrasero-burn/brasero-session-span.c | 328 ++++++++++++++++++++++++++++++
libbrasero-burn/brasero-session-span.h | 82 ++++++++
libbrasero-burn/brasero-session.c | 10 +-
libbrasero-burn/brasero-track-data-cfg.c | 34 +++
libbrasero-burn/brasero-track-data-cfg.h | 9 +
9 files changed, 742 insertions(+), 86 deletions(-)
diff --git a/libbrasero-burn/brasero-burn-dialog.c b/libbrasero-burn/brasero-burn-dialog.c
index 7ef6dfa..a81775c 100644
--- a/libbrasero-burn/brasero-burn-dialog.c
+++ b/libbrasero-burn/brasero-burn-dialog.c
@@ -397,6 +397,85 @@ brasero_burn_dialog_update_info (BraseroBurnDialog *dialog,
gtk_window_set_icon_name (GTK_WINDOW (dialog), "brasero");
}
+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)
+{
+ gint result;
+ gint added_id;
+ GtkWindow *window;
+ GtkWidget *message;
+ gboolean hide = FALSE;
+ BraseroBurnDialogPrivate *priv;
+
+ priv = BRASERO_BURN_DIALOG_PRIVATE (dialog);
+ window = GTK_WINDOW (dialog);
+
+ if (!GTK_WIDGET_VISIBLE (dialog)) {
+ gtk_widget_show (GTK_WIDGET (dialog));
+ hide = TRUE;
+ }
+
+ g_timer_stop (priv->total_time);
+
+ if (secondary_message) {
+ message = gtk_message_dialog_new (window,
+ GTK_DIALOG_DESTROY_WITH_PARENT|
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CANCEL,
+ "%s", main_message);
+
+ if (secondary_message)
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message),
+ "%s", secondary_message);
+ }
+ else {
+ gchar *string;
+
+ message = gtk_message_dialog_new_with_markup (window,
+ GTK_DIALOG_DESTROY_WITH_PARENT|
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CANCEL,
+ NULL);
+
+ string = g_strdup_printf ("<b><big>%s</big></b>", 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);
+
+ 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_start (priv->total_time);
+
+ return result;
+}
+
static gchar *
brasero_burn_dialog_get_media_type_string (BraseroBurn *burn,
BraseroMedia type,
@@ -478,16 +557,6 @@ brasero_burn_dialog_get_media_type_string (BraseroBurn *burn,
return message;
}
-static void
-brasero_burn_dialog_wait_for_insertion (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_insert_disc_cb (BraseroBurn *burn,
BraseroDrive *drive,
@@ -496,23 +565,12 @@ brasero_burn_dialog_insert_disc_cb (BraseroBurn *burn,
BraseroBurnDialog *dialog)
{
gint result;
- gint added_id;
gchar *drive_name;
- GtkWindow *window;
- GtkWidget *message;
- gboolean hide = FALSE;
BraseroBurnDialogPrivate *priv;
gchar *main_message = NULL, *secondary_message = NULL;
priv = BRASERO_BURN_DIALOG_PRIVATE (dialog);
- if (!GTK_WIDGET_VISIBLE (dialog)) {
- gtk_widget_show (GTK_WIDGET (dialog));
- hide = TRUE;
- }
-
- g_timer_stop (priv->total_time);
-
if (drive)
drive_name = brasero_drive_get_display_name (drive);
else
@@ -567,60 +625,15 @@ brasero_burn_dialog_insert_disc_cb (BraseroBurn *burn,
g_free (drive_name);
- window = GTK_WINDOW (dialog);
-
- if (secondary_message) {
- message = gtk_message_dialog_new (window,
- GTK_DIALOG_DESTROY_WITH_PARENT|
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CANCEL,
- "%s", main_message);
-
- if (secondary_message) {
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message),
- "%s", secondary_message);
- g_free (secondary_message);
- }
- }
- else {
- gchar *string;
-
- message = gtk_message_dialog_new_with_markup (window,
- GTK_DIALOG_DESTROY_WITH_PARENT|
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CANCEL,
- NULL);
-
- string = g_strdup_printf ("<b><big>%s</big></b>", main_message);
- gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (message), string);
- g_free (string);
- }
-
+ result = brasero_burn_dialog_wait_for_insertion (dialog, drive, main_message, secondary_message);
g_free (main_message);
+ g_free (secondary_message);
- /* 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),
- message);
-
- result = gtk_dialog_run (GTK_DIALOG (message));
-
- g_signal_handler_disconnect (drive, added_id);
- gtk_widget_destroy (message);
-
- /* see if we should update the infos */
+ /* update the infos */
brasero_burn_dialog_update_info (dialog,
&priv->input,
brasero_burn_session_get_dest_media (priv->session));
- if (hide)
- gtk_widget_hide (GTK_WIDGET (dialog));
-
- g_timer_start (priv->total_time);
-
if (result != GTK_RESPONSE_OK)
return BRASERO_BURN_CANCEL;
@@ -2042,6 +2055,76 @@ brasero_burn_dialog_end_session (BraseroBurnDialog *dialog,
}
static BraseroBurnResult
+brasero_burn_dialog_record_spanned_session (BraseroBurnDialog *dialog,
+ GError **error)
+{
+ BraseroDrive *burner;
+ BraseroTrackType *type;
+ BraseroBurnResult result;
+ BraseroBurnDialogPrivate *priv;
+ gchar *secondary_message = NULL;
+
+ priv = BRASERO_BURN_DIALOG_PRIVATE (dialog);
+ burner = brasero_burn_session_get_burner (priv->session);
+
+ type = brasero_track_type_new ();
+ if (brasero_track_type_get_has_data (type))
+ secondary_message = g_strdup (_("There are some files left to burn."));
+ 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 (_("There are some more videos left to burn."));
+ else
+ secondary_message = g_strdup (_("There are some more songs left to burn."));
+ }
+ 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) {
+ g_free (secondary_message);
+ return BRASERO_BURN_OK;
+ }
+
+ res = brasero_burn_dialog_wait_for_insertion (dialog,
+ burner,
+ _("Please insert a recordable CD or DVD."),
+ secondary_message);
+ 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) {
+ res = brasero_burn_dialog_wait_for_insertion (dialog,
+ burner,
+ _("Please insert a recordable CD or DVD."),
+ _("Not enough space available on the disc"));
+ 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);
+
+ brasero_session_span_stop (BRASERO_SESSION_SPAN (priv->session));
+ return result;
+}
+
+static BraseroBurnResult
brasero_burn_dialog_record_session (BraseroBurnDialog *dialog,
BraseroMedia media)
{
@@ -2060,14 +2143,16 @@ brasero_burn_dialog_record_session (BraseroBurnDialog *dialog,
if (result != BRASERO_BURN_OK)
return result;
- result = brasero_burn_record (priv->burn,
- priv->session,
- &error);
+ 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;
diff --git a/libbrasero-burn/brasero-burn-options.c b/libbrasero-burn/brasero-burn-options.c
index 4dc8456..9e1fcdf 100644
--- a/libbrasero-burn/brasero-burn-options.c
+++ b/libbrasero-burn/brasero-burn-options.c
@@ -43,6 +43,7 @@
#include "brasero-medium.h"
#include "brasero-medium-selection-priv.h"
+#include "burn-debug.h"
#include "brasero-session.h"
#include "brasero-session-helper.h"
#include "brasero-burn-options.h"
@@ -215,6 +216,21 @@ brasero_burn_options_message_response_cb (BraseroDiscMessage *message,
}
}
+static void
+brasero_burn_options_message_response_span_cb (BraseroDiscMessage *message,
+ GtkResponseType response,
+ BraseroBurnOptions *self)
+{
+ if (response == GTK_RESPONSE_OK) {
+ BraseroBurnOptionsPrivate *priv;
+
+ priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
+ brasero_session_span_start (BRASERO_SESSION_SPAN (priv->session));
+ if (brasero_session_span_next (BRASERO_SESSION_SPAN (priv->session)) == BRASERO_BURN_ERR)
+ BRASERO_BURN_LOG ("Spanning failed\n");
+ }
+}
+
#define BRASERO_BURN_OPTIONS_NO_MEDIUM_WARNING 1000
static void
@@ -321,11 +337,33 @@ brasero_burn_options_update_valid (BraseroBurnOptions *self)
}
if (valid == BRASERO_SESSION_INSUFFICIENT_SPACE) {
- brasero_notify_message_add (BRASERO_NOTIFY (priv->message_output),
- _("Please choose another CD or DVD or insert a new one."),
- _("The size of the project is too large for the disc even with the overburn option."),
- -1,
- BRASERO_NOTIFY_CONTEXT_SIZE);
+ /* Here there is an alternative: we may be able to span the data
+ * across multiple media. So try that. */
+ if (brasero_session_span_possible (BRASERO_SESSION_SPAN (priv->session)) == BRASERO_BURN_RETRY) {
+ GtkWidget *message;
+
+ message = brasero_notify_message_add (BRASERO_NOTIFY (priv->message_output),
+ _("Would you like to burn the selection of files across several media?"),
+ _("The size of the project is too large for the disc even with the overburn option."),
+ -1,
+ BRASERO_NOTIFY_CONTEXT_SIZE);
+ brasero_notify_button_add (BRASERO_NOTIFY (priv->message_output),
+ BRASERO_DISC_MESSAGE (message),
+ _("_Span File Selection"),
+ _("Burn the selection of files across several media"),
+ GTK_RESPONSE_OK);
+
+ g_signal_connect (message,
+ "response",
+ G_CALLBACK (brasero_burn_options_message_response_span_cb),
+ self);
+ }
+ else
+ brasero_notify_message_add (BRASERO_NOTIFY (priv->message_output),
+ _("Please choose another CD or DVD or insert a new one."),
+ _("The size of the project is too large for the disc even with the overburn option."),
+ -1,
+ BRASERO_NOTIFY_CONTEXT_SIZE);
}
else if (valid == BRASERO_SESSION_NO_OUTPUT) {
brasero_notify_message_add (BRASERO_NOTIFY (priv->message_output),
@@ -366,6 +404,7 @@ brasero_burn_options_update_valid (BraseroBurnOptions *self)
-1,
BRASERO_NOTIFY_CONTEXT_SIZE);
brasero_track_type_free (type);
+ gtk_window_resize (GTK_WINDOW (self), 10, 10);
return;
}
else if (valid == BRASERO_SESSION_NO_INPUT_MEDIUM) {
diff --git a/libbrasero-burn/brasero-data-project.c b/libbrasero-burn/brasero-data-project.c
index 9ef2254..a04fc9e 100644
--- a/libbrasero-burn/brasero-data-project.c
+++ b/libbrasero-burn/brasero-data-project.c
@@ -52,6 +52,7 @@
#include "brasero-misc.h"
#include "brasero-io.h"
+#include "burn-debug.h"
#include "brasero-track-data.h"
typedef struct _BraseroDataProjectPrivate BraseroDataProjectPrivate;
@@ -2494,7 +2495,7 @@ brasero_data_project_span_generate (BraseroDataProject *self,
graft->path = g_strconcat (graft->path, "/", NULL);
g_free (tmp);
}
-
+ graft->uri = brasero_data_project_node_to_uri (self, node);
grafts = g_slist_prepend (grafts, graft);
}
@@ -2642,8 +2643,10 @@ brasero_data_project_span (BraseroDataProject *self,
}
/* This means it's finished */
- if (!callback_data.grafts)
+ if (!callback_data.grafts) {
+ BRASERO_BURN_LOG ("No graft found for spanning");
return BRASERO_BURN_OK;
+ }
brasero_data_project_span_generate (self,
&callback_data,
@@ -2654,14 +2657,82 @@ brasero_data_project_span (BraseroDataProject *self,
brasero_track_data_add_fs (track, callback_data.fs_type);
brasero_track_data_set_file_num (track, callback_data.files_num);
+ BRASERO_BURN_LOG ("Set object (size %" G_GOFFSET_FORMAT ")", total_sectors);
+
g_slist_free (callback_data.grafts);
g_slist_free (callback_data.joliet_grafts);
return BRASERO_BURN_RETRY;
}
+BraseroBurnResult
+brasero_data_project_span_possible (BraseroDataProject *self,
+ goffset max_sectors)
+{
+ BraseroDataProjectPrivate *priv;
+ gboolean has_data_left = FALSE;
+ BraseroFileNode *children;
+
+ priv = BRASERO_DATA_PROJECT_PRIVATE (self);
+
+ /* When empty this is an error */
+ if (!g_hash_table_size (priv->grafts))
+ return BRASERO_BURN_ERR;
+
+ children = BRASERO_FILE_NODE_CHILDREN (priv->root);
+ while (children) {
+ goffset child_sectors;
+
+ if (g_slist_find (priv->spanned, children)) {
+ children = children->next;
+ continue;
+ }
+
+ if (children->is_file)
+ child_sectors = BRASERO_FILE_NODE_SECTORS (children);
+ else
+ child_sectors = brasero_data_project_get_folder_sectors (self, children);
+
+ /* Find at least one file or directory that can be spanned */
+ if (child_sectors < max_sectors)
+ return BRASERO_BURN_RETRY;
+
+ /* if the top directory is too large, continue */
+ children = children->next;
+ has_data_left = TRUE;
+ }
+
+ if (has_data_left)
+ return BRASERO_BURN_ERR;
+
+ return BRASERO_BURN_OK;
+}
+
+BraseroBurnResult
+brasero_data_project_span_again (BraseroDataProject *self)
+{
+ BraseroDataProjectPrivate *priv;
+ BraseroFileNode *children;
+
+ priv = BRASERO_DATA_PROJECT_PRIVATE (self);
+
+ /* When empty this is an error */
+ if (!g_hash_table_size (priv->grafts))
+ return BRASERO_BURN_ERR;
+
+ children = BRASERO_FILE_NODE_CHILDREN (priv->root);
+ while (children) {
+ if (!g_slist_find (priv->spanned, children))
+ return BRASERO_BURN_RETRY;
+
+ children = children->next;
+ }
+
+ return BRASERO_BURN_OK;
+}
+
void
-brasero_data_project_span_cancel (BraseroDataProject *self)
+brasero_data_project_span_stop (BraseroDataProject *self)
{
BraseroDataProjectPrivate *priv;
diff --git a/libbrasero-burn/brasero-data-project.h b/libbrasero-burn/brasero-data-project.h
index 4d81134..873d969 100644
--- a/libbrasero-burn/brasero-data-project.h
+++ b/libbrasero-burn/brasero-data-project.h
@@ -237,8 +237,14 @@ brasero_data_project_span (BraseroDataProject *project,
gboolean append_slash,
gboolean joliet,
BraseroTrackData *track);
+BraseroBurnResult
+brasero_data_project_span_again (BraseroDataProject *project);
+
+BraseroBurnResult
+brasero_data_project_span_possible (BraseroDataProject *project,
+ goffset max_sectors);
void
-brasero_data_project_span_cancel (BraseroDataProject *project);
+brasero_data_project_span_stop (BraseroDataProject *project);
G_END_DECLS
diff --git a/libbrasero-burn/brasero-session-span.c b/libbrasero-burn/brasero-session-span.c
new file mode 100644
index 0000000..02eeb29
--- /dev/null
+++ b/libbrasero-burn/brasero-session-span.c
@@ -0,0 +1,328 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Libbrasero-burn
+ * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app wanadoo fr>
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "brasero-drive.h"
+#include "brasero-medium.h"
+
+#include "burn-debug.h"
+#include "brasero-track.h"
+#include "brasero-track-data.h"
+#include "brasero-track-data-cfg.h"
+#include "brasero-session-span.h"
+
+typedef struct _BraseroSessionSpanPrivate BraseroSessionSpanPrivate;
+struct _BraseroSessionSpanPrivate
+{
+ GSList * track_list;
+ BraseroTrack * last_track;
+};
+
+#define BRASERO_SESSION_SPAN_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_SESSION_SPAN, BraseroSessionSpanPrivate))
+
+G_DEFINE_TYPE (BraseroSessionSpan, brasero_session_span, BRASERO_TYPE_BURN_SESSION);
+
+static goffset
+brasero_session_span_get_available_medium_space (BraseroSessionSpan *session)
+{
+ BraseroDrive *burner;
+ BraseroMedium *medium;
+ BraseroBurnFlag flags;
+ goffset available_blocks = 0;
+
+ /* Retrieve the size available for burning */
+ burner = brasero_burn_session_get_burner (BRASERO_BURN_SESSION (session));
+ if (!burner)
+ return 0;
+
+ medium = brasero_drive_get_medium (burner);
+ if (!medium)
+ return 0;
+
+ flags = brasero_burn_session_get_flags (BRASERO_BURN_SESSION (session));
+ if (flags & (BRASERO_BURN_FLAG_MERGE|BRASERO_BURN_FLAG_APPEND))
+ brasero_medium_get_free_space (medium, NULL, &available_blocks);
+ else if (brasero_burn_session_can_blank (BRASERO_BURN_SESSION (session)) == BRASERO_BURN_OK)
+ brasero_medium_get_capacity (medium, NULL, &available_blocks);
+ else
+ brasero_medium_get_free_space (medium, NULL, &available_blocks);
+
+ BRASERO_BURN_LOG ("Available space for spanning %" G_GINT64_FORMAT, available_blocks);
+ return available_blocks;
+}
+
+BraseroBurnResult
+brasero_session_span_again (BraseroSessionSpan *session)
+{
+ GSList *tracks;
+ BraseroTrack *track;
+ BraseroSessionSpanPrivate *priv;
+
+ g_return_val_if_fail (BRASERO_IS_SESSION_SPAN (session), BRASERO_BURN_ERR);
+
+ priv = BRASERO_SESSION_SPAN_PRIVATE (session);
+ if (!priv->track_list)
+ return BRASERO_BURN_ERR;
+
+ if (priv->last_track) {
+ tracks = g_slist_find (priv->track_list, priv->last_track);
+ if (!tracks->next) {
+ priv->track_list = NULL;
+ return BRASERO_BURN_OK;
+ }
+
+ return BRASERO_BURN_RETRY;
+ }
+
+ tracks = priv->track_list;
+ track = tracks->data;
+
+ if (BRASERO_IS_TRACK_DATA_CFG (track))
+ return brasero_track_data_cfg_span_again (BRASERO_TRACK_DATA_CFG (track));
+
+ return (tracks != NULL)? BRASERO_BURN_RETRY:BRASERO_BURN_OK;
+}
+
+BraseroBurnResult
+brasero_session_span_possible (BraseroSessionSpan *session)
+{
+ GSList *tracks;
+ BraseroTrack *track;
+ goffset max_sectors = 0;
+ goffset track_blocks = 0;
+ BraseroSessionSpanPrivate *priv;
+
+ g_return_val_if_fail (BRASERO_IS_SESSION_SPAN (session), BRASERO_BURN_ERR);
+
+ priv = BRASERO_SESSION_SPAN_PRIVATE (session);
+
+ max_sectors = brasero_session_span_get_available_medium_space (session);
+ if (max_sectors <= 0)
+ return BRASERO_BURN_ERR;
+
+ if (!priv->track_list)
+ tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (session));
+ else if (priv->last_track) {
+ tracks = g_slist_find (priv->track_list, priv->last_track);
+ if (!tracks->next) {
+ priv->track_list = NULL;
+ return BRASERO_BURN_OK;
+ }
+ tracks = tracks->next;
+ }
+ else
+ tracks = priv->track_list;
+
+ if (!tracks)
+ return BRASERO_BURN_ERR;
+
+ track = tracks->data;
+
+ if (BRASERO_IS_TRACK_DATA_CFG (track))
+ return brasero_track_data_cfg_span_possible (BRASERO_TRACK_DATA_CFG (track),
+ max_sectors);
+
+ /* This is the common case */
+ brasero_track_get_size (BRASERO_TRACK (track),
+ &track_blocks,
+ NULL);
+
+ if (track_blocks >= max_sectors)
+ return BRASERO_BURN_ERR;
+
+ return BRASERO_BURN_RETRY;
+}
+
+BraseroBurnResult
+brasero_session_span_start (BraseroSessionSpan *session)
+{
+ BraseroSessionSpanPrivate *priv;
+
+ g_return_val_if_fail (BRASERO_IS_SESSION_SPAN (session), BRASERO_BURN_ERR);
+
+ priv = BRASERO_SESSION_SPAN_PRIVATE (session);
+
+ priv->track_list = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (session));
+ if (priv->last_track) {
+ g_object_unref (priv->last_track);
+ priv->last_track = NULL;
+ }
+
+ return BRASERO_BURN_OK;
+}
+
+BraseroBurnResult
+brasero_session_span_next (BraseroSessionSpan *session)
+{
+ GSList *tracks;
+ gboolean pushed = FALSE;
+ goffset max_sectors = 0;
+ goffset total_sectors = 0;
+ BraseroSessionSpanPrivate *priv;
+
+ g_return_val_if_fail (BRASERO_IS_SESSION_SPAN (session), BRASERO_BURN_ERR);
+
+ priv = BRASERO_SESSION_SPAN_PRIVATE (session);
+
+ g_return_val_if_fail (priv->track_list != NULL, BRASERO_BURN_ERR);
+
+ max_sectors = brasero_session_span_get_available_medium_space (session);
+ if (max_sectors <= 0)
+ return BRASERO_BURN_ERR;
+
+ /* NOTE: should we pop here? */
+ if (priv->last_track) {
+ tracks = g_slist_find (priv->track_list, priv->last_track);
+ g_object_unref (priv->last_track);
+ priv->last_track = NULL;
+
+ if (!tracks->next) {
+ priv->track_list = NULL;
+ return BRASERO_BURN_OK;
+ }
+ tracks = tracks->next;
+ }
+ else
+ tracks = priv->track_list;
+
+ for (; tracks; tracks = tracks->next) {
+ BraseroTrack *track;
+ goffset track_blocks = 0;
+
+ track = tracks->data;
+
+ if (BRASERO_IS_TRACK_DATA_CFG (track)) {
+ BraseroTrackData *new_track;
+ BraseroBurnResult result;
+
+ /* NOTE: the case where track_blocks < max_blocks will
+ * be handled by brasero_track_data_cfg_span () */
+
+ /* This track type is the only one to be able to span itself */
+ new_track = brasero_track_data_new ();
+ result = brasero_track_data_cfg_span (BRASERO_TRACK_DATA_CFG (track),
+ max_sectors,
+ new_track);
+ if (result != BRASERO_BURN_RETRY) {
+ g_object_unref (new_track);
+ return result;
+ }
+
+ brasero_burn_session_push_tracks (BRASERO_BURN_SESSION (session));
+ brasero_burn_session_add_track (BRASERO_BURN_SESSION (session), BRASERO_TRACK (new_track));
+ break;
+ }
+
+ /* This is the common case */
+ brasero_track_get_size (BRASERO_TRACK (track),
+ &track_blocks,
+ NULL);
+
+ /* NOTE: keep the order of tracks */
+ if (track_blocks + total_sectors >= max_sectors) {
+ BRASERO_BURN_LOG ("Reached end of spanned size");
+ break;
+ }
+
+ total_sectors += track_blocks;
+
+ if (!pushed) {
+ BRASERO_BURN_LOG ("Pushing tracks for media spanning");
+ brasero_burn_session_push_tracks (BRASERO_BURN_SESSION (session));
+ pushed = TRUE;
+ }
+
+ BRASERO_BURN_LOG ("Adding tracks");
+ brasero_burn_session_add_track (BRASERO_BURN_SESSION (session), track);
+
+ if (priv->last_track)
+ g_object_unref (priv->last_track);
+
+ priv->last_track = g_object_ref (track);
+ }
+
+ /* If we pushed anything it means we succeeded */
+ return (pushed? BRASERO_BURN_RETRY:BRASERO_BURN_ERR);
+}
+
+void
+brasero_session_span_stop (BraseroSessionSpan *session)
+{
+ BraseroSessionSpanPrivate *priv;
+
+ g_return_if_fail (BRASERO_IS_SESSION_SPAN (session));
+
+ priv = BRASERO_SESSION_SPAN_PRIVATE (session);
+
+ if (priv->last_track) {
+ g_object_unref (priv->last_track);
+ priv->last_track = NULL;
+ }
+ else if (priv->track_list) {
+ BraseroTrack *track;
+
+ track = priv->track_list->data;
+ if (BRASERO_IS_TRACK_DATA_CFG (track))
+ brasero_track_data_cfg_span_stop (BRASERO_TRACK_DATA_CFG (track));
+ }
+
+ priv->track_list = NULL;
+}
+
+static void
+brasero_session_span_init (BraseroSessionSpan *object)
+{ }
+
+static void
+brasero_session_span_finalize (GObject *object)
+{
+ brasero_session_span_stop (BRASERO_SESSION_SPAN (object));
+ G_OBJECT_CLASS (brasero_session_span_parent_class)->finalize (object);
+}
+
+static void
+brasero_session_span_class_init (BraseroSessionSpanClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (BraseroSessionSpanPrivate));
+
+ object_class->finalize = brasero_session_span_finalize;
+}
+
+BraseroSessionSpan *
+brasero_session_span_new (void)
+{
+ return g_object_new (BRASERO_TYPE_SESSION_SPAN, NULL);
+}
+
diff --git a/libbrasero-burn/brasero-session-span.h b/libbrasero-burn/brasero-session-span.h
new file mode 100644
index 0000000..db34ea8
--- /dev/null
+++ b/libbrasero-burn/brasero-session-span.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Libbrasero-burn
+ * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app wanadoo fr>
+ *
+ * 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.
+ */
+
+#ifndef _BRASERO_SESSION_SPAN_H_
+#define _BRASERO_SESSION_SPAN_H_
+
+#include <glib-object.h>
+
+#include <brasero-session.h>
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_SESSION_SPAN (brasero_session_span_get_type ())
+#define BRASERO_SESSION_SPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_SESSION_SPAN, BraseroSessionSpan))
+#define BRASERO_SESSION_SPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_SESSION_SPAN, BraseroSessionSpanClass))
+#define BRASERO_IS_SESSION_SPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_SESSION_SPAN))
+#define BRASERO_IS_SESSION_SPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_SESSION_SPAN))
+#define BRASERO_SESSION_SPAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_SESSION_SPAN, BraseroSessionSpanClass))
+
+typedef struct _BraseroSessionSpanClass BraseroSessionSpanClass;
+typedef struct _BraseroSessionSpan BraseroSessionSpan;
+
+struct _BraseroSessionSpanClass
+{
+ BraseroBurnSessionClass parent_class;
+};
+
+struct _BraseroSessionSpan
+{
+ BraseroBurnSession parent_instance;
+};
+
+GType brasero_session_span_get_type (void) G_GNUC_CONST;
+
+BraseroSessionSpan *
+brasero_session_span_new (void);
+
+BraseroBurnResult
+brasero_session_span_again (BraseroSessionSpan *session);
+
+BraseroBurnResult
+brasero_session_span_possible (BraseroSessionSpan *session);
+
+BraseroBurnResult
+brasero_session_span_start (BraseroSessionSpan *session);
+
+BraseroBurnResult
+brasero_session_span_next (BraseroSessionSpan *session);
+
+void
+brasero_session_span_stop (BraseroSessionSpan *session);
+
+G_END_DECLS
+
+#endif /* _BRASERO_SESSION_SPAN_H_ */
diff --git a/libbrasero-burn/brasero-session.c b/libbrasero-burn/brasero-session.c
index a15c8b1..8958ee6 100644
--- a/libbrasero-burn/brasero-session.c
+++ b/libbrasero-burn/brasero-session.c
@@ -261,16 +261,18 @@ brasero_burn_session_add_track (BraseroBurnSession *self,
priv->tracks = g_slist_prepend (NULL, new_track);
brasero_burn_session_start_track_monitoring (self, new_track);
-
- g_signal_emit (self,
- brasero_burn_session_signals [INPUT_CHANGED_SIGNAL],
- 0);
}
else {
brasero_burn_session_start_track_monitoring (self, new_track);
priv->tracks = g_slist_append (priv->tracks, new_track);
}
+ /* Always emit the signal even when adding another BraseroTrackStream
+ * since the size has probably changed. */
+ g_signal_emit (self,
+ brasero_burn_session_signals [INPUT_CHANGED_SIGNAL],
+ 0);
+
return BRASERO_BURN_OK;
}
diff --git a/libbrasero-burn/brasero-track-data-cfg.c b/libbrasero-burn/brasero-track-data-cfg.c
index 7eeae09..979e712 100644
--- a/libbrasero-burn/brasero-track-data-cfg.c
+++ b/libbrasero-burn/brasero-track-data-cfg.c
@@ -2327,6 +2327,40 @@ brasero_track_data_cfg_span (BraseroTrackDataCfg *track,
return BRASERO_BURN_RETRY;
}
+BraseroBurnResult
+brasero_track_data_cfg_span_again (BraseroTrackDataCfg *track)
+{
+ BraseroTrackDataCfgPrivate *priv;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+ return brasero_data_project_span_again (BRASERO_DATA_PROJECT (priv->tree));
+}
+
+BraseroBurnResult
+brasero_track_data_cfg_span_possible (BraseroTrackDataCfg *track,
+ goffset sectors)
+{
+ BraseroTrackDataCfgPrivate *priv;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+ if (priv->loading
+ || brasero_data_vfs_is_active (BRASERO_DATA_VFS (priv->tree))
+ || brasero_data_session_get_loaded_medium (BRASERO_DATA_SESSION (priv->tree)) != NULL)
+ return BRASERO_BURN_NOT_READY;
+
+ return brasero_data_project_span_possible (BRASERO_DATA_PROJECT (priv->tree),
+ sectors);
+}
+
+void
+brasero_track_data_cfg_span_stop (BraseroTrackDataCfg *track)
+{
+ BraseroTrackDataCfgPrivate *priv;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+ brasero_data_project_span_stop (BRASERO_DATA_PROJECT (priv->tree));
+}
+
static void
brasero_track_data_cfg_init (BraseroTrackDataCfg *object)
{
diff --git a/libbrasero-burn/brasero-track-data-cfg.h b/libbrasero-burn/brasero-track-data-cfg.h
index fc74ecb..018116e 100644
--- a/libbrasero-burn/brasero-track-data-cfg.h
+++ b/libbrasero-burn/brasero-track-data-cfg.h
@@ -156,6 +156,15 @@ BraseroBurnResult
brasero_track_data_cfg_span (BraseroTrackDataCfg *track,
goffset sectors,
BraseroTrackData *new_track);
+BraseroBurnResult
+brasero_track_data_cfg_span_again (BraseroTrackDataCfg *track);
+
+BraseroBurnResult
+brasero_track_data_cfg_span_possible (BraseroTrackDataCfg *track,
+ goffset sectors);
+
+void
+brasero_track_data_cfg_span_stop (BraseroTrackDataCfg *track);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]