[banshee] Configurable browser filters (bgo#540873)
- From: Alexander Kojevnikov <alexk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee] Configurable browser filters (bgo#540873)
- Date: Sun, 6 Nov 2011 12:28:18 +0000 (UTC)
commit 1ef1a4c868e154c446f6a1b8ae76d57cdfaa1dc0
Author: Frank Ziegler <funtastix googlemail com>
Date: Sun Nov 6 20:22:08 2011 +0800
Configurable browser filters (bgo#540873)
Add the genre filter. Option to switch between artists and album artists.
Signed-off-by: Alexander Kojevnikov <alexk gnome org>
.../DatabaseAlbumArtistInfo.cs | 86 ++++++++++
.../DatabaseAlbumArtistListModel.cs | 78 +++++++++
src/Core/Banshee.Services/Banshee.Services.csproj | 2 +
.../Banshee.Sources/DatabaseSource.cs | 6 +-
src/Core/Banshee.Services/Makefile.am | 2 +
.../CompositeTrackSourceContents.cs | 165 ++++++++++++++++++--
.../FilteredListSourceContents.cs | 8 +-
7 files changed, 330 insertions(+), 17 deletions(-)
---
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseAlbumArtistInfo.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseAlbumArtistInfo.cs
new file mode 100644
index 0000000..3448cb9
--- /dev/null
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseAlbumArtistInfo.cs
@@ -0,0 +1,86 @@
+//
+// DatabaseAlbumArtistInfo.cs
+//
+// Author:
+// Frank Ziegler <funtastix googlemail com>
+//
+// 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 Mono.Unix;
+
+using Hyena.Data;
+using Hyena.Data.Sqlite;
+
+using Banshee.Database;
+using Banshee.ServiceStack;
+
+namespace Banshee.Collection.Database
+{
+ public class DatabaseAlbumArtistInfo : ArtistInfo
+ {
+ private static BansheeModelProvider<DatabaseAlbumArtistInfo> provider = new BansheeModelProvider<DatabaseAlbumArtistInfo> (
+ ServiceManager.DbConnection, "CoreArtists"
+ );
+
+ public static BansheeModelProvider<DatabaseAlbumArtistInfo> Provider {
+ get { return provider; }
+ }
+
+ public DatabaseAlbumArtistInfo () : base (null, null)
+ {
+ }
+
+ [DatabaseColumn("ArtistID", Constraints = DatabaseColumnConstraints.PrimaryKey)]
+ private int dbid;
+ public int DbId {
+ get { return dbid; }
+ }
+
+ [DatabaseColumn("Name")]
+ public override string Name {
+ get { return base.Name; }
+ set { base.Name = value; }
+ }
+
+ [DatabaseColumn(Select = false)]
+ internal string NameLowered {
+ get { return Hyena.StringUtil.SearchKey (DisplayName); }
+ }
+
+ [DatabaseColumn("NameSort")]
+ public override string NameSort {
+ get { return base.NameSort; }
+ set { base.NameSort = value; }
+ }
+
+ [DatabaseColumn(Select = false)]
+ internal byte[] NameSortKey {
+ get { return Hyena.StringUtil.SortKey (NameSort ?? DisplayName); }
+ }
+
+ public override string ToString ()
+ {
+ return String.Format ("DatabaseAlbumArtistInfo<DbId: {0}, Name: {1}>", DbId, Name);
+ }
+ }
+}
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseAlbumArtistListModel.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseAlbumArtistListModel.cs
new file mode 100644
index 0000000..0b49aec
--- /dev/null
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseAlbumArtistListModel.cs
@@ -0,0 +1,78 @@
+//
+// DatabaseAlbumArtistListModel.cs
+//
+// Author:
+// Frank Ziegler <funtastix googlemail com>
+//
+// 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.Collections.Generic;
+using Mono.Unix;
+
+using Hyena;
+using Hyena.Data.Sqlite;
+using Hyena.Query;
+
+using Banshee.Database;
+
+namespace Banshee.Collection.Database
+{
+ public class DatabaseAlbumArtistListModel : DatabaseFilterListModel<DatabaseAlbumArtistInfo, ArtistInfo>
+ {
+ public DatabaseAlbumArtistListModel (Banshee.Sources.DatabaseSource source, DatabaseTrackListModel trackModel, BansheeDbConnection connection, string uuid)
+ : base (Banshee.Query.BansheeQuery.AlbumArtistField.Name, Banshee.Query.BansheeQuery.AlbumArtistField.Label,
+ source, trackModel, connection, DatabaseAlbumArtistInfo.Provider, new ArtistInfo (null, null), uuid)
+ {
+ QueryFields = new QueryFieldSet (Banshee.Query.BansheeQuery.AlbumArtistField);
+ ReloadFragmentFormat = @"
+ FROM (SELECT DISTINCT ArtistID, ArtistNameSortKey FROM CoreAlbums) CoreArtists WHERE CoreArtists.ArtistID IN
+ (SELECT CoreAlbums.ArtistID FROM CoreAlbums, CoreTracks, CoreCache{0}
+ WHERE CoreCache.ModelID = {1} AND
+ CoreTracks.AlbumID = CoreAlbums.AlbumID AND
+ EXISTS (SELECT 1 FROM CoreArtists WHERE ArtistID = CoreAlbums.ArtistID) AND
+ CoreCache.ItemID = {2} {3})
+ ORDER BY ArtistNameSortKey";
+ }
+
+ public override string FilterColumn {
+ get { return "CoreTracks.AlbumID"; }
+ }
+
+ protected override string ItemToFilterValue (object item)
+ {
+ return (item is DatabaseAlbumArtistInfo) ? "SELECT CoreAlbums.AlbumID FROM CoreAlbums WHERE CoreAlbums.ArtistID = " + (item as DatabaseAlbumArtistInfo).DbId.ToString () : null;
+ }
+
+ public override string GetSqlFilter ()
+ {
+ string res = base.GetSqlFilter ();
+ if (String.IsNullOrEmpty (res))
+ return res;
+ return res.Replace (","," UNION ");
+ }
+
+ public override void UpdateSelectAllItem (long count)
+ {
+ select_all_item.Name = String.Format (Catalog.GetString ("All AlbumArtists ({0})"), count);
+ }
+ }
+}
diff --git a/src/Core/Banshee.Services/Banshee.Services.csproj b/src/Core/Banshee.Services/Banshee.Services.csproj
index 2377802..3484a6e 100644
--- a/src/Core/Banshee.Services/Banshee.Services.csproj
+++ b/src/Core/Banshee.Services/Banshee.Services.csproj
@@ -322,6 +322,8 @@
<Compile Include="Banshee.MediaEngine\Tests.cs" />
<Compile Include="Banshee.Sources\Tests.cs" />
<Compile Include="Banshee.Query\Tests\BansheeQueryTests.cs" />
+ <Compile Include="Banshee.Collection.Database\DatabaseAlbumArtistInfo.cs" />
+ <Compile Include="Banshee.Collection.Database\DatabaseAlbumArtistListModel.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Banshee.Services.addin.xml">
diff --git a/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs b/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
index 785a43d..c67a14c 100644
--- a/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
+++ b/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
@@ -58,7 +58,7 @@ namespace Banshee.Sources
protected DatabaseTrackListModel track_model;
protected DatabaseAlbumListModel album_model;
- protected DatabaseArtistListModel artist_model;
+ protected DatabaseFilterListModel<DatabaseArtistInfo, ArtistInfo> artist_model;
protected DatabaseQueryFilterModel<string> genre_model;
private RateLimiter reload_limiter;
@@ -142,6 +142,7 @@ namespace Banshee.Sources
yield break;
}
+ DatabaseAlbumArtistListModel albumartist_model = new DatabaseAlbumArtistListModel (src, src.DatabaseTrackModel, ServiceManager.DbConnection, src.UniqueId);
DatabaseArtistListModel artist_model = new DatabaseArtistListModel (src, src.DatabaseTrackModel, ServiceManager.DbConnection, src.UniqueId);
DatabaseAlbumListModel album_model = new DatabaseAlbumListModel (src, src.DatabaseTrackModel, ServiceManager.DbConnection, src.UniqueId);
DatabaseQueryFilterModel<string> genre_model = new DatabaseQueryFilterModel<string> (src, src.DatabaseTrackModel, ServiceManager.DbConnection,
@@ -153,9 +154,10 @@ namespace Banshee.Sources
this.genre_model = genre_model;
}
+ yield return genre_model;
+ yield return albumartist_model;
yield return artist_model;
yield return album_model;
- yield return genre_model;
}
protected virtual void AfterInitialized ()
diff --git a/src/Core/Banshee.Services/Makefile.am b/src/Core/Banshee.Services/Makefile.am
index c361c2f..ff63324 100644
--- a/src/Core/Banshee.Services/Makefile.am
+++ b/src/Core/Banshee.Services/Makefile.am
@@ -6,6 +6,8 @@ SOURCES = \
Banshee.Base/RateLimiter.cs \
Banshee.Collection.Database/Bookmark.cs \
Banshee.Collection.Database/CachedList.cs \
+ Banshee.Collection.Database/DatabaseAlbumArtistInfo.cs \
+ Banshee.Collection.Database/DatabaseAlbumArtistListModel.cs \
Banshee.Collection.Database/DatabaseAlbumInfo.cs \
Banshee.Collection.Database/DatabaseAlbumListModel.cs \
Banshee.Collection.Database/DatabaseArtistInfo.cs \
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
index 366cbe1..6e1fa85 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
@@ -46,37 +46,164 @@ using Banshee.Configuration;
using Banshee.Gui;
using Banshee.Collection.Gui;
+using ScrolledWindow=Gtk.ScrolledWindow;
+
namespace Banshee.Sources.Gui
{
public class CompositeTrackSourceContents : FilteredListSourceContents, ITrackModelSourceContents
{
- // private QueryFilterView<string> genre_view;
+ private QueryFilterView<string> genre_view;
private ArtistListView artist_view;
+ private ArtistListView albumartist_view;
private AlbumListView album_view;
private TrackListView track_view;
+ private InterfaceActionService action_service;
+ private ActionGroup configure_browser_actions;
+
+ private static string menu_xml = @"
+ <ui>
+ <menubar name=""MainMenu"">
+ <menu name=""ViewMenu"" action=""ViewMenuAction"">
+ <placeholder name=""BrowserViews"">
+ <menu name=""BrowserListsMenu"" action=""BrowserListsMenuAction"">
+ <menuitem name=""Artist"" action=""ArtistAction"" />
+ <menuitem name=""AlbumArtist"" action=""AlbumArtistAction"" />
+ <separator />
+ <menuitem name=""Genre"" action=""GenreAction"" />
+ </menu>
+ <separator />
+ </placeholder>
+ </menu>
+ </menubar>
+ </ui>
+ ";
+
public CompositeTrackSourceContents () : base ("albumartist")
{
+ if (ServiceManager.Contains ("InterfaceActionService")) {
+ action_service = ServiceManager.Get<InterfaceActionService> ();
+
+ if (action_service.FindActionGroup ("BrowserConfiguration") == null) {
+ configure_browser_actions = new ActionGroup ("BrowserConfiguration");
+
+ configure_browser_actions.Add (new ActionEntry [] {
+ new ActionEntry ("BrowserListsMenuAction", null,
+ Catalog.GetString ("Configure Browser"), null,
+ Catalog.GetString ("Configure the filters available in the browser"), null)
+ });
+
+ configure_browser_actions.Add (new RadioActionEntry [] {
+ new RadioActionEntry ("ArtistAction", null,
+ Catalog.GetString ("Use all available artists"), null,
+ Catalog.GetString ("Use all available artists in the browser filter list"), 0),
+
+ new RadioActionEntry ("AlbumArtistAction", null,
+ Catalog.GetString ("Use album artists only"), null,
+ Catalog.GetString ("Use only album artists, not the ones with only single tracks"), 1),
+ }, ArtistListViewType.Get ().Equals ("artist") ? 0 : 1 , null);
+
+ configure_browser_actions.Add (new ToggleActionEntry [] {
+ new ToggleActionEntry ("GenreAction", null,
+ Catalog.GetString ("Show Genre filter"), null,
+ Catalog.GetString ("Show a list of genres to filter by"), null, GenreListShown.Get ())});
+
+ action_service.AddActionGroup (configure_browser_actions);
+ action_service.UIManager.AddUiFromString (menu_xml);
+ }
+
+ (action_service.FindAction("BrowserConfiguration.ArtistAction") as RadioAction).Changed += OnArtistFilterChanged;
+ //(action_service.FindAction("BrowserConfiguration.AlbumArtistAction") as RadioAction).Changed += OnArtistFilterChanged;
+ action_service.FindAction("BrowserConfiguration.GenreAction").Activated += OnGenreFilterChanged;;
+ }
+ }
+
+ private void OnGenreFilterChanged (object o, EventArgs args)
+ {
+ ToggleAction action = (ToggleAction)o;
+
+ ClearFilterSelections ();
+
+ GenreListShown.Set (action.Active);
+
+ Widget genre_view_widget = (Widget)genre_view;
+ genre_view_widget.Parent.Visible = GenreListShown.Get ();
+ }
+
+ private void OnArtistFilterChanged (object o, ChangedArgs args)
+ {
+ Widget new_artist_view = args.Current.Value == 0 ? artist_view : albumartist_view;
+ Widget old_artist_view = args.Current.Value == 1 ? artist_view : albumartist_view;
+
+ List<ScrolledWindow> new_filter_list = new List<ScrolledWindow> ();
+ List<ScrolledWindow> old_filter_list = new List<ScrolledWindow> (filter_scrolled_windows);
+ foreach (ScrolledWindow fw in old_filter_list)
+ {
+ bool contains = false;
+ foreach (Widget child in fw.AllChildren)
+ if (child == old_artist_view)
+ contains = true;
+ if (contains)
+ {
+ Widget view_widget = (Widget)new_artist_view;
+ if (view_widget.Parent == null)
+ SetupFilterView (new_artist_view as ArtistListView);
+
+ ScrolledWindow win = (ScrolledWindow)view_widget.Parent;
+
+ new_filter_list.Add (win);
+ } else
+ new_filter_list.Add (fw);
+ }
+
+ filter_scrolled_windows = new_filter_list;
+
+ ClearFilterSelections ();
+
+ if (BrowserPosition.Get ().Equals ("left")) {
+ LayoutLeft ();
+ } else {
+ LayoutTop ();
+ }
+
+ ArtistListViewType.Set (args.Current.Value == 1 ? "albumartist" : "artist");
}
protected override void InitializeViews ()
{
SetupMainView (track_view = new TrackListView ());
- // SetupFilterView (genre_view = new QueryFilterView<string> (Catalog.GetString ("Not Set")));
- SetupFilterView (artist_view = new ArtistListView ());
+
+ SetupFilterView (genre_view = new QueryFilterView<string> (Catalog.GetString ("Not Set")));
+ Widget genre_view_widget = (Widget)genre_view;
+ genre_view_widget.Parent.Shown += delegate {
+ genre_view_widget.Parent.Visible = GenreListShown.Get ();
+ };
+
+ if (ArtistListViewType.Get ().Equals ("artist")) {
+ SetupFilterView (artist_view = new ArtistListView ());
+ albumartist_view = new ArtistListView ();
+ } else {
+ SetupFilterView (albumartist_view = new ArtistListView ());
+ artist_view = new ArtistListView ();
+ }
+
SetupFilterView (album_view = new AlbumListView ());
}
protected override void ClearFilterSelections ()
{
- // if (genre_view.Model != null) {
- // genre_view.Selection.Clear ();
- // }
+ if (genre_view.Model != null) {
+ genre_view.Selection.Clear ();
+ }
if (artist_view.Model != null) {
artist_view.Selection.Clear ();
}
+ if (albumartist_view.Model != null) {
+ albumartist_view.Selection.Clear ();
+ }
+
if (album_view.Model != null) {
album_view.Selection.Clear ();
}
@@ -87,7 +214,7 @@ namespace Banshee.Sources.Gui
SetModel (track);
SetModel (artist);
SetModel (album);
- // SetModel (genre);
+ SetModel (genre);
}
IListView<TrackInfo> ITrackModelSourceContents.TrackView {
@@ -128,12 +255,14 @@ namespace Banshee.Sources.Gui
if (filterable_source != null && filterable_source.CurrentFilters != null) {
foreach (IListModel model in filterable_source.CurrentFilters) {
- if (model is IListModel<ArtistInfo>)
+ if (model is IListModel<ArtistInfo> && model is DatabaseArtistListModel)
SetModel (artist_view, (model as IListModel<ArtistInfo>));
+ else if (model is IListModel<ArtistInfo> && model is DatabaseAlbumArtistListModel)
+ SetModel (albumartist_view, (model as IListModel<ArtistInfo>));
else if (model is IListModel<AlbumInfo>)
SetModel (album_view, (model as IListModel<AlbumInfo>));
- // else if (model is IListModel<QueryFilterInfo<string>>)
- // SetModel (genre_view, (model as IListModel<QueryFilterInfo<string>>));
+ else if (model is IListModel<QueryFilterInfo<string>>)
+ SetModel (genre_view, (model as IListModel<QueryFilterInfo<string>>));
// else
// Hyena.Log.DebugFormat ("CompositeTrackSourceContents got non-album/artist filter model: {0}", model);
}
@@ -148,12 +277,26 @@ namespace Banshee.Sources.Gui
source = null;
SetModel (track_view, null);
SetModel (artist_view, null);
+ SetModel (albumartist_view, null);
SetModel (album_view, null);
- // SetModel (genre_view, null);
+ SetModel (genre_view, null);
track_view.HeaderVisible = false;
}
#endregion
+ public static readonly SchemaEntry<string> ArtistListViewType = new SchemaEntry<string> (
+ "artist_list_view", "type",
+ "artist",
+ "Artist/AlbumArtist List View Type",
+ "The type of the Artist/AlbumArtist list view; either 'artist' or 'albumartist'"
+ );
+
+ public static readonly SchemaEntry<bool> GenreListShown = new SchemaEntry<bool> (
+ "genre_list_view", "shown",
+ false,
+ "GenreListView Shown",
+ "Define if the GenreList filter view is shown or not"
+ );
}
}
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/FilteredListSourceContents.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/FilteredListSourceContents.cs
index 640b871..00523fa 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/FilteredListSourceContents.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/FilteredListSourceContents.cs
@@ -58,7 +58,7 @@ namespace Banshee.Sources.Gui
private Gtk.ScrolledWindow main_scrolled_window;
private List<object> filter_views = new List<object> ();
- private List<ScrolledWindow> filter_scrolled_windows = new List<ScrolledWindow> ();
+ protected List<ScrolledWindow> filter_scrolled_windows = new List<ScrolledWindow> ();
private Dictionary<object, double> model_positions = new Dictionary<object, double> ();
@@ -196,12 +196,12 @@ namespace Banshee.Sources.Gui
}
}
- private void LayoutLeft ()
+ protected void LayoutLeft ()
{
Layout (false);
}
- private void LayoutTop ()
+ protected void LayoutTop ()
{
Layout (true);
}
@@ -325,7 +325,7 @@ namespace Banshee.Sources.Gui
protected void SetModel<T> (ListView<T> view, IListModel<T> model)
{
if (view.Model != null) {
- model_positions[view.Model] = view.Vadjustment.Value;
+ model_positions[view.Model] = view.Vadjustment != null ? view.Vadjustment.Value : 0;
}
if (model == null) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]