Update the task model with tasks from the server.
authorTravis Reitter <treitter@torizo.(none)>
Tue, 17 Nov 2009 06:33:50 +0000 (22:33 -0800)
committerTravis Reitter <treitter@gmail.com>
Fri, 4 Dec 2009 06:01:13 +0000 (22:01 -0800)
src/milk-auth.c
src/milk-auth.h
src/milk-task-model.c

index 4c60455..aa075fe 100644 (file)
@@ -44,16 +44,28 @@ struct _MilkAuthPrivate
         char *api_key;
         char *shared_secret;
         char *frob;
+        MilkAuthState state;
 };
 
 enum {
         PROP_API_KEY = 1,
         PROP_SHARED_SECRET,
+        PROP_STATE,
 };
 
 static MilkAuth *default_auth = NULL;
 
 
+MilkAuthState
+milk_auth_get_state (MilkAuth *auth)
+{
+        g_return_val_if_fail (auth, MILK_AUTH_STATE_DISCONNECTED);
+        g_return_val_if_fail (MILK_IS_AUTH (auth),
+                        MILK_AUTH_STATE_DISCONNECTED);
+
+        return MILK_AUTH_PRIVATE (auth)->state;
+}
+
 static void
 milk_auth_get_property (GObject    *object,
                         guint       property_id,
@@ -72,6 +84,10 @@ milk_auth_get_property (GObject    *object,
                         g_value_set_string (value, priv->shared_secret);
                 break;
 
+                case PROP_STATE:
+                        g_value_set_int (value, priv->state);
+                break;
+
                 default:
                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
                                         pspec);
@@ -100,6 +116,10 @@ milk_auth_set_property (GObject      *object,
                         priv->shared_secret = g_value_dup_string (value);
                 break;
 
+                case PROP_STATE:
+                        priv->state = g_value_get_int (value);
+                break;
+
                 default:
                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
                                         pspec);
@@ -113,18 +133,19 @@ auth_response_cb (GtkWidget *dialog,
 
 {
         MilkAuthPrivate *priv;
-
         GError *error = NULL;
         gchar *auth_token;
         gchar *username;
+        MilkAuthState previous_state;
 
         priv = MILK_AUTH_PRIVATE (auth);
 
+        previous_state = priv->state;
         auth_token = rtm_glib_auth_get_token (priv->rtm_glib, priv->frob,
                         &error);
         if (error != NULL) {
                 g_error ("%s", rtm_error_get_message (error));
-                goto auth_response_cb_OUT;
+                goto auth_response_cb_error_OUT;
         }
 
         if (!rtm_glib_auth_check_token (priv->rtm_glib, auth_token, NULL)) {
@@ -133,7 +154,7 @@ auth_response_cb (GtkWidget *dialog,
         }
         if (error != NULL) {
                 g_error ("%s", rtm_error_get_message (error));
-                goto auth_response_cb_OUT;
+                goto auth_response_cb_error_OUT;
         }
         username = rtm_glib_test_login (priv->rtm_glib, auth_token, &error);
 
@@ -141,68 +162,59 @@ auth_response_cb (GtkWidget *dialog,
 
         if (error != NULL) {
                 g_error ("%s", rtm_error_get_message (error));
-                goto auth_response_cb_OUT;
+                goto auth_response_cb_error_OUT;
         }
 
-        /* FIXME: work this in where appropriate */
-#if 0
-        glist = rtm_glib_tasks_get_list (priv->rtm_glib, NULL, NULL, NULL, &error);
-        if (error != NULL) {
-                g_error ("%s", rtm_error_get_message (error));
-        }
-        for (item = glist; item; item = g_list_next (item)) {
-                task = (RtmTask *) item->data;
-                g_print ("%s", rtm_task_to_string (task));
-        }
-        g_list_free (glist);
+        priv->state = MILK_AUTH_STATE_CONNECTED;
+        goto auth_response_cb_OUT;
 
-        glist = rtm_glib_lists_get_list (priv->rtm_glib, &error);
-        if (error != NULL) {
-                g_error ("%s", rtm_error_get_message (error));
-                goto auth_response_cb_OUT;
-        }
-        for (item = glist; item; item = g_list_next (item)) {
-                rtm_list = (RtmList *) item->data;
-                if (g_strcmp0 (rtm_list_get_name (rtm_list), "Sent") == 0) {
-                        list_id_sent = rtm_list_get_id (rtm_list);
-                }
-                g_print ("%s", rtm_list_to_string (rtm_list));
-        }
-        g_list_free (glist);
+auth_response_cb_error_OUT:
+        priv->state = MILK_AUTH_STATE_DISCONNECTED;
 
-        timeline = rtm_glib_timelines_create (priv->rtm_glib, &error);
-        if (error != NULL) {
-                g_error ("%s", rtm_error_get_message (error));
-        }
-        g_print ("timeline: %s", timeline);
+auth_response_cb_OUT:
+        if (priv->state != previous_state)
+                g_object_notify (G_OBJECT (auth), "state");
 
-        task = rtm_glib_tasks_add (priv->rtm_glib, timeline, "test-rtm-glib", NULL, FALSE, &error);
+        gtk_widget_destroy (dialog);
+}
+
+GList *
+milk_auth_get_tasks (MilkAuth *auth)
+{
+        MilkAuthPrivate *priv;
+        GError *error = NULL;
+        GList *rtm_tasks;
+
+        g_return_val_if_fail (auth, NULL);
+        g_return_val_if_fail (MILK_IS_AUTH (auth), NULL);
+        g_return_val_if_fail (
+                        milk_auth_get_state (auth) == MILK_AUTH_STATE_CONNECTED,
+                        NULL);
+
+        priv = MILK_AUTH_PRIVATE (auth);
+
+        /* FIXME: cache this */
+        rtm_tasks = rtm_glib_tasks_get_list (priv->rtm_glib, NULL, NULL, NULL,
+                        &error);
         if (error != NULL) {
                 g_error ("%s", rtm_error_get_message (error));
-                goto auth_response_cb_OUT;
-        }
-        if (task != NULL) {
-                g_print ("First task added! task_id: %s\n", rtm_task_get_id (task));
-        } else {
-                g_print ("First task NOT added!\n");
-                goto auth_response_cb_OUT;
+                return NULL;
         }
-
-#endif
-
-auth_response_cb_OUT:
-        gtk_widget_destroy (dialog);
+        
+        return rtm_tasks;
 }
 
 void
 milk_auth_log_in (MilkAuth *auth)
 {
         MilkAuthPrivate *priv;
-
         GError *error = NULL;
         gchar *url;
         GtkDialog *dialog;
 
+        g_return_if_fail (auth);
+        g_return_if_fail (MILK_IS_AUTH (auth));
+
         priv = MILK_AUTH_PRIVATE (auth);
 
         if (rtm_glib_test_echo (priv->rtm_glib, &error)) {
@@ -237,7 +249,6 @@ milk_auth_log_in (MilkAuth *auth)
                         auth);
 }
 
-
 static void
 milk_auth_constructed (GObject *object)
 {
@@ -292,6 +303,18 @@ milk_auth_class_init (MilkAuthClass *klass)
                           RTM_SHARED_SECRET,
                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                           G_PARAM_STATIC_STRINGS));
+
+        g_object_class_install_property
+                (object_class,
+                 PROP_STATE,
+                 g_param_spec_int
+                         ("state",
+                          "Authentication state",
+                          "Authentication/connection state with the server.",
+                          0, (NUM_MILK_AUTH_STATES-1),
+                          MILK_AUTH_STATE_DISCONNECTED,
+                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
 }
 
 static void
index 4508a84..d3a2046 100644 (file)
@@ -59,11 +59,19 @@ struct _MilkAuthClass
         GObjectClass parent_class;
 };
 
-GType milk_auth_get_type (void);
+typedef enum {
+        MILK_AUTH_STATE_DISCONNECTED,
+        MILK_AUTH_STATE_CONNECTED,
+        MILK_AUTH_STATE_SERVICE_UNAVAILABLE,
+        NUM_MILK_AUTH_STATES,
+} MilkAuthState;
 
+GType milk_auth_get_type (void);
 
-MilkAuth* milk_auth_get_default (void);
 
-void milk_auth_log_in (MilkAuth* auth) ;
+MilkAuth*     milk_auth_get_default (void);
+void          milk_auth_log_in      (MilkAuth* auth);
+MilkAuthState milk_auth_get_state   (MilkAuth* auth);
+GList*        milk_auth_get_tasks   (MilkAuth* auth);
 
 #endif /* _MILK_AUTH_H */
index 9a69c6a..9e20765 100644 (file)
@@ -23,6 +23,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <hildon/hildon.h>
+#include <rtm-glib/rtm-glib.h>
 
 #include "milk-task-model.h"
 #include "milk-auth.h"
@@ -232,34 +233,36 @@ milk_task_model_iter_parent (GtkTreeModel *model,
 static void
 populate_model (MilkTaskModel *model)
 {
-        typedef struct {
-                const char *id;
-                const char *title;
-                gint priority;
-        } MilkTask_args;
-
-        /* FIXME: don't hard-code this */
-        static MilkTask_args tasks[] = {
-                { "0", "Walk the dog", 1},
-                { "2", "Make a Maemo 5 RTM client", 1},
-                { "6", "Stand on one foot", 3},
-                { "9", "Pick up some DVX ('cause it's so crisp)", 2},
-                { "5", "Finalize Halloween costume", 3},
-        };
-
         MilkTaskModelPrivate *priv = MILK_TASK_MODEL_PRIVATE (model);
+        GList *rtm_tasks;
+        GList *l;
         GtkTreeIter iter;
-        gint i;
 
-        /* FIXME: remove all existing rows */
-        /* FIXME: use the tasks from the auth */
+        gtk_list_store_clear (priv->store);
+
+        /* FIXME: poll for new tasks periodically -- there's rtm-glib API to
+         * optimize just fetching the latest ones */
+        rtm_tasks = milk_auth_get_tasks (priv->auth);
 
         /* Populate model */
-        for (i = 0; i < G_N_ELEMENTS (tasks); i++) {
+        for (l = rtm_tasks; l; l = g_list_delete_link (l, l)) {
+                RtmTask *rtm_task;
                 MilkTask *task;
 
-                task = milk_task_new (
-                                tasks[i].id, tasks[i].title, tasks[i].priority);
+                rtm_task = RTM_TASK (l->data);
+
+                /* XXX: if possible, avoid fetching these in the first place */
+                /* Skip tasks deleted or completed. */
+                if (rtm_task_get_completed_date (rtm_task) ||
+                    rtm_task_get_deleted_date (rtm_task)) {
+                        continue;
+                }
+
+                task = milk_task_new (rtm_task_get_id (rtm_task),
+                                rtm_task_get_name (rtm_task),
+                                /* FIXME: switch priority from int to string */
+                                g_ascii_strtod (rtm_task_get_priority
+                                                (rtm_task), NULL));
 
                 gtk_list_store_append (priv->store, &iter);
                 gtk_list_store_set (
@@ -269,6 +272,53 @@ populate_model (MilkTaskModel *model)
         }
 }
 
+static void
+auth_notify_cb (MilkAuth      *auth,
+                GParamSpec    *spec,
+                MilkTaskModel *model)
+{
+        if (milk_auth_get_state (auth) == MILK_AUTH_STATE_CONNECTED) {
+                populate_model (model);
+        }
+}
+
+static void
+row_changed_cb (GtkTreeModel  *model,
+                GtkTreePath   *path,
+                GtkTreeIter   *iter,
+                MilkTaskModel *self)
+{
+        gtk_tree_model_row_changed (GTK_TREE_MODEL (self), path, iter);
+}
+
+static void
+row_deleted_cb (GtkTreeModel  *model,
+                GtkTreePath   *path,
+                MilkTaskModel *self)
+{
+        gtk_tree_model_row_deleted (GTK_TREE_MODEL (self), path);
+}
+
+static void
+row_inserted_cb (GtkTreeModel  *model,
+                 GtkTreePath   *path,
+                 GtkTreeIter   *iter,
+                 MilkTaskModel *self)
+{
+        gtk_tree_model_row_inserted (GTK_TREE_MODEL (self), path, iter);
+}
+
+static void
+rows_reordered_cb (GtkTreeModel  *model,
+                   GtkTreePath   *path,
+                   GtkTreeIter   *iter,
+                   gint          *new_order,
+                   MilkTaskModel *self)
+{
+        gtk_tree_model_rows_reordered (GTK_TREE_MODEL (self), path, NULL,
+                        new_order);
+}
+
 void
 milk_task_model_set_auth (MilkTaskModel *model,
                           MilkAuth      *auth)
@@ -282,15 +332,17 @@ milk_task_model_set_auth (MilkTaskModel *model,
 
         priv = MILK_TASK_MODEL_PRIVATE (model);
 
-        /* FIXME: cut this */
-        g_debug ("authorizing and populating model with %p", auth);
-
         if (priv->auth) {
                 g_object_unref (priv->auth);
-                priv->auth = g_object_ref (auth);
         }
+        priv->auth = g_object_ref (auth);
 
-        populate_model (model);
+        if (milk_auth_get_state (priv->auth) == MILK_AUTH_STATE_CONNECTED) {
+                populate_model (model);
+        } else {
+                g_signal_connect (priv->auth, "notify::state",
+                                G_CALLBACK (auth_notify_cb), model);
+        }
 }
 
 static void
@@ -342,6 +394,15 @@ milk_task_model_dispose (GObject *object)
                 priv->auth = NULL;
         }
 
+        g_signal_handlers_disconnect_by_func (priv->store, row_changed_cb,
+                        object);
+        g_signal_handlers_disconnect_by_func (priv->store, row_deleted_cb,
+                        object);
+        g_signal_handlers_disconnect_by_func (priv->store, row_inserted_cb,
+                        object);
+        g_signal_handlers_disconnect_by_func (priv->store, rows_reordered_cb,
+                        object);
+
         if (priv->store) {
                 g_object_unref (priv->store);
                 priv->store = NULL;
@@ -383,6 +444,18 @@ milk_task_model_init (MilkTaskModel *self)
 
         priv->store = gtk_list_store_new (
                         MILK_TASK_MODEL_N_COLUMNS, MILK_TYPE_TASK);
+
+        g_signal_connect (priv->store, "row-changed",
+                        G_CALLBACK (row_changed_cb), self);
+
+        g_signal_connect (priv->store, "row-deleted",
+                        G_CALLBACK (row_deleted_cb), self);
+
+        g_signal_connect (priv->store, "row-inserted",
+                        G_CALLBACK (row_inserted_cb), self);
+
+        g_signal_connect (priv->store, "rows-reordered",
+                        G_CALLBACK (rows_reordered_cb), self);
 }
 
 static void