[banshee: 57/61] [InternetArchive] Add HomeSource, reorganize



commit 85401907d9ef59590efd93900a2a5a4a1b00e6bd
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Mon Oct 19 16:35:35 2009 -0700

    [InternetArchive] Add HomeSource, reorganize
    
    The HomeSource is the main Internet Archive source now.  It has a big
    search bar, intro text explaining what IA is, useful example searches,
    and buttons to search some popular collections (concerts, etc).
    
    The search results source appears beneath it when a search is initiated.

 .../Banshee.InternetArchive.addin.xml              |    2 +-
 .../Banshee.InternetArchive/Actions.cs             |    6 +-
 .../Banshee.InternetArchive/DetailsSource.cs       |    7 +-
 .../Banshee.InternetArchive/DetailsView.cs         |   66 +++--
 .../Banshee.InternetArchive/HeaderFilters.cs       |   59 ++--
 .../Banshee.InternetArchive/HomeSource.cs          |  164 ++++++++++
 .../Banshee.InternetArchive/HomeView.cs            |  345 ++++++++++++++++++++
 .../Banshee.InternetArchive/SearchDescription.cs   |   76 +++++
 .../Banshee.InternetArchive/SearchSource.cs        |  125 +------
 .../InternetArchive/MediaType.cs                   |   26 ++-
 .../InternetArchive/Search.cs                      |    2 +-
 .../InternetArchive/Sort.cs                        |   20 +-
 src/Extensions/Banshee.InternetArchive/Makefile.am |    4 +
 .../Banshee.InternetArchive/Resources/GlobalUI.xml |    6 +
 .../Resources/HomeSourceActiveUI.xml               |    7 +
 .../Hyena.Gui/Hyena.Widgets/ImageButton.cs         |   18 +-
 16 files changed, 750 insertions(+), 183 deletions(-)
---
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive.addin.xml b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive.addin.xml
index c166a31..f7f9118 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive.addin.xml
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive.addin.xml
@@ -17,6 +17,6 @@
   </Dependencies>
 
   <Extension path="/Banshee/SourceManager/Source">
-    <Source class="Banshee.InternetArchive.SearchSource"/>
+    <Source class="Banshee.InternetArchive.HomeSource"/>
   </Extension>
 </Addin>
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
index a866fd5..d2ad85b 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
@@ -39,14 +39,14 @@ namespace Banshee.InternetArchive
 {
     public class Actions : Banshee.Gui.BansheeActionGroup
     {
-        public Actions (SearchSource source) : base ("InternetArchive")
+        public Actions (HomeSource source) : base ("InternetArchive")
         {
             Add (
                 new ActionEntry ("IaResultPopup", null, null, null, null, (o, a) => {
                     ShowContextMenu ("/IaResultPopup");
                 }),
                 new ActionEntry ("ViewItemDetails", null, Catalog.GetString ("View Item Details"), null, null, (o, a) => {
-                    var item = source.FocusedItem;
+                    var item = source.SearchSource.FocusedItem;
                     if (item != null && item.Id != null) {
                         string id = item.Id;
                         var src = new DetailsSource (id, item.Title, item.MediaType);
@@ -60,7 +60,7 @@ namespace Banshee.InternetArchive
                     if (src != null) {
                         uri = src.Item.Details.WebpageUrl;
                     } else {
-                        var item = source.FocusedItem;
+                        var item = source.SearchSource.FocusedItem;
                         if (item != null) {
                             uri = item.WebpageUrl;
                         }
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs
index c225802..db7fd83 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs
@@ -65,7 +65,7 @@ namespace Banshee.InternetArchive
 
         public DetailsSource (string id, string title, string mediaType) : this (Item.LoadOrCreate (id, title, mediaType)) {}
 
-        public DetailsSource (Item item) : base (item.Title, item.Title, 40, "internet-archive-" + item.Id)
+        public DetailsSource (Item item) : base (item.Title, item.Title, 195, "internet-archive-" + item.Id)
         {
             this.item = item;
             track_model = new MemoryTrackListModel ();
@@ -77,7 +77,6 @@ namespace Banshee.InternetArchive
 
             SetIcon ();
 
-
             gui = new DetailsView (this, item);
             Properties.Set<Gtk.Widget> ("Nereid.SourceContents", gui);
 
@@ -146,6 +145,10 @@ namespace Banshee.InternetArchive
         {
         }
 
+        public override string PreferencesPageId {
+            get { return Parent.PreferencesPageId; }
+        }
+
         public override int Count {
             get { return 0; }
         }
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsView.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsView.cs
index 788f626..d5d5941 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsView.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsView.cs
@@ -99,7 +99,7 @@ namespace Banshee.InternetArchive
 
 #endregion
 
-        private Widget CreateSection (string label, Widget child)
+        private Section CreateSection (string label, Widget child)
         {
             var section = new Section (label, child);
             return section;
@@ -111,19 +111,22 @@ namespace Banshee.InternetArchive
             {
                 Spacing = 6;
 
-                var header = new SectionHeader (label, child);
-                PackStart (header, false, false, 0);
+                Header = new SectionHeader (label, child);
+                PackStart (Header, false, false, 0);
                 PackStart (child, false, false, 0);
             }
+
+            public SectionHeader Header { get; private set; }
         }
 
         private class SectionHeader : EventBox
         {
-            HBox box;
             Arrow arrow;
             Label label;
             Widget child;
 
+            public HBox Box { get; private set; }
+
             public SectionHeader (string headerString, Widget child)
             {
                 this.child = child;
@@ -131,14 +134,14 @@ namespace Banshee.InternetArchive
                 AppPaintable = true;
                 CanFocus = true;
 
-                box = new HBox ();
-                box.Spacing = 6;
-                box.BorderWidth = 4;
+                Box = new HBox ();
+                Box.Spacing = 6;
+                Box.BorderWidth = 4;
                 label = new Label ("<b>" + headerString + "</b>") { Xalign = 0f, UseMarkup = true };
                 arrow = new Arrow (ArrowType.Down, ShadowType.None);
 
-                box.PackStart (arrow, false, false, 0);
-                box.PackStart (label, true, true, 0);
+                Box.PackStart (arrow, false, false, 0);
+                Box.PackStart (label, true, true, 0);
 
                 State = StateType.Selected;
 
@@ -151,7 +154,7 @@ namespace Banshee.InternetArchive
                     }
                 };
 
-                Child = box;
+                Child = Box;
 
                 ButtonPressEvent += (o, a) => Toggle ();
                 KeyPressEvent += (o, a) => {
@@ -244,13 +247,8 @@ namespace Banshee.InternetArchive
             var expander = CreateSection (Catalog.GetString ("Details"), table);
 
             // Reviews
-            Widget reviews = null;
+            Section reviews = null;
             if (details.NumReviews > 0) {
-                var reviews_box = new VBox () { Spacing = 12, BorderWidth = 0 };
-                reviews = CreateSection (String.Format (Catalog.GetPluralString (
-                    "Reviews ({0} reviewer)", "Reviews ({0} reviewers)", details.NumReviews), details.NumReviews
-                ), reviews_box);
-
                 string [] stars = {
                     "\u2606\u2606\u2606\u2606\u2606",
                     "\u2605\u2606\u2606\u2606\u2606",
@@ -260,6 +258,18 @@ namespace Banshee.InternetArchive
                     "\u2605\u2605\u2605\u2605\u2605"
                 };
 
+                var reviews_box = new VBox () { Spacing = 12, BorderWidth = 0 };
+                reviews = CreateSection (Catalog.GetString ("Reviews"), reviews_box);
+
+                var avg_label = new Label (String.Format (Catalog.GetPluralString (
+                    // Translators: {0} is the number of reviewers, {1} is the average rating (not really relevant if there's only 1)
+                    "{0} reviewer", "{0} reviewers, avg {1}", details.NumReviews),
+                    details.NumReviews, stars[(int)Math.Round (details.AvgRating)]
+                ));
+                avg_label.TooltipText = String.Format ("{0:N2}", details.AvgRating);
+                avg_label.Xalign = 1.0f;
+                reviews.Header.Box.PackEnd (avg_label, false, false, 0);
+
                 var sb = new System.Text.StringBuilder ();
                 foreach (var review in details.Reviews) {
                     //sb.Append ("<small>");
@@ -314,9 +324,11 @@ namespace Banshee.InternetArchive
 
             sw.Child.ModifyBg (StateType.Normal, Style.Base (StateType.Normal));
             sw.Child.ModifyFg (StateType.Normal, Style.Text (StateType.Normal));
+            sw.Child.ModifyText (StateType.Normal, Style.Text (StateType.Normal));
             StyleSet += delegate {
                 sw.Child.ModifyBg (StateType.Normal, Style.Base (StateType.Normal));
                 sw.Child.ModifyFg (StateType.Normal, Style.Text (StateType.Normal));
+                sw.Child.ModifyText (StateType.Normal, Style.Text (StateType.Normal));
             };
 
             PackStart (frame, true, true, 0);
@@ -422,6 +434,12 @@ namespace Banshee.InternetArchive
                 }
             }
 
+            // Order the formats according to the preferences
+            string format_order = String.Format (", {0}, {1}, {2},", HomeSource.VideoTypes.Get (), HomeSource.AudioTypes.Get (), HomeSource.TextTypes.Get ()).ToLower ();
+
+            var sorted_formats = formats.Select (f => new { Format = f, Order = Math.Max (format_order.IndexOf (", " + f.ToLower () + ","), format_order.IndexOf (f.ToLower ())) })
+                                        .OrderBy (o => o.Order == -1 ? Int32.MaxValue : o.Order);
+
             // Make these columns snugly fix their data
             if (tracks.Count > 0) {
                 SetWidth (columns.TrackColumn,    tracks.Max (f => f.TrackNumber), 0);
@@ -431,22 +449,18 @@ namespace Banshee.InternetArchive
 
             string max_title = "     ";
             if (tracks.Count > 0) {
-                var sorted_by_title = tracks.OrderBy (f => f.TrackTitle == null ? 0 : f.TrackTitle.Length).ToList ();
-                string nine_tenths = sorted_by_title[(int)Math.Floor (.90 * sorted_by_title.Count)].TrackTitle ?? "";
-                string max = sorted_by_title[sorted_by_title.Count - 1].TrackTitle ?? "";
-                max_title = ((double)max.Length >= (double)(2.0 * (double)nine_tenths.Length)) ? nine_tenths : max;
+                var sorted_by_title = files.Where (t => !t.Location.Contains ("zip"))
+                                           .OrderBy (f => f.Title == null ? 0 : f.Title.Length)
+                                           .ToList ();
+                string nine_tenths = sorted_by_title[(int)Math.Floor (.90 * sorted_by_title.Count)].Title ?? "";
+                string max = sorted_by_title[sorted_by_title.Count - 1].Title ?? "";
+                max_title = ((double)max.Length >= (double)(1.6 * (double)nine_tenths.Length)) ? nine_tenths : max;
             }
             (columns.TitleColumn.GetCell (0) as ColumnCellText).SetMinMaxStrings (max_title);
 
             file_list.ColumnController = file_columns;
             file_list.SetModel (files_model);
 
-            // Order the formats according to the preferences
-            string format_order = String.Format (", {0}, {1}, {2},", SearchSource.VideoTypes.Get (), SearchSource.AudioTypes.Get (), SearchSource.TextTypes.Get ()).ToLower ();
-
-            var sorted_formats = formats.Select (f => new { Format = f, Order = Math.Max (format_order.IndexOf (", " + f.ToLower () + ","), format_order.IndexOf (f.ToLower ())) })
-                                        .OrderBy (o => o.Order == -1 ? Int32.MaxValue : o.Order);
-
             var format_list = ComboBox.NewText ();
             format_list.RowSeparatorFunc = (model, iter) => {
                 return (string)model.GetValue (iter, 0) == "---";
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HeaderFilters.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HeaderFilters.cs
index a7b7bc8..c52e4e9 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HeaderFilters.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HeaderFilters.cs
@@ -46,6 +46,9 @@ namespace Banshee.InternetArchive
         private Banshee.Widgets.SearchEntry search_entry;
         private Button search_button;
 
+        private Dictionary<IA.FieldValue, TreeIter> mediatypes;
+        private TreeIter all_iter;
+
         public Widget SearchEntry {
             get { return search_entry; }
         }
@@ -53,6 +56,15 @@ namespace Banshee.InternetArchive
         public HeaderFilters (SearchSource source)
         {
             this.source = source;
+            source.Updated += (o, a) => {
+                var s = source.SearchDescription;
+                if (s != null) {
+                    var iter = s.MediaType == null ? all_iter : mediatypes[s.MediaType];
+                    media_type_combo.SetActiveIter (iter);
+                    sort_combo.Active = Math.Max (Array.IndexOf (sorts, s.Sort), 0);
+                    search_entry.Query = s.Query ?? "";
+                }
+            };
 
             Spacing = 6;
 
@@ -60,8 +72,6 @@ namespace Banshee.InternetArchive
             BuildSortCombo ();
             BuildSearchEntry ();
             BuildSearchButton ();
-
-            UpdateSearch ();
         }
 
         private void BuildMediaTypeCombo ()
@@ -70,15 +80,18 @@ namespace Banshee.InternetArchive
             var combo = media_type_combo = new ComboBox ();
             combo.Model = store;
 
-            store.AppendValues (null, Catalog.GetString ("All"));
+            all_iter = store.AppendValues (null, Catalog.GetString ("All"));
 
+            mediatypes = new Dictionary<IA.FieldValue, TreeIter> ();
             foreach (var mediatype in IA.MediaType.Options.OrderBy (t => t.Name)) {
                 if (mediatype.Id != "software") {
                     var iter = store.AppendValues (mediatype, mediatype.Name);
+                    mediatypes.Add (mediatype, iter);
 
                     if (mediatype.Children != null) {
                         foreach (var child in mediatype.Children.OrderBy (t => t.Name)) {
                             var child_iter = store.AppendValues (iter, child, child.Name);
+                            mediatypes.Add (child, child_iter);
 
                             // FIXME should remember the last selected one in a schema or per-source in the db
                             if (child.Id == "etree")
@@ -141,11 +154,9 @@ namespace Banshee.InternetArchive
         {
             var combo = sort_combo = ComboBox.NewText ();
 
-            combo.AppendText (Catalog.GetString ("Downloads"));
-            combo.AppendText (Catalog.GetString ("Downloads This Week"));
-            combo.AppendText (Catalog.GetString ("Rating"));
-            combo.AppendText (Catalog.GetString ("Year Created"));
-            combo.AppendText (Catalog.GetString ("Date Added"));
+            foreach (var sort in sorts) {
+                combo.AppendText (sort.Name);
+            }
             combo.Active = 0;
 
             PackStart (new Label (Catalog.GetString ("Sort by:")), false, false, 0);
@@ -155,39 +166,23 @@ namespace Banshee.InternetArchive
         private void BuildSearchButton ()
         {
             var button = search_button = new Hyena.Widgets.ImageButton (Catalog.GetString ("_Search"), Stock.Find);
-            button.Clicked += (o, a) => {
-                UpdateSearch ();
-                source.Reload ();
-            };
+            button.Clicked += (o, a) => UpdateSearch ();
 
             PackStart (button, false, false, 0);
         }
 
+        private static IA.Sort [] sorts = { IA.Sort.DownloadsDesc, IA.Sort.WeekDesc, IA.Sort.DateCreatedDesc, IA.Sort.DateCreatedAsc, IA.Sort.DateAddedDesc, IA.Sort.AvgRatingDesc };
+
         private void UpdateSearch ()
         {
-            source.Search.Sorts.Clear ();
-
-            string [] sorts = { "downloads desc", "week desc", "avg_rating desc", "year asc", "addeddate desc" };
-            source.Search.Sorts.Add (new IA.Sort () { Id = sorts[sort_combo.Active] });
-
-            // And if the above sort value is the same for two items, sort by creator then by title
-            source.Search.Sorts.Add (new IA.Sort () { Id = "creatorSorter asc" });
-            source.Search.Sorts.Add (new IA.Sort () { Id = "titleSorter asc" });
-
+            IA.FieldValue media_type = null;
             TreeIter iter;
             if (media_type_combo.GetActiveIter (out iter)) {
-                var media_type = media_type_store.GetValue (iter, 0) as IA.FieldValue;
-                string query = media_type != null ? media_type.ToString () + " AND " : "";
-
-                // Remove medialess 'collection' results
-                query += "-mediatype:collection";
-
-                if (!String.IsNullOrEmpty (search_entry.Query)) {
-                    query += String.Format (" AND {0}", search_entry.Query);
-                }
-
-                source.Search.Query = query;
+                media_type = media_type_store.GetValue (iter, 0) as IA.FieldValue;
             }
+
+            var settings = new SearchDescription (null, search_entry.Query, sorts[sort_combo.Active], media_type);
+            source.SetSearch (settings);
         }
     }
 }
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HomeSource.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HomeSource.cs
new file mode 100644
index 0000000..501418e
--- /dev/null
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HomeSource.cs
@@ -0,0 +1,164 @@
+//
+// HomeSource.cs
+//
+// Authors:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 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 System.Collections.Generic;
+using System.Linq;
+
+using Mono.Unix;
+
+using Hyena.Collections;
+using Hyena.Data;
+
+using Banshee.Base;
+using Banshee.Collection;
+using Banshee.Collection.Database;
+using Banshee.Configuration;
+using Banshee.Database;
+using Banshee.Gui;
+using Banshee.Library;
+using Banshee.MediaEngine;
+using Banshee.PlaybackController;
+using Banshee.Playlist;
+using Banshee.Preferences;
+using Banshee.ServiceStack;
+using Banshee.Sources;
+
+using IA=InternetArchive;
+
+namespace Banshee.InternetArchive
+{
+    public class HomeSource : Banshee.Sources.Source, IDisposable
+    {
+        private static string name = Catalog.GetString ("Internet Archive");
+        private SearchSource search_source;
+        private Actions actions;
+
+        public SearchSource SearchSource {
+            get { return search_source; }
+        }
+
+        public HomeSource () : base (name, name, 190, "internet-archive")
+        {
+            InstallPreferences ();
+
+            //Properties.SetStringList ("Icon.Name", "video-x-generic", "video", "source-library");
+            Properties.SetString ("ActiveSourceUIResource", "HomeSourceActiveUI.xml");
+            Properties.SetString ("GtkActionPath", "/IaHomeSourcePopup");
+            Properties.Set<Gtk.Widget> ("Nereid.SourceContents", new HomeView (this));
+
+            actions = new Actions (this);
+
+            foreach (var item in Item.LoadAll ()) {
+                AddChildSource (new DetailsSource (item));
+            }
+        }
+
+        public void SetSearch (SearchDescription search)
+        {
+            if (search_source == null) {
+                search_source = new SearchSource ();
+                AddChildSource (search_source);
+            }
+
+            SearchSource.SetSearch (search);
+        }
+
+        public override int Count {
+            get { return 0; }
+        }
+
+        public void Dispose ()
+        {
+            UninstallPreferences ();
+
+            if (actions != null) {
+                actions.Dispose ();
+            }
+        }
+
+#region Preferences
+
+        private SourcePage pref_page;
+        private Section pref_section;
+
+        private void InstallPreferences ()
+        {
+            PreferenceService service = ServiceManager.Get<PreferenceService> ();
+            if (service == null) {
+                return;
+            }
+
+            pref_page = new Banshee.Preferences.SourcePage (this);
+
+            pref_section = pref_page.Add (new Section ("mediatypes", Catalog.GetString ("Preferred Media Types"), 20));
+
+            pref_section.Add (new SchemaPreference<string> (AudioTypes,
+                Catalog.GetString ("_Audio"), Catalog.GetString ("")));
+
+            pref_section.Add (new SchemaPreference<string> (VideoTypes,
+                Catalog.GetString ("_Video"), Catalog.GetString ("")));
+
+            pref_section.Add (new SchemaPreference<string> (TextTypes,
+                Catalog.GetString ("_Text"), Catalog.GetString ("")));
+        }
+
+        private void UninstallPreferences ()
+        {
+            PreferenceService service = ServiceManager.Get<PreferenceService> ();
+            if (service == null || pref_page == null) {
+                return;
+            }
+
+            pref_page.Dispose ();
+            pref_page = null;
+            pref_section = null;
+        }
+
+        public override string PreferencesPageId {
+            get { return pref_page.Id; }
+        }
+
+        public static readonly SchemaEntry<string> AudioTypes = new SchemaEntry<string> (
+            "plugins.internetarchive", "audio_types",
+            "Audio, VBR Mp3, Ogg Vorbis, 128Kbps MP3,  64Kbps MP3, Flac, VBR ZIP, 64Kbps MP3 ZIP",
+            "Ordered list of preferred mediatypes for audio items", null);
+
+        public static readonly SchemaEntry<string> VideoTypes = new SchemaEntry<string> (
+            "plugins.internetarchive", "video_types",
+            "Ogg Video, 512Kb MPEG4, MPEG2, h.264 MPEG4, DivX, Quicktime, MPEG1",
+            "Ordered list of preferred mediatypes for video items", null);
+
+        public static readonly SchemaEntry<string> TextTypes = new SchemaEntry<string> (
+            "plugins.internetarchive", "text_types",
+            "Text PDF, Standard LuraTech PDF, Grayscale LuraTech PDF, ZIP, Text, Hypertext",
+            "Ordered list of preferred mediatypes for text items", null);
+
+#endregion
+    }
+}
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HomeView.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HomeView.cs
new file mode 100644
index 0000000..f83de29
--- /dev/null
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/HomeView.cs
@@ -0,0 +1,345 @@
+//
+// HomeView.cs
+//
+// Authors:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 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 System.Collections.Generic;
+using System.Linq;
+
+using Mono.Unix;
+using Gtk;
+
+using Hyena.Collections;
+using Hyena.Data.Sqlite;
+
+using Hyena.Data;
+using Hyena.Data.Gui;
+using Hyena.Widgets;
+
+using Banshee.Base;
+using Banshee.Collection;
+using Banshee.Collection.Gui;
+using Banshee.Collection.Database;
+using Banshee.Configuration;
+using Banshee.Database;
+using Banshee.Gui;
+using Banshee.Library;
+using Banshee.MediaEngine;
+using Banshee.PlaybackController;
+using Banshee.Playlist;
+using Banshee.Preferences;
+using Banshee.ServiceStack;
+using Banshee.Sources;
+using Banshee.Widgets;
+
+using IA=InternetArchive;
+
+namespace Banshee.InternetArchive
+{
+    public class HomeView : Gtk.HBox, Banshee.Sources.Gui.ISourceContents
+    {
+        private HomeSource source;
+
+        public HomeView (HomeSource source)
+        {
+            this.source = source;
+
+            //var sw = new Gtk.ScrolledWindow ();
+            //sw.BorderWidth = 4;
+            //sw.AddWithViewport (Build ());
+
+            var frame = new Hyena.Widgets.RoundedFrame ();
+            frame.Child = Build ();
+
+            PackStart (frame, true, true, 0);
+            ShowAll ();
+        }
+
+        private Widget Build ()
+        {
+            var hbox = new HBox () { Spacing = 8, BorderWidth = 4 };
+
+            hbox.PackStart (BuildTiles (), false, false, 0);
+            hbox.PackStart (BuildCenter (), true, true, 0);
+
+            return hbox;
+        }
+
+        private Widget BuildCenter ()
+        {
+            var vbox = new VBox () { Spacing = 2 };
+
+            // Search entry/button
+            var search_box = new HBox () { Spacing = 6, BorderWidth = 4 };
+            var entry = new Banshee.Widgets.SearchEntry () {
+                Visible = true,
+                EmptyMessage = String.Format (Catalog.GetString ("Search..."))
+            };
+
+            // Make the search entry text nice and big
+            var font = entry.InnerEntry.Style.FontDescription;
+            font.Size = (int) (font.Size * Pango.Scale.XLarge);
+            entry.InnerEntry.ModifyFont (font);
+
+            var button = new Hyena.Widgets.ImageButton (Catalog.GetString ("_Go"), Stock.Find);
+            entry.Activated += (o, a) => { button.Activate (); };
+            button.Clicked += (o, a) => source.SetSearch (new SearchDescription (null, entry.Query, IA.Sort.DownloadsDesc, null));
+
+            search_box.PackStart (entry, true, true, 0);
+            search_box.PackStart (button, false, false, 0);
+
+            // Example searches
+            var example_searches = new SearchDescription [] {
+                new SearchDescription (Catalog.GetString ("Staff Picks"), "pick:1", IA.Sort.WeekDesc, null),
+                new SearchDescription (Catalog.GetString ("Creative Commons"), "license:creativecommons", IA.Sort.DownloadsDesc, null),
+                new SearchDescription (Catalog.GetString ("History"), "subject:history", IA.Sort.DownloadsDesc, null),
+                new SearchDescription (Catalog.GetString ("Classic Cartoons"), "", IA.Sort.DateCreatedAsc, IA.MediaType.Get ("animationandcartoons")),
+                new SearchDescription (Catalog.GetString ("Creator is United States"), "creator:\"United States\"", IA.Sort.DownloadsDesc, null),
+                new SearchDescription (Catalog.GetString ("Oldest Movies"), "", IA.Sort.DateCreatedAsc, IA.MediaType.Get ("moviesandfilms")),
+                new SearchDescription (Catalog.GetString ("New From LibriVox"), "publisher:LibriVox", IA.Sort.DateAddedDesc, IA.MediaType.Get ("audio")),
+                new SearchDescription (Catalog.GetString ("Oldest Texts"), "", IA.Sort.DateCreatedAsc, IA.MediaType.Get ("texts")),
+                new SearchDescription (Catalog.GetString ("Charlie Chaplin"), "\"Charlie Chaplin\"", IA.Sort.DownloadsDesc, null),
+                new SearchDescription (Catalog.GetString ("NASA"), "NASA", IA.Sort.DownloadsDesc, null)
+            };
+
+            var examples = new FlowBox () { Spacing = 0 };
+            examples.Add (PaddingBox (new Label () { Markup = "Examples:" }));
+
+            foreach (var search in example_searches) {
+                var this_search = search;
+                var link = CreateLink (search.Name, search.Query);
+                link.TooltipText = search.Query;
+                link.Clicked += (o, a) => source.SetSearch (this_search);
+                examples.Add (link);
+            }
+
+            // Intro text and visit button
+            var intro_label = new Hyena.Widgets.WrapLabel () {
+                Markup = Catalog.GetString ("The Internet Archive, a 501(c)(3) non-profit, is building a digital library of Internet sites and other cultural artifacts in digital form. Like a paper library, we provide free access to researchers, historians, scholars, and the general public.")
+            };
+
+            var visit_button = new LinkButton ("http://archive.org/";, "Visit the Internet Archive online at archive.org");
+            visit_button.Clicked += (o, a) => Banshee.Web.Browser.Open ("http://archive.org/";);
+            visit_button.Xalign = 0f;
+            var visit_box = new HBox ();
+            visit_box.PackStart (visit_button, false, false, 0);
+            visit_box.PackStart (new Label () { Visible = true }, true, true, 0);
+
+            // Packing
+            vbox.PackStart (search_box, false, false, 0);
+            vbox.PackStart (examples, false, false, 0);
+            vbox.PackStart (PaddingBox (new HSeparator ()), false, false, 6);
+            vbox.PackStart (PaddingBox (intro_label), false, false, 0);
+            vbox.PackStart (visit_box, false, false, 0);
+
+            return vbox;
+        }
+
+        private Widget PaddingBox (Widget child)
+        {
+            var box = new HBox () { BorderWidth = 4 };
+            box.PackStart (child, true, true, 0);
+            child.Show ();
+            box.Show ();
+            return box;
+        }
+
+        public class FlowBox : VBox
+        {
+            private List<HBox> rows = new List<HBox> ();
+            private List<Widget> children = new List<Widget> ();
+
+            private int hspacing;
+            public int HSpacing {
+                get { return hspacing; }
+                set {
+                    hspacing = value;
+                    foreach (var box in rows) {
+                        box.Spacing = hspacing;
+                    }
+                }
+            }
+
+            public FlowBox ()
+            {
+                HSpacing = 2;
+                Spacing = 2;
+
+                bool updating_layout = false;
+                SizeAllocated += (o, a) => {
+                    if (!updating_layout) {
+                        updating_layout = true;
+                        UpdateLayout ();
+                        updating_layout = false;
+                    }
+                };
+            }
+
+            public new void Add (Widget widget)
+            {
+                children.Add (widget);
+                UpdateLayout ();
+            }
+
+            private void UpdateLayout ()
+            {
+                if (Allocation.Width < 2)
+                    return;
+
+                int width = Allocation.Width;
+                int y = 0;
+                int x = 0;
+                int j = 0;
+                foreach (var widget in children) {
+                    x += widget.Allocation.Width + hspacing;
+                    if (x > width) {
+                        y++;
+                        j = 0;
+                        x = widget.Allocation.Width;
+                    }
+
+                    Reparent (widget, GetRow (y), j);
+                    j++;
+                }
+
+                for (int i = y + 1; i < rows.Count; i++) {
+                    var row = GetRow (i);
+                    rows.Remove (row);
+                    Remove (row);
+                }
+            }
+            
+            private void Reparent (Widget widget, HBox box, int index)
+            {
+                if (widget.Parent == box) {
+                    return;
+                }
+
+                if (widget.Parent == null) {
+                    box.PackStart (widget, false, false, 0);
+                } else {
+                    widget.Reparent (box);
+                    box.SetChildPacking (widget, false, false, 0, PackType.Start);
+                }
+
+                box.ReorderChild (widget, index);
+                widget.Show ();
+            }
+
+            private HBox GetRow (int i)
+            {
+                if (i < rows.Count) {
+                    return rows[i];
+                } else {
+                    var box = new HBox () { Spacing = HSpacing };
+                    rows.Add (box);
+                    PackStart (box, false, false, 0);
+                    box.Show ();
+                    return box;
+                }
+            }
+        }
+
+        private Button CreateLink (string title, string url)
+        {
+            var button = new LinkButton (url, "") {
+                Relief = ReliefStyle.None,
+            };
+
+            var label = button.Child as Label;
+            if (label != null) {
+                label.Markup = title;//"<small>" + title + "</small>";
+            }
+            return button;
+        }
+
+        private class Category : SearchDescription
+        {
+            public long Count { get; private set; }
+            public string IconName { get; private set; }
+
+            public Category (string media_type, string name, int count, string icon_name)
+                : base (name, null, IA.Sort.DownloadsDesc, IA.MediaType.Get (media_type))
+            {
+                Count = count;
+                IconName = icon_name;
+            }
+        }
+
+        private Widget BuildTiles ()
+        {
+            var vbox = new VBox () { Spacing = 12, BorderWidth = 4 };
+
+            var categories = new Category [] {
+                new Category ("audio_bookspoetry", Catalog.GetString ("Audiobooks"), 4300, "audio-x-generic"),
+                new Category ("movies", Catalog.GetString ("Movies"), 200000, "video-x-generic"),
+                new Category ("education", Catalog.GetString ("Lectures"), 1290, "x-office-presentation"),
+                new Category ("etree", Catalog.GetString ("Concerts"), 69000, "audio-x-generic"),
+                new Category ("texts", Catalog.GetString ("Books"), 1600000, "x-office-document")
+            };
+
+            foreach (var cat in categories.OrderBy (c => c.Name)) {
+                /*var tile = new Banshee.Widgets.Tile () {
+                    PrimaryText = cat.Name,
+                    SecondaryText = String.Format ("Over {0:N0} items", cat.Count),
+                    Pixbuf = IconThemeUtils.LoadIcon (cat.IconName, 22)
+                };*/
+
+                var this_cat = cat;
+                var tile = new ImageButton (cat.Name, cat.IconName) {
+                    InnerPadding = 4
+                };
+                tile.LabelWidget.Xalign = 0;
+                tile.Clicked += (o, a) => source.SetSearch (this_cat);
+
+                vbox.PackStart (tile, false, false, 0);
+            }
+
+            return vbox;
+        }
+
+#region ISourceContents
+
+        public bool SetSource (ISource source)
+        {
+            this.source = source as HomeSource;
+            return this.source != null;
+        }
+
+        public void ResetSource ()
+        {
+            source = null;
+        }
+
+        public ISource Source { get { return source; } }
+
+        public Widget Widget { get { return this; } }
+
+#endregion
+
+    }
+}
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchDescription.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchDescription.cs
new file mode 100644
index 0000000..de87c49
--- /dev/null
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchDescription.cs
@@ -0,0 +1,76 @@
+//
+// SearchDescription.cs
+//
+// Authors:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 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 System.Collections.Generic;
+using System.Linq;
+
+using Mono.Unix;
+
+using IA=InternetArchive;
+
+namespace Banshee.InternetArchive
+{
+    public class SearchDescription
+    {
+        public string  Name  { get; set; }
+        public string  Query { get; set; }
+        public IA.Sort Sort  { get; set; }
+        public IA.FieldValue MediaType  { get; set; }
+
+        public SearchDescription (string name, string query, IA.Sort sort, IA.FieldValue type)
+        {
+            Name = name;
+            Query = query;
+            Sort = sort;
+            MediaType = type;
+        }
+
+        public void ApplyTo (IA.Search search)
+        {
+            search.Sorts.Clear ();
+
+            search.Sorts.Add (Sort);
+
+            // And if the above sort value is the same for two items, sort by creator then by title
+            search.Sorts.Add (IA.Sort.CreatorAsc);
+            search.Sorts.Add (IA.Sort.TitleAsc);
+
+            string query = MediaType != null ? MediaType.ToString () + " AND " : "";
+
+            // Remove medialess 'collection' results
+            query += "-mediatype:collection";
+
+            if (!String.IsNullOrEmpty (Query)) {
+                query += String.Format (" AND {0}", Query);
+            }
+
+            search.Query = query;
+        }
+    }
+}
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs
index c37ab6c..eefbd38 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs
@@ -45,7 +45,6 @@ using Banshee.Library;
 using Banshee.MediaEngine;
 using Banshee.PlaybackController;
 using Banshee.Playlist;
-using Banshee.Preferences;
 using Banshee.ServiceStack;
 using Banshee.Sources;
 
@@ -53,12 +52,11 @@ using IA=InternetArchive;
 
 namespace Banshee.InternetArchive
 {
-    public class SearchSource : Banshee.Sources.Source, IDisposable
+    public class SearchSource : Banshee.Sources.Source
     {
-        private static string name = Catalog.GetString ("Internet Archive");
+        private static string name = Catalog.GetString ("Search Results");
         private MemoryListModel<IA.SearchResult> model = new MemoryListModel<IA.SearchResult> ();
 
-        private Actions actions;
         private Gtk.Widget header_widget;
         private IA.Search search;
         private string status_text = "";
@@ -67,6 +65,7 @@ namespace Banshee.InternetArchive
         public int TotalResults { get { return total_results; } }
 
         public IA.Search Search { get { return search; } }
+        public SearchDescription SearchDescription { get; private set; }
 
         public IListModel<IA.SearchResult> Model { get { return model; } }
 
@@ -81,22 +80,18 @@ namespace Banshee.InternetArchive
             }
         }
 
-        public SearchSource () : base (name, name, 190, "internet-archive")
+        public SearchSource () : base (name, name, 190, "internet-archive-search")
         {
             IA.Search.UserAgent = Banshee.Web.Browser.UserAgent;
             IA.Search.TimeoutMs = 12*1000;
 
-            InstallPreferences ();
-
             search = new IA.Search () { NumResults = 100 };
 
-            //Properties.SetStringList ("Icon.Name", "video-x-generic", "video", "source-library");
+            Properties.SetStringList ("Icon.Name", "search", "gtk-search");
 
             Properties.SetString ("ActiveSourceUIResource", "SearchSourceActiveUI.xml");
             Properties.SetString ("GtkActionPath", "/IaSearchSourcePopup");
 
-            actions = new Actions (this);
-
             if (header_widget == null) {
                 header_widget = new HeaderFilters (this);
                 header_widget.ShowAll ();
@@ -104,12 +99,15 @@ namespace Banshee.InternetArchive
             }
 
             Properties.Set<Gtk.Widget> ("Nereid.SourceContents", new SearchView (this));
+        }
 
-            foreach (var item in Item.LoadAll ()) {
-                AddChildSource (new DetailsSource (item));
-            }
-
-            ShowIntroText ();
+        public void SetSearch (SearchDescription settings)
+        {
+            SearchDescription = settings;
+            settings.ApplyTo (Search);
+            Reload ();
+            OnUpdated ();
+            ServiceManager.SourceManager.SetActiveSource (this);
         }
 
         public void Reload ()
@@ -203,6 +201,10 @@ namespace Banshee.InternetArchive
             });
         }
 
+        public override string PreferencesPageId {
+            get { return Parent.PreferencesPageId; }
+        }
+
         public override int Count {
             get { return 0; }
         }
@@ -213,98 +215,5 @@ namespace Banshee.InternetArchive
         {
             return status_text;
         }
-
-        /*public override bool AcceptsInputFromSource (Source source)
-        {
-            return false;
-        }*/
-
-        public void Dispose ()
-        {
-            if (actions != null) {
-                actions.Dispose ();
-            }
-
-            UninstallPreferences ();
-        }
-
-        private void ShowIntroText ()
-        {
-            if (show_intro.Get ()) {
-                string intro_txt = Catalog.GetString ("The Internet Archive, a 501(c)(3) non-profit, is building a digital library of Internet sites and other cultural artifacts in digital form. Like a paper library, we provide free access to researchers, historians, scholars, and the general public.");
-
-                SetStatus (intro_txt, true, false, "gtk-info");
-
-                MessageNotify += (o, a) => {
-                    var msg = CurrentMessage;
-                    if (msg != null) {
-                        if (msg.IsHidden && msg.Text == intro_txt) {
-                            show_intro.Set (false);
-                        }
-                    }
-                };
-            }
-        }
-
-        private SchemaEntry<bool> show_intro = new SchemaEntry<bool> ("plugins.internetarchive", "show_intro", true, null, null);
-
-#region Preferences
-
-        private SourcePage pref_page;
-        private Section pref_section;
-
-        private void InstallPreferences ()
-        {
-            PreferenceService service = ServiceManager.Get<PreferenceService> ();
-            if (service == null) {
-                return;
-            }
-
-            pref_page = new Banshee.Preferences.SourcePage (this);
-
-            pref_section = pref_page.Add (new Section ("mediatypes", Catalog.GetString ("Preferred Media Types"), 20));
-
-            pref_section.Add (new SchemaPreference<string> (AudioTypes,
-                Catalog.GetString ("_Audio"), Catalog.GetString ("")));
-
-            pref_section.Add (new SchemaPreference<string> (VideoTypes,
-                Catalog.GetString ("_Video"), Catalog.GetString ("")));
-
-            pref_section.Add (new SchemaPreference<string> (TextTypes,
-                Catalog.GetString ("_Text"), Catalog.GetString ("")));
-        }
-
-        private void UninstallPreferences ()
-        {
-            PreferenceService service = ServiceManager.Get<PreferenceService> ();
-            if (service == null || pref_page == null) {
-                return;
-            }
-
-            pref_page.Dispose ();
-            pref_page = null;
-            pref_section = null;
-        }
-
-        public override string PreferencesPageId {
-            get { return pref_page.Id; }
-        }
-
-        public static readonly SchemaEntry<string> AudioTypes = new SchemaEntry<string> (
-            "plugins.internetarchive", "audio_types",
-            "Audio, VBR Mp3, Ogg Vorbis, 64Kbps MP3, Flac, VBR ZIP, 64Kbps MP3 ZIP",
-            "Ordered list of preferred mediatypes for audio items", null);
-
-        public static readonly SchemaEntry<string> VideoTypes = new SchemaEntry<string> (
-            "plugins.internetarchive", "video_types",
-            "Ogg Video, 512Kb MPEG4, MPEG2, h.264 MPEG4, DivX, Quicktime, MPEG1",
-            "Ordered list of preferred mediatypes for video items", null);
-
-        public static readonly SchemaEntry<string> TextTypes = new SchemaEntry<string> (
-            "plugins.internetarchive", "text_types",
-            "Text PDF, Standard LuraTech PDF, Grayscale LuraTech PDF, ZIP, Text, Hypertext",
-            "Ordered list of preferred mediatypes for text items", null);
-
-#endregion
     }
 }
diff --git a/src/Extensions/Banshee.InternetArchive/InternetArchive/MediaType.cs b/src/Extensions/Banshee.InternetArchive/InternetArchive/MediaType.cs
index f82459c..5b8b58b 100644
--- a/src/Extensions/Banshee.InternetArchive/InternetArchive/MediaType.cs
+++ b/src/Extensions/Banshee.InternetArchive/InternetArchive/MediaType.cs
@@ -33,14 +33,13 @@ namespace InternetArchive
 {
     public class MediaType : FieldValue
     {
-        public MediaType (string id, string name) : base (Field.MediaType, id, name) {}
+        public MediaType (string id, string name) : base (Field.MediaType, id, name)
+        {
+            Children = new List<Collection> ();
+        }
 
         public MediaType AddChildren (params Collection [] children)
         {
-            if (Children == null) {
-                Children = new List<Collection> ();
-            }
-
             foreach (var child in children) {
                 Children.Add (child);
                 child.MediaType = this;
@@ -51,6 +50,23 @@ namespace InternetArchive
 
         public IList<Collection> Children { get; set; }
 
+        public static FieldValue Get (string id)
+        {
+            foreach (var type in Options) {
+                if (type.Id == id) {
+                    return type;
+                }
+
+                foreach (var collection in type.Children) {
+                    if (collection.Id == id) {
+                        return collection;
+                    }
+                }
+            }
+
+            return null;
+        }
+
         public static MediaType [] Options = new MediaType [] {
             new MediaType ("movies", Catalog.GetString ("Moving Images")).AddChildren (
                 new Collection ("animationandcartoons", Catalog.GetString ("Animation & Cartoons")),
diff --git a/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs b/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs
index 6983f5c..587d286 100644
--- a/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs
+++ b/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs
@@ -52,7 +52,7 @@ namespace InternetArchive
         {
             NumResults = 50;
             result_fields.AddRange (Field.Fields);
-            sorts.Add (new Sort () { Id = "avg_rating desc" });
+            sorts.Add (Sort.AvgRatingDesc);
         }
 
         private string GetQuery ()
diff --git a/src/Extensions/Banshee.InternetArchive/InternetArchive/Sort.cs b/src/Extensions/Banshee.InternetArchive/InternetArchive/Sort.cs
index 7a10db8..a2c1313 100644
--- a/src/Extensions/Banshee.InternetArchive/InternetArchive/Sort.cs
+++ b/src/Extensions/Banshee.InternetArchive/InternetArchive/Sort.cs
@@ -26,6 +26,8 @@
 
 using System;
 
+using Mono.Unix;
+
 namespace InternetArchive
 {
     /*
@@ -86,10 +88,24 @@ namespace InternetArchive
 
     public class Sort
     {
-        public Sort ()
+        public static Sort DownloadsDesc  = new Sort ("downloads desc",  Catalog.GetString ("Downloads"));
+        public static Sort WeekDesc       = new Sort ("week desc",       Catalog.GetString ("Downloads This Week"));
+        public static Sort DateCreatedDesc= new Sort ("createdate desc", Catalog.GetString ("Newest"));
+        public static Sort DateCreatedAsc = new Sort ("createdate asc",  Catalog.GetString ("Oldest"));
+        public static Sort DateAddedDesc  = new Sort ("addeddate desc",  Catalog.GetString ("Recently Added"));
+        public static Sort AvgRatingDesc  = new Sort ("avg_rating desc", Catalog.GetString ("Rating"));
+        public static Sort TitleAsc       = new Sort ("titleSorter asc", Catalog.GetString ("Title"));
+        public static Sort CreatorAsc     = new Sort ("creatorSorter asc", Catalog.GetString ("Creator"));
+
+        public Sort () {}
+
+        public Sort (string id, string name)
         {
+            Id = id;
+            Name = name;
         }
 
-        public string Id { get; set; }
+        public string Id { get; private set; }
+        public string Name { get; private set; }
     }
 }
diff --git a/src/Extensions/Banshee.InternetArchive/Makefile.am b/src/Extensions/Banshee.InternetArchive/Makefile.am
index 8ff5b37..2b84939 100644
--- a/src/Extensions/Banshee.InternetArchive/Makefile.am
+++ b/src/Extensions/Banshee.InternetArchive/Makefile.am
@@ -8,7 +8,10 @@ SOURCES = \
 	Banshee.InternetArchive/DetailsSource.cs \
 	Banshee.InternetArchive/DetailsView.cs \
 	Banshee.InternetArchive/HeaderFilters.cs \
+	Banshee.InternetArchive/HomeSource.cs \
+	Banshee.InternetArchive/HomeView.cs \
 	Banshee.InternetArchive/Item.cs \
+	Banshee.InternetArchive/SearchDescription.cs \
 	Banshee.InternetArchive/SearchSource.cs \
 	Banshee.InternetArchive/SearchView.cs \
 	InternetArchive/Collection.cs \
@@ -28,6 +31,7 @@ RESOURCES = \
 	Banshee.InternetArchive.addin.xml \
 	Resources/DetailsSourceActiveUI.xml \
 	Resources/GlobalUI.xml \
+	Resources/HomeSourceActiveUI.xml \
 	Resources/SearchSourceActiveUI.xml
 
 include $(top_srcdir)/build/build.mk
diff --git a/src/Extensions/Banshee.InternetArchive/Resources/GlobalUI.xml b/src/Extensions/Banshee.InternetArchive/Resources/GlobalUI.xml
index ebb21d3..9943d23 100644
--- a/src/Extensions/Banshee.InternetArchive/Resources/GlobalUI.xml
+++ b/src/Extensions/Banshee.InternetArchive/Resources/GlobalUI.xml
@@ -1,4 +1,9 @@
 <ui>
+  <popup action="IaHomeSourcePopup">
+    <menuitem action="VisitInternetArchive" />
+    <menuitem name="SourcePreferences" action="SourcePreferencesAction"/>
+  </popup>
+
   <popup action="IaSearchSourcePopup">
     <menuitem action="VisitInternetArchive" />
     <menuitem name="SourcePreferences" action="SourcePreferencesAction"/>
@@ -7,6 +12,7 @@
   <popup action="IaDetailsSourcePopup">
     <menuitem action="OpenItemWebsite" />
     <menuitem action="VisitInternetArchive" />
+    <menuitem name="SourcePreferences" action="SourcePreferencesAction"/>
     <separator />
     <menuitem action="UnmapSourceAction"/>
   </popup>
diff --git a/src/Extensions/Banshee.InternetArchive/Resources/HomeSourceActiveUI.xml b/src/Extensions/Banshee.InternetArchive/Resources/HomeSourceActiveUI.xml
new file mode 100644
index 0000000..cb99c63
--- /dev/null
+++ b/src/Extensions/Banshee.InternetArchive/Resources/HomeSourceActiveUI.xml
@@ -0,0 +1,7 @@
+<ui>
+  <toolbar name="HeaderToolbar">
+    <placeholder name="SourceActions">
+        <toolitem action="VisitInternetArchive" />
+    </placeholder>
+  </toolbar>
+</ui>
diff --git a/src/Libraries/Hyena.Gui/Hyena.Widgets/ImageButton.cs b/src/Libraries/Hyena.Gui/Hyena.Widgets/ImageButton.cs
index a3db0b0..fa121ac 100644
--- a/src/Libraries/Hyena.Gui/Hyena.Widgets/ImageButton.cs
+++ b/src/Libraries/Hyena.Gui/Hyena.Widgets/ImageButton.cs
@@ -33,20 +33,32 @@ namespace Hyena.Widgets
 {
     public class ImageButton : Button
     {
+        private Image image;
+        private Label label;
+        private HBox hbox;
+
+        public Image ImageWidget { get { return image; } }
+        public Label LabelWidget { get { return label; } }
+
+        public uint InnerPadding {
+            get { return hbox.BorderWidth; }
+            set { hbox.BorderWidth = value; }
+        }
+
         public ImageButton (string text, string iconName) : this (text, iconName, Gtk.IconSize.Button)
         {
         }
         
         public ImageButton (string text, string iconName, Gtk.IconSize iconSize) : base ()
         {
-            Image image = new Image ();
+            image = new Image ();
             image.IconName = iconName;
             image.IconSize = (int) iconSize;
 
-            Label label = new Label ();
+            label = new Label ();
             label.MarkupWithMnemonic = text;
 
-            HBox hbox = new HBox ();
+            hbox = new HBox ();
             hbox.Spacing = 2;
             hbox.PackStart (image, false, false, 0);
             hbox.PackStart (label, true, true, 0);



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