[rhythmbox] mtp: add thread task for folder creation



commit 8681fbf07afc816c90d3d31e3ebdf40de561b5c1
Author: Jonathan Matthew <jonathan d14n org>
Date:   Wed Jun 16 17:45:31 2010 +1000

    mtp: add thread task for folder creation
    
    Given a sequence of path name components, this locates or creates
    a corresponding folder on the device, then calls the callback with
    the folder ID.

 plugins/mtpdevice/rb-mtp-thread.c |   96 +++++++++++++++++++++++++++++++++++++
 plugins/mtpdevice/rb-mtp-thread.h |    8 +++
 2 files changed, 104 insertions(+), 0 deletions(-)
---
diff --git a/plugins/mtpdevice/rb-mtp-thread.c b/plugins/mtpdevice/rb-mtp-thread.c
index 3cfc29c..67d9d5b 100644
--- a/plugins/mtpdevice/rb-mtp-thread.c
+++ b/plugins/mtpdevice/rb-mtp-thread.c
@@ -48,6 +48,8 @@ typedef struct {
 		SET_DEVICE_NAME,
 		THREAD_CALLBACK,
 
+		CREATE_FOLDER,
+
 		ADD_TO_ALBUM,
 		REMOVE_FROM_ALBUM,
 		SET_ALBUM_IMAGE,
@@ -66,6 +68,7 @@ typedef struct {
 	char *filename;
 	GdkPixbuf *image;
 	char *name;
+	char **path;
 
 	gpointer callback;
 	gpointer user_data;
@@ -81,6 +84,8 @@ task_name (RBMtpThreadTask *task)
 	case SET_DEVICE_NAME:	return g_strdup_printf ("set device name to %s", task->name);
 	case THREAD_CALLBACK:	return g_strdup ("thread callback");
 
+	case CREATE_FOLDER:	return g_strdup_printf ("create folder %s", task->path[g_strv_length (task->path)-1]);
+
 	case ADD_TO_ALBUM:	return g_strdup_printf ("add track %u to album %s", task->track_id, task->album);
 	case REMOVE_FROM_ALBUM:	return g_strdup_printf ("remove track %u from album %s", task->track_id, task->album);
 	case SET_ALBUM_IMAGE:	return g_strdup_printf ("set image for album %s", task->album);
@@ -114,6 +119,7 @@ destroy_task (RBMtpThreadTask *task)
 	g_free (task->album);
 	g_free (task->filename);
 	g_free (task->name);
+	g_strfreev (task->path);
 
 	if (task->image) {
 		g_object_unref (task->image);
@@ -162,6 +168,77 @@ open_device (RBMtpThread *thread, RBMtpThreadTask *task)
 	cb (thread->device, task->user_data);
 }
 
+static void
+create_folder (RBMtpThread *thread, RBMtpThreadTask *task)
+{
+	RBMtpCreateFolderCallback cb = task->callback;
+	LIBMTP_folder_t *folders;
+	LIBMTP_folder_t *f;
+	LIBMTP_folder_t *target = NULL;
+	uint32_t folder_id;
+	uint32_t storage_id;
+	int i;
+
+	folders = LIBMTP_Get_Folder_List (thread->device);
+	if (folders == NULL) {
+		rb_debug ("unable to get folder list");
+		rb_mtp_thread_report_errors (thread, FALSE);
+		cb (0, task->user_data);
+		return;
+	}
+
+	/* first find the default music folder */
+	f = LIBMTP_Find_Folder (folders, thread->device->default_music_folder);
+	if (f == NULL) {
+		rb_debug ("unable to find default music folder");
+		cb (0, task->user_data);
+		LIBMTP_destroy_folder_t (folders);
+		return;
+	}
+	storage_id = f->storage_id;
+	folder_id = f->folder_id;
+
+	/* descend through the folder tree, following the path */
+	i = 0;
+	while (task->path[i] != NULL) {
+
+		/* look for a folder at this level with the same name as the
+		 * next path component
+		 */
+		target = f->child;
+		while (target != NULL) {
+			if (g_strcmp0 (target->name, task->path[i]) == 0) {
+				rb_debug ("found path element %d: %s", i, target->name);
+				break;
+			}
+			target = target->sibling;
+		}
+
+		if (target == NULL) {
+			rb_debug ("path element %d (%s) not found", i, task->path[i]);
+			break;
+		}
+		f = target;
+		folder_id = f->folder_id;
+		i++;
+	}
+
+	/* now create any path elements that don't already exist */
+	while (task->path[i] != NULL) {
+		folder_id = LIBMTP_Create_Folder (thread->device, task->path[i], folder_id, storage_id);
+		if (folder_id == 0) {
+			rb_debug ("couldn't create path element %d: %s", i, task->path[i]);
+			rb_mtp_thread_report_errors (thread, FALSE);
+			break;
+		}
+		rb_debug ("created path element %d: %s with folder ID %u", i, task->path[i], folder_id);
+		i++;
+	}
+
+	cb (folder_id, task->user_data);
+	LIBMTP_destroy_folder_t (folders);
+}
+
 static LIBMTP_album_t *
 add_track_to_album (RBMtpThread *thread, const char *album_name, uint32_t track_id, uint32_t storage_id, gboolean *new_album)
 {
@@ -561,6 +638,10 @@ run_task (RBMtpThread *thread, RBMtpThreadTask *task)
 		}
 		break;
 
+	case CREATE_FOLDER:
+		create_folder (thread, task);
+		break;
+
 	case ADD_TO_ALBUM:
 		add_track_to_album_and_update (thread, task);
 		break;
@@ -647,6 +728,21 @@ rb_mtp_thread_set_device_name (RBMtpThread *thread, const char *name)
 }
 
 void
+rb_mtp_thread_create_folder (RBMtpThread *thread,
+			     const char **path,
+			     RBMtpCreateFolderCallback func,
+			     gpointer data,
+			     GDestroyNotify destroy_data)
+{
+	RBMtpThreadTask *task = create_task (CREATE_FOLDER);
+	task->path = g_strdupv ((char **)path);
+	task->callback = func;
+	task->user_data = data;
+	task->destroy_data = destroy_data;
+	queue_task (thread, task);
+}
+
+void
 rb_mtp_thread_add_to_album (RBMtpThread *thread, LIBMTP_track_t *track, const char *album)
 {
 	RBMtpThreadTask *task = create_task (ADD_TO_ALBUM);
diff --git a/plugins/mtpdevice/rb-mtp-thread.h b/plugins/mtpdevice/rb-mtp-thread.h
index e37f2f6..8085634 100644
--- a/plugins/mtpdevice/rb-mtp-thread.h
+++ b/plugins/mtpdevice/rb-mtp-thread.h
@@ -83,6 +83,7 @@ typedef void (*RBMtpTrackListCallback) (LIBMTP_track_t *tracklist, gpointer user
 typedef void (*RBMtpUploadCallback) (LIBMTP_track_t *track, GError *error, gpointer user_data);
 typedef void (*RBMtpDownloadCallback) (uint32_t track_id, const char *filename, GError *error, gpointer user_data);
 typedef void (*RBMtpThreadCallback) (LIBMTP_mtpdevice_t *device, gpointer user_data);
+typedef void (*RBMtpCreateFolderCallback) (uint32_t folder_id, gpointer user_data);
 
 GType		rb_mtp_thread_get_type (void);
 RBMtpThread *	rb_mtp_thread_new (void);
@@ -106,6 +107,13 @@ void		rb_mtp_thread_queue_callback (RBMtpThread *thread,
 					      gpointer data,
 					      GDestroyNotify destroy_data);
 
+/* folders */
+void		rb_mtp_thread_create_folder (RBMtpThread *thread,
+					     const char **path,
+					     RBMtpCreateFolderCallback func,
+					     gpointer data,
+					     GDestroyNotify destroy_data);
+
 /* albums */
 void		rb_mtp_thread_add_to_album (RBMtpThread *thread, LIBMTP_track_t *track, const char *album);
 void		rb_mtp_thread_remove_from_album (RBMtpThread *thread, LIBMTP_track_t *track, const char *album);



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