[brasero] Ported audio project to use the same GtkTreeModel backend as video project



commit e1e0d03b35bd8ebb5834e0613c7fc47e5d879a75
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date:   Sun Jun 14 21:19:12 2009 +0200

    Ported audio project to use the same GtkTreeModel backend as video project

 libbrasero-burn/brasero-error.h            |    1 +
 libbrasero-burn/brasero-tags.h             |    1 +
 libbrasero-burn/brasero-track-stream-cfg.c |  121 ++
 libbrasero-burn/brasero-track-stream.c     |   13 +-
 libbrasero-burn/brasero-track-stream.h     |   12 +-
 src/brasero-audio-disc.c                   | 2937 ++++------------------------
 src/brasero-data-disc.c                    |    3 +
 src/brasero-disc.c                         |   12 +-
 src/brasero-disc.h                         |    5 +-
 src/brasero-project.c                      |   26 +-
 src/brasero-song-properties.h              |    1 +
 src/brasero-video-disc.c                   |   36 +-
 src/brasero-video-tree-model.c             |  522 +++++-
 src/brasero-video-tree-model.h             |   12 +-
 14 files changed, 1061 insertions(+), 2641 deletions(-)
---
diff --git a/libbrasero-burn/brasero-error.h b/libbrasero-burn/brasero-error.h
index f067e88..b862f11 100644
--- a/libbrasero-burn/brasero-error.h
+++ b/libbrasero-burn/brasero-error.h
@@ -53,6 +53,7 @@ typedef enum {
 
 	BRASERO_BURN_ERROR_FILE_INVALID,
 	BRASERO_BURN_ERROR_FILE_FOLDER,
+	BRASERO_BURN_ERROR_FILE_PLAYLIST,
 	BRASERO_BURN_ERROR_FILE_NOT_FOUND,
 	BRASERO_BURN_ERROR_FILE_NOT_LOCAL,
 
diff --git a/libbrasero-burn/brasero-tags.h b/libbrasero-burn/brasero-tags.h
index 874ff74..7e4df3e 100644
--- a/libbrasero-burn/brasero-tags.h
+++ b/libbrasero-burn/brasero-tags.h
@@ -56,6 +56,7 @@ G_BEGIN_DECLS
 #define BRASERO_TRACK_STREAM_COMPOSER_TAG		"track::stream::info::composer"
 #define BRASERO_TRACK_STREAM_ARTIST_TAG			"track::stream::info::artist"
 #define BRASERO_TRACK_STREAM_THUMBNAIL_TAG		"track::stream::snapshot"
+#define BRASERO_TRACK_STREAM_MIME_TAG			"track::stream::mime"
 
 /**
  * Int
diff --git a/libbrasero-burn/brasero-track-stream-cfg.c b/libbrasero-burn/brasero-track-stream-cfg.c
index 75588e9..5788216 100644
--- a/libbrasero-burn/brasero-track-stream-cfg.c
+++ b/libbrasero-burn/brasero-track-stream-cfg.c
@@ -35,6 +35,7 @@
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 #include <glib-object.h>
+#include <gio/gio.h>
 
 #include "brasero-misc.h"
 
@@ -47,6 +48,8 @@ struct _BraseroTrackStreamCfgPrivate
 {
 	BraseroIOJobBase *load_uri;
 
+	GFileMonitor *monitor;
+
 	GError *error;
 
 	guint loading:1;
@@ -56,6 +59,41 @@ struct _BraseroTrackStreamCfgPrivate
 
 G_DEFINE_TYPE (BraseroTrackStreamCfg, brasero_track_stream_cfg, BRASERO_TYPE_TRACK_STREAM);
 
+static void
+brasero_track_stream_cfg_file_changed (GFileMonitor *monitor,
+								GFile *file,
+								GFile *other_file,
+								GFileMonitorEvent event,
+								BraseroTrackStream *track)
+{
+	BraseroTrackStreamCfgPrivate *priv;
+	gchar *name;
+
+	priv = BRASERO_TRACK_STREAM_CFG_PRIVATE (track);
+
+        switch (event) {
+ /*               case G_FILE_MONITOR_EVENT_CHANGED:
+                        return;
+*/
+                case G_FILE_MONITOR_EVENT_DELETED:
+                        g_object_unref (priv->monitor);
+                        priv->monitor = NULL;
+
+			name = g_file_get_basename (file);
+			priv->error = g_error_new (BRASERO_BURN_ERROR,
+								  BRASERO_BURN_ERROR_FILE_NOT_FOUND,
+								  /* Translators: %s is the name of the file that has just been deleted */
+								  _("\"%s\" was removed from the file system."),
+								 name);
+			g_free (name);
+                        break;
+
+                default:
+                        return;
+        }
+
+        brasero_track_changed (BRASERO_TRACK (track));
+}
 
 static void
 brasero_track_stream_cfg_results_cb (GObject *obj,
@@ -65,6 +103,7 @@ brasero_track_stream_cfg_results_cb (GObject *obj,
 				     gpointer user_data)
 {
 	guint64 len;
+	GFile *file;
 	GObject *snapshot;
 	BraseroTrackStreamCfgPrivate *priv;
 
@@ -89,6 +128,20 @@ brasero_track_stream_cfg_results_cb (GObject *obj,
 		return;
 	}
 
+	if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR
+	&&  (!strcmp (g_file_info_get_content_type (info), "audio/x-scpls")
+	||   !strcmp (g_file_info_get_content_type (info), "audio/x-ms-asx")
+	||   !strcmp (g_file_info_get_content_type (info), "audio/x-mp3-playlist")
+	||   !strcmp (g_file_info_get_content_type (info), "audio/x-mpegurl"))) {
+		/* This error is special as it can be recovered from */
+		priv->error = g_error_new (BRASERO_BURN_ERROR,
+					   BRASERO_BURN_ERROR_FILE_PLAYLIST,
+					   _("Playlists cannot be added to video or audio discs"));
+
+		brasero_track_changed (BRASERO_TRACK (obj));
+		return;
+	}
+
 	if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR
 	|| (!g_file_info_get_attribute_boolean (info, BRASERO_IO_HAS_VIDEO)
 	&&  !g_file_info_get_attribute_boolean (info, BRASERO_IO_HAS_AUDIO))) {
@@ -144,6 +197,37 @@ brasero_track_stream_cfg_results_cb (GObject *obj,
 				       value);
 	}
 
+	if (g_file_info_get_content_type (info)) {
+		const gchar *icon_string = "text-x-preview";
+		GtkIconTheme *theme;
+		GIcon *icon;
+
+		theme = gtk_icon_theme_get_default ();
+
+		/* NOTE: implemented in glib 2.15.6 (not for windows though) */
+		icon = g_content_type_get_icon (g_file_info_get_content_type (info));
+		if (G_IS_THEMED_ICON (icon)) {
+			const gchar * const *names = NULL;
+
+			names = g_themed_icon_get_names (G_THEMED_ICON (icon));
+			if (names) {
+				gint i;
+
+				for (i = 0; names [i]; i++) {
+					if (gtk_icon_theme_has_icon (theme, names [i])) {
+						icon_string = names [i];
+						break;
+					}
+				}
+			}
+		}
+
+		brasero_track_tag_add_string (BRASERO_TRACK (obj),
+					      BRASERO_TRACK_STREAM_MIME_TAG,
+					      icon_string);
+		g_object_unref (icon);
+	}
+
 	/* Get the song info */
 	if (g_file_info_get_attribute_string (info, BRASERO_IO_TITLE))
 		brasero_track_tag_add_string (BRASERO_TRACK (obj),
@@ -162,6 +246,19 @@ brasero_track_stream_cfg_results_cb (GObject *obj,
 					   BRASERO_TRACK_STREAM_ISRC_TAG,
 					   g_file_info_get_attribute_int32 (info, BRASERO_IO_ISRC));
 
+	/* Start monitoring it */
+	file = g_file_new_for_uri (uri);
+	priv->monitor = g_file_monitor_file (file,
+	                                     G_FILE_MONITOR_NONE,
+	                                     NULL,
+	                                     NULL);
+	g_object_unref (file);
+
+	g_signal_connect (priv->monitor,
+	                  "changed",
+	                  G_CALLBACK (brasero_track_stream_cfg_file_changed),
+	                  obj);
+
 	brasero_track_changed (BRASERO_TRACK (obj));
 }
 
@@ -196,12 +293,24 @@ brasero_track_stream_cfg_get_info (BraseroTrackStreamCfg *track)
 				  BRASERO_IO_INFO_METADATA_MISSING_CODEC|
 				  BRASERO_IO_INFO_METADATA_THUMBNAIL,
 				  track);
+	g_free (uri);
 }
 
 static BraseroBurnResult
 brasero_track_stream_cfg_set_source (BraseroTrackStream *track,
 				     const gchar *uri)
 {
+	BraseroTrackStreamCfgPrivate *priv;
+
+	priv = BRASERO_TRACK_STREAM_CFG_PRIVATE (track);
+	if (priv->monitor) {
+		g_object_unref (priv->monitor);
+		priv->monitor = NULL;
+	}
+
+	if (priv->load_uri)
+		brasero_io_cancel_by_base (priv->load_uri);
+
 	if (BRASERO_TRACK_STREAM_CLASS (brasero_track_stream_cfg_parent_class)->set_source)
 		BRASERO_TRACK_STREAM_CLASS (brasero_track_stream_cfg_parent_class)->set_source (track, uri);
 
@@ -248,6 +357,18 @@ brasero_track_stream_cfg_finalize (GObject *object)
 	BraseroTrackStreamCfgPrivate *priv;
 
 	priv = BRASERO_TRACK_STREAM_CFG_PRIVATE (object);
+
+	if (priv->load_uri) {
+		brasero_io_cancel_by_base (priv->load_uri);
+		g_free (priv->load_uri);
+		priv->load_uri = NULL;
+	}
+
+	if (priv->monitor) {
+		g_object_unref (priv->monitor);
+		priv->monitor = NULL;
+	}
+
 	if (priv->error) {
 		g_error_free (priv->error);
 		priv->error = NULL;
diff --git a/libbrasero-burn/brasero-track-stream.c b/libbrasero-burn/brasero-track-stream.c
index 4e3238d..cc1e900 100644
--- a/libbrasero-burn/brasero-track-stream.c
+++ b/libbrasero-burn/brasero-track-stream.c
@@ -43,6 +43,7 @@
 typedef struct _BraseroTrackStreamPrivate BraseroTrackStreamPrivate;
 struct _BraseroTrackStreamPrivate
 {
+        GFileMonitor *monitor;
 	gchar *uri;
 
 	BraseroStreamFormat format;
@@ -142,9 +143,9 @@ brasero_track_stream_set_format (BraseroTrackStream *track,
 
 static BraseroBurnResult
 brasero_track_stream_set_boundaries_real (BraseroTrackStream *track,
-					  guint64 start,
-					  guint64 end,
-					  guint64 gap)
+					  gint64 start,
+					  gint64 end,
+					  gint64 gap)
 {
 	BraseroTrackStreamPrivate *priv;
 
@@ -164,9 +165,9 @@ brasero_track_stream_set_boundaries_real (BraseroTrackStream *track,
 
 BraseroBurnResult
 brasero_track_stream_set_boundaries (BraseroTrackStream *track,
-				     guint64 start,
-				     guint64 end,
-				     guint64 gap)
+				     gint64 start,
+				     gint64 end,
+				     gint64 gap)
 {
 	BraseroTrackStreamClass *klass;
 	BraseroBurnResult res;
diff --git a/libbrasero-burn/brasero-track-stream.h b/libbrasero-burn/brasero-track-stream.h
index e588737..e6e867c 100644
--- a/libbrasero-burn/brasero-track-stream.h
+++ b/libbrasero-burn/brasero-track-stream.h
@@ -60,9 +60,9 @@ struct _BraseroTrackStreamClass
 							 BraseroStreamFormat format);
 
 	BraseroBurnResult       (*set_boundaries)       (BraseroTrackStream *track,
-							 guint64 start,
-							 guint64 end,
-							 guint64 gap);
+							 gint64 start,
+							 gint64 end,
+							 gint64 gap);
 };
 
 struct _BraseroTrackStream
@@ -85,9 +85,9 @@ brasero_track_stream_set_format (BraseroTrackStream *track,
 
 BraseroBurnResult
 brasero_track_stream_set_boundaries (BraseroTrackStream *track,
-				     guint64 start,
-				     guint64 end,
-				     guint64 gap);
+				     gint64 start,
+				     gint64 end,
+				     gint64 gap);
 
 gchar *
 brasero_track_stream_get_source (BraseroTrackStream *track,
diff --git a/src/brasero-audio-disc.c b/src/brasero-audio-disc.c
index 68577a2..c4ef3e7 100644
--- a/src/brasero-audio-disc.c
+++ b/src/brasero-audio-disc.c
@@ -50,37 +50,13 @@
 #include "brasero-song-properties.h"
 #include "brasero-io.h"
 #include "brasero-split-dialog.h"
+#include "brasero-track-stream-cfg.h"
 #include "brasero-session-cfg.h"
-
+#include "brasero-video-tree-model.h"
 #include "brasero-tags.h"
 
 #include "eggtreemultidnd.h"
 
-#ifdef BUILD_INOTIFY
-
-#include "sys/inotify.h"
-
-#endif
-
-static void brasero_audio_disc_class_init (BraseroAudioDiscClass *klass);
-static void brasero_audio_disc_init (BraseroAudioDisc *sp);
-static void brasero_audio_disc_finalize (GObject *object);
-static void brasero_audio_disc_iface_disc_init (BraseroDiscIface *iface);
-
-static void brasero_audio_disc_get_property (GObject * object,
-					     guint prop_id,
-					     GValue * value,
-					     GParamSpec * pspec);
-static void brasero_audio_disc_set_property (GObject * object,
-					     guint prop_id,
-					     const GValue * value,
-					     GParamSpec * spec);
-
-static BraseroDiscResult
-brasero_audio_disc_get_status (BraseroDisc *disc,
-			       gint *remaining,
-			       gchar **current_task);
-
 static BraseroDiscResult
 brasero_audio_disc_get_track (BraseroDisc *disc,
 			      BraseroDiscTrack *track);
@@ -97,10 +73,7 @@ brasero_audio_disc_add_uri (BraseroDisc *disc,
 			    const char *uri);
 static void
 brasero_audio_disc_delete_selected (BraseroDisc *disc);
-static void
-brasero_audio_disc_clear (BraseroDisc *disc);
-static void
-brasero_audio_disc_reset (BraseroDisc *disc);
+
 
 static guint
 brasero_audio_disc_add_ui (BraseroDisc *disc,
@@ -128,58 +101,6 @@ brasero_audio_disc_display_editing_started_cb (GtkCellRenderer *renderer,
 static void
 brasero_audio_disc_display_editing_canceled_cb (GtkCellRenderer *renderer,
 						 BraseroAudioDisc *disc);
-static void
-brasero_audio_disc_drag_data_received_cb (GtkTreeView *tree,
-					  GdkDragContext *drag_context,
-					  gint x,
-					  gint y,
-					  GtkSelectionData *selection_data,
-					  guint info,
-					  guint time,
-					  BraseroAudioDisc *disc);
-static gboolean
-brasero_audio_disc_drag_drop_cb (GtkWidget *widget,
-				 GdkDragContext*drag_context,
-				 gint x,
-				 gint y,
-				 guint time,
-				 BraseroAudioDisc *disc);
-static gboolean
-brasero_audio_disc_drag_motion_cb (GtkWidget *tree,
-				   GdkDragContext *drag_context,
-				   gint x,
-				   gint y,
-				   guint time,
-				   BraseroAudioDisc *disc);
-static void
-brasero_audio_disc_drag_leave_cb (GtkWidget *tree,
-				  GdkDragContext *drag_context,
-				  guint time,
-				  BraseroAudioDisc *disc);
-
-static void
-brasero_audio_disc_drag_begin_cb (GtkWidget *widget,
-				  GdkDragContext *drag_context,
-				  BraseroAudioDisc *disc);
-static void
-brasero_audio_disc_drag_end_cb (GtkWidget *tree,
-			        GdkDragContext *drag_context,
-			        BraseroAudioDisc *disc);
-
-static void
-brasero_audio_disc_row_deleted_cb (GtkTreeModel *model,
-				   GtkTreePath *arg1,
-				   BraseroAudioDisc *disc);
-static void
-brasero_audio_disc_row_inserted_cb (GtkTreeModel *model,
-				    GtkTreePath *arg1,
-				    GtkTreeIter *arg2,
-				    BraseroAudioDisc *disc);
-static void
-brasero_audio_disc_row_changed_cb (GtkTreeModel *model,
-				   GtkTreePath *path,
-				   GtkTreeIter *iter,
-				   BraseroAudioDisc *disc);
 
 static void
 brasero_audio_disc_edit_information_cb (GtkAction *action,
@@ -193,9 +114,6 @@ brasero_audio_disc_delete_activated_cb (GtkAction *action,
 static void
 brasero_audio_disc_paste_activated_cb (GtkAction *action,
 				       BraseroAudioDisc *disc);
-static void
-brasero_audio_disc_decrease_activity_counter (BraseroAudioDisc *disc);
-
 static gboolean
 brasero_audio_disc_get_selected_uri (BraseroDisc *disc,
 				     gchar **uri);
@@ -212,30 +130,8 @@ brasero_audio_disc_split_cb (GtkAction *action, BraseroAudioDisc *disc);
 static void
 brasero_audio_disc_selection_changed (GtkTreeSelection *selection, BraseroAudioDisc *disc);
 
-#ifdef BUILD_INOTIFY
-
-typedef struct {
-	gchar *uri;
-	guint32 cookie;
-	gint id;
-} BraseroInotifyMovedData;
-
-static gboolean
-brasero_audio_disc_inotify_monitor_cb (GIOChannel *channel,
-				       GIOCondition condition,
-				       BraseroAudioDisc *disc);
-static void
-brasero_audio_disc_start_monitoring (BraseroAudioDisc *disc,
-				     const char *uri);
-static void
-brasero_audio_disc_cancel_monitoring (BraseroAudioDisc *disc,
-				      const char *uri);
-#endif
-
 struct _BraseroAudioDiscPrivate {
-	BraseroIOJobBase *attr_changed;
 	BraseroIOJobBase *add_dir;
-	BraseroIOJobBase *add_uri;
 	BraseroIOJobBase *add_playlist;
 
 	GtkWidget *notebook;
@@ -246,24 +142,8 @@ struct _BraseroAudioDiscPrivate {
 
 	GtkTreePath *selected_path;
 
-#ifdef BUILD_INOTIFY
-
-	BraseroIOJobBase *reload_uri;
-
-	int notify_id;
-	GIOChannel *notify;
-	GHashTable *monitored;
-
-	GSList *moved_list;
-
-#endif
-
-	gint64 sectors;
-
        	GdkDragContext *drag_context;
 
-	gint activity_counter;
-
 	/* only used at start time when loading a project */
 	guint loading;
 
@@ -272,29 +152,6 @@ struct _BraseroAudioDiscPrivate {
 	guint reject_files:1;
 };
 
-enum {
-	TRACK_NUM_COL,
-	ICON_COL,
-	NAME_COL,
-	SIZE_COL,
-	ARTIST_COL,
-	URI_COL,
-	START_COL,
-	END_COL,
-	LENGTH_COL,
-	COMPOSER_COL,
-	ISRC_COL,
-	BACKGROUND_COL,
-	SONG_COL,
-	EDITABLE_COL,
-	LENGTH_SET_COL, /* if start/end were set through scanning or not */
-	TITLE_SET_COL,
-	ARTIST_SET_COL,
-	COMPOSER_SET_COL,
-	ISRC_SET_COL,
-	NB_COL
-};
-
 static GtkActionEntry entries[] = {
 	{"ContextualMenu", NULL, N_("Menu")},
 	{"OpenSong", GTK_STOCK_OPEN, NULL, NULL, N_("Open the selected files"),
@@ -368,77 +225,23 @@ enum {
 /* 1 sec = 75 sectors, len is in nanosecond */
 #define BRASERO_SECTORS_TO_TIME(sectors)	(gint64) (sectors * GST_SECOND / 75)
 #define COL_KEY "column_key"
-#define COL_KEY_SET "column_key_set"
-
-GType
-brasero_audio_disc_get_type()
-{
-	static GType type = 0;
-
-	if(type == 0) {
-		static const GTypeInfo our_info = {
-			sizeof (BraseroAudioDiscClass),
-			NULL,
-			NULL,
-			(GClassInitFunc)brasero_audio_disc_class_init,
-			NULL,
-			NULL,
-			sizeof (BraseroAudioDisc),
-			0,
-			(GInstanceInitFunc) brasero_audio_disc_init,
-		};
-
-		static const GInterfaceInfo disc_info =
-		{
-			(GInterfaceInitFunc) brasero_audio_disc_iface_disc_init,
-			NULL,
-			NULL
-		};
-
-		type = g_type_register_static(GTK_TYPE_VBOX, 
-					      "BraseroAudioDisc",
-					      &our_info,
-					      0);
-
-		g_type_add_interface_static (type,
-					     BRASERO_TYPE_DISC,
-					     &disc_info);
-	}
-
-	return type;
-}
 
-static void
-brasero_audio_disc_class_init (BraseroAudioDiscClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
-	parent_class = g_type_class_peek_parent (klass);
-	object_class->finalize = brasero_audio_disc_finalize;
-	object_class->set_property = brasero_audio_disc_set_property;
-	object_class->get_property = brasero_audio_disc_get_property;
+static void brasero_audio_disc_iface_disc_init (BraseroDiscIface *iface);
 
-	g_object_class_install_property (object_class,
-					 PROP_REJECT_FILE,
-					 g_param_spec_boolean
-					 ("reject-file",
-					  "Whether it accepts files",
-					  "Whether it accepts files",
-					  FALSE,
-					  G_PARAM_READWRITE));
-}
+G_DEFINE_TYPE_WITH_CODE (BraseroAudioDisc,
+			 brasero_audio_disc,
+			 GTK_TYPE_VBOX,
+			 G_IMPLEMENT_INTERFACE (BRASERO_TYPE_DISC,
+					        brasero_audio_disc_iface_disc_init));
 
 static void
 brasero_audio_disc_iface_disc_init (BraseroDiscIface *iface)
 {
 	iface->add_uri = brasero_audio_disc_add_uri;
 	iface->delete_selected = brasero_audio_disc_delete_selected;
-	iface->clear = brasero_audio_disc_clear;
-	iface->reset = brasero_audio_disc_reset;
 	iface->get_track = brasero_audio_disc_get_track;
 	iface->set_session_contents = brasero_audio_disc_set_session_contents;
 	iface->load_track = brasero_audio_disc_load_track;
-	iface->get_status = brasero_audio_disc_get_status;
 	iface->get_selected_uri = brasero_audio_disc_get_selected_uri;
 	iface->get_boundaries = brasero_audio_disc_get_boundaries;
 	iface->add_ui = brasero_audio_disc_add_ui;
@@ -542,18 +345,14 @@ brasero_audio_disc_selection_function (GtkTreeSelection *selection,
 				       gboolean is_selected,
 				       gpointer NULL_data)
 {
-	GtkTreeIter iter;
-	gboolean is_song = FALSE;
-
-	gtk_tree_model_get_iter (model, &iter, treepath);
-	gtk_tree_model_get (model, &iter,
-			    SONG_COL, &is_song,
-			    -1);
+	BraseroTrack *track;
 
-	if (is_song)
+	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
+/*	if (track)
 		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    EDITABLE_COL, (is_selected == FALSE),
+				    BRASERO_VIDEO_TREE_MODEL_EDITABLE, (is_selected == FALSE),
 				    -1);
+*/
 	return TRUE;
 }
 
@@ -563,7 +362,6 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 	GtkTreeSelection *selection;
 	GtkTreeViewColumn *column;
 	GtkCellRenderer *renderer;
-	GtkTreeModel *model;
 	GtkWidget *scroll;
 
 	obj->priv = g_new0 (BraseroAudioDiscPrivate, 1);
@@ -600,48 +398,10 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 	gtk_tree_selection_set_select_function (selection, brasero_audio_disc_selection_function, NULL, NULL);
 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (obj->priv->tree), TRUE);
 
-	model = (GtkTreeModel*) gtk_list_store_new (NB_COL,
-						    G_TYPE_STRING,
-						    G_TYPE_STRING,
-						    G_TYPE_STRING,
-						    G_TYPE_STRING,
-						    G_TYPE_STRING,
-						    G_TYPE_STRING,
-						    G_TYPE_INT64,
-						    G_TYPE_INT64,
-						    G_TYPE_INT64, 
-						    G_TYPE_STRING,
-						    G_TYPE_INT,
-						    G_TYPE_STRING,
-						    G_TYPE_BOOLEAN,
-						    G_TYPE_BOOLEAN,
-						    G_TYPE_BOOLEAN,
-						    G_TYPE_BOOLEAN,
-						    G_TYPE_BOOLEAN,
-						    G_TYPE_BOOLEAN,
-						    G_TYPE_BOOLEAN);
-
-	g_signal_connect (G_OBJECT (model),
-			  "row-deleted",
-			  G_CALLBACK (brasero_audio_disc_row_deleted_cb),
-			  obj);
-	g_signal_connect (G_OBJECT (model),
-			  "row-inserted",
-			  G_CALLBACK (brasero_audio_disc_row_inserted_cb),
-			  obj);
-	g_signal_connect (G_OBJECT (model),
-			  "row-changed",
-			  G_CALLBACK (brasero_audio_disc_row_changed_cb),
-			  obj);
-
-	gtk_tree_view_set_model (GTK_TREE_VIEW (obj->priv->tree),
-				 GTK_TREE_MODEL (model));
-	g_object_unref (model);
-
 	/* Track num column */
 	renderer = gtk_cell_renderer_text_new ();
 	column = gtk_tree_view_column_new_with_attributes (_("Track"), renderer,
-							   "text", TRACK_NUM_COL,
+							   "text", BRASERO_VIDEO_TREE_MODEL_INDEX,
 							   NULL);
 	gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree), column);
 	gtk_tree_view_column_set_resizable (column, FALSE);
@@ -654,11 +414,10 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 	renderer = gtk_cell_renderer_pixbuf_new ();
 	gtk_tree_view_column_pack_start (column, renderer, FALSE);
 	gtk_tree_view_column_add_attribute (column, renderer,
-					    "icon-name", ICON_COL);
+					    "icon-name", BRASERO_VIDEO_TREE_MODEL_ICON_NAME);
 
 	renderer = gtk_cell_renderer_text_new ();
-	g_object_set_data (G_OBJECT (renderer), COL_KEY, GINT_TO_POINTER (NAME_COL));
-	g_object_set_data (G_OBJECT (renderer), COL_KEY_SET, GINT_TO_POINTER (TITLE_SET_COL));
+	g_object_set_data (G_OBJECT (renderer), COL_KEY, BRASERO_TRACK_STREAM_TITLE_TAG);
 	g_object_set (G_OBJECT (renderer),
 		      "mode", GTK_CELL_RENDERER_MODE_EDITABLE,
 		      "ellipsize-set", TRUE,
@@ -674,11 +433,11 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 
 	gtk_tree_view_column_pack_end (column, renderer, TRUE);
 	gtk_tree_view_column_add_attribute (column, renderer,
-					    "markup", NAME_COL);
-	gtk_tree_view_column_add_attribute (column, renderer,
+					    "markup", BRASERO_VIDEO_TREE_MODEL_NAME);
+/*	gtk_tree_view_column_add_attribute (column, renderer,
 					    "background", BACKGROUND_COL);
-	gtk_tree_view_column_add_attribute (column, renderer,
-					    "editable", EDITABLE_COL);
+*/	gtk_tree_view_column_add_attribute (column, renderer,
+					    "editable", BRASERO_VIDEO_TREE_MODEL_EDITABLE);
 	gtk_tree_view_column_set_title (column, _("Title"));
 	g_object_set (G_OBJECT (column),
 		      "expand", TRUE,
@@ -691,8 +450,7 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 					   column);
 
 	renderer = gtk_cell_renderer_text_new ();
-	g_object_set_data (G_OBJECT (renderer), COL_KEY, GINT_TO_POINTER (ARTIST_COL));
-	g_object_set_data (G_OBJECT (renderer), COL_KEY_SET, GINT_TO_POINTER (ARTIST_SET_COL));
+	g_object_set_data (G_OBJECT (renderer), COL_KEY, BRASERO_TRACK_STREAM_ARTIST_TAG);
 	g_object_set (G_OBJECT (renderer),
 		      /* "editable", TRUE, disable this for the time being it doesn't play well with DND and double click */
 		      /* "mode", GTK_CELL_RENDERER_MODE_EDITABLE,*/
@@ -707,7 +465,7 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 	g_signal_connect (G_OBJECT (renderer), "editing-canceled",
 			  G_CALLBACK (brasero_audio_disc_display_editing_canceled_cb), obj);
 	column = gtk_tree_view_column_new_with_attributes (_("Artist"), renderer,
-							   "text", ARTIST_COL,
+							   "text", BRASERO_VIDEO_TREE_MODEL_ARTIST,
 							   NULL);
 	gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
 				     column);
@@ -716,8 +474,8 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 
 	renderer = gtk_cell_renderer_text_new ();
 	column = gtk_tree_view_column_new_with_attributes (_("Length"), renderer,
-							   "text", SIZE_COL,
-							   "background", BACKGROUND_COL,
+							   "text", BRASERO_VIDEO_TREE_MODEL_SIZE,
+							  /* "background", BACKGROUND_COL, */
 							   NULL);
 	gtk_tree_view_append_column (GTK_TREE_VIEW (obj->priv->tree),
 				     column);
@@ -744,7 +502,7 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 					      GDK_ACTION_COPY|
 					      GDK_ACTION_MOVE);
 
-	g_signal_connect (G_OBJECT (obj->priv->tree),
+/*	g_signal_connect (G_OBJECT (obj->priv->tree),
 			  "drag-data-received",
 			  G_CALLBACK (brasero_audio_disc_drag_data_received_cb),
 			  obj);
@@ -769,75 +527,21 @@ brasero_audio_disc_init (BraseroAudioDisc *obj)
 			  "drag_end",
 			  G_CALLBACK (brasero_audio_disc_drag_end_cb),
 			  obj);
-
+*/
 	gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (obj->priv->tree),
 						GDK_BUTTON1_MASK,
 						ntables_source,
 						nb_targets_source,
 						GDK_ACTION_COPY |
 						GDK_ACTION_MOVE);
-
-#ifdef BUILD_INOTIFY
-	int fd;
-
-	fd = inotify_init ();
-	if (fd != -1) {
-		obj->priv->notify = g_io_channel_unix_new (fd);
-
-		g_io_channel_set_encoding (obj->priv->notify, NULL, NULL);
-		g_io_channel_set_close_on_unref (obj->priv->notify, TRUE);
-		obj->priv->notify_id = g_io_add_watch (obj->priv->notify,
-						       G_IO_IN | G_IO_HUP | G_IO_PRI,
-						       (GIOFunc) brasero_audio_disc_inotify_monitor_cb,
-						       obj);
-		g_io_channel_unref (obj->priv->notify);
-	}
-	else
-		g_warning ("Failed to open /dev/inotify: %s\n",
-			   g_strerror (errno));
-#endif
 }
 
 static void
 brasero_audio_disc_reset_real (BraseroAudioDisc *disc)
 {
-	brasero_io_cancel_by_base (disc->priv->attr_changed);
 	brasero_io_cancel_by_base (disc->priv->add_dir);
-	brasero_io_cancel_by_base (disc->priv->add_uri);
 	brasero_io_cancel_by_base (disc->priv->add_playlist);
 
-#ifdef BUILD_INOTIFY
-
-	GSList *iter;
-
-	/* we remove all the moved events waiting in the list */
-	for (iter = disc->priv->moved_list; iter; iter = iter->next) {
-		BraseroInotifyMovedData *data;
-
-		data = iter->data;
-		g_source_remove (data->id);
-		g_free (data->uri);
-		g_free (data);
-	}
-	g_slist_free (disc->priv->moved_list);
-	disc->priv->moved_list = NULL;
-
-	/* destroy monitoring hash */
-	if (disc->priv->monitored) {
-		g_hash_table_destroy (disc->priv->monitored);
-		disc->priv->monitored = NULL;
-	}
-
-	if (disc->priv->reload_uri && disc->priv->reload_uri)
-		brasero_io_cancel_by_base (disc->priv->reload_uri);
-
-#endif
-
-	disc->priv->sectors = 0;
-
-	disc->priv->activity_counter = 1;
-	brasero_audio_disc_decrease_activity_counter (disc);
-
 	if (disc->priv->selected_path) {
 		gtk_tree_path_free (disc->priv->selected_path);
 		disc->priv->selected_path = NULL;
@@ -852,29 +556,9 @@ brasero_audio_disc_finalize (GObject *object)
 	
 	brasero_audio_disc_reset_real (cobj);
 
-#ifdef BUILD_INOTIFY
-
-	if (cobj->priv->notify_id)
-		g_source_remove (cobj->priv->notify_id);
-
-	if (cobj->priv->monitored) {
-		g_hash_table_destroy (cobj->priv->monitored);
-		cobj->priv->monitored = NULL;
-	}
-
-#endif
-	
-	brasero_io_cancel_by_base (cobj->priv->attr_changed);
-	brasero_io_cancel_by_base (cobj->priv->add_dir);
-	brasero_io_cancel_by_base (cobj->priv->add_uri);
-	brasero_io_cancel_by_base (cobj->priv->add_playlist);
-	g_free (cobj->priv->attr_changed);
 	g_free (cobj->priv->add_dir);
-	g_free (cobj->priv->add_uri);
 	g_free (cobj->priv->add_playlist);
-	cobj->priv->attr_changed = NULL;
 	cobj->priv->add_dir = NULL;
-	cobj->priv->add_uri = NULL;
 	cobj->priv->add_playlist = NULL;
 
 	if (cobj->priv->manager) {
@@ -886,253 +570,22 @@ brasero_audio_disc_finalize (GObject *object)
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
-GtkWidget *
-brasero_audio_disc_new ()
-{
-	BraseroAudioDisc *obj;
-	
-	obj = BRASERO_AUDIO_DISC (g_object_new (BRASERO_TYPE_AUDIO_DISC, NULL));
-	
-	return GTK_WIDGET (obj);
-}
-
-/******************************** activity *************************************/
-static BraseroDiscResult
-brasero_audio_disc_get_status (BraseroDisc *disc,
-			       gint *remaining,
-			       gchar **current_task)
-{
-	GtkTreeModel *model;
-
-	if (BRASERO_AUDIO_DISC (disc)->priv->activity_counter) {
-		if (remaining)
-			*remaining = BRASERO_AUDIO_DISC (disc)->priv->activity_counter;
-
-		if (current_task)
-			*current_task = g_strdup (_("Analysing audio files"));
-
-		return BRASERO_DISC_NOT_READY;
-	}
-
-	if (BRASERO_AUDIO_DISC (disc)->priv->loading)
-		return BRASERO_DISC_LOADING;
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (BRASERO_AUDIO_DISC (disc)->priv->tree));
-	if (!gtk_tree_model_iter_n_children (model, NULL))
-		return BRASERO_DISC_ERROR_EMPTY_SELECTION;
-
-	return BRASERO_DISC_OK;
-}
-
-static void
-brasero_audio_disc_increase_activity_counter (BraseroAudioDisc *disc)
-{
-	GdkCursor *cursor;
-
-	if (disc->priv->activity_counter == 0 && GTK_WIDGET (disc)->window) {
-		cursor = gdk_cursor_new (GDK_WATCH);
-		gdk_window_set_cursor (GTK_WIDGET (disc)->window, cursor);
-		gdk_cursor_unref (cursor);
-	}
-
-	disc->priv->activity_counter++;
-}
-
-static void
-brasero_audio_disc_decrease_activity_counter (BraseroAudioDisc *disc)
-{
-
-	if (disc->priv->activity_counter == 1 && GTK_WIDGET (disc)->window)
-		gdk_window_set_cursor (GTK_WIDGET (disc)->window, NULL);
-
-	disc->priv->activity_counter--;
-}
-
 /******************************** utility functions ****************************/
-static void
-brasero_audio_disc_size_changed (BraseroAudioDisc *disc)
-{
-	brasero_disc_size_changed (BRASERO_DISC (disc),
-				   disc->priv->sectors);
-}
-
-static gboolean
-brasero_audio_disc_has_gap (BraseroAudioDisc *disc,
-			    GtkTreeIter *row,
-			    GtkTreeIter *gap)
-{
-	GtkTreeModel *model;
-	gboolean is_song;
-
-	*gap = *row;
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	if (!gtk_tree_model_iter_next (model, gap))
-		return FALSE;
-
-	gtk_tree_model_get (model, gap,
-			    SONG_COL, &is_song,
-			    -1);
-
-	return (is_song != TRUE);
-}
 
 static void
 brasero_audio_disc_add_gap (BraseroAudioDisc *disc,
-			    GtkTreeIter *iter,
+			    GtkTreePath *treepath,
 			    gint64 gap)
 {
-	GtkTreeIter gap_iter;
 	GtkTreeModel *model;
-	gint64 length;
+	BraseroTrack *track;
 
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	if (gap) {
-		gchar *size;
-
-		if (brasero_audio_disc_has_gap (disc, iter, &gap_iter)) {
-			gtk_tree_model_get (model, &gap_iter,
-					    LENGTH_COL, &length,
-					    -1);
-
-			disc->priv->sectors -= BRASERO_DURATION_TO_SECTORS (length);
-		}
-		else {
-			gchar *string;
-
-			gtk_list_store_insert_after (GTK_LIST_STORE (model),
-						     &gap_iter,
-						     iter);
-
-			string = g_strdup_printf ("<i><b>%s</b></i>", _("Pause"));
-			gtk_list_store_set (GTK_LIST_STORE (model), &gap_iter,
-					    NAME_COL, string,
-					    SONG_COL, FALSE,
-					    //BACKGROUND_COL, "green yellow",
-					    ICON_COL, GTK_STOCK_MEDIA_PAUSE,
-					    -1);
-			g_free (string);
-		}
-
-		size = brasero_units_get_time_string (gap, TRUE, FALSE);
-		gtk_list_store_set (GTK_LIST_STORE (model), &gap_iter,
-				    SIZE_COL, size,
-				    LENGTH_COL, gap,
-				    -1);
-		g_free (size);
-
-		disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (gap);
-		brasero_audio_disc_size_changed (disc);
-	}
-	else if (brasero_audio_disc_has_gap (disc, iter, &gap_iter)) {
-		gtk_tree_model_get (model, &gap_iter,
-				    LENGTH_COL, &length,
-				    -1);
-
-		disc->priv->sectors -= BRASERO_DURATION_TO_SECTORS (length);
-		brasero_audio_disc_size_changed (disc);
-		gtk_list_store_remove (GTK_LIST_STORE (model), &gap_iter);
-	}
-}
-
-static void
-brasero_audio_disc_re_index_track_num (BraseroAudioDisc *disc,
-				       GtkTreeModel *model)
-{
-	GtkTreeIter iter;
-	gboolean is_song;
-	gchar *text;
-	gint num = 0;
-
-	if (!gtk_tree_model_get_iter_first (model, &iter))
-		return;
-
-	g_signal_handlers_block_by_func (model,
-					 brasero_audio_disc_row_changed_cb,
-					 disc);
-	do {
-		gtk_tree_model_get (model, &iter,
-				    SONG_COL, &is_song,
-				    -1);
-
-		/* This is gap row */
-		if (!is_song)
-			continue;
-
-		num ++;
-		text = g_strdup_printf ("%02i", num);
-
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    TRACK_NUM_COL, text,
-				    -1);
-
-		g_free (text);
-	} while (gtk_tree_model_iter_next (model, &iter));
-
-	g_signal_handlers_unblock_by_func (model,
-					   brasero_audio_disc_row_changed_cb,
-					   disc);
-}
-
-static gint
-brasero_audio_disc_get_track_num (BraseroAudioDisc *disc,
-				  GtkTreeModel *model)
-{
-	GtkTreeIter iter;
-	gboolean is_song;
-	gint num = 0;
-
-	if (!gtk_tree_model_get_iter_first (model, &iter))
-		return 0;
-
-	g_signal_handlers_block_by_func (model,
-					 brasero_audio_disc_row_changed_cb,
-					 disc);
-	do {
-		gtk_tree_model_get (model, &iter,
-				    SONG_COL, &is_song,
-				    -1);
-
-		if (is_song)
-			num ++;
-
-	} while (gtk_tree_model_iter_next (model, &iter));
-
-	g_signal_handlers_unblock_by_func (model,
-					   brasero_audio_disc_row_changed_cb,
-					   disc);
-
-	return num;		
-}
-
-static void
-brasero_audio_disc_row_deleted_cb (GtkTreeModel *model,
-				   GtkTreePath *path,
-				   BraseroAudioDisc *disc)
-{
-	brasero_disc_contents_changed (BRASERO_DISC (disc),
-				       brasero_audio_disc_get_track_num (disc, model));
-	brasero_audio_disc_re_index_track_num (disc, model);
-}
-
-static void
-brasero_audio_disc_row_inserted_cb (GtkTreeModel *model,
-				    GtkTreePath *path,
-				    GtkTreeIter *iter,
-				    BraseroAudioDisc *disc)
-{
-	brasero_disc_contents_changed (BRASERO_DISC (disc),
-				       brasero_audio_disc_get_track_num (disc, model));
-}
-
-static void
-brasero_audio_disc_row_changed_cb (GtkTreeModel *model,
-				   GtkTreePath *path,
-				   GtkTreeIter *iter,
-				   BraseroAudioDisc *disc)
-{
-	brasero_audio_disc_re_index_track_num (disc, model);
-	brasero_disc_contents_changed (BRASERO_DISC (disc),
-				       brasero_audio_disc_get_track_num (disc, model));
+	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
+	brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+					     -1,
+					     -1,
+					     gap);
 }
 
 static void
@@ -1144,164 +597,67 @@ brasero_audio_disc_short_track_dialog (BraseroAudioDisc *disc)
 			   GTK_MESSAGE_WARNING);
 }
 
-static gboolean
-brasero_audio_disc_set_row_from_metadata (BraseroAudioDisc *disc,
-					  GtkTreeModel *model,
-					  GtkTreeIter *iter,
-					  GFileInfo *info)
+static BraseroDiscResult
+brasero_audio_disc_add_uri_real (BraseroAudioDisc *disc,
+				 const gchar *uri,
+				 gint pos,
+				 gint64 gap_sectors,
+				 gint64 start,
+				 gint64 end,
+				 BraseroStreamInfo *info,
+				 GtkTreePath **path_return)
 {
-	const gchar *icon_string = BRASERO_DEFAULT_ICON;
-	gint64 current_length;
-	gboolean composer_set;
-	GtkTreeIter gap_iter;
-	gboolean artist_set;
-	gchar *size_string;
-	gboolean title_set;
-	gboolean isrc_set;
-	gint64 length;
-	gint64 start;
-	GIcon *icon;
-	gint64 end;
-
-	/* NOTE: implemented in glib 2.15.6 (not for windows though) */
-	icon = g_content_type_get_icon (g_file_info_get_content_type (info));
-	if (G_IS_THEMED_ICON (icon)) {
-		const gchar * const *names = NULL;
-
-		names = g_themed_icon_get_names (G_THEMED_ICON (icon));
-		if (names) {
-			gint i;
-			GtkIconTheme *theme;
-
-			theme = gtk_icon_theme_get_default ();
-			for (i = 0; names [i]; i++) {
-				if (gtk_icon_theme_has_icon (theme, names [i])) {
-					icon_string = names [i];
-					break;
-				}
-			}
-		}
-	}
-
-	gtk_tree_model_get (model, iter,
-			    START_COL, &start,
-			    END_COL, &end,
-			    -1);
-
-	/* make sure there is a length and it's not over the real one */
-	if (start >= 0 && end > 0)
-		current_length = BRASERO_STREAM_LENGTH (start, end);
-	else
-		current_length = 0;
-
-	if (current_length > g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN)) {
-		guint64 len;
-
-		len = g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN);
-		end = len - start;
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    END_COL, (gint64) end,
-				    -1);
-	}
-	/* make sure a length was set if not (and then start is 0) then set it */
-	else if (end <= 0) {
-		end = g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN);
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    END_COL, (gint64) end,
-				    -1);
-	}
-
-	/* Just in case */
-	if (start > end) {
-		/* problem */
-		start = end - BRASERO_MIN_STREAM_LENGTH;
-		if (start < 0)
-			start = 0;
-
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    START_COL, (gint64) start,
-				    -1);
-	}
-
-	/* check the track size and warn the user just in case */
-	if (brasero_audio_disc_has_gap (disc, iter, &gap_iter)) {
-		gint64 gap;
-
-		gtk_tree_model_get (model, &gap_iter,
-				    LENGTH_COL, &gap,
-				    -1);
+	BraseroTrackStreamCfg *track;
+	BraseroSessionCfg *session;
+	BraseroTrack *sibling;
+	GtkTreeModel *store;
 
-		/* gap counts as length */
-		if (end - start + BRASERO_SECTORS_TO_TIME (gap) < BRASERO_MIN_STREAM_LENGTH)
-			brasero_audio_disc_short_track_dialog (disc);
-	}
-	else if (end - start < BRASERO_MIN_STREAM_LENGTH) {
-		brasero_audio_disc_short_track_dialog (disc);
-	}
+	g_return_val_if_fail (uri != NULL, BRASERO_DISC_ERROR_UNKNOWN);
 
-	length = BRASERO_STREAM_LENGTH (start, end);
-	if (length != current_length) {
-		/* update global size */
-		if (current_length > 0)
-			disc->priv->sectors -= BRASERO_DURATION_TO_SECTORS (current_length);
+	if (disc->priv->reject_files)
+		return BRASERO_DISC_NOT_READY;
 
-		disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (length);
-		brasero_audio_disc_size_changed (disc);
-	}
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (BRASERO_AUDIO_DISC (disc)->priv->notebook), 1);
 
-	size_string = brasero_units_get_time_string (length, TRUE, FALSE);
-	gtk_list_store_set (GTK_LIST_STORE (model), iter,
-			    SIZE_COL, size_string,
-			    ICON_COL, icon_string,
-			    LENGTH_COL, g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN),
-			    SONG_COL, TRUE,
-			    -1);
-	g_free (size_string);
-
-	/* Set all informations provided they were not set already */
-	gtk_tree_model_get (model, iter,
-			    TITLE_SET_COL, &title_set,
-			    ARTIST_SET_COL, &artist_set,
-			    COMPOSER_SET_COL, &composer_set,
-			    ISRC_SET_COL, &isrc_set,
-			    -1);
+	store = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (store));
 
-	if (!title_set && g_file_info_get_attribute_string (info, BRASERO_IO_TITLE)) {
-		gchar *name;
+	track = brasero_track_stream_cfg_new ();
+	brasero_track_stream_set_source (BRASERO_TRACK_STREAM (track), uri);
+	brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+					     start,
+					     end,
+					     BRASERO_SECTORS_TO_TIME (gap_sectors));
 
-		name = brasero_utils_validate_utf8 (g_file_info_get_attribute_string (info, BRASERO_IO_TITLE));
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    NAME_COL, name,
-				    -1);
-		g_free (name);
-	}
+	if (info) {
+		brasero_track_tag_add_string (BRASERO_TRACK (track),
+					      BRASERO_TRACK_STREAM_TITLE_TAG,
+					      info->title);
+		brasero_track_tag_add_string (BRASERO_TRACK (track),
+					      BRASERO_TRACK_STREAM_ARTIST_TAG,
+					      info->artist);
+		brasero_track_tag_add_string (BRASERO_TRACK (track),
+					      BRASERO_TRACK_STREAM_COMPOSER_TAG,
+					      info->composer);
 
-	if (!artist_set && g_file_info_get_attribute_string (info, BRASERO_IO_ARTIST)) {
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    ARTIST_COL, g_file_info_get_attribute_string (info, BRASERO_IO_ARTIST),
-				    -1);
+		brasero_track_tag_add_int (BRASERO_TRACK (track),
+					   BRASERO_TRACK_STREAM_ISRC_TAG,
+					   info->isrc);
 	}
-	else if (!artist_set)
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    ARTIST_COL, _("Unknown"),
-				    -1);
 
-	if (!composer_set && g_file_info_get_attribute_string (info, BRASERO_IO_COMPOSER)) {
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    COMPOSER_COL, g_file_info_get_attribute_string (info, BRASERO_IO_COMPOSER),
-				    -1);
-	}
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (store));
+	if (pos > 0) {
+		GSList *tracks;
 
-	if (!isrc_set && g_file_info_get_attribute_int32 (info, BRASERO_IO_ISRC)) {
-		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    ISRC_COL, g_file_info_get_attribute_int32 (info, BRASERO_IO_ISRC),
-				    -1);
+		tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (session));
+		sibling = g_slist_nth_data (tracks, pos - 1);
 	}
 
-	if (icon)
-		g_object_unref (icon);
+	brasero_burn_session_add_track (BRASERO_BURN_SESSION (session), BRASERO_TRACK (track), sibling);
+	if (path_return)
+		*path_return = brasero_video_tree_model_track_to_path (BRASERO_VIDEO_TREE_MODEL (store), BRASERO_TRACK (track));
 
-	return TRUE;
+	return BRASERO_DISC_OK;
 }
 
 /*************** shared code for dir/playlist addition *************************/
@@ -1355,14 +711,6 @@ brasero_audio_disc_video_file_dialog (BraseroAudioDisc *disc,
 
 	return (answer == GTK_RESPONSE_OK);
 }
-static void
-brasero_audio_disc_add_file (BraseroAudioDisc *disc,
-			     const gchar *uri)
-{
-#ifdef BUILD_INOTIFY
-	brasero_audio_disc_start_monitoring (disc, uri);
-#endif
-}
 
 static void
 brasero_audio_disc_result (GObject *obj,
@@ -1371,11 +719,6 @@ brasero_audio_disc_result (GObject *obj,
 			   GFileInfo *info,
 			   gpointer null_data)
 {
-	gchar *name;
-	gchar *markup;
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-	gchar *escaped_name;
 	BraseroAudioDisc *disc = BRASERO_AUDIO_DISC (obj);
 
 	if (error)
@@ -1392,58 +735,27 @@ brasero_audio_disc_result (GObject *obj,
 	&& !brasero_audio_disc_video_file_dialog (disc, uri))
 		return;
 
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-
-	escaped_name = g_path_get_basename (uri);
-	name = g_uri_unescape_string (escaped_name, NULL);
-	g_free (escaped_name);
-
-	markup = brasero_utils_validate_utf8 (name);
-	g_free (name);
-
-	/* Set a default name here */
-    	gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-			    NAME_COL, markup,
-			    URI_COL, uri,
-			    -1);
-	g_free (markup);
-
-	if (!brasero_audio_disc_set_row_from_metadata (disc,
-						       model,
-						       &iter,
-						       info))
-		return;
-
-	brasero_audio_disc_add_file (disc, uri);
-}
-
-static void
-brasero_audio_disc_vfs_operation_finished (GObject *object,
-					   gboolean cancelled,
-					   gpointer null_data)
-{
-	BraseroAudioDisc *disc = BRASERO_AUDIO_DISC (object);
-
-	brasero_audio_disc_decrease_activity_counter (disc);
-
-	if (disc->priv->loading)
-		disc->priv->loading --;
+	brasero_audio_disc_add_uri_real (disc,
+					 uri,
+					 -1,
+					 -1,
+					 -1,
+					 -1,
+					 NULL,
+					 NULL);
 }
 
 /*********************** directories exploration *******************************/
 static BraseroDiscResult
-brasero_audio_disc_visit_dir_async (BraseroAudioDisc *disc,
-				    const gchar *uri)
+brasero_audio_disc_add_directory_contents (BraseroAudioDisc *disc,
+					   const gchar *uri)
 {
 	if (!disc->priv->add_dir)
 		disc->priv->add_dir = brasero_io_register (G_OBJECT (disc),
 							   brasero_audio_disc_result,
-							   brasero_audio_disc_vfs_operation_finished,
+							   NULL,
 							   NULL);
 
-	brasero_audio_disc_increase_activity_counter (disc);
-
 	/* we have to pass a dummy value here otherwise finished is never called */
 	brasero_io_load_directory (uri,
 				   disc->priv->add_dir,
@@ -1479,10 +791,10 @@ brasero_audio_disc_add_dir (BraseroAudioDisc *disc, const gchar *uri)
 	answer = gtk_dialog_run (GTK_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
 
-	if (answer != GTK_RESPONSE_OK)
+	if (answer == GTK_RESPONSE_OK)
 		return TRUE;
 
-	return brasero_audio_disc_visit_dir_async (disc, uri);
+	return FALSE;
 }
 
 /************************** playlist parsing ***********************************/
@@ -1496,10 +808,9 @@ brasero_audio_disc_add_playlist (BraseroAudioDisc *disc,
 	if (!disc->priv->add_playlist)
 		disc->priv->add_playlist = brasero_io_register (G_OBJECT (disc),
 								brasero_audio_disc_result,
-								brasero_audio_disc_vfs_operation_finished,
+								NULL,
 								NULL);
 
-	brasero_audio_disc_increase_activity_counter (disc);
 	brasero_io_parse_playlist (uri,
 				   disc->priv->add_playlist,
 				   BRASERO_IO_INFO_PERM|
@@ -1533,218 +844,104 @@ brasero_audio_disc_unreadable_dialog (BraseroAudioDisc *disc,
 }
 
 static void
-brasero_audio_disc_new_row_cb (GObject *obj,
-			       GError *error,
-			       const gchar *uri,
-			       GFileInfo *info,
-			       gpointer user_data)
+brasero_audio_disc_session_changed (BraseroSessionCfg *session,
+				    BraseroAudioDisc *self)
 {
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-	GtkTreeIter gap_iter;
-	GtkTreePath *treepath;
-	GtkTreeRowReference *ref = user_data;
-	BraseroAudioDisc *disc = BRASERO_AUDIO_DISC (obj);
+	GSList *next;
+	GSList *tracks;
+	gboolean notready;
+	BraseroStatus *status;
 
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	treepath = gtk_tree_row_reference_get_path (ref);
-	gtk_tree_row_reference_free (ref);
-	if (!treepath)
+	if (!GTK_WIDGET (self)->window)
 		return;
 
-	gtk_tree_model_get_iter (model, &iter, treepath);
-	gtk_tree_path_free (treepath);
-
-	if (error) {
-		brasero_audio_disc_unreadable_dialog (disc,
-						      uri,
-						      error);
+	/* make sure all tracks have video */
+	notready = FALSE;
+	status = brasero_status_new ();
+	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (session));
+	for (; tracks; tracks = next) {
+		BraseroStreamFormat format;
+		BraseroTrackStream *track;
+		BraseroBurnResult result;
 
-		if (brasero_audio_disc_has_gap (disc, &iter, &gap_iter))
-			brasero_audio_disc_add_gap (disc, &gap_iter, 0);
+		track = tracks->data;
+		next = tracks->next;
 
-		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-		return;
-	}
+		if (!BRASERO_IS_TRACK_STREAM (track))
+			continue;
 
-	if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
-		if (brasero_audio_disc_has_gap (disc, &iter, &gap_iter))
-			brasero_audio_disc_add_gap (disc, &gap_iter, 0);
+		result = brasero_track_get_status (BRASERO_TRACK (track), status);
+		if (result == BRASERO_BURN_ERR) {
+			GError *error;
+			gboolean res;
+			gchar *uri;
 
-		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-		brasero_audio_disc_add_dir (disc, uri);
-		return;
-	}
+			uri = brasero_track_stream_get_source (track, TRUE);
+			error = brasero_status_get_error (status);
+			if (!error)
+				brasero_audio_disc_file_type_error_dialog (self, uri);
+			else if (error->code == BRASERO_BURN_ERROR_FILE_FOLDER) {
+				res = brasero_audio_disc_add_dir (self, uri);
+				if (res)
+					brasero_audio_disc_add_directory_contents (self, uri);
+			}
 
 #if BUILD_PLAYLIST
-
-	const gchar *mime;
-
-	/* see if it a playlist */
-	mime = g_file_info_get_content_type (info);
-	if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR
-	&&  (!strcmp (mime, "audio/x-scpls")
-	||   !strcmp (mime, "audio/x-ms-asx")
-	||   !strcmp (mime, "audio/x-mp3-playlist")
-	||   !strcmp (mime, "audio/x-mpegurl"))) {
-		/* This is a supported playlist */
-		if (brasero_audio_disc_has_gap (disc, &iter, &gap_iter))
-			brasero_audio_disc_add_gap (disc, &gap_iter, 0);
-
-		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-		brasero_audio_disc_add_playlist (disc, uri);
-		return;
-	}
-
+			else if (error->code == BRASERO_BURN_ERROR_FILE_PLAYLIST) {
+				/* This is a supported playlist */
+				brasero_audio_disc_add_playlist (self, uri);
+			}
 #endif
 
-	if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR
-	|| !g_file_info_get_attribute_boolean (info, BRASERO_IO_HAS_AUDIO)) {
-		if (brasero_audio_disc_has_gap (disc, &iter, &gap_iter))
-			brasero_audio_disc_add_gap (disc, &gap_iter, 0);
-
-		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-		brasero_audio_disc_file_type_error_dialog (disc, uri);
-		return;
-	}
-
-	if (g_file_info_get_attribute_boolean (info, BRASERO_IO_HAS_VIDEO)
-	&& !brasero_audio_disc_video_file_dialog (disc, uri)) {
-		if (brasero_audio_disc_has_gap (disc, &iter, &gap_iter))
-			brasero_audio_disc_add_gap (disc, &gap_iter, 0);
-
-		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-		return;
-	}
-
-	if (g_file_info_get_is_symlink (info)) {
-		uri = g_strconcat ("file://", g_file_info_get_symlink_target (info), NULL);
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    URI_COL, uri, -1);
-	}
-
-	if (!brasero_audio_disc_set_row_from_metadata (disc,
-						       model,
-						       &iter,
-						       info))
-		return;
+			else if (error->code == BRASERO_BURN_ERROR_FILE_NOT_FOUND) {
+				/* It could be a file that was deleted */
+				brasero_audio_disc_file_type_error_dialog (self, uri);
+			}
+			else
+				brasero_audio_disc_unreadable_dialog (self,
+								      uri,
+								      error);
 
-	brasero_audio_disc_add_file (disc, uri);
-}
+			brasero_burn_session_remove_track (BRASERO_BURN_SESSION (session),
+							   BRASERO_TRACK (track));
+			g_error_free (error);
+			g_free (uri);
+			continue;
+		}
 
-static BraseroDiscResult
-brasero_audio_disc_add_uri_real (BraseroAudioDisc *disc,
-				 const gchar *uri,
-				 gint pos,
-				 gint64 gap_sectors,
-				 gint64 start,
-				 gint64 end,
-				 BraseroStreamInfo *info,
-				 GtkTreePath **path_return)
-{
-	GtkTreeRowReference *ref;
-	GtkTreePath *treepath;
-	GtkTreeModel *store;
-	GtkTreeIter iter;
-	gchar *markup;
-	gchar *name;
+		if (result == BRASERO_BURN_NOT_READY) {
+			notready = TRUE;
+			continue;
+		}
 
-	g_return_val_if_fail (uri != NULL, BRASERO_DISC_ERROR_UNKNOWN);
+		if (result != BRASERO_BURN_OK)
+			continue;
 
-	if (disc->priv->reject_files)
-		return BRASERO_DISC_NOT_READY;
+		format = brasero_track_stream_get_format (track);
+		if (!BRASERO_STREAM_FORMAT_AUDIO (format)) {
+			gchar *uri;
 
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (BRASERO_AUDIO_DISC (disc)->priv->notebook), 1);
+			uri = brasero_track_stream_get_source (track, TRUE);
+			brasero_audio_disc_file_type_error_dialog (self, uri);
+			brasero_burn_session_remove_track (BRASERO_BURN_SESSION (session),
+							   BRASERO_TRACK (track));
+			g_free (uri);
+		}
 
-	store = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	if (pos > -1)
-		gtk_list_store_insert (GTK_LIST_STORE (store), &iter, pos);
-	else
-		gtk_list_store_append (GTK_LIST_STORE (store), &iter);
+		if (BRASERO_STREAM_FORMAT_HAS_VIDEO (format)) {
+			gboolean res;
 
-	BRASERO_GET_BASENAME_FOR_DISPLAY (uri, name);
-	markup = g_markup_escape_text (name, -1);
-	g_free (name);
+			gchar *uri;
 
-	if (info)
-		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
-				    URI_COL, uri,
-				    SONG_COL, TRUE,
-				    ICON_COL, "image-loading",
-				    NAME_COL, info->title? info->title:markup,
-				    TITLE_SET_COL, info->title? TRUE:FALSE,
-				    ARTIST_COL, info->artist? info->artist:_("(loading ...)"),
-				    ARTIST_SET_COL, info->artist? TRUE:FALSE,
-				    COMPOSER_COL, info->composer? info->composer:NULL,
-				    COMPOSER_SET_COL, info->composer? TRUE:FALSE,
-				    ISRC_COL, info->isrc,
-				    ISRC_SET_COL, info->isrc? TRUE:FALSE,
-				    -1);
-	else
-		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
-				    NAME_COL, markup,
-				    ICON_COL, "image-loading",
-				    URI_COL, uri,
-				    ARTIST_COL, _("(loading ...)"),
-				    SONG_COL, TRUE,
-				    -1);
-	g_free (markup);
-
-	start = start > 0 ? start:0;
-	if (end > 0 && end > start) {
-		gchar *string;
-		gint64 length;
-
-		/* update global size */
-		length = BRASERO_STREAM_LENGTH (start, end);
-		disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (length);
-		brasero_audio_disc_size_changed (disc);
-
-		string = brasero_units_get_time_string (length, TRUE, FALSE);
-		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
-				    START_COL, start,
-				    END_COL, end,
-				    SIZE_COL, string,
-				    -1);
-		g_free (string);
+			uri = brasero_track_stream_get_source (track, TRUE);
+			res = brasero_audio_disc_video_file_dialog (self, uri);
+			if (res)
+				brasero_burn_session_remove_track (BRASERO_BURN_SESSION (session),
+								   BRASERO_TRACK (track));
+			g_free (uri);
+		}
 	}
-	else
-		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
-				    SIZE_COL, _("(loading ...)"),
-				    -1);
-
-	if (gap_sectors > 0)
-		brasero_audio_disc_add_gap (disc,
-					    &iter,
-					    BRASERO_SECTORS_TO_TIME (gap_sectors));
-
-	treepath = gtk_tree_model_get_path (store, &iter);
-	ref = gtk_tree_row_reference_new (store, treepath);
-
-	if (path_return)
-		*path_return = treepath;
-	else
-		gtk_tree_path_free (treepath);
-
-	/* get info async for the file */
-	if (!disc->priv->add_uri)
-		disc->priv->add_uri = brasero_io_register (G_OBJECT (disc),
-							   brasero_audio_disc_new_row_cb,
-							   brasero_audio_disc_vfs_operation_finished,
-							   NULL);
-	/* FIXME: if cancelled ref won't be destroyed ? 
-	 * no, since the callback is always called even if there is an error */
-	brasero_audio_disc_increase_activity_counter (disc);
-	brasero_io_get_file_info (uri,
-				  disc->priv->add_uri,
-				  BRASERO_IO_INFO_PERM|
-				  BRASERO_IO_INFO_MIME|
-				  BRASERO_IO_INFO_URGENT|
-				  BRASERO_IO_INFO_METADATA|
-				  BRASERO_IO_INFO_METADATA_MISSING_CODEC,
-				  ref);
-
-	return BRASERO_DISC_OK;
+	brasero_status_free (status);
 }
 
 static BraseroDiscResult
@@ -1778,62 +975,32 @@ brasero_audio_disc_add_uri (BraseroDisc *disc,
 	return result;
 }
 
-/******************************** Row removing *********************************/
 static void
 brasero_audio_disc_remove (BraseroAudioDisc *disc,
 			   GtkTreePath *treepath)
 {
-	GtkTreeIter gap_iter;
+	BraseroSessionCfg *session;
 	GtkTreeModel *model;
+	BraseroTrack *track;
 	GtkTreeIter iter;
-	gint64 sectors;
-	gint64 length;
-	gint64 start;
-	gint64 end;
-	gchar *uri;
+	gboolean is_gap;
 
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
 	gtk_tree_model_get_iter (model, &iter, treepath);
 	gtk_tree_model_get (model, &iter,
-			    URI_COL, &uri,
-			    START_COL, &start,
-			    END_COL, &end,
-			    LENGTH_COL, &length,
+			    BRASERO_VIDEO_TREE_MODEL_IS_GAP, &is_gap,
 			    -1);
 
-	sectors = 0;
-	if (uri) {
-		if (end - start > 0)
-			sectors = BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (start, end));
-	}
-	else if (length) /* gap */
-		sectors = BRASERO_DURATION_TO_SECTORS (length);
-
-	if (brasero_audio_disc_has_gap (disc, &iter, &gap_iter)) {
-		gint64 gap_length = 0;
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
+	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
 
-		gtk_tree_model_get (model, &gap_iter,
-				    LENGTH_COL, &gap_length,
-				    -1);
-
-		sectors += BRASERO_DURATION_TO_SECTORS (gap_length);
-		gtk_list_store_remove (GTK_LIST_STORE (model), &gap_iter);
-	}
-
-	gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-
-	if (sectors > 0) {
-		disc->priv->sectors -= sectors;
-		brasero_audio_disc_size_changed (disc);
-	}
-
-	if (!uri)
-		return;
-
-#ifdef BUILD_INOTIFY
-	brasero_audio_disc_cancel_monitoring (disc, uri);
-#endif
-	g_free (uri);
+	if (is_gap)
+		brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+						     -1,
+						     -1,
+						     0);
+	else
+		brasero_burn_session_remove_track (BRASERO_BURN_SESSION (session), track);
 }
 
 static void
@@ -1865,121 +1032,46 @@ brasero_audio_disc_delete_selected (BraseroDisc *disc)
 	brasero_disc_selection_changed (disc);
 }
 
-static void
-brasero_audio_disc_clear (BraseroDisc *disc)
-{
-	BraseroAudioDisc *audio;
-	GtkTreeModel *model;
-
-	audio = BRASERO_AUDIO_DISC (disc);
-	brasero_audio_disc_reset_real (audio);
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (audio->priv->tree));
-	gtk_list_store_clear (GTK_LIST_STORE (model));
-
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (BRASERO_AUDIO_DISC (disc)->priv->notebook), 0);
-	brasero_disc_size_changed (disc, 0);
-}
-
-static void
-brasero_audio_disc_reset (BraseroDisc *disc)
-{
-	brasero_audio_disc_clear (disc);
-}
-
 /********************************* create track ********************************/
 static BraseroDiscResult
 brasero_audio_disc_get_track (BraseroDisc *disc,
-			      BraseroDiscTrack *track)
+			      BraseroDiscTrack *track_arg)
 {
-	gchar *uri;
-	GtkTreeIter iter;
+	GSList *tracks;
 	GtkTreeModel *model;
-	BraseroDiscSong *song;
 	BraseroAudioDisc *audio;
+	BraseroSessionCfg *session;
 
 	audio = BRASERO_AUDIO_DISC (disc);
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (audio->priv->tree));
-	if (!gtk_tree_model_get_iter_first (model, &iter))
-		return BRASERO_DISC_ERROR_EMPTY_SELECTION;
-
-	track->type = BRASERO_PROJECT_TYPE_AUDIO;
-	song = NULL;
-
-	do {
-		gint isrc;
-		gint64 end;
-		gint64 start;
-		gchar *title;
-		gchar *artist;
-		gchar *composer;
-		gboolean isrc_set;
-		gboolean title_set;
-		gboolean artist_set;
-		gboolean composer_set;
-		gboolean length_set;
-
-		gtk_tree_model_get (model, &iter,
-				    URI_COL, &uri,
-				    START_COL, &start,
-				    END_COL, &end,
-				    LENGTH_SET_COL, &length_set,
-				    TITLE_SET_COL, &title_set,
-				    ARTIST_SET_COL, &artist_set,
-				    COMPOSER_SET_COL, &composer_set,
-				    ISRC_SET_COL, &isrc_set,
-				    NAME_COL, &title,
-				    ARTIST_COL, &artist,
-				    COMPOSER_COL, &composer,
-				    ISRC_COL, &isrc,
-				    -1);
-
-		if (!uri) {
-			gint64 length;
-
-			/* this is a gap */
-			gtk_tree_model_get (model, &iter,
-					    LENGTH_COL, &length,
-					    -1);
-			if (length && song)
-				song->gap += BRASERO_DURATION_TO_SECTORS (length);
-		}
-		else {
-			BraseroStreamInfo *info;
-
-			song = g_new0 (BraseroDiscSong, 1);
-			song->uri = uri;
-
-			if (length_set) {
-				song->start = start > 0 ? start:0;
-				song->end = end > 0 ? end:0;
-			}
-
-			info = g_new0 (BraseroStreamInfo, 1);
-			if (title_set)
-				info->title = title;
-			else
-				g_free (title);
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
 
-			if (artist_set)
-				info->artist = artist;
-			else
-				g_free (artist);
+	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (session));
+	if (!tracks)
+		return BRASERO_DISC_ERROR_EMPTY_SELECTION;
 
-			if (composer_set)
-				info->composer = composer;
-			else
-				g_free (composer);
+	for (; tracks; tracks = tracks->next) {
+		BraseroTrackStream *track;
+		BraseroStreamInfo *info;
+		BraseroDiscSong *song;
 
-			if (isrc_set)
-				info->isrc = isrc;
+		track = tracks->data;
 
-			song->info = info;
+		song = g_new0 (BraseroDiscSong, 1);
+		song->uri = brasero_track_stream_get_source (track, TRUE);
+		song->start = brasero_track_stream_get_start (track);
+		song->end = brasero_track_stream_get_end (track);
+		song->gap = brasero_track_stream_get_gap (track);
 
-			track->contents.tracks = g_slist_append (track->contents.tracks, song);
-		}
+		info = g_new0 (BraseroStreamInfo, 1);
+		info->title = g_strdup (brasero_track_tag_lookup_string (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_TITLE_TAG));
+		info->artist = g_strdup (brasero_track_tag_lookup_string (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_ARTIST_TAG));
+		info->composer = g_strdup (brasero_track_tag_lookup_string (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_COMPOSER_TAG));
+		info->isrc = brasero_track_tag_lookup_int (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_ISRC_TAG);
+		song->info = info;
 
-	} while (gtk_tree_model_iter_next (model, &iter));
+		track_arg->contents.tracks = g_slist_append (track_arg->contents.tracks, song);
+	}
 
 	return BRASERO_DISC_OK;
 }
@@ -1988,80 +1080,26 @@ static BraseroDiscResult
 brasero_audio_disc_set_session_contents (BraseroDisc *disc,
 					 BraseroBurnSession *session)
 {
-	GtkTreeIter iter;
-	GtkTreeModel *model;
 	BraseroAudioDisc *audio;
-	BraseroTrackStream *track;
+	BraseroVideoTreeModel *model;
 
 	audio = BRASERO_AUDIO_DISC (disc);
 
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (audio->priv->tree));
-	if (!gtk_tree_model_get_iter_first (model, &iter))
-		return BRASERO_DISC_ERROR_EMPTY_SELECTION;
-
-	track = NULL;
-	do {
-		gchar *uri;
-		gchar *title;
-		gchar *artist;
-		gchar *composer;
-		gint isrc;
-		gint64 end;
-		gint64 start;
-		gint64 length;
-
-		gtk_tree_model_get (model, &iter,
-				    URI_COL, &uri,
-				    NAME_COL, &title,
-				    ARTIST_COL, &artist,
-				    COMPOSER_COL, &composer,
-				    ISRC_COL, &isrc,
-				    LENGTH_COL, &length,
-				    START_COL, &start,
-				    END_COL, &end,
-				    -1);
-
-		if (!uri) {
-			/* This is a gap so sectors refers to its size */
-			brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
-							     -1,
-							     -1,
-							     length);
-			continue;
-		}
-
-		track = brasero_track_stream_new ();
-		brasero_track_stream_set_source (track, uri);
-		brasero_track_stream_set_format (track,
-						 BRASERO_AUDIO_FORMAT_UNDEFINED|
-						 BRASERO_METADATA_INFO);
+	if (!session) {
+		gtk_tree_view_set_model (GTK_TREE_VIEW (audio->priv->tree), NULL);
+		return BRASERO_DISC_OK;
+	}
 
-		brasero_track_stream_set_boundaries (track, start, end, -1);
+	model = brasero_video_tree_model_new ();
+	brasero_video_tree_model_set_session (model, BRASERO_SESSION_CFG (session));
+	gtk_tree_view_set_model (GTK_TREE_VIEW (audio->priv->tree),
+				 GTK_TREE_MODEL (model));
+	g_object_unref (model);
 
-		if (title)
-			brasero_track_tag_add_string (BRASERO_TRACK (track),
-						      BRASERO_TRACK_STREAM_TITLE_TAG,
-						      title);
-		if (artist)
-			brasero_track_tag_add_string (BRASERO_TRACK (track),
-						      BRASERO_TRACK_STREAM_ARTIST_TAG,
-						      artist);
-		if (composer)
-			brasero_track_tag_add_string (BRASERO_TRACK (track),
-						      BRASERO_TRACK_STREAM_COMPOSER_TAG,
-						      composer);
-		if (isrc)
-			brasero_track_tag_add_int (BRASERO_TRACK (track),
-						   BRASERO_TRACK_STREAM_ISRC_TAG,
-						   isrc);
-
-		brasero_burn_session_add_track (session, BRASERO_TRACK (track), NULL);
-
-		/* It's good practice to unref the track afterwards as we don't
-		 * need it anymore. BraseroBurnSession refs it. */
-		g_object_unref (track);
-		g_free (uri);
-	} while (gtk_tree_model_iter_next (model, &iter));
+	g_signal_connect (session,
+			  "is-valid",
+			  G_CALLBACK (brasero_audio_disc_session_changed),
+			  disc);
 
 	return BRASERO_DISC_OK;
 }
@@ -2072,50 +1110,19 @@ brasero_audio_disc_add_track (BraseroAudioDisc *disc,
 			      BraseroDiscSong *song)
 {
 	GtkTreeModel *model;
-	GtkTreeIter iter;
+	BraseroSessionCfg *session;
 
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
 
-	gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-			    URI_COL, song->uri,
-			    START_COL, (guint64) song->start,
-			    END_COL, (guint64) song->end,
-			    SONG_COL, TRUE,
-			    -1);
-
-	disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (song->start, song->end));
-
-	if (song->info) {
-		if (song->info->title)
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    NAME_COL, song->info->title,
-					    TITLE_SET_COL, TRUE,
-					    -1);
-		if (song->info->artist)
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    ARTIST_COL, song->info->artist,
-					    ARTIST_SET_COL, TRUE,
-					    -1);
-		if (song->info->composer)
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    COMPOSER_COL, song->info->composer,
-					    COMPOSER_SET_COL, TRUE,
-					    -1);
-		if (song->info->isrc)
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    ISRC_COL, song->info->isrc,
-					    ISRC_SET_COL, TRUE,
-					    -1);
-	}
-
-	if (song->gap) {
-		gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    LENGTH_COL, (guint64) song->gap,
-				    -1);
-		disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (song->gap);
-	}
+	brasero_audio_disc_add_uri_real (disc,
+					 song->uri,
+					 -1,
+					 song->gap,
+					 song->start,
+					 song->end,
+					 song->info,
+					 NULL);
 }
 
 static BraseroDiscResult
@@ -2157,458 +1164,6 @@ brasero_audio_disc_load_track (BraseroDisc *disc,
 	return BRASERO_DISC_OK;
 }
 
-/********************************* DND *****************************************/
-static gint
-brasero_audio_disc_get_dest_path (BraseroAudioDisc *disc,
-				  gint x,
-				  gint y)
-{
-	gint position;
-	GtkTreeModel *model;
-	GtkTreeViewDropPosition pos;
-	GtkTreePath *treepath = NULL;
-
-	/* while the treeview is still under the information pane, it is not 
-	 * realized yet and the following function will fail */
-	if (GTK_WIDGET_DRAWABLE (disc->priv->tree))
-		gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (disc->priv->tree),
-						   x,
-						   y,
-						   &treepath,
-						   &pos);
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-
-	if (treepath) {
-		if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE
-		||  pos == GTK_TREE_VIEW_DROP_BEFORE) {
-			if (!gtk_tree_path_prev (treepath)) {
-				gtk_tree_path_free (treepath);
-				treepath = NULL;
-			}
-		}
-
-		if (treepath) {
-			gint *indices;
-			gboolean is_song;
-			GtkTreeIter iter;
-
-			/* we check that the dest is not in between a song
-			 * and its pause/gap/silence */
-			gtk_tree_model_get_iter (model, &iter, treepath);
-			gtk_tree_model_get (model, &iter,
-					    SONG_COL, &is_song,
-					    -1);
-
-			if (is_song
-			&&  gtk_tree_model_iter_next (model, &iter)) {
-				gtk_tree_model_get (model, &iter,
-						    SONG_COL, &is_song,
-						    -1);
-
-				if (!is_song)
-					gtk_tree_path_next (treepath);
-			}
-
-			indices = gtk_tree_path_get_indices (treepath);
-			position = indices [0];
-
-			gtk_tree_path_free (treepath);
-		}
-		else
-			position = -1;
-	}
-	else
-		position = gtk_tree_model_iter_n_children (model, NULL) - 1;
-
-	return position;
-}
-
-static void
-brasero_audio_disc_merge_gaps (BraseroAudioDisc *disc,
-			       GtkTreeModel *model,
-			       GtkTreeIter *iter,
-			       GtkTreeIter *pos)
-{
-	GtkTreePath *iter_path, *pos_path;
-	gint64 length_iter, length_pos;
-	gchar *size;
-	gint equal;
-
-	iter_path = gtk_tree_model_get_path (model, iter);
-	pos_path = gtk_tree_model_get_path (model, pos);
-	equal = gtk_tree_path_compare (iter_path, pos_path);
-	gtk_tree_path_free (iter_path);
-	gtk_tree_path_free (pos_path);
-
-	if (!equal)
-		return;
-
-	gtk_tree_model_get (model, pos,
-			    LENGTH_COL, &length_pos,
-			    -1);
-	gtk_tree_model_get (model, iter,
-			    LENGTH_COL, &length_iter,
-			    -1);
-
-	length_pos += length_iter;
-	size = brasero_units_get_time_string (length_pos, TRUE, FALSE);
-	gtk_list_store_set (GTK_LIST_STORE (model), pos,
-			    SIZE_COL, size,
-			    LENGTH_COL, length_pos,
-			    -1);
-	g_free (size);
-
-	gtk_list_store_remove (GTK_LIST_STORE (model), iter);
-}
-
-static GtkTreePath *
-brasero_audio_disc_move_to_dest (BraseroAudioDisc *disc,
-				 GtkTreeSelection *selection,
-				 GtkTreeModel *model,
-				 GtkTreePath *dest,
-				 GtkTreeIter *iter,
-				 gboolean is_gap)
-{
-	GtkTreeIter position;
-	GtkTreeIter gap_iter;
-	gboolean has_gap = FALSE;
-
-	gtk_tree_model_get_iter (model, &position, dest);
-	if (is_gap) {
-		gboolean is_song;
-		GtkTreeIter next_pos;
-
-		/* Check that the row and the row under the destination
-		 * row are not gaps as well and if so merge both of them */
-
-		gtk_tree_model_get (model, &position,
-				    SONG_COL, &is_song,
-				    -1);
-
-		if (!is_song) {
-			/* NOTE: if the path we're moving is above the
-			 * dest the dest path won't be valid once we
-			 * have merged the two gaps */
-			gtk_tree_path_free (dest);
-			brasero_audio_disc_merge_gaps (disc,
-						       model,
-						       iter,
-						       &position);
-			return gtk_tree_model_get_path (model, &position);
-		}
-
-		gtk_tree_path_next (dest);
-		if (gtk_tree_model_get_iter (model, &next_pos, dest)) {
-			gtk_tree_model_get (model, &next_pos,
-					    SONG_COL, &is_song,
-					    -1);
-
-			if (!is_song) {
-				/* NOTE: if the path we're moving is above the
-				 * dest the dest path won't be valid once we
-				 * have merged the two gaps */
-				gtk_tree_path_free (dest);
-				brasero_audio_disc_merge_gaps (disc,
-							       model,
-							       iter,
-							       &next_pos);
-				return gtk_tree_model_get_path (model, &next_pos);
-			}
-		}
-	}
-	else
-		has_gap = brasero_audio_disc_has_gap (disc, iter, &gap_iter);
-
-	gtk_tree_path_free (dest);
-	gtk_list_store_move_after (GTK_LIST_STORE (model),
-				   iter,
-				   &position);
-
-	if (has_gap && !gtk_tree_selection_iter_is_selected (selection, &gap_iter)) {
-		gtk_list_store_move_after (GTK_LIST_STORE (model),
-					   &gap_iter,
-					   iter);
-
-		return gtk_tree_model_get_path (model, &gap_iter);
-	}
-
-	return gtk_tree_model_get_path (model, iter);
-}
-
-static void
-brasero_audio_disc_move_to_first_pos (BraseroAudioDisc *disc,
-				      GtkTreeSelection *selection,
-				      GtkTreeModel *model,
-				      GtkTreeIter *iter,
-				      gboolean is_gap)
-{
-	GtkTreeIter position;
-	GtkTreeIter gap_iter;
-	gboolean has_gap = FALSE;
-
-	gtk_tree_model_get_iter_first (model, &position);
-	if (is_gap) {
-		gboolean is_song;
-
-		gtk_tree_model_get (model, &position,
-				    SONG_COL, &is_song,
-				    -1);
-
-		if (!is_song) {
-			brasero_audio_disc_merge_gaps (disc,
-						       model,
-						       iter,
-						       &position);
-			return;
-		}
-	}
-	else
-		has_gap = brasero_audio_disc_has_gap (disc, iter, &gap_iter);
-
-	gtk_list_store_move_before (GTK_LIST_STORE (model),
-				    iter,
-				    &position);
-
-	if (has_gap && !gtk_tree_selection_iter_is_selected (selection, &gap_iter))
-		gtk_list_store_move_after (GTK_LIST_STORE (model),
-					   &gap_iter,
-					   iter);
-}
-
-static void
-brasero_audio_disc_drag_data_received_cb (GtkTreeView *tree,
-					  GdkDragContext *drag_context,
-					  gint x,
-					  gint y,
-					  GtkSelectionData *selection_data,
-					  guint info,
-					  guint time,
-					  BraseroAudioDisc *disc)
-{
-	GtkTreeSelection *selection;
-	BraseroDiscResult success;
-	gboolean result = TRUE;
-	GtkTreePath *treepath;
-	GtkTreeModel *model;
-	gchar **uri, **uris;
-	GtkTreeIter iter;
-	gboolean is_song;
-	gint pos;
-
-	if (info == TREE_MODEL_ROW) {
-		GList *references = NULL;
-		GtkTreePath *dest;
-		GList *list_iter;
-		GList *selected;
-
-		/* this signal gets emitted during dragging */
-		if (disc->priv->dragging) {
-			gdk_drag_status (drag_context,
-					 GDK_ACTION_MOVE,
-					 time);
-			g_signal_stop_emission_by_name (tree, "drag-data-received");
-			return;
-		}
-
-		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (disc->priv->tree));
-		selected = gtk_tree_selection_get_selected_rows (selection, &model);
-
-		for (list_iter = selected; list_iter; list_iter = list_iter->next) {
-			GtkTreeRowReference *reference;
-
-			reference = gtk_tree_row_reference_new (model, list_iter->data);
-			references = g_list_prepend (references, reference);
-			gtk_tree_path_free (list_iter->data);
-		}
-		g_list_free (selected);
-
-		pos = brasero_audio_disc_get_dest_path (disc, x, y);
-		if (pos != -1) {
-			references = g_list_reverse (references);
-			dest = gtk_tree_path_new_from_indices (pos, -1);
-		}
-		else
-			dest = NULL;
-
-		for (list_iter = references; list_iter; list_iter = list_iter->next) {
-			treepath = gtk_tree_row_reference_get_path (list_iter->data);
-			gtk_tree_row_reference_free (list_iter->data);
-
-			if (!gtk_tree_model_get_iter (model, &iter, treepath)) {
-				gtk_tree_path_free (treepath);
-				continue;
-			}
-			gtk_tree_path_free (treepath);
-
-			gtk_tree_model_get (model, &iter,
-					    SONG_COL, &is_song,
-					    -1);
-
-			if (dest)
-				dest = brasero_audio_disc_move_to_dest (disc,
-									selection,
-									model,
-									dest,
-									&iter,
-									is_song == FALSE);
-			else
-				brasero_audio_disc_move_to_first_pos (disc,
-								      selection,
-								      model,
-								      &iter,
-								      is_song == FALSE);
-		}
-		g_list_free (references);
-
-		if (dest)
-			gtk_tree_path_free (dest);
-
-		gtk_drag_finish (drag_context,
-				 TRUE,
-				 FALSE,
-				 time);
-		g_signal_stop_emission_by_name (tree, "drag-data-received");
-
-		brasero_audio_disc_re_index_track_num (disc, model);
-		return;
-	}
-
-	if (selection_data->length <= 0
-	||  selection_data->format != 8) {
-		gtk_drag_finish (drag_context, FALSE, FALSE, time);
-		return;
-	}
-
-	/* get pos and URIS */
-	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (disc->priv->tree));
-	gtk_tree_selection_unselect_all (selection);
-
-	pos = brasero_audio_disc_get_dest_path (disc, x, y);
-	pos ++;
-
-	uris = gtk_selection_data_get_uris (selection_data);
-	for (uri = uris; *uri != NULL; uri++) {
-		treepath = NULL;
-		success = brasero_audio_disc_add_uri_real (disc,
-							   *uri,
-							   pos,
-							   0,
-							   -1,
-							   -1,
-							   NULL,
-							   &treepath);
-		if (success == BRASERO_DISC_OK) {
-			pos ++;
-			if (treepath) {
-				gtk_tree_selection_select_path (selection, treepath);
-				gtk_tree_path_free (treepath);
-			}
-		}
-
-		result = result ? (success == BRASERO_DISC_OK) : FALSE;
-		g_free (*uri);
-	}
-	g_free (uris);
-
-	gtk_drag_finish (drag_context,
-			 result,
-			 (drag_context->action == GDK_ACTION_MOVE),
-			 time);
-}
-
-static gboolean
-brasero_audio_disc_drag_drop_cb (GtkWidget *widget,
-				 GdkDragContext*drag_context,
-				 gint x,
-				 gint y,
-				 guint time,
-				 BraseroAudioDisc *disc)
-{
-	disc->priv->dragging = 0;
-	return FALSE;
-}
-
-static void
-brasero_audio_disc_drag_leave_cb (GtkWidget *tree,
-				  GdkDragContext *drag_context,
-				  guint time,
-				  BraseroAudioDisc *disc)
-{
-	if (disc->priv->drag_context) {
-		GdkPixbuf *pixbuf;
-		GdkPixmap *pixmap;
-		GdkBitmap *mask;
-
-		pixbuf = gtk_widget_render_icon (tree,
-						 GTK_STOCK_DELETE,
-						 GTK_ICON_SIZE_DND,
-						 NULL);
-		gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf,
-								gtk_widget_get_colormap (tree),
-								&pixmap,
-								&mask,
-								128);
-		g_object_unref (pixbuf);
-
-		gtk_drag_set_icon_pixmap (disc->priv->drag_context,
-					  gdk_drawable_get_colormap (pixmap),
-					  pixmap,
-					  mask,
-					  -2,
-					  -2);
-	}
-}
-
-static gboolean
-brasero_audio_disc_drag_motion_cb (GtkWidget *tree,
-				   GdkDragContext *drag_context,
-				   gint x,
-				   gint y,
-				   guint time,
-				   BraseroAudioDisc *disc)
-{
-	GdkAtom target;
-
-	target = gtk_drag_dest_find_target (tree,
-					    drag_context,
-					    gtk_drag_dest_get_target_list(tree));
-
-	if (target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE)
-	&&  disc->priv->drag_context)
-		gtk_drag_set_icon_default (disc->priv->drag_context);
-
-	return FALSE;
-}
-
-static void
-brasero_audio_disc_drag_begin_cb (GtkWidget *widget,
-				  GdkDragContext *drag_context,
-				  BraseroAudioDisc *disc)
-{
-	disc->priv->drag_context = drag_context;
-	g_object_ref (drag_context);
-
-	disc->priv->dragging = 1;
-}
-
-static void
-brasero_audio_disc_drag_end_cb (GtkWidget *tree,
-			        GdkDragContext *drag_context,
-			        BraseroAudioDisc *disc)
-{
-	gint x, y;
-
-	if (disc->priv->drag_context) {
-		g_object_unref (disc->priv->drag_context);
-		disc->priv->drag_context = NULL;
-	}
-
-	gtk_widget_get_pointer (tree, &x, &y);
-	if (x < 0 || y < 0 || x > tree->allocation.width || y > tree->allocation.height)
-		brasero_audio_disc_delete_selected (BRASERO_DISC (disc));
-}
-
 /********************************** Cell Editing *******************************/
 static void
 brasero_audio_disc_display_edited_cb (GtkCellRendererText *renderer,
@@ -2616,21 +1171,21 @@ brasero_audio_disc_display_edited_cb (GtkCellRendererText *renderer,
 				      gchar *text,
 				      BraseroAudioDisc *disc)
 {
-	GtkTreePath *treepath;
+	const gchar *tag;
 	GtkTreeModel *model;
-	gint col_set_num;
-	GtkTreeIter row;
-	gint col_num;
+	BraseroTrack *track;
+	GtkTreePath *treepath;
+	BraseroSessionCfg *session;
+
+	tag = g_object_get_data (G_OBJECT (renderer), COL_KEY);
 
-	col_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), COL_KEY));
-	col_set_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), COL_KEY_SET));
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
 	treepath = gtk_tree_path_new_from_string (path_string);
-	gtk_tree_model_get_iter (model, &row, treepath);
-	gtk_list_store_set (GTK_LIST_STORE (model), &row,
-			    col_num, text,
-			    col_set_num, TRUE,
-			    -1);
+	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
+	brasero_track_tag_add_string (BRASERO_TRACK (track),
+				      tag,
+				      text);
 	disc->priv->editing = 0;
 }
 
@@ -2655,7 +1210,6 @@ static void
 brasero_audio_disc_add_pause (BraseroAudioDisc *disc)
 {
 	GtkTreeSelection *selection;
-	GtkTreeRowReference *ref;
 	GtkTreePath *treepath;
 	GtkTreeModel *model;
 	GList *references = NULL;
@@ -2669,6 +1223,8 @@ brasero_audio_disc_add_pause (BraseroAudioDisc *disc)
 	/* since we are going to modify the model, we need to convert all these
 	 * into row references */
 	for (iter = selected; iter; iter = iter->next) {
+		GtkTreeRowReference *ref;
+
 		treepath = iter->data;
 		ref = gtk_tree_row_reference_new (model, treepath);
 		references = g_list_append (references, ref);
@@ -2678,23 +1234,13 @@ brasero_audio_disc_add_pause (BraseroAudioDisc *disc)
 	g_list_free (selected);
 
 	for (iter = references; iter; iter = iter->next) {
-		GtkTreeIter row;
+		GtkTreeRowReference *ref;
 
 		ref = iter->data;
 		treepath = gtk_tree_row_reference_get_path (ref);
 		gtk_tree_row_reference_free (ref);
 
-		if (gtk_tree_model_get_iter (model, &row, treepath)) {
-			gboolean is_song;
-
-			gtk_tree_model_get (model, &row,
-					    SONG_COL, &is_song,
-					    -1);
-
-			if (is_song)
-				brasero_audio_disc_add_gap (disc, &row, 2 * GST_SECOND);
-		}
-
+		brasero_audio_disc_add_gap (disc, treepath, 2 * GST_SECOND);
 		gtk_tree_path_free (treepath);
 	}
 
@@ -2710,30 +1256,16 @@ brasero_audio_disc_add_pause_cb (GtkAction *action,
 
 static void
 brasero_audio_disc_add_slices (BraseroAudioDisc *disc,
-			       GtkTreeIter *parent,
+			       GtkTreePath *treepath,
 			       GSList *slices)
 {
+	BraseroSessionCfg *session;
+	BraseroStreamFormat format;
 	BraseroAudioSlice *slice;
+	BraseroTrack *track;
 	GtkTreeModel *model;
-	GtkTreeIter row;
-	gchar *string;
-	gint64 length;
 	GSList *iter;
-
-	gboolean title_set;
-	gboolean artist_set;
-	gboolean composer_set;
-	gboolean isrc_set;
-
-	gint64 start;
-	gint64 end;
-
 	gchar *uri;
-	gchar *isrc;
-	gchar *name;
-	gchar *artist;
-	gchar *composer;
-	gchar *icon_string;
 
 	if (!slices)
 		return;
@@ -2742,88 +1274,53 @@ brasero_audio_disc_add_slices (BraseroAudioDisc *disc,
 	slice = slices->data;
 
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
+	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
 
-	gtk_tree_model_get (model, parent,
-			    NAME_COL, &name,
-			    TITLE_SET_COL, &title_set,
-			    ICON_COL, &icon_string,
-			    ARTIST_COL, &artist,
-			    ARTIST_SET_COL, &artist_set,
-			    COMPOSER_COL, &composer,
-			    COMPOSER_SET_COL, &composer_set,
-			    ISRC_COL, &isrc,
-			    ISRC_SET_COL, &isrc_set,
-			    URI_COL, &uri,
-			    LENGTH_COL, &length,
-			    START_COL, &start,
-			    END_COL, &end,
-			    -1);
-	disc->priv->sectors -= BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (start, end));
-
-	string = brasero_units_get_time_string (BRASERO_STREAM_LENGTH (slice->start, slice->end), TRUE, FALSE); 
-	gtk_list_store_set (GTK_LIST_STORE (model), parent,
-			    LENGTH_SET_COL, TRUE,
-			    START_COL, slice->start,
-			    END_COL, slice->end,
-			    SIZE_COL, string,
-			    -1);
-	g_free (string);
-	disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (slice->start, slice->end));
+	brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+					     slice->start,
+					     slice->end,
+					     -1);
+
+	uri = brasero_track_stream_get_source (BRASERO_TRACK_STREAM (track), TRUE);
+	format = brasero_track_stream_get_format (BRASERO_TRACK_STREAM (track));
 
 	for (iter = slices->next; iter; iter = iter->next) {
-		slice = iter->data;
+		BraseroTrackStream *new_track;
 
-		gtk_list_store_insert_after (GTK_LIST_STORE (model), &row, parent);
-		gtk_tree_model_iter_next (model, parent);
-
-		string = brasero_units_get_time_string (BRASERO_STREAM_LENGTH (slice->start, slice->end), TRUE, FALSE); 
-		gtk_list_store_set (GTK_LIST_STORE (model), &row,
-				    URI_COL, uri,
-				    NAME_COL, name,
-				    TITLE_SET_COL, title_set,
-				    ICON_COL, icon_string,
-				    ARTIST_COL, artist,
-				    ARTIST_SET_COL, artist_set,
-				    COMPOSER_COL, composer,
-				    COMPOSER_SET_COL, composer_set,
-				    ISRC_COL, isrc,
-				    ISRC_SET_COL, isrc_set,
-				    SONG_COL, TRUE,
-				    LENGTH_SET_COL, TRUE,
-				    START_COL, slice->start,
-				    END_COL, slice->end,
-				    SIZE_COL, string,
-				    LENGTH_COL, length,
-				    -1);
-		g_free (string);
+		slice = iter->data;
 
-		disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (slice->start, slice->end));
+		new_track = brasero_track_stream_new ();
+		brasero_track_stream_set_source (new_track, uri);
+		brasero_track_stream_set_format (new_track, format);
+		brasero_track_stream_set_boundaries (new_track,
+						     slice->start,
+						     slice->end,
+						     brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track)));
+		brasero_track_tag_copy_missing (BRASERO_TRACK (new_track),
+						BRASERO_TRACK (track));
+		brasero_burn_session_add_track (BRASERO_BURN_SESSION (session),
+						BRASERO_TRACK (new_track),
+						BRASERO_TRACK (track));
 	}
 
-	g_free (icon_string);
-	g_free (composer);
-	g_free (artist);
-	g_free (name);
 	g_free (uri);
-
-	brasero_disc_size_changed (BRASERO_DISC (disc), disc->priv->sectors);
 }
 
 static void
 brasero_audio_disc_split (BraseroAudioDisc *disc)
 {
 	GtkTreeSelection *selection;
+	BraseroSessionCfg *session;
 	GtkTreePath *treepath;
 	GtkTreeModel *model;
-	GtkTreeIter row;
+	BraseroTrack *track;
 
 	GtkResponseType response;
 	GtkWidget *toplevel;
 	GtkWidget *dialog;
 	GList *selected;
 	GSList *slices;
-	gint64 start;
-	gint64 end;
 	gchar *uri;
 
 	/* get the URIs */
@@ -2846,18 +1343,9 @@ brasero_audio_disc_split (BraseroAudioDisc *disc)
 	treepath = selected->data;
 	g_list_free (selected);
 
-	if (!gtk_tree_model_get_iter (model, &row, treepath)) {
-		gtk_tree_path_free (treepath);
-		return;
-	}
-	gtk_tree_path_free (treepath);
-
 	/* NOTE: this is necessarily a song since otherwise button is grey */
-	gtk_tree_model_get (model, &row,
-			    URI_COL, &uri,
-			    START_COL, &start,
-			    END_COL, &end,
-			    -1);
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
+	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
 
 	dialog = brasero_split_dialog_new ();
 	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (disc));
@@ -2865,24 +1353,28 @@ brasero_audio_disc_split (BraseroAudioDisc *disc)
 	gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
 	gtk_window_set_position (GTK_WINDOW (toplevel), GTK_WIN_POS_CENTER_ON_PARENT);
 
+	uri = brasero_track_stream_get_source (BRASERO_TRACK_STREAM (track), TRUE);
 	brasero_split_dialog_set_uri (BRASERO_SPLIT_DIALOG (dialog), uri);
-	brasero_split_dialog_set_boundaries (BRASERO_SPLIT_DIALOG (dialog),
-					     start,
-					     end);
 	g_free (uri);
 
+	brasero_split_dialog_set_boundaries (BRASERO_SPLIT_DIALOG (dialog),
+					     brasero_track_stream_get_start (BRASERO_TRACK_STREAM (track)),
+					     brasero_track_stream_get_end (BRASERO_TRACK_STREAM (track)));
+
 	response = gtk_dialog_run (GTK_DIALOG (dialog));
 	if (response != GTK_RESPONSE_OK) {
 		gtk_widget_destroy (dialog);
+		gtk_tree_path_free (treepath);
 		return;
 	}
 
 	slices = brasero_split_dialog_get_slices (BRASERO_SPLIT_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
 
-	brasero_audio_disc_add_slices (disc, &row, slices);
+	brasero_audio_disc_add_slices (disc, treepath, slices);
 	g_slist_foreach (slices, (GFunc) g_free, NULL);
 	g_slist_free (slices);
+	gtk_tree_path_free (treepath);
 }
 
 static void
@@ -2945,12 +1437,12 @@ brasero_audio_disc_selection_changed (GtkTreeSelection *selection,
 
 		treepath = iter->data;
 		if (gtk_tree_model_get_iter (model, &row, treepath)) {
-			gboolean is_song;
+			gboolean is_gap;
 
 			gtk_tree_model_get (model, &row,
-					    SONG_COL, &is_song,
+					    BRASERO_VIDEO_TREE_MODEL_IS_GAP, &is_gap,
 					    -1);
-			if (is_song) {
+			if (!is_gap) {
 				selected_num ++;
 
 				gtk_action_set_sensitive (action_open, TRUE);
@@ -2975,8 +1467,6 @@ static void
 brasero_audio_disc_open_file (BraseroAudioDisc *disc)
 {
 	char *uri;
-	gboolean success;
-	GtkTreeIter iter;
 	GList *item, *list;
 	GSList *uris = NULL;
 	GtkTreeModel *model;
@@ -2987,15 +1477,16 @@ brasero_audio_disc_open_file (BraseroAudioDisc *disc)
 	list = gtk_tree_selection_get_selected_rows (selection, &model);
 
 	for (item = list; item; item = item->next) {
+                BraseroTrack *track;
+
 		treepath = item->data;
-		success = gtk_tree_model_get_iter (model, &iter, treepath);
+                track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
 		gtk_tree_path_free (treepath);
 
-		if (!success)
+		if (!track)
 			continue;
 
-		gtk_tree_model_get (model, &iter,
-				    URI_COL, &uri, -1);
+		uri = brasero_track_stream_get_source (BRASERO_TRACK_STREAM (track), TRUE);
 
 		if (uri)
 			uris = g_slist_prepend (uris, uri);
@@ -3014,10 +1505,18 @@ brasero_audio_disc_rename_songs (GtkTreeModel *model,
 				 const gchar *old_name,
 				 const gchar *new_name)
 {
-	gtk_list_store_set (GTK_LIST_STORE (model), iter,
-			    NAME_COL, new_name,
-			    TITLE_SET_COL, TRUE,
-			    -1);
+	BraseroSessionCfg *session;
+	BraseroTrack *track;
+
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
+	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
+
+	brasero_track_tag_add_string (track,
+				      BRASERO_TRACK_STREAM_TITLE_TAG,
+				      new_name);
+
+	/* Update the view */
+	brasero_track_changed (track);
 	return TRUE;
 }
 
@@ -3056,7 +1555,7 @@ brasero_audio_disc_edit_multi_song_properties (BraseroAudioDisc *disc,
 
 	brasero_multi_song_props_set_rename_callback (BRASERO_MULTI_SONG_PROPS (props),
 						      gtk_tree_view_get_selection (GTK_TREE_VIEW (disc->priv->tree)),
-						      NAME_COL,
+						      BRASERO_VIDEO_TREE_MODEL_NAME,
 						      brasero_audio_disc_rename_songs);
 
 	brasero_multi_song_props_get_properties (BRASERO_MULTI_SONG_PROPS (props),
@@ -3071,40 +1570,43 @@ brasero_audio_disc_edit_multi_song_properties (BraseroAudioDisc *disc,
 	copy = g_list_reverse (copy);
 	for (item = copy; item; item = item->next) {
 		GtkTreePath *treepath;
+		BraseroTrack *track;
 		GtkTreeIter iter;
-		gboolean is_song;
+		gboolean is_gap;
 
 		treepath = item->data;
-		if (!gtk_tree_model_get_iter (model, &iter, treepath))
-			continue;
-
+                gtk_tree_model_get_iter (model, &iter, treepath);
 		gtk_tree_model_get (model, &iter,
-				    SONG_COL, &is_song,
+				    BRASERO_VIDEO_TREE_MODEL_IS_GAP, &is_gap,
 				    -1);
 
-		if (!is_song)
+		if (is_gap)
+			continue;
+
+                track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
+		if (!track)
 			continue;
 
 		if (artist)
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    ARTIST_COL, artist,
-					    ARTIST_SET_COL, TRUE,
-					    -1);
+                        brasero_track_tag_add_string (BRASERO_TRACK (track),
+                                                      BRASERO_TRACK_STREAM_ARTIST_TAG,
+                                                      artist);
 
 		if (composer)
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    COMPOSER_COL, composer,
-					    COMPOSER_SET_COL, TRUE,
-					    -1);
+                        brasero_track_tag_add_string (BRASERO_TRACK (track),
+                                                      BRASERO_TRACK_STREAM_COMPOSER_TAG,
+                                                      composer);
 
 		if (isrc > 0)
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    ISRC_COL, isrc,
-					    ISRC_SET_COL, TRUE,
-					    -1);
+                        brasero_track_tag_add_int (BRASERO_TRACK (track),
+                                                   BRASERO_TRACK_STREAM_ISRC_TAG,
+                                                   isrc);
 
-		if (gap > -1)
-			brasero_audio_disc_add_gap (disc, &iter, gap);
+                if (gap > -1)
+                        brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+                                                                                       -1,
+                                                                                       -1,
+                                                                                       gap);
 	}
 	g_list_free (copy);
 	g_free (artist);
@@ -3121,77 +1623,44 @@ brasero_audio_disc_edit_single_song_properties (BraseroAudioDisc *disc,
 	gint isrc;
 	gint64 end;
 	gint64 start;
-	gint track_num;
+	guint track_num;
 	GtkWidget *props;
-	gchar *length_str;
 	GtkWidget *toplevel;
 	GtkTreeModel *model;
+	BraseroTrack *track;
 	GtkResponseType result;
-	gint64 length;
-	gboolean is_song;
-	gboolean success;
+	BraseroSessionCfg *session;
+	guint64 length;
 	gchar *title;
 	gchar *artist;
 	gchar *composer;
 	GtkTreeIter iter;
-	gchar *track_num_str;
-	GtkTreeIter gap_iter;
 
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	success = gtk_tree_model_get_iter (model, &iter, treepath);
-	if (!success)
-		return;
-
-	gtk_tree_model_get (model, &iter,
-			    SONG_COL, &is_song,
-			    -1);
-	if (!is_song)
+	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
+        track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), treepath);
+	if (!track)
 		return;
 
-	/* get all information */
-	gtk_tree_model_get (model, &iter,
-			    NAME_COL, &title,
-			    ARTIST_COL, &artist,
-			    COMPOSER_COL, &composer,
-			    TRACK_NUM_COL, &track_num_str,
-			    ISRC_COL, &isrc,
-			    END_COL, &end,
-			    START_COL, &start,
-			    LENGTH_COL, &length,
-			    -1);
-
-	if (brasero_audio_disc_has_gap (disc, &iter, &gap_iter))
-		gtk_tree_model_get (model, &gap_iter,
-				    LENGTH_COL, &gap,
-				    -1);
-	else
-		gap = 0;
-
-	if (track_num_str) {
-		track_num = (gint) g_strtod (track_num_str + 6 /* (ignore markup) */, NULL);
-		g_free (track_num_str);
-	}
-	else
-		track_num = 0;
+        /* information about the track */
+        gtk_tree_model_get_iter (model, &iter, treepath);
+        gtk_tree_model_get (model, &iter,
+                                         BRASERO_VIDEO_TREE_MODEL_INDEX_NUM, &track_num,
+                                         -1);
+        brasero_track_stream_get_length (BRASERO_TRACK_STREAM (track), &length);
 
 	/* set up dialog */
 	props = brasero_song_props_new ();
 	brasero_song_props_set_properties (BRASERO_SONG_PROPS (props),
 					   track_num,
-					   artist,
-					   title,
-					   composer,
-					   isrc,
+					   brasero_track_tag_lookup_string (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_ARTIST_TAG),
+					   brasero_track_tag_lookup_string (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_TITLE_TAG),
+					   brasero_track_tag_lookup_string (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_COMPOSER_TAG),
+					   brasero_track_tag_lookup_int (BRASERO_TRACK (track), BRASERO_TRACK_STREAM_ISRC_TAG),
 					   length,
-					   start,
-					   end,
-					   gap);
-	if (artist)
-		g_free (artist);
-	if (title)
-		g_free (title);
-	if (composer)
-		g_free (composer);
+					   brasero_track_stream_get_start (BRASERO_TRACK_STREAM (track)),
+					   brasero_track_stream_get_end (BRASERO_TRACK_STREAM (track)),
+					   brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track)));
 
 	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (disc));
 	gtk_window_set_transient_for (GTK_WINDOW (props),
@@ -3208,7 +1677,6 @@ brasero_audio_disc_edit_single_song_properties (BraseroAudioDisc *disc,
 		return;
 	}
 
-	disc->priv->sectors -= BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (start, end));
 	brasero_song_props_get_properties (BRASERO_SONG_PROPS (props),
 					   &artist,
 					   &title,
@@ -3218,55 +1686,34 @@ brasero_audio_disc_edit_single_song_properties (BraseroAudioDisc *disc,
 					   &end,
 					   &gap);
 
-	length_str = brasero_units_get_time_string (BRASERO_STREAM_LENGTH (start, end), TRUE, FALSE);
-
-	gtk_tree_model_get_iter (model, &iter, treepath);
-	gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-			    LENGTH_SET_COL, TRUE,
-			    START_COL, start,
-			    END_COL, end,
-			    SIZE_COL, length_str,
-			    -1);
-	g_free (length_str);
-
-	if (title) {
-		gchar *markup;
+	brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+                                                                      start,
+                                                                      end,
+                                                                      BRASERO_SECTORS_TO_TIME (gap));
 
-		markup = g_markup_escape_text (title, -1);
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    NAME_COL, markup,
-				    TITLE_SET_COL, TRUE,
-				    -1);
-		g_free (markup);
-	}
+	if (title)
+		brasero_track_tag_add_string (BRASERO_TRACK (track),
+					      BRASERO_TRACK_STREAM_TITLE_TAG,
+					      title);
 
 	if (artist)
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    ARTIST_COL, artist,
-				    ARTIST_SET_COL, TRUE,
-				    -1);
+		brasero_track_tag_add_string (BRASERO_TRACK (track),
+					      BRASERO_TRACK_STREAM_ARTIST_TAG,
+					      artist);
 
 	if (composer)
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    COMPOSER_COL, composer,
-				    COMPOSER_SET_COL, TRUE,
-				    -1);
+		brasero_track_tag_add_string (BRASERO_TRACK (track),
+					      BRASERO_TRACK_STREAM_COMPOSER_TAG,
+					      composer);
 
-	if (isrc)
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-				    ISRC_COL, isrc,
-				    ISRC_SET_COL, TRUE,
-				    -1);
+	if (isrc > 0)
+		brasero_track_tag_add_int (BRASERO_TRACK (track),
+					   BRASERO_TRACK_STREAM_ISRC_TAG,
+					   isrc);
 
 	if (end - start + BRASERO_SECTORS_TO_TIME (gap) < BRASERO_MIN_STREAM_LENGTH)
 		brasero_audio_disc_short_track_dialog (disc);
 
-	if (gap)
-		brasero_audio_disc_add_gap (disc, &iter, gap);
-
-	disc->priv->sectors += BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (start, end));
-	brasero_audio_disc_size_changed (disc);
-
 	g_free (title);
 	g_free (artist);
 	g_free (composer);
@@ -3291,17 +1738,17 @@ brasero_audio_disc_edit_song_properties (BraseroAudioDisc *disc,
 	song_num = 0;
 	for (item = list; item; item = item->next) {
 		GtkTreePath *tmp;
+		gboolean is_gap;
 		GtkTreeIter iter;
-		gboolean is_song;
 
 		tmp = item->data;
 
 		gtk_tree_model_get_iter (model, &iter, tmp);
 		gtk_tree_model_get (model, &iter, 
-				    SONG_COL, &is_song,
+				    BRASERO_VIDEO_TREE_MODEL_IS_GAP, &is_gap,
 				    -1);
 
-		if (is_song) {
+		if (!is_gap) {
 			song_num ++;
 			real_list = g_list_prepend (real_list, tmp);
 		}
@@ -3571,7 +2018,7 @@ static gboolean
 brasero_audio_disc_get_selected_uri (BraseroDisc *disc,
 				     gchar **uri)
 {
-	GtkTreeIter iter;
+	BraseroTrack *track;
 	GtkTreeModel *model;
 	BraseroAudioDisc *audio;
 
@@ -3584,13 +2031,15 @@ brasero_audio_disc_get_selected_uri (BraseroDisc *disc,
 
 	/* we are asked for just one uri so return the first one */
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (audio->priv->tree));
-	if (!gtk_tree_model_get_iter (model, &iter, audio->priv->selected_path)) {
+        track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model),
+                                                                                       audio->priv->selected_path);
+        if (!track) {
 		gtk_tree_path_free (audio->priv->selected_path);
 		audio->priv->selected_path = NULL;
 		return FALSE;
 	}
 
-	gtk_tree_model_get (model, &iter, URI_COL, uri, -1);
+	*uri = brasero_track_stream_get_source (BRASERO_TRACK_STREAM (track), TRUE);
 	return TRUE;
 }
 
@@ -3599,7 +2048,7 @@ brasero_audio_disc_get_boundaries (BraseroDisc *disc,
 				   gint64 *start,
 				   gint64 *end)
 {
-	GtkTreeIter iter;
+	BraseroTrack *track;
 	GtkTreeModel *model;
 	BraseroAudioDisc *audio;
 
@@ -3609,624 +2058,46 @@ brasero_audio_disc_get_boundaries (BraseroDisc *disc,
 
 	/* we are asked for just one uri so return the first one */
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (audio->priv->tree));
-	if (!gtk_tree_model_get_iter (model, &iter, audio->priv->selected_path)) {
+        track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model),
+                                                                                       audio->priv->selected_path);
+        if (!track) {
 		gtk_tree_path_free (audio->priv->selected_path);
 		audio->priv->selected_path = NULL;
 		return FALSE;
 	}
 
-	gtk_tree_model_get (model, &iter,
-			    START_COL, start,
-			    END_COL, end,
-			    -1);
+        *start = brasero_track_stream_get_start (BRASERO_TRACK_STREAM (track));
+        *end = brasero_track_stream_get_end (BRASERO_TRACK_STREAM (track));
 	return TRUE;
 }
 
-/********************************** Monitoring *********************************/
-#ifdef BUILD_INOTIFY
-
-struct _BraseroMonitoredRemoveData {
-	BraseroAudioDisc *disc;
-	gchar *uri;
-};
-typedef struct _BraseroMonitoredRemoveData BraseroMonitoredRemoveData;
-
-struct _BraseroMonitoredDir {
-	gint ref;
-	gchar *uri;
-};
-typedef struct _BraseroMonitoredDir BraseroMonitoredDir;
-
-static void
-brasero_audio_disc_inotify_free_monitored (gpointer data)
-{
-	BraseroMonitoredDir *dir = data;
-
-	g_free (dir->uri);
-	g_free (dir);
-}
-
-static void
-brasero_audio_disc_start_monitoring (BraseroAudioDisc *disc,
-				     const gchar *uri)
-{
-	if (!disc->priv->monitored)
-		disc->priv->monitored = g_hash_table_new_full (g_direct_hash,
-							       g_direct_equal,
-							       NULL,
-							       brasero_audio_disc_inotify_free_monitored);
-
-	if (disc->priv->notify && !strncmp (uri, "file://", 7)) {
-		BraseroMonitoredDir *dir;
-		gchar *parent;
-		int dev_fd;
-		char *path;
-		uint32_t mask;
-		int wd;
-
-		/* we want to be able to catch files being renamed in the same
-		 * directory that's why we watch the parent directory instead 
-		 * of the file itself. Another advantage is that it saves wds
-		 * if several files are in the same directory. */
-		parent = g_path_get_dirname (uri);
-		dir = g_hash_table_lookup (disc->priv->monitored, parent);
-		if (dir) {
-			/* no need to add a watch, parent directory
-			 * is already being monitored */
-			g_free (parent);
-			dir->ref ++;
-			return;
-		}
-
-		dir = g_new0 (BraseroMonitoredDir, 1);
-		dir->uri = parent;
-		dir->ref = 1;
-
-		dev_fd = g_io_channel_unix_get_fd (disc->priv->notify);
-		mask = IN_MODIFY |
-		       IN_ATTRIB |
-		       IN_MOVED_FROM |
-		       IN_MOVED_TO |
-		       IN_DELETE |
-		       IN_DELETE_SELF |
-		       IN_MOVE_SELF |
-		       IN_UNMOUNT;
-
-	    	path = g_filename_from_uri (parent, NULL, NULL);
-		wd = inotify_add_watch (dev_fd, path, mask);
-		if (wd == -1) {
-			g_warning ("ERROR creating watch for local file %s : %s\n",
-				   parent,
-				   g_strerror (errno));
-
-			g_free (parent);
-			g_free (dir);
-		}
-		else
-			g_hash_table_insert (disc->priv->monitored,
-					     GINT_TO_POINTER (wd),
-					     dir);
-		g_free (path);
-	}
-}
-
-static gboolean
-_foreach_monitored_remove_uri_cb (int wd,
-				  BraseroMonitoredDir *dir,
-				  BraseroMonitoredRemoveData *data)
-{
-	gint dev_fd;
-
-	if (strcmp (data->uri, dir->uri))
-		return FALSE;
-
-	dir->ref --;
-	if (dir->ref)
-		return FALSE;
-
-	/* we can now safely remove the watch */
-	dev_fd = g_io_channel_unix_get_fd (data->disc->priv->notify);
-	inotify_rm_watch (dev_fd, wd);
-	return TRUE;
-}
-
-static void
-brasero_audio_disc_cancel_monitoring (BraseroAudioDisc *disc,
-				      const char *uri)
-{
-	BraseroMonitoredRemoveData callback_data;
-
-	if (!disc->priv->notify)
-		return;
-
-	callback_data.uri = g_path_get_dirname (uri);
-	callback_data.disc = disc;
-
-	if (disc->priv->monitored)
-		g_hash_table_foreach_remove (disc->priv->monitored,
-					     (GHRFunc) _foreach_monitored_remove_uri_cb,
-					     &callback_data);
-
-	g_free (callback_data.uri);
-}
-
-static void
-brasero_audio_disc_inotify_removal_warning (BraseroAudioDisc *disc,
-					    const gchar *uri)
-{
-	gchar *name;
-	gchar *primary;
-
-	BRASERO_GET_BASENAME_FOR_DISPLAY (uri, name);
-
-	/* Translators: "%s" is the name of a file here */
-	primary = g_strdup_printf (_("\"%s\" was removed from the file system."), name);
-	brasero_app_alert (brasero_app_get_default (),
-			   primary,
-			   /* Translators: This is when brasero detects that a file
-			    * in the audio project was removed from its original 
-			    * location (on a hard drive, USB stick, whatever) so
-			    * it removes the file from the project (not from its
-			    * original location) and lets the user know. The "It"
-			    * refers to the file and this string is coupled with
-			    * previous string:
-			    * ""\"%s\" was removed from the file system."*/
-			   _("It will be removed from the project"),
-			   GTK_MESSAGE_WARNING);
-	g_free (primary);
-	g_free (name);
-}
-
-static void
-brasero_audio_disc_inotify_remove_all (BraseroAudioDisc *disc,
-				       BraseroMonitoredDir *dir,
-				       gint32 wd)
-{
-	gint len;
-	gint dev_fd;
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-
-	brasero_audio_disc_inotify_removal_warning (disc, dir->uri);
-
-	/* it's the same as below except that we remove all children of uri */
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	if (gtk_tree_model_get_iter_first (model, &iter))
-		return;
-
-	len = strlen (dir->uri);
-	do {
-		gint64 end;
-		gint64 start;
-		gchar *row_uri;
-
-		gtk_tree_model_get (model, &iter,
-				    URI_COL, &row_uri,
-				    START_COL, &start,
-				    END_COL, &end,
-				    -1);
-
-		if (row_uri && !strncmp (row_uri, dir->uri, len)) {
-			if (end - start > 0)
-				disc->priv->sectors -= BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (start, end));
-
-			if (!gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) {
-				g_free (row_uri);
-				break;
-			}
-		}
-
-		g_free (row_uri);
-	} while (gtk_tree_model_iter_next (model, &iter));
-
-	brasero_audio_disc_size_changed (disc);
-
-	/* remove the monitored directory and stop the watch */
-	g_hash_table_remove (disc->priv->monitored, GINT_TO_POINTER (wd));
-
-	dev_fd = g_io_channel_unix_get_fd (disc->priv->notify);
-	inotify_rm_watch (dev_fd, wd);
-}
-
-static GSList *
-brasero_audio_disc_inotify_find_rows (BraseroAudioDisc *disc,
-				      const char *uri)
-{
-	GtkTreePath *treepath;
-	GtkTreeModel *model;
-	GSList *list = NULL;
-	GtkTreeIter iter;
-	gchar *row_uri;
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	if (!gtk_tree_model_get_iter_first (model, &iter))
-		return NULL;
-
-	do {
-		gtk_tree_model_get (model, &iter,
-				    URI_COL, &row_uri,
-				    -1);
-
-		if (row_uri && !strcmp (uri, row_uri)) {
-			treepath = gtk_tree_model_get_path (model, &iter);
-
-			/* NOTE: prepend is better here since last found will be
-			 * the first in the list. That way when deleting rows the
-			 * paths we delete last will be valid since they are at 
-			 * the top in treeview */
-			list = g_slist_prepend (list, treepath);
-		}
-
-		g_free (row_uri);
-	} while (gtk_tree_model_iter_next (model, &iter));
-
-	return list;
-}
-
-static void
-brasero_audio_disc_inotify_remove (BraseroAudioDisc *disc,
-				   const gchar *uri)
-{
-	GtkTreeModel *model;
-	GSList *list,*iter_list;
-
-	list = brasero_audio_disc_inotify_find_rows (disc, uri);
-	if (!list)
-		return;
-
-	brasero_audio_disc_inotify_removal_warning (disc, uri);
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	for (iter_list = list; iter_list; iter_list = iter_list->next) {
-		GtkTreePath *treepath;
-		GtkTreeIter iter;
-		gint64 start;
-		gint64 end;
-
-		treepath = iter_list->data;
-
-		gtk_tree_model_get_iter (model, &iter, treepath);
-		gtk_tree_model_get (model, &iter,
-				    START_COL, &start,
-				    END_COL, &end,
-				    -1);
-
-		if (end - start > 0)
-			disc->priv->sectors -= BRASERO_DURATION_TO_SECTORS (BRASERO_STREAM_LENGTH (start, end));
-
-		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-	}
-
-	g_slist_foreach (list, (GFunc) gtk_tree_path_free, NULL);
-	g_slist_free (list);
-
-	brasero_audio_disc_size_changed (disc);
-	brasero_audio_disc_cancel_monitoring (disc, uri);
-}
-
 static void
-brasero_audio_disc_inotify_modify_result (GObject *object,
-					  GError *error,
-					  const gchar *uri,
-					  GFileInfo *info,
-					  gpointer callback_data)
+brasero_audio_disc_class_init (BraseroAudioDiscClass *klass)
 {
-	BraseroAudioDisc *disc = BRASERO_AUDIO_DISC (object);
-	GSList *list, *list_iter;
-	GtkTreeModel *model;
-
-	list = brasero_audio_disc_inotify_find_rows (disc, uri);
-	if (!list)
-		return;
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	for (list_iter = list; list_iter; list_iter = list_iter->next) {
-		GtkTreePath *treepath;
-		GtkTreeIter iter;
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-		treepath = list_iter->data;
-		gtk_tree_model_get_iter (model, &iter, treepath);
+	parent_class = g_type_class_peek_parent (klass);
+	object_class->finalize = brasero_audio_disc_finalize;
+	object_class->set_property = brasero_audio_disc_set_property;
+	object_class->get_property = brasero_audio_disc_get_property;
 
-		if (error)
-			brasero_audio_disc_remove (disc, treepath);
-		else
-			brasero_audio_disc_set_row_from_metadata (disc,
-								  model,
-								  &iter,
-								  info);
-	}
-	g_slist_foreach (list, (GFunc) gtk_tree_path_free, NULL);
-	g_slist_free (list);
+	g_object_class_install_property (object_class,
+					 PROP_REJECT_FILE,
+					 g_param_spec_boolean
+					 ("reject-file",
+					  "Whether it accepts files",
+					  "Whether it accepts files",
+					  FALSE,
+					  G_PARAM_READWRITE));
 }
 
-static gboolean
-brasero_audio_disc_inotify_move_timeout (BraseroAudioDisc *audio)
+GtkWidget *
+brasero_audio_disc_new ()
 {
-	BraseroInotifyMovedData *data;
-
-	/* an IN_MOVED_FROM timed out. It is the first in the queue. */
-	data = audio->priv->moved_list->data;
-	audio->priv->moved_list = g_slist_remove (audio->priv->moved_list, data);
-	brasero_audio_disc_inotify_remove (audio, data->uri);
-
-	/* clean up */
-	g_free (data->uri);
-	g_free (data);
+	BraseroAudioDisc *obj;
 	
-	return FALSE;
-}
-
-static void
-brasero_audio_disc_inotify_move (BraseroAudioDisc *disc,
-				 struct inotify_event *event,
-				 const gchar *uri)
-{
-	BraseroInotifyMovedData *data = NULL;
-
-	if (!event->cookie) {
-		brasero_audio_disc_inotify_remove (disc, uri);
-		return;
-	}
-
-	if (event->mask & IN_MOVED_FROM) {
-		data = g_new0 (BraseroInotifyMovedData, 1);
-		data->cookie = event->cookie;
-		data->uri = g_strdup (uri);
-			
-		/* we remember this move for 5s. If 5s later we haven't received
-		 * a corresponding MOVED_TO then we consider the file was
-		 * removed. */
-		data->id = g_timeout_add_seconds (5,
-						  (GSourceFunc) brasero_audio_disc_inotify_move_timeout,
-						  disc);
-
-		/* NOTE: the order is important, we _must_ append them */
-		disc->priv->moved_list = g_slist_append (disc->priv->moved_list, data);
-	}
-	else {
-		GSList *iter;
-
-		for (iter = disc->priv->moved_list; iter; iter = iter->next) {
-			data = iter->data;
-			if (data->cookie == event->cookie)
-				break;
-
-			data = NULL;
-		}
-
-		if (data) {
-			GSList *paths;
-
-			/* we've got one match:
-			 * - remove from the list
-			 * - remove the timeout
-			 * - change all the uris with the new one */
-			disc->priv->moved_list = g_slist_remove (disc->priv->moved_list, data);
-			paths = brasero_audio_disc_inotify_find_rows (disc, data->uri);
-
-			/* we are only interested if the destination is in our tree
-			 * then that means the file was modified */
-			if (!disc->priv->reload_uri)
-				disc->priv->reload_uri = brasero_io_register (G_OBJECT (disc),
-									      brasero_audio_disc_inotify_modify_result,
-									      NULL,
-									      NULL);
-
-			brasero_io_get_file_info (uri,
-						  disc->priv->reload_uri,
-						  BRASERO_IO_INFO_PERM|
-						  BRASERO_IO_INFO_MIME|
-						  BRASERO_IO_INFO_URGENT|
-						  BRASERO_IO_INFO_METADATA|
-						  BRASERO_IO_INFO_METADATA_MISSING_CODEC,
-						  NULL);
-
-			/* clean up the mess */
-			g_slist_foreach (paths, (GFunc) gtk_tree_path_free, NULL);
-			g_slist_free (paths);
-
-			g_source_remove (data->id);
-			g_free (data->uri);
-			g_free (data);
-		}
-	}
-}
-
-static void
-brasero_audio_disc_inotify_attributes_changed_cb (GObject *obj,
-						  GError *error,
-						  const gchar *uri,
-						  GFileInfo *info,
-						  gpointer null_data)
-{
-	gboolean readable;
-	BraseroAudioDisc *disc = BRASERO_AUDIO_DISC (obj);
-
-	if (error)
-		readable = FALSE;
-	else if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
-		readable = TRUE;
-	else
-		readable = FALSE;
-
-	if (!readable)
-		brasero_audio_disc_inotify_remove (disc, uri);
-}
-
-static gboolean
-brasero_audio_disc_inotify_attributes_changed (BraseroAudioDisc *disc,
-					       const gchar *uri)
-{
-	if (!disc->priv->attr_changed)
-		disc->priv->attr_changed = brasero_io_register (G_OBJECT (disc),
-								brasero_audio_disc_inotify_attributes_changed_cb,
-								brasero_audio_disc_vfs_operation_finished,
-								NULL);
-
-	brasero_audio_disc_increase_activity_counter (disc);
-	brasero_io_get_file_info (uri,
-				  disc->priv->attr_changed,
-				  BRASERO_IO_INFO_PERM,
-				  NULL);
-	return TRUE;
-}
-
-static gboolean
-brasero_audio_disc_inotify_is_in_selection (BraseroAudioDisc *disc,
-					    const char *uri)
-{
-	GtkTreeModel *model;
-	GtkTreeIter iter;
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (disc->priv->tree));
-	if (gtk_tree_model_get_iter_first (model, &iter))
-		return FALSE;
-
-	do {
-		gchar *row_uri;
-
-		gtk_tree_model_get (model, &iter,
-				    URI_COL, &row_uri,
-				    -1);
-
-		if (!strcmp (uri, row_uri)) {
-			g_free (row_uri);
-			return TRUE;
-		}
-
-		g_free (row_uri);
-	} while (gtk_tree_model_iter_next (model, &iter));
-
-	return FALSE;
+	obj = BRASERO_AUDIO_DISC (g_object_new (BRASERO_TYPE_AUDIO_DISC, NULL));
+	
+	return GTK_WIDGET (obj);
 }
 
-static gboolean
-brasero_audio_disc_inotify_monitor_cb (GIOChannel *channel,
-				       GIOCondition condition,
-				       BraseroAudioDisc *disc)
-{
-	struct inotify_event event;
-	BraseroMonitoredDir *dir;
-	GError *err = NULL;
-	GIOStatus status;
-	gchar *monitored;
-	gchar *name;
-	gsize size;
-
-	while (condition & G_IO_IN) {
-		monitored = NULL;
-
-		status = g_io_channel_read_chars (channel,
-						  (char *) &event,
-						  sizeof (struct inotify_event),
-						  &size,
-						  &err);
-
-		if (status == G_IO_STATUS_EOF)
-			return TRUE;
-
-		if (event.len) {
-			name = g_new (char, event.len + 1);
-			name[event.len] = '\0';
-			status = g_io_channel_read_chars (channel,
-							  name,
-							  event.len,
-							  &size,
-							  &err);
-			if (status != G_IO_STATUS_NORMAL) {
-				g_warning ("Error reading inotify: %s\n",
-					   err ? "Unknown error" : err->message);
-				g_error_free (err);
-				return TRUE;
-			}
-		}
-		else
-			name = NULL;
-
-		/* look for ignored signal usually following deletion */
-		if (event.mask & IN_IGNORED) {
-			g_hash_table_remove (disc->priv->monitored,
-					     GINT_TO_POINTER (event.wd));
-
-			if (name)
-				g_free (name);
-
-			condition = g_io_channel_get_buffer_condition (channel);
-			continue;
-		}
-
-		dir = g_hash_table_lookup (disc->priv->monitored,
-					   GINT_TO_POINTER (event.wd));
-		if (!dir) {
-			condition = g_io_channel_get_buffer_condition (channel);
-			continue;
-		}
-
-		if (dir->uri && name) {
-			gchar *escaped_name;
-
-			escaped_name = g_uri_escape_string (name,
-							    G_URI_RESERVED_CHARS_ALLOWED_IN_PATH,
-							    FALSE);
-			monitored = g_strconcat (dir->uri, "/", name, NULL);
-			g_free (escaped_name);
-			g_free (name);
-		}
-		else
-			monitored = NULL;
-
-		/* This is a parent directory of at least
-		 * one of the files in the selection */
-		if (event.mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)) {
-			/* The parent directory was moved or deleted so there is
-			 * no other choice but to remove all the children :( */
-			brasero_audio_disc_inotify_remove_all (disc, dir, event.wd);
-		}
-		else if (event.mask & IN_DELETE) {
-			/* a child was deleted */
-			brasero_audio_disc_inotify_remove (disc, monitored);
-		}
-		else if (event.mask & IN_MOVED_FROM) {
-			/* a child was moved from the directory or renamed:
-			 * wait 5s for a MOVED_TO signals that would mean
-			 * it was simply renamed */
-			brasero_audio_disc_inotify_move (disc, &event, monitored);
-		}
-		else if (event.mask & IN_MOVED_TO) {
-			/* a file was either moved to this directory or it's a
-			 * renaming (see above) */
-			brasero_audio_disc_inotify_move (disc, &event, monitored);
-		}
-		else if (event.mask & IN_ATTRIB) {
-			/* a file attributes were changed */
-			brasero_audio_disc_inotify_attributes_changed (disc, monitored);
-		}
-		else if (event.mask & IN_MODIFY
-		     &&  brasero_audio_disc_inotify_is_in_selection (disc, monitored)) {
-			if (!disc->priv->reload_uri)
-				disc->priv->reload_uri = brasero_io_register (G_OBJECT (disc),
-									      brasero_audio_disc_inotify_modify_result,
-									      NULL,
-									      NULL);
-
-			brasero_io_get_file_info (monitored,
-						  disc->priv->reload_uri,
-						  BRASERO_IO_INFO_PERM|
-						  BRASERO_IO_INFO_MIME|
-						  BRASERO_IO_INFO_URGENT|
-						  BRASERO_IO_INFO_METADATA|
-						  BRASERO_IO_INFO_METADATA_MISSING_CODEC,
-						  NULL);
-		}
-
-		if (monitored) {
-			g_free (monitored);
-			monitored = NULL;
-		}
-
-		condition = g_io_channel_get_buffer_condition (channel);
-	}
-
-	return TRUE;
-}
-#endif
diff --git a/src/brasero-data-disc.c b/src/brasero-data-disc.c
index 438e055..97950ef 100644
--- a/src/brasero-data-disc.c
+++ b/src/brasero-data-disc.c
@@ -1384,6 +1384,9 @@ brasero_data_disc_set_session_contents (BraseroDisc *self,
 
 	priv = BRASERO_DATA_DISC_PRIVATE (self);
 
+	if (!session)
+		return BRASERO_DISC_OK;
+
 	brasero_burn_session_add_track (session,
 					BRASERO_TRACK (priv->project),
 					NULL);
diff --git a/src/brasero-disc.c b/src/brasero-disc.c
index c617940..6bed970 100644
--- a/src/brasero-disc.c
+++ b/src/brasero-disc.c
@@ -161,16 +161,19 @@ brasero_disc_delete_selected (BraseroDisc *disc)
 		(* iface->delete_selected) (disc);
 }
 
-void
+gboolean
 brasero_disc_clear (BraseroDisc *disc)
 {
 	BraseroDiscIface *iface;
 
-	g_return_if_fail (BRASERO_IS_DISC (disc));
+	g_return_val_if_fail (BRASERO_IS_DISC (disc), FALSE);
 	
 	iface = BRASERO_DISC_GET_IFACE (disc);
-	if (iface->clear)
-		(* iface->clear) (disc);
+	if (!iface->clear)
+		return FALSE;
+
+	(* iface->clear) (disc);
+	return TRUE;
 }
 
 void
@@ -226,7 +229,6 @@ brasero_disc_set_session_contents (BraseroDisc *disc,
 	BraseroDiscIface *iface;
 
 	g_return_val_if_fail (BRASERO_IS_DISC (disc), BRASERO_DISC_ERROR_UNKNOWN);
-	g_return_val_if_fail (BRASERO_IS_BURN_SESSION (session), BRASERO_DISC_ERROR_UNKNOWN);
 	
 	iface = BRASERO_DISC_GET_IFACE (disc);
 	if (iface->set_session_contents)
diff --git a/src/brasero-disc.h b/src/brasero-disc.h
index 7d01ca1..3305782 100644
--- a/src/brasero-disc.h
+++ b/src/brasero-disc.h
@@ -130,10 +130,9 @@ brasero_disc_get_boundaries (BraseroDisc *disc,
 
 void
 brasero_disc_delete_selected (BraseroDisc *disc);
-void
+
+gboolean
 brasero_disc_clear (BraseroDisc *disc);
-void
-brasero_disc_reset (BraseroDisc *disc);
 
 BraseroDiscResult
 brasero_disc_get_status (BraseroDisc *disc,
diff --git a/src/brasero-project.c b/src/brasero-project.c
index fc925e8..a6cc2e4 100644
--- a/src/brasero-project.c
+++ b/src/brasero-project.c
@@ -1354,7 +1354,7 @@ static void
 brasero_project_switch (BraseroProject *project, BraseroProjectType type)
 {
 	GtkAction *action;
-	
+
 	if (project->priv->project_status) {
 		gtk_widget_hide (project->priv->project_status);
 		gtk_dialog_response (GTK_DIALOG (project->priv->project_status),
@@ -1366,6 +1366,11 @@ brasero_project_switch (BraseroProject *project, BraseroProjectType type)
 				      "media-optical",
 				      GTK_ICON_SIZE_LARGE_TOOLBAR);
 
+	if (project->priv->current) {
+		brasero_disc_set_session_contents (project->priv->current, NULL);
+		project->priv->current = NULL;
+	}
+
 	brasero_project_reset (project);
 
 	if (project->priv->chooser) {
@@ -1386,14 +1391,12 @@ brasero_project_switch (BraseroProject *project, BraseroProjectType type)
 		g_free (project->priv->cover);
 		project->priv->cover = NULL;
 	}
-g_print ("IN HERE\n");
+
 	/* remove the buttons from the "toolbar" */
-	if (project->priv->merge_id) {
-		g_print ("REEEK\n");
+	if (project->priv->merge_id > 0)
 		gtk_ui_manager_remove_ui (project->priv->manager,
 					  project->priv->merge_id);
-	}
-
+g_object_ref (project->priv->session);
 	if (type == BRASERO_PROJECT_TYPE_AUDIO) {
 		gtk_widget_hide (project->priv->button_img);
 
@@ -1421,7 +1424,7 @@ g_print ("IN HERE\n");
 	}
 	else if (type == BRASERO_PROJECT_TYPE_VIDEO) {
 		gtk_widget_hide (project->priv->button_img);
-g_print ("KKK\n");
+
 		project->priv->current = BRASERO_DISC (project->priv->video);
 		project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
 							       project->priv->manager,
@@ -1579,8 +1582,12 @@ brasero_project_set_none (BraseroProject *project)
 		project->priv->chooser = NULL;
 	}
 
+	if (project->priv->current) {
+		brasero_disc_set_session_contents (project->priv->current, NULL);
+		project->priv->current = NULL;
+	}
+
 	brasero_project_reset (project);
-	project->priv->current = NULL;
 
 	/* update buttons/menus */
 	action = gtk_action_group_get_action (project->priv->project_group, "Add");
@@ -1900,7 +1907,8 @@ brasero_project_empty_cb (GtkAction *action, BraseroProject *project)
 			return;
 	}
 
-	brasero_disc_clear (BRASERO_DISC (project->priv->current));
+	if (brasero_disc_clear (BRASERO_DISC (project->priv->current)))
+		brasero_burn_session_add_track (BRASERO_BURN_SESSION (project->priv->session), NULL, NULL);
 }
 
 static void
diff --git a/src/brasero-song-properties.h b/src/brasero-song-properties.h
index cc35f6f..e7aa156 100644
--- a/src/brasero-song-properties.h
+++ b/src/brasero-song-properties.h
@@ -77,4 +77,5 @@ brasero_song_props_set_properties (BraseroSongProps *self,
 				   gint64 start,
 				   gint64 end,
 				   gint64 gap);
+
 #endif /* SONG_PROPERTIES_H */
diff --git a/src/brasero-video-disc.c b/src/brasero-video-disc.c
index 6a42809..176b84d 100644
--- a/src/brasero-video-disc.c
+++ b/src/brasero-video-disc.c
@@ -469,13 +469,19 @@ brasero_video_disc_session_changed (BraseroSessionCfg *session,
 
 			uri = brasero_track_stream_get_source (track, TRUE);
 			error = brasero_status_get_error (status);
-			if (!error || error->code != BRASERO_BURN_ERROR_FILE_FOLDER)
+			if (!error)
 				brasero_video_disc_unreadable_uri_dialog (self, uri, error);
-			else {
+			else if (error->code != BRASERO_BURN_ERROR_FILE_FOLDER) {
 				res = brasero_video_disc_directory_dialog (self);
 				if (res)
 					brasero_video_disc_add_directory_contents (self, uri, BRASERO_TRACK (track));
 			}
+			else if (error->code == BRASERO_BURN_ERROR_FILE_NOT_FOUND) {
+				/* It could be a file that was deleted */
+				brasero_video_disc_unreadable_uri_dialog (self, uri, error);
+			}
+			else
+				brasero_video_disc_unreadable_uri_dialog (self, uri, error);
 
 			brasero_burn_session_remove_track (BRASERO_BURN_SESSION (session),
 							   BRASERO_TRACK (track));
@@ -1197,7 +1203,9 @@ brasero_video_disc_init (BraseroVideoDisc *object)
 	renderer = gtk_cell_renderer_pixbuf_new ();
 	gtk_tree_view_column_pack_start (column, renderer, FALSE);
 	gtk_tree_view_column_add_attribute (column, renderer,
-					    "pixbuf", BRASERO_VIDEO_TREE_MODEL_MIME_ICON);
+					    "pixbuf", BRASERO_VIDEO_TREE_MODEL_THUMBNAIL);
+	gtk_tree_view_column_add_attribute (column, renderer,
+					    "icon-name", BRASERO_VIDEO_TREE_MODEL_ICON_NAME);
 
 	renderer = gtk_cell_renderer_text_new ();
 	g_signal_connect (G_OBJECT (renderer), "edited",
@@ -1334,22 +1342,6 @@ brasero_video_disc_set_property (GObject * object,
 	}
 }
 
-static void
-brasero_video_disc_clear (BraseroDisc *disc)
-{
-	BraseroVideoDiscPrivate *priv;
-	BraseroSessionCfg *session;
-	GtkTreeModel *model;
-
-	priv = BRASERO_VIDEO_DISC_PRIVATE (disc);
-
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
-	session = brasero_video_tree_model_get_session (BRASERO_VIDEO_TREE_MODEL (model));
-	brasero_burn_session_add_track (BRASERO_BURN_SESSION (session), NULL, NULL);
-
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 0);
-}
-
 static BraseroDiscResult
 brasero_video_disc_set_session_contents (BraseroDisc *self,
 					 BraseroBurnSession *session)
@@ -1359,6 +1351,11 @@ brasero_video_disc_set_session_contents (BraseroDisc *self,
 
 	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
 
+	if (!session) {
+		gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree), NULL);
+		return BRASERO_DISC_OK;
+	}
+
 	model = brasero_video_tree_model_new ();
 	brasero_video_tree_model_set_session (model, BRASERO_SESSION_CFG (session));
 	gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree),
@@ -1454,7 +1451,6 @@ brasero_video_disc_iface_disc_init (BraseroDiscIface *iface)
 {
 	iface->add_uri = brasero_video_disc_add_uri;
 	iface->delete_selected = brasero_video_disc_delete_selected;
-	iface->clear = brasero_video_disc_clear;
 
 	iface->set_session_contents = brasero_video_disc_set_session_contents;
 
diff --git a/src/brasero-video-tree-model.c b/src/brasero-video-tree-model.c
index d881b98..c4795b0 100644
--- a/src/brasero-video-tree-model.c
+++ b/src/brasero-video-tree-model.c
@@ -43,6 +43,8 @@ struct _BraseroVideoTreeModelPrivate
 {
 	BraseroSessionCfg *session;
 
+	GSList *gaps;
+
 	guint stamp;
 	GtkIconTheme *theme;
 };
@@ -70,6 +72,10 @@ G_DEFINE_TYPE_WITH_CODE (BraseroVideoTreeModel,
 			 G_IMPLEMENT_INTERFACE (EGG_TYPE_TREE_MULTI_DRAG_SOURCE,
 					        brasero_video_tree_model_multi_drag_source_iface_init));
 
+enum {
+	BRASERO_STREAM_ROW_NORMAL	= 0,
+	BRASERO_STREAM_ROW_GAP		= 1,
+};
 
 /**
  * This is mainly a list so the following functions are not implemented.
@@ -127,6 +133,7 @@ brasero_video_tree_model_get_value (GtkTreeModel *model,
 	const gchar *string;
 	GdkPixbuf *pixbuf;
 	GValue *value_tag;
+	GSList *tracks;
 	gchar *text;
 
 	self = BRASERO_VIDEO_TREE_MODEL (model);
@@ -137,10 +144,54 @@ brasero_video_tree_model_get_value (GtkTreeModel *model,
 	g_return_if_fail (iter->user_data != NULL);
 
 	track = iter->user_data;
-
 	if (!BRASERO_IS_TRACK_STREAM (track))
 		return;
 
+	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_STREAM_ROW_GAP) {
+		switch (column) {
+		case BRASERO_VIDEO_TREE_MODEL_NAME:
+			text = g_strdup_printf ("<i><b>%s</b></i>", _("Pause"));
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, text);
+			g_free (text);
+			break;
+		case BRASERO_VIDEO_TREE_MODEL_ICON_NAME:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, GTK_STOCK_MEDIA_PAUSE);
+			break;
+		case BRASERO_VIDEO_TREE_MODEL_EDITABLE:
+		case BRASERO_VIDEO_TREE_MODEL_SELECTABLE:
+			g_value_init (value, G_TYPE_BOOLEAN);
+			g_value_set_boolean (value, FALSE);
+			break;
+		case BRASERO_VIDEO_TREE_MODEL_IS_GAP:
+			g_value_init (value, G_TYPE_BOOLEAN);
+			g_value_set_boolean (value, TRUE);
+			break;
+
+		case BRASERO_VIDEO_TREE_MODEL_SIZE:
+			g_value_init (value, G_TYPE_STRING);
+			text = brasero_units_get_time_string (brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track)), TRUE, FALSE);
+			g_value_set_string (value, text);
+			g_free (text);
+			break;
+
+		case BRASERO_VIDEO_TREE_MODEL_INDEX:
+		case BRASERO_VIDEO_TREE_MODEL_ARTIST:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, NULL);
+			break;
+
+		case BRASERO_VIDEO_TREE_MODEL_THUMBNAIL:
+		case BRASERO_VIDEO_TREE_MODEL_INDEX_NUM:
+		default:
+			g_value_init (value, G_TYPE_INVALID);
+			break;
+		}
+
+		return;
+	}
+
 	switch (column) {
 	case BRASERO_VIDEO_TREE_MODEL_NAME:
 		g_value_init (value, G_TYPE_STRING);
@@ -170,36 +221,44 @@ brasero_video_tree_model_get_value (GtkTreeModel *model,
 
 		return;
 
-	case BRASERO_VIDEO_TREE_MODEL_MIME_ICON:
+	case BRASERO_VIDEO_TREE_MODEL_ARTIST:
+		g_value_init (value, G_TYPE_STRING);
+
+		string = brasero_track_tag_lookup_string (track, BRASERO_TRACK_STREAM_ARTIST_TAG);
+		if (string)
+			g_value_set_string (value, string);
+
+		return;
+
+	case BRASERO_VIDEO_TREE_MODEL_ICON_NAME:
 		status = brasero_status_new ();
 		brasero_track_get_status (track, status);
+		g_value_init (value, G_TYPE_STRING);
 
-		g_value_init (value, GDK_TYPE_PIXBUF);
+		value_tag = NULL;
+		if (brasero_status_get_result (status) == BRASERO_BURN_NOT_READY)
+			g_value_set_string (value, "image-loading");
+		else if (brasero_track_tag_lookup (track, BRASERO_TRACK_STREAM_MIME_TAG, &value_tag) == BRASERO_BURN_OK)
+			g_value_set_string (value, g_value_get_string (value_tag));
+		else
+			g_value_set_string (value, "image-missing");
+
+		brasero_status_free (status);
+		return;
 
+	case BRASERO_VIDEO_TREE_MODEL_THUMBNAIL:
 		value_tag = NULL;
-		brasero_track_tag_lookup (BRASERO_TRACK (track),
+		brasero_track_tag_lookup (track,
 					  BRASERO_TRACK_STREAM_THUMBNAIL_TAG,
 					  &value_tag);
-		if (value_tag)
+
+		if (value_tag) {
+			g_value_init (value, GDK_TYPE_PIXBUF);
 			pixbuf = g_value_dup_object (value_tag);
-		else if (brasero_status_get_result (status) == BRASERO_BURN_NOT_READY) {
-			pixbuf = gtk_icon_theme_load_icon (priv->theme,
-							   "image-loading",
-							   48,
-							   0,
-							   NULL);
-		}
-		else {
-			pixbuf = gtk_icon_theme_load_icon (priv->theme,
-							   "image-missing",
-							   48,
-							   0,
-							   NULL);
+			g_value_set_object (value, pixbuf);
+			g_object_unref (pixbuf);
 		}
 
-		g_value_set_object (value, pixbuf);
-		brasero_status_free (status);
-		g_object_unref (pixbuf);
 		return;
 
 	case BRASERO_VIDEO_TREE_MODEL_SIZE:
@@ -212,6 +271,7 @@ brasero_video_tree_model_get_value (GtkTreeModel *model,
 			guint64 len = 0;
 
 			brasero_track_stream_get_length (BRASERO_TRACK_STREAM (track), &len);
+			len -= brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track));
 			text = brasero_units_get_time_string (len, TRUE, FALSE);
 			g_value_set_string (value, text);
 			g_free (text);
@@ -236,6 +296,23 @@ brasero_video_tree_model_get_value (GtkTreeModel *model,
 		//g_value_set_boolean (value, file->editable);
 		return;
 
+	case BRASERO_VIDEO_TREE_MODEL_IS_GAP:
+		g_value_init (value, G_TYPE_BOOLEAN);
+		g_value_set_boolean (value, FALSE);
+		return;
+
+	case BRASERO_VIDEO_TREE_MODEL_INDEX:
+		tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
+		g_value_init (value, G_TYPE_STRING);
+		g_value_set_string_take_ownership (value, g_strdup_printf ("%02i", g_slist_index (tracks, track) + 1));
+		return;
+
+	case BRASERO_VIDEO_TREE_MODEL_INDEX_NUM:
+		tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
+		g_value_init (value, G_TYPE_UINT);
+		g_value_set_uint (value, g_slist_index (tracks, track) + 1);
+		return;
+
 	default:
 		break;
 	}
@@ -243,24 +320,33 @@ brasero_video_tree_model_get_value (GtkTreeModel *model,
 
 GtkTreePath *
 brasero_video_tree_model_track_to_path (BraseroVideoTreeModel *self,
-				        BraseroTrack *track)
+				        BraseroTrack *track_arg)
 {
 	BraseroVideoTreeModelPrivate *priv;
-	GtkTreePath *path;
 	GSList *tracks;
-	guint nth;
+	gint nth = 0;
 
-	if (!BRASERO_IS_TRACK_STREAM (track))
+	if (!BRASERO_IS_TRACK_STREAM (track_arg))
 		return NULL;
 
 	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (self);
 
-	path = gtk_tree_path_new ();
 	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
-	nth = g_slist_index (tracks, track);
-	gtk_tree_path_prepend_index (path, nth);
+	for (; tracks; tracks = tracks->next) {
+		BraseroTrackStream *track;
+
+		track = tracks->data;
+		if (track == BRASERO_TRACK_STREAM (track_arg))
+			break;
+
+		nth ++;
 
-	return path;
+		if (brasero_track_stream_get_gap (track) > 0)
+			nth ++;
+
+	}
+
+	return gtk_tree_path_new_from_indices (nth, -1);
 }
 
 static GtkTreePath *
@@ -268,8 +354,8 @@ brasero_video_tree_model_get_path (GtkTreeModel *model,
 				   GtkTreeIter *iter)
 {
 	BraseroVideoTreeModelPrivate *priv;
-	BraseroTrack *track;
-	GtkTreePath *path;
+	GSList *tracks;
+	gint nth = 0;
 
 	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (model);
 
@@ -277,11 +363,28 @@ brasero_video_tree_model_get_path (GtkTreeModel *model,
 	g_return_val_if_fail (priv->stamp == iter->stamp, NULL);
 	g_return_val_if_fail (iter->user_data != NULL, NULL);
 
-	track = iter->user_data;
+	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
+	for (; tracks; tracks = tracks->next) {
+		BraseroTrackStream *track;
+
+		track = tracks->data;
+		if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_STREAM_ROW_NORMAL
+		&&  track == iter->user_data)
+			break;
+
+		nth ++;
+
+		if (brasero_track_stream_get_gap (track) > 0) {
+			if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_STREAM_ROW_GAP
+			&&  track == iter->user_data)
+				break;
+
+			nth ++;
+		}
+	}
 
 	/* NOTE: there is only one single file without a name: root */
-	path = brasero_video_tree_model_track_to_path (BRASERO_VIDEO_TREE_MODEL (model), track);
-	return path;
+	return gtk_tree_path_new_from_indices (nth, -1);
 }
 
 BraseroTrack *
@@ -292,6 +395,7 @@ brasero_video_tree_model_path_to_track (BraseroVideoTreeModel *self,
 	const gint *indices;
 	GSList *tracks;
 	guint depth;
+	gint index;
 
 	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (self);
 
@@ -303,8 +407,26 @@ brasero_video_tree_model_path_to_track (BraseroVideoTreeModel *self,
 	if (depth > 2)
 		return NULL;
 
+	/* Whether it is a GAP or a NORMAL row is of no importance */
 	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
-	return g_slist_nth_data (tracks, indices [0]);
+	index = indices [0];
+	for (; tracks; tracks = tracks->next) {
+		BraseroTrackStream *track;
+
+		track = tracks->data;
+		if (index <= 0)
+			return BRASERO_TRACK (track);
+
+		index --;
+
+		if (index <= 0)
+			return BRASERO_TRACK (track);
+
+		if (brasero_track_stream_get_gap (track) > 0)
+			index --;
+	}
+
+	return NULL;
 }
 
 static gboolean
@@ -313,17 +435,86 @@ brasero_video_tree_model_get_iter (GtkTreeModel *model,
 				   GtkTreePath *path)
 {
 	BraseroVideoTreeModelPrivate *priv;
-	BraseroTrack *track;
+	const gint *indices;
+	GSList *tracks;
+	guint depth;
+	gint index;
 
 	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (model);
-	track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (model), path);
-	if (!track)
+
+	depth = gtk_tree_path_get_depth (path);
+
+	/* NOTE: it can happen that paths are depth 2 when there is DND but then
+	 * only the first index is relevant. */
+	if (depth > 2)
 		return FALSE;
 
-	iter->user_data = track;
-	iter->stamp = priv->stamp;
+	/* Whether it is a GAP or a NORMAL row is of no importance */
+	indices = gtk_tree_path_get_indices (path);
+	index = indices [0];
+	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
+	for (; tracks; tracks = tracks->next) {
+		BraseroTrackStream *track;
+
+		track = tracks->data;
+		if (index <= 0) {
+			iter->stamp = priv->stamp;
+			iter->user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_NORMAL);
+			iter->user_data = track;
+			return TRUE;
+		}
+		index --;
+
+		if (brasero_track_stream_get_gap (track) > 0) {
+			if (index <= 0) {
+				iter->stamp = priv->stamp;
+				iter->user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_GAP);
+				iter->user_data = track;
+				return TRUE;
+			}
+			index --;
+		}
+	}
+
+	return FALSE;
+}
 
-	return TRUE;
+static BraseroTrack *
+brasero_video_tree_model_track_next (BraseroVideoTreeModel *model,
+				     BraseroTrack *track)
+{
+	BraseroVideoTreeModelPrivate *priv;
+	GSList *tracks;
+	GSList *node;
+
+	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (model);
+
+	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
+	node = g_slist_find (tracks, track);
+	if (!node || !node->next)
+		return NULL;
+
+	return node->next->data;
+}
+
+static BraseroTrack *
+brasero_video_tree_model_track_previous (BraseroVideoTreeModel *model,
+					 BraseroTrack *track)
+{
+	BraseroVideoTreeModelPrivate *priv;
+	GSList *tracks;
+
+	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (model);
+
+	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
+	while (tracks && tracks->next) {
+		if (tracks->next->data == track)
+			return tracks->data;
+
+		tracks = tracks->next;
+	}
+
+	return NULL;
 }
 
 static gboolean
@@ -331,7 +522,7 @@ brasero_video_tree_model_iter_next (GtkTreeModel *model,
 				    GtkTreeIter *iter)
 {
 	BraseroVideoTreeModelPrivate *priv;
-	BraseroTrack *track;
+	BraseroTrackStream *track;
 	GSList *tracks;
 	GSList *node;
 
@@ -341,15 +532,22 @@ brasero_video_tree_model_iter_next (GtkTreeModel *model,
 	g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
 	g_return_val_if_fail (iter->user_data != NULL, FALSE);
 
-	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
-	track = iter->user_data;
+	track = BRASERO_TRACK_STREAM (iter->user_data);
 	if (!track)
 		return FALSE;
 
+	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_STREAM_ROW_NORMAL
+	&&  brasero_track_stream_get_gap (track) > 0) {
+		iter->user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_GAP);
+		return TRUE;
+	}
+
+	tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
 	node = g_slist_find (tracks, track);
 	if (!node || !node->next)
 		return FALSE;
 
+	iter->user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_NORMAL);
 	iter->user_data = node->next->data;
 	return TRUE;
 }
@@ -362,9 +560,15 @@ brasero_video_tree_model_get_column_type (GtkTreeModel *model,
 	case BRASERO_VIDEO_TREE_MODEL_NAME:
 		return G_TYPE_STRING;
 
-	case BRASERO_VIDEO_TREE_MODEL_MIME_ICON:
+	case BRASERO_VIDEO_TREE_MODEL_ARTIST:
+		return G_TYPE_STRING;
+
+	case BRASERO_VIDEO_TREE_MODEL_THUMBNAIL:
 		return GDK_TYPE_PIXBUF;
 
+	case BRASERO_VIDEO_TREE_MODEL_ICON_NAME:
+		return G_TYPE_STRING;
+
 	case BRASERO_VIDEO_TREE_MODEL_SIZE:
 		return G_TYPE_STRING;
 
@@ -374,6 +578,15 @@ brasero_video_tree_model_get_column_type (GtkTreeModel *model,
 	case BRASERO_VIDEO_TREE_MODEL_SELECTABLE:
 		return G_TYPE_BOOLEAN;
 
+	case BRASERO_VIDEO_TREE_MODEL_INDEX:
+		return G_TYPE_STRING;
+
+	case BRASERO_VIDEO_TREE_MODEL_INDEX_NUM:
+		return G_TYPE_UINT;
+
+	case BRASERO_VIDEO_TREE_MODEL_IS_GAP:
+		return G_TYPE_STRING;
+
 	default:
 		break;
 	}
@@ -435,12 +648,121 @@ brasero_video_tree_model_multi_drag_data_delete (EggTreeMultiDragSource *drag_so
 	return TRUE;
 }
 
+void
+brasero_video_tree_model_move_before (BraseroVideoTreeModel *self,
+				      GtkTreeIter *iter,
+				      GtkTreePath *dest_before)
+{
+	BraseroTrack *track;
+	GtkTreeIter sibling;
+	BraseroTrack *track_sibling;
+	BraseroVideoTreeModelPrivate *priv;
+
+	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (self);
+
+	track = BRASERO_TRACK (iter->user_data);
+	if (!dest_before || !brasero_video_tree_model_get_iter (GTK_TREE_MODEL (self), &sibling, dest_before)) {
+		if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_STREAM_ROW_GAP) {
+			guint64 gap;
+			GSList *tracks;
+
+			gap = brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track));
+			brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+							     -1,
+							     -1,
+							     0);
+			brasero_track_changed (track);
+
+			/* Get last track */
+			tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
+			tracks = g_slist_last (tracks);
+			track_sibling = tracks->data;
+
+			gap += brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track_sibling));
+			brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track_sibling),
+							     -1,
+							     -1,
+							     gap);
+			brasero_track_changed (track_sibling);
+			return;
+		}
+
+		brasero_burn_session_move_track (BRASERO_BURN_SESSION (priv->session),
+						 track,
+						 NULL);
+		return;
+	}
+
+	track_sibling = BRASERO_TRACK (sibling.user_data);
+
+	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_STREAM_ROW_GAP) {
+		guint64 gap;
+		BraseroTrack *previous_sibling;
+
+		/* Merge the gaps or add it */
+		gap = brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track));
+		brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+						     -1,
+						     -1,
+						     0);
+		brasero_track_changed (track);
+
+		if (GPOINTER_TO_INT (sibling.user_data2) == BRASERO_STREAM_ROW_GAP) {
+			gap += brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track_sibling));
+			brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track_sibling),
+							     -1,
+							     -1,
+							     gap);
+			brasero_track_changed (track_sibling);
+			return;
+		}
+
+		/* get the track before track_sibling */
+		previous_sibling = brasero_video_tree_model_track_previous (self, track_sibling);
+		if (previous_sibling)
+			track_sibling = previous_sibling;
+
+		gap += brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track_sibling));
+		brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track_sibling),
+						     -1,
+						     -1,
+						     gap);
+		brasero_track_changed (track_sibling);
+		return;
+	}
+
+	if (GPOINTER_TO_INT (sibling.user_data2) == BRASERO_STREAM_ROW_GAP) {
+		guint64 gap;
+
+		/* merge */
+		gap = brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track_sibling));
+		brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track_sibling),
+						     -1,
+						     -1,
+						     0);
+		brasero_track_changed (track_sibling);
+
+		gap += brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track));
+		brasero_track_stream_set_boundaries (BRASERO_TRACK_STREAM (track),
+						     -1,
+						     -1,
+						     gap);
+		brasero_track_changed (track);
+
+		/* Track sibling is now the next track of current track_sibling */
+		track_sibling = brasero_video_tree_model_track_next (self, track_sibling);
+	}
+
+	brasero_burn_session_move_track (BRASERO_BURN_SESSION (priv->session),
+					 track,
+					 track_sibling);
+}
+
 static gboolean
 brasero_video_tree_model_drag_data_received (GtkTreeDragDest *drag_dest,
 					     GtkTreePath *dest_path,
 					     GtkSelectionData *selection_data)
 {
-	BraseroTrack *track;
 	BraseroTrack *sibling;
 	BraseroVideoTreeModelPrivate *priv;
 
@@ -465,16 +787,18 @@ brasero_video_tree_model_drag_data_received (GtkTreeDragDest *drag_dest,
 		for (iter = context->references; iter; iter = iter->next) {
 			GtkTreeRowReference *reference;
 			GtkTreePath *treepath;
+			GtkTreeIter tree_iter;
 
 			reference = iter->data;
 			treepath = gtk_tree_row_reference_get_path (reference);
-
-			track = brasero_video_tree_model_path_to_track (BRASERO_VIDEO_TREE_MODEL (drag_dest), treepath);
+			gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
+						 &tree_iter,
+						 treepath);
 			gtk_tree_path_free (treepath);
 
-			brasero_burn_session_move_track (BRASERO_BURN_SESSION (priv->session),
-							 track,
-							 sibling);
+			brasero_video_tree_model_move_before (BRASERO_VIDEO_TREE_MODEL (drag_dest),
+							      &tree_iter,
+							      dest_path);
 		}
 	}
 	else if (selection_data->target == gdk_atom_intern ("text/uri-list", TRUE)) {
@@ -524,12 +848,50 @@ brasero_video_tree_model_drag_data_delete (GtkTreeDragSource *source,
 }
 
 static void
+brasero_video_tree_model_reindex (BraseroVideoTreeModel *model,
+				  BraseroBurnSession *session,
+				  BraseroTrack *track_arg,
+				  GtkTreeIter *iter,
+				  GtkTreePath *path)
+{
+	GSList *tracks;
+	BraseroVideoTreeModelPrivate *priv;
+
+	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (model);
+
+	/* tracks (including) after sibling need to be reindexed */
+	tracks = brasero_burn_session_get_tracks (session);
+	tracks = g_slist_find (tracks, track_arg);
+	if (!tracks)
+		return;
+
+	tracks = tracks->next;
+	for (; tracks; tracks = tracks->next) {
+		BraseroTrack *track;
+
+		track = tracks->data;
+
+		iter->stamp = priv->stamp;
+		iter->user_data = track;
+		iter->user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_NORMAL);
+
+		gtk_tree_path_next (path);
+		gtk_tree_model_row_changed (GTK_TREE_MODEL (model),
+					    path,
+					    iter);
+
+		/* skip gap rows */
+		if (brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track)) > 0)
+			gtk_tree_path_next (path);
+	}
+}
+
+static void
 brasero_video_tree_model_track_added (BraseroBurnSession *session,
 				      BraseroTrack *track,
 				      BraseroVideoTreeModel *model)
 {
 	BraseroVideoTreeModelPrivate *priv;
-	BraseroStatus *status;
 	GtkTreePath *path;
 	GtkTreeIter iter;
 
@@ -540,19 +902,30 @@ brasero_video_tree_model_track_added (BraseroBurnSession *session,
 
 	iter.stamp = priv->stamp;
 	iter.user_data = track;
+	iter.user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_NORMAL);
 
 	path = brasero_video_tree_model_track_to_path (model, track);
 
 	/* if the file is reloading (because of a file system change or because
 	 * it was a file that was a tmp folder) then no need to signal an added
 	 * signal but a changed one */
-	status = brasero_status_new ();
-	brasero_track_get_status (track, status);
 	gtk_tree_model_row_inserted (GTK_TREE_MODEL (model),
 				     path,
 				     &iter);
+
+	if (brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track)) > 0) {
+		priv->gaps = g_slist_prepend (priv->gaps, track);
+
+		iter.user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_GAP);
+		gtk_tree_path_next (path);
+		gtk_tree_model_row_inserted (GTK_TREE_MODEL (model),
+					     path,
+					     &iter);
+	}
+
+	/* tracks (including) after sibling need to be reindexed */
+	brasero_video_tree_model_reindex (model, session, track, &iter, path);
 	gtk_tree_path_free (path);
-	brasero_status_free (status);
 }
 
 static void
@@ -563,6 +936,7 @@ brasero_video_tree_model_track_removed (BraseroBurnSession *session,
 {
 	BraseroVideoTreeModelPrivate *priv;
 	GtkTreePath *path;
+	GtkTreeIter iter;
 
 	if (!BRASERO_IS_TRACK_STREAM (track))
 		return;
@@ -572,6 +946,14 @@ brasero_video_tree_model_track_removed (BraseroBurnSession *session,
 	/* remove the file. */
 	path = gtk_tree_path_new_from_indices (former_location, -1);
 	gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
+
+	if (brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track)) > 0) {
+		priv->gaps = g_slist_remove (priv->gaps, track);
+		gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
+	}
+
+	/* tracks (including) after former_location need to be reindexed */
+	brasero_video_tree_model_reindex (model, session, track, &iter, path);
 	gtk_tree_path_free (path);
 }
 
@@ -614,12 +996,36 @@ brasero_video_tree_model_track_changed (BraseroBurnSession *session,
 
 	/* Get the iter for the file */
 	iter.stamp = priv->stamp;
+	iter.user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_NORMAL);
 	iter.user_data = track;
 
 	path = brasero_video_tree_model_track_to_path (model, track);
 	gtk_tree_model_row_changed (GTK_TREE_MODEL (model),
 				    path,
 				    &iter);
+
+	/* Get the iter for a possible gap row.
+	 * The problem is to know whether one was added, removed or simply
+	 * changed. */
+	gtk_tree_path_next (path);
+	if (brasero_track_stream_get_gap (BRASERO_TRACK_STREAM (track)) > 0) {
+		iter.user_data2 = GINT_TO_POINTER (BRASERO_STREAM_ROW_GAP);
+		if (!g_slist_find (priv->gaps, track)) {
+			priv->gaps = g_slist_prepend (priv->gaps,  track);
+			gtk_tree_model_row_inserted (GTK_TREE_MODEL (model),
+						     path,
+						     &iter);
+		}
+		else
+			gtk_tree_model_row_changed (GTK_TREE_MODEL (model),
+						    path,
+						    &iter);
+	}
+	else if (g_slist_find (priv->gaps, track)) {
+		priv->gaps = g_slist_remove (priv->gaps, track);
+		gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);		
+	}
+
 	gtk_tree_path_free (path);
 }
 
@@ -683,9 +1089,9 @@ brasero_video_tree_model_finalize (GObject *object)
 
 	priv = BRASERO_VIDEO_TREE_MODEL_PRIVATE (object);
 
-	if (priv->theme) {
-		g_object_unref (priv->theme);
-		priv->theme = NULL;
+	if (priv->gaps) {
+		g_slist_free (priv->gaps);
+		priv->gaps = NULL;
 	}
 
 	G_OBJECT_CLASS (brasero_video_tree_model_parent_class)->finalize (object);
diff --git a/src/brasero-video-tree-model.h b/src/brasero-video-tree-model.h
index 09999cc..acbfd53 100644
--- a/src/brasero-video-tree-model.h
+++ b/src/brasero-video-tree-model.h
@@ -41,10 +41,15 @@ typedef struct _BraseroDNDVideoContext BraseroDNDVideoContext;
 
 typedef enum {
 	BRASERO_VIDEO_TREE_MODEL_NAME		= 0,
-	BRASERO_VIDEO_TREE_MODEL_MIME_ICON,
+	BRASERO_VIDEO_TREE_MODEL_ARTIST		= 1,
+	BRASERO_VIDEO_TREE_MODEL_THUMBNAIL,
+	BRASERO_VIDEO_TREE_MODEL_ICON_NAME,
 	BRASERO_VIDEO_TREE_MODEL_SIZE,
 	BRASERO_VIDEO_TREE_MODEL_EDITABLE,
 	BRASERO_VIDEO_TREE_MODEL_SELECTABLE,
+	BRASERO_VIDEO_TREE_MODEL_INDEX,
+	BRASERO_VIDEO_TREE_MODEL_INDEX_NUM,
+	BRASERO_VIDEO_TREE_MODEL_IS_GAP,
 	BRASERO_VIDEO_TREE_MODEL_COL_NUM
 } BraseroVideoProjectColumn;
 
@@ -87,6 +92,11 @@ GtkTreePath *
 brasero_video_tree_model_track_to_path (BraseroVideoTreeModel *self,
 				        BraseroTrack *track);
 
+void
+brasero_video_tree_model_move_before (BraseroVideoTreeModel *self,
+				      GtkTreeIter *iter,
+				      GtkTreePath *dest_before);
+
 G_END_DECLS
 
 #endif /* _BRASERO_VIDEO_TREE_MODEL_H_ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]