summaryrefslogtreecommitdiff
path: root/src/data/folderdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/folderdata.c')
-rw-r--r--src/data/folderdata.c353
1 files changed, 301 insertions, 52 deletions
diff --git a/src/data/folderdata.c b/src/data/folderdata.c
index 6a9ee00..d9ef0e4 100644
--- a/src/data/folderdata.c
+++ b/src/data/folderdata.c
@@ -17,9 +17,23 @@
#include <Elementary.h>
#include <media_content.h>
#include <app_debug.h>
+#include <app_media.h>
#include "data/datamgr.h"
+struct folderdata;
+
+typedef bool (*get_media_list)(struct folderdata *fd, void *data);
+typedef int (*media_compare)(struct group_info *gi, app_media_info *info);
+typedef void *(*media_compare_data_get)(app_media_info *info);
+typedef char *(*group_name_get)(app_media_info *info);
+
+static bool _get_media_name_list(struct folderdata *fd, void *data);
+static int _compare_cb_name(const void *, const void *);
+static int _compare_title(struct group_info *, app_media_info *);
+static char *_get_title(app_media_info *);
+static void *_get_data_title(app_media_info *info);
+
enum _filter_type {
E_FILTER_FOLDER = 0,
E_FILTER_MEDIA
@@ -27,6 +41,7 @@ enum _filter_type {
struct folderdata {
Eina_List *folder_list;
+ Eina_List *media_list;
char *parent_id;
@@ -34,6 +49,25 @@ struct folderdata {
int source_type;
};
+struct _list_info {
+ get_media_list get_list;
+
+ Eina_Compare_Cb sort_cmp_cb;
+ media_compare media_cmp;
+ media_compare_data_get data_get;
+ group_name_get name_get;
+};
+
+static struct _list_info g_group_info[E_GROUP_FOLDER_MAX] = {
+ [E_GROUP_FOLDER_MEDIA_NAME] = {
+ .get_list = _get_media_name_list,
+ .sort_cmp_cb = _compare_cb_name,
+ .media_cmp = _compare_title,
+ .name_get = _get_title,
+ .data_get = _get_data_title,
+ },
+};
+
static bool _create_filter(struct folderdata *fd, filter_h *filter,
const char *cond, int filter_type)
{
@@ -47,43 +81,91 @@ static bool _create_filter(struct folderdata *fd, filter_h *filter,
return false;
}
- snprintf(buf, sizeof(buf), "%s", fd->media_type);
+ if (filter_type == E_FILTER_FOLDER) {
+ if (cond)
+ snprintf(buf, sizeof(buf), "%s", cond);
- if (fd->source_type != E_SOURCE_ALL) {
- char s1[256];
+ media_filter_set_order(tmp_filter, MEDIA_CONTENT_ORDER_ASC,
+ FOLDER_NAME, MEDIA_CONTENT_COLLATE_DEFAULT);
+ } else {
+ snprintf(buf, sizeof(buf), "%s", fd->media_type);
- snprintf(s1, sizeof(s1), " AND MEDIA_STORAGE_TYPE=%d",
- fd->source_type);
+ if (fd->source_type != E_SOURCE_ALL) {
+ char s1[256];
- strcat(buf, s1);
- }
+ snprintf(s1, sizeof(s1), " AND MEDIA_STORAGE_TYPE=%d",
+ fd->source_type);
- if (cond) {
- char s2[256];
+ strcat(buf, s1);
+ }
- snprintf(s2, sizeof(s2), " AND %s", cond);
+ if (cond) {
+ char s2[256];
- strcat(buf, s2);
- }
+ snprintf(s2, sizeof(s2), " AND %s", cond);
- media_filter_set_condition(tmp_filter, buf,
- MEDIA_CONTENT_COLLATE_DEFAULT);
+ strcat(buf, s2);
+ }
- if (filter_type == E_FILTER_FOLDER) {
media_filter_set_order(tmp_filter, MEDIA_CONTENT_ORDER_ASC,
- FOLDER_NAME, MEDIA_CONTENT_COLLATE_DEFAULT);
+ MEDIA_TITLE,
+ MEDIA_CONTENT_COLLATE_DEFAULT);
}
+ media_filter_set_condition(tmp_filter, buf,
+ MEDIA_CONTENT_COLLATE_DEFAULT);
+
*filter = tmp_filter;
return true;
}
-static void _destroy_folder_list(struct folderdata *fd)
+static int _compare_cb_name(const void *data1, const void *data2)
+{
+ app_media *am1, *am2;
+ app_media_info *mi1, *mi2;
+
+ am1 = (app_media *)data1;
+ am2 = (app_media *)data2;
+
+ mi1 = app_media_get_info(am1);
+ mi2 = app_media_get_info(am2);
+
+ if (!mi1 || !mi2 || !mi1->title || !mi2->title)
+ return -1;
+
+ return strcasecmp(mi1->title, mi2->title);
+}
+
+static int _compare_title(struct group_info *gi, app_media_info *mi)
+{
+ if (!gi || !gi->data || !mi->title)
+ return -1;
+
+ return strncasecmp(gi->data, mi->title, 1);
+}
+
+static void *_get_data_title(app_media_info *mi)
+{
+ if (!mi->title)
+ return NULL;
+
+ return strdup(mi->title);
+}
+
+static char *_get_title(app_media_info *mi)
+{
+ if (!mi->title)
+ return NULL;
+
+ return strndup(mi->title, 1);
+}
+
+static void _destroy_folder_list(Eina_List *list)
{
struct folder_info *fi;
- EINA_LIST_FREE(fd->folder_list, fi) {
+ EINA_LIST_FREE(list, fi) {
free(fi->id);
free(fi->name);
free(fi->path);
@@ -91,8 +173,14 @@ static void _destroy_folder_list(struct folderdata *fd)
free(fi);
}
+}
+
+static void _destroy_media_list(Eina_List *list)
+{
+ app_media *am;
- fd->folder_list = NULL;
+ EINA_LIST_FREE(list, am)
+ app_media_destroy(am);
}
static bool _get_folder_id(media_folder_h folder, void *data)
@@ -179,6 +267,27 @@ static bool _get_each_folder_info(media_folder_h folder, void *data)
return true;
}
+static bool _get_each_media_info(media_info_h media_h, void *data)
+{
+ struct folderdata *fd;
+ app_media *am;
+
+ if (!data)
+ return false;
+
+ fd = data;
+
+ am = app_media_create(media_h);
+ if (!am) {
+ _ERR("failed to create app media");
+ return false;
+ }
+
+ fd->media_list = eina_list_append(fd->media_list, am);
+
+ return true;
+}
+
static bool _find_folder_id(struct folderdata *fd, const char *path)
{
filter_h filter;
@@ -205,16 +314,12 @@ static bool _find_folder_id(struct folderdata *fd, const char *path)
return true;
}
-static bool _get_sub_folder_list(struct folderdata *fd)
+static bool _get_sub_folder_list(struct folderdata *fd, const char *cond)
{
filter_h filter;
int ret;
- char buf[1024];
-
- snprintf(buf, sizeof(buf), "FOLDER_PARENT_FOLDER_ID=\"%s\"",
- fd->parent_id);
- if (!_create_filter(fd, &filter, buf, E_FILTER_FOLDER)) {
+ if (!_create_filter(fd, &filter, cond, E_FILTER_FOLDER)) {
_ERR("failed to create filter");
return false;
}
@@ -223,7 +328,7 @@ static bool _get_sub_folder_list(struct folderdata *fd)
_get_each_folder_info, fd);
if (ret != MEDIA_CONTENT_ERROR_NONE) {
_ERR("failed to get folder info");
- _destroy_folder_list(fd);
+ _destroy_folder_list(fd->folder_list);
media_filter_destroy(filter);
return false;
}
@@ -233,6 +338,104 @@ static bool _get_sub_folder_list(struct folderdata *fd)
return true;
}
+static bool _get_folder_list(struct folderdata *fd, char **path)
+{
+ int ret;
+ int i;
+ char buf[1024] = {0,};
+
+ ret = media_content_connect();
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ _ERR("failed to connect to media content");
+ return false;
+ }
+
+ i = 0;
+ while (path[i++]) {
+ char s[128];
+
+ if (!_find_folder_id(fd, path[i])) {
+ _ERR("failed to find folder id");
+ media_content_disconnect();
+ return false;
+ }
+
+ if (strlen(buf)) {
+ snprintf(s, sizeof(s),
+ " OR FOLDER_PARENT_FOLDER_ID=\"%s\"",
+ fd->parent_id);
+ } else {
+ snprintf(s, sizeof(s), "FOLDER_PARENT_FOLDER_ID=\"%s\"",
+ fd->parent_id);
+ }
+
+ strcat(buf, s);
+ }
+
+ if (!_get_sub_folder_list(fd, buf)) {
+ _ERR("failed to get child folder list");
+ media_content_disconnect();
+ return false;
+ }
+
+ media_content_disconnect();
+
+ return true;
+}
+
+static bool _get_media_name_list(struct folderdata *fd, void *data)
+{
+ filter_h filter;
+ int ret;
+ int i;
+ char **path;
+
+ path = data;
+
+ if (fd->media_list) {
+ _destroy_media_list(fd->media_list);
+ fd->media_list = NULL;
+ }
+
+ ret = media_content_connect();
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ _ERR("failed to connect to media content");
+ return false;
+ }
+
+ if (!_create_filter(fd, &filter, NULL, E_FILTER_MEDIA)) {
+ _ERR("failed to create filter");
+ media_content_disconnect();
+ return false;
+ }
+
+ i = 0;
+ while (path[i++]) {
+ if (!_find_folder_id(fd, path[i])) {
+ _ERR("failed to find folder id");
+ media_filter_destroy(filter);
+ media_content_disconnect();
+ return false;
+ }
+
+ ret = media_folder_foreach_media_from_db(fd->parent_id, filter,
+ _get_each_media_info, fd);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ _ERR("failed to get media info");
+ _destroy_media_list(fd->media_list);
+ media_filter_destroy(filter);
+ media_content_disconnect();
+ return false;
+ }
+ }
+
+ media_filter_destroy(filter);
+
+ media_content_disconnect();
+
+ return true;
+}
+
static void *_create(const char *media_type, int source_type)
{
struct folderdata *fd;
@@ -265,7 +468,8 @@ static void _destroy(void *handle)
fd = handle;
- _destroy_folder_list(fd);
+ _destroy_folder_list(fd->folder_list);
+ _destroy_media_list(fd->media_list);
free(fd->parent_id);
free(fd);
@@ -274,6 +478,7 @@ static void _destroy(void *handle)
static Eina_List *_get_list(void *handle, int type, void *data)
{
struct folderdata *fd;
+ char **path;
if (!handle) {
_ERR("failed to get folderdata handle");
@@ -282,7 +487,17 @@ static Eina_List *_get_list(void *handle, int type, void *data)
fd = handle;
- return fd->folder_list;
+ switch (type) {
+ case E_LIST_FOLDER:
+ path = data;
+ _get_folder_list(fd, path);
+
+ return fd->folder_list;
+ default:
+ break;
+ }
+
+ return NULL;
}
static int _get_count(void *handle, int type)
@@ -299,15 +514,40 @@ static int _get_count(void *handle, int type)
return eina_list_count(fd->folder_list);
}
+static void _free_group_list(Eina_List *list)
+{
+ struct group_info *gi;
+
+ EINA_LIST_FREE(list, gi) {
+ free(gi->name);
+ free(gi->data);
+ _destroy_media_list(gi->list);
+
+ free(gi);
+ }
+}
+
static void _free_group(Eina_List *list)
{
- eina_list_free(list);
+ _free_group_list(list);
+}
+
+static Eina_List *_sort_list(Eina_List *list, int sort)
+{
+ Eina_List *sorted_list;
+
+ sorted_list = eina_list_sort(list, 0, g_group_info[sort].sort_cmp_cb);
+
+ return sorted_list;
}
static Eina_List *_get_group(void *handle, int type, void *data)
{
+ Eina_List *list, *l;
struct folderdata *fd;
- int ret;
+ struct group_info *gi;
+ app_media *am;
+ app_media_info *mi;
if (!handle) {
_ERR("failed to get folderdata handle");
@@ -321,32 +561,41 @@ static Eina_List *_get_group(void *handle, int type, void *data)
fd = handle;
- if (fd->folder_list) {
- _destroy_folder_list(fd);
- free(fd->parent_id);
- }
-
- ret = media_content_connect();
- if (ret != MEDIA_CONTENT_ERROR_NONE) {
- _ERR("failed to connect to media content");
- return false;
- }
-
- if (!_find_folder_id(fd, data)) {
- _ERR("failed to find folder id");
- media_content_disconnect();
- return false;
+ if (!g_group_info[type].get_list(fd, data)) {
+ _ERR("failed to get list");
+ return NULL;
}
- if (!_get_sub_folder_list(fd)) {
- _ERR("failed to get child folder list");
- media_content_disconnect();
- return false;
+ fd->media_list = _sort_list(fd->media_list, type);
+
+ gi = NULL;
+ list = NULL;
+ EINA_LIST_FOREACH(fd->media_list, l, am) {
+ mi = app_media_get_info(am);
+ if (!mi) {
+ _ERR("failed to get media info");
+ _free_group_list(list);
+ return NULL;
+ }
+
+ if (g_group_info[type].media_cmp(gi, mi)) {
+ gi = calloc(1, sizeof(*gi));
+ if (!gi) {
+ _ERR("failed to create group info");
+ _free_group_list(list);
+ return NULL;
+ }
+
+ gi->name = g_group_info[type].name_get(mi);
+ gi->data = g_group_info[type].data_get(mi);
+
+ list = eina_list_append(list, gi);
+ }
+
+ gi->list = eina_list_append(gi->list, am);
}
- media_content_disconnect();
-
- return eina_list_clone(fd->folder_list);
+ return list;
}
static struct data_ops _ops = {