banshee r3386 - in trunk/banshee: . src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Base src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.SmartPlaylist src/Core/Banshee.Services/Banshee.Sources src/Core/Banshee.ThickClient/Banshee.Sources.Gui src/Libraries/Hyena/Hyena.Collections src/Libraries/Hyena/Hyena.Data.Sqlite



Author: gburt
Date: Wed Mar  5 22:13:06 2008
New Revision: 3386
URL: http://svn.gnome.org/viewvc/banshee?rev=3386&view=rev

Log:
2008-03-05  Gabriel Burt  <gabriel burt gmail com>

	* src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs: Change to prevent
	the method from being called while it is still running, queueing another
	run to happen when the current one finishes, instead of specifying a
	specific rate limit.

	* src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs:
	* src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs:
	Set HasSelectAllItem on cache to true.

	* src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs:
	Avoid parsing the user query if it hasn't changed since we last parsed it.
	Add SuppressReloads method so we can update both the album and artist
	filter before doing a Reload, and add a ClearArtistAlbumFilters method
	that directly, quickly does that.

	* src/Core/Banshee.Services/Banshee.Collection/AlbumListModel.cs:
	* src/Core/Banshee.Services/Banshee.Collection/ArtistListModel.cs:
	* src/Core/Banshee.Services/Banshee.Collection/BansheeListModel.cs:
	* src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs: Create
	the selection object within each subclass so that Album and Artist models
	can create a SelectAllSelection.

	* src/Core/Banshee.Services/Makefile.am:
	* src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs: New
	class that makes sure the first item is selected as the AllSelected = true
	state.

	* src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs:
	Override new ReloadTrackModel method which is called by DatabaseSource's
	RateLimitedReload and RateLimitedFilter methods.

	* src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs: Add
	RateLimitedFilter method for spawning off the filter handler.

	* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs:
	Updated to work with SelectAllSelection and to trigger two track model
	updates when the artist model changes - one that is not filtered by any
	artists or albums, and one that is filtered by the artist/album selection,
	if any.

	* src/Libraries/Hyena/Hyena.Collections/Selection.cs: Change AllSelected
	and SelectAll to be virtual, add a MaxIndex getter.

	* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs: Update the
	SaveSelection and RestoreSelection code to work with artist/album
	selections that have a first (fake) item "All *".


Added:
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs
Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/AlbumListModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ArtistListModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/BansheeListModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
   trunk/banshee/src/Core/Banshee.Services/Makefile.am
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Collections/Selection.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs	Wed Mar  5 22:13:06 2008
@@ -27,7 +27,6 @@
 //
 
 using System;
-using GLib;
 
 namespace Banshee.Base
 {
@@ -36,72 +35,41 @@
         public delegate void RateLimitedMethod ();
 
         private RateLimitedMethod method;
-        private double initial_delay_ms;
-        private double min_interval_ms;
-        private DateTime last_executed = DateTime.MinValue;
-        private uint timeout_id = 0;
-
         private bool requested = false;
-        private double requested_interval;
         private bool executing = false;
 
-        public RateLimiter (double min_interval_ms, RateLimitedMethod method) : this (0.0, min_interval_ms, method)
-        {
-        }
-
-        public RateLimiter (double initial_delay_ms, double min_interval_ms, RateLimitedMethod method)
+        public RateLimiter (RateLimitedMethod method)
         {
-            this.initial_delay_ms = initial_delay_ms;
-            this.min_interval_ms = min_interval_ms;
             this.method = method;
         }
 
         public void Execute ()
         {
-            Execute (min_interval_ms);
-        }
-
-        public void Execute (double min_interval_ms)
-        {
             lock (this) {
-                if (requested || timeout_id != 0) {
-                    return;
-                }
-
-                if (executing) {
+                if (requested || executing) {
                     requested = true;
-                    requested_interval = min_interval_ms;
                     return;
                 }
-
-                double delta = (DateTime.Now - last_executed).TotalMilliseconds;
-                if (delta >= min_interval_ms) {
-                    timeout_id = GLib.Timeout.Add ((uint) initial_delay_ms, OnRateLimitTimer);
-                } else {
-                    timeout_id = GLib.Timeout.Add ((uint) (min_interval_ms - delta), OnRateLimitTimer);
-                }
             }
+
+            InnerExecute ();
         }
 
-        private bool OnRateLimitTimer ()
+        private bool InnerExecute ()
         {
             lock (this) {
-                timeout_id = 0;
                 executing = true;
             }
 
-            //Hyena.Log.DebugFormat ("Executing method {0} from {1} in {2}", method.Method.Name, method.Method.DeclaringType, System.Threading.Thread.CurrentThread.ManagedThreadId);
             method ();
 
             lock (this) {
-                last_executed = DateTime.Now;
-                //Hyena.Log.DebugFormat ("Done executing method {0} from {1} at {2}", method.Method.Name, method.Method.DeclaringType, last_executed);
                 executing = false;
             }
 
             if (requested) {
                 requested = false;
-                Execute (requested_interval);
+                Execute ();
             }
 
             return false;

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs	Wed Mar  5 22:13:06 2008
@@ -53,6 +53,7 @@
         {
             provider = LibraryAlbumInfo.Provider;
             cache = new BansheeModelCache <LibraryAlbumInfo> (connection, uuid, this, provider);
+            cache.HasSelectAllItem = true;
         }
 
         public AlbumListDatabaseModel(TrackListDatabaseModel trackModel, 
@@ -62,7 +63,7 @@
         }
 
         private bool first_reload = true;
-        public override void Reload()
+        public override void Reload ()
         {
             if (!first_reload || !cache.Warm) {
                 bool either = (artist_id_filter_query != null) || (track_model != null);

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs	Wed Mar  5 22:13:06 2008
@@ -51,6 +51,7 @@
         {
             provider = LibraryArtistInfo.Provider;
             cache = new BansheeModelCache <LibraryArtistInfo> (connection, uuid, this, provider);
+            cache.HasSelectAllItem = true;
         }
 
         public ArtistListDatabaseModel(TrackListDatabaseModel trackModel, BansheeDbConnection connection, string uuid) : this (connection, uuid)
@@ -59,7 +60,7 @@
         }
     
         private bool first_reload = true;
-        public override void Reload()
+        public override void Reload ()
         {
             if (!first_reload || !cache.Warm) {
                 reload_fragment = String.Format (

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs	Wed Mar  5 22:13:06 2008
@@ -93,35 +93,24 @@
             Refilter ();
         }
         
+        private bool have_new_filter = true;
         private void GenerateFilterQueryPart()
         {
+            if (!have_new_filter)
+                return;
+
             if (String.IsNullOrEmpty(Filter)) {
                 filter_query = null;
             } else {
-                Hyena.Query.UserQueryParser qp = new UserQueryParser (Filter);
-                QueryNode n = qp.BuildTree (BansheeQuery.FieldSet);
-
-                filter_query = n.ToSql (BansheeQuery.FieldSet);
-
-                /*
-                Console.WriteLine ("query: {0}", Filter);
-                Console.WriteLine ("Xml for Query: {0}", n.ToXml (BansheeQuery.FieldSet, true));
-                Console.WriteLine ("Sql for Query: {0}", filter_query);
-                Hyena.Query.QueryParser qp2 = new XmlQueryParser (n.ToXml (BansheeQuery.FieldSet));
-                QueryNode n2 = qp2.BuildTree (BansheeQuery.FieldSet);
-                if (n2 != null) {
-                    Console.WriteLine ("User query for Xml: {0}", n2.ToUserQuery ());
-                } else
-                    Console.WriteLine ("n2 is null");
-                    */
+                QueryNode query_tree = UserQueryParser.Parse (Filter, BansheeQuery.FieldSet);
+                filter_query = (query_tree == null) ? null : query_tree.ToSql (BansheeQuery.FieldSet);
 
-                if (filter_query.Length == 0)
+                if (filter_query != null && filter_query.Length == 0) {
                     filter_query = null;
-                //else {
-                    //artist_id_filter_query = null;
-                    //album_id_filter_query = null;
-                //}
+                }
             }
+
+            have_new_filter = false;
         }
 
         private void GenerateSortQueryPart()
@@ -211,6 +200,9 @@
         private bool first_reload = true;
         public override void Reload()
         {
+            if (suppress_reload)
+                return;
+
             UpdateUnfilteredAggregates ();
 
             StringBuilder qb = new StringBuilder ();
@@ -287,6 +279,7 @@
             set { 
                 lock(this) {
                     filter = value; 
+                    have_new_filter = true;
                 }
             }
         }
@@ -382,6 +375,14 @@
             }
         }
 
+        public override void ClearArtistAlbumFilters ()
+        {
+            artist_id_filter_query = null;
+            album_id_filter_query = null;
+            Refilter();
+            Reload();
+        }
+
         public int CacheId {
             get { return (int) cache.CacheId; }
         }
@@ -428,6 +429,12 @@
             set { caches_join_table_entries = value; }
         }
 
+        private bool suppress_reload = false;
+        public bool SuppressReloads {
+            get { return suppress_reload; }
+            set { suppress_reload = value; }
+        }
+
         // Implement ICacheableModel
         public int FetchCount {
             get { return RowsInView > 0 ? RowsInView * 5 : 100; }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/AlbumListModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/AlbumListModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/AlbumListModel.cs	Wed Mar  5 22:13:06 2008
@@ -38,12 +38,14 @@
     {
         public AlbumListModel() : base ()
         {
-            selection.Select (0);
+            selection = new SelectAllSelection ();
+            selection.SelectAll ();
         }
         
         public AlbumListModel(IDBusExportable parent) : base(parent)
         {
-            selection.Select (0);
+            selection = new SelectAllSelection ();
+            selection.SelectAll ();
         }
 
         public virtual IEnumerable<ArtistInfo> ArtistInfoFilter {

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ArtistListModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ArtistListModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ArtistListModel.cs	Wed Mar  5 22:13:06 2008
@@ -37,12 +37,14 @@
     {
         public ArtistListModel() : base ()
         {
-            selection.Select (0);
+            selection = new SelectAllSelection ();
+            selection.SelectAll ();
         }
         
         public ArtistListModel(IDBusExportable parent) : base(parent)
         {
-            selection.Select (0);
+            selection = new SelectAllSelection ();
+            selection.SelectAll ();
         }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/BansheeListModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/BansheeListModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/BansheeListModel.cs	Wed Mar  5 22:13:06 2008
@@ -37,7 +37,7 @@
 {
     public abstract class BansheeListModel<T> : ExportableModel, IListModel<T>
     {
-        protected Selection selection = new Selection ();
+        protected Selection selection;
 
         public event EventHandler Cleared;
         public event EventHandler Reloaded;
@@ -91,5 +91,12 @@
         public virtual Selection Selection {
             get { return selection; }
         }
+
+        protected ModelSelection<T> model_selection;
+        public virtual ModelSelection<T> SelectedItems {
+            get {
+                return model_selection ?? model_selection = new ModelSelection<T> (this, Selection);
+            }
+        }
     }
 }

Added: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs	Wed Mar  5 22:13:06 2008
@@ -0,0 +1,61 @@
+//
+// SelectAllSelection.cs
+//
+// Author:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// 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 Hyena.Collections;
+
+namespace Banshee.Collection
+{
+    public class SelectAllSelection : Selection
+    {
+        public SelectAllSelection () : base ()
+        {
+        }
+
+        protected override void OnChanged ()
+        {
+            if (Count == 0 || base.AllSelected) {
+                Clear (false);
+                QuietSelect (0);
+            }
+
+            base.OnChanged ();
+        }
+
+        public override void SelectAll ()
+        {
+            Clear (false);
+            Select (0);
+        }
+
+        public override bool AllSelected {
+            get { return Contains (0); }
+        }
+    }
+}

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs	Wed Mar  5 22:13:06 2008
@@ -30,6 +30,7 @@
 using System.Collections.Generic;
 
 using Hyena.Data;
+using Hyena.Collections;
 using Hyena.Query;
 
 using Banshee.ServiceStack;
@@ -40,10 +41,12 @@
     {
         public TrackListModel() : base ()
         {
+            selection = new Selection ();
         }
         
         public TrackListModel(IDBusExportable parent) : base(parent)
         {
+            selection = new Selection ();
         }
         
         public virtual int IndexOf(TrackInfo track)
@@ -58,5 +61,9 @@
         public virtual IEnumerable<AlbumInfo> AlbumInfoFilter {
             set { throw new NotImplementedException(); }
         }
+
+        public virtual void ClearArtistAlbumFilters ()
+        {
+        }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs	Wed Mar  5 22:13:06 2008
@@ -291,7 +291,7 @@
 
 #region DatabaseSource overrides
 
-        public override void RateLimitedReload ()
+        protected override void ReloadTrackModel ()
         {
             // Wipe the member list clean
             ServiceManager.DbConnection.Execute (String.Format (
@@ -308,7 +308,7 @@
                 DbId, PrependCondition("AND"), OrderAndLimit
             ));
 
-            base.RateLimitedReload ();
+            base.ReloadTrackModel ();
         }
 
 #endregion

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs	Wed Mar  5 22:13:06 2008
@@ -54,6 +54,7 @@
         protected ArtistListDatabaseModel artist_model;
 
         protected RateLimiter reload_limiter;
+        protected RateLimiter filter_limiter;
         
         public DatabaseSource (string generic_name, string name, string id, int order) : base (generic_name, name, order)
         {
@@ -61,7 +62,8 @@
             track_model = new TrackListDatabaseModel (ServiceManager.DbConnection, uuid);
             album_model = new AlbumListDatabaseModel (track_model, ServiceManager.DbConnection, uuid);
             artist_model = new ArtistListDatabaseModel (track_model, ServiceManager.DbConnection, uuid);
-            reload_limiter = new RateLimiter (50.0, RateLimitedReload);
+            reload_limiter = new RateLimiter (RateLimitedReload);
+            filter_limiter = new RateLimiter (RateLimitedFilter);
         }
 
 #region Public Properties
@@ -93,9 +95,7 @@
         public override string FilterQuery {
             set {
                 base.FilterQuery = value;
-                track_model.Filter = value;
-                track_model.Refilter ();
-                Reload ();
+                filter_limiter.Execute ();
             }
         }
 
@@ -135,30 +135,53 @@
 
 #region Public Methods
 
-        public void Reload (double min_interval_ms)
+        public void Reload ()
         {
-            ThreadAssist.SpawnFromMain (delegate {
-                //reload_limiter.Execute (min_interval_ms);
-                RateLimitedReload ();
-            });
+            reload_limiter.Execute ();
         }
 
-        public void Reload ()
+        protected virtual void RateLimitedReload ()
         {
             ThreadAssist.SpawnFromMain (delegate {
-                //reload_limiter.Execute (100.0);
-                RateLimitedReload ();
+                lock (track_model) {
+                    ReloadTrackModel ();
+                    artist_model.Reload ();
+                    album_model.Reload ();
+                    OnUpdated ();
+                }
             });
         }
 
-        public virtual void RateLimitedReload ()
+        protected virtual void ReloadTrackModel ()
         {
-            lock (track_model) {
-                track_model.Reload ();
-                artist_model.Reload ();
-                album_model.Reload ();
-                OnUpdated ();
-            }
+            track_model.Reload ();
+        }
+
+        protected virtual void RateLimitedFilter ()
+        {
+            ThreadAssist.SpawnFromMain (delegate {
+                lock (this) {
+                    // First, reload the track model w/o the artist/album filter
+                    track_model.SuppressReloads = true;
+                    track_model.Filter = FilterQuery;
+                    track_model.ClearArtistAlbumFilters ();
+                    track_model.SuppressReloads = false;
+                    ReloadTrackModel ();
+
+                    // Then, reload the artist/album models
+                    artist_model.Reload ();
+                    album_model.Reload ();
+
+                    // Then, reload the track model with the artist/album filters
+                    track_model.SuppressReloads = true;
+                    track_model.ArtistInfoFilter = artist_model.SelectedItems;
+                    track_model.AlbumInfoFilter = album_model.SelectedItems;
+                    track_model.SuppressReloads = false;
+                    ReloadTrackModel ();
+
+                    OnUpdated ();
+                }
+            });
         }
 
         /*protected virtual void ReloadChildren ()

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	Wed Mar  5 22:13:06 2008
@@ -25,6 +25,7 @@
 	Banshee.Collection/ImportEventHandler.cs \
 	Banshee.Collection/ImportManager.cs \
 	Banshee.Collection/ModelHelper.cs \
+	Banshee.Collection/SelectAllSelection.cs \
 	Banshee.Collection/TrackListModel.cs \
 	Banshee.Configuration/DatabaseConfigurationClient.cs \
 	Banshee.Database/BansheeDbConnection.cs \

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs	Wed Mar  5 22:13:06 2008
@@ -255,6 +255,7 @@
         {
             ToggleAction action = (ToggleAction)o;
             artist_view.Selection.Clear ();
+            album_view.Selection.Clear ();
             browser_container.Visible = action.Active && ActiveSourceCanHasBrowser;
             BrowserVisible.Set (action.Active);
         }
@@ -263,20 +264,18 @@
         {
             Hyena.Collections.Selection selection = (Hyena.Collections.Selection)o;
             TrackListModel model = track_view.Model as TrackListModel;
-            
-            if (selection.Count == 1 && selection.Contains(0) || selection.AllSelected) {
+
+            if (selection.AllSelected) {
                 if (model != null && o == artist_view.Selection ) {
-                    model.ArtistInfoFilter = null;
+                    model.ClearArtistAlbumFilters ();
                     album_model.ArtistInfoFilter = null;
+                    if (!album_model.Selection.AllSelected) {
+                        UpdateAlbumSelectionFilters ();
+                    }
                 } else if (model != null && o == album_view.Selection) {
                     model.AlbumInfoFilter = null;
                 }
                 return;
-            } else if (selection.Count == 0) {
-                selection.Select(0);
-                return;
-            } else if (selection.Count > 0 && !selection.AllSelected) {
-                selection.QuietUnselect(0);
             }
             
             if (o == artist_view.Selection) {
@@ -287,19 +286,18 @@
                     artists[i++] = artist_view.Model[row_index];
                 }
             
+                model.AlbumInfoFilter = null;
                 model.ArtistInfoFilter = artists;
                 album_model.ArtistInfoFilter = artists;
             } else if (o == album_view.Selection) {
-                AlbumInfo [] albums = new AlbumInfo[selection.Count];
-                int i = 0;
-            
-                foreach (int row_index in album_view.Selection) {
-                    albums[i++] = album_view.Model[row_index];
-                }
-            
-                model.AlbumInfoFilter = albums;
+                UpdateAlbumSelectionFilters ();
             }
         }
+
+        private void UpdateAlbumSelectionFilters ()
+        {
+            (track_view.Model as TrackListModel).AlbumInfoFilter = (album_view.Model as AlbumListModel).SelectedItems;
+        }
         
         public void SetModels (TrackListModel track, ArtistListModel artist, AlbumListModel album)
         {

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Collections/Selection.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Collections/Selection.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Collections/Selection.cs	Wed Mar  5 22:13:06 2008
@@ -58,7 +58,7 @@
         public Selection ()
         {
         }
-        
+
         protected virtual void OnChanged ()
         {
             EventHandler handler = Changed;
@@ -73,7 +73,7 @@
                 ranges.Add (index);
             }
             
-            OnChanged();
+            OnChanged ();
         }
         
         public void Select (int index)
@@ -136,7 +136,7 @@
             OnChanged ();
         }
 
-        public void SelectAll ()
+        public virtual void SelectAll ()
         {
             SelectRange (0, max_index);
         }
@@ -153,9 +153,8 @@
             }
             
             ranges.Clear ();
-            if (raise) {
+            if (raise)
                 OnChanged ();
-            }
         }
         
         public int Count {
@@ -164,9 +163,10 @@
         
         public int MaxIndex {
             set { max_index = value; }
+            get { return max_index; }
         }
         
-        public bool AllSelected {
+        public virtual bool AllSelected {
             get { 
                 if (ranges.RangeCount == 1) {
                     RangeCollection.Range range = ranges.Ranges[0];

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs	Wed Mar  5 22:13:06 2008
@@ -188,6 +188,12 @@
             ));
         }
 
+        private bool has_select_all_item = false;
+        public bool HasSelectAllItem {
+            get { return has_select_all_item; }
+            set { has_select_all_item = value; }
+        }
+
         public bool Warm {
             //get { return warm; }
             get { return false; }
@@ -223,8 +229,7 @@
             if (rows == 0) {
                 return -1;
             }
-            select_single_command.ApplyValues (item_id);
-            long target_id = connection.Query<long> (select_single_command);
+            long target_id = connection.Query<long> (select_single_command, item_id);
             if (target_id == 0) {
                 return -1;
             }
@@ -266,39 +271,50 @@
         {
             connection.Execute (delete_selection_command);
 
-            if (model.Selection.Count > 0) {
+            if (model.Selection.Count > 0 && !(has_select_all_item && model.Selection.AllSelected)) {
+                long start, end;
                 foreach (Hyena.Collections.RangeCollection.Range range in model.Selection.Ranges) {
-                    connection.Execute (save_selection_command.ApplyValues (range.Start, range.End - range.Start + 1));
+                    start = range.Start;
+                    end = range.End;
+
+                    // Compensate for the first, fake 'All *' item
+                    if (has_select_all_item) {
+                        start -= 1;
+                        end -= 1;
+                    }
+
+                    connection.Execute (save_selection_command, start, end - start + 1);
                 }
             }
         }
 
         private void RestoreSelection ()
         {
-            model.Selection.Clear (false);
+            bool cleared = false;
             long selected_id = -1;
             long first_id = FirstOrderId;
+
+            // Compensate for the first, fake 'All *' item
+            if (has_select_all_item) {
+                first_id -= 1;
+            }
+
             using (IDataReader reader = connection.Query (get_selection_command)) {
                 while (reader.Read ()) {
-                    selected_id = Convert.ToInt64 (reader[0]);
-                    selected_id -= first_id;
+                    if (!cleared) {
+                        model.Selection.Clear (false);
+                        cleared = true;
+                    }
+                    selected_id = Convert.ToInt64 (reader[0]) - first_id;
                     model.Selection.QuietSelect ((int)selected_id);
                 }
             }
-
-            // Trigger a model Changed event
-            if (selected_id == -1) {
-                model.Selection.Clear ();
-            } else {
-                model.Selection.Select ((int)selected_id);
-            }
         }
 
         protected override void FetchSet (long offset, long limit)
         {
             //using (new Timer (String.Format ("Fetching set for {0}", model))) {
-                select_range_command.ApplyValues (offset, limit);
-                using (IDataReader reader = connection.Query (select_range_command)) {
+                using (IDataReader reader = connection.Query (select_range_command, offset, limit)) {
                     while (reader.Read ()) {
                         if (!ContainsKey (offset)) {
                             Add (offset, provider.Load (reader, (int)offset));
@@ -311,7 +327,7 @@
         
         protected void UpdateAggregates ()
         {
-            using (IDataReader reader = connection.Query (count_command.ApplyValues (uid))) {
+            using (IDataReader reader = connection.Query (count_command, uid)) {
                 if (reader.Read ()) {
                     rows = Convert.ToInt64 (reader[0]);
 



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