[rhythmbox] add a task list controller



commit 3df446a27ea6b23d6c6650440d313815d5b3ec9e
Author: Jonathan Matthew <jonathan d14n org>
Date:   Tue May 14 22:00:27 2013 +1000

    add a task list controller
    
    This contains the (minimal) logic for updating the task list model.

 bindings/gi/Makefile.am |    2 +
 shell/Makefile.am       |    2 +
 shell/rb-task-list.c    |  212 +++++++++++++++++++++++++++++++++++++++++++++++
 shell/rb-task-list.h    |   58 +++++++++++++
 4 files changed, 274 insertions(+), 0 deletions(-)
---
diff --git a/bindings/gi/Makefile.am b/bindings/gi/Makefile.am
index 324bec0..bf5b19c 100644
--- a/bindings/gi/Makefile.am
+++ b/bindings/gi/Makefile.am
@@ -101,6 +101,8 @@ rb_introspection_sources = \
                shell/rb-history.c \
                shell/rb-play-order.h \
                shell/rb-play-order.c \
+               shell/rb-task-list.h \
+               shell/rb-task-list.c \
                shell/rb-track-transfer-batch.c \
                shell/rb-track-transfer-batch.h \
                shell/rb-track-transfer-queue.c \
diff --git a/shell/Makefile.am b/shell/Makefile.am
index be308bc..65a702d 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -96,6 +96,8 @@ librhythmbox_core_la_SOURCES =                                \
        rb-shell-preferences.h                          \
        rb-statusbar.c                                  \
        rb-statusbar.h                                  \
+       rb-task-list.c                                  \
+       rb-task-list.h                                  \
        rb-track-transfer-batch.c                       \
        rb-track-transfer-queue.c
 
diff --git a/shell/rb-task-list.c b/shell/rb-task-list.c
new file mode 100644
index 0000000..eccca5e
--- /dev/null
+++ b/shell/rb-task-list.c
@@ -0,0 +1,212 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ *  Copyright (C) 2013 Jonathan Matthew <jonathan d14n org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#include <config.h>
+
+#include <shell/rb-task-list.h>
+
+/* leave completed and cancelled tasks in the list for a while */
+#define        FINISHED_EXPIRE_TIME            2
+
+enum {
+       PROP_0,
+       PROP_MODEL
+};
+
+typedef struct {
+       RBTaskList *list;
+       RBTaskProgress *task;
+       gulong expiry_id;
+} TaskExpiry;
+
+struct _RBTaskList
+{
+       GObject parent;
+
+       RBListModel *model;
+       GList *expiring;
+};
+
+struct _RBTaskListClass
+{
+       GObjectClass parent;
+};
+
+G_DEFINE_TYPE (RBTaskList, rb_task_list, G_TYPE_OBJECT);
+
+static void rb_task_list_class_init (RBTaskListClass *klass);
+static void rb_task_list_init (RBTaskList *list);
+
+
+
+static void
+impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+       RBTaskList *list = RB_TASK_LIST (object);
+       
+       switch (prop_id) {
+       case PROP_MODEL:
+               g_value_set_object (value, list->model);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+       /*RBTaskList *list = RB_TASK_LIST (object);*/
+       
+       switch (prop_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+impl_dispose (GObject *object)
+{
+       RBTaskList *list = RB_TASK_LIST (object);
+       
+       g_clear_object (&list->model);
+
+       G_OBJECT_CLASS (rb_task_list_parent_class)->dispose (object);
+}
+
+static void
+unref_task (gpointer element)
+{
+       gpointer item = *(gpointer *)element;
+       g_object_unref (item);
+}
+
+static void
+rb_task_list_init (RBTaskList *list)
+{
+       list->model = rb_list_model_new (G_TYPE_OBJECT, unref_task);
+}
+
+static void
+rb_task_list_class_init (RBTaskListClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = impl_dispose;
+       object_class->set_property = impl_set_property;
+       object_class->get_property = impl_get_property;
+
+       g_object_class_install_property (object_class,
+                                        PROP_MODEL,
+                                        g_param_spec_object ("model",
+                                                             "model",
+                                                             "model",
+                                                             RB_TYPE_LIST_MODEL,
+                                                             G_PARAM_READABLE));
+}
+
+static gboolean
+task_expired (TaskExpiry *expiry)
+{
+       rb_list_model_remove_item (expiry->list->model, expiry->task);
+       expiry->list->expiring = g_list_remove (expiry->list->expiring, expiry);
+       return FALSE;
+}
+
+static void
+expire_task (RBTaskList *list, RBTaskProgress *task, gint seconds)
+{
+       TaskExpiry *expiry;
+       GList *l;
+
+       /* remove any existing expiry for this task */
+       for (l = list->expiring; l != NULL; l = l->next) {
+               expiry = l->data;
+               if (expiry->task == task) {
+                       expiry->list->expiring = g_list_remove (expiry->list->expiring, expiry);
+                       g_source_remove (expiry->expiry_id);
+                       break;
+               }
+       }
+
+       expiry = g_new0 (TaskExpiry, 1);
+       expiry->task = task;
+       expiry->list = list;
+       expiry->expiry_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
+                                                       seconds,
+                                                       (GSourceFunc)task_expired,
+                                                       expiry,
+                                                       (GDestroyNotify) g_free);
+       list->expiring = g_list_append (list->expiring, expiry);
+}
+
+static void
+task_outcome_notify_cb (GObject *object, GParamSpec *pspec, RBTaskList *list)
+{
+       RBTaskOutcome outcome;
+       g_object_get (object, "task-outcome", &outcome, NULL);
+       switch (outcome) {
+       case RB_TASK_OUTCOME_COMPLETE:
+       case RB_TASK_OUTCOME_CANCELLED:
+               expire_task (list, RB_TASK_PROGRESS (object), FINISHED_EXPIRE_TIME);
+               break;
+
+       case RB_TASK_OUTCOME_NONE:
+               break;
+
+       default:
+               g_assert_not_reached ();
+       }
+}
+
+void
+rb_task_list_add_task (RBTaskList *list, RBTaskProgress *task)
+{
+       g_signal_connect (task, "notify::task-outcome", G_CALLBACK (task_outcome_notify_cb), list);
+       rb_list_model_append (list->model, g_object_ref (task));
+}
+
+void
+rb_task_list_remove_task (RBTaskList *list, RBTaskProgress *task)
+{
+       rb_list_model_remove_item (list->model, task);
+}
+
+RBTaskList *
+rb_task_list_new ()
+{
+       return RB_TASK_LIST (g_object_new (RB_TYPE_TASK_LIST, NULL));
+}
+
+RBListModel *
+rb_task_list_get_model (RBTaskList *list)
+{
+       return list->model;
+}
diff --git a/shell/rb-task-list.h b/shell/rb-task-list.h
new file mode 100644
index 0000000..96abc92
--- /dev/null
+++ b/shell/rb-task-list.h
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 2013 Jonathan Matthew  <jonathan d14n org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#ifndef RB_TASK_LIST_H
+#define RB_TASK_LIST_H
+
+#include <lib/rb-list-model.h>
+#include <lib/rb-task-progress.h>
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_TASK_LIST         (rb_task_list_get_type ())
+#define RB_TASK_LIST(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_TASK_LIST, RBTaskList))
+#define RB_TASK_LIST_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_TASK_LIST, RBTaskListClass))
+#define RB_IS_TASK_LIST(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_TASK_LIST))
+#define RB_IS_TASK_LIST_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_TASK_LIST))
+#define RB_TASK_LIST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_TASK_LIST, RBTaskListClass))
+
+typedef struct _RBTaskList RBTaskList;
+typedef struct _RBTaskListClass RBTaskListClass;
+typedef struct _RBTaskListPrivate RBTaskListPrivate;
+
+GType          rb_task_list_get_type           (void);
+
+RBTaskList *   rb_task_list_new                (void);
+
+RBListModel *  rb_task_list_get_model          (RBTaskList *list);
+
+void           rb_task_list_add_task           (RBTaskList *list, RBTaskProgress *task);
+void           rb_task_list_remove_task        (RBTaskList *list, RBTaskProgress *task);
+
+G_END_DECLS
+
+#endif /* RB_TASK_LIST_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]