banshee r5083 - in trunk/banshee: . src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Sources src/Core/Banshee.ThickClient/Banshee.Gui src/Core/Banshee.ThickClient/Banshee.Sources.Gui src/Core/Banshee.ThickClient/Resources src/Extensions/Banshee.InternetRadio/Resources src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio src/Extensions/Banshee.Lastfm/Resources src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying src/Extensions/Banshee.Podcasting/Resources



Author: gburt
Date: Fri Feb 27 20:27:23 2009
New Revision: 5083
URL: http://svn.gnome.org/viewvc/banshee?rev=5083&view=rev

Log:
2009-02-27  Gabriel Burt  <gabriel burt gmail com>

	Patch from John Millikin, with a few enhancements by me, adding support
	for sorting sources in real time and saving/restoring the preference for each
	primary source, in a general way so that sources can add their own sort
	options (BGO #556976)

	* src/Core/Banshee.Services/Makefile.am:
	* src/Core/Banshee.Services/Banshee.Sources/SourceSortType.cs: New class
	for defining sort types, giving them a name, id, and comparer.

	* src/Core/Banshee.Services/Banshee.Sources/Source.cs: Add new properties
	for defining how the children of a source can be sorted (if applicable),
	listening for the Updated event on all child sources and resorting when
	changed (so if sorted by size and a playlist gets a new item, it will be
	resorted immediately).  Save and restore the sort type configuration.

	* src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs: Override the
	child sort properties, adding name and size asc/desc options.

	* src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs: Dynamically
	generate the Sort by menu from the SortTypes a given source has (if any).
	Allow overriding its label.

	* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CellEditEntry.cs: Fix
	firing the EditingDone event twice.

	* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs: Handle
	resorting a little differently.

	* src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml:
	* src/Extensions/Banshee.InternetRadio/Resources/GlobalUI.xml:
	* src/Extensions/Banshee.Podcasting/Resources/GlobalUI.xml:
	* src/Extensions/Banshee.Lastfm/Resources/GlobalUI.xml: Use the new
	SortChildrenAction in the context menu for these types.

	* src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmActions.cs:
	Instead of using a totally custom menu for sorting Last.fm stations, use
	the new, generic Source SortTypes method for defining them.

	* src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmSource.cs:
	Remove custom sort logic since now handled upstream of us, customize the
	SortChildrenAction label, pass the typeUniqueId to the base ctor.

	* src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs:
	* src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs:
	Pass the typeUniqueId to the base ctor so it's set that much earlier.
	Really should clarify/enforce a sensible API here.

Added:
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/SourceSortType.cs
Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
   trunk/banshee/src/Core/Banshee.Services/Makefile.am
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CellEditEntry.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml
   trunk/banshee/src/Extensions/Banshee.InternetRadio/Resources/GlobalUI.xml
   trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmActions.cs
   trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmSource.cs
   trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs
   trunk/banshee/src/Extensions/Banshee.Lastfm/Resources/GlobalUI.xml
   trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
   trunk/banshee/src/Extensions/Banshee.Podcasting/Resources/GlobalUI.xml

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs	Fri Feb 27 20:27:23 2009
@@ -174,6 +174,20 @@
             get { return is_local; }
             protected set { is_local = value; }
         }
+        
+        private static SourceSortType[] sort_types = new SourceSortType[] {
+            SortNameAscending,
+            SortSizeAscending,
+            SortSizeDescending
+        };
+        
+        public override SourceSortType[] SortTypes {
+            get { return sort_types; }
+        }
+        
+        public override SourceSortType DefaultChildSort {
+            get { return SortNameAscending; }
+        }
 
         public delegate void TrackEventHandler (Source sender, TrackEventArgs args);
 
@@ -210,6 +224,7 @@
 
         protected PrimarySource (string generic_name, string name, string id, int order) : base (generic_name, name, id, order)
         {
+            Properties.SetString ("SortChildrenActionLabel", Catalog.GetString ("Sort Playlists by"));
             PrimarySourceInitialize ();
         }
 

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs	Fri Feb 27 20:27:23 2009
@@ -55,6 +55,10 @@
         private List<Source> child_sources = new List<Source> ();
         private ReadOnlyCollection<Source> read_only_children;
 
+        private SourceSortType child_sort;
+        private bool sort_children = true;
+        private SchemaEntry<string> child_sort_schema;
+
         public event EventHandler Updated;
         public event EventHandler UserNotifyUpdated;
         public event EventHandler MessageNotify;
@@ -67,7 +71,7 @@
         {
         }
 
-        protected Source (string generic_name, string name, int order, string type_unique_id)
+        protected Source (string generic_name, string name, int order, string type_unique_id) : this ()
         {
             GenericName = generic_name;
             Name = name;
@@ -79,6 +83,7 @@
 
         protected Source ()
         {
+            child_sort = DefaultChildSort;
         }
 
         // This method is chained to subclasses intialize methods,
@@ -103,6 +108,8 @@
             if (ApplicationContext.Debugging && ApplicationContext.CommandLine.Contains ("test-source-messages")) {
                 TestMessages ();
             }
+
+            LoadSortSchema ();
         }
         
         protected void OnSetupComplete ()
@@ -133,6 +140,16 @@
                 }
             }
         }
+        
+        protected void PauseSorting ()
+        {
+            sort_children = false;
+        }
+        
+        protected void ResumeSorting ()
+        {
+            sort_children = true;
+        }
 
 #region Public Methods
         
@@ -221,9 +238,10 @@
 
         public class NameComparer : IComparer<Source>
         {
+            static IComparer inner_cmp = new CaseInsensitiveComparer ();
             public int Compare (Source a, Source b)
             {
-                return a.Name.CompareTo (b.Name);
+                return inner_cmp.Compare (a.Name, b.Name);
             }
         }
 
@@ -235,19 +253,58 @@
             }
         }
 
-        public virtual void SortChildSources (IComparer<Source> comparer, bool asc)
+        public virtual void SortChildSources (SourceSortType sort_type)
         {
-            lock (Children) {
-                child_sources.Sort (comparer);
-                if (!asc) {
-                    child_sources.Reverse ();
+            child_sort = sort_type;
+            child_sort_schema.Set (child_sort.Id);
+            SortChildSources ();
+        }
+
+        public virtual void SortChildSources ()
+        {
+            lock (this) {
+                if (!sort_children) {
+                    return;
                 }
+                sort_children = false;
+            }
+            
+            if (child_sort.SortType != SortType.None) {
+                lock (Children) {
+                    child_sources.Sort (child_sort.Comparer);
+                    if (child_sort.SortType == SortType.Descending) {
+                        child_sources.Reverse ();
+                    }
 
-                int i = 0;
-                foreach (Source child in child_sources) {
-                    child.Order = i++;
+                    int i = 0;
+                    foreach (Source child in child_sources) {
+                        child.Order = i++;
+                    }
                 }
             }
+            sort_children = true;
+        }
+        
+        private void LoadSortSchema ()
+        {
+            if (SortTypes.Length == 0) {
+                return;
+            }
+
+            if (unique_id == null && type_unique_id == null) {
+                Hyena.Log.WarningFormat ("Trying to LoadSortSchema, but source's id not set! {0}", UniqueId);
+                return;
+            }
+            
+            child_sort_schema = CreateSchema<string> ("child_sort_id", DefaultChildSort.Id, "", "");
+            string child_sort_id = child_sort_schema.Get ();
+            foreach (SourceSortType sort_type in SortTypes) {
+                if (sort_type.Id == child_sort_id) {
+                    child_sort = sort_type;
+                    break;
+                }
+            }
+            SortChildSources ();
         }
 
         public T GetProperty<T> (string name, bool propagate)
@@ -409,6 +466,8 @@
     
         protected virtual void OnChildSourceAdded (Source source)
         {
+            SortChildSources ();
+            source.Updated += OnChildSourceUpdated;
             ThreadAssist.ProxyToMain (delegate {
                 SourceEventHandler handler = ChildSourceAdded;
                 if (handler != null) {
@@ -421,6 +480,7 @@
         
         protected virtual void OnChildSourceRemoved (Source source)
         {
+            source.Updated -= OnChildSourceUpdated;
             ThreadAssist.ProxyToMain (delegate {
                 SourceEventHandler handler = ChildSourceRemoved;
                 if (handler != null) {
@@ -438,6 +498,11 @@
                 handler (this, EventArgs.Empty);
             }
         }
+        
+        protected virtual void OnChildSourceUpdated (object o, EventArgs args)
+        {
+            SortChildSources ();
+        }
 
         public void NotifyUser ()
         {
@@ -590,6 +655,34 @@
             get { return null; }
         }
         
+        public static readonly SourceSortType SortNameAscending = new SourceSortType (
+            "NameAsc",
+            Catalog.GetString ("Name Ascending"),
+            SortType.Ascending, new NameComparer ());
+        
+        public static readonly SourceSortType SortSizeAscending = new SourceSortType (
+            "SizeAsc",
+            Catalog.GetString ("Size Ascending"),
+            SortType.Ascending, new SizeComparer ());
+        
+        public static readonly SourceSortType SortSizeDescending = new SourceSortType (
+            "SizeDesc",
+            Catalog.GetString ("Size Descending"),
+            SortType.Descending, new SizeComparer ());
+        
+        private static SourceSortType[] sort_types = new SourceSortType[] {};
+        public virtual SourceSortType[] SortTypes {
+            get { return sort_types; }
+        }
+        
+        public SourceSortType ActiveChildSort {
+            get { return child_sort; }
+        }
+        
+        public virtual SourceSortType DefaultChildSort {
+            get { return null; }
+        }
+        
 #endregion
 
 #region Status Message Stuff        

Added: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/SourceSortType.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/SourceSortType.cs	Fri Feb 27 20:27:23 2009
@@ -0,0 +1,80 @@
+//
+// SourceSortType.cs
+//
+// Author:
+//   John Millikin <jmillikin gmail com>
+//
+// Copyright (C) 2009 John Millikin
+//
+// 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;
+using System.Reflection;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+using Mono.Unix;
+
+using Hyena;
+using Hyena.Data;
+using Hyena.Query;
+
+using Banshee.Base;
+using Banshee.Collection;
+using Banshee.Configuration;
+using Banshee.ServiceStack;
+
+namespace Banshee.Sources
+{
+    public class SourceSortType
+    {
+        private string id;
+        private string label;
+        private SortType sort_type;
+        private IComparer<Source> comparer;
+        
+        public SourceSortType (string id, string label, SortType sortType, IComparer<Source> comparer)
+        {
+            this.id = id;
+            this.label = label;
+            this.sort_type = sortType;
+            this.comparer = comparer;
+        }
+        
+        public string Id {
+            get { return id; }
+        }
+        
+        public string Label {
+            get { return label; }
+        }
+        
+        public SortType SortType {
+            get { return sort_type; }
+        }
+        
+        public IComparer<Source> Comparer {
+            get { return comparer; }
+        }
+    }
+}

Modified: trunk/banshee/src/Core/Banshee.Services/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Makefile.am	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Makefile.am	Fri Feb 27 20:27:23 2009
@@ -194,6 +194,7 @@
 	Banshee.Sources/SourceManager.cs \
 	Banshee.Sources/SourceMergeType.cs \
 	Banshee.Sources/SourceMessage.cs \
+	Banshee.Sources/SourceSortType.cs \
 	Banshee.Streaming/RadioTrackInfo.cs \
 	Banshee.Web/Browser.cs \
 	Banshee.Web/HttpRequest.cs

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs	Fri Feb 27 20:27:23 2009
@@ -100,11 +100,16 @@
                     
                 new ActionEntry ("SourcePropertiesAction", null,
                     Catalog.GetString ("Source Properties"), null, null, OnSourceProperties),
+                    
+                new ActionEntry ("SortChildrenAction", Stock.SortDescending, 
+                    Catalog.GetString ("Sort Children by"), null, null,
+                    OnSortChildrenMenu)
             });
 
             this["NewPlaylistAction"].IconName = Stock.New;
             this["UnmapSourceAction"].IconName = Stock.Delete;
             this["SourcePropertiesAction"].IconName = Stock.Properties;
+            this["SortChildrenAction"].HideIfEmpty = false;
 
             AddImportant (
                 new ActionEntry ("RefreshSmartPlaylistAction", Stock.Refresh,
@@ -112,27 +117,6 @@
                     Catalog.GetString ("Refresh this randomly sorted smart playlist"), OnRefreshSmartPlaylist)
             );
             
-            Add (new Gtk.ActionEntry [] {
-                new Gtk.ActionEntry ("SortChildrenAction", null, 
-                    Catalog.GetString ("Sort Children"), null, null, null),
-                    
-                new Gtk.ActionEntry ("SortChildrenNameAscAction", null, 
-                    Catalog.GetString ("Name Ascending"), null, null, 
-                    delegate { ActionSource.SortChildSources (new Source.NameComparer (), true); }),
-                    
-                new Gtk.ActionEntry ("SortChildrenNameDescAction", null, 
-                    Catalog.GetString ("Name Descending"), null, null, 
-                    delegate { ActionSource.SortChildSources (new Source.NameComparer (), false); }),
-                    
-                new Gtk.ActionEntry ("SortChildrenSizeAscAction", null, 
-                    Catalog.GetString ("Size Ascending"), null, null, 
-                    delegate { ActionSource.SortChildSources (new Source.SizeComparer (), true); }),
-                    
-                new Gtk.ActionEntry ("SortChildrenSizeDescAction", null, 
-                    Catalog.GetString ("Size Descending"), null, null, 
-                    delegate { ActionSource.SortChildSources (new Source.SizeComparer (), false); })
-            });
-                
             //ServiceManager.SourceManager.SourceUpdated += OnPlayerEngineStateChanged;
             //ServiceManager.SourceManager.SourceViewChanged += OnPlayerEngineStateChanged;
             //ServiceManager.SourceManager.SourceAdded += OnPlayerEngineStateChanged;
@@ -331,6 +315,19 @@
             }
         }
 
+        private void OnSortChildrenMenu (object o, EventArgs args)
+        {
+            foreach (Widget proxy_widget in this["SortChildrenAction"].Proxies) {
+                MenuItem menu = proxy_widget as MenuItem;
+                if (menu == null)
+                    continue;
+
+                Menu submenu = BuildSortMenu (ActionSource);
+                menu.Submenu = submenu;
+                submenu.ShowAll ();
+            }
+        }
+
 #endregion
 
 #region Utility Methods
@@ -377,7 +374,7 @@
             }
             
             if (source != null) {
-                UpdateAction ("SortChildrenAction", source.Children.Count > 1, true, null);
+                UpdateAction ("SortChildrenAction", source.SortTypes.Length > 0 && source.Children.Count > 1, true, source);
             }
 
             Action<Source> handler = Updated;
@@ -429,6 +426,30 @@
             }
         }
 
+        private static Menu BuildSortMenu (Source source)
+        {
+            Menu menu = new Menu ();
+            GLib.SList group = null;
+            foreach (SourceSortType sort_type in source.SortTypes) {
+                RadioMenuItem item = new RadioMenuItem (group, sort_type.Label);
+                group = item.Group;
+                item.Active = (sort_type == source.ActiveChildSort);
+                item.Toggled += BuildSortChangedHandler (source, sort_type);
+                menu.Append (item);
+            }
+            return menu;
+        }
+
+        private static EventHandler BuildSortChangedHandler (Source source, SourceSortType sort_type)
+        {
+            return delegate (object sender, EventArgs args) {
+                RadioMenuItem item = sender as RadioMenuItem;
+                if (item != null && item.Active) {
+                    source.SortChildSources (sort_type);
+                }
+            };
+        }
+
 #endregion
         
     }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CellEditEntry.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CellEditEntry.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CellEditEntry.cs	Fri Feb 27 20:27:23 2009
@@ -34,6 +34,7 @@
     internal class CellEditEntry : Entry, CellEditable
     {
         public string path;
+        private bool fired_edit_done = false;
     
         public CellEditEntry () : base ()
         {
@@ -42,9 +43,17 @@
         
         protected override bool OnFocusOutEvent (Gdk.EventFocus focus)
         {
-            FinishEditing ();
+            if (!fired_edit_done) {
+                FinishEditing ();
+            }
             RemoveWidget ();
             return base.OnFocusOutEvent (focus);
         }
+        
+        protected override void OnEditingDone ()
+        {
+            fired_edit_done = true;
+            base.OnEditingDone ();
+        }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs	Fri Feb 27 20:27:23 2009
@@ -61,6 +61,7 @@
         private SourceModel store;
         private int current_timeout = -1;
         private bool editing_row = false;
+        private bool need_resort = false;
 
         public SourceView ()
         {
@@ -110,7 +111,7 @@
                     lock (args.Source) {
                         TreeIter iter = store.FindSource (args.Source);
                         if (!TreeIter.Zero.Equals (iter)) {
-                            store.SetValue (iter, 1, args.Source.Order);
+                            need_resort = true;
                             QueueDraw ();
                         }
                     }
@@ -222,6 +223,21 @@
         
         protected override bool OnExposeEvent (Gdk.EventExpose evnt)
         {
+            if (need_resort) {
+                need_resort = false;
+                
+                // Resort the tree store. This is performed in an event handler
+                // known not to conflict with gtk_tree_view_bin_expose() to prevent
+                // errors about corrupting the TreeView's internal state.
+                foreach (Source dsource in ServiceManager.SourceManager.Sources) {
+                    TreeIter iter = store.FindSource (dsource);
+                    if (!TreeIter.Zero.Equals (iter)) {
+                        store.SetValue (iter, 1, dsource.Order);
+                    }
+                }
+                QueueDraw ();
+            }
+            
             try {
                 cr = Gdk.CairoHelper.Create (evnt.Window);
                 return base.OnExposeEvent (evnt);

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml	Fri Feb 27 20:27:23 2009
@@ -106,27 +106,16 @@
   <popup name="LibraryContextMenu" action="LibraryContextMenuAction">
     <menuitem name="NewPlaylist" action="NewPlaylistAction"/>
     <menuitem name="NewSmartPlaylist" action="NewSmartPlaylistAction"/>
+    <menu name="SortChildren" action="SortChildrenAction" />
     <separator/>
     <menuitem name="Import" action="ImportAction"/>
     <separator/>
-    <menu name="SortChildren" action="SortChildrenAction">
-      <menuitem name="SortChildrenNameAsc" action="SortChildrenNameAscAction"/>
-      <menuitem name="SortChildrenNameDesc" action="SortChildrenNameDescAction"/>
-      <menuitem name="SortChildrenSizeAsc" action="SortChildrenSizeAscAction"/>
-      <menuitem name="SortChildrenSizeDesc" action="SortChildrenSizeDescAction"/>
-    </menu>
   </popup>
 
   <popup name="RemovableSourceContextMenu" action="RemovableSourceContextMenuAction">
     <menuitem name="NewPlaylist" action="NewPlaylistAction"/>
     <menuitem name="NewSmartPlaylist" action="NewSmartPlaylistAction"/>
-    <separator/>
-    <menu name="SortChildren" action="SortChildrenAction">
-      <menuitem name="SortChildrenNameAsc" action="SortChildrenNameAscAction"/>
-      <menuitem name="SortChildrenNameDesc" action="SortChildrenNameDescAction"/>
-      <menuitem name="SortChildrenSizeAsc" action="SortChildrenSizeAscAction"/>
-      <menuitem name="SortChildrenSizeDesc" action="SortChildrenSizeDescAction"/>
-    </menu>
+    <menu name="SortChildren" action="SortChildrenAction" />
     <separator/>
     <placeholder name="AboveImportSource"/>
     <menuitem name="ImportSource" action="ImportSourceAction"/>

Modified: trunk/banshee/src/Extensions/Banshee.InternetRadio/Resources/GlobalUI.xml
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.InternetRadio/Resources/GlobalUI.xml	(original)
+++ trunk/banshee/src/Extensions/Banshee.InternetRadio/Resources/GlobalUI.xml	Fri Feb 27 20:27:23 2009
@@ -4,5 +4,6 @@
         <separator/>
         <menuitem name="NewPlaylist" action="NewPlaylistAction"/>
         <menuitem name="NewSmartPlaylist" action="NewSmartPlaylistAction"/>
+        <menu name="SortChildren" action="SortChildrenAction" />
     </popup>
-</ui>
\ No newline at end of file
+</ui>

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmActions.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmActions.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmActions.cs	Fri Feb 27 20:27:23 2009
@@ -73,11 +73,6 @@
                     "LastfmConnectAction", null,
                      Catalog.GetString ("Connect"),
                      null, String.Empty, OnConnect
-                ),
-                new ActionEntry (
-                    "LastfmSortAction", "gtk-sort-descending",
-                    Catalog.GetString ("Sort Stations by"),
-                    null, String.Empty, null
                 )
             });
 
@@ -159,31 +154,6 @@
             this["LastfmLoveAction"].IconName = "face-smile";
             this["LastfmHateAction"].IconName = "face-sad";
 
-            Add (
-                new RadioActionEntry [] {
-                    new RadioActionEntry (
-                        "LastfmSortStationsByNameAction", null,
-                         Catalog.GetString ("Station Name"),
-                         null, "", 0
-                    ),
-                    new RadioActionEntry (
-                        "LastfmSortStationsByPlayCountAction", null,
-                         Catalog.GetString ("Total Play Count"),
-                         null, "", 1
-                    ),
-                    new RadioActionEntry (
-                        "LastfmSortStationsByTypeAction", null,
-                         Catalog.GetString ("Station Type"),
-                         null, "", 2
-                    )
-                },
-                Array.IndexOf (LastfmSource.ChildComparers, lastfm.ChildComparer),
-                delegate (object sender, ChangedArgs args) {
-                    lastfm.ChildComparer = LastfmSource.ChildComparers[args.Current.Value];
-                    lastfm.SortChildSources ();
-                }
-            );
-
             this["LastfmLoveAction"].IsImportant = true;
             this["LastfmHateAction"].IsImportant = true;
 
@@ -362,7 +332,7 @@
         private void OnTrackRecommend (object sender, EventArgs args)
         {
         }
-
+        
 #endregion
 
         private string artist;
@@ -415,7 +385,6 @@
 
             bool have_user = (lastfm.Account != null && lastfm.Account.UserName != null);
             this["LastfmAddAction"].Sensitive = have_user;
-            this["LastfmSortAction"].Sensitive = have_user;
             this["LastfmConnectAction"].Visible = lastfm.Connection.State == ConnectionState.Disconnected;
 
             TrackInfo current_track = ServiceManager.PlayerEngine.CurrentTrack;

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmSource.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmSource.cs	Fri Feb 27 20:27:23 2009
@@ -34,7 +34,6 @@
 
 using Lastfm;
 using Hyena.Data;
-using SortType = Hyena.Data.SortType;
 
 using Banshee.Base;
 using Banshee.Collection;
@@ -69,9 +68,8 @@
             get { return actions; }
         }
 
-        public LastfmSource () : base (lastfm, lastfm, 210)
+        public LastfmSource () : base (lastfm, lastfm, 210, lastfm)
         {
-            TypeUniqueId = lastfm;
             account = LastfmCore.Account;
 
             // We don't automatically connect to Last.fm, but load the last Last.fm
@@ -102,6 +100,7 @@
             Properties.SetString ("GtkActionPath", "/LastfmSourcePopup");
             Properties.SetString ("Icon.Name", "lastfm-audioscrobbler");
             Properties.SetString ("SourcePropertiesActionLabel", Catalog.GetString ("Edit Last.fm Settings"));
+            Properties.SetString ("SortChildrenActionLabel", Catalog.GetString ("Sort Stations by"));
             Properties.Set<LastfmColumnController> ("TrackView.ColumnController", new LastfmColumnController ());
 
             // FIXME this is temporary until we split the GUI part from the non-GUI part
@@ -139,20 +138,6 @@
             }
         }
 
-        /*public override void AddChildSource (ChildSource source)
-        {
-            base.AddChildSource (source);
-            SortChildSources ();
-            source.Updated += HandleChildUpdated;
-        }
-
-        public override void RemoveChildSource (ChildSource source)
-        {
-            base.RemoveChildSource (source);
-            source.Updated -= HandleChildUpdated;
-        }*/
-
-
         // Order by the playCount of a station, then by inverted name
         public class PlayCountComparer : IComparer<Source>
         {
@@ -176,51 +161,27 @@
                 return c == 0 ? (a.Name.CompareTo (b.Name)) : c; 
             }
         }
-
-        public static IComparer<Source> [] ChildComparers = new IComparer<Source> [] {
-            new NameComparer (), new PlayCountComparer (), new TypeComparer ()
+        
+        private static SourceSortType[] sort_types = new SourceSortType[] {
+            SortNameAscending,
+            new SourceSortType (
+                "LastfmTotalPlayCount",
+                Catalog.GetString ("Total Play Count"),
+                SortType.Descending, new PlayCountComparer ()),
+            new SourceSortType (
+                "LastfmStationType",
+                Catalog.GetString ("Station Type"),
+                SortType.Ascending, new TypeComparer ())
         };
-        public static SortType [] child_orders = new SortType [] {
-            SortType.Ascending, SortType.Descending, SortType.Ascending
-        };
-
-        public IComparer<Source> ChildComparer {
-            get {
-                if (child_comparer == null) {
-                    int i = (int) StationSortSchema.Get ();
-                    ChildComparer = ChildComparers [i];
-                }
-                return child_comparer;
-            }
-            set {
-                child_comparer = value;
-                int i = Array.IndexOf (ChildComparers, child_comparer);
-                child_order = child_orders[i];
-                StationSortSchema.Set (i);
-            }
+        
+        public override SourceSortType[] SortTypes {
+            get { return sort_types; }
+        }
+        
+        public override SourceSortType DefaultChildSort {
+            get { return SortNameAscending; }
         }
-
-        private bool sorting = false;
-        private IComparer<Source> child_comparer;
-        private SortType child_order;
-        public override void SortChildSources (IComparer<Source> comparer, bool asc)
-        {
-            lock (this) {
-                if (sorting)
-                    return;
-                sorting = true;
-            }
-
-            base.SortChildSources (comparer, asc);
-            ChildComparer = comparer;
-            sorting = false;
-        }
-
-        public void SortChildSources  ()
-        {
-            SortChildSources (ChildComparer, child_order == SortType.Ascending);
-        }
-
+        
         private string last_username;
         private bool last_was_subscriber = false;
         public void SetUserName (string username)
@@ -230,11 +191,11 @@
                 last_was_subscriber = Connection.Subscriber;
                 LastfmSource.LastUserSchema.Set (last_username);
                 ClearChildSources ();
-                sorting = true;
+                PauseSorting ();
                 foreach (StationSource child in StationSource.LoadAll (this, Account.UserName)) {
                     AddChildSource (child);
                 }
-                sorting = false;
+                ResumeSorting ();
                 SortChildSources ();
             }
         }
@@ -269,11 +230,6 @@
             UpdateUI ();
         }
 
-        /*private void HandleChildUpdated (object sender, EventArgs args)
-        {
-            SortChildSources ();
-        }*/
-
         private void UpdateUI ()
         {
             bool have_user = Account.UserName != null;
@@ -326,10 +282,6 @@
             "plugins.lastfm", "enabled", false, "Extension enabled", "Last.fm extension enabled"
         );
 
-        public static readonly SchemaEntry<int> StationSortSchema = new SchemaEntry<int> (
-            "plugins.lastfm", "station_sort", 0, "Station sort criteria", "Last.fm station sort criteria. 0 = name, 1 = play count, 2 = type"
-        );
-
         public static readonly SchemaEntry<string> LastUserSchema = new SchemaEntry<string> (
             "plugins.lastfm", "username", "", "Last.fm user", "Last.fm username"
         );

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs	Fri Feb 27 20:27:23 2009
@@ -111,11 +111,10 @@
         private int dbid;
         
         // For StationSources that already exist in the db
-        protected StationSource (LastfmSource lastfm, int dbId, string name, string type, string arg, int playCount) : base (generic_name, name, 150)
+        protected StationSource (LastfmSource lastfm, int dbId, string name, string type, string arg, int playCount) : base (generic_name, name, 150, dbId.ToString ())
         {
             this.lastfm = lastfm;
             dbid = dbId;
-            TypeUniqueId = dbid.ToString ();
             Type = StationType.FindByName (type);
             Arg = arg;
             PlayCount = playCount;

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Resources/GlobalUI.xml
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Resources/GlobalUI.xml	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Resources/GlobalUI.xml	Fri Feb 27 20:27:23 2009
@@ -1,12 +1,8 @@
 <ui>
     <popup name="LastfmSourcePopup" action="LastfmSourcePopupAction">
         <menuitem name="LastfmAdd" action="LastfmAddAction" />
-        <menu name='SortPlaylist' action='LastfmSortAction'>
-            <menuitem name='SortStationByName' action='LastfmSortStationsByNameAction' />
-            <menuitem name='SortStationByPlayCount' action='LastfmSortStationsByPlayCountAction' />
-            <menuitem name='SortStationByType' action='LastfmSortStationsByTypeAction' />
-        </menu>
         <menuitem name="Connect" action="LastfmConnectAction" />
+        <menu name='SortChildren' action='SortChildrenAction' />
         <separator />
         <menuitem name="SourceProperties" action="SourcePropertiesAction" />
     </popup>

Modified: trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs	Fri Feb 27 20:27:23 2009
@@ -45,14 +45,13 @@
         private TrackInfo transitioned_track;
         private NowPlayingInterface now_playing_interface;
         
-        public NowPlayingSource () : base ("now-playing", Catalog.GetString ("Now Playing"), 10)
+        public NowPlayingSource () : base ("now-playing", Catalog.GetString ("Now Playing"), 10, "now-playing")
         {
             if (Banshee.ServiceStack.ServiceManager.PlayerEngine.VideoDisplayContextType != 
                 Banshee.MediaEngine.VideoDisplayContextType.GdkWindow) {
                 throw new ApplicationException ("Unsupported video display context");
             }
         
-            TypeUniqueId = "now-playing";
             now_playing_interface = new NowPlayingInterface ();
         
             Properties.SetString ("Icon.Name", "applications-multimedia");

Modified: trunk/banshee/src/Extensions/Banshee.Podcasting/Resources/GlobalUI.xml
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Podcasting/Resources/GlobalUI.xml	(original)
+++ trunk/banshee/src/Extensions/Banshee.Podcasting/Resources/GlobalUI.xml	Fri Feb 27 20:27:23 2009
@@ -5,13 +5,7 @@
         <separator/>
         <menuitem name="NewPlaylist" action="NewPlaylistAction"/>
         <menuitem name="NewSmartPlaylist" action="NewSmartPlaylistAction"/>
-        <separator/>
-        <menu name="SortChildren" action="SortChildrenAction">
-          <menuitem name="SortChildrenNameAsc" action="SortChildrenNameAscAction"/>
-          <menuitem name="SortChildrenNameDesc" action="SortChildrenNameDescAction"/>
-          <menuitem name="SortChildrenSizeAsc" action="SortChildrenSizeAscAction"/>
-          <menuitem name="SortChildrenSizeDesc" action="SortChildrenSizeDescAction"/>
-        </menu>
+        <menu name="SortChildren" action="SortChildrenAction" />
     </popup>
 
     <popup name="PodcastAllFeedsContextMenu" action="PodcastAllFeedsContextMenuAction">



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