From a3cf6da4bd41ce528ddcf11c53691ff1a880adbe Mon Sep 17 00:00:00 2001 From: Travis Reitter Date: Mon, 16 Nov 2009 22:33:50 -0800 Subject: [PATCH] Update the task model with tasks from the server. --- src/milk-auth.c | 119 +++++++++++++++++++++++++++------------------- src/milk-auth.h | 14 ++++-- src/milk-task-model.c | 125 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 181 insertions(+), 77 deletions(-) diff --git a/src/milk-auth.c b/src/milk-auth.c index 4c60455..aa075fe 100644 --- a/src/milk-auth.c +++ b/src/milk-auth.c @@ -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 diff --git a/src/milk-auth.h b/src/milk-auth.h index 4508a84..d3a2046 100644 --- a/src/milk-auth.h +++ b/src/milk-auth.h @@ -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 */ diff --git a/src/milk-task-model.c b/src/milk-task-model.c index 9a69c6a..9e20765 100644 --- a/src/milk-task-model.c +++ b/src/milk-task-model.c @@ -23,6 +23,7 @@ #include #include #include +#include #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 -- 1.7.9.5