Add a search thread to the movie list store
authorPhilipp Zabel <philipp.zabel@gmail.com>
Thu, 15 Oct 2009 13:39:07 +0000 (15:39 +0200)
committerPhilipp Zabel <philipp.zabel@gmail.com>
Tue, 3 Nov 2009 12:11:21 +0000 (13:11 +0100)
For now, the first plugin's first source is selected on startup.
There is an arbitrary limit of 100 movies in the result list.

Makefile
src/main.vala
src/movie-list-store.vala
src/movie-list-view.vala
src/movie-list-window.vala

index 4e70e7a..39d2bd6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,8 @@ cinaest_SOURCES = \
        src/plugin-interface.vala \
        src/plugin-registrar.vala
 
-cinaest_VALAFLAGS = --vapidir ./vapi --pkg hildon-1 --pkg libosso --pkg gmodule-2.0
+cinaest_VALAFLAGS = --thread --vapidir ./vapi \
+       --pkg hildon-1 --pkg libosso --pkg gmodule-2.0
 
 cinaest: ${cinaest_SOURCES}
        valac -o $@ ${cinaest_VALAFLAGS} ${cinaest_SOURCES}
index 667e1c1..f243102 100644 (file)
@@ -61,11 +61,18 @@ public class CinaestProgram : Hildon.Program {
 
        public void run () {
                register_plugins ();
+               // FIXME - always start with the first plugin's first source for now
+               if (plugins != null) {
+                       var plugin = plugins.first ().data;
+                       if (plugin != null)
+                               window.store.source = plugin.get_sources ().first ().data;
+               }
                Gtk.main ();
        }
 
        static int main (string[] args) {
                Gtk.init (ref args);
+               Gdk.threads_init ();
 
                var osso_context = new Osso.Context ("org.maemo.cinaest", "0.0.1", true, null);
                if (osso_context == null) {
index fef0ff5..f162306 100644 (file)
@@ -38,10 +38,15 @@ public class MovieListStore : ListStore, TreeModel {
                typeof (Movie)
        };
        private Gdk.Pixbuf no_poster;
+       public MovieSource source;
+       private string query;
+       public bool update_running;
 
        construct {
                set_column_types (base_type);
                no_poster = null;
+               source = null;
+               update_running = false;
        }
 
        public void add (Movie movie, out TreeIter iter) {
@@ -77,6 +82,46 @@ public class MovieListStore : ListStore, TreeModel {
                return false;
        }
 
+       public bool start_search (string _query) {
+               if (update_running)
+                       return false;
+
+               query = _query;
+               try {
+                       Thread.create (search_thread, false);
+                       update_running = true;
+               } catch (ThreadError e) {
+                       warning ("Failed to start search thread: %s", e.message);
+               }
+               return update_running;
+       }
+
+       // Update thread
+       private void* search_thread () {
+               stdout.printf ("search thread started: \"%s\"\n", query);
+
+               Gdk.threads_enter ();
+               clear ();
+               Gdk.threads_leave ();
+
+               if (source != null)
+                       // FIXME - arbitrary limit
+                       source.get_movies (query, receive_movie, 100);
+
+               update_running = false;
+
+               stdout.printf ("search thread stopped\n");
+               return null;
+       }
+
+       private void receive_movie (Movie movie) {
+               TreeIter iter;
+
+               Gdk.threads_enter ();
+               add (movie, out iter);
+               Gdk.threads_leave ();
+       }
+
        // Implement TreeModel interface
        public virtual GLib.Type get_column_type (int index_) {
                return_val_if_fail (index_ >= 0 && index_ < Columns.N_COLUMNS, 0);
index 86406d2..9d3b53e 100644 (file)
@@ -20,7 +20,7 @@ using Gtk;
 using Hildon;
 
 public class MovieListView : PannableArea {
-       MovieListStore store;
+       public MovieListStore store;
        TreeView tree;
        public TreeSortable sorted_store;
 
index cc9a84e..17b3998 100644 (file)
@@ -22,6 +22,9 @@ using Hildon;
 public class MovieListWindow : StackableWindow {
        private Hildon.Entry search_field;
        private Toolbar search_bar;
+       private uint source_id;
+       private MovieListView movie_list;
+       public MovieListStore store;
        private Label no_movies;
 
        construct {
@@ -47,8 +50,9 @@ public class MovieListWindow : StackableWindow {
                add_toolbar (search_bar);
 
                // Movie list - connected to menu for sorting
-               var movie_list = new MovieListView ();
+               movie_list = new MovieListView ();
                menu.sortable = movie_list.sorted_store;
+               store = movie_list.store;
 
                no_movies = new Label ("No movies");
                Hildon.helper_set_logical_font (no_movies, "LargeSystemFont");
@@ -63,6 +67,7 @@ public class MovieListWindow : StackableWindow {
                add (vbox);
 
                // Connect signals
+               search_field.changed.connect (on_search_field_changed);
                close_button.clicked.connect (on_close_button_clicked);
                key_press_event.connect (on_key_press_event);
 
@@ -89,5 +94,30 @@ public class MovieListWindow : StackableWindow {
 
                return false;
        }
+
+       private void on_search_field_changed () {
+               if (search_field.get_text () == "") {
+                       store.clear ();
+                       movie_list.hide ();
+                       no_movies.show ();
+                       return;
+               }
+
+               // With every change we reset the timer to 500ms
+               if (source_id != 0) {
+                       Source.remove (source_id);
+               }
+               source_id = Timeout.add (500, start_search);
+       }
+
+       private bool start_search () {
+               if (store.start_search (search_field.get_text ())) {
+                       movie_list.show ();
+                       no_movies.hide ();
+               }
+
+               // One-shot only
+               return false;
+       }
 }