Turn MilkTask into a proper GObject and use it directly in MilkTaskModel
[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 #include "milk-task.h"
29
30 static void
31 milk_task_model_tree_model_init (GtkTreeModelIface *iface);
32
33 G_DEFINE_TYPE_EXTENDED (MilkTaskModel,
34                         milk_task_model,
35                         G_TYPE_OBJECT,
36                         0,
37                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
38                                                milk_task_model_tree_model_init));
39
40 /* less expensive than G_TYPE_INSTANCE_GET_PRIVATE */
41 #define MILK_TASK_MODEL_PRIVATE(o) ((MILK_TASK_MODEL ((o)))->priv)
42
43 struct _MilkTaskModelPrivate
44 {
45         GtkListStore *store;
46 };
47
48 static GtkTreeModelFlags
49 milk_task_model_get_flags (GtkTreeModel *model)
50 {
51         return GTK_TREE_MODEL_LIST_ONLY;
52 }
53
54 static gint
55 milk_task_model_get_n_columns (GtkTreeModel *model)
56 {
57         return MILK_TASK_MODEL_N_COLUMNS;
58 }
59
60 static GType
61 milk_task_model_get_column_type (GtkTreeModel *model,
62                                  gint          column)
63 {
64         switch (column) {
65                 case MILK_TASK_MODEL_COLUMN_TASK:
66                         return MILK_TYPE_TASK;
67
68                 default:
69                         g_warning (G_STRLOC ": invalid column: %d", column);
70                         return G_TYPE_INVALID;
71         }
72 }
73
74 static gboolean
75 milk_task_model_get_iter (GtkTreeModel *model,
76                           GtkTreeIter  *iter,
77                           GtkTreePath  *path)
78 {
79         MilkTaskModelPrivate *priv;
80
81         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
82         g_return_val_if_fail (iter, FALSE);
83         g_return_val_if_fail (gtk_tree_path_get_depth (path) == 1, FALSE);
84
85         priv = MILK_TASK_MODEL_PRIVATE (model);
86
87         return gtk_tree_model_get_iter (
88                         GTK_TREE_MODEL (priv->store), iter, path);
89 }
90
91 static GtkTreePath*
92 milk_task_model_get_path (GtkTreeModel *model,
93                           GtkTreeIter  *iter)
94 {
95         MilkTaskModelPrivate *priv;
96
97         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), NULL);
98         g_return_val_if_fail (iter, NULL);
99
100         priv = MILK_TASK_MODEL_PRIVATE (model);
101
102         return gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), iter);
103 }
104
105 static void
106 milk_task_model_get_value (GtkTreeModel *model,
107                            GtkTreeIter  *iter,
108                            gint          column,
109                            GValue       *value)
110 {
111         MilkTaskModelPrivate *priv;
112
113         g_return_if_fail (MILK_IS_TASK_MODEL (model));
114         g_return_if_fail (iter);
115         g_return_if_fail (value);
116
117         priv = MILK_TASK_MODEL_PRIVATE (model);
118
119         gtk_tree_model_get_value (
120                         GTK_TREE_MODEL (priv->store), iter, column, value);
121 }
122
123 static gboolean
124 milk_task_model_iter_next (GtkTreeModel *model,
125                            GtkTreeIter  *iter)
126 {
127         MilkTaskModelPrivate *priv;
128
129         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
130         g_return_val_if_fail (iter, FALSE);
131
132         priv = MILK_TASK_MODEL_PRIVATE (model);
133
134         return gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), iter);
135 }
136
137 static gboolean
138 milk_task_model_iter_nth_child (GtkTreeModel *model,
139                                 GtkTreeIter  *iter,
140                                 GtkTreeIter  *parent,
141                                 gint          index)
142 {
143         MilkTaskModelPrivate *priv;
144
145         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
146         g_return_val_if_fail (iter, FALSE);
147         /* we're one-dimensional */
148         g_return_val_if_fail (!parent, FALSE);
149         g_return_val_if_fail (index >= 0, FALSE);
150
151         priv = MILK_TASK_MODEL_PRIVATE (model);
152
153         return gtk_tree_model_iter_nth_child (
154                         GTK_TREE_MODEL (priv->store), iter, parent, index);
155 }
156
157 static gboolean
158 milk_task_model_iter_children (GtkTreeModel *model,
159                                GtkTreeIter  *iter,
160                                GtkTreeIter  *parent)
161 {
162         MilkTaskModelPrivate *priv;
163
164         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
165         g_return_val_if_fail (iter, FALSE);
166         /* we're one-dimensional */
167         g_return_val_if_fail (!parent, FALSE);
168
169         priv = MILK_TASK_MODEL_PRIVATE (model);
170
171         return gtk_tree_model_iter_children (
172                         GTK_TREE_MODEL (priv->store), iter, parent);
173 }
174
175 static gboolean
176 milk_task_model_iter_has_child (GtkTreeModel *model,
177                                 GtkTreeIter  *iter)
178 {
179         MilkTaskModelPrivate *priv;
180
181         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
182         g_return_val_if_fail (iter, FALSE);
183
184         priv = MILK_TASK_MODEL_PRIVATE (model);
185
186         return gtk_tree_model_iter_has_child (
187                         GTK_TREE_MODEL (priv->store), iter);
188 }
189
190 static gint
191 milk_task_model_iter_n_children (GtkTreeModel *model,
192                                  GtkTreeIter  *iter)
193 {
194         MilkTaskModelPrivate *priv;
195
196         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), -1);
197         g_return_val_if_fail (iter, -1);
198
199         priv = MILK_TASK_MODEL_PRIVATE (model);
200
201         /* we're one-dimensional */
202         if (iter)
203                 return 0;
204
205         return gtk_tree_model_iter_n_children (
206                         GTK_TREE_MODEL (priv->store), iter);
207 }
208
209 static gboolean
210 milk_task_model_iter_parent (GtkTreeModel *model,
211                              GtkTreeIter  *iter,
212                              GtkTreeIter  *child)
213 {
214         MilkTaskModelPrivate *priv;
215
216         g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
217         g_return_val_if_fail (iter, FALSE);
218         g_return_val_if_fail (child, FALSE);
219
220         priv = MILK_TASK_MODEL_PRIVATE (model);
221
222         return gtk_tree_model_iter_parent (
223                         GTK_TREE_MODEL (priv->store), iter, child);
224 }
225
226 static void
227 milk_task_model_get_property (GObject    *object,
228                                guint       property_id,
229                                GValue     *value,
230                                GParamSpec *pspec)
231 {
232         switch (property_id)
233         {
234                 default:
235                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
236                                         pspec);
237         }
238 }
239
240 static void
241 milk_task_model_set_property (GObject      *object,
242                                guint         property_id,
243                                const GValue *value,
244                                GParamSpec   *pspec)
245 {
246         switch (property_id)
247         {
248                 default:
249                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
250                                         pspec);
251         }
252 }
253
254 static void
255 milk_task_model_dispose (GObject *object)
256 {
257         MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (object);
258
259         if (priv->store) {
260                 g_object_unref (priv->store);
261                 priv->store = NULL;
262         }
263
264         G_OBJECT_CLASS (milk_task_model_parent_class)->dispose (object);
265 }
266
267 static void
268 milk_task_model_constructed (GObject* object)
269 {
270         typedef struct {
271                 const char *id;
272                 const char *title;
273                 gint priority;
274         } MilkTask_args;
275
276         /* FIXME: don't hard-code this */
277         static MilkTask_args tasks[] = {
278                 { "0", "Walk the dog", 1},
279                 { "2", "Make a Maemo 5 RTM client", 1},
280                 { "6", "Stand on one foot", 3},
281                 { "9", "Pick up some DVX ('cause it's so crisp)", 2},
282                 { "5", "Finalize Halloween costume", 3},
283         };
284
285         MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (object);
286         GtkTreeIter iter;
287         gint i;
288
289         /* Populate model */
290         for (i = 0; i < G_N_ELEMENTS (tasks); i++) {
291                 MilkTask *task;
292
293                 task = milk_task_new (
294                                 tasks[i].id, tasks[i].title, tasks[i].priority);
295
296                 gtk_list_store_append (priv->store, &iter);
297                 gtk_list_store_set (
298                                 priv->store, &iter,
299                                 MILK_TASK_MODEL_COLUMN_TASK, task,
300                                 -1);
301         }
302 }
303
304 static void
305 milk_task_model_class_init (MilkTaskModelClass *klass)
306 {
307         GObjectClass *object_class = G_OBJECT_CLASS (klass);
308
309         g_type_class_add_private (klass, sizeof (MilkTaskModelPrivate));
310
311         object_class->get_property = milk_task_model_get_property;
312         object_class->set_property = milk_task_model_set_property;
313         object_class->constructed = milk_task_model_constructed;
314         object_class->dispose = milk_task_model_dispose;
315 }
316
317 static void
318 milk_task_model_init (MilkTaskModel *self)
319 {
320         MilkTaskModelPrivate *priv;
321
322         self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (
323                         self, MILK_TYPE_TASK_MODEL, MilkTaskModelPrivate);
324
325         priv->store = gtk_list_store_new (
326                         MILK_TASK_MODEL_N_COLUMNS, MILK_TYPE_TASK);
327 }
328
329 static void
330 milk_task_model_tree_model_init (GtkTreeModelIface *iface)
331 {
332         iface->get_flags       = milk_task_model_get_flags;
333         iface->get_n_columns   = milk_task_model_get_n_columns;
334         iface->get_column_type = milk_task_model_get_column_type;
335         iface->get_iter        = milk_task_model_get_iter;
336         iface->get_path        = milk_task_model_get_path;
337         iface->get_value       = milk_task_model_get_value;
338         iface->iter_next       = milk_task_model_iter_next;
339         iface->iter_children   = milk_task_model_iter_children;
340         iface->iter_has_child  = milk_task_model_iter_has_child;
341         iface->iter_n_children = milk_task_model_iter_n_children;
342         iface->iter_nth_child  = milk_task_model_iter_nth_child;
343         iface->iter_parent     = milk_task_model_iter_parent;
344 }
345
346 MilkTaskModel*
347 milk_task_model_new ()
348 {
349         return g_object_new (MILK_TYPE_TASK_MODEL, NULL);
350 }