[longomatch] Transform MediaFileSet from a dictionary to a list. MediaFiles now have a name which will be used to



commit e3fd53bcef453e53d8f50369d29cd2172c0816fd
Author: Julien Moutte <julien fluendo com>
Date:   Fri Mar 6 14:26:36 2015 +0100

    Transform MediaFileSet from a dictionary to a list.
    MediaFiles now have a name which will be used to add concepts such as camera name.
    A MediaFileSet is now an ordered list of named MediaFiles that can be replaced using their name or 
reference as the key.
    Adapt unit tests to check deserialisation / migration and fix API usage in code using MediaFile(Set).
    Transform the MediaFileChooser and and SetSelection widgets to support an infinite number of files.

 LongoMatch.Core/Store/MediaFile.cs                 |   11 +-
 LongoMatch.Core/Store/MediaFileSet.cs              |  123 ++++++---
 LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs         |    5 +-
 .../Gui/Utils/FramesCapturer.cs                    |    4 +-
 LongoMatch.GUI/Gui/Component/MediaFileChooser.cs   |   53 ++++-
 .../Gui/Component/MediaFileSetSelection.cs         |  112 +++-----
 LongoMatch.GUI/Gui/Component/ProjectListWidget.cs  |    3 +-
 LongoMatch.GUI/Gui/Component/ProjectPeriods.cs     |    2 +-
 LongoMatch.GUI/Gui/Component/Timeline.cs           |    4 +-
 LongoMatch.GUI/Gui/Component/VideoFileInfo.cs      |    7 +-
 LongoMatch.GUI/Gui/GUIToolkit.cs                   |    2 +-
 LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs        |    6 +-
 .../LongoMatch.Gui.Component.MediaFileChooser.cs   |   47 +++-
 ...ngoMatch.Gui.Component.MediaFileSetSelection.cs |  239 ++---------------
 LongoMatch.GUI/gtk-gui/gui.stetic                  |  291 +++----------------
 LongoMatch.Migration/Converter.cs                  |    3 +-
 LongoMatch.Multimedia/Utils/GstDiscoverer.cs       |    2 +-
 LongoMatch.Services/Services/EventsManager.cs      |    5 +-
 LongoMatch.Services/Services/ProjectsManager.cs    |   17 +-
 .../Services/RenderingJobsManager.cs               |    2 +-
 Tests/Core/Store/TestMediaFile.cs                  |    3 +-
 Tests/Core/Store/TestMediaFileSet.cs               |   65 ++++--
 Tests/Core/Store/TestPlaysFilter.cs                |    4 +-
 Tests/Core/Store/TestProject.cs                    |    4 +-
 Tests/Core/Store/TestProjectDescription.cs         |    9 +-
 25 files changed, 392 insertions(+), 631 deletions(-)
---
diff --git a/LongoMatch.Core/Store/MediaFile.cs b/LongoMatch.Core/Store/MediaFile.cs
index ddd5b83..4a3b8a2 100644
--- a/LongoMatch.Core/Store/MediaFile.cs
+++ b/LongoMatch.Core/Store/MediaFile.cs
@@ -41,9 +41,10 @@ namespace LongoMatch.Core.Store
                                 string videoCodec,
                                 string audioCodec,
                                 uint videoWidth,
-                                uint videoHeight, 
+                                uint videoHeight,
                                 double par,
-                                Image preview)
+                                Image preview,
+                         String name)
                {
                        FilePath = filePath;
                        Duration = new Time ((int)length);
@@ -58,6 +59,7 @@ namespace LongoMatch.Core.Store
                        Preview = preview;
                        Par = par;
                        Offset = new Time (0);
+                       Name = name;
                }
 
                public string FilePath {
@@ -125,6 +127,11 @@ namespace LongoMatch.Core.Store
                        set;
                }
 
+               public String Name {
+                       get;
+                       set;
+               }
+
                [JsonIgnore]
                public string ShortDescription {
                        get {
diff --git a/LongoMatch.Core/Store/MediaFileSet.cs b/LongoMatch.Core/Store/MediaFileSet.cs
index 31773eb..3dc64e0 100644
--- a/LongoMatch.Core/Store/MediaFileSet.cs
+++ b/LongoMatch.Core/Store/MediaFileSet.cs
@@ -19,80 +19,137 @@ using System;
 using System.Linq;
 using System.Collections.Generic;
 using LongoMatch.Core.Common;
+using Mono.Unix;
 using Newtonsoft.Json;
 
 namespace LongoMatch.Core.Store
 {
        [JsonObject(MemberSerialization.OptIn)]
        [Serializable]
-       public class MediaFileSet
+       public class MediaFileSet : List<MediaFile>
        {
 
                public MediaFileSet ()
                {
-                       Files = new Dictionary<MediaFileAngle, MediaFile>();
-                       Files[MediaFileAngle.Angle1] = null;
-                       Files[MediaFileAngle.Angle2] = null;
-                       Files[MediaFileAngle.Angle3] = null;
-                       Files[MediaFileAngle.Angle4] = null;
                }
 
                [JsonProperty]
+               List<MediaFile> MediaFiles {
+                       get {
+                               if (Count == 0) {
+                                       return null;
+                               } else {
+                                       return new List<MediaFile> (this);
+                               }
+                       }
+                       set {
+                               this.Clear ();
+                               if (value != null) {
+                                       AddRange (value);
+                               }
+                       }
+               }
+
+               [JsonProperty]
+               [Obsolete]
                Dictionary <MediaFileAngle, MediaFile> Files {
-                       get;
-                       set;
+                       set {
+                               // Transform old Files dict to ordered list
+                               foreach (KeyValuePair<MediaFileAngle, MediaFile> File in value) {
+                                       if (File.Value != null) {
+                                               // Set the angle as the name
+                                               switch (File.Key) {
+                                               case MediaFileAngle.Angle1:
+                                                       File.Value.Name = Catalog.GetString ("Main camera 
angle");
+                                                       break;
+                                               default:
+                                                       File.Value.Name = Catalog.GetString ("Camera angle");
+                                                       break;
+                                               }
+                                               // Add to list
+                                               Add (File.Value);
+                                       }
+                               }
+                               // FIXME: Order list
+                       }
                }
 
+               /// <summary>
+               /// Gets the preview of the first file in set or null if the set is empty.
+               /// </summary>
+               /// <value>The preview.</value>
                public Image Preview {
                        get {
-                               if (Files.Count == 0) {
-                                       return null;
+                               MediaFile file = this.FirstOrDefault ();
+
+                               if (file != null) {
+                                       return file.Preview;
                                } else {
-                                       return Files[MediaFileAngle.Angle1].Preview;
+                                       return null;
                                }
                        }
                }
 
+               /// <summary>
+               /// Gets the total duration of all files in set.
+               /// </summary>
+               /// <value>The duration.</value>
                public Time Duration {
                        get {
-                               return Files.Values.Max (mf => mf == null ? new Time (0) : mf.Duration);
+                               return this.Max (mf => mf == null ? new Time (0) : mf.Duration);
                        }
                }
 
-               public MediaFile GetAngle (MediaFileAngle angle)
-               {
-                       if (Files [angle] != null) {
-                               return Files [angle];
-                       } else {
-                               Log.Warning ("View not found for file set: " + angle);
-                               return null;
-                       }
+               /// <summary>
+               /// Search for first file with matching name and replace with new file.
+               /// If no file with matching name was found, this is equivalent to adding new file to the set.
+               /// Note that new file does not have to use the same name.
+               /// </summary>
+               /// <param name="name">Name to use for the search.</param>
+               /// <param name="file">File.</param>
+               /// <returns><c>true</c> if the name was found and a substitution happened, <c>false</c> 
otherwise.</returns>
+               public bool Replace (String name, MediaFile file) {
+                       MediaFile old_file = this.Where (mf => mf.Name == name).FirstOrDefault ();
+                       return Replace (old_file, file);
                }
-               
-               public void SetAngle (MediaFileAngle angle, MediaFile file)
-               {
-                       Files[angle] = file;
+
+               /// <summary>
+               /// Search for a file in the set and replace it with a new one.
+               /// If old file is not found, this is equivalent to adding new file to the set.
+               /// </summary>
+               /// <param name="old_file">Old file.</param>
+               /// <param name="new_file">New file.</param>
+               /// <returns>><c>true</c> if the old file was found and a substitution happened, <c>false</c> 
otherwise.</returns>
+               public bool Replace (MediaFile old_file, MediaFile new_file) {
+                       bool found = false;
+
+                       if (Contains (old_file)) {
+                               Remove (old_file);
+                               found = true;
+                       }
+
+                       //FIXME: Should we copy some properties from the previous file such as Offset ?
+                       Add (new_file);
+
+                       return found;
                }
 
+               /// <summary>
+               /// Checks that all files in the set are valid.
+               /// </summary>
+               /// <returns><c>true</c>, if files was checked, <c>false</c> otherwise.</returns>
                public bool CheckFiles ()
                {
-                       List<MediaFile> files = ActiveFiles;
-                       if (files.Count == 0) {
+                       if (Count == 0) {
                                return false;
                        }
-                       foreach (MediaFile f in files) {
+                       foreach (MediaFile f in this) {
                                if (!f.Exists ()) {
                                        return false;
                                }
                        }
                        return true;
                }
-
-               public List<MediaFile> ActiveFiles {
-                       get {
-                               return Files.Values.Where(f => f != null).ToList();
-                       }
-               }
        }
 }
 
diff --git a/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs b/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
index 0cada8f..3f92160 100644
--- a/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
+++ b/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
@@ -439,8 +439,7 @@ namespace LongoMatch.Gui
                        if (fileSet != this.fileSet || force) {
                                readyToSeek = false;
                                this.fileSet = fileSet;
-                               angle = MediaFileAngle.Angle1;
-                               activeFile = fileSet.GetAngle (angle);
+                               activeFile = fileSet.First ();
                                if (activeFile.VideoHeight != 0) {
                                        videowindow.Ratio = (float)(activeFile.VideoWidth * activeFile.Par / 
activeFile.VideoHeight);
                                } else {
@@ -581,7 +580,7 @@ namespace LongoMatch.Gui
                {
                        loadedPlaylistElement = video;
                        MediaFileSet fileSet = new MediaFileSet ();
-                       fileSet.SetAngle (MediaFileAngle.Angle1, video.File);
+                       fileSet.Add (video.File);
                        Open (fileSet, false, true, true);
                }
 
diff --git a/LongoMatch.GUI.Multimedia/Gui/Utils/FramesCapturer.cs 
b/LongoMatch.GUI.Multimedia/Gui/Utils/FramesCapturer.cs
index 32ca657..47ad1d5 100644
--- a/LongoMatch.GUI.Multimedia/Gui/Utils/FramesCapturer.cs
+++ b/LongoMatch.GUI.Multimedia/Gui/Utils/FramesCapturer.cs
@@ -20,7 +20,7 @@
 
 using System;
 using System.Threading;
-
+using System.Linq;
 using LongoMatch.Core.Common;
 using LongoMatch.Core.Interfaces.Multimedia;
 using LongoMatch.Video;
@@ -90,7 +90,7 @@ namespace LongoMatch.Video.Utils
                                        break;
                                }
                                Log.Debug ("Start frames series capture for angle " + angle);
-                               MediaFile file = fileSet.GetAngle (angle);
+                               MediaFile file = fileSet.First ();
                                capturer.Open (file.FilePath);
                                pos = new Time {MSeconds = start.MSeconds};
                                if(Progress != null) {
diff --git a/LongoMatch.GUI/Gui/Component/MediaFileChooser.cs 
b/LongoMatch.GUI/Gui/Component/MediaFileChooser.cs
index 14bf728..71f9c8b 100644
--- a/LongoMatch.GUI/Gui/Component/MediaFileChooser.cs
+++ b/LongoMatch.GUI/Gui/Component/MediaFileChooser.cs
@@ -33,20 +33,38 @@ namespace LongoMatch.Gui.Component
                string proposedFileName;
                string proposedDirectoryName;
 
-               public MediaFileChooser ()
+               public MediaFileChooser (String name)
                {
                        this.Build ();
 
+                       nameentry.NoShowAll = true;
+                       clearbutton.NoShowAll = true;
+
+                       // The name entry is only visible when not empty
+                       nameentry.Visible = !String.IsNullOrEmpty (name);
+                       nameentry.Text = name;
+
                        addbuttonimage.Pixbuf = Helpers.Misc.LoadIcon ("longomatch-browse", 
Gtk.IconSize.Button, 0);
+                       clearbuttonimage.Pixbuf = Helpers.Misc.LoadStockIcon (clearbuttonimage, "gtk-clear", 
Gtk.IconSize.Button);
+
                        FilterName = "MP4";
                        FilterExtensions = new string[] { "*.mp4" }; 
                        FileChooserMode = FileChooserMode.MediaFile;
+
                        UpdateFile ();
-                       addbutton.Clicked += HandleClicked;
+
+                       addbutton.Clicked += HandleAddClicked;
+                       clearbutton.Clicked += HandleClearClicked;
+                       nameentry.Changed += HandleNameChanged;
+
                        ProposedFileName = String.Format ("LongoMatch-{0}.mp4", 
DateTime.Now.ToShortDateString ());
                        ProposedDirectoryName = String.Format ("LongoMatch-{0}", 
DateTime.Now.ToShortDateString ()); 
                }
 
+               public MediaFileChooser () : this (null)
+               {
+               }
+
                public FileChooserMode FileChooserMode {
                        get;
                        set;
@@ -92,6 +110,9 @@ namespace LongoMatch.Gui.Component
 
                public MediaFile MediaFile {
                        get {
+                               if (mediaFile != null && nameentry.Visible && !String.IsNullOrEmpty 
(nameentry.Text)) {
+                                       mediaFile.Name = nameentry.Text;
+                               }
                                return mediaFile;
                        }
                        set {
@@ -102,6 +123,8 @@ namespace LongoMatch.Gui.Component
 
                void UpdateFile ()
                {
+                       bool clear_visible = false;
+
                        if (mediaFile != null) {
                                fileentry.Text = System.IO.Path.GetFileName (mediaFile.FilePath);
                                fileentry.TooltipText = mediaFile.FilePath;
@@ -110,19 +133,36 @@ namespace LongoMatch.Gui.Component
                                } else {
                                        fileentry.ModifyText (Gtk.StateType.Normal, Misc.ToGdkColor 
(Color.Red1));
                                }
+                               clear_visible = true;
                        } else if (path != null) {
                                fileentry.Text = System.IO.Path.GetFileName (path);
                                fileentry.TooltipText = path;
+                               clear_visible = true;
                        } else {
                                if (FileChooserMode == FileChooserMode.Directory) {
                                        fileentry.Text = Catalog.GetString ("Select folder...");
                                } else {
                                        fileentry.Text = Catalog.GetString ("Select file...");
                                }
+                               fileentry.TooltipText = fileentry.Text;
                        }
+
+                       clearbutton.Visible = clear_visible;
                }
 
-               void HandleClicked (object sender, EventArgs e)
+               void HandleClearClicked (object sender, EventArgs e)
+               {
+                       mediaFile = null;
+                       path = null;
+
+                       UpdateFile ();
+
+                       if (ChangedEvent != null) {
+                               ChangedEvent (this, null);
+                       }
+               }
+
+               void HandleAddClicked (object sender, EventArgs e)
                {
                        if (FileChooserMode == FileChooserMode.MediaFile) {
                                MediaFile file = Misc.OpenFile (this);
@@ -146,6 +186,13 @@ namespace LongoMatch.Gui.Component
                                ChangedEvent (this, null);
                        }
                }
+
+               void HandleNameChanged (object sender, EventArgs e)
+               {
+                       if (ChangedEvent != null) {
+                               ChangedEvent (this, null);
+                       }
+               }
        }
 }
 
diff --git a/LongoMatch.GUI/Gui/Component/MediaFileSetSelection.cs 
b/LongoMatch.GUI/Gui/Component/MediaFileSetSelection.cs
index 4cda742..f0f6205 100644
--- a/LongoMatch.GUI/Gui/Component/MediaFileSetSelection.cs
+++ b/LongoMatch.GUI/Gui/Component/MediaFileSetSelection.cs
@@ -16,6 +16,8 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
 using System;
+using System.Collections.Generic;
+using Mono.Unix;
 using LongoMatch.Core.Store;
 using LongoMatch.Core.Common;
 using Gtk;
@@ -26,100 +28,78 @@ namespace LongoMatch.Gui.Component
        public partial class MediaFileSetSelection : Gtk.Bin
        {
                MediaFileSet fileSet;
-               bool ignoreChanges;
+               List<MediaFileChooser> fileChoosers;
 
                public MediaFileSetSelection ()
                {
                        this.Build ();
-                       frame2.NoShowAll = true;
-                       frame3.NoShowAll = true;
-                       frame4.NoShowAll = true;
-                       mediafilechooser1.ChangedEvent += HandleFileChangedEvent;
-                       mediafilechooser2.ChangedEvent += HandleFileChangedEvent;
-                       mediafilechooser3.ChangedEvent += HandleFileChangedEvent;
-                       mediafilechooser4.ChangedEvent += HandleFileChangedEvent;
-                       delfile2button.Clicked += HandleFileRemoved;
-                       delfile3button.Clicked += HandleFileRemoved;
-                       delfile4button.Clicked += HandleFileRemoved;
-                       filetable.RowSpacing = StyleConf.NewTableHSpacing;
-                       filetable.ColumnSpacing = StyleConf.NewTeamsSpacing; 
+
+                       fileChoosers = new List<MediaFileChooser> ();
+
+                       // Add the first media file chooser for main camera
+                       AddMediaFileChooser (Catalog.GetString ("Main angle camera"));
                }
 
                public MediaFileSet FileSet {
                        set {
                                fileSet = value;
-                               UpdateMediaFile (mediafilechooser1);
-                               UpdateMediaFile (mediafilechooser2);
-                               UpdateMediaFile (mediafilechooser3);
-                               UpdateMediaFile (mediafilechooser4);
                        }
                        get {
                                return fileSet;
                        }
                }
 
-               void UpdateMediaFile (MediaFileChooser filechooser, MediaFile file = null, bool delete = 
false)
+               void AddMediaFileChooser (String name)
                {
-                       MediaFileAngle angle = MediaFileAngle.Angle1;
-                       Button delbutton = null;
-
-                       ignoreChanges = true;
-                       if (filechooser == mediafilechooser1) {
-                               angle = MediaFileAngle.Angle1;
-                       } else if (filechooser == mediafilechooser2) {
-                               delbutton = delfile2button;
-                               angle = MediaFileAngle.Angle2;
-                       } else if (filechooser == mediafilechooser3) {
-                               delbutton = delfile3button;
-                               angle = MediaFileAngle.Angle3;
-                       } else if (filechooser == mediafilechooser4) {
-                               delbutton = delfile4button;
-                               angle = MediaFileAngle.Angle4;
-                       }
-                       
-                       if (delete) {
-                               FileSet.SetAngle (angle, null);
-                               filechooser.MediaFile = null;
-                       } else {
-                               if (file == null) {
-                                       filechooser.MediaFile = FileSet.GetAngle (angle);
+                       Alignment alignment = new Alignment (0.0f, 0.5f, 0.0f, 0.0f);
+                       MediaFileChooser chooser = new MediaFileChooser (name);
+
+                       chooser.ChangedEvent += HandleFileChangedEvent;
+                       alignment.Add (chooser);
+                       alignment.ShowAll ();
+
+                       mfss_vbox.PackStart (alignment, true, false, 0);
+
+                       fileChoosers.Add (chooser);
+               }
+
+               void UpdateFileSet ()
+               {
+                       bool have_empty_chooser = false;
+                       List<MediaFileChooser> to_remove = new List<MediaFileChooser> ();
+
+                       fileSet.Clear ();
+
+                       foreach (MediaFileChooser chooser in fileChoosers) {
+                               if (chooser.MediaFile != null) {
+                                       fileSet.Add (chooser.MediaFile);
                                } else {
-                                       FileSet.SetAngle (angle, file);
-                                       filechooser.MediaFile = file;
+                                       if (!have_empty_chooser) {
+                                               have_empty_chooser = true;
+                                       } else {
+                                               // Mark for removal as we only want one empty file chooser at 
most
+                                               to_remove.Add (chooser);
+                                       }
                                }
                        }
 
-                       if (delbutton != null) {
-                               delbutton.Visible = filechooser.MediaFile != null;
+                       foreach (MediaFileChooser chooser in to_remove) {
+                               chooser.ChangedEvent -= HandleFileChangedEvent;
+                               fileChoosers.Remove (chooser);
+                               mfss_vbox.Remove (chooser.Parent);
                        }
 
+                       to_remove.Clear ();
 
-                       ignoreChanges = false;
-               }
-
-               void HandleFileChangedEvent (object sender, EventArgs e)
-               {
-                       if (ignoreChanges) {
-                               return;
+                       if (!have_empty_chooser) {
+                               AddMediaFileChooser (String.Format ("{0} {1}", Catalog.GetString ("Angle"), 
fileChoosers.Count));
                        }
-                       MediaFileChooser filechooser = sender as MediaFileChooser;
-                       UpdateMediaFile (filechooser, filechooser.MediaFile);
                }
 
-               void HandleFileRemoved (object sender, EventArgs e)
+               void HandleFileChangedEvent (object sender, EventArgs e)
                {
-                       MediaFileChooser filechooser = null;
-
-                       if (sender == delfile2button) {
-                               filechooser = mediafilechooser2;
-                       } else if (sender == delfile3button) {
-                               filechooser = mediafilechooser3;
-                       } else if (sender == delfile4button) {
-                               filechooser = mediafilechooser4;
-                       }
-                       UpdateMediaFile (filechooser, null, true);
+                       UpdateFileSet ();
                }
-
        }
 }
 
diff --git a/LongoMatch.GUI/Gui/Component/ProjectListWidget.cs 
b/LongoMatch.GUI/Gui/Component/ProjectListWidget.cs
index 6af51d7..591632c 100644
--- a/LongoMatch.GUI/Gui/Component/ProjectListWidget.cs
+++ b/LongoMatch.GUI/Gui/Component/ProjectListWidget.cs
@@ -18,6 +18,7 @@
 //
 //
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using Gdk;
 using Gtk;
@@ -98,7 +99,7 @@ namespace LongoMatch.Gui.Component
                        this.projects = projects;
                        store.Clear ();
                        foreach (ProjectDescription pdesc in projects) {
-                               MediaFile file = pdesc.FileSet.GetAngle (MediaFileAngle.Angle1);
+                               MediaFile file = pdesc.FileSet.FirstOrDefault ();
                                if (file != null && file.FilePath == Constants.FAKE_PROJECT) {
                                        image = Misc.LoadIcon ("longomatch-video-device-fake", 50);
                                } else if (pdesc.FileSet.Preview != null) {
diff --git a/LongoMatch.GUI/Gui/Component/ProjectPeriods.cs b/LongoMatch.GUI/Gui/Component/ProjectPeriods.cs
index 6e84b64..c5a45f0 100644
--- a/LongoMatch.GUI/Gui/Component/ProjectPeriods.cs
+++ b/LongoMatch.GUI/Gui/Component/ProjectPeriods.cs
@@ -109,7 +109,7 @@ namespace LongoMatch.Gui.Component
                                this.project = value;
                                gamePeriods = value.Dashboard.GamePeriods;
 
-                               file = value.Description.FileSet.GetAngle (MediaFileAngle.Angle1);
+                               file = value.Description.FileSet.FirstOrDefault ();
                                start = new Time (0);
                                duration = file.Duration;
                                pDuration = new Time (duration.MSeconds / gamePeriods.Count);
diff --git a/LongoMatch.GUI/Gui/Component/Timeline.cs b/LongoMatch.GUI/Gui/Component/Timeline.cs
index 76b1238..3301685 100644
--- a/LongoMatch.GUI/Gui/Component/Timeline.cs
+++ b/LongoMatch.GUI/Gui/Component/Timeline.cs
@@ -16,6 +16,7 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
 using System;
+using System.Linq;
 using LongoMatch.Drawing.Widgets;
 using LongoMatch.Core.Store;
 using LongoMatch.Core.Common;
@@ -130,7 +131,8 @@ namespace LongoMatch.Gui.Component
                                timeoutID = GLib.Timeout.Add (TIMEOUT_MS, UpdateTime);
                        }
                        focusscale.Value = 6;
-                       timerule.Duration = project.Description.FileSet.GetAngle 
(MediaFileAngle.Angle1).Duration;
+                       // Can throw an exception if there are no files in set
+                       timerule.Duration = project.Description.FileSet.First ().Duration;
                        timeline.ShowMenuEvent += HandleShowMenu;
                        timeline.ShowTimersMenuEvent += HandleShowTimersMenu;
                        timeline.ShowTimerMenuEvent += HandleShowTimerMenuEvent;
diff --git a/LongoMatch.GUI/Gui/Component/VideoFileInfo.cs b/LongoMatch.GUI/Gui/Component/VideoFileInfo.cs
index 0abc958..7bb66da 100644
--- a/LongoMatch.GUI/Gui/Component/VideoFileInfo.cs
+++ b/LongoMatch.GUI/Gui/Component/VideoFileInfo.cs
@@ -16,6 +16,7 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
 using System;
+using System.Linq;
 using Mono.Unix;
 using LongoMatch.Core.Common;
 using LongoMatch.Core.Store;
@@ -44,7 +45,8 @@ namespace LongoMatch.Gui.Component
                {
                        this.fileSet = fileSet;
                        this.angle = angle;
-                       mediaFile = fileSet.GetAngle (angle);
+                       // FIXME: use first file for now
+                       mediaFile = fileSet.First ();
                        disableChanges = false;
                        UpdateMediaFile ();
                }
@@ -102,7 +104,8 @@ namespace LongoMatch.Gui.Component
                                if (mediaFile != null) {
                                        file.Offset = mediaFile.Offset;
                                }
-                               fileSet.SetAngle (angle, file);
+                               // FIXME: Change file for a given name in list
+                               fileSet.Add (file);
                                mediaFile = file;
                                UpdateMediaFile ();
                        }
diff --git a/LongoMatch.GUI/Gui/GUIToolkit.cs b/LongoMatch.GUI/Gui/GUIToolkit.cs
index 81d7b80..aa2f5ad 100644
--- a/LongoMatch.GUI/Gui/GUIToolkit.cs
+++ b/LongoMatch.GUI/Gui/GUIToolkit.cs
@@ -418,7 +418,7 @@ namespace LongoMatch.Gui
                                        WarningMessage (Catalog.GetString ("Some video files are still 
missing for this project."), d);
                                        continue;
                                }
-                               if (fileselector.FileSet.GetAngle (MediaFileAngle.Angle1) == null) {
+                               if (fileselector.FileSet.Count == 0) {
                                        WarningMessage (Catalog.GetString ("You need at least 1 video file 
for the main angle"));
                                        continue;
                                }
diff --git a/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs b/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs
index 7dc2b6d..54e2ba8 100644
--- a/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs
+++ b/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs
@@ -397,13 +397,13 @@ namespace LongoMatch.Gui.Panel
                        
                        captureSettings.EncodingSettings = encSettings;
 
-                       file = project.Description.FileSet.GetAngle (MediaFileAngle.Angle1); 
+                       file = project.Description.FileSet.FirstOrDefault (); 
                        if (file == null) {
-                               file = new MediaFile ();
+                               file = new MediaFile () { Name = Catalog.GetString ("Main angle camera") };
                                file.FilePath = capturemediafilechooser.CurrentPath;
                                file.Fps = (ushort)(Config.FPS_N / Config.FPS_D);
                                file.Par = 1;
-                               project.Description.FileSet.SetAngle (MediaFileAngle.Angle1, file);
+                               project.Description.FileSet.Add (file);
                        }
                        
                        if (projectType == ProjectType.CaptureProject) {
diff --git a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileChooser.cs 
b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileChooser.cs
index bc39bf7..b798431 100644
--- a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileChooser.cs
+++ b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileChooser.cs
@@ -5,9 +5,19 @@ namespace LongoMatch.Gui.Component
        public partial class MediaFileChooser
        {
                private global::Gtk.EventBox fileentryeventbox;
+               
                private global::Gtk.HBox hbox1;
+               
+               private global::Gtk.Entry nameentry;
+               
                private global::Gtk.Entry fileentry;
+               
+               private global::Gtk.Button clearbutton;
+               
+               private global::Gtk.Image clearbuttonimage;
+               
                private global::Gtk.Button addbutton;
+               
                private global::Gtk.Image addbuttonimage;
 
                protected virtual void Build ()
@@ -24,6 +34,16 @@ namespace LongoMatch.Gui.Component
                        this.hbox1.Name = "hbox1";
                        this.hbox1.BorderWidth = ((uint)(2));
                        // Container child hbox1.Gtk.Box+BoxChild
+                       this.nameentry = new global::Gtk.Entry ();
+                       this.nameentry.CanFocus = true;
+                       this.nameentry.Name = "nameentry";
+                       this.nameentry.IsEditable = true;
+                       this.nameentry.HasFrame = false;
+                       this.nameentry.InvisibleChar = '•';
+                       this.hbox1.Add (this.nameentry);
+                       global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.hbox1 
[this.nameentry]));
+                       w1.Position = 0;
+                       // Container child hbox1.Gtk.Box+BoxChild
                        this.fileentry = new global::Gtk.Entry ();
                        this.fileentry.CanFocus = true;
                        this.fileentry.Name = "fileentry";
@@ -31,8 +51,21 @@ namespace LongoMatch.Gui.Component
                        this.fileentry.HasFrame = false;
                        this.fileentry.InvisibleChar = '•';
                        this.hbox1.Add (this.fileentry);
-                       global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.hbox1 
[this.fileentry]));
-                       w1.Position = 0;
+                       global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox1 
[this.fileentry]));
+                       w2.Position = 1;
+                       // Container child hbox1.Gtk.Box+BoxChild
+                       this.clearbutton = new global::Gtk.Button ();
+                       this.clearbutton.CanFocus = true;
+                       this.clearbutton.Name = "clearbutton";
+                       // Container child clearbutton.Gtk.Container+ContainerChild
+                       this.clearbuttonimage = new global::Gtk.Image ();
+                       this.clearbuttonimage.Name = "clearbuttonimage";
+                       this.clearbutton.Add (this.clearbuttonimage);
+                       this.hbox1.Add (this.clearbutton);
+                       global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1 
[this.clearbutton]));
+                       w4.Position = 2;
+                       w4.Expand = false;
+                       w4.Fill = false;
                        // Container child hbox1.Gtk.Box+BoxChild
                        this.addbutton = new global::Gtk.Button ();
                        this.addbutton.CanFocus = true;
@@ -41,17 +74,17 @@ namespace LongoMatch.Gui.Component
                        this.addbuttonimage = new global::Gtk.Image ();
                        this.addbuttonimage.Name = "addbuttonimage";
                        this.addbutton.Add (this.addbuttonimage);
-                       this.addbutton.Label = null;
                        this.hbox1.Add (this.addbutton);
-                       global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1 
[this.addbutton]));
-                       w3.Position = 1;
-                       w3.Expand = false;
-                       w3.Fill = false;
+                       global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.hbox1 
[this.addbutton]));
+                       w6.Position = 3;
+                       w6.Expand = false;
+                       w6.Fill = false;
                        this.fileentryeventbox.Add (this.hbox1);
                        this.Add (this.fileentryeventbox);
                        if ((this.Child != null)) {
                                this.Child.ShowAll ();
                        }
+                       this.nameentry.Hide ();
                        this.Hide ();
                }
        }
diff --git a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileSetSelection.cs 
b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileSetSelection.cs
index 599245d..2d21945 100644
--- a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileSetSelection.cs
+++ b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.MediaFileSetSelection.cs
@@ -4,29 +4,9 @@ namespace LongoMatch.Gui.Component
 {
        public partial class MediaFileSetSelection
        {
-               private global::Gtk.Table filetable;
-               private global::Gtk.Frame frame1;
-               private global::Gtk.Alignment GtkAlignment3;
-               private global::LongoMatch.Gui.Component.MediaFileChooser mediafilechooser1;
-               private global::Gtk.Label GtkLabel3;
-               private global::Gtk.Frame frame2;
-               private global::Gtk.Alignment GtkAlignment2;
-               private global::Gtk.HBox file2box;
-               private global::LongoMatch.Gui.Component.MediaFileChooser mediafilechooser2;
-               private global::Gtk.Button delfile2button;
-               private global::Gtk.Label GtkLabel2;
-               private global::Gtk.Frame frame3;
-               private global::Gtk.Alignment GtkAlignment1;
-               private global::Gtk.HBox file3box;
-               private global::LongoMatch.Gui.Component.MediaFileChooser mediafilechooser3;
-               private global::Gtk.Button delfile3button;
-               private global::Gtk.Label GtkLabel4;
-               private global::Gtk.Frame frame4;
-               private global::Gtk.Alignment GtkAlignment;
-               private global::Gtk.HBox file4box;
-               private global::LongoMatch.Gui.Component.MediaFileChooser mediafilechooser4;
-               private global::Gtk.Button delfile4button;
-               private global::Gtk.Label GtkLabel5;
+               private global::Gtk.ScrolledWindow mfss_scrolledwindow;
+               
+               private global::Gtk.VBox mfss_vbox;
 
                protected virtual void Build ()
                {
@@ -35,207 +15,24 @@ namespace LongoMatch.Gui.Component
                        global::Stetic.BinContainer.Attach (this);
                        this.Name = "LongoMatch.Gui.Component.MediaFileSetSelection";
                        // Container child 
LongoMatch.Gui.Component.MediaFileSetSelection.Gtk.Container+ContainerChild
-                       this.filetable = new global::Gtk.Table (((uint)(2)), ((uint)(2)), true);
-                       this.filetable.Name = "filetable";
-                       this.filetable.RowSpacing = ((uint)(6));
-                       this.filetable.ColumnSpacing = ((uint)(6));
-                       // Container child filetable.Gtk.Table+TableChild
-                       this.frame1 = new global::Gtk.Frame ();
-                       this.frame1.Name = "frame1";
-                       this.frame1.ShadowType = ((global::Gtk.ShadowType)(0));
-                       // Container child frame1.Gtk.Container+ContainerChild
-                       this.GtkAlignment3 = new global::Gtk.Alignment (0F, 0F, 1F, 1F);
-                       this.GtkAlignment3.Name = "GtkAlignment3";
-                       this.GtkAlignment3.LeftPadding = ((uint)(12));
-                       this.GtkAlignment3.BorderWidth = ((uint)(2));
-                       // Container child GtkAlignment3.Gtk.Container+ContainerChild
-                       this.mediafilechooser1 = new global::LongoMatch.Gui.Component.MediaFileChooser ();
-                       this.mediafilechooser1.Events = ((global::Gdk.EventMask)(256));
-                       this.mediafilechooser1.Name = "mediafilechooser1";
-                       this.GtkAlignment3.Add (this.mediafilechooser1);
-                       this.frame1.Add (this.GtkAlignment3);
-                       this.GtkLabel3 = new global::Gtk.Label ();
-                       this.GtkLabel3.Name = "GtkLabel3";
-                       this.GtkLabel3.LabelProp = global::Mono.Unix.Catalog.GetString ("<b>Main camera 
angle</b>");
-                       this.GtkLabel3.UseMarkup = true;
-                       this.frame1.LabelWidget = this.GtkLabel3;
-                       this.filetable.Add (this.frame1);
-                       global::Gtk.Table.TableChild w3 = ((global::Gtk.Table.TableChild)(this.filetable 
[this.frame1]));
-                       w3.YOptions = ((global::Gtk.AttachOptions)(4));
-                       // Container child filetable.Gtk.Table+TableChild
-                       this.frame2 = new global::Gtk.Frame ();
-                       this.frame2.Name = "frame2";
-                       this.frame2.ShadowType = ((global::Gtk.ShadowType)(0));
-                       // Container child frame2.Gtk.Container+ContainerChild
-                       this.GtkAlignment2 = new global::Gtk.Alignment (0F, 0F, 1F, 1F);
-                       this.GtkAlignment2.Name = "GtkAlignment2";
-                       this.GtkAlignment2.LeftPadding = ((uint)(12));
-                       this.GtkAlignment2.BorderWidth = ((uint)(2));
-                       // Container child GtkAlignment2.Gtk.Container+ContainerChild
-                       this.file2box = new global::Gtk.HBox ();
-                       this.file2box.Name = "file2box";
-                       // Container child file2box.Gtk.Box+BoxChild
-                       this.mediafilechooser2 = new global::LongoMatch.Gui.Component.MediaFileChooser ();
-                       this.mediafilechooser2.Events = ((global::Gdk.EventMask)(256));
-                       this.mediafilechooser2.Name = "mediafilechooser2";
-                       this.file2box.Add (this.mediafilechooser2);
-                       global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.file2box 
[this.mediafilechooser2]));
-                       w4.Position = 0;
-                       // Container child file2box.Gtk.Box+BoxChild
-                       this.delfile2button = new global::Gtk.Button ();
-                       this.delfile2button.CanFocus = true;
-                       this.delfile2button.Name = "delfile2button";
-                       this.delfile2button.UseUnderline = true;
-                       // Container child delfile2button.Gtk.Container+ContainerChild
-                       global::Gtk.Alignment w5 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
-                       // Container child GtkAlignment.Gtk.Container+ContainerChild
-                       global::Gtk.HBox w6 = new global::Gtk.HBox ();
-                       w6.Spacing = 2;
-                       // Container child GtkHBox.Gtk.Container+ContainerChild
-                       global::Gtk.Image w7 = new global::Gtk.Image ();
-                       w7.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-remove", 
global::Gtk.IconSize.Menu);
-                       w6.Add (w7);
-                       // Container child GtkHBox.Gtk.Container+ContainerChild
-                       global::Gtk.Label w9 = new global::Gtk.Label ();
-                       w6.Add (w9);
-                       w5.Add (w6);
-                       this.delfile2button.Add (w5);
-                       this.file2box.Add (this.delfile2button);
-                       global::Gtk.Box.BoxChild w13 = ((global::Gtk.Box.BoxChild)(this.file2box 
[this.delfile2button]));
-                       w13.Position = 1;
-                       w13.Expand = false;
-                       w13.Fill = false;
-                       this.GtkAlignment2.Add (this.file2box);
-                       this.frame2.Add (this.GtkAlignment2);
-                       this.GtkLabel2 = new global::Gtk.Label ();
-                       this.GtkLabel2.Name = "GtkLabel2";
-                       this.GtkLabel2.LabelProp = global::Mono.Unix.Catalog.GetString ("<b>Angle 2</b>");
-                       this.GtkLabel2.UseMarkup = true;
-                       this.frame2.LabelWidget = this.GtkLabel2;
-                       this.filetable.Add (this.frame2);
-                       global::Gtk.Table.TableChild w16 = ((global::Gtk.Table.TableChild)(this.filetable 
[this.frame2]));
-                       w16.LeftAttach = ((uint)(1));
-                       w16.RightAttach = ((uint)(2));
-                       w16.YOptions = ((global::Gtk.AttachOptions)(4));
-                       // Container child filetable.Gtk.Table+TableChild
-                       this.frame3 = new global::Gtk.Frame ();
-                       this.frame3.Name = "frame3";
-                       this.frame3.ShadowType = ((global::Gtk.ShadowType)(0));
-                       // Container child frame3.Gtk.Container+ContainerChild
-                       this.GtkAlignment1 = new global::Gtk.Alignment (0F, 0F, 1F, 1F);
-                       this.GtkAlignment1.Name = "GtkAlignment1";
-                       this.GtkAlignment1.LeftPadding = ((uint)(12));
-                       this.GtkAlignment1.BorderWidth = ((uint)(2));
-                       // Container child GtkAlignment1.Gtk.Container+ContainerChild
-                       this.file3box = new global::Gtk.HBox ();
-                       this.file3box.Name = "file3box";
-                       // Container child file3box.Gtk.Box+BoxChild
-                       this.mediafilechooser3 = new global::LongoMatch.Gui.Component.MediaFileChooser ();
-                       this.mediafilechooser3.Events = ((global::Gdk.EventMask)(256));
-                       this.mediafilechooser3.Name = "mediafilechooser3";
-                       this.file3box.Add (this.mediafilechooser3);
-                       global::Gtk.Box.BoxChild w17 = ((global::Gtk.Box.BoxChild)(this.file3box 
[this.mediafilechooser3]));
-                       w17.Position = 0;
-                       // Container child file3box.Gtk.Box+BoxChild
-                       this.delfile3button = new global::Gtk.Button ();
-                       this.delfile3button.CanFocus = true;
-                       this.delfile3button.Name = "delfile3button";
-                       this.delfile3button.UseUnderline = true;
-                       // Container child delfile3button.Gtk.Container+ContainerChild
-                       global::Gtk.Alignment w18 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
-                       // Container child GtkAlignment.Gtk.Container+ContainerChild
-                       global::Gtk.HBox w19 = new global::Gtk.HBox ();
-                       w19.Spacing = 2;
-                       // Container child GtkHBox.Gtk.Container+ContainerChild
-                       global::Gtk.Image w20 = new global::Gtk.Image ();
-                       w20.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-remove", 
global::Gtk.IconSize.Menu);
-                       w19.Add (w20);
-                       // Container child GtkHBox.Gtk.Container+ContainerChild
-                       global::Gtk.Label w22 = new global::Gtk.Label ();
-                       w19.Add (w22);
-                       w18.Add (w19);
-                       this.delfile3button.Add (w18);
-                       this.file3box.Add (this.delfile3button);
-                       global::Gtk.Box.BoxChild w26 = ((global::Gtk.Box.BoxChild)(this.file3box 
[this.delfile3button]));
-                       w26.Position = 1;
-                       w26.Expand = false;
-                       w26.Fill = false;
-                       this.GtkAlignment1.Add (this.file3box);
-                       this.frame3.Add (this.GtkAlignment1);
-                       this.GtkLabel4 = new global::Gtk.Label ();
-                       this.GtkLabel4.Name = "GtkLabel4";
-                       this.GtkLabel4.LabelProp = global::Mono.Unix.Catalog.GetString ("<b>Angle 3</b>");
-                       this.GtkLabel4.UseMarkup = true;
-                       this.frame3.LabelWidget = this.GtkLabel4;
-                       this.filetable.Add (this.frame3);
-                       global::Gtk.Table.TableChild w29 = ((global::Gtk.Table.TableChild)(this.filetable 
[this.frame3]));
-                       w29.TopAttach = ((uint)(1));
-                       w29.BottomAttach = ((uint)(2));
-                       w29.YOptions = ((global::Gtk.AttachOptions)(4));
-                       // Container child filetable.Gtk.Table+TableChild
-                       this.frame4 = new global::Gtk.Frame ();
-                       this.frame4.Name = "frame4";
-                       this.frame4.ShadowType = ((global::Gtk.ShadowType)(0));
-                       // Container child frame4.Gtk.Container+ContainerChild
-                       this.GtkAlignment = new global::Gtk.Alignment (0F, 0F, 1F, 1F);
-                       this.GtkAlignment.Name = "GtkAlignment";
-                       this.GtkAlignment.LeftPadding = ((uint)(12));
-                       this.GtkAlignment.BorderWidth = ((uint)(2));
-                       // Container child GtkAlignment.Gtk.Container+ContainerChild
-                       this.file4box = new global::Gtk.HBox ();
-                       this.file4box.Name = "file4box";
-                       // Container child file4box.Gtk.Box+BoxChild
-                       this.mediafilechooser4 = new global::LongoMatch.Gui.Component.MediaFileChooser ();
-                       this.mediafilechooser4.Events = ((global::Gdk.EventMask)(256));
-                       this.mediafilechooser4.Name = "mediafilechooser4";
-                       this.file4box.Add (this.mediafilechooser4);
-                       global::Gtk.Box.BoxChild w30 = ((global::Gtk.Box.BoxChild)(this.file4box 
[this.mediafilechooser4]));
-                       w30.Position = 0;
-                       // Container child file4box.Gtk.Box+BoxChild
-                       this.delfile4button = new global::Gtk.Button ();
-                       this.delfile4button.CanFocus = true;
-                       this.delfile4button.Name = "delfile4button";
-                       this.delfile4button.UseUnderline = true;
-                       // Container child delfile4button.Gtk.Container+ContainerChild
-                       global::Gtk.Alignment w31 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
-                       // Container child GtkAlignment.Gtk.Container+ContainerChild
-                       global::Gtk.HBox w32 = new global::Gtk.HBox ();
-                       w32.Spacing = 2;
-                       // Container child GtkHBox.Gtk.Container+ContainerChild
-                       global::Gtk.Image w33 = new global::Gtk.Image ();
-                       w33.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-remove", 
global::Gtk.IconSize.Menu);
-                       w32.Add (w33);
-                       // Container child GtkHBox.Gtk.Container+ContainerChild
-                       global::Gtk.Label w35 = new global::Gtk.Label ();
-                       w32.Add (w35);
-                       w31.Add (w32);
-                       this.delfile4button.Add (w31);
-                       this.file4box.Add (this.delfile4button);
-                       global::Gtk.Box.BoxChild w39 = ((global::Gtk.Box.BoxChild)(this.file4box 
[this.delfile4button]));
-                       w39.Position = 1;
-                       w39.Expand = false;
-                       w39.Fill = false;
-                       this.GtkAlignment.Add (this.file4box);
-                       this.frame4.Add (this.GtkAlignment);
-                       this.GtkLabel5 = new global::Gtk.Label ();
-                       this.GtkLabel5.Name = "GtkLabel5";
-                       this.GtkLabel5.LabelProp = global::Mono.Unix.Catalog.GetString ("<b>Angle 4</b>");
-                       this.GtkLabel5.UseMarkup = true;
-                       this.frame4.LabelWidget = this.GtkLabel5;
-                       this.filetable.Add (this.frame4);
-                       global::Gtk.Table.TableChild w42 = ((global::Gtk.Table.TableChild)(this.filetable 
[this.frame4]));
-                       w42.TopAttach = ((uint)(1));
-                       w42.BottomAttach = ((uint)(2));
-                       w42.LeftAttach = ((uint)(1));
-                       w42.RightAttach = ((uint)(2));
-                       w42.YOptions = ((global::Gtk.AttachOptions)(4));
-                       this.Add (this.filetable);
+                       this.mfss_scrolledwindow = new global::Gtk.ScrolledWindow ();
+                       this.mfss_scrolledwindow.CanFocus = true;
+                       this.mfss_scrolledwindow.Name = "mfss_scrolledwindow";
+                       this.mfss_scrolledwindow.HscrollbarPolicy = ((global::Gtk.PolicyType)(2));
+                       this.mfss_scrolledwindow.ShadowType = ((global::Gtk.ShadowType)(1));
+                       // Container child mfss_scrolledwindow.Gtk.Container+ContainerChild
+                       global::Gtk.Viewport w1 = new global::Gtk.Viewport ();
+                       w1.ShadowType = ((global::Gtk.ShadowType)(0));
+                       // Container child GtkViewport.Gtk.Container+ContainerChild
+                       this.mfss_vbox = new global::Gtk.VBox ();
+                       this.mfss_vbox.Name = "mfss_vbox";
+                       this.mfss_vbox.Spacing = 6;
+                       w1.Add (this.mfss_vbox);
+                       this.mfss_scrolledwindow.Add (w1);
+                       this.Add (this.mfss_scrolledwindow);
                        if ((this.Child != null)) {
                                this.Child.ShowAll ();
                        }
-                       this.frame2.Hide ();
-                       this.frame3.Hide ();
-                       this.frame4.Hide ();
                        this.Hide ();
                }
        }
diff --git a/LongoMatch.GUI/gtk-gui/gui.stetic b/LongoMatch.GUI/gtk-gui/gui.stetic
index 5bcde7e..bdaf26a 100644
--- a/LongoMatch.GUI/gtk-gui/gui.stetic
+++ b/LongoMatch.GUI/gtk-gui/gui.stetic
@@ -9910,7 +9910,7 @@ You can continue with the current capture, cancel it or save your project.
       </widget>
     </child>
   </widget>
-  <widget class="Gtk.Bin" id="LongoMatch.Gui.Component.MediaFileChooser" design-size="259 64">
+  <widget class="Gtk.Bin" id="LongoMatch.Gui.Component.MediaFileChooser" design-size="490 64">
     <property name="MemberName" />
     <property name="Visible">False</property>
     <child>
@@ -9921,6 +9921,20 @@ You can continue with the current capture, cancel it or save your project.
             <property name="MemberName" />
             <property name="BorderWidth">2</property>
             <child>
+              <widget class="Gtk.Entry" id="nameentry">
+                <property name="MemberName" />
+                <property name="Visible">False</property>
+                <property name="CanFocus">True</property>
+                <property name="IsEditable">True</property>
+                <property name="HasFrame">False</property>
+                <property name="InvisibleChar">•</property>
+              </widget>
+              <packing>
+                <property name="Position">0</property>
+                <property name="AutoSize">True</property>
+              </packing>
+            </child>
+            <child>
               <widget class="Gtk.Entry" id="fileentry">
                 <property name="MemberName" />
                 <property name="CanFocus">True</property>
@@ -9929,11 +9943,29 @@ You can continue with the current capture, cancel it or save your project.
                 <property name="InvisibleChar">•</property>
               </widget>
               <packing>
-                <property name="Position">0</property>
+                <property name="Position">1</property>
                 <property name="AutoSize">True</property>
               </packing>
             </child>
             <child>
+              <widget class="Gtk.Button" id="clearbutton">
+                <property name="MemberName" />
+                <property name="CanFocus">True</property>
+                <property name="Type">Custom</property>
+                <child>
+                  <widget class="Gtk.Image" id="clearbuttonimage">
+                    <property name="MemberName" />
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="Position">2</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+            <child>
               <widget class="Gtk.Button" id="addbutton">
                 <property name="MemberName" />
                 <property name="CanFocus">True</property>
@@ -9945,7 +9977,7 @@ You can continue with the current capture, cancel it or save your project.
                 </child>
               </widget>
               <packing>
-                <property name="Position">1</property>
+                <property name="Position">3</property>
                 <property name="AutoSize">True</property>
                 <property name="Expand">False</property>
                 <property name="Fill">False</property>
@@ -10532,266 +10564,35 @@ You can continue with the current capture, cancel it or save your project.
       </widget>
     </child>
   </widget>
-  <widget class="Gtk.Bin" id="LongoMatch.Gui.Component.MediaFileSetSelection" design-size="542 180">
+  <widget class="Gtk.Bin" id="LongoMatch.Gui.Component.MediaFileSetSelection" design-size="1058 180">
     <property name="MemberName" />
     <property name="Visible">False</property>
     <child>
-      <widget class="Gtk.Table" id="filetable">
+      <widget class="Gtk.ScrolledWindow" id="mfss_scrolledwindow">
         <property name="MemberName" />
-        <property name="NRows">2</property>
-        <property name="NColumns">2</property>
-        <property name="Homogeneous">True</property>
-        <property name="RowSpacing">6</property>
-        <property name="ColumnSpacing">6</property>
+        <property name="CanFocus">True</property>
+        <property name="HscrollbarPolicy">Never</property>
+        <property name="ShadowType">In</property>
         <child>
-          <widget class="Gtk.Frame" id="frame1">
+          <widget class="Gtk.Viewport" id="GtkViewport">
             <property name="MemberName" />
             <property name="ShadowType">None</property>
             <child>
-              <widget class="Gtk.Alignment" id="GtkAlignment3">
+              <widget class="Gtk.VBox" id="mfss_vbox">
                 <property name="MemberName" />
-                <property name="Xalign">0</property>
-                <property name="Yalign">0</property>
-                <property name="LeftPadding">12</property>
-                <property name="BorderWidth">2</property>
+                <property name="Spacing">6</property>
                 <child>
-                  <widget class="LongoMatch.Gui.Component.MediaFileChooser" id="mediafilechooser1">
-                    <property name="MemberName" />
-                    <property name="Events">ButtonPressMask</property>
-                  </widget>
+                  <placeholder />
                 </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="Gtk.Label" id="GtkLabel3">
-                <property name="MemberName" />
-                <property name="LabelProp" translatable="yes">&lt;b&gt;Main camera angle&lt;/b&gt;</property>
-                <property name="UseMarkup">True</property>
-              </widget>
-              <packing>
-                <property name="type">label_item</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="AutoSize">False</property>
-            <property name="YOptions">Fill</property>
-            <property name="XExpand">True</property>
-            <property name="XFill">True</property>
-            <property name="XShrink">False</property>
-            <property name="YExpand">False</property>
-            <property name="YFill">True</property>
-            <property name="YShrink">False</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="Gtk.Frame" id="frame2">
-            <property name="MemberName" />
-            <property name="Visible">False</property>
-            <property name="ShadowType">None</property>
-            <child>
-              <widget class="Gtk.Alignment" id="GtkAlignment2">
-                <property name="MemberName" />
-                <property name="Xalign">0</property>
-                <property name="Yalign">0</property>
-                <property name="LeftPadding">12</property>
-                <property name="BorderWidth">2</property>
                 <child>
-                  <widget class="Gtk.HBox" id="file2box">
-                    <property name="MemberName" />
-                    <child>
-                      <widget class="LongoMatch.Gui.Component.MediaFileChooser" id="mediafilechooser2">
-                        <property name="MemberName" />
-                        <property name="Events">ButtonPressMask</property>
-                      </widget>
-                      <packing>
-                        <property name="Position">0</property>
-                        <property name="AutoSize">True</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="Gtk.Button" id="delfile2button">
-                        <property name="MemberName" />
-                        <property name="CanFocus">True</property>
-                        <property name="Type">TextAndIcon</property>
-                        <property name="Icon">stock:gtk-remove Menu</property>
-                        <property name="Label" translatable="yes" />
-                        <property name="UseUnderline">True</property>
-                      </widget>
-                      <packing>
-                        <property name="Position">1</property>
-                        <property name="AutoSize">True</property>
-                        <property name="Expand">False</property>
-                        <property name="Fill">False</property>
-                      </packing>
-                    </child>
-                  </widget>
-                </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="Gtk.Label" id="GtkLabel2">
-                <property name="MemberName" />
-                <property name="LabelProp" translatable="yes">&lt;b&gt;Angle 2&lt;/b&gt;</property>
-                <property name="UseMarkup">True</property>
-              </widget>
-              <packing>
-                <property name="type">label_item</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="LeftAttach">1</property>
-            <property name="RightAttach">2</property>
-            <property name="AutoSize">False</property>
-            <property name="YOptions">Fill</property>
-            <property name="XExpand">True</property>
-            <property name="XFill">True</property>
-            <property name="XShrink">False</property>
-            <property name="YExpand">False</property>
-            <property name="YFill">True</property>
-            <property name="YShrink">False</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="Gtk.Frame" id="frame3">
-            <property name="MemberName" />
-            <property name="Visible">False</property>
-            <property name="ShadowType">None</property>
-            <child>
-              <widget class="Gtk.Alignment" id="GtkAlignment1">
-                <property name="MemberName" />
-                <property name="Xalign">0</property>
-                <property name="Yalign">0</property>
-                <property name="LeftPadding">12</property>
-                <property name="BorderWidth">2</property>
-                <child>
-                  <widget class="Gtk.HBox" id="file3box">
-                    <property name="MemberName" />
-                    <child>
-                      <widget class="LongoMatch.Gui.Component.MediaFileChooser" id="mediafilechooser3">
-                        <property name="MemberName" />
-                        <property name="Events">ButtonPressMask</property>
-                      </widget>
-                      <packing>
-                        <property name="Position">0</property>
-                        <property name="AutoSize">True</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="Gtk.Button" id="delfile3button">
-                        <property name="MemberName" />
-                        <property name="CanFocus">True</property>
-                        <property name="Type">TextAndIcon</property>
-                        <property name="Icon">stock:gtk-remove Menu</property>
-                        <property name="Label" translatable="yes" />
-                        <property name="UseUnderline">True</property>
-                      </widget>
-                      <packing>
-                        <property name="Position">1</property>
-                        <property name="AutoSize">True</property>
-                        <property name="Expand">False</property>
-                        <property name="Fill">False</property>
-                      </packing>
-                    </child>
-                  </widget>
+                  <placeholder />
                 </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="Gtk.Label" id="GtkLabel4">
-                <property name="MemberName" />
-                <property name="LabelProp" translatable="yes">&lt;b&gt;Angle 3&lt;/b&gt;</property>
-                <property name="UseMarkup">True</property>
-              </widget>
-              <packing>
-                <property name="type">label_item</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="TopAttach">1</property>
-            <property name="BottomAttach">2</property>
-            <property name="AutoSize">False</property>
-            <property name="YOptions">Fill</property>
-            <property name="XExpand">True</property>
-            <property name="XFill">True</property>
-            <property name="XShrink">False</property>
-            <property name="YExpand">False</property>
-            <property name="YFill">True</property>
-            <property name="YShrink">False</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="Gtk.Frame" id="frame4">
-            <property name="MemberName" />
-            <property name="Visible">False</property>
-            <property name="ShadowType">None</property>
-            <child>
-              <widget class="Gtk.Alignment" id="GtkAlignment">
-                <property name="MemberName" />
-                <property name="Xalign">0</property>
-                <property name="Yalign">0</property>
-                <property name="LeftPadding">12</property>
-                <property name="BorderWidth">2</property>
                 <child>
-                  <widget class="Gtk.HBox" id="file4box">
-                    <property name="MemberName" />
-                    <child>
-                      <widget class="LongoMatch.Gui.Component.MediaFileChooser" id="mediafilechooser4">
-                        <property name="MemberName" />
-                        <property name="Events">ButtonPressMask</property>
-                      </widget>
-                      <packing>
-                        <property name="Position">0</property>
-                        <property name="AutoSize">True</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="Gtk.Button" id="delfile4button">
-                        <property name="MemberName" />
-                        <property name="CanFocus">True</property>
-                        <property name="Type">TextAndIcon</property>
-                        <property name="Icon">stock:gtk-remove Menu</property>
-                        <property name="Label" translatable="yes" />
-                        <property name="UseUnderline">True</property>
-                      </widget>
-                      <packing>
-                        <property name="Position">1</property>
-                        <property name="AutoSize">True</property>
-                        <property name="Expand">False</property>
-                        <property name="Fill">False</property>
-                      </packing>
-                    </child>
-                  </widget>
+                  <placeholder />
                 </child>
               </widget>
             </child>
-            <child>
-              <widget class="Gtk.Label" id="GtkLabel5">
-                <property name="MemberName" />
-                <property name="LabelProp" translatable="yes">&lt;b&gt;Angle 4&lt;/b&gt;</property>
-                <property name="UseMarkup">True</property>
-              </widget>
-              <packing>
-                <property name="type">label_item</property>
-              </packing>
-            </child>
           </widget>
-          <packing>
-            <property name="TopAttach">1</property>
-            <property name="BottomAttach">2</property>
-            <property name="LeftAttach">1</property>
-            <property name="RightAttach">2</property>
-            <property name="AutoSize">False</property>
-            <property name="YOptions">Fill</property>
-            <property name="XExpand">True</property>
-            <property name="XFill">True</property>
-            <property name="XShrink">False</property>
-            <property name="YExpand">False</property>
-            <property name="YFill">True</property>
-            <property name="YShrink">False</property>
-          </packing>
         </child>
       </widget>
     </child>
diff --git a/LongoMatch.Migration/Converter.cs b/LongoMatch.Migration/Converter.cs
index 7308c21..1fe686d 100644
--- a/LongoMatch.Migration/Converter.cs
+++ b/LongoMatch.Migration/Converter.cs
@@ -99,8 +99,7 @@ namespace LongoMatch.Migration
                        newdesc.MatchDate = desc.MatchDate;
                        newdesc.LastModified = desc.LastModified;
                        newdesc.FileSet = new LongoMatch.Core.Store.MediaFileSet ();
-                       newdesc.FileSet.SetAngle (LongoMatch.Core.Common.MediaFileAngle.Angle1,
-                                                 ConvertMediaFile (desc.File));
+                       newdesc.FileSet.Add (ConvertMediaFile (desc.File));
                        return newdesc;
                }
 
diff --git a/LongoMatch.Multimedia/Utils/GstDiscoverer.cs b/LongoMatch.Multimedia/Utils/GstDiscoverer.cs
index d03b9e3..c7e6d81 100644
--- a/LongoMatch.Multimedia/Utils/GstDiscoverer.cs
+++ b/LongoMatch.Multimedia/Utils/GstDiscoverer.cs
@@ -84,7 +84,7 @@ namespace LongoMatch.Video.Utils
                        
                        return new LongoMatch.Core.Store.MediaFile (filePath, duration, (ushort)fps, 
has_audio, has_video,
                                                               container, video_codec, audio_codec, width, 
height,
-                                                              par, preview);
+                                                              par, preview, null);
                }
        }
 }
diff --git a/LongoMatch.Services/Services/EventsManager.cs b/LongoMatch.Services/Services/EventsManager.cs
index a300fb8..f280694 100644
--- a/LongoMatch.Services/Services/EventsManager.cs
+++ b/LongoMatch.Services/Services/EventsManager.cs
@@ -71,7 +71,7 @@ namespace LongoMatch.Services
 
                        if (projectType == ProjectType.FileProject) {
                                framesCapturer = Config.MultimediaToolkit.GetFramesCapturer ();
-                               framesCapturer.Open (openedProject.Description.FileSet.GetAngle 
(MediaFileAngle.Angle1).FilePath);
+                               framesCapturer.Open (openedProject.Description.FileSet.First ().FilePath);
                        }
                        this.analysisWindow = analysisWindow;
                        player = analysisWindow.Player;
@@ -198,7 +198,8 @@ namespace LongoMatch.Services
                        }
 
                        if (framesCapturer != null && !current) {
-                               Time offset = openedProject.Description.FileSet.GetAngle (angle).Offset;
+                               // FIXME
+                               Time offset = openedProject.Description.FileSet.First ().Offset;
                                pixbuf = framesCapturer.GetFrame (pos + offset, true, -1, -1);
                        } else {
                                pixbuf = player.CurrentFrame;
diff --git a/LongoMatch.Services/Services/ProjectsManager.cs b/LongoMatch.Services/Services/ProjectsManager.cs
index 73accb1..ae69d3e 100644
--- a/LongoMatch.Services/Services/ProjectsManager.cs
+++ b/LongoMatch.Services/Services/ProjectsManager.cs
@@ -16,6 +16,7 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
 using System;
+using System.Linq;
 using System.IO;
 using LongoMatch.Core.Common;
 using LongoMatch.Core.Interfaces;
@@ -129,7 +130,8 @@ namespace LongoMatch.Services
                void SaveCaptureProject (Project project)
                {
                        Guid projectID = project.ID;
-                       string filePath = project.Description.FileSet.GetAngle 
(MediaFileAngle.Angle1).FilePath;
+                       // FIXME
+                       string filePath = project.Description.FileSet.First ().FilePath;
 
                        /* scan the new file to build a new PreviewMediaFile with all the metadata */
                        try {
@@ -139,7 +141,7 @@ namespace LongoMatch.Services
                        
                                Log.Debug ("Reloading saved file: " + filePath);
                                MediaFile file = multimediaToolkit.DiscoverFile (filePath);
-                               project.Description.FileSet.SetAngle (MediaFileAngle.Angle1, file);
+                               project.Description.FileSet.Add (file);
                                project.Periods = Capturer.Periods;
                                Config.DatabaseManager.ActiveDB.AddProject (project);
                        } catch (Exception ex) {
@@ -196,7 +198,7 @@ namespace LongoMatch.Services
                                projectType == ProjectType.URICaptureProject ||
                                projectType == ProjectType.FakeCaptureProject) {
                                try {
-                                       Capturer.Run (props, project.Description.FileSet.GetAngle 
(MediaFileAngle.Angle1));
+                                       Capturer.Run (props, project.Description.FileSet.First ());
                                } catch (Exception ex) {
                                        Log.Exception (ex);
                                        guiToolkit.ErrorMessage (ex.Message);
@@ -250,8 +252,9 @@ namespace LongoMatch.Services
                                return false;
                        } else {
                                EndCaptureResponse res;
-                               
-                               res = guiToolkit.EndCapture (OpenedProject.Description.FileSet.GetAngle 
(MediaFileAngle.Angle1).FilePath);
+
+                               // FIXME:
+                               res = guiToolkit.EndCapture (OpenedProject.Description.FileSet.First 
().FilePath);
 
                                /* Close project wihtout saving */
                                if (res == EndCaptureResponse.Quit) {
@@ -355,8 +358,8 @@ namespace LongoMatch.Services
                                guiToolkit.ErrorMessage (ex.Message);
                                return;
                        }
-
-                       if (project.Description.FileSet.GetAngle (MediaFileAngle.Angle1).FilePath == 
Constants.FAKE_PROJECT) {
+                       // FIXME
+                       if (project.Description.FileSet.First ().FilePath == Constants.FAKE_PROJECT) {
                                /* If it's a fake live project prompt for a video file and
                                 * create a new PreviewMediaFile for this project and recreate the thumbnails 
*/
                                Log.Debug ("Importing fake live project");
diff --git a/LongoMatch.Services/Services/RenderingJobsManager.cs 
b/LongoMatch.Services/Services/RenderingJobsManager.cs
index 39dfd38..f3ab696 100644
--- a/LongoMatch.Services/Services/RenderingJobsManager.cs
+++ b/LongoMatch.Services/Services/RenderingJobsManager.cs
@@ -250,7 +250,7 @@ namespace LongoMatch.Services
                        
                        lastTS = play.Start;
                        /* FIXME: for now we only support rendering the first angle in the list */
-                       file = element.FileSet.GetAngle (element.Angles.FirstOrDefault ());
+                       file = element.FileSet.FirstOrDefault ();
                        drawings = play.Drawings.Where (d => d.Angle == element.Angles.FirstOrDefault ());
                        if (file == null || drawings == null) {
                                return false;
diff --git a/Tests/Core/Store/TestMediaFile.cs b/Tests/Core/Store/TestMediaFile.cs
index 1dfe657..401dc33 100644
--- a/Tests/Core/Store/TestMediaFile.cs
+++ b/Tests/Core/Store/TestMediaFile.cs
@@ -30,7 +30,7 @@ namespace Tests.Core.Store
                public void TestSerialization ()
                {
                        MediaFile mf = new MediaFile ("path", 34000, 25, true, true, "mp4", "h264",
-                                                     "aac", 320, 240, 1.3, null);
+                                                     "aac", 320, 240, 1.3, null, "Test asset");
                        Utils.CheckSerialization (mf);
                        
                        MediaFile newmf = Utils.SerializeDeserialize (mf);
@@ -46,6 +46,7 @@ namespace Tests.Core.Store
                        Assert.AreEqual (mf.VideoHeight, newmf.VideoHeight);
                        Assert.AreEqual (mf.Par, newmf.Par);
                        Assert.AreEqual (mf.Offset, new Time (0));
+                       Assert.AreEqual (mf.Name, newmf.Name);
                                
                }
                
diff --git a/Tests/Core/Store/TestMediaFileSet.cs b/Tests/Core/Store/TestMediaFileSet.cs
index 2ac8db1..d653009 100644
--- a/Tests/Core/Store/TestMediaFileSet.cs
+++ b/Tests/Core/Store/TestMediaFileSet.cs
@@ -16,6 +16,7 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
 using System;
+using System.Linq;
 using LongoMatch.Core.Store;
 using NUnit.Framework;
 using LongoMatch.Core.Common;
@@ -30,16 +31,56 @@ namespace Tests.Core.Store
                public void TestSerialization ()
                {
                        MediaFileSet mf = new MediaFileSet ();
+                       mf.Add (new MediaFile ("path", 34000, 25, true, true, "mp4", "h264",
+                               "aac", 320, 240, 1.3, null, "Test asset"));
+                       mf.Add (new MediaFile ("path", 34000, 25, true, true, "mp4", "h264",
+                               "aac", 320, 240, 1.3, null, "Test asset 2"));
                        Utils.CheckSerialization (mf);
                }
+
+               [Test()]
+               public void TestMigration ()
+               {
+                       String old_json = @"""FileSet"": { 
+                                                             ""$id"": ""88"",
+                                                             ""$type"": 
""LongoMatch.Core.Store.MediaFileSet, LongoMatch.Core"",
+                                                             ""Files"": { 
+                                                               ""$id"": ""1"",
+                                                               ""$type"": 
""System.Collections.Generic.Dictionary`2[[LongoMatch.Core.Common.MediaFileAngle, 
LongoMatch.Core],[LongoMatch.Core.Store.MediaFile, LongoMatch.Core]], mscorlib"",
+                                                               ""Angle1"": { ""$id"": ""2"", ""$type"": 
""LongoMatch.Core.Store.MediaFile, LongoMatch.Core"", ""FilePath"": ""test.mp4"", ""Duration"": null, 
""HasVideo"": false, ""HasAudio"": false, ""Container"": null, ""VideoCodec"": null, ""AudioCodec"": null, 
""VideoWidth"": 640, ""VideoHeight"": 480, ""Fps"": 25, ""Par"": 1.0, ""Preview"": null, ""Offset"": 0 },
+                                                               ""Angle2"": { ""$id"": ""3"", ""$type"": 
""LongoMatch.Core.Store.MediaFile, LongoMatch.Core"", ""FilePath"": ""test2.mp4"", ""Duration"": null, 
""HasVideo"": false, ""HasAudio"": false, ""Container"": null, ""VideoCodec"": null, ""AudioCodec"": null, 
""VideoWidth"": 640, ""VideoHeight"": 480, ""Fps"": 25, ""Par"": 1.0, ""Preview"": null, ""Offset"": 0 },
+                                                               ""Angle3"": null,
+                                                               ""Angle4"": null
+                                                             }
+                                                               }";
+                       MemoryStream stream = new MemoryStream();
+                       StreamWriter writer = new StreamWriter(stream);
+                       writer.Write(old_json);
+                       writer.Flush();
+                       stream.Position = 0;
+
+                       // Deserialize and check the FileSet
+                       var newobj = Serializer.Load<MediaFileSet> (stream, SerializationType.Json);
+
+                       Assert.AreEqual (2, newobj.Count);
+
+                       MediaFile mf = newobj.First ();
+
+                       Assert.AreEqual ("test.mp4", mf.FilePath);
+                       Assert.AreEqual ("Main camera angle", mf.Name);
+
+                       mf = newobj [1];
+
+                       Assert.AreEqual ("test2.mp4", mf.FilePath);
+                       Assert.AreEqual ("Angle 1", mf.Name);
+               }
                
                [Test()]
                public void TestPreview ()
                {
                        MediaFileSet mf = new MediaFileSet ();
                        Assert.IsNull (mf.Preview);
-                       mf.SetAngle (MediaFileAngle.Angle1,
-                                    new MediaFile {Preview = Utils.LoadImageFromFile ()});
+                       mf.Add (new MediaFile {Preview = Utils.LoadImageFromFile (), Name = "Test asset"});
                        Assert.IsNotNull (mf.Preview);
                }
                
@@ -48,10 +89,10 @@ namespace Tests.Core.Store
                {
                        MediaFileSet mf = new MediaFileSet ();
                        Assert.AreEqual (mf.Duration.MSeconds, 0);
-                       mf.SetAngle (MediaFileAngle.Angle1, new MediaFile {Duration = new Time (2000)});
+                       mf.Add (new MediaFile {Duration = new Time (2000), Name = "Test asset"});
                        Assert.AreEqual (mf.Duration.MSeconds, 2000); 
-                       mf.SetAngle (MediaFileAngle.Angle1, new MediaFile {Duration = new Time (2001)});
-                       Assert.AreEqual (mf.Duration.MSeconds, 2001); 
+                       mf.Replace ("Test asset", new MediaFile {Duration = new Time (2001), Name = "Test 
asset 2"});
+                       Assert.AreEqual (mf.Duration.MSeconds, 2001);
                }
                
                [Test()]
@@ -60,25 +101,13 @@ namespace Tests.Core.Store
                        string path = Path.GetTempFileName ();
                        MediaFileSet mf = new MediaFileSet ();
                        Assert.IsFalse (mf.CheckFiles());
-                       mf.SetAngle (MediaFileAngle.Angle1, new MediaFile {FilePath = path});
+                       mf.Add (new MediaFile {FilePath = path, Name = "Test asset"});
                        try {
                                Assert.IsTrue (mf.CheckFiles ());
                        } finally {
                                File.Delete (path);
                        }
                }
-               
-               [Test()]
-               public void TestGetSetAngles ()
-               {
-                       MediaFileSet mfs = new MediaFileSet ();
-                       MediaFile mf = new MediaFile ();
-                       Assert.IsNull (mfs.GetAngle (MediaFileAngle.Angle1));
-                       mfs.SetAngle (MediaFileAngle.Angle1, mf);
-                       Assert.AreEqual (mfs.GetAngle (MediaFileAngle.Angle1), mf);
-                       mfs.SetAngle (MediaFileAngle.Angle2, mf);
-                       Assert.AreEqual (mfs.GetAngle (MediaFileAngle.Angle2), mf);
-               }
        }
 }
 
diff --git a/Tests/Core/Store/TestPlaysFilter.cs b/Tests/Core/Store/TestPlaysFilter.cs
index 8ddb3b1..b1480c7 100644
--- a/Tests/Core/Store/TestPlaysFilter.cs
+++ b/Tests/Core/Store/TestPlaysFilter.cs
@@ -34,10 +34,10 @@ namespace Tests.Core.Store
                        p.LocalTeamTemplate = TeamTemplate.DefaultTemplate (5);
                        p.VisitorTeamTemplate = TeamTemplate.DefaultTemplate (5);
                        MediaFile mf = new MediaFile ("path", 34000, 25, true, true, "mp4", "h264",
-                                                     "aac", 320, 240, 1.3, null);
+                                                     "aac", 320, 240, 1.3, null, "Test asset");
                        ProjectDescription pd = new ProjectDescription ();
                        pd.FileSet = new MediaFileSet ();
-                       pd.FileSet.SetAngle (MediaFileAngle.Angle1, mf);
+                       pd.FileSet.Add (mf);
                        p.Description = pd;
                        p.UpdateEventTypesAndTimers ();
                        
diff --git a/Tests/Core/Store/TestProject.cs b/Tests/Core/Store/TestProject.cs
index 1773496..6f8b1d6 100644
--- a/Tests/Core/Store/TestProject.cs
+++ b/Tests/Core/Store/TestProject.cs
@@ -38,10 +38,10 @@ namespace Tests.Core.Store
                        p.LocalTeamTemplate = TeamTemplate.DefaultTemplate (10);
                        p.VisitorTeamTemplate = TeamTemplate.DefaultTemplate (12);
                        MediaFile mf = new MediaFile ("path", 34000, 25, true, true, "mp4", "h264",
-                                              "aac", 320, 240, 1.3, null);
+                                              "aac", 320, 240, 1.3, null, "Test asset");
                        ProjectDescription pd = new ProjectDescription ();
                        pd.FileSet = new MediaFileSet ();
-                       pd.FileSet.SetAngle (MediaFileAngle.Angle1, mf);
+                       pd.FileSet.Add (mf);
                        p.Description = pd;
                        if (fill) {
                                p.AddEvent (p.EventTypes [0], new Time (1000), new Time (2000), null, null, 
null, null);
diff --git a/Tests/Core/Store/TestProjectDescription.cs b/Tests/Core/Store/TestProjectDescription.cs
index e9a918c..22ff286 100644
--- a/Tests/Core/Store/TestProjectDescription.cs
+++ b/Tests/Core/Store/TestProjectDescription.cs
@@ -16,6 +16,7 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
 using System;
+using System.Linq;
 using NUnit.Framework;
 using LongoMatch.Core.Common;
 using LongoMatch.Core.Store;
@@ -29,12 +30,12 @@ namespace Tests.Core.Store
                public void TestSerialization ()
                {
                        MediaFile mf = new MediaFile ("path", 34000, 25, true, true, "mp4", "h264",
-                                              "aac", 320, 240, 1.3, null);
+                                              "aac", 320, 240, 1.3, null, "Test asset");
                        ProjectDescription pd = new ProjectDescription ();
                        Utils.CheckSerialization (pd);
                        
                        pd.FileSet = new MediaFileSet ();
-                       pd.FileSet.SetAngle (MediaFileAngle.Angle1, mf);
+                       pd.FileSet.Add (mf);
                        pd.Competition = "Comp";
                        pd.Category = "Cat";
                        pd.Group = "Group";
@@ -49,8 +50,8 @@ namespace Tests.Core.Store
                        
                        ProjectDescription newpd = Utils.SerializeDeserialize (pd);
                        Assert.AreEqual (pd.CompareTo (newpd), 0);
-                       Assert.AreEqual (pd.FileSet.GetAngle (MediaFileAngle.Angle1).FilePath,
-                               newpd.FileSet.GetAngle (MediaFileAngle.Angle1).FilePath);
+                       Assert.AreEqual (pd.FileSet.First ().FilePath,
+                               newpd.FileSet.First ().FilePath);
                        Assert.AreEqual (pd.ID, newpd.ID);
                        Assert.AreEqual (pd.Competition, newpd.Competition);
                        Assert.AreEqual (pd.Category, newpd.Category);


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