[Banshee-List] Child sources patch



Hi,

Attached is a patch which adds support for child sources in Banshee.
This means that all your playlists should now appear as children of the
library source. This is our first small step to full DAP playlist
support.

Please test the code thoroughly, but I wasn't able to trigger any
issues.

Have fun!


Lukas
? mediaengines/xing-encoder
? po/stamp-it
? src/.PlayerInterface.cs.swp
Index: src/PlayerInterface.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/PlayerInterface.cs,v
retrieving revision 1.173
diff -u -r1.173 PlayerInterface.cs
--- src/PlayerInterface.cs	10 Apr 2006 16:40:52 -0000	1.173
+++ src/PlayerInterface.cs	11 Apr 2006 20:02:17 -0000
@@ -593,7 +593,6 @@
             LoadSourceView();
             
             SourceManager.AddSource(LibrarySource.Instance, true);
-            PlaylistUtil.LoadSources();
 
             if(LocalQueueSource.Instance.Count > 0) {
                 SourceManager.AddSource(LocalQueueSource.Instance);
@@ -1435,7 +1434,7 @@
             playlist.Rename(PlaylistUtil.GoodUniqueName(playlist.Tracks));
             playlist.Commit();
             
-            SourceManager.AddSource(playlist);
+            LibrarySource.Instance.AddChildSource(playlist);
         }
         
         private void OnItemAddToPlaylistActivated(object o, EventArgs args)
Index: src/SourceView.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/SourceView.cs,v
retrieving revision 1.45
diff -u -r1.45 SourceView.cs
--- src/SourceView.cs	18 Feb 2006 16:25:52 -0000	1.45
+++ src/SourceView.cs	11 Apr 2006 20:02:26 -0000
@@ -67,7 +67,7 @@
         private TreeIter newPlaylistIter = TreeIter.Zero;
         private bool newPlaylistVisible = false;
         
-        private ListStore store;
+        private TreeStore store;
         private int currentTimeout = -1;
 
         public SourceView()
@@ -79,25 +79,19 @@
             col.SetCellDataFunc(renderer, new TreeCellDataFunc(SourceCellDataFunc));
             AppendColumn(col);
             
-            store = new ListStore(typeof(Source));
+            store = new TreeStore(typeof(Source));
             Model = store;
             HeadersVisible = false;
             
             CursorChanged += OnCursorChanged;
             RefreshList();
-            
+
             SourceManager.SourceAdded += delegate(SourceAddedArgs args) {
-                if(FindSource(args.Source).Equals(TreeIter.Zero)) {
-                    TreeIter iter = store.Insert(args.Position);
-                    store.SetValue(iter, 0, args.Source);
-                }
+		AddSource (args.Source, args.Position);
             };
             
             SourceManager.SourceRemoved += delegate(SourceEventArgs args) {
-                TreeIter iter = FindSource(args.Source);
-                if(!iter.Equals(TreeIter.Zero)) {
-                    store.Remove(ref iter);
-                }
+		RemoveSource (args.Source);
             };
             
             SourceManager.ActiveSourceChanged += delegate(SourceEventArgs args) {
@@ -109,8 +103,10 @@
             };
         }
 
+	// FIXME: This is lame and could use some recusrion instead. I may get
+	// around to fixing it soon!
         private TreeIter FindSource(Source source) {
-            for(int i = 0, n = store.IterNChildren(); i < n; i++) {
+            for(int i = 0, m = store.IterNChildren(); i < m; i++) {
                 TreeIter iter = TreeIter.Zero;
                 if(!store.IterNthChild(out iter, i)) {
                     continue;
@@ -119,6 +115,17 @@
                 if((store.GetValue(iter, 0) as Source) == source) {
                     return iter;
                 }
+		
+		for (int j = 0, n = store.IterNChildren(iter); j < n; j++) {
+			TreeIter citer = TreeIter.Zero;
+			if(!store.IterNthChild(out citer, iter, j)) {
+                	    continue;
+	                }
+    
+                	if((store.GetValue(citer, 0) as Source) == source) {
+	                    return citer;
+                	}
+		}
             }
 
             return TreeIter.Zero;
@@ -150,11 +157,44 @@
             source.Rename(text);
         }
         
+	private void AddSource(Source source)
+	{
+		AddSource (source, -1);
+	}
+
+	private void AddSource(Source source, int position)
+	{
+		if(FindSource(source).Equals(TreeIter.Zero)) {
+                	TreeIter iter = store.InsertNode(position);
+                	store.SetValue(iter, 0, source);
+			
+			foreach (ChildSource s in source.Children) {
+				TreeIter i = store.AppendNode(iter);
+        	        	store.SetValue(i, 0, s);
+			}
+		    
+			source.ChildSourceAdded += delegate(SourceEventArgs e) {
+				TreeIter i = store.AppendNode(iter);
+        	        	store.SetValue(i, 0, e.Source);
+			};
+		}
+
+		ExpandAll ();
+	}
+
+	private void RemoveSource(Source source)
+	{
+                TreeIter iter = FindSource(source);
+                if(!iter.Equals(TreeIter.Zero)) {
+                    store.Remove(ref iter);
+                }
+	}
+	
         private void RefreshList()
         {
             store.Clear();
             foreach(Source source in SourceManager.Sources) {
-                store.AppendValues(source);
+                AddSource (source);
             }
         } 
         
@@ -194,13 +234,15 @@
             SetDragDestRow(null, TreeViewDropPosition.IntoOrAfter);
             Gdk.Drag.Status(context, 0, time);
 
-            // TODO: Support other drag sources
-            if(!(SourceManager.ActiveSource is LibrarySource)) {
+            // FIXME: We need to handle this nicer
+            if(!((SourceManager.ActiveSource is LibrarySource)
+		|| ((SourceManager.ActiveSource is PlaylistSource) && (SourceManager.ActiveSource as PlaylistSource).Local))) {
                 return true;
             }
             
             if(!newPlaylistVisible) {
-                newPlaylistIter = store.AppendValues(newPlaylistSource);
+		TreeIter library = FindSource (LibrarySource.Instance);
+                newPlaylistIter = store.AppendValues(library, newPlaylistSource);
                 newPlaylistVisible = true;
             }
 
@@ -267,7 +309,7 @@
                 playlist.AddTrack(tracks);
                 playlist.Rename(PlaylistUtil.GoodUniqueName(playlist.Tracks));
                 playlist.Commit();
-                SourceManager.AddSource(playlist);
+                LibrarySource.Instance.AddChildSource(playlist);
             }
             
             Gtk.Drag.Finish(context, true, false, time);
@@ -291,14 +333,12 @@
         
         public void ResetHighlight()
         {
-            TreeIter iter = TreeIter.Zero;
+            TreeIter iter = FindSource (SourceManager.ActiveSource);
             
-            if(!store.IterNthChild(out iter, SourceManager.ActiveSourceIndex)) {
-                return;
+            if(!iter.Equals(TreeIter.Zero)){
+                Selection.SelectIter(iter);
             }
-             
-            Selection.SelectIter(iter);
-        }
+         }
         
         public Source HighlightedSource {
             get {
Index: src/Banshee.Base/Library.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Library.cs,v
retrieving revision 1.10
diff -u -r1.10 Library.cs
--- src/Banshee.Base/Library.cs	9 Apr 2006 21:30:23 -0000	1.10
+++ src/Banshee.Base/Library.cs	11 Apr 2006 20:02:30 -0000
@@ -56,7 +56,6 @@
         public BansheeDatabase Db;
         public Hashtable Tracks = new Hashtable();
         public Hashtable TracksFnKeyed = new Hashtable();
-        public Hashtable Playlists = new Hashtable();
         
         public event EventHandler Reloaded;
         public event EventHandler Updated;
Index: src/Banshee.Base/Makefile.am
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Makefile.am,v
retrieving revision 1.28
diff -u -r1.28 Makefile.am
--- src/Banshee.Base/Makefile.am	9 Apr 2006 21:30:23 -0000	1.28
+++ src/Banshee.Base/Makefile.am	11 Apr 2006 20:02:30 -0000
@@ -35,6 +35,7 @@
 SOURCES_SOURCES = \
 	$(srcdir)/SourceManager.cs \
 	$(srcdir)/Source.cs \
+	$(srcdir)/ChildSource.cs \
 	$(srcdir)/Sources/LibrarySource.cs \
 	$(srcdir)/Sources/PlaylistSource.cs \
 	$(srcdir)/Sources/AudioCdSource.cs \
Index: src/Banshee.Base/Source.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Source.cs,v
retrieving revision 1.7
diff -u -r1.7 Source.cs
--- src/Banshee.Base/Source.cs	13 Feb 2006 22:18:08 -0000	1.7
+++ src/Banshee.Base/Source.cs	11 Apr 2006 20:02:36 -0000
@@ -54,15 +54,20 @@
         private int order;
         private string name;
 
+        private ArrayList child_sources;
+
         public event EventHandler Updated;
         public event TrackEventHandler TrackAdded;
         public event TrackEventHandler TrackRemoved;
         public event EventHandler ViewChanged;
+        public event SourceEventHandler ChildSourceAdded;
+        public event SourceEventHandler ChildSourceRemoved;
         
         protected Source(string name, int order)
         {
             this.name = name;
             this.order = order;
+            this.child_sources = new ArrayList ();
         }
         
         public void Dispose()
@@ -173,6 +178,37 @@
             }
         }
         
+	public virtual void AddChildSource(ChildSource source)
+	{
+		source.SetParentSource(source);
+		child_sources.Add(source);
+		
+    		SourceEventHandler handler = ChildSourceAdded;
+    		if(handler != null) {
+			SourceEventArgs evargs = new SourceEventArgs();
+	                evargs.Source = source;
+                	handler(evargs);
+	        }
+	}
+
+	public virtual void RemoveChildSource(ChildSource source)
+	{
+		child_sources.Remove(source);
+
+    		SourceEventHandler handler = ChildSourceRemoved;
+    		if(handler != null) {
+			SourceEventArgs evargs = new SourceEventArgs();
+	                evargs.Source = source;
+                	handler(evargs);
+	        }
+	}
+	
+	public ICollection Children {
+            get {
+                return child_sources;
+            }
+	}
+
         public virtual int Count {
             get {
                 return -1;
Index: src/Banshee.Base/SourceManager.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/SourceManager.cs,v
retrieving revision 1.7
diff -u -r1.7 SourceManager.cs
--- src/Banshee.Base/SourceManager.cs	18 Feb 2006 16:25:52 -0000	1.7
+++ src/Banshee.Base/SourceManager.cs	11 Apr 2006 20:02:36 -0000
@@ -216,18 +216,6 @@
             });
         }
         
-        public static int ActiveSourceIndex {
-            get {
-                for(int i = 0; i < sources.Count; i++) {
-                    if((sources[i] as Source) == active_source) {
-                        return i;
-                    }
-                }
-                
-                return -1;
-            }
-        }
-        
         public static ICollection Sources {
             get {
                 return sources;
Index: src/Banshee.Base/Sources/LibrarySource.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Sources/LibrarySource.cs,v
retrieving revision 1.6
diff -u -r1.6 LibrarySource.cs
--- src/Banshee.Base/Sources/LibrarySource.cs	20 Mar 2006 08:38:39 -0000	1.6
+++ src/Banshee.Base/Sources/LibrarySource.cs	11 Apr 2006 20:02:36 -0000
@@ -58,6 +58,10 @@
                 OnTrackAdded(args.Track);
                 OnUpdated();
             };  
+
+            foreach (ChildSource playlist in PlaylistUtil.LoadSources()) {
+		    AddChildSource (playlist);
+	    }
         }
         
         public override void RemoveTrack(TrackInfo track)
Index: src/Banshee.Base/Sources/PlaylistSource.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Sources/PlaylistSource.cs,v
retrieving revision 1.5
diff -u -r1.5 PlaylistSource.cs
--- src/Banshee.Base/Sources/PlaylistSource.cs	13 Feb 2006 22:18:10 -0000	1.5
+++ src/Banshee.Base/Sources/PlaylistSource.cs	11 Apr 2006 20:02:42 -0000
@@ -36,29 +36,34 @@
 
 namespace Banshee.Sources
 {
-    public class PlaylistSource : Source
+    public class PlaylistSource : ChildSource
     {
-        private static ArrayList playlists = new ArrayList();
+        private static Hashtable playlists = new Hashtable();
+	
         public static IEnumerable Playlists {
             get {
-                return playlists;
+                return playlists.Values;
             }
         }
         
         public static int PlaylistCount {
             get {
-                return playlists.Count;
+                return playlists.Values.Count;
             }
         }
         
         private ArrayList tracks = new ArrayList();
         private int id;
-    
+	
         public PlaylistSource() : this(0)
         {
         }
-    
-        public PlaylistSource(int id) : base(Catalog.GetString("New Playlist"), 500)
+
+	public PlaylistSource(string name) : base(name, 500)
+	{
+	}
+
+	public PlaylistSource(int id) : base(Catalog.GetString("New Playlist"), 500)
         {
             this.id = id;
             
@@ -71,7 +76,7 @@
             }
             
             Globals.Library.TrackRemoved += OnLibraryTrackRemoved;
-            playlists.Add(this);
+            playlists.Add(id, this);
         }
         
         private void CreateNewPlaylist()
@@ -138,10 +143,8 @@
  
         public override void AddTrack(TrackInfo track)
         {
-            if(track is LibraryTrackInfo) {
-                tracks.Add(track);
-                OnUpdated();
-            }
+            tracks.Add(track);
+            OnUpdated();
         }
         
         public override void RemoveTrack(TrackInfo track)
@@ -164,7 +167,7 @@
             ));
             
             SourceManager.RemoveSource(this);
-            playlists.Remove(this);
+            playlists.Remove(id);
         }
         
         public override void Commit()
@@ -246,18 +249,28 @@
                 return IconThemeUtils.LoadIcon(22, "source-playlist");
             }
         }
+
+        public bool Local {
+            get {
+                return (id > 0);
+            }
+        }  
     }
     
     public static class PlaylistUtil
     {
-        public static void LoadSources()
+        public static ICollection LoadSources()
         {
-            IDataReader reader = Globals.Library.Db.Query("SELECT PlaylistID FROM Playlists");
+	    ArrayList sources = new ArrayList ();
+	    
+	    IDataReader reader = Globals.Library.Db.Query("SELECT PlaylistID FROM Playlists");
             while(reader.Read()) {
                 PlaylistSource playlist = new PlaylistSource(Convert.ToInt32(reader[0]));
-                SourceManager.AddSource(playlist);
+		sources.Add (playlist);
             }
             reader.Dispose();
+
+	    return sources;
         }
     
         internal static int GetPlaylistID(string name)
--- /dev/null	2006-04-03 19:40:38.000000000 +0200
+++ src/Banshee.Base/ChildSource.cs	2006-04-11 21:51:33.000000000 +0200
@@ -0,0 +1,63 @@
+
+/***************************************************************************
+ *  ChildSource.cs
+ *
+ *  Copyright (C) 2006 Novell
+ *  Written by Lukas Lipka (lukas pmad net)
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),  
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+ 
+namespace Banshee.Sources
+{
+    public class ChildSource : Source
+    {
+	private Source parent;	    
+
+	protected ChildSource(string name, int position) : base(name, position)
+	{
+	}
+
+	public override void AddChildSource(ChildSource source)
+	{
+            throw new Exception("Cannot add a child source to a child source!");
+	}
+
+	public override void RemoveChildSource(ChildSource source)
+	{
+            throw new Exception("Cannot remove a child source from a child source!");
+	}
+
+	public void SetParentSource(Source source)
+	{
+            parent = source;
+	}
+
+	public Source Parent {
+            get {
+                return parent;
+            }
+	}
+    }
+}


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