Make priority sorting work
authorTravis Reitter <treitter@gmail.com>
Sun, 28 Mar 2010 17:05:53 +0000 (10:05 -0700)
committerTravis Reitter <treitter@gmail.com>
Sun, 28 Mar 2010 17:05:54 +0000 (10:05 -0700)
src/milk-cache.c
src/milk-main-window.c
src/milk-task-model.c

index af0c7cb..24eebff 100644 (file)
@@ -247,8 +247,9 @@ db_get_tasks_active (sqlite3 *db)
         char *statement;
         GList *tasks = NULL;
 
+        /* FIXME: get the priority */
         statement = g_strdup_printf ("SELECT "
-                        "task_id, name, due_date FROM tasks "
+                        "task_id, name, priority, due_date FROM tasks "
                         "WHERE "
                                 "delete_date IS NULL AND "
                                 "complete_date IS NULL"
@@ -277,8 +278,10 @@ db_get_tasks_active (sqlite3 *db)
 
                 rtm_task_set_id   (task, (char*)sqlite3_column_text (query, 0));
                 rtm_task_set_name (task, (char*)sqlite3_column_text (query, 1));
+                rtm_task_set_priority (task,
+                                (char*)sqlite3_column_text (query, 2));
 
-                if (db_date_column_to_timeval (query, 2, &timeval))
+                if (db_date_column_to_timeval (query, 3, &timeval))
                         rtm_task_set_due_date (task, &timeval);
 
                 tasks = g_list_prepend (tasks, task);
@@ -384,6 +387,7 @@ db_update_schema_0_to_1 (sqlite3 *db)
                         "       ON DELETE CASCADE,"
                         "name TEXT NOT NULL,"
                         "local_changes BOOLEAN DEFAULT 0,"
+                        "priority TEXT,"
                         "due_date TEXT,"
                         "delete_date TEXT,"
                         "complete_date TEXT,"
@@ -542,6 +546,7 @@ db_insert_or_update_local_task (sqlite3    *db,
         GTimeVal *due, *deleted, *completed;
         char *name_str, *due_str, *deleted_str, *completed_str;
         const char *task_id;
+        const char *priority;
         const char *list_id;
         const char *taskseries_id;
         gint status;
@@ -591,6 +596,9 @@ db_insert_or_update_local_task (sqlite3    *db,
         task_id = rtm_task_get_id (task);
         task_id = task_id ? task_id : "NULL";
 
+        priority = rtm_task_get_priority (task);
+        priority = priority ? priority : "N";
+
         list_id = rtm_task_get_list_id (task);
         list_id = list_id ? list_id : "NULL";
 
@@ -610,14 +618,15 @@ db_insert_or_update_local_task (sqlite3    *db,
 
         /* all but the name fields are already quoted or NULL */
         statement = g_strdup_printf ("INSERT OR REPLACE INTO tasks "
-                        "('local_id','task_id','name','due_date','delete_date',"
-                        "'complete_date','list_id','taskseries_id',"
-                        "'local_changes') "
-                        "VALUES (%s, %s, '%s', %s, %s, %s, %s, %s, %d)"
+                        "('local_id','task_id','name','priority','due_date',"
+                        "'delete_date','complete_date','list_id',"
+                        "'taskseries_id','local_changes') "
+                        "VALUES (%s, %s, '%s', '%s', %s, %s, %s, %s, %s, %d)"
                         ";",
                         local_id,
                         task_id,
                         name_str,
+                        priority,
                         due_str,
                         deleted_str,
                         completed_str,
@@ -800,6 +809,7 @@ db_insert_or_update_task (sqlite3  *db,
 
         success &= db_insert_or_update_local_task (db, task,
                         local_id_formatted, local_changes);
+
         g_free (local_id_formatted);
 
         return success;
@@ -1212,7 +1222,10 @@ cache_receive_changes_ERROR:
 static gboolean
 cache_send_receive_changes (MilkCache *cache)
 {
-        return cache_send_changes (cache) && cache_receive_changes (cache);
+        cache_send_changes (cache);
+        cache_receive_changes (cache);
+
+        return TRUE;
 }
 
 static void
@@ -1223,9 +1236,6 @@ restart_send_receive_poll (MilkCache *cache,
 
         priv = MILK_CACHE_PRIVATE (cache);
 
-        /* FIXME: cut this */
-        g_debug ("restarting the send/receive poll");
-
         if (priv->update_id)
                 g_source_remove (priv->update_id);
 
index abf9ec7..9754c45 100644 (file)
@@ -369,11 +369,47 @@ create_menu (gpointer user_data)
 }
 
 static void
-contact_column_render_func (GtkCellLayout   *cell_layout,
-                            GtkCellRenderer *renderer,
-                            GtkTreeModel    *model,
-                            GtkTreeIter     *iter,
-                            gpointer         user_data)
+priority_column_render_func (GtkCellLayout   *cell_layout,
+                             GtkCellRenderer *renderer,
+                             GtkTreeModel    *model,
+                             GtkTreeIter     *iter,
+                             gpointer         user_data)
+{
+        RtmTask *task;
+        const char *priority;
+        GdkColor color = {};
+        gboolean color_set = TRUE;
+
+        gtk_tree_model_get (
+                        model, iter, MILK_TASK_MODEL_COLUMN_TASK, &task, -1);
+
+        priority = rtm_task_get_priority (task);
+
+        if (FALSE) {
+        } else if (!g_strcmp0 (priority, "1")) {
+                gdk_color_parse ("#ea5200", &color);
+        } else if (!g_strcmp0 (priority, "2")) {
+                gdk_color_parse ("#0060bf", &color);
+        } else if (!g_strcmp0 (priority, "3")) {
+                gdk_color_parse ("#359aff", &color);
+        } else {
+                color_set = FALSE;
+        }
+
+        g_object_set (renderer,
+                        "cell-background-gdk", color_set ? &color : NULL,
+                        "cell-background-set", color_set,
+                        NULL);
+
+        g_object_unref (task);
+}
+
+static void
+name_column_render_func (GtkCellLayout   *cell_layout,
+                         GtkCellRenderer *renderer,
+                         GtkTreeModel    *model,
+                         GtkTreeIter     *iter,
+                         gpointer         user_data)
 {
         RtmTask *task;
 
@@ -432,18 +468,32 @@ milk_main_window_constructed (GObject* object)
         model = GTK_TREE_MODEL (milk_task_model_new ());
         w = hildon_touch_selector_new ();
 
+        col = hildon_touch_selector_append_column (
+                        HILDON_TOUCH_SELECTOR (w), model, NULL, NULL);
+
         renderer = gtk_cell_renderer_text_new ();
         g_object_set (renderer,
-                        "ellipsize", PANGO_ELLIPSIZE_END,
+                        "width", HILDON_ICON_PIXEL_SIZE_XSMALL,
+                        "width-chars", 1,
                         NULL);
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (col), renderer, FALSE);
+        gtk_cell_layout_set_cell_data_func (
+                        GTK_CELL_LAYOUT (col), renderer,
+                        (GtkCellLayoutDataFunc) priority_column_render_func,
+                        self, NULL);
 
-        col = hildon_touch_selector_append_column (
-                        HILDON_TOUCH_SELECTOR (w), model, NULL, NULL);
+        renderer = gtk_cell_renderer_text_new ();
+        g_object_set (renderer,
+                        "ellipsize", PANGO_ELLIPSIZE_END,
+                        "alignment", PANGO_ALIGN_LEFT,
+                        "xpad", HILDON_MARGIN_DEFAULT,
+                        NULL);
         gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (col), renderer, TRUE);
         gtk_cell_layout_set_cell_data_func (
                         GTK_CELL_LAYOUT (col), renderer,
-                        (GtkCellLayoutDataFunc) contact_column_render_func,
+                        (GtkCellLayoutDataFunc) name_column_render_func,
                         self, NULL);
+
         g_object_unref (model);
 
         hildon_touch_selector_set_column_selection_mode (
index cb24974..981be2a 100644 (file)
 
 static void
 milk_task_model_tree_model_init (GtkTreeModelIface *iface);
+static void
+milk_task_model_tree_sortable_init (GtkTreeSortableIface *iface);
 
-G_DEFINE_TYPE_EXTENDED (MilkTaskModel,
-                        milk_task_model,
-                        G_TYPE_OBJECT,
-                        0,
-                        G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
-                                               milk_task_model_tree_model_init));
+G_DEFINE_TYPE_WITH_CODE (MilkTaskModel,
+                         milk_task_model,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
+                                 milk_task_model_tree_model_init)
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
+                                 milk_task_model_tree_sortable_init));
 
 /* less expensive than G_TYPE_INSTANCE_GET_PRIVATE */
 #define MILK_TASK_MODEL_PRIVATE(o) ((MILK_TASK_MODEL ((o)))->priv)
@@ -232,6 +235,59 @@ milk_task_model_iter_parent (GtkTreeModel *model,
                         GTK_TREE_MODEL (priv->store), iter, child);
 }
 
+static gboolean
+milk_task_model_get_sort_column_id (GtkTreeSortable *sortable,
+                                    gint            *column_id,
+                                    GtkSortType     *order)
+{
+        MilkTaskModel *model;
+        MilkTaskModelPrivate *priv;
+
+        g_return_if_fail (MILK_IS_TASK_MODEL (sortable));
+
+        model = MILK_TASK_MODEL (model);
+        priv = MILK_TASK_MODEL_PRIVATE (model);
+
+        return gtk_tree_sortable_get_sort_column_id (
+                        GTK_TREE_SORTABLE (priv->store), column_id, order);
+}
+
+static gboolean
+milk_task_model_set_sort_column_id (GtkTreeSortable *sortable,
+                                    gint             column_id,
+                                    GtkSortType      order)
+{
+        MilkTaskModel *model;
+        MilkTaskModelPrivate *priv;
+
+        g_return_if_fail (MILK_IS_TASK_MODEL (sortable));
+
+        model = MILK_TASK_MODEL (model);
+        priv = MILK_TASK_MODEL_PRIVATE (model);
+
+        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->store),
+                        column_id, order);
+}
+
+static void
+milk_task_model_set_default_sort_func (GtkTreeSortable        *sortable,
+                                       GtkTreeIterCompareFunc  callback,
+                                       gpointer                user_data,
+                                       GDestroyNotify          destroy_data)
+{
+        MilkTaskModel *model;
+        MilkTaskModelPrivate *priv;
+
+        g_return_if_fail (MILK_IS_TASK_MODEL (sortable));
+
+        model = MILK_TASK_MODEL (model);
+        priv = MILK_TASK_MODEL_PRIVATE (model);
+
+        gtk_tree_sortable_set_default_sort_func (
+                        GTK_TREE_SORTABLE (priv->store), callback, user_data,
+                        destroy_data);
+}
+
 typedef gchar* (*RtmTaskAttrFunc) (RtmTask*);
 
 static gboolean
@@ -324,6 +380,48 @@ rows_reordered_cb (GtkTreeModel  *model,
                         new_order);
 }
 
+static gint
+model_priority_sort_func (GtkTreeModel *model,
+                          GtkTreeIter  *a,
+                          GtkTreeIter  *b,
+                          gpointer      user_data)
+{
+        gint retval;
+        RtmTask *task_a, *task_b;
+        const char *priority_str_a, *priority_str_b;
+        gint64 priority_a, priority_b;
+        const char *name_a, *name_b;
+
+        gtk_tree_model_get (model, a,
+                        MILK_TASK_MODEL_COLUMN_TASK, &task_a,
+                        -1);
+
+        gtk_tree_model_get (model, b,
+                        MILK_TASK_MODEL_COLUMN_TASK, &task_b,
+                        -1);
+
+        priority_str_a = rtm_task_get_priority (task_a);
+        priority_str_b = rtm_task_get_priority (task_b);
+
+        /* these will be assigned 0 if they're not the well-known priorites
+         * (1-3) */
+        priority_a = g_ascii_strtoll (priority_str_a, NULL, 10);
+        priority_b = g_ascii_strtoll (priority_str_b, NULL, 10);
+
+        priority_a = (priority_a <= 0) ? G_MAXINT : priority_a;
+        priority_b = (priority_b <= 0) ? G_MAXINT : priority_b;
+
+        retval = (priority_a - priority_b);
+        if (retval != 0)
+                return retval;
+
+        /* secondary sort, by name */
+        name_a = rtm_task_get_name (task_a);
+        name_b = rtm_task_get_name (task_b);
+
+        return g_utf8_collate (name_a, name_b);
+}
+
 static void
 cache_cleared_cb (MilkCache     *cache,
                   MilkTaskModel *model)
@@ -588,6 +686,16 @@ milk_task_model_init (MilkTaskModel *self)
         priv->store = gtk_list_store_new (
                         MILK_TASK_MODEL_N_COLUMNS, RTM_TYPE_TASK);
 
+        gtk_tree_sortable_set_default_sort_func (
+                        GTK_TREE_SORTABLE (priv->store),
+                        model_priority_sort_func, g_object_ref (self),
+                        g_object_unref);
+
+        gtk_tree_sortable_set_sort_column_id (
+                        GTK_TREE_SORTABLE (priv->store),
+                        GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+                        GTK_SORT_ASCENDING);
+
         g_signal_connect (priv->store, "row-changed",
                         G_CALLBACK (row_changed_cb), self);
 
@@ -618,6 +726,14 @@ milk_task_model_tree_model_init (GtkTreeModelIface *iface)
         iface->iter_parent     = milk_task_model_iter_parent;
 }
 
+static void
+milk_task_model_tree_sortable_init (GtkTreeSortableIface *iface)
+{
+        iface->get_sort_column_id    = milk_task_model_get_sort_column_id;
+        iface->set_sort_column_id    = milk_task_model_set_sort_column_id;
+        iface->set_default_sort_func = milk_task_model_set_default_sort_func;
+}
+
 MilkTaskModel*
 milk_task_model_new ()
 {