[Banshee-List] Child Source patch v0.8



Hey,

Hopefully the final version of the child source patch. I figured I
forgot to commment out some lines in the previous one, so here is the
fixed version. Please test it and if you still do find any issues please
report them.

Thanks,
Lukas
? po/stamp-it
? src/.SourceView.cs.swp
? src/Banshee.Base/ChildSource.cs
Index: src/PlayerInterface.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/PlayerInterface.cs,v
retrieving revision 1.174
diff -u -r1.174 PlayerInterface.cs
--- src/PlayerInterface.cs	14 Apr 2006 15:33:43 -0000	1.174
+++ src/PlayerInterface.cs	16 Apr 2006 12:01:53 -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)
@@ -1854,7 +1853,7 @@
         {
             PlaylistSource playlist = new PlaylistSource();
             playlist.Rename(PlaylistUtil.UniqueName);
-            SourceManager.AddSource(playlist);
+            LibrarySource.Instance.AddChildSource(playlist);
         }
         
         private void OnImportFolderAction(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	16 Apr 2006 12:01:53 -0000
@@ -67,37 +67,37 @@
         private TreeIter newPlaylistIter = TreeIter.Zero;
         private bool newPlaylistVisible = false;
         
-        private ListStore store;
+        private TreeStore store;
         private int currentTimeout = -1;
-
+	
         public SourceView()
         {
-            TreeViewColumn col = new TreeViewColumn();
+	    // Hidden expander column
+	    TreeViewColumn col = new TreeViewColumn();
+	    col.Visible = false;
+	    AppendColumn(col);
+	    ExpanderColumn = col;
+		
+            col = new TreeViewColumn();
             SourceRowRenderer renderer = new SourceRowRenderer();
             col.Title = Catalog.GetString("Source");
             col.PackStart(renderer, true);
             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 +109,11 @@
             };
         }
 
-        private TreeIter FindSource(Source source) {
-            for(int i = 0, n = store.IterNChildren(); i < n; i++) {
+	// 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, m = store.IterNChildren(); i < m; i++) {
                 TreeIter iter = TreeIter.Zero;
                 if(!store.IterNthChild(out iter, i)) {
                     continue;
@@ -119,10 +122,39 @@
                 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;
         }
+
+	private bool UpdateView()
+	{
+	    for(int i = 0, m = store.IterNChildren(); i < m; i++) {
+                TreeIter iter = TreeIter.Zero;
+                if(!store.IterNthChild(out iter, i)) {
+                    continue;
+                }
+                
+                if(store.IterNChildren(iter) > 0) {
+                    ExpanderColumn = Columns[1];
+		    return true;
+                }
+	    }
+	    
+	    ExpanderColumn = Columns[0];
+	    return false;
+	}
                     
         protected void SourceCellDataFunc(TreeViewColumn tree_column,
             CellRenderer cell, TreeModel tree_model, TreeIter iter)
@@ -150,11 +182,55 @@
             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);
+				Expand(iter);
+			};
+
+			Expand(iter);
+		}
+
+		UpdateView();
+	}
+
+	private void RemoveSource(Source source)
+	{
+                TreeIter iter = FindSource(source);
+                if(!iter.Equals(TreeIter.Zero)) {
+                    store.Remove(ref iter);
+                }
+
+		UpdateView();
+	}
+	
+	private void Expand(TreeIter iter)
+	{
+		TreePath path = store.GetPath (iter);
+		ExpandRow (path, true);
+	}
+	
         private void RefreshList()
         {
             store.Clear();
             foreach(Source source in SourceManager.Sources) {
-                store.AppendValues(source);
+                AddSource (source);
             }
         } 
         
@@ -188,62 +264,76 @@
             return false;
         }
         
-        protected override bool OnDragMotion(Gdk.DragContext context, int x, int y, uint time)
+	protected override bool OnDragMotion(Gdk.DragContext context, int x, int y, uint time)
         {
             base.OnDragMotion(context, x, y, time);
-            SetDragDestRow(null, TreeViewDropPosition.IntoOrAfter);
-            Gdk.Drag.Status(context, 0, time);
+	    SetDragDestRow(null, TreeViewDropPosition.IntoOrAfter);
+            Gdk.Drag.Status(context, Gdk.DragAction.Copy, time);
 
-            // TODO: Support other drag sources
-            if(!(SourceManager.ActiveSource is LibrarySource)) {
-                return true;
+            // FIXME: We need to handle this nicer
+            if(!((SourceManager.ActiveSource is LibrarySource) ||
+                ((SourceManager.ActiveSource is PlaylistSource) && (SourceManager.ActiveSource as PlaylistSource).Local))) {
+                return false;
             }
-            
-            if(!newPlaylistVisible) {
-                newPlaylistIter = store.AppendValues(newPlaylistSource);
+	    
+            if (!newPlaylistVisible) {
+       		TreeIter library = FindSource(LibrarySource.Instance);
+                newPlaylistIter = store.AppendNode(library);
+		store.SetValue(newPlaylistIter, 0, newPlaylistSource);
                 newPlaylistVisible = true;
-            }
 
+		UpdateView ();
+		Expand(library);
+            }
+	    
             TreePath path;
             TreeViewDropPosition pos;
-            if(!GetDestRowAtPos(x, y, out path, out pos)) {
-                path = store.GetPath(newPlaylistIter);
-            }
+            if(GetDestRowAtPos(x, y, out path, out pos)) {
+                Source source = GetSource(path);
+                SetDragDestRow(path, TreeViewDropPosition.IntoOrAfter);
+	            
+                // TODO: Support other drag destinations
+                if((source is PlaylistSource) || (source is DapSource)) {
+                    return true;
+                }
 
-            Source source = GetSource(path);
-            if(source == null) {
-                return true;
-            }
-            
-            // TODO: Support other drag destinations
-            if(!(source is PlaylistSource) && !(source is DapSource)) {
-                return true;
-            }
+                Gdk.Drag.Status(context, 0, time);
+		return true;
+	    }
             
-            SetDragDestRow(path, TreeViewDropPosition.IntoOrAfter);
-            Gdk.Drag.Status(context, Gdk.DragAction.Copy, time);
             return true;
         }
         
+	private Source final_drag_source = null;
+	private uint final_drag_start_time = 0;
+	
         protected override void OnDragLeave(Gdk.DragContext context, uint time)
         {
-            if(newPlaylistVisible) {
+            TreePath path;
+            TreeViewDropPosition pos;
+            GetDragDestRow (out path, out pos);
+
+            if(path == null)
+                path = store.GetPath(newPlaylistIter);
+		
+            final_drag_source = GetSource (path);
+	    final_drag_start_time = context.StartTime;
+	    
+            if (newPlaylistVisible) {
                 store.Remove(ref newPlaylistIter);
                 newPlaylistVisible = false;
+                UpdateView ();
             }
         }
 
         protected override void OnDragDataReceived(Gdk.DragContext context, int x, int y,
             Gtk.SelectionData selectionData, uint info, uint time)
-        {
-            TreePath destPath;
-            TreeViewDropPosition pos;
-            
+        {       
             string rawData = Dnd.SelectionDataToString(selectionData);        
             string [] rawDataArray = Dnd.SplitSelectionData(rawData);
             if(rawData.Length <= 0) {
                 Gtk.Drag.Finish(context, false, false, time);
-                return;        
+                return;
             }
             
             ArrayList tracks = new ArrayList();
@@ -255,21 +345,24 @@
                     continue;
                 }
             }
-            
-            if(GetDestRowAtPos(x, y, out destPath, out pos)) {
-                Source source = GetSource(destPath);
-                if(source is PlaylistSource || source is DapSource) {
-                    source.AddTrack(tracks);
-                    source.Commit();
-                }
-            } else {
-                PlaylistSource playlist = new PlaylistSource();
-                playlist.AddTrack(tracks);
-                playlist.Rename(PlaylistUtil.GoodUniqueName(playlist.Tracks));
-                playlist.Commit();
-                SourceManager.AddSource(playlist);
+
+	    if(final_drag_start_time == context.StartTime) {
+                if(final_drag_source == newPlaylistSource) {
+                    PlaylistSource playlist = new PlaylistSource();
+                    playlist.AddTrack(tracks);
+                    playlist.Rename(PlaylistUtil.GoodUniqueName(playlist.Tracks));
+                    playlist.Commit();
+                    LibrarySource.Instance.AddChildSource(playlist);
+                    UpdateView ();
+		} else {
+                    Source source = final_drag_source;
+                    if(source is PlaylistSource || source is DapSource) {
+                        source.AddTrack(tracks);
+                        source.Commit();
+                    }
+		}
             }
-            
+	    
             Gtk.Drag.Finish(context, true, false, time);
         }
         
@@ -282,23 +375,23 @@
         {
             TreeIter iter;
         
+	    //Console.WriteLine (path.ToString ());
+	    
             if(store.GetIter(out iter, path)) {
                 return store.GetValue(iter, 0) as Source;
             }
-            
+	    
             return null;
         }
         
         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 {
@@ -489,3 +582,5 @@
         }
     }
 }
+
+
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	16 Apr 2006 12:01:56 -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/LibraryTrackInfo.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/LibraryTrackInfo.cs,v
retrieving revision 1.9
diff -u -r1.9 LibraryTrackInfo.cs
--- src/Banshee.Base/LibraryTrackInfo.cs	9 Apr 2006 21:30:23 -0000	1.9
+++ src/Banshee.Base/LibraryTrackInfo.cs	16 Apr 2006 12:01:58 -0000
@@ -423,12 +423,12 @@
             }
         }
 
-		static string Choose (string priority, string fallback)
-		{
-			if (priority == null || priority.Length == 0)
-				return fallback;
-			return priority;
-		}
+	static string Choose (string priority, string fallback)
+	{
+		if (priority == null || priority.Length == 0)
+			return fallback;
+		return priority;
+	}
 		
         private void LoadFromFile(string filename)
         {
@@ -487,5 +487,10 @@
             Core.Library.Db.Execute(query);*/
             Save();
         }
+
+	public bool Valid()
+	{
+		return File.Exists(Uri.AbsolutePath);
+	}
     }
 }
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	16 Apr 2006 12:01:58 -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	16 Apr 2006 12:02:03 -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	16 Apr 2006 12:02:03 -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	16 Apr 2006 12:02:10 -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	16 Apr 2006 12:02:10 -0000
@@ -36,9 +36,10 @@
 
 namespace Banshee.Sources
 {
-    public class PlaylistSource : Source
+    public class PlaylistSource : ChildSource
     {
         private static ArrayList playlists = new ArrayList();
+	
         public static IEnumerable Playlists {
             get {
                 return playlists;
@@ -53,12 +54,16 @@
         
         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;
             
@@ -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)
@@ -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-14 12:01:04.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]