Movie list view: fix movie poster icon width to 64 px
[cinaest] / src / movie-list-store.vala
1 /* This file is part of Cinaest.
2  *
3  * Copyright (C) 2009 Philipp Zabel
4  *
5  * Cinaest is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Cinaest is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 using Gtk;
20
21 public class MovieListStore : ListStore, TreeModel {
22         public enum Columns {
23                 TITLE,
24                 YEAR,
25                 RATING,
26                 POSTER,
27                 MOVIE,
28                 N_COLUMNS
29         }
30         private GLib.Type[] types = {
31                 typeof (string),
32                 typeof (int),
33                 typeof (int),
34                 typeof (Gdk.Pixbuf),
35                 typeof (Movie)
36         };
37         private GLib.Type[] base_type = {
38                 typeof (Movie)
39         };
40         private Gdk.Pixbuf no_poster;
41         public MovieSource source;
42         private MovieFilter filter;
43         public bool update_running { get; set; }
44         private Cancellable cancellable;
45
46         construct {
47                 set_column_types (base_type);
48                 no_poster = null;
49                 source = null;
50                 update_running = false;
51         }
52
53         public void add (Movie movie, out TreeIter iter) {
54                 TreeIter iter1;
55
56                 append (out iter1);
57                 base.set (iter1, 0, movie);
58
59                 movie.notify.connect ((source, property) => { on_movie_changed(source); });
60
61                 iter = iter1;
62         }
63
64         private void on_movie_changed (GLib.Object source) {
65                 Movie movie = (Movie) source;
66
67                 TreeIter iter;
68                 if (get_iter_from_movie (out iter, movie)) {
69                         TreePath path = get_path (iter);
70                         base.row_changed (path, iter);
71                 }
72         }
73
74         public bool get_iter_from_movie (out TreeIter iter, Movie movie_a) {
75                 if (get_iter_first (out iter)) {
76                         do {
77                                 Movie movie_b;
78                                 get (iter, Columns.MOVIE, out movie_b);
79                                 if (movie_a == movie_b)
80                                         return true;
81                         } while (iter_next (ref iter));
82                 }
83                 return false;
84         }
85
86         public bool start_search (MovieFilter _filter) {
87                 if (update_running) {
88                         stdout.printf ("aborting search ...\n");
89                         cancellable.cancel ();
90                 //      poster_factory.clear_queue ();
91                         return false;
92                 }
93                 if (cancellable == null || cancellable.is_cancelled ())
94                         cancellable = new Cancellable ();
95
96                 filter = _filter;
97                 stdout.printf ("begin search\n");
98                 search_async.begin ();
99                 update_running = true;
100                 return true;
101         }
102
103         // Asynchronous update method
104         private async void search_async () {
105                 stdout.printf ("search started: \"%s\"\n", filter.title);
106
107                 clear ();
108
109                 if (source != null)
110                         // FIXME - arbitrary limit
111                         yield source.get_movies (filter, receive_movie, 100, cancellable);
112
113                 update_running = false;
114                 if (cancellable.is_cancelled ()) {
115                         stdout.printf ("search aborted, starting new\n");
116                         cancellable.reset ();
117                         if (cancellable.is_cancelled ()) {
118                                 stdout.printf ("OW WEY\n");
119                         }
120                         start_search (filter);
121                 } else {
122                         stdout.printf ("search stopped\n");
123                 }
124         }
125
126         private void receive_movie (Movie movie) {
127                 TreeIter iter;
128
129                 if (cancellable.is_cancelled ())
130                         return;
131
132                 add (movie, out iter);
133         }
134
135         // Implement TreeModel interface
136         public virtual GLib.Type get_column_type (int index_) {
137                 return_val_if_fail (index_ >= 0 && index_ < Columns.N_COLUMNS, 0);
138
139                 return types[index_];
140         }
141
142         public virtual int get_n_columns () {
143                 return Columns.N_COLUMNS;
144         }
145
146         public virtual void get_value (TreeIter iter, int column, out GLib.Value value) {
147                 Movie movie;
148
149                 // FIXME
150                 if (no_poster == null) try {
151                         no_poster = new Gdk.Pixbuf.from_file ("/usr/share/icons/hicolor/64x64/hildon/general_video.png");
152                 } catch (Error e) {
153                         critical ("Missing general_video icon: %s\n", e.message);
154                 }
155
156                 return_if_fail (column >= 0 && column < Columns.N_COLUMNS);
157
158                 // Get the Movie from our parent's storage
159                 Value val;
160                 base.get_value (iter, 0, out val);
161                 movie = (Movie) val.get_object ();
162
163                 value.init (get_column_type (column));
164
165                 switch (column) {
166                 case Columns.TITLE:
167                         if (movie != null) {
168                                 value.set_string (movie.title);
169                         } else {
170                                 value.set_string ("");
171                         }
172                         break;
173
174                 case Columns.YEAR:
175                         if (movie != null) {
176                                 value.set_int (movie.year);
177                         } else {
178                                 value.set_int (-1);
179                         }
180                         break;
181
182                 case Columns.RATING:
183                         if (movie != null) {
184                                 value.set_int (movie.rating);
185                         } else {
186                                 value.set_int (-1);
187                         }
188                         break;
189
190                 case Columns.POSTER:
191                         if ((movie.poster != null) && (movie.poster.thumbnail != null))
192                                 value.set_object (movie.poster.thumbnail);
193                         else
194                                 value.set_object (no_poster);
195                         break;
196
197                 case Columns.MOVIE:
198                         value.set_object (movie);
199                         break;
200
201                 default:
202                         assert_not_reached ();
203                 }
204         }
205 }