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