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.
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.
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
17 * Authors: Travis Reitter <treitter@gmail.com>
23 #include <glib/gi18n.h>
25 #include <hildon/hildon.h>
26 #include <rtm-glib/rtm-glib.h>
28 #include "milk-task-model.h"
29 #include "milk-auth.h"
30 #include "milk-task.h"
33 milk_task_model_tree_model_init (GtkTreeModelIface *iface);
35 G_DEFINE_TYPE_EXTENDED (MilkTaskModel,
39 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
40 milk_task_model_tree_model_init));
42 /* less expensive than G_TYPE_INSTANCE_GET_PRIVATE */
43 #define MILK_TASK_MODEL_PRIVATE(o) ((MILK_TASK_MODEL ((o)))->priv)
45 struct _MilkTaskModelPrivate
55 static GtkTreeModelFlags
56 milk_task_model_get_flags (GtkTreeModel *model)
58 return GTK_TREE_MODEL_LIST_ONLY;
62 milk_task_model_get_n_columns (GtkTreeModel *model)
64 return MILK_TASK_MODEL_N_COLUMNS;
68 milk_task_model_get_column_type (GtkTreeModel *model,
72 case MILK_TASK_MODEL_COLUMN_TASK:
73 return MILK_TYPE_TASK;
76 g_warning (G_STRLOC ": invalid column: %d", column);
77 return G_TYPE_INVALID;
82 milk_task_model_get_iter (GtkTreeModel *model,
86 MilkTaskModelPrivate *priv;
88 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
89 g_return_val_if_fail (iter, FALSE);
90 g_return_val_if_fail (gtk_tree_path_get_depth (path) == 1, FALSE);
92 priv = MILK_TASK_MODEL_PRIVATE (model);
94 return gtk_tree_model_get_iter (
95 GTK_TREE_MODEL (priv->store), iter, path);
99 milk_task_model_get_path (GtkTreeModel *model,
102 MilkTaskModelPrivate *priv;
104 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), NULL);
105 g_return_val_if_fail (iter, NULL);
107 priv = MILK_TASK_MODEL_PRIVATE (model);
109 return gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), iter);
113 milk_task_model_get_value (GtkTreeModel *model,
118 MilkTaskModelPrivate *priv;
120 g_return_if_fail (MILK_IS_TASK_MODEL (model));
121 g_return_if_fail (iter);
122 g_return_if_fail (value);
124 priv = MILK_TASK_MODEL_PRIVATE (model);
126 gtk_tree_model_get_value (
127 GTK_TREE_MODEL (priv->store), iter, column, value);
131 milk_task_model_iter_next (GtkTreeModel *model,
134 MilkTaskModelPrivate *priv;
136 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
137 g_return_val_if_fail (iter, FALSE);
139 priv = MILK_TASK_MODEL_PRIVATE (model);
141 return gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), iter);
145 milk_task_model_iter_nth_child (GtkTreeModel *model,
150 MilkTaskModelPrivate *priv;
152 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
153 g_return_val_if_fail (iter, FALSE);
154 /* we're one-dimensional */
155 g_return_val_if_fail (!parent, FALSE);
156 g_return_val_if_fail (index >= 0, FALSE);
158 priv = MILK_TASK_MODEL_PRIVATE (model);
160 return gtk_tree_model_iter_nth_child (
161 GTK_TREE_MODEL (priv->store), iter, parent, index);
165 milk_task_model_iter_children (GtkTreeModel *model,
169 MilkTaskModelPrivate *priv;
171 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
172 g_return_val_if_fail (iter, FALSE);
173 /* we're one-dimensional */
174 g_return_val_if_fail (!parent, FALSE);
176 priv = MILK_TASK_MODEL_PRIVATE (model);
178 return gtk_tree_model_iter_children (
179 GTK_TREE_MODEL (priv->store), iter, parent);
183 milk_task_model_iter_has_child (GtkTreeModel *model,
186 MilkTaskModelPrivate *priv;
188 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
189 g_return_val_if_fail (iter, FALSE);
191 priv = MILK_TASK_MODEL_PRIVATE (model);
193 return gtk_tree_model_iter_has_child (
194 GTK_TREE_MODEL (priv->store), iter);
198 milk_task_model_iter_n_children (GtkTreeModel *model,
201 MilkTaskModelPrivate *priv;
203 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), -1);
204 g_return_val_if_fail (iter, -1);
206 priv = MILK_TASK_MODEL_PRIVATE (model);
208 /* we're one-dimensional */
212 return gtk_tree_model_iter_n_children (
213 GTK_TREE_MODEL (priv->store), iter);
217 milk_task_model_iter_parent (GtkTreeModel *model,
221 MilkTaskModelPrivate *priv;
223 g_return_val_if_fail (MILK_IS_TASK_MODEL (model), FALSE);
224 g_return_val_if_fail (iter, FALSE);
225 g_return_val_if_fail (child, FALSE);
227 priv = MILK_TASK_MODEL_PRIVATE (model);
229 return gtk_tree_model_iter_parent (
230 GTK_TREE_MODEL (priv->store), iter, child);
234 populate_model (MilkTaskModel *model)
236 MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (model);
241 gtk_list_store_clear (priv->store);
243 /* FIXME: poll for new tasks periodically -- there's rtm-glib API to
244 * optimize just fetching the latest ones */
245 rtm_tasks = milk_auth_get_tasks (priv->auth);
248 for (l = rtm_tasks; l; l = g_list_delete_link (l, l)) {
252 rtm_task = RTM_TASK (l->data);
254 /* XXX: if possible, avoid fetching these in the first place */
255 /* Skip tasks deleted or completed. */
256 if (rtm_task_get_completed_date (rtm_task) ||
257 rtm_task_get_deleted_date (rtm_task)) {
261 task = milk_task_new (rtm_task_get_id (rtm_task),
262 rtm_task_get_name (rtm_task),
263 /* FIXME: switch priority from int to string */
264 g_ascii_strtod (rtm_task_get_priority
267 gtk_list_store_append (priv->store, &iter);
270 MILK_TASK_MODEL_COLUMN_TASK, task,
276 auth_notify_cb (MilkAuth *auth,
278 MilkTaskModel *model)
280 if (milk_auth_get_state (auth) == MILK_AUTH_STATE_CONNECTED) {
281 populate_model (model);
286 row_changed_cb (GtkTreeModel *model,
291 gtk_tree_model_row_changed (GTK_TREE_MODEL (self), path, iter);
295 row_deleted_cb (GtkTreeModel *model,
299 gtk_tree_model_row_deleted (GTK_TREE_MODEL (self), path);
303 row_inserted_cb (GtkTreeModel *model,
308 gtk_tree_model_row_inserted (GTK_TREE_MODEL (self), path, iter);
312 rows_reordered_cb (GtkTreeModel *model,
318 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (self), path, NULL,
323 milk_task_model_set_auth (MilkTaskModel *model,
326 MilkTaskModelPrivate *priv;
328 g_return_if_fail (model);
329 g_return_if_fail (MILK_IS_TASK_MODEL (model));
330 g_return_if_fail (auth);
331 g_return_if_fail (MILK_IS_AUTH (auth));
333 priv = MILK_TASK_MODEL_PRIVATE (model);
336 g_object_unref (priv->auth);
338 priv->auth = g_object_ref (auth);
340 if (milk_auth_get_state (priv->auth) == MILK_AUTH_STATE_CONNECTED) {
341 populate_model (model);
343 g_signal_connect (priv->auth, "notify::state",
344 G_CALLBACK (auth_notify_cb), model);
349 milk_task_model_get_property (GObject *object,
354 MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (object);
359 g_value_set_object (value, priv->auth);
363 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
369 milk_task_model_set_property (GObject *object,
377 milk_task_model_set_auth (MILK_TASK_MODEL (object),
378 g_value_get_object (value));
382 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
388 milk_task_model_dispose (GObject *object)
390 MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (object);
393 g_object_unref (priv->auth);
397 g_signal_handlers_disconnect_by_func (priv->store, row_changed_cb,
399 g_signal_handlers_disconnect_by_func (priv->store, row_deleted_cb,
401 g_signal_handlers_disconnect_by_func (priv->store, row_inserted_cb,
403 g_signal_handlers_disconnect_by_func (priv->store, rows_reordered_cb,
407 g_object_unref (priv->store);
411 G_OBJECT_CLASS (milk_task_model_parent_class)->dispose (object);
415 milk_task_model_class_init (MilkTaskModelClass *klass)
417 GObjectClass *object_class = G_OBJECT_CLASS (klass);
419 g_type_class_add_private (klass, sizeof (MilkTaskModelPrivate));
421 object_class->get_property = milk_task_model_get_property;
422 object_class->set_property = milk_task_model_set_property;
423 object_class->dispose = milk_task_model_dispose;
425 g_object_class_install_property
430 "Authentication proxy",
431 "Remember The Milk authentication proxy.",
433 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
434 G_PARAM_STATIC_STRINGS));
438 milk_task_model_init (MilkTaskModel *self)
440 MilkTaskModelPrivate *priv;
442 self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (
443 self, MILK_TYPE_TASK_MODEL, MilkTaskModelPrivate);
445 priv->store = gtk_list_store_new (
446 MILK_TASK_MODEL_N_COLUMNS, MILK_TYPE_TASK);
448 g_signal_connect (priv->store, "row-changed",
449 G_CALLBACK (row_changed_cb), self);
451 g_signal_connect (priv->store, "row-deleted",
452 G_CALLBACK (row_deleted_cb), self);
454 g_signal_connect (priv->store, "row-inserted",
455 G_CALLBACK (row_inserted_cb), self);
457 g_signal_connect (priv->store, "rows-reordered",
458 G_CALLBACK (rows_reordered_cb), self);
462 milk_task_model_tree_model_init (GtkTreeModelIface *iface)
464 iface->get_flags = milk_task_model_get_flags;
465 iface->get_n_columns = milk_task_model_get_n_columns;
466 iface->get_column_type = milk_task_model_get_column_type;
467 iface->get_iter = milk_task_model_get_iter;
468 iface->get_path = milk_task_model_get_path;
469 iface->get_value = milk_task_model_get_value;
470 iface->iter_next = milk_task_model_iter_next;
471 iface->iter_children = milk_task_model_iter_children;
472 iface->iter_has_child = milk_task_model_iter_has_child;
473 iface->iter_n_children = milk_task_model_iter_n_children;
474 iface->iter_nth_child = milk_task_model_iter_nth_child;
475 iface->iter_parent = milk_task_model_iter_parent;
479 milk_task_model_new (MilkAuth *auth)
481 return g_object_new (MILK_TYPE_TASK_MODEL, "auth", auth, NULL);