/* This file is part of Cinaest. * * Copyright (C) 2009 Philipp Zabel * * Cinaest is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Cinaest is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Cinaest. If not, see . */ using Gtk; public class MovieListStore : ListStore, TreeModel { public enum Columns { TITLE, YEAR, RATING, POSTER, MOVIE, N_COLUMNS } private GLib.Type[] types = { typeof (string), typeof (int), typeof (int), typeof (Gdk.Pixbuf), typeof (Movie) }; private GLib.Type[] base_type = { typeof (Movie) }; private Gdk.Pixbuf no_poster; public MovieSource source; private string query; public bool update_running { get; set; } construct { set_column_types (base_type); no_poster = null; source = null; update_running = false; } public void add (Movie movie, out TreeIter iter) { TreeIter iter1; append (out iter1); base.set (iter1, 0, movie); movie.notify.connect ((source, property) => { on_movie_changed(source); }); iter = iter1; } private void on_movie_changed (GLib.Object source) { Movie movie = (Movie) source; TreeIter iter; if (get_iter_from_movie (out iter, movie)) { TreePath path = get_path (iter); base.row_changed (path, iter); } } public bool get_iter_from_movie (out TreeIter iter, Movie movie_a) { if (get_iter_first (out iter)) { do { Movie movie_b; get (iter, Columns.MOVIE, out movie_b); if (movie_a == movie_b) return true; } while (iter_next (ref iter)); } 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); Gdk.threads_enter (); update_running = false; Gdk.threads_leave (); 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); return types[index_]; } public virtual int get_n_columns () { return Columns.N_COLUMNS; } public virtual void get_value (TreeIter iter, int column, out GLib.Value value) { Movie movie; // FIXME if (no_poster == null) try { no_poster = new Gdk.Pixbuf.from_file ("/usr/share/icons/hicolor/64x64/hildon/general_video.png"); } catch (Error e) { critical ("Missing general_video icon: %s\n", e.message); } return_if_fail (column >= 0 && column < Columns.N_COLUMNS); // Get the Movie from our parent's storage Value val; base.get_value (iter, 0, out val); movie = (Movie) val.get_object (); value.init (get_column_type (column)); switch (column) { case Columns.TITLE: if (movie != null) { value.set_string (movie.title); } else { value.set_string (""); } break; case Columns.YEAR: if (movie != null) { value.set_int (movie.year); } else { value.set_int (-1); } break; case Columns.RATING: if (movie != null) { value.set_int (movie.rating); } else { value.set_int (-1); } break; case Columns.POSTER: if ((movie.poster != null) && (movie.poster.thumbnail != null)) value.set_object (movie.poster.thumbnail); else value.set_object (no_poster); break; case Columns.MOVIE: value.set_object (movie); break; default: assert_not_reached (); } } }