Initial Import
[profile/ivi/clutter-toys.git] / attic / woohaa / wh-video-model.c
1 #include "wh-video-model.h"
2 #include <string.h>
3
4 G_DEFINE_TYPE (WHVideoModel, wh_video_model, G_TYPE_OBJECT);
5
6 #define VIDEO_MODEL_PRIVATE(o) \
7   (G_TYPE_INSTANCE_GET_PRIVATE ((o), WH_TYPE_VIDEO_MODEL, WHVideoModelPrivate))
8
9 typedef struct _WHVideoModelPrivate WHVideoModelPrivate;
10
11 enum
12 {
13   REORDERED,
14   ROW_CHANGED,
15   ROW_ADDED,
16   FILTER,
17   LAST_SIGNAL
18 };
19
20 static guint _model_signals[LAST_SIGNAL] = { 0 };
21
22 struct _WHVideoModelPrivate
23 {
24   WHFilterRowFunc  filter;
25   gpointer         filter_data;
26   WHCompareRowFunc sort;
27   gpointer         sort_data;
28   EggSequence     *rows;
29 };
30
31 static void
32 wh_video_model_get_property (GObject *object, guint property_id,
33                              GValue *value, GParamSpec *pspec)
34 {
35   switch (property_id) {
36   default:
37     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
38   }
39 }
40
41 static void
42 wh_video_model_set_property (GObject *object, guint property_id,
43                                   const GValue *value, GParamSpec *pspec)
44 {
45   switch (property_id) {
46   default:
47     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
48   }
49 }
50
51 static void
52 wh_video_model_dispose (GObject *object)
53 {
54   if (G_OBJECT_CLASS (wh_video_model_parent_class)->dispose)
55     G_OBJECT_CLASS (wh_video_model_parent_class)->dispose (object);
56 }
57
58 static void
59 wh_video_model_finalize (GObject *object)
60 {
61   G_OBJECT_CLASS (wh_video_model_parent_class)->finalize (object);
62 }
63
64 static void
65 wh_video_model_class_init (WHVideoModelClass *klass)
66 {
67   GObjectClass *object_class = G_OBJECT_CLASS (klass);
68
69   g_type_class_add_private (klass, sizeof (WHVideoModelPrivate));
70
71   object_class->get_property = wh_video_model_get_property;
72   object_class->set_property = wh_video_model_set_property;
73   object_class->dispose = wh_video_model_dispose;
74   object_class->finalize = wh_video_model_finalize;
75
76   _model_signals[REORDERED] =
77     g_signal_new ("rows-reordered",
78                   G_OBJECT_CLASS_TYPE (object_class),
79                   G_SIGNAL_RUN_FIRST,
80                   G_STRUCT_OFFSET (WHVideoModelClass, reordered),
81                   NULL, NULL,
82                   g_cclosure_marshal_VOID__VOID,
83                   G_TYPE_NONE, 0);
84
85   _model_signals[FILTER] =
86     g_signal_new ("filter-changed",
87                   G_OBJECT_CLASS_TYPE (object_class),
88                   G_SIGNAL_RUN_FIRST,
89                   G_STRUCT_OFFSET (WHVideoModelClass, filter_change),
90                   NULL, NULL,
91                   g_cclosure_marshal_VOID__VOID,
92                   G_TYPE_NONE, 0);
93
94   _model_signals[ROW_CHANGED] =
95     g_signal_new ("row-changed",
96                   G_OBJECT_CLASS_TYPE (object_class),
97                   G_SIGNAL_RUN_FIRST,
98                   G_STRUCT_OFFSET (WHVideoModelClass, row_change),
99                   NULL, NULL,
100                   g_cclosure_marshal_VOID__OBJECT,
101                   G_TYPE_NONE, 1, WH_TYPE_VIDEO_MODEL_ROW);
102
103   _model_signals[ROW_ADDED] =
104     g_signal_new ("row-added",
105                   G_OBJECT_CLASS_TYPE (object_class),
106                   G_SIGNAL_RUN_FIRST,
107                   G_STRUCT_OFFSET (WHVideoModelClass, row_added),
108                   NULL, NULL,
109                   g_cclosure_marshal_VOID__OBJECT,
110                   G_TYPE_NONE, 1, WH_TYPE_VIDEO_MODEL_ROW);
111
112 }
113
114 static void
115 wh_video_model_init (WHVideoModel *self)
116 {
117   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(self);
118
119   priv->rows = egg_sequence_new (NULL);
120 }
121
122 static gboolean 
123 check_filter (WHVideoModel *model, EggSequenceIter *iter)
124 {
125   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(model);  
126   gboolean res;
127
128   if (priv->filter == NULL)
129     return TRUE;
130
131   res = priv->filter(model, 
132                      (WHVideoModelRow*)egg_sequence_get (iter), 
133                      priv->filter_data); 
134   return res;
135 }
136
137 guint
138 wh_video_model_row_count (WHVideoModel *model)
139 {
140   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(model);  
141   EggSequenceIter     *iter;
142   gint                 n = 0;
143
144   if (priv->filter == NULL)
145     return egg_sequence_get_length (priv->rows);    
146
147   iter = egg_sequence_get_begin_iter (priv->rows);
148
149   while (!egg_sequence_iter_is_end (iter))
150     {
151       if (check_filter (model, iter))
152         n++;
153       iter = egg_sequence_iter_next (iter);
154     }
155
156   return n;
157 }
158
159 WHVideoModelRow*
160 wh_video_model_get_row (WHVideoModel *model, gint index)
161 {
162   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(model);
163   EggSequenceIter     *iter;
164   gint                 n = 0;
165
166   if (priv->filter == NULL)
167     return (WHVideoModelRow*)egg_sequence_get 
168       (egg_sequence_get_iter_at_pos (priv->rows, index));
169
170   iter = egg_sequence_get_begin_iter (priv->rows);
171
172   while (!egg_sequence_iter_is_end (iter))
173     {
174       if (check_filter (model, iter))
175         {
176           if (n == index)
177             return (WHVideoModelRow*)egg_sequence_get (iter);
178           n++;
179         }
180       iter = egg_sequence_iter_next (iter);
181     }
182
183   return NULL;
184 }
185
186 static void
187 on_row_changed (GObject      *obj,
188                 GParamSpec   *arg1,
189                 gpointer      data)
190 {
191   WHVideoModel        *model = WH_VIDEO_MODEL(data);
192   WHVideoModelPrivate *priv;
193
194   priv = VIDEO_MODEL_PRIVATE(model);
195
196   /* thumbnail changing does not effect ordering */
197   if (!strcmp(g_param_spec_get_name(arg1), "thumbnail"))
198     return;
199
200   if (priv->sort)
201     {
202       egg_sequence_sort (priv->rows, 
203                          (GCompareDataFunc)priv->sort, priv->sort_data);
204       g_signal_emit (model, _model_signals[REORDERED], 0);
205     }
206
207   g_signal_emit (model, _model_signals[ROW_CHANGED], 0, 
208                  WH_VIDEO_MODEL_ROW(obj));
209
210
211 void
212 wh_video_model_append_row (WHVideoModel *model, WHVideoModelRow *row)
213 {
214   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(model);
215   EggSequenceIter     *iter;
216
217   g_signal_connect (row,
218                     "notify",
219                     G_CALLBACK (on_row_changed),
220                     model);
221
222   g_object_ref (row);
223
224   if (priv->sort)
225     iter = egg_sequence_insert_sorted (priv->rows,
226                                        (gpointer)row,
227                                        (GCompareDataFunc)priv->sort,
228                                        priv->sort_data);
229   else
230     iter = egg_sequence_append (priv->rows, (gpointer)row);
231
232   if (check_filter (model, iter))
233     g_signal_emit (model, _model_signals[ROW_ADDED], 0, row);
234 }
235
236
237 void
238 wh_video_model_foreach (WHVideoModel      *model, 
239                         WHForeachRowFunc   func,
240                         gpointer           data)
241 {
242   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(model);
243   EggSequenceIter     *iter;
244
245   iter = egg_sequence_get_begin_iter (priv->rows);
246
247     while (!egg_sequence_iter_is_end (iter))
248     {
249       if (check_filter (model, iter))
250         if (func (model, 
251                   (WHVideoModelRow*)egg_sequence_get (iter),
252                   data) == FALSE)
253           return;
254         
255       iter = egg_sequence_iter_next (iter);
256     }
257 }
258
259 void
260 wh_video_model_set_sort_func (WHVideoModel     *model, 
261                               WHCompareRowFunc  func, 
262                               gpointer          userdata)
263 {
264   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(model);
265
266   priv->sort      = func;
267   priv->sort_data = userdata;
268
269   if (func)
270     {
271       egg_sequence_sort (priv->rows, (GCompareDataFunc)func, userdata);
272       g_signal_emit (model, _model_signals[REORDERED], 0);
273     }
274 }
275
276 void
277 wh_video_model_set_filter (WHVideoModel    *model,
278                            WHFilterRowFunc  filter, 
279                            gpointer         data)
280 {
281   WHVideoModelPrivate *priv = VIDEO_MODEL_PRIVATE(model);
282   WHFilterRowFunc      prev_filter;
283
284   prev_filter = priv->filter;
285
286   priv->filter      = filter;
287   priv->filter_data = data;
288
289   if (prev_filter != priv->filter)
290     g_signal_emit (model, _model_signals[FILTER], 0);
291 }
292
293 WHVideoModel*
294 wh_video_model_new ()
295 {
296   return g_object_new (WH_TYPE_VIDEO_MODEL, NULL);
297 }
298