After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 399655 - Jump to song starting with 'foo' (GTK+ type-ahead search)
Jump to song starting with 'foo' (GTK+ type-ahead search)
Status: RESOLVED FIXED
Product: banshee
Classification: Other
Component: User Interface
git master
Other All
: High enhancement
: 1.x
Assigned To: Banshee Maintainers
Banshee Maintainers
papercut
: 507665 536295 537994 551598 553317 557968 588912 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2007-01-23 03:53 UTC by jason fuchs
Modified: 2015-07-09 15:11 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
First iteration (30.80 KB, patch)
2009-11-07 01:23 UTC, Neil Loknath
none Details | Review
2nd iteration (28.40 KB, patch)
2009-11-07 22:53 UTC, Neil Loknath
none Details | Review
3rd iteration (34.93 KB, patch)
2009-11-11 08:48 UTC, Neil Loknath
needs-work Details | Review
4th iteration (39.98 KB, patch)
2009-11-12 20:18 UTC, Neil Loknath
needs-work Details | Review
5th iteration (35.07 KB, patch)
2009-11-13 19:17 UTC, Neil Loknath
needs-work Details | Review
6th (35.61 KB, patch)
2009-11-13 22:20 UTC, Neil Loknath
committed Details | Review

Description jason fuchs 2007-01-23 03:53:38 UTC
Would be handy for long playlists/librarys to jump straight to artist name simply by entering the information, similar to nautilus. if this was implimented the 'fwd' and 'prev' key shortcuts would need to be changed.

Other information:
Search is not convinient for this as it limits whats displayed to a certain value. I'm suggesting a quick 'jump-to' by first letters of the artist name by typing at any time..
Comment 1 Aaron Bockover 2007-02-19 06:30:36 UTC
This is an enhancement.
Comment 2 Josiah Ritchie - flickerfly 2007-02-19 12:51:37 UTC
I'd also suggest that this not start playing when it jumps. That could get really annoying if I fat finger something, who knows where I'd end up.
Comment 3 Gabriel Burt 2008-03-29 08:22:44 UTC
If we implement this at all, I'd suggest making it look like Gtk.TreeView's built-in search box (eg bottom right), and it could only search the column that is sorted (or should it search the default columns, title, album, artist?)
Comment 4 Gabriel Burt 2008-04-06 22:27:38 UTC
*** Bug 507665 has been marked as a duplicate of this bug. ***
Comment 5 Gabriel Burt 2008-04-06 22:28:35 UTC
See bug #507665 for a lot more discussion.
Comment 6 Gabriel Burt 2008-06-02 18:21:34 UTC
*** Bug 536295 has been marked as a duplicate of this bug. ***
Comment 7 Gabriel Burt 2008-07-28 01:28:37 UTC
*** Bug 537994 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Conkling 2008-07-28 02:54:29 UTC
(In reply to comment #1)
> This is an enhancement.

I know Banshee is using a custom widget, but why isn't this a normal/minor bug?
Comment 9 Gabriel Burt 2008-07-28 16:36:11 UTC
Because even with a Gtk.TreeView you'd have to turn on the type-ahead-find and configure it, possibly even writing your own match function.  There's nothing wrong with the current behavior, so it's not a bug.
Comment 10 Michael Martin-Smucker 2008-08-13 22:32:10 UTC
Interestingly enough though, when you click on an item in the left side navigation, like "Now Playing" and start typing, the "find" box pops up but it doesn't actually find anything.  It seems like if it's going to use the "find" box instead of Banshee's custom widget, it might as well actually find something.  ...although I'd much prefer this feature being built into the music library instead of just the left navigation menu.
Comment 11 Andrew Conkling 2008-09-10 12:31:48 UTC
*** Bug 551598 has been marked as a duplicate of this bug. ***
Comment 12 Andrew Conkling 2008-09-23 01:55:14 UTC
*** Bug 553317 has been marked as a duplicate of this bug. ***
Comment 13 Gabriel Burt 2008-10-26 18:30:48 UTC
*** Bug 557968 has been marked as a duplicate of this bug. ***
Comment 14 Sandy Armstrong 2009-01-28 23:57:04 UTC
Does this bug include the idea of using type-ahead find in the artist/album browsers?
Comment 15 Gabriel Burt 2009-01-29 00:05:37 UTC
Yes, since they're the same widget and the idea IMO makes as much sense (or more) for them than is does for tracks.
Comment 16 Brad Jensen 2009-02-14 03:27:04 UTC
I would really like this to work in the artist/album browser windows.  This missing feature has kept me switching back and forth between Banshee and Rhythmbox.  It takes less effort to skip to the artist or album that you may want then it takes to use the search; which hides everything else, then makes you clear the search box to see everything else again.

This kind of "skipping" works in iTunes, Rhythmbox, Songbird and many others..  

I don't know why Banshee shouldn't have it, but I can see why it could be useful in Banshee.
Comment 17 Adam Reeve 2009-03-14 02:02:21 UTC
I was going to report this as an enhancement myself before I found this. This one small feature would make Banshee so much better. It's the one thing that gets really annoying and all other music players I've used follow this behaviour. If I have my artist or library list in focus and I type "n" I want to go to the artists beginning with n, I don't want to play the next song.

Yes this would require changing the shortcuts, but I think that's acceptable as this is the behaviour many new users would expect. Most other applications also require pressing "Ctrl" or "Alt" in combination with shortcut keys.
Comment 18 tvst 2009-04-15 06:49:26 UTC
Agreed. This is the one thing keeping me from using Banshee fulltime.

I'm not a fan of the default shortcuts (which get on the way of type-ahead search) but if they are set in stone, then why not give an option to activate type-ahead search?

As it is, Banshee breaks with the expected Gtk/Gnome behavior and makes everyone I know change my song queue by accident when trying to search :)

What are the main obstacles for this? I know a treeview widget has been created from the ground up, and that this probably requires some extra coding, but are there any technical reasons why this has not been implemented?
Comment 19 Derek Leverenz 2009-05-12 01:08:57 UTC
I agree, this is the one feature that I would like to see more than anything else, and the one major deal-breaker keeping me from using banshee as my main media-player. Almost everything else (Nautilus, all the other media players I have used, windows explorer, etc) has type-ahead functionality, and many people. myself included, have grown used to it and expect it. I consider it a bug, in that it is a feature I took for granted, but it wasn't working (due to the fact that it was missing, of course).

The search function is nice, but not nearly as handy, -- I can't just jump to an artist. If it type the artist name in the box, I don't see anythign OTHER than that artist (or even other songs with the name of that artist that I was not looking for).

I often try to use it without thinking about it, and accidently press one of the shortcuts, which is bothersome.

I would be interested to know if/when this might appear in a future release, and what might be necessary to get it working.

Thanks.
Comment 20 Gabriel Burt 2009-07-17 20:18:07 UTC
*** Bug 588912 has been marked as a duplicate of this bug. ***
Comment 21 Neil Loknath 2009-11-07 01:23:18 UTC
Created attachment 147152 [details] [review]
First iteration

Attached is a partially working patch. My goal was to closely model the behaviour of Rhythmbox.

I chose to implement this as a subclass of ListView called SearchableListView. AlbumInfo, ArtistInfo, and TrackInfo implement a new interface called ISearchable. They all define a new method called Find that takes a target string and returns a bool value to indicate a hit or miss.

Known issues remaining:
* Popup behaviour is close, but not perfect ie. when Application window is moved pop-up should disappear, etc. FocusOut event is not getting raised. I'm guessing because the popup is modal?

* Handling of keyboard shortcuts already in place ie. should ListView popup be brought up with some other key combination to preserve existing shortcuts?

* SearchableListView.PerformSearch method ie. is this sufficient? Zippy with my 2500 track library, but maybe not with larger libraries. It's currently performing a sequential search. A more efficient implementation might restrict searching to the sorted column of the ListView and perform a binary search? Not sure if that is necessary, however.

Feedback, especially on the implementation decisions, would be awesome before doing anything further
Comment 22 Michael Martin-Smucker 2009-11-07 15:58:10 UTC
(In reply to comment #21)
> Created an attachment (id=147152) [details] [review]
> First iteration
> 
> Attached is a partially working patch. My goal was to closely model the
> behaviour of Rhythmbox.

First of all, you are awesome for working on this.  Once I have a little free time, I'm definitely looking forward to testing the patch.

How closely does this model Rhythmbox's behavior?  If I remember correctly, Rhythmbox searches any word in the title.  I prefer searching the Artist column instead, but that's definitely my past iTunes experience speaking.

> * Handling of keyboard shortcuts already in place ie. should ListView popup be
> brought up with some other key combination to preserve existing shortcuts?

I have a feeling that Banshee developers will be in favor of preserving the existing shortcuts, but before they chime in, I'd like to make the case for replacing the existing shortcuts.

The existing shortcuts are hard to discover and not well documented.  Some of these shortcuts (N, B, T, F, R) can be found in the menus.  Others (o, /, y) can be found in the support section of Banshee's website.  I couldn't find the "S" shortcut (focus on the search field) mentioned anywhere.

Many of the existing shortcuts are duplicates of other keyboard shortcuts.  S and / both duplicate Ctrl+F for focusing on the search box (and searching will hopefully be less common once type-ahead is implemented).  F does the same thing as F11, and F11 is more common in other applications.  Restart is basically a duplicate of Previous (Bug 576931), so R essentially duplicates B.  If Bug 535924 is fixed, N and B won't be necessary because Control-Right and Control Left (or some variation) will do the same thing.

Also, type-ahead should be a quick way of navigating a collection.  Requiring an extra keystroke to trigger it defeats (some of) the purpose.  If you need to use an extra key to do the search, you might as well hit the "/" or "s" key and just use the search box.  Users familiar with this kind of searching in Rhythmbox, Nautilus, and Firefox (to name only a few) won't expect an extra key to trigger type-ahead.

The lost keyboard shortcuts could probably add a Ctrl modifier, or maybe choosing between type-ahead and Banshee's current keyboard shortcuts could be a preferences option somewhere.  If it's all-or-nothing, though, I'd really like to throw in my vote for type-ahead replacing shortcuts.
Comment 23 Neil Loknath 2009-11-07 17:56:02 UTC
(In reply to comment #22)
> How closely does this model Rhythmbox's behavior?  If I remember correctly,
> Rhythmbox searches any word in the title.  I prefer searching the Artist column
> instead, but that's definitely my past iTunes experience speaking.
> 

This is one area where my implementation differs. When typing ahead on the track list the track name, artist name, and album name are searched in that order. And, it's currently not searching for any word. That's an oversight on my part. Currently, it takes the type ahead string and looks for a match in one of the above columns that start with it. This can easily be changed.
Comment 24 Neil Loknath 2009-11-07 22:53:40 UTC
Created attachment 147189 [details] [review]
2nd iteration

* Allow up / down key use when jump ahead popup is in use. This lets the user move to the next / previous search result
* Use String.Contains instead of String.StartsWith for matching
Comment 25 Robin Stocker 2009-11-07 23:15:12 UTC
(In reply to comment #24)
> * Use String.Contains instead of String.StartsWith for matching

Just a note: iTunes only compares the typed string with the start, not if it is contained within the text. And if it has no results, it lands at the closest match (type "Mon" and you land on the first "Morcheba", after "Moby").
Comment 26 Michael Martin-Smucker 2009-11-08 00:27:01 UTC
(In reply to comment #24)
> * Use String.Contains instead of String.StartsWith for matching

I actually think that StartsWith is a better choice than Contains for a type-ahead search.  If you're searching for "contains" in 3 different columns in a decently large library, the chances of actually hitting what you're looking for when you start typing seems fairly low.

Of course I have no data to back this up, but I did come up with one lame scenario: I want to listen to a song that's name begins with "in the".  With my library, typing "in the" would have a 1/130 chance of hitting the song I want using the Contains method and a 1/8 chance using StartsWith.

Since speed of navigation is one major advantage of type-ahead, I think enforcing a more strict searching policy (eg "you have to start searching with the beginning of the track/artist/album name") is a fair compromise for returning more relevant results more quickly.  If the user wants a more complete list of matches, there's always standard slow searching for that.

Of course, this is just my 2 cents (for the second time today; I guess we're almost up to a nickel...).  I haven't even tested the patch yet, but I will in just a minute.
Comment 27 Gabriel Burt 2009-11-08 02:44:16 UTC
Thanks for working on this Neil. I'd be much more comfortable if the lookup happened in the Model, not by iterating the list.  That way we can implement a SQL-based lookup for all DatabaseSources, using a combination of the existing query infrastructure (QueryFields + '=' operator) and adding a new IndexOf method that takes the query and an offset # and uses its cache to look it up.
Comment 28 Neil Loknath 2009-11-11 08:48:04 UTC
Created attachment 147451 [details] [review]
3rd iteration

Thanks for the feedback, Gabriel.

I've changed the ISearchable interface so it applies to the model instead. It enforces a DefaultQueryFields property definition, so the SearchableListView knows which fields it can search. And, it also enforces an IndexOf method implementation.

The IndexOf method in the model takes a QueryNode as a parameter. Not sure if maybe that is too strict and a string representing a SQL WHERE fragment would be better?

Comments on what I've done would be great. I think this is a step in the right direction, as searching large libraries should no longer be an issue.
Comment 29 Gabriel Burt 2009-11-11 18:00:12 UTC
Review of attachment 147451 [details] [review]:

Great job Neil, I think this is definitely on the right track.  I think passing the QueryNode in IndexOf makes perfect sense - not all models will be SQL backed, and they can deal w/ the QueryNode tree how they want.

::: src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseAlbumListModel.cs
@@ +48,3 @@
                     source, trackModel, connection, DatabaseAlbumInfo.Provider, new AlbumInfo (null), uuid)
         {
+            DefaultQueryFields = new QueryField[] { Banshee.Query.BansheeQuery.AlbumField };

Hrm, not seeing it in HACKING, but I think we usually put a space before [] in array ctor calls.

::: src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseFilterListModel.cs
@@ +234,3 @@
+                }
+                
+                long index = cache.IndexOf (query.ToSql (null), offset);

I think it's crucial to pass the QueryFieldSet to ToSql - it's used to determine the default fields if there is a QueryTermNode that doesn't specify a field.

In fact, instead of having the DefaultQueryFields property on ISearchable, should probably just have a QueryFieldSet, which is basically the same thing.  Then for the track model, you can just reuse BansheeQuery.FieldSet.

Note that QueryFieldSet class is a list of fields, with some of them marked as Default fields, such that if a QueryTermNode doesn't specify a column, it'll search all of them.

::: src/Core/Banshee.Services/Banshee.Collection.Database/ISearchable.cs
@@ +34,3 @@
+    public interface ISearchable
+    {
+        QueryField[] DefaultQueryFields { get; set; }

Don't need setter in the iface

::: src/Core/Banshee.ThickClient/Banshee.Collection.Gui/SearchableListView.cs
@@ +58,3 @@
+        }
+
+        //TODO building tree on every search is probably unnecessary

To avoid this, can cache the QueryListNode and the last target, and reuse if target is the same.

@@ +150,3 @@
+        // this is exactly what the base class does
+        // perhaps just make change from private to protected there?
+        protected void InvalidateList ()

Making this protected in ListView is fine with me

::: src/Libraries/Hyena.Gui/Hyena.Widgets/EntryPopup.cs
@@ +63,3 @@
+            text_entry.CanFocus = true;
+            
+            text_entry.FocusOutEvent += delegate(object o, FocusOutEventArgs args) {

instead of all these delegates, use += (o, a) =>

::: src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
@@ +242,3 @@
+            }
+            
+            String sql = String.Format (select_str + " {0} LIMIT {1}, 1", where_fragment, offset);

instead of concatenating select_str here, can just add it to the string.format

also, String sql -> string sql (we use keyword names of value types for var declarations)
Comment 30 Neil Loknath 2009-11-12 20:18:07 UTC
Created attachment 147607 [details] [review]
4th iteration

Applied your comments, Gabriel.

Other notable stuff in this patch:
* To build the query tree, SearchableListView will pick out the default fields in the QueryFieldSet it finds in its model. If none of the fields are defaults, it will take all of them.
* DatabaseQueryFilterModel updated to allow searching (ie. the Genre browser for the Radio extension). SqlliteModelCache required some tweaking.
* No longer calling Provider.Load in the new SqlliteModelCache.IndexOf method. It's unnecessary.

I've noticed that the search popup for the SourceView, which is a subclass of TreeView, behaves exactly (from my observations) like my new EntryPopup widget. For example, when the main window is moved, the popup stays open. So, I'm wondering if the EntryPopup behaviour is fine as is. Personally, I would rather the popup disappear when the main window is moved because it looks odd when it's left floating in the same position. I'm having trouble getting that functionality in place, however.
Comment 31 Gabriel Burt 2009-11-12 21:36:17 UTC
Review of attachment 147607 [details] [review]:

Thanks Neil, looking really good.

::: src/Core/Banshee.ThickClient/Banshee.Collection.Gui/SearchableListView.cs
@@ +50,3 @@
+        private long search_offset = 0;
+        
+        public SearchableListView () : base ()

base () is superfluous

@@ +55,3 @@
+
+        private QueryNode last_query = null;
+        public QueryNode LastQuery {

can make this just "public QueryNode LastQuery { get; private set; }

@@ +125,3 @@
+            }
+
+            if (last_query == null) {

To better future-proof this, I think you should store/check last_query_fields too; a single ListView can be used by various models, and in the future the Podcast source might have a different set of fields but use the same ListView.

@@ +128,3 @@
+                last_query = BuildQueryTree (model.QueryFields, StringQueryValue.StartsWith, target);
+            }
+            else {

put this on the same line as the }

I also see quite a few of these below

@@ +209,3 @@
+        {
+            char input = Convert.ToChar (Gdk.Keyval.ToUnicode (press.KeyValue));
+            if (!IsCharValid (input)) {

Should probably check here also whether the model is ISearchable

@@ +226,3 @@
+            search_popup.HasFocus = true;
+            search_popup.Show ();
+            search_popup.Text = String.Format ("{0}{1}", search_popup.Text, Convert.ToChar (press.KeyValue));

Why do you convert to char here when you already have input?

@@ +241,3 @@
+                    break;
+                case Gdk.Key.Down:
+                case Gdk.Key.KP_Down:

Should handle F3 (ala Firefox) and Ctrl+G (ala GNOME HIG) for go-to-next-match, and shift+F3 and shift+ctrl+G for go-to-previous.

@@ +244,3 @@
+                    previous_search_offset = search_offset++;
+                    if (!PerformSearch (search_popup.Text)) {
+                        search_offset = previous_search_offset;

should we wrap around instead of staying at the previous match?

::: src/Core/Banshee.ThickClient/Banshee.Collection.Gui/SearchableTrackFilterListView.cs
@@ +1,2 @@
+//
+// SearchableTrackFilterListView.cs

Why do you have this class and the modifications to TrackFilterListView?

::: src/Libraries/Hyena.Gui/Hyena.Widgets/EntryPopup.cs
@@ +64,3 @@
+            
+            text_entry.FocusOutEvent += (o, a) => {
+                Console.WriteLine ("focus out");

remove WriteLine

@@ +90,3 @@
+        }
+
+//        public EntryPopup (Gtk.Widget widget) : this ()

Remove

@@ +106,3 @@
+//        }
+        
+        public EntryPopup (string text) : this ()

Move this to above the other ctor

::: src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
@@ +142,3 @@
+
+                //TODO this works, but is it reliable? Note JOIN on Value column
+                search_str = String.Format (

Using the select_str as the search_str doesn't work in this case?

Ideally we could just reuse that.  I think we should modify the select_str's to also grab CoreCache.OrderId directly - then we can avoid the IndexOf query and just return OrderId - FirstOrderId.  This will help prevent bugs where a song is in a playlist twice and the type-ahead search has issues jumping to the 2nd entry.
Comment 32 Neil Loknath 2009-11-12 22:33:05 UTC
Sorry about the style issues and debugging code I forgot to remove.

(In reply to comment #31)
> @@ +55,3 @@
> +
> +        private QueryNode last_query = null;
> +        public QueryNode LastQuery {
> 
> can make this just "public QueryNode LastQuery { get; private set; } 
> 

Does that make last_query redundant? I guess I need to understand the reasoning. What if it were changed to:
public QueryNode LastQuery { 
   get { return last_query; } 
}

...and I just used last_query within the class?

> 
> @@ +244,3 @@
> +                    previous_search_offset = search_offset++;
> +                    if (!PerformSearch (search_popup.Text)) {
> +                        search_offset = previous_search_offset;
> 
> should we wrap around instead of staying at the previous match?
> 

Not sure. When the list stops moving, you get visual feedback letting you know that there are no more search results in the direction you're scrolling. If it wrapped, it may not be as obvious. But, I could be wrong. The list normally doesn't wrap when either extreme is reached, so maybe for that reason it shouldn't wrap? Comments, anyone?

> :::
> src/Core/Banshee.ThickClient/Banshee.Collection.Gui/SearchableTrackFilterListView.cs
> @@ +1,2 @@
> +//
> +// SearchableTrackFilterListView.cs
> 
> Why do you have this class and the modifications to TrackFilterListView?
> 

Sorry. I think this was just from me playing around with things, and I later forgot about it. Are you cool with TrackFilterListView subclassing SearchableListView? If so, SearchableTrackFilterListView can be removed.

> 
> ::: src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
> @@ +142,3 @@
> +
> +                //TODO this works, but is it reliable? Note JOIN on Value
> column
> +                search_str = String.Format (
> 
> Using the select_str as the search_str doesn't work in this case?
> 

No, it doesn't work because when Model.CacheValues is true, select_str = "SELECT OrderID, ItemID FROM {0} WHERE {0}.ModelID = {1}". So, the QueryNode for the WHERE fragment is wrong.

> Ideally we could just reuse that.  I think we should modify the select_str's to
> also grab CoreCache.OrderId directly - then we can avoid the IndexOf query and
> just return OrderId - FirstOrderId.  This will help prevent bugs where a song
> is in a playlist twice and the type-ahead search has issues jumping to the 2nd
> entry.

Good idea. I'll work this in.
Comment 33 Gabriel Burt 2009-11-12 23:04:59 UTC
(In reply to comment #32)
> Sorry about the style issues and debugging code I forgot to remove.

No worries.

> Does that make last_query redundant? I guess I need to understand the
> reasoning. What if it were changed to:
> public QueryNode LastQuery { 
>    get { return last_query; } 
> }

Yeah, it would make it redundant.  Your approach is fine too - just a little more verbose.

> Not sure. When the list stops moving, you get visual feedback letting you know
> that there are no more search results in the direction you're scrolling. If it
> wrapped, it may not be as obvious. But, I could be wrong. The list normally
> doesn't wrap when either extreme is reached, so maybe for that reason it
> shouldn't wrap? Comments, anyone?

Well...since it'll be non-trivial to implement wrapping when going in reverse (since we'd have to know how many matches there are) - maybe we can just not wrap for now at least.

> Sorry. I think this was just from me playing around with things, and I later
> forgot about it. Are you cool with TrackFilterListView subclassing
> SearchableListView? If so, SearchableTrackFilterListView can be removed.

Yeah, that's fine.

> No, it doesn't work because when Model.CacheValues is true, select_str =
> "SELECT OrderID, ItemID FROM {0} WHERE {0}.ModelID = {1}". So, the QueryNode
> for the WHERE fragment is wrong.

It's only wrong b/c you're reusing the GenreField, etc, right?  I think you could make a new QueryField just for use within the QueryFilterList, and set it's SQL column name to whatever will work - ItemID right?
Comment 34 Neil Loknath 2009-11-13 19:17:28 UTC
Created attachment 147685 [details] [review]
5th iteration

Applied your comments, Gabriel.

SqlliteModelCache is using the select_str variable again with the OrderID added in. A new QueryField named QueryFilterField has been added to BansheeQuery.

Another oddity I noticed with the EntryPopup is that the cursor is not visible even though the focus is on the Entry widget within it. I don't know why that is.
Comment 35 Gabriel Burt 2009-11-13 19:33:56 UTC
Review of attachment 147685 [details] [review]:

Looking really good.  Just a few more things.

::: src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseQueryFilterModel.cs
@@ +56,3 @@
                     ORDER BY Value";
+
+            QueryFields = new QueryFieldSet (Banshee.Query.BansheeQuery.QueryFilterField);

Let's move QueryFilterField into this class, making it private.  It's kind of a hack - very specific to the Cache stuff, and it's best if other people don't use it without really knowing what they're doing.

::: src/Core/Banshee.ThickClient/Banshee.Collection.Gui/SearchableListView.cs
@@ +254,3 @@
+                    if ((press.State & Gdk.ModifierType.ShiftMask) != 0) {
+                        search_backward = true;
+                        break;

unnecessary break;  also, make the Key.G case like this one, with if/else

@@ +267,3 @@
+            if (search_forward) {
+               previous_search_offset = search_offset++;
+                if (!PerformSearch (search_popup.Text)) {

there is an extra indentation space before this if

::: src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
@@ +243,3 @@
+            
+            string sql = String.Format ("{0} {1} LIMIT {2}, 1", select_str, where_fragment, offset);
+//            Log.DebugFormat ("cache.IndexOf SQL = {0}", sql);

Remove

@@ +246,3 @@
+
+            lock (this) {
+                using (IDataReader reader = connection.Query (new HyenaSqliteCommand (sql))) {

Could cache this HyenaSqliteCommand, and only regenerate it when where_fragment != last_indexof_where_fragment
Comment 36 Neil Loknath 2009-11-13 20:28:31 UTC
(In reply to comment #35)
> ::: src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
> 
> @@ +246,3 @@
> +
> +            lock (this) {
> +                using (IDataReader reader = connection.Query (new
> HyenaSqliteCommand (sql))) {
> 
> Could cache this HyenaSqliteCommand, and only regenerate it when where_fragment
> != last_indexof_where_fragment

While the where_fragment doesn't change when scrolling, the offset does. Therefore, the SQL command as a whole is almost always different for each IndexOf call because of the 'LIMIT offset, 1' parameter of the SQL command. Thus, a HyenaSqliteCommand object would have to be created almost every call, anyway. The only time the caching would kick in is when the user types a single char in the jump ahead, lets it disappear, and then they type the exact same char again. Still worthwhile?
Comment 37 Gabriel Burt 2009-11-13 20:53:17 UTC
IF instead of {2} you put ? for the offset, then you can reuse the same HyenaSqliteCommand, just passing in a new offset value each time: connection.Query (cmd, offset);
Comment 38 Neil Loknath 2009-11-13 22:20:33 UTC
Created attachment 147697 [details] [review]
6th

(In reply to comment #37)
> IF instead of {2} you put ? for the offset, then you can reuse the same
> HyenaSqliteCommand, just passing in a new offset value each time:
> connection.Query (cmd, offset);

Nice. Forgot about that. 

Here's another one for you.
Comment 39 Gabriel Burt 2009-11-14 03:50:26 UTC
Comment on attachment 147697 [details] [review]
6th

I committed the patch to the new typeahead branch so we can iterate on it a bit more from there.  Things left to do from my view:

1. figure out how to open it - maybe change / to open it and keep ctrl-f to focus the search box?  I don't see us changing our single-key keybindings (space, p, f, n, etc) anytime soon.

2. Focus the entry so we get the focus highlighting and cursor

Great job on this, Neil!
Comment 40 Neil Loknath 2009-11-14 22:59:19 UTC
Awesome! and thanks. It was fun. :)

In addition to your list of things to do, there's also this that I mentioned above:

(In reply to comment #30)
> I've noticed that the search popup for the SourceView, which is a subclass of
> TreeView, behaves exactly (from my observations) like my new EntryPopup widget.
> For example, when the main window is moved, the popup stays open. So, I'm
> wondering if the EntryPopup behaviour is fine as is. Personally, I would rather
> the popup disappear when the main window is moved because it looks odd when
> it's left floating in the same position. I'm having trouble getting that
> functionality in place, however.

Looking forward to seeing this merged into master.
Comment 41 Gabriel Burt 2009-11-14 23:07:02 UTC
(In reply to comment #40)
> (In reply to comment #30)
> > the popup disappear when the main window is moved because it looks odd when
> > it's left floating in the same position. I'm having trouble getting that

I would think it would just move with the window.  Let's add that to the todo list.
Comment 42 tvst 2009-11-15 08:07:02 UTC
(In reply to comment #39)
> 
> 1. figure out how to open it - maybe change / to open it and keep ctrl-f to
> focus the search box?  I don't see us changing our single-key keybindings
> (space, p, f, n, etc) anytime soon.
> 

Since the keybindings are now editable, many users change the single-key shortcuts to multi-key ones. For these users it makes sense to initiate the type-ahead action when any key is pressed. Do you think there's any chance this can be a configurable option? (even if only through gconf)
Comment 43 Robin Stocker 2009-11-15 23:03:10 UTC
(In reply to comment #39)
> 1. figure out how to open it - maybe change / to open it and keep ctrl-f to
> focus the search box?  I don't see us changing our single-key keybindings
> (space, p, f, n, etc) anytime soon.

Please keep in mind that for users of non-US/UK keyboards, "/" is not just a single key but may require two key presses (Shift+7 for de_CH). That makes it awkward and it loses the convenience of the usual GNOME type-ahead search.

Also keep in mind that most users use multimedia keys if their keyboard has them, so they wouldn't need space, p, f, n. So +1 for a configuration option I guess.
Comment 44 Gabriel Burt 2009-12-05 22:57:57 UTC
Ok, I made it require '?' (shift-/ on US keyboards) for now, and merged into master.  Please file new bugs with any changes you'd like made.  I filed bug #603878 about the entry not being focused.
Comment 45 Gabriel Burt 2010-03-03 20:53:11 UTC
*** Bug 611739 has been marked as a duplicate of this bug. ***
Comment 46 Michael Chirico 2015-07-08 18:54:49 UTC
Wow, I'm a bit discouraged to see that this seems to be something that everyone wants but hasn't been implemented in over 6 years.

But anyway I'm throwing my hat in the ring of users in favor of this type of navigation, which is common in other players.

As an iTunes veteran, the mapping of shortcuts directly to keyboard keys (as opposed to tied through chooser keys like shift or control) is a major bugbear.

The requirement to enter the search bar to navigate quickly is cumbersome--in the situation where I'm jonesing for a particular track, but would like the shuffle of my full library to ensue, the need to remember to X out of the search selection seems unnecessary.
Comment 47 André Klapper 2015-07-09 15:11:23 UTC
(In reply to Michael Chirico from comment #46)
> Wow, I'm a bit discouraged to see that this seems to be something that
> everyone wants but hasn't been implemented in over 6 years.

This bug report is closed as FIXED. If your "this" is a different "this", feel free to file a new feature request. In general, volunteer manpower is always limited and the best approach to get a bug fixed is to contribute patches.