8e6a13d2430649a602b263882745b74746f3f701
[milk] / src / milk-task-model.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License as
4  * published by the Free Software Foundation; either version 2 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public
13  * License along with this program; if not, write to the
14  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
15  * Boston, MA  02110-1301  USA
16  *
17  * Authors: Travis Reitter <treitter@gmail.com>
18  */
19
20 #include <config.h>
21
22 #include <glib.h>
23 #include <glib/gi18n.h>
24 #include <gtk/gtk.h>
25 #include <hildon/hildon.h>
26
27 #include "milk-task-model.h"
28
29 static void
30 milk_task_model_tree_model_init (GtkTreeModelIface *iface);
31
32 G_DEFINE_TYPE_EXTENDED (MilkTaskModel,
33                         milk_task_model,
34                         G_TYPE_OBJECT,
35                         0,
36                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
37                                                milk_task_model_tree_model_init));
38
39 /* less expensive than G_TYPE_INSTANCE_GET_PRIVATE */
40 #define MILK_TASK_MODEL_PRIVATE(o) ((MILK_TASK_MODEL ((o)))->priv)
41
42 struct _MilkTaskModelPrivate
43 {
44         GtkListStore *store;
45 };
46
47 /* FIXME: relocate this to its own class */
48 typedef struct {
49         gint id;
50         gint priority;
51         char *title;
52 } MilkTask;
53
54 /* FIXME: don't hard-code this */
55 static MilkTask tasks[] = {
56         { 0, 1, "Remember the milk"},
57         { 2, 1, "Make a Maemo 5 RTM client"},
58         { 6, 3, "Get a haircut"},
59         { 9, 2, "Keep it real"},
60         { 5, 3, "Invent smellovision"},
61 };
62
63 static GtkTreeModelFlags
64 milk_task_model_get_flags (GtkTreeModel *model)
65 {
66         return GTK_TREE_MODEL_LIST_ONLY;
67 }
68
69 static gint
70 milk_task_model_get_n_columns (GtkTreeModel *model)
71 {
72         return MILK_TASK_MODEL_N_COLUMNS;
73 }
74
75 static GType
76 milk_task_model_get_column_type (GtkTreeModel *model,
77                                  gint          column)
78 {
79         switch (column) {
80                 case MILK_TASK_MODEL_COLUMN_ID:
81                         return G_TYPE_INT;
82
83                 case MILK_TASK_MODEL_COLUMN_PRIORITY:
84                         return G_TYPE_UINT;
85
86                 case MILK_TASK_MODEL_COLUMN_TITLE:
87                         return G_TYPE_STRING;
88
89                 default:
90                         g_warning (G_STRLOC ": invalid column: %d", column);
91                         return G_TYPE_INVALID;
92         }
93 }
94
95 static gboolean
96 milk_task_model_get_iter (GtkTreeModel *model,
97                           GtkTreeIter  *iter,
98                           GtkTreePath  *path)
99 {
100         MilkTaskModelPrivate *priv;
101
102         g_return_val_if_fail (MILK_IS_LIST_STORE (model), FALSE);
103         g_return_val_if_fail (iter, FALSE);
104         g_return_val_if_fail (gtk_tree_path_get_depth (path) == 1, FALSE);
105
106         priv = MILK_TASK_MODEL_PRIVATE (model);
107
108         return gtk_tree_model_get_iter (
109                         GTK_TREE_MODEL (priv->store), iter, path);
110 }
111
112 static GtkTreePath*
113 milk_task_model_get_path (GtkTreeModel *model,
114                           GtkTreeIter  *iter)
115 {
116         MilkTaskModelPrivate *priv;
117
118         g_return_val_if_fail (MILK_IS_LIST_STORE (model), NULL);
119         g_return_val_if_fail (iter, NULL);
120
121         priv = MILK_TASK_MODEL_PRIVATE (model);
122
123         return gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), iter);
124 }
125
126 static void
127 milk_task_model_get_value (GtkTreeModel *model,
128                            GtkTreeIter  *iter,
129                            gint          column,
130                            GValue       *value)
131 {
132         MilkTaskModelPrivate *priv;
133
134         g_return_if_fail (MILK_IS_LIST_STORE (model));
135         g_return_if_fail (iter);
136         g_return_if_fail (column >= 0);
137         g_return_if_fail (value);
138
139         priv = MILK_TASK_MODEL_PRIVATE (model);
140
141         gtk_tree_model_get_value (
142                         GTK_TREE_MODEL (priv->store), iter, column, value);
143 }
144
145 static gboolean
146 milk_task_model_iter_next (GtkTreeModel *model,
147                            GtkTreeIter  *iter)
148 {
149         MilkTaskModelPrivate *priv;
150
151         g_return_val_if_fail (MILK_IS_LIST_STORE (model), FALSE);
152         g_return_val_if_fail (iter, FALSE);
153
154         priv = MILK_TASK_MODEL_PRIVATE (model);
155
156         return gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), iter);
157 }
158
159 static gboolean
160 milk_task_model_iter_nth_child (GtkTreeModel *model,
161                                 GtkTreeIter  *iter,
162                                 GtkTreeIter  *parent,
163                                 gint          index)
164 {
165         MilkTaskModelPrivate *priv;
166
167         g_return_val_if_fail (MILK_IS_LIST_STORE (model), FALSE);
168         g_return_val_if_fail (iter, FALSE);
169         /* we're one-dimensional */
170         g_return_val_if_fail (!parent, FALSE);
171         g_return_val_if_fail (index >= 0, FALSE);
172
173         priv = MILK_TASK_MODEL_PRIVATE (model);
174
175         return gtk_tree_model_iter_nth_child (
176                         GTK_TREE_MODEL (priv->store), iter, parent, index);
177 }
178
179 static gboolean
180 milk_task_model_iter_children (GtkTreeModel *model,
181                                GtkTreeIter  *iter,
182                                GtkTreeIter  *parent)
183 {
184         MilkTaskModelPrivate *priv;
185
186         g_return_val_if_fail (MILK_IS_LIST_STORE (model), FALSE);
187         g_return_val_if_fail (iter, FALSE);
188         /* we're one-dimensional */
189         g_return_val_if_fail (!parent, FALSE);
190
191         priv = MILK_TASK_MODEL_PRIVATE (model);
192
193         return gtk_tree_model_iter_children (
194                         GTK_TREE_MODEL (priv->store), iter, parent);
195 }
196
197 static gboolean
198 milk_task_model_iter_has_child (GtkTreeModel *model,
199                                 GtkTreeIter  *iter)
200 {
201         MilkTaskModelPrivate *priv;
202
203         g_return_val_if_fail (MILK_IS_LIST_STORE (model), FALSE);
204         g_return_val_if_fail (iter, FALSE);
205
206         priv = MILK_TASK_MODEL_PRIVATE (model);
207
208         return gtk_tree_model_iter_has_child (
209                         GTK_TREE_MODEL (priv->store), iter);
210 }
211
212 static gint
213 milk_task_model_iter_n_children (GtkTreeModel *model,
214                                  GtkTreeIter  *iter)
215 {
216         MilkTaskModelPrivate *priv;
217
218         g_return_val_if_fail (MILK_IS_LIST_STORE (model), -1);
219         g_return_val_if_fail (iter, -1);
220
221         priv = MILK_TASK_MODEL_PRIVATE (model);
222
223         /* we're one-dimensional */
224         if (iter)
225                 return 0;
226
227         return gtk_tree_model_iter_n_children (
228                         GTK_TREE_MODEL (priv->store), iter);
229 }
230
231 static gboolean
232 milk_task_model_iter_parent (GtkTreeModel *model,
233                              GtkTreeIter  *iter,
234                              GtkTreeIter  *child)
235 {
236         MilkTaskModelPrivate *priv;
237
238         g_return_val_if_fail (MILK_IS_LIST_STORE (model), FALSE);
239         g_return_val_if_fail (iter, FALSE);
240         g_return_val_if_fail (child, FALSE);
241
242         priv = MILK_TASK_MODEL_PRIVATE (model);
243
244         return gtk_tree_model_iter_parent (
245                         GTK_TREE_MODEL (priv->store), iter, child);
246 }
247
248 static void
249 milk_task_model_get_property (GObject    *object,
250                                guint       property_id,
251                                GValue     *value,
252                                GParamSpec *pspec)
253 {
254         switch (property_id)
255         {
256                 default:
257                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
258                                         pspec);
259         }
260 }
261
262 static void
263 milk_task_model_set_property (GObject      *object,
264                                guint         property_id,
265                                const GValue *value,
266                                GParamSpec   *pspec)
267 {
268         switch (property_id)
269         {
270                 default:
271                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
272                                         pspec);
273         }
274 }
275
276 static void
277 milk_task_model_dispose (GObject *object)
278 {
279         MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (object);
280
281         if (priv->store) {
282                 g_object_unref (priv->store);
283                 priv->store = NULL;
284         }
285
286         G_OBJECT_CLASS (milk_task_model_parent_class)->dispose (object);
287 }
288
289 static void
290 milk_task_model_constructed (GObject* object)
291 {
292         typedef struct {
293                 const char *id;
294                 const char *title;
295                 gint priority;
296         } MilkTask_args;
297
298         /* FIXME: don't hard-code this */
299         static MilkTask_args tasks[] = {
300                 { "0", "Walk the dog", 1},
301                 { "2", "Make a Maemo 5 RTM client", 1},
302                 { "6", "Stand on one foot", 3},
303                 { "9", "Pick up some DVX ('cause it's so crisp)", 2},
304                 { "5", "Finalize Halloween costume", 3},
305         };
306
307         MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (object);
308         GtkTreeIter iter;
309         gint i;
310
311         /* Populate model */
312         for (i = 0; i < G_N_ELEMENTS (tasks); i++) {
313                 gtk_list_store_append (priv->store, &iter);
314                 gtk_list_store_set (
315                                 priv->store, &iter,
316                                 MILK_TASK_MODEL_COLUMN_ID,
317                                 tasks[i].id,
318                                 MILK_TASK_MODEL_COLUMN_PRIORITY,
319                                 tasks[i].priority,
320                                 MILK_TASK_MODEL_COLUMN_TITLE,
321                                 tasks[i].title,
322                                 -1);
323         }
324 }
325
326 static void
327 milk_task_model_class_init (MilkTaskModelClass *klass)
328 {
329         GObjectClass *object_class = G_OBJECT_CLASS (klass);
330
331         g_type_class_add_private (klass, sizeof (MilkTaskModelPrivate));
332
333         object_class->get_property = milk_task_model_get_property;
334         object_class->set_property = milk_task_model_set_property;
335         object_class->constructed = milk_task_model_constructed;
336         object_class->dispose = milk_task_model_dispose;
337 }
338
339 static void
340 milk_task_model_init (MilkTaskModel *self)
341 {
342         MilkTaskModelPrivate *priv;
343
344         self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (
345                         self, MILK_TYPE_LIST_STORE, MilkTaskModelPrivate);
346
347         priv->store = gtk_list_store_new (
348                         MILK_TASK_MODEL_N_COLUMNS, G_TYPE_INT, G_TYPE_UINT,
349                         G_TYPE_STRING);
350 }
351
352 static void
353 milk_task_model_tree_model_init (GtkTreeModelIface *iface)
354 {
355         iface->get_flags       = milk_task_model_get_flags;
356         iface->get_n_columns   = milk_task_model_get_n_columns;
357         iface->get_column_type = milk_task_model_get_column_type;
358         iface->get_iter        = milk_task_model_get_iter;
359         iface->get_path        = milk_task_model_get_path;
360         iface->get_value       = milk_task_model_get_value;
361         iface->iter_next       = milk_task_model_iter_next;
362         iface->iter_children   = milk_task_model_iter_children;
363         iface->iter_has_child  = milk_task_model_iter_has_child;
364         iface->iter_n_children = milk_task_model_iter_n_children;
365         iface->iter_nth_child  = milk_task_model_iter_nth_child;
366         iface->iter_parent     = milk_task_model_iter_parent;
367 }
368
369 MilkTaskModel*
370 milk_task_model_new ()
371 {
372         return g_object_new (MILK_TYPE_LIST_STORE,
373                              NULL);
374 }