4252 lines
142 KiB
C
4252 lines
142 KiB
C
#include "empc_private.h"
|
|
#include "eldbus_empd_empdd.h"
|
|
#include "eldbus_empd_empc.h"
|
|
|
|
#define EMPC_METHOD_BASE "org.empd.empc"
|
|
|
|
#define WEIGHT evas_object_size_hint_weight_set
|
|
#define ALIGN evas_object_size_hint_align_set
|
|
#define EXPAND(X) WEIGHT((X), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND)
|
|
#define FILL(X) ALIGN((X), EVAS_HINT_FILL, EVAS_HINT_FILL)
|
|
|
|
|
|
typedef enum
|
|
{
|
|
EMPC_SIGNAL_BACKGROUND_CHANGED,
|
|
} EMPC_Signals;
|
|
|
|
typedef struct Empc_Entity
|
|
{
|
|
int type;
|
|
void *value;
|
|
} Empc_Entity;
|
|
|
|
static Eina_Bool selecting, unselecting;
|
|
|
|
Eina_Bool master = EINA_FALSE;
|
|
|
|
static Eina_Bool bg_updated = EINA_FALSE;
|
|
|
|
static Eina_Stringshare *empd_host;
|
|
static unsigned int empd_port;
|
|
static Eldbus_Pending *config_call;
|
|
|
|
static int empd_state = 0;
|
|
|
|
static Evas_Object *win = NULL;
|
|
static Evas_Object *bg[2] = {NULL};
|
|
static Evas_Object *layout = NULL;
|
|
static Evas_Object *layout_filesystem = NULL;
|
|
|
|
static Eina_Bool ctxpopup_locked_overlay = EINA_FALSE;
|
|
static Eina_Bool overlay_locked_state = EINA_FALSE;
|
|
static Eina_Bool lyrics_visible = EINA_FALSE;
|
|
static Eina_Bool empd_connected = EINA_FALSE;
|
|
|
|
static Eina_Bool bgheader_dirty = EINA_FALSE;
|
|
static Eina_Bool bgchooser = EINA_FALSE;
|
|
static Empc_Fetch_Request *bgfetch = NULL;
|
|
static Eina_Bool bg_ignore = EINA_FALSE;
|
|
static Eina_Bool bg_pasting = EINA_FALSE;
|
|
|
|
static Eina_Bool queue_list_state = EINA_FALSE;
|
|
static Eina_Bool filesystem_state = EINA_FALSE;
|
|
static Evas_Object *ctxpopup = NULL;
|
|
EAPI Evas_Object *queue_list = NULL;
|
|
static Elm_Object_Item *queue_list_scroll_item = NULL;
|
|
static Eina_List *queue_list_realized = NULL;
|
|
static Eina_List *filesystems = NULL;
|
|
static Eina_List *filesystems_realized = NULL;
|
|
static Ecore_Idler *filesystem_idler = NULL;
|
|
static Elm_Object_Item *filesystem_idler_pos = NULL;
|
|
static Evas_Object *filesystem_entry = NULL;
|
|
static Evas_Object *controls = NULL;
|
|
static Evas_Object *repeat = NULL;
|
|
static Evas_Object *shuffle = NULL;
|
|
static Evas_Object *single = NULL;
|
|
static Evas_Object *consume = NULL;
|
|
|
|
static Eina_Bool login_visible = EINA_FALSE;
|
|
static Evas_Object *login_host = NULL;
|
|
static Evas_Object *login_port = NULL;
|
|
static Evas_Object *login_password = NULL;
|
|
|
|
static Eina_Array *clipboard = NULL;
|
|
static long long clipboard_paste_id = -1;
|
|
static unsigned int clipboard_paste_length = 0;
|
|
|
|
int empc_log_dom = -1;
|
|
|
|
EAPI void *empd_proxy = NULL;
|
|
EAPI void *empc_proxy = NULL;
|
|
static Eldbus_Service_Interface *empc_iface = NULL;
|
|
static Eldbus_Connection *dbus_conn = NULL;
|
|
|
|
static Eina_List *handlers = NULL;
|
|
EAPI Eina_Hash *empd_current_queue = NULL;
|
|
EAPI Eina_Hash *empd_current_queue_headers = NULL;
|
|
|
|
Eina_Stringshare *empd_music_directory = NULL;
|
|
static int empd_songid = -1;
|
|
static int empd_song_track = -1;
|
|
static Eina_Stringshare *empd_song_title = NULL;
|
|
static Eina_Stringshare *empd_song_artist = NULL;
|
|
static Eina_Stringshare *empd_song_album = NULL;
|
|
static Elm_Object_Item *empd_song_item = NULL;
|
|
static unsigned int empd_song_length = 0;
|
|
static unsigned int empd_song_elapsed = 0;
|
|
EAPI unsigned int empd_queue_length = 0;
|
|
|
|
static unsigned char background_num = 0;
|
|
|
|
Eina_Hash *empc_metadata_fetch_reqs[EMPC_METADATA_TYPE_LAST];
|
|
|
|
Eina_Inlist *empc_modules[EMPC_MODULE_TYPE_LAST];
|
|
|
|
static size_t empc_module_size[EMPC_MODULE_TYPE_LAST] =
|
|
{
|
|
[EMPC_MODULE_TYPE_METADATA_FETCH] = sizeof(Empc_Module_Metadata_Fetch),
|
|
[EMPC_MODULE_TYPE_METADATA_SAVER] = sizeof(Empc_Module_Metadata_Save),
|
|
[EMPC_MODULE_TYPE_MISC] = sizeof(Empc_Module_Misc),
|
|
};
|
|
|
|
static void queue_list_header_image(void *data, Empc_Fetch_Request *req, Evas_Object *obj);
|
|
static void filesystem_base(Eldbus_Proxy *proxy, void *data, Eldbus_Pending *pending, Eldbus_Error_Info *error, Eina_Value *args);
|
|
static void filesystem_item_image(void *data, Empc_Fetch_Request *req, Evas_Object *obj);
|
|
static void queue_list_handler(Eina_Value *value, Eina_Bool update);
|
|
static void filesystem_next(void *data, Evas_Object *obj, void *event_info);
|
|
static void filesystem_prev(void);
|
|
static Evas_Object *filesystem_new(const char *uri);
|
|
|
|
static void
|
|
error_o_doom(void)
|
|
{
|
|
Evas_Object *o;
|
|
|
|
o = elm_popup_add(win);
|
|
elm_object_text_set(o, _("<b>THIS IS THE ANGRY ERROR MESSAGE!<br/>"
|
|
"DBUS </b>.service<b> INSTALLATION FAILED.<br/>"
|
|
"FIX YOUR INSTALL OR START '</b>empdd<b>' MANUALLY.<br/>"
|
|
"<br/>"
|
|
"RESTART EMPC WHEN YOU HAVE FIXED THIS.<br/>"
|
|
"<br/>"
|
|
"PS. CAPS LOCK IS FUN FOR DEVELOPERS!"));
|
|
evas_object_show(o);
|
|
}
|
|
|
|
static inline unsigned char
|
|
bg_next_get(void)
|
|
{
|
|
char num = background_num + 1;
|
|
return num % 2;
|
|
}
|
|
|
|
static void
|
|
queue_list_clear(void)
|
|
{
|
|
eina_hash_free_buckets(empd_current_queue_headers);
|
|
elm_genlist_clear(queue_list);
|
|
queue_list_scroll_item = NULL;
|
|
}
|
|
|
|
static void
|
|
ctxpopup_item_append(unsigned int *num, Evas_Object *ctx, const char *label, Evas_Object *icon, Evas_Smart_Cb cb, const void *data)
|
|
{
|
|
Elm_Object_Item *it;
|
|
char buf[128];
|
|
|
|
it = elm_ctxpopup_item_append(ctx, _(label), icon, cb, data);
|
|
snprintf(buf, sizeof(buf), "%u", ++(*num));
|
|
elm_object_item_part_text_set(it, "empc.text.hint", buf);
|
|
}
|
|
|
|
static void
|
|
item_box_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
evas_object_del(data);
|
|
}
|
|
|
|
static Evas_Object *
|
|
ee_image_add(void)
|
|
{
|
|
Evas_Object *o;
|
|
|
|
o = ecore_evas_object_image_new(ecore_evas_ecore_evas_get(evas_object_evas_get(win)));
|
|
ecore_evas_alpha_set(evas_object_data_get(o, "Ecore_Evas"), 1);
|
|
evas_object_image_filled_set(o, 1);
|
|
return o;
|
|
}
|
|
|
|
static void
|
|
ee_image_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
evas_object_del(data);
|
|
}
|
|
|
|
static void
|
|
ee_image_copy(Evas_Object *obj, Evas_Object *o, int size)
|
|
{
|
|
Evas_Object *orig, *copy;
|
|
const Eina_File *file;
|
|
Eina_Stringshare *f, *g;
|
|
int w, h;
|
|
|
|
orig = elm_image_object_get(obj);
|
|
evas_object_image_mmap_get(orig, &file, &g);
|
|
copy = evas_object_image_filled_add(ecore_evas_object_evas_get(o));
|
|
elm_image_object_size_get(obj, &w, &h);
|
|
evas_object_size_hint_aspect_set(o, EVAS_ASPECT_CONTROL_BOTH, w, h);
|
|
size *= elm_config_scale_get();
|
|
if (w > h)
|
|
{
|
|
h = size * h / w;
|
|
w = size;
|
|
}
|
|
else if (h > w)
|
|
{
|
|
w = size * w / h;
|
|
h = size;
|
|
}
|
|
else
|
|
w = h = size;
|
|
evas_object_data_set(o, "__empc_image", copy);
|
|
evas_object_image_size_set(o, w, h);
|
|
evas_object_resize(copy, w, h);
|
|
evas_object_show(copy);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, ee_image_del, copy);
|
|
evas_object_image_smooth_scale_set(copy, 0);
|
|
if (file)
|
|
evas_object_image_mmap_set(copy, file, g);
|
|
else
|
|
{
|
|
evas_object_image_file_get(orig, &f, &g);
|
|
evas_object_image_file_set(copy, f, g);
|
|
}
|
|
}
|
|
|
|
static inline Elm_Object_Item *
|
|
queue_list_header_prev_get(Elm_Object_Item *it)
|
|
{
|
|
Elm_Object_Item *pick;
|
|
|
|
pick = elm_genlist_item_prev_get(it);
|
|
if (pick)
|
|
{
|
|
do
|
|
{
|
|
Elm_Object_Item *h = elm_genlist_item_parent_get(pick);
|
|
|
|
if ((!h) && (pick != it)) return pick;
|
|
if (h != it)
|
|
return h;
|
|
pick = elm_genlist_item_prev_get(pick);
|
|
} while (pick);
|
|
}
|
|
return elm_genlist_last_item_get(queue_list);
|
|
}
|
|
|
|
static inline Elm_Object_Item *
|
|
queue_list_header_next_get(Elm_Object_Item *it)
|
|
{
|
|
Elm_Object_Item *pick;
|
|
|
|
pick = elm_genlist_item_next_get(it);
|
|
if (pick)
|
|
{
|
|
do
|
|
{
|
|
Elm_Object_Item *h = elm_genlist_item_parent_get(pick);
|
|
|
|
if ((!h) && (pick != it)) return pick;
|
|
if (h != it)
|
|
return h;
|
|
pick = elm_genlist_item_next_get(pick);
|
|
} while (pick);
|
|
}
|
|
return elm_genlist_item_parent_get(elm_genlist_first_item_get(queue_list));
|
|
}
|
|
|
|
static int
|
|
queue_list_sort(Elm_Object_Item *a, Elm_Object_Item *b)
|
|
{
|
|
Empd_Empdd_Song *a1, *b1;
|
|
|
|
a1 = elm_object_item_data_get(a);
|
|
b1 = elm_object_item_data_get(b);
|
|
|
|
return a1->song_pos - b1->song_pos;
|
|
}
|
|
|
|
const char *
|
|
filesystem_entity_name_get(const Empc_Entity *ent)
|
|
{
|
|
Empd_Empdd_Directory *dir = ent->value;
|
|
Empd_Empdd_File *f = ent->value;
|
|
|
|
switch (ent->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
return dir->uri;
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
return f->uri;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static int
|
|
filesystem_sort(Elm_Object_Item *it1, Elm_Object_Item *it2)
|
|
{
|
|
Empc_Entity *a, *b;
|
|
const char *a1, *b1;
|
|
|
|
a = elm_object_item_data_get(it1);
|
|
b = elm_object_item_data_get(it2);
|
|
a1 = filesystem_entity_name_get(a);
|
|
b1 = filesystem_entity_name_get(b);
|
|
|
|
if (a->type == b->type)
|
|
return strcmp(a1, b1);
|
|
switch (a->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
if (b->type == MPD_ENTITY_TYPE_PLAYLIST) return -1;
|
|
return 1;
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
return 1;
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
return -1;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static void
|
|
clipboard_entity_free(Empc_Entity *ent)
|
|
{
|
|
eina_stringshare_del(ent->value);
|
|
free(ent);
|
|
}
|
|
|
|
static void
|
|
clipboard_clear(void)
|
|
{
|
|
Eina_Iterator *it;
|
|
Empc_Entity *ent;
|
|
|
|
if (!eina_array_count(clipboard)) return;
|
|
|
|
it = eina_array_iterator_new(clipboard);
|
|
EINA_ITERATOR_FOREACH(it, ent)
|
|
clipboard_entity_free(ent);
|
|
eina_iterator_free(it);
|
|
eina_array_clean(clipboard);
|
|
}
|
|
|
|
static Eina_Bool
|
|
clipboard_copy(void)
|
|
{
|
|
const Eina_List *l;
|
|
Eina_List *sorted;
|
|
Elm_Object_Item *it;
|
|
Empd_Empdd_Song *so;
|
|
Empc_Entity *ent, *eso;
|
|
|
|
if (filesystem_state)
|
|
{
|
|
l = elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems));
|
|
if (!l) return EINA_TRUE;
|
|
clipboard_clear();
|
|
sorted = eina_list_clone(l);
|
|
sorted = eina_list_sort(sorted, 0, (Eina_Compare_Cb)filesystem_sort);
|
|
EINA_LIST_FREE(sorted, it)
|
|
{
|
|
ent = malloc(sizeof(Empc_Entity));
|
|
eso = elm_object_item_data_get(it);
|
|
ent->type = eso->type;
|
|
ent->value = (void*)eina_stringshare_ref(filesystem_entity_name_get(eso));
|
|
eina_array_push(clipboard, ent);
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
else if (queue_list_state)
|
|
{
|
|
l = elm_genlist_selected_items_get(queue_list);
|
|
if (!l) return EINA_TRUE;
|
|
clipboard_clear();
|
|
sorted = eina_list_clone(l);
|
|
sorted = eina_list_sort(sorted, 0, (Eina_Compare_Cb)queue_list_sort);
|
|
EINA_LIST_FREE(sorted, it)
|
|
{
|
|
ent = malloc(sizeof(Empc_Entity));
|
|
so = elm_object_item_data_get(it);
|
|
ent->value = (void*)eina_stringshare_ref(so->uri);
|
|
ent->type = MPD_ENTITY_TYPE_SONG;
|
|
eina_array_push(clipboard, ent);
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static Eina_Bool
|
|
clipboard_paste(long long after)
|
|
{
|
|
Eina_Iterator *it;
|
|
Empc_Entity *ent;
|
|
|
|
if (!queue_list_state) return EINA_FALSE;
|
|
if (!eina_array_count(clipboard)) return EINA_TRUE;
|
|
if (clipboard_paste_length || (clipboard_paste_id != -1)) return EINA_FALSE;
|
|
if (after != empd_queue_length)
|
|
{
|
|
clipboard_paste_length = empd_queue_length;
|
|
clipboard_paste_id = after;
|
|
}
|
|
it = eina_array_iterator_new(clipboard);
|
|
EINA_ITERATOR_FOREACH(it, ent)
|
|
{
|
|
switch (ent->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
empd_empdd_add_list_call(empd_proxy, ent->value);
|
|
break;
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
empd_empdd_load_playlist_call(empd_proxy, ent->value);
|
|
break;
|
|
}
|
|
}
|
|
eina_iterator_free(it);
|
|
empd_empdd_status_call(empd_proxy);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
ctxpopup_mouse(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
elm_layout_signal_emit(layout, "empc,mouse,move", "empc");
|
|
}
|
|
|
|
static void
|
|
ctxpopup_dismiss(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
if (ctxpopup == obj)
|
|
ctxpopup = NULL;
|
|
if (ctxpopup_locked_overlay)
|
|
{
|
|
ctxpopup_locked_overlay = EINA_FALSE;
|
|
if (overlay_locked_state)
|
|
elm_object_signal_emit(layout, "empc,overlay,toggle", "empc");
|
|
}
|
|
evas_object_del(obj);
|
|
}
|
|
|
|
static void
|
|
ctxpopup_copy(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
clipboard_copy();
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static Evas_Object *
|
|
ctxpopup_add(Evas_Object *obj, const char *style)
|
|
{
|
|
Evas_Object *ctx;
|
|
|
|
ctx = elm_ctxpopup_add(obj);
|
|
evas_object_event_callback_add(ctx, EVAS_CALLBACK_MOUSE_MOVE, ctxpopup_mouse, NULL);
|
|
elm_object_style_set(ctx, style);
|
|
evas_object_smart_callback_add(ctx, "dismissed", ctxpopup_dismiss, NULL);
|
|
if (!overlay_locked_state)
|
|
{
|
|
elm_object_signal_emit(layout, "empc,overlay,toggle", "empc");
|
|
ctxpopup_locked_overlay = EINA_TRUE;
|
|
}
|
|
return ctx;
|
|
}
|
|
|
|
static void
|
|
ctxpopup_mouse_position(Evas_Object *ctx)
|
|
{
|
|
//FIXME: T1211
|
|
int x, y, w, h, ow, oh, px, py;
|
|
|
|
evas_pointer_canvas_xy_get(evas_object_evas_get(ctx), &x, &y);
|
|
evas_object_geometry_get(layout, NULL, NULL, &w, &h);
|
|
evas_object_size_hint_min_get(ctx, &ow, &oh);
|
|
if (ow) ow = 200;
|
|
if (oh) oh = 200;
|
|
|
|
px = x, py = y;
|
|
if (px + ow >= w)
|
|
px -= ow;
|
|
if (px < 0)
|
|
px += (ow / 2);
|
|
if (py + oh >= h)
|
|
py -= oh;
|
|
if (py < 0)
|
|
py += (oh / 2);
|
|
evas_object_move(ctxpopup, px, py);
|
|
}
|
|
|
|
static Evas_Object *
|
|
tooltip_create(Evas_Object *tooltip, Elm_Object_Item *item)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Evas_Object *o, *copy, *ly;
|
|
const Eina_File *f;
|
|
Eina_Stringshare *file, *key;
|
|
Empd_Empdd_Song *so;
|
|
char buf[1024];
|
|
const char *infos;
|
|
Eina_Bool playing;
|
|
|
|
it = elm_genlist_item_parent_get(item);
|
|
if (!it) it = item;
|
|
so = elm_object_item_data_get(item);
|
|
|
|
if (item == empd_song_item)
|
|
{
|
|
o = bgselector_get(bg[background_num]);
|
|
if (o)
|
|
o = elm_image_object_get(o);
|
|
}
|
|
else
|
|
{
|
|
o = elm_object_item_part_content_get(it, EMPC_SWALLOW_ALBUM);
|
|
if (o)
|
|
{
|
|
if (!strcmp(evas_object_type_get(o), "Evas_Object_Box"))
|
|
o = eina_list_data_get(evas_object_box_children_get(o));
|
|
if (o)
|
|
o = evas_object_data_get(o, "__empc_image");
|
|
}
|
|
}
|
|
ly = elm_layout_add(tooltip);
|
|
elm_layout_theme_set(ly, "layout", "empc", "tooltip");
|
|
|
|
if (o)
|
|
{
|
|
int w, h;
|
|
|
|
evas_object_image_mmap_get(o, &f, &key);
|
|
if (!f)
|
|
evas_object_image_file_get(o, &file, &key);
|
|
copy = elm_image_add(tooltip);
|
|
if (f)
|
|
elm_image_mmap_set(copy, f, key);
|
|
else
|
|
elm_image_file_set(copy, file, key);
|
|
elm_image_fill_outside_set(copy, EINA_FALSE);
|
|
elm_image_smooth_set(copy, EINA_FALSE);
|
|
elm_image_object_size_get(copy, &w, &h);
|
|
evas_object_size_hint_max_set(copy, w, h);
|
|
if (w > 256)
|
|
{
|
|
h = 256 * h / w;
|
|
w = 256;
|
|
}
|
|
else if (h > 256)
|
|
{
|
|
w = 256 * w / h;
|
|
h = 256;
|
|
}
|
|
evas_object_size_hint_min_set(copy, w, h);
|
|
elm_object_part_content_set(ly, "empc.swallow.icon", copy);
|
|
}
|
|
playing = (empd_song_item && (elm_genlist_item_parent_get(empd_song_item) == it));
|
|
infos = elm_layout_data_get(ly, "empc.infos");
|
|
if (infos && infos[0])
|
|
{
|
|
unsigned int num, i;
|
|
char **str;
|
|
|
|
str = eina_str_split_full(infos, " ", 0, &num);
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
char *itemname = str[i];
|
|
Evas_Object *name, *value;
|
|
|
|
name = elm_label_add(tooltip);
|
|
elm_object_style_set(name, "tooltip_info");
|
|
value = elm_label_add(tooltip);
|
|
elm_object_style_set(value, "tooltip_info_value");
|
|
if (eina_streq(itemname, "artist"))
|
|
{
|
|
elm_object_text_set(name, _("Artist:"));
|
|
elm_object_text_set(value, so->artist);
|
|
}
|
|
else if (eina_streq(itemname, "album"))
|
|
{
|
|
elm_object_text_set(name, _("Album:"));
|
|
elm_object_text_set(value, so->album);
|
|
}
|
|
else if (eina_streq(itemname, "time"))
|
|
{
|
|
elm_object_text_set(name, _("Time:"));
|
|
snprintf(buf, sizeof(buf), "%.2ld:%.2ld", so->duration / 60, so->duration % 60);
|
|
elm_object_text_set(value, buf);
|
|
}
|
|
else if (eina_streq(itemname, "track"))
|
|
{
|
|
if (it == item) //header
|
|
{
|
|
elm_layout_signal_emit(ly, "empc,state,header", "empc");
|
|
elm_object_text_set(name, _("Tracks:"));
|
|
snprintf(buf, sizeof(buf), "%u", elm_genlist_item_subitems_count(it));
|
|
}
|
|
else
|
|
{
|
|
elm_object_text_set(name, _("Track:"));
|
|
if (so->track > (int)elm_genlist_item_subitems_count(it))
|
|
snprintf(buf, sizeof(buf), "%d", so->track);
|
|
else
|
|
snprintf(buf, sizeof(buf), "%d/%u", so->track, elm_genlist_item_subitems_count(it));
|
|
}
|
|
elm_object_text_set(value, buf);
|
|
}
|
|
else if (eina_streq(itemname, "index"))
|
|
{
|
|
elm_object_text_set(name, _("Index:"));
|
|
snprintf(buf, sizeof(buf), "%d", so->song_pos);
|
|
elm_object_text_set(value, buf);
|
|
}
|
|
if (playing)
|
|
elm_layout_signal_emit(value, "empc,state,playing", "empc");
|
|
evas_object_show(name);
|
|
evas_object_show(value);
|
|
elm_layout_table_pack(ly, "empc.table", name, 0, i, 1, 1);
|
|
elm_layout_table_pack(ly, "empc.table", value, 1, i, 1, 1);
|
|
}
|
|
if (num)
|
|
free(str[0]);
|
|
free(str);
|
|
}
|
|
|
|
if (playing)
|
|
elm_layout_signal_emit(ly, "empc,state,playing", "empc");
|
|
|
|
return ly;
|
|
}
|
|
|
|
static void
|
|
save_image(Eina_Bool force, Evas_Object *img, const char *uri, const char *artist, const char *album, Empc_Module_Metadata_Save_Post_Cb post_cb)
|
|
{
|
|
Empc_Module *mod;
|
|
Eina_Bool nosave = EINA_FALSE, override = EINA_FALSE;
|
|
|
|
if ((!force) && (!master)) return;
|
|
if (!master)
|
|
{
|
|
const char *f = NULL, *g;
|
|
|
|
elm_image_file_get(img, &f, &g);
|
|
if (f && f[0])
|
|
empd_empc_set_background_file_call(empc_proxy, artist, album ?: "", f, g ?: "");
|
|
else
|
|
{
|
|
Eldbus_Message *msg;
|
|
Eldbus_Message_Iter *iter, *array;
|
|
const Eina_File *eif;
|
|
Eina_File *e;
|
|
Evas_Object *o;
|
|
void *px;
|
|
|
|
o = elm_image_object_get(img);
|
|
|
|
evas_object_image_mmap_get(o, &eif, NULL);
|
|
e = eina_file_dup(eif);
|
|
msg = eldbus_proxy_method_call_new(empc_proxy, "SetBackgroundData");
|
|
iter = eldbus_message_iter_get(msg);
|
|
eldbus_message_iter_basic_append(iter, 's', artist);
|
|
eldbus_message_iter_basic_append(iter, 's', album ?: "");
|
|
px = eina_file_map_all(e, EINA_FILE_POPULATE);
|
|
eldbus_message_iter_basic_append(iter, 's', eina_file_filename_get(e));
|
|
array = eldbus_message_iter_container_new(iter, 'a', "y");
|
|
if (!eldbus_message_iter_fixed_array_append(array, 'y', px, eina_file_size_get(e)))
|
|
abort();
|
|
if (!eldbus_message_iter_container_close(iter, array))
|
|
abort();
|
|
eldbus_proxy_send(empc_proxy, msg, NULL, NULL, -1);
|
|
eina_file_map_free(e, px);
|
|
eina_file_close(e);
|
|
}
|
|
bg_ignore = EINA_TRUE;
|
|
return;
|
|
}
|
|
if (img)
|
|
{
|
|
override = !!evas_object_data_get(img, "__empc_override");
|
|
nosave = !!evas_object_data_get(img, "__empc_nosave");
|
|
|
|
if ((!override) && nosave) return;
|
|
}
|
|
EINA_INLIST_FOREACH(empc_modules[EMPC_MODULE_TYPE_METADATA_SAVER], mod)
|
|
{
|
|
Empc_Module_Metadata_Save *es = (Empc_Module_Metadata_Save *)mod;
|
|
INF("IMAGE SAVE(%s)", strrchr(eina_module_file_get(mod->module), '/') + 1);
|
|
if (es->save_image) es->save_image(img, uri, artist, album, post_cb);
|
|
}
|
|
}
|
|
|
|
static void
|
|
save_text(Evas_Object *obj, const char *artist, const char *song)
|
|
{
|
|
Empc_Module *mod;
|
|
|
|
if (!master) return;
|
|
if (evas_object_data_get(obj, "__empc_nosave")) return;
|
|
EINA_INLIST_FOREACH(empc_modules[EMPC_MODULE_TYPE_METADATA_SAVER], mod)
|
|
{
|
|
Empc_Module_Metadata_Save *es = (Empc_Module_Metadata_Save *)mod;
|
|
INF("TEXT SAVE(%s)", strrchr(eina_module_file_get(mod->module), '/') + 1);
|
|
if (es->save_text) es->save_text(elm_entry_entry_get(obj), artist, song);
|
|
}
|
|
}
|
|
|
|
static void
|
|
fetch_req_free(Empc_Fetch_Request_Internal *ireq)
|
|
{
|
|
if ((Empc_Fetch_Request*)ireq == bgfetch) bgfetch = NULL;
|
|
while (ireq->end_cbs)
|
|
{
|
|
Empc_Fetch_Request_End_Cb *ecb = (Empc_Fetch_Request_End_Cb *)ireq->end_cbs;
|
|
|
|
ecb->cb(ecb->data, ireq);
|
|
ireq->end_cbs = eina_inlist_remove(ireq->end_cbs, ireq->end_cbs);
|
|
free(ecb);
|
|
}
|
|
eina_stringshare_del(ireq->req.artist);
|
|
eina_stringshare_del(ireq->req.album);
|
|
eina_stringshare_del(ireq->req.song);
|
|
eina_stringshare_del(ireq->req.uri);
|
|
ecore_job_del(ireq->fail_job);
|
|
E_FREE_LIST(ireq->results, free);
|
|
E_FREE_LIST(ireq->urls_pending, eina_stringshare_del);
|
|
free(ireq);
|
|
}
|
|
|
|
void
|
|
lyrics_set(void *data EINA_UNUSED, Empc_Fetch_Request *req, Evas_Object *obj)
|
|
{
|
|
if (!obj) return;
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_LYRICS, obj);
|
|
save_text(obj, req->artist, req->song);
|
|
if (!lyrics_visible)
|
|
elm_object_signal_emit(layout, "empc,lyrics,show", "empc");
|
|
}
|
|
|
|
static void
|
|
bg_update_propogate(const char *artist, const char *album)
|
|
{
|
|
const Eina_List *l;
|
|
Elm_Object_Item *it;
|
|
|
|
EINA_LIST_FOREACH(empc_modapi_queue_list_header_items_find(artist, album), l, it)
|
|
elm_genlist_item_fields_update(it, EMPC_SWALLOW_ALBUM, ELM_GENLIST_ITEM_FIELD_CONTENT);
|
|
}
|
|
|
|
static void
|
|
bg_changed_post(void *d EINA_UNUSED, void *d2 EINA_UNUSED)
|
|
{
|
|
bg_update_propogate(empd_song_artist, empd_song_album);
|
|
}
|
|
|
|
static void
|
|
bg_update_signal(void)
|
|
{
|
|
if (master)
|
|
{
|
|
Evas_Object *cur, *o;
|
|
Eina_Stringshare *f = NULL, *g = NULL;
|
|
|
|
o = elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND);
|
|
cur = bgselector_get(o);
|
|
elm_image_file_get(cur, &f, &g);
|
|
eldbus_service_signal_emit(empc_iface, EMPC_SIGNAL_BACKGROUND_CHANGED, f ?: "", g ?: "");
|
|
}
|
|
bg_ignore = EINA_TRUE;
|
|
}
|
|
|
|
static Evas_Object *
|
|
bg_tooltip_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *tooltip)
|
|
{
|
|
if (bgchooser || (!empd_song_item)) return NULL;
|
|
return tooltip_create(tooltip, empd_song_item);
|
|
}
|
|
|
|
void
|
|
bg_add(void *data EINA_UNUSED, Empc_Fetch_Request *req, Evas_Object *obj)
|
|
{
|
|
Evas_Object *parent;
|
|
|
|
if (!obj)
|
|
{
|
|
if (!bgchooser)
|
|
elm_object_signal_emit(layout, "empc,info,show", "empc");
|
|
return;
|
|
}
|
|
parent = elm_object_parent_widget_get(obj);
|
|
bgselector_image_add(parent, obj);
|
|
if (!bgchooser)
|
|
save_image(EINA_FALSE, obj, NULL, req->artist, req->album, (master && (!bg_updated)) ? bg_update_signal : NULL);
|
|
if (bg_updated) return;
|
|
bg_update_propogate(empd_song_artist, empd_song_album);
|
|
elm_object_signal_emit(layout, "empc,bg,done", "empc");
|
|
bg_updated = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
bg_changed(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
evas_object_hide(elm_object_part_content_unset(layout, EMPC_SWALLOW_BACKGROUND));
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_BACKGROUND, bg[background_num]);
|
|
elm_layout_sizing_eval(layout);
|
|
evas_object_smart_calculate(layout);
|
|
elm_object_signal_emit(layout, "empc,bg,done", "empc");
|
|
if (bgheader_dirty)
|
|
bg_changed_post(NULL, NULL);
|
|
bgheader_dirty = EINA_FALSE;
|
|
}
|
|
|
|
static Empc_Fetch_Request *
|
|
bg_update(int num, Eina_Stringshare *artist, Eina_Stringshare *album, Eina_Stringshare *uri)
|
|
{
|
|
Evas_Object *o;
|
|
|
|
o = bg[num];
|
|
if ((artist != bgselector_artist_get(o)) || (album != bgselector_album_get(o)))
|
|
{
|
|
bgselector_clear(o);
|
|
bgselector_info_set(o, artist, album);
|
|
return metadata_fetch_begin(EMPC_METADATA_TYPE_IMAGE, o, artist, album, uri, EINA_FALSE, EINA_FALSE, bg_add, NULL);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
bg_paste_download_start(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
evas_object_data_set(obj, "__empc_downloading", (void*)1);
|
|
bg_pasting = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
bg_paste_download_done(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
evas_object_data_del(obj, "__empc_downloading");
|
|
bgselector_image_max_recalc(obj);
|
|
bg_pasting = EINA_FALSE;
|
|
if (bgchooser)
|
|
{
|
|
bgselector_image_add(bg[background_num], obj);
|
|
return;
|
|
}
|
|
background_num = bg_next_get();
|
|
bgselector_clear(bg[background_num]);
|
|
bgselector_info_set(bg[background_num], empd_song_artist, empd_song_album);
|
|
bgselector_image_add(bg[background_num], obj);
|
|
elm_object_signal_emit(layout, "empc,bg,next", "empc");
|
|
save_image(EINA_TRUE, obj, NULL, empd_song_artist, empd_song_album, bg_update_signal);
|
|
bg_update_propogate(empd_song_artist, empd_song_album);
|
|
}
|
|
|
|
static void
|
|
bg_paste_download_error(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
evas_object_data_del(obj, "__empc_downloading");
|
|
bg_pasting = EINA_FALSE;
|
|
evas_object_del(obj);
|
|
}
|
|
|
|
static Eina_Bool
|
|
bg_paste(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Elm_Selection_Data *ev)
|
|
{
|
|
if (filesystem_state)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Empc_Entity *ent;
|
|
|
|
it = elm_gengrid_selected_item_get(eina_list_last_data_get(filesystems));
|
|
if (!it) return EINA_TRUE;
|
|
|
|
ent = elm_object_item_data_get(it);
|
|
if (ent->type != MPD_ENTITY_TYPE_DIRECTORY) return EINA_TRUE;
|
|
|
|
evas_object_data_set(win, "__empc_bg_paste", ev);
|
|
elm_gengrid_item_update(it);
|
|
evas_object_data_del(win, "__empc_bg_paste");
|
|
return EINA_TRUE;
|
|
}
|
|
switch (ev->format)
|
|
{
|
|
case ELM_SEL_FORMAT_IMAGE:
|
|
{
|
|
Evas_Object *img;
|
|
|
|
img = elm_image_add(win);
|
|
elm_image_fill_outside_set(img, EINA_FALSE);
|
|
elm_image_smooth_set(img, EINA_FALSE);
|
|
if (elm_image_memfile_set(img, ev->data, ev->len, NULL, NULL))
|
|
{
|
|
unsigned int num = background_num;
|
|
|
|
if (!bgchooser)
|
|
{
|
|
num = background_num = bg_next_get();
|
|
elm_object_signal_emit(layout, "empc,bg,next", "empc");
|
|
bgselector_clear(bg[background_num]);
|
|
bgselector_info_set(bg[background_num], empd_song_artist, empd_song_album);
|
|
save_image(EINA_TRUE, img, NULL, empd_song_artist, empd_song_album, bg_update_signal);
|
|
bg_update_propogate(empd_song_artist, empd_song_album);
|
|
}
|
|
bgselector_image_add(bg[num], img);
|
|
}
|
|
else
|
|
evas_object_del(img);
|
|
}
|
|
break;
|
|
case ELM_SEL_FORMAT_TEXT:
|
|
{
|
|
Evas_Object *img;
|
|
char buf[4096];
|
|
|
|
if (ev->len > sizeof(buf) - 1) break;
|
|
|
|
img = elm_image_add(win);
|
|
elm_image_fill_outside_set(img, EINA_FALSE);
|
|
elm_image_smooth_set(img, EINA_FALSE);
|
|
memcpy(buf, ev->data, ev->len);
|
|
buf[ev->len] = 0;
|
|
evas_object_smart_callback_add(img, "download,start", bg_paste_download_start, buf);
|
|
evas_object_smart_callback_add(img, "download,done", bg_paste_download_done, NULL);
|
|
evas_object_smart_callback_add(img, "download,error", bg_paste_download_error, NULL);
|
|
if (elm_image_file_set(img, buf, NULL))
|
|
{
|
|
unsigned int num = background_num;
|
|
|
|
if ((!bgchooser) && (!evas_object_data_get(img, "__empc_downloading")))
|
|
{
|
|
num = bg_next_get();
|
|
bgselector_clear(bg[num]);
|
|
bgselector_info_set(bg[num], empd_song_artist, empd_song_album);
|
|
/* must be local file, only save uri */
|
|
save_image(EINA_TRUE, NULL, buf, empd_song_artist, empd_song_album, bg_update_signal);
|
|
bg_update_propogate(empd_song_artist, empd_song_album);
|
|
bgselector_image_add(bg[num], img);
|
|
}
|
|
}
|
|
else
|
|
evas_object_del(img);
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
artist_changed(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
elm_object_part_text_set(layout, EMPC_TEXT_ARTIST, empd_song_artist);
|
|
elm_object_signal_emit(layout, "empc,artist,change,2", "empc");
|
|
}
|
|
|
|
static void
|
|
album_changed(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
elm_object_part_text_set(layout, EMPC_TEXT_ALBUM, empd_song_album);
|
|
elm_object_signal_emit(layout, "empc,album,change,2", "empc");
|
|
}
|
|
|
|
static void
|
|
title_text_set(void)
|
|
{
|
|
if (empd_song_track > 0)
|
|
{
|
|
char buf[1024];
|
|
|
|
snprintf(buf, sizeof(buf), "%.2d - %s", empd_song_track, empd_song_title);
|
|
elm_object_part_text_set(layout, EMPC_TEXT_TITLE, buf);
|
|
}
|
|
else
|
|
elm_object_part_text_set(layout, EMPC_TEXT_TITLE, empd_song_title);
|
|
}
|
|
|
|
static void
|
|
title_changed(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
title_text_set();
|
|
elm_object_signal_emit(layout, "empc,title,change,2", "empc");
|
|
}
|
|
|
|
static void
|
|
title_update(void)
|
|
{
|
|
char buf[4096];
|
|
const char *st;
|
|
|
|
switch (empd_state)
|
|
{
|
|
case MPD_STATE_STOP:
|
|
st = "Stopped";
|
|
break;
|
|
case MPD_STATE_PLAY:
|
|
st = "Playing";
|
|
break;
|
|
case MPD_STATE_PAUSE:
|
|
st = "Paused";
|
|
break;
|
|
case MPD_STATE_UNKNOWN:
|
|
default:
|
|
st = "Unknown State";
|
|
break;
|
|
}
|
|
if (empd_song_title && empd_song_artist)
|
|
snprintf(buf, sizeof(buf), "EMPC | %s - %s (%s)", empd_song_artist, empd_song_title, st);
|
|
else if (empd_song_title)
|
|
snprintf(buf, sizeof(buf), "EMPC | %s (%s)", empd_song_title, st);
|
|
else
|
|
snprintf(buf, sizeof(buf), "EMPC | (%s)", st);
|
|
elm_win_title_set(win, buf);
|
|
}
|
|
|
|
static Eina_Bool
|
|
status_update(int state)
|
|
{
|
|
Evas_Object *button, *ic, *o;
|
|
|
|
if (state == empd_state) return EINA_FALSE;
|
|
empd_state = state;
|
|
o = evas_object_data_get(win, "slider");
|
|
button = evas_object_data_get(win, "play_button");
|
|
ic = elm_object_content_get(button);
|
|
switch (state)
|
|
{
|
|
case MPD_STATE_UNKNOWN:
|
|
elm_object_signal_emit(o, "empc,state,unknown", "empc");
|
|
elm_icon_standard_set(ic, "media_player/play");
|
|
break;
|
|
case MPD_STATE_STOP:
|
|
elm_object_signal_emit(o, "empc,state,stopped", "empc");
|
|
elm_icon_standard_set(ic, "media_player/play");
|
|
break;
|
|
case MPD_STATE_PLAY:
|
|
elm_object_signal_emit(o, "empc,state,playing", "empc");
|
|
elm_icon_standard_set(ic, "media_player/pause");
|
|
break;
|
|
case MPD_STATE_PAUSE:
|
|
elm_object_signal_emit(o, "empc,state,paused", "empc");
|
|
elm_icon_standard_set(ic, "media_player/play");
|
|
break;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static int
|
|
songid_update(int songid)
|
|
{
|
|
Eina_Bool artist, album, first = (empd_songid == -1);
|
|
Elm_Object_Item *it, *itp = NULL;
|
|
Empd_Empdd_Song *so, *sop = NULL;
|
|
int ret, uid = background_num;
|
|
|
|
if (empd_songid == songid) return 0;
|
|
/* don't allow set until config has been checked */
|
|
if (config_call) return 0;
|
|
if (empd_songid != -1)
|
|
itp = eina_hash_find(empd_current_queue, &empd_songid);
|
|
it = eina_hash_find(empd_current_queue, &songid);
|
|
/* don't allow set until item exists */
|
|
if (!it) return 0;
|
|
so = elm_object_item_data_get(it);
|
|
/* don't allow set until song exists */
|
|
if (!so) return 0;
|
|
empd_song_item = it;
|
|
if (empd_song_track == -1)
|
|
elm_object_signal_callback_add(layout, "empc,bg,changed", "empc", bg_changed, NULL);
|
|
empd_song_track = so->track;
|
|
eina_stringshare_refplace(&empd_song_title, so->title);
|
|
artist = eina_stringshare_refplace(&empd_song_artist, so->artist);
|
|
album = eina_stringshare_refplace(&empd_song_album, so->album);
|
|
if (artist || album)
|
|
{
|
|
uid = first ? background_num : bg_next_get();
|
|
bg_update(uid, empd_song_artist, empd_song_album, so->uri);
|
|
}
|
|
ret = songid - empd_songid;
|
|
empd_songid = songid;
|
|
if (itp)
|
|
{
|
|
elm_object_item_signal_emit(itp, "empc,state,not_playing", "empc");
|
|
if (elm_genlist_item_parent_get(itp) != elm_genlist_item_parent_get(it))
|
|
{
|
|
elm_object_item_signal_emit(elm_genlist_item_parent_get(itp), "empc,state,not_playing", "empc");
|
|
elm_genlist_item_fields_update(elm_genlist_item_parent_get(itp), EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
elm_genlist_item_fields_update(itp, EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
sop = elm_object_item_data_get(itp);
|
|
}
|
|
else if (first)
|
|
elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
|
|
{
|
|
char buf[128];
|
|
|
|
snprintf(buf, sizeof(buf), "%.2d:%.2d", empd_song_length / 60, empd_song_length % 60);
|
|
elm_object_part_text_set(evas_object_data_get(win, "slider"), "empc.text.length", buf);
|
|
}
|
|
elm_object_item_signal_emit(it, "empc,state,playing", "empc");
|
|
elm_object_item_signal_emit(elm_genlist_item_parent_get(it), "empc,state,playing", "empc");
|
|
elm_genlist_item_fields_update(it, EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_LYRICS, NULL);
|
|
if (lyrics_visible)
|
|
metadata_fetch_begin(EMPC_METADATA_TYPE_TEXT, layout, empd_song_artist, empd_song_title, so->uri, EINA_FALSE, EINA_FALSE, lyrics_set, NULL);
|
|
so = elm_object_item_data_get(it);
|
|
if ((!itp) || (so->album != sop->album) || (so->artist != sop->artist))
|
|
{
|
|
if (bgchooser)
|
|
elm_object_signal_emit(layout, "empc,bg_chooser,stop", "empc");
|
|
if (!first)
|
|
{
|
|
if ((ret >= 0) || (itp && (!elm_genlist_item_next_get(itp))))
|
|
elm_object_signal_emit(layout, "empc,bg,next", "empc");
|
|
else
|
|
elm_object_signal_emit(layout, "empc,bg,prev", "empc");
|
|
}
|
|
if (itp || (uid != background_num))
|
|
background_num = bg_next_get();
|
|
elm_genlist_item_fields_update(elm_genlist_item_parent_get(it), EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
|
|
if ((ret >= 0) || (itp && (!elm_genlist_item_next_get(itp))))
|
|
{
|
|
if ((!itp) || (so->artist != sop->artist))
|
|
elm_object_signal_emit(layout, "empc,artist,change,next", "empc");
|
|
elm_object_signal_emit(layout, "empc,album,change,next", "empc");
|
|
}
|
|
else
|
|
{
|
|
if ((!itp) || (so->artist != sop->artist))
|
|
elm_object_signal_emit(layout, "empc,artist,change,prev", "empc");
|
|
elm_object_signal_emit(layout, "empc,album,change,prev", "empc");
|
|
}
|
|
}
|
|
if (first)
|
|
title_changed(NULL, NULL, NULL, NULL);
|
|
else
|
|
{
|
|
if ((ret >= 0) || (itp && (!elm_genlist_item_next_get(itp))))
|
|
elm_object_signal_emit(layout, "empc,title,change,next", "empc");
|
|
else
|
|
elm_object_signal_emit(layout, "empc,title,change,prev", "empc");
|
|
}
|
|
return ret || artist || album;
|
|
}
|
|
|
|
static const char *
|
|
filesystem_text_helper(Empc_Entity *ent)
|
|
{
|
|
Empd_Empdd_File *file;
|
|
const char *str;
|
|
|
|
if (ent->type != MPD_ENTITY_TYPE_SONG)
|
|
{
|
|
/* playlist and directory structs are identical */
|
|
Empd_Empdd_Directory *dir = ent->value;
|
|
|
|
str = ecore_file_file_get(dir->uri);
|
|
return str ?: dir->uri;
|
|
}
|
|
file = ent->value;
|
|
return file->title;
|
|
}
|
|
|
|
static void
|
|
filesystem_search_visible(void *d EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
elm_object_focus_set(filesystem_entry, 1);
|
|
}
|
|
|
|
static void
|
|
filesystem_search_hidden(void *d EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
elm_entry_entry_set(filesystem_entry, NULL);
|
|
E_FREE_FUNC(filesystem_idler, ecore_idler_del);
|
|
filesystem_idler_pos = NULL;
|
|
}
|
|
|
|
static Eina_Bool
|
|
filesystem_idler_cb(void *ly EINA_UNUSED)
|
|
{
|
|
const char *str;
|
|
double t;
|
|
size_t len;
|
|
|
|
t = ecore_time_get();
|
|
str = elm_entry_entry_get(filesystem_entry);
|
|
len = strlen(str);
|
|
if (!filesystem_idler_pos)
|
|
filesystem_idler_pos = elm_gengrid_first_item_get(eina_list_last_data_get(filesystems));
|
|
while (filesystem_idler_pos && (ecore_time_get() - t < ecore_animator_frametime_get() / 4))
|
|
{
|
|
if (!strncasecmp(filesystem_text_helper(elm_object_item_data_get(filesystem_idler_pos)), str, len))
|
|
{
|
|
if ((eina_list_count(elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems))) != 1) ||
|
|
(!elm_gengrid_item_selected_get(filesystem_idler_pos)))
|
|
{
|
|
const Eina_List *l, *ll;
|
|
Elm_Object_Item *it;
|
|
|
|
EINA_LIST_FOREACH_SAFE(elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems)), l, ll, it)
|
|
elm_gengrid_item_selected_set(it, 0);
|
|
elm_gengrid_item_selected_set(filesystem_idler_pos, EINA_TRUE);
|
|
elm_gengrid_item_bring_in(filesystem_idler_pos, ELM_GENGRID_ITEM_SCROLLTO_MIDDLE);
|
|
}
|
|
E_FREE_FUNC(filesystem_idler, ecore_idler_del);
|
|
return EINA_FALSE;
|
|
}
|
|
filesystem_idler_pos = elm_gengrid_item_next_get(filesystem_idler_pos);
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
filesystem_mouse(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
elm_object_focus_set(filesystem_entry, 1);
|
|
}
|
|
|
|
static void
|
|
filesystem_entry_hide(Evas_Object *ly)
|
|
{
|
|
Evas_Object *fs;
|
|
|
|
fs = elm_object_part_content_get(ly, EMPC_SWALLOW_FILESYSTEM);
|
|
elm_layout_signal_emit(ly, "empc,search,hide", "empc");
|
|
elm_layout_signal_emit(ly, "empc,buttons,show", "empc");
|
|
if (eina_list_count(filesystems) > 1)
|
|
elm_layout_signal_emit(ly, "empc,back,show", "empc");
|
|
else
|
|
elm_layout_signal_emit(ly, "empc,back,hide", "empc");
|
|
elm_object_focus_allow_set(fs, 1);
|
|
elm_object_focus_set(fs, 1);
|
|
}
|
|
|
|
static void
|
|
filesystem_entry_key_select(Eina_Bool forward, int dx, int dy, Eina_Bool multi)
|
|
{
|
|
const Eina_List *l;
|
|
Elm_Object_Item *it, *it2;
|
|
unsigned int x, y, wx, wy;
|
|
Elm_Object_Item *(*fn)(const Elm_Object_Item *) = elm_gengrid_item_next_get;
|
|
|
|
if (!forward)
|
|
fn = elm_gengrid_item_prev_get;
|
|
l = elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems));
|
|
it = eina_list_last_data_get(l);
|
|
if ((eina_list_count(l) > 1) && (!multi))
|
|
while (eina_list_count(l) > 1)
|
|
{
|
|
elm_gengrid_item_selected_set(eina_list_data_get(l), 0);
|
|
l = elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems));
|
|
}
|
|
elm_gengrid_item_pos_get(it, &x, &y);
|
|
if (((!x) && (dx < 0)) || ((!y) && (dy < 0))) return;
|
|
wx = x + dx, wy = y + dy;
|
|
while ((x != wx) || (y != wy))
|
|
{
|
|
it2 = it;
|
|
it = fn(it2);
|
|
if (!it) break;
|
|
elm_gengrid_item_pos_get(it, &x, &y);
|
|
if (forward && ((dx && (x > wx)) || (dy && (y > wy)))) break;
|
|
if ((!forward) && ((dx && (x < wx)) || (dy && (y < wy)))) break;
|
|
}
|
|
if (!it) it = it2;
|
|
if ((!multi) && (eina_list_data_get(l) != it))
|
|
elm_gengrid_item_selected_set(eina_list_data_get(l), 0);
|
|
elm_gengrid_item_selected_set(it, 1);
|
|
elm_gengrid_item_bring_in(filesystem_idler_pos, ELM_GENGRID_ITEM_SCROLLTO_MIDDLE);
|
|
filesystem_entry_hide(elm_object_parent_widget_get(eina_list_last_data_get(filesystems)));
|
|
}
|
|
|
|
static void
|
|
filesystem_entry_key(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
{
|
|
Evas_Event_Key_Down *ev = event_info;
|
|
Evas_Object *ly;
|
|
|
|
ly = elm_object_parent_widget_get(obj);
|
|
if ((!strcmp(ev->key, "Escape")) || (!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
|
|
{
|
|
filesystem_entry_hide(ly);
|
|
if (strcmp(ev->key, "Escape"))
|
|
{
|
|
if (eina_list_count(elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems))) == 1)
|
|
filesystem_next(NULL, NULL, elm_gengrid_selected_item_get(eina_list_last_data_get(filesystems)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!filesystem_idler)
|
|
filesystem_idler = ecore_idler_add(filesystem_idler_cb, ly);
|
|
if (!strcmp(ev->key, "BackSpace"))
|
|
{
|
|
const char *str;
|
|
|
|
filesystem_idler_pos = NULL;
|
|
str = elm_entry_entry_get(filesystem_entry);
|
|
if ((!str) || (!str[0]))
|
|
{
|
|
filesystem_entry_hide(ly);
|
|
E_FREE_FUNC(filesystem_idler, ecore_idler_del);
|
|
}
|
|
}
|
|
}
|
|
elm_layout_signal_emit(layout, "empc,key,down", "empc");
|
|
}
|
|
|
|
static void
|
|
filesystem_key(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
{
|
|
Evas_Event_Key_Down *ev = event_info;
|
|
Evas_Object *ly;
|
|
const char *str;
|
|
|
|
ly = elm_object_parent_widget_get(obj);
|
|
if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
|
|
{
|
|
if (eina_list_count(elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems))) == 1)
|
|
filesystem_next(NULL, NULL, elm_gengrid_selected_item_get(eina_list_last_data_get(filesystems)));
|
|
}
|
|
else if (!strcmp(ev->key, "Escape"))
|
|
{
|
|
if (eina_list_count(filesystems) > 1)
|
|
filesystem_prev();
|
|
}
|
|
else if (ev->compose && (((ev->compose[0] != '\\') && (ev->compose[0] >= ' ')) || ev->compose[1]))
|
|
{
|
|
str = elm_entry_entry_get(filesystem_entry);
|
|
if ((!str) || (!str[0]))
|
|
{
|
|
elm_layout_signal_emit(ly, "empc,search,show", "empc");
|
|
elm_layout_signal_emit(ly, "empc,buttons,hide", "empc");
|
|
elm_object_focus_set(filesystem_entry, 1);
|
|
elm_object_focus_allow_set(obj, 0);
|
|
}
|
|
elm_entry_entry_append(filesystem_entry, ev->compose);
|
|
elm_entry_cursor_end_set(filesystem_entry);
|
|
if (!filesystem_idler)
|
|
filesystem_idler = ecore_idler_add(filesystem_idler_cb, ly);
|
|
}
|
|
elm_layout_signal_emit(layout, "empc,key,down", "empc");
|
|
}
|
|
|
|
static void
|
|
filesystem_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
eina_stringshare_del(evas_object_data_del(obj, "uri"));
|
|
}
|
|
|
|
static void
|
|
filesystem_button_add(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
Evas_Object *o;
|
|
const Eina_List *l, *items;
|
|
Elm_Object_Item *it;
|
|
|
|
o = eina_list_last_data_get(filesystems);
|
|
items = elm_gengrid_selected_items_get(o);
|
|
EINA_LIST_FOREACH(items, l, it)
|
|
{
|
|
Empc_Entity *ent = elm_object_item_data_get(it);
|
|
|
|
switch (ent->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
empd_empdd_add_list_call(empd_proxy, filesystem_entity_name_get(ent));
|
|
break;
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
empd_empdd_load_playlist_call(empd_proxy, filesystem_entity_name_get(ent));
|
|
break;
|
|
}
|
|
}
|
|
if (items || (eina_list_count(filesystems) == 1)) return;
|
|
empd_empdd_add_list_call(empd_proxy, evas_object_data_get(o, "uri"));
|
|
}
|
|
|
|
static void
|
|
filesystem_button_append(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
Eina_Array *old = clipboard;
|
|
|
|
clipboard = eina_array_new(10);
|
|
clipboard_copy();
|
|
clipboard_paste(-1);
|
|
clipboard_clear();
|
|
eina_array_free(clipboard);
|
|
clipboard = old;
|
|
if (ctxpopup)
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
filesystem_button_insert_after(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
Eina_Array *old = clipboard;
|
|
Elm_Object_Item *it;
|
|
Empd_Empdd_Song *so;
|
|
unsigned int total, pos;
|
|
|
|
it = eina_hash_find(empd_current_queue, &empd_songid);
|
|
so = elm_object_item_data_get(it);
|
|
if (data) //after album
|
|
{
|
|
total = elm_genlist_item_subitems_count(elm_genlist_item_parent_get(it));
|
|
pos = so->song_pos + (total - so->track);
|
|
}
|
|
else
|
|
pos = so->song_pos;
|
|
clipboard = eina_array_new(10);
|
|
clipboard_copy();
|
|
clipboard_paste(pos + 1);
|
|
clipboard_clear();
|
|
eina_array_free(clipboard);
|
|
clipboard = old;
|
|
if (ctxpopup)
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
filesystem_button_replace(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
empd_empdd_clear_list_call(empd_proxy);
|
|
filesystem_button_add(NULL, NULL, NULL);
|
|
empd_empdd_play_call(empd_proxy);
|
|
if (ctxpopup)
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
filesystem_ctxpopup_show(Evas_Object *obj)
|
|
{
|
|
Evas_Object *ctx;
|
|
unsigned int num = 0;
|
|
|
|
if (!elm_gengrid_selected_items_get(obj)) return;
|
|
ctxpopup = ctx = ctxpopup_add(obj, "filesystem");
|
|
ctxpopup_item_append(&num, ctx, "Append selection", NULL, filesystem_button_append, NULL);
|
|
if ((empd_state == MPD_STATE_PLAY) || (empd_state == MPD_STATE_PAUSE))
|
|
{
|
|
ctxpopup_item_append(&num, ctx, "Insert after current song", NULL, filesystem_button_insert_after, NULL);
|
|
ctxpopup_item_append(&num, ctx, "Insert after current album", NULL, filesystem_button_insert_after, (void*)1);
|
|
}
|
|
ctxpopup_item_append(&num, ctx, "Replace queue with selection", NULL, filesystem_button_replace, NULL);
|
|
ctxpopup_item_append(&num, ctx, "Copy selection", NULL, ctxpopup_copy, NULL);
|
|
ctxpopup_mouse_position(ctx);
|
|
evas_object_show(ctx);
|
|
}
|
|
|
|
static void
|
|
filesystem_longpress(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
filesystem_ctxpopup_show(obj);
|
|
}
|
|
|
|
static void
|
|
filesystem_click(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
Evas_Event_Mouse_Down *ev = event_info;
|
|
|
|
if (ev->button == 3)
|
|
filesystem_ctxpopup_show(obj);
|
|
}
|
|
|
|
static void
|
|
filesystem_item_realized(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
filesystems_realized = eina_list_append(filesystems_realized, event_info);
|
|
}
|
|
|
|
static void
|
|
filesystem_item_unrealized(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
filesystems_realized = eina_list_remove(filesystems_realized, event_info);
|
|
}
|
|
|
|
static Evas_Object *
|
|
filesystem_new(const char *uri)
|
|
{
|
|
Evas_Object *o;
|
|
|
|
o = elm_gengrid_add(win);
|
|
elm_object_style_set(o, "filesystem");
|
|
evas_object_data_set(o, "uri", eina_stringshare_add(uri));
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, filesystem_del, NULL);
|
|
filesystems = eina_list_append(filesystems, o);
|
|
evas_object_smart_callback_add(o, "realized", filesystem_item_realized, NULL);
|
|
evas_object_smart_callback_add(o, "unrealized", filesystem_item_unrealized, NULL);
|
|
evas_object_smart_callback_add(o, "longpressed", filesystem_longpress, NULL);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, filesystem_click, NULL);
|
|
evas_object_smart_callback_add(o, "clicked,double", filesystem_next, NULL);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, filesystem_key, NULL);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, filesystem_mouse, NULL);
|
|
elm_gengrid_item_size_set(o,
|
|
elm_config_scale_get() * 100,
|
|
elm_config_scale_get() * 125);
|
|
elm_gengrid_multi_select_mode_set(o, ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL);
|
|
elm_gengrid_multi_select_set(o, 1);
|
|
elm_scroller_bounce_set(o, 0, 0);
|
|
elm_scroller_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
|
|
|
|
return o;
|
|
}
|
|
|
|
static void
|
|
filesystem_item_del(Empc_Entity *ent, Evas_Object *obj EINA_UNUSED)
|
|
{
|
|
switch (ent->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
Empd_Empdd_Directory_free(ent->value);
|
|
break;
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
Empd_Empdd_Playlist_free(ent->value);
|
|
break;
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
Empd_Empdd_Song_free(ent->value);
|
|
break;
|
|
}
|
|
free(ent);
|
|
}
|
|
|
|
static char *
|
|
filesystem_item_text_get(Empc_Entity *ent, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
|
|
{
|
|
return strdup(filesystem_text_helper(ent));
|
|
}
|
|
|
|
static void
|
|
filesystem_item_content_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
metadata_fetch_cancel(data, NULL, filesystem_item_image, obj);
|
|
}
|
|
|
|
static void
|
|
filesystem_item_image(void *data, Empc_Fetch_Request *req, Evas_Object *obj)
|
|
{
|
|
Evas_Object *o;
|
|
int w, h;
|
|
|
|
if (req)
|
|
evas_object_event_callback_del_full(data, EVAS_CALLBACK_DEL, filesystem_item_content_del, req);
|
|
if (!obj) return;
|
|
o = ee_image_add();
|
|
ee_image_copy(obj, o, 128);
|
|
EXPAND(o);
|
|
FILL(o);
|
|
evas_object_show(o);
|
|
evas_object_box_append(data, o);
|
|
elm_gengrid_item_size_get(eina_list_data_get(filesystems), &w, &h);
|
|
evas_object_size_hint_max_set(data, w, h);
|
|
evas_object_size_hint_aspect_get(o, NULL, &w, &h);
|
|
evas_object_size_hint_aspect_set(data, EVAS_ASPECT_CONTROL_BOTH, w, h);
|
|
evas_object_event_callback_add(data, EVAS_CALLBACK_DEL, item_box_del, o);
|
|
if (req)
|
|
save_image(EINA_FALSE, obj, NULL, req->artist, req->album, NULL);
|
|
evas_object_del(obj);
|
|
}
|
|
|
|
static void
|
|
filesystem_item_content_get_post_save(void)
|
|
{
|
|
Eina_List *l;
|
|
Elm_Object_Item *it;
|
|
|
|
EINA_LIST_FOREACH(filesystems_realized, l, it)
|
|
elm_gengrid_item_update(it);
|
|
}
|
|
|
|
static void
|
|
filesystem_paste_download_start(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
evas_object_data_set(obj, "__empc_downloading", (void*)1);
|
|
}
|
|
|
|
static Evas_Object *
|
|
filesystem_item_content_get(Empc_Entity *ent, Evas_Object *obj, const char *part EINA_UNUSED)
|
|
{
|
|
Empc_Fetch_Request *req = NULL;
|
|
Evas_Object *cur = NULL, *img = NULL;
|
|
Eina_Stringshare *uri = NULL;
|
|
Elm_Selection_Data *ev;
|
|
|
|
switch (ent->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
{
|
|
/* assumes directory structure:
|
|
*
|
|
* $artist/$album/songs
|
|
*/
|
|
const char *p;
|
|
Empd_Empdd_Directory *dir = ent->value;
|
|
|
|
cur = evas_object_box_add(evas_object_evas_get(obj));
|
|
|
|
ev = evas_object_data_get(win, "__empc_bg_paste");
|
|
p = strchr(dir->uri, '/');
|
|
if (ev)
|
|
{
|
|
img = elm_image_add(win);
|
|
|
|
if (ev->format == ELM_SEL_FORMAT_TEXT)
|
|
{
|
|
if (ev->len > 4096) break;
|
|
|
|
uri = eina_stringshare_add_length((char*)ev->data, ev->len);
|
|
evas_object_smart_callback_add(img, "download,start", filesystem_paste_download_start, NULL);
|
|
if (elm_image_file_set(img, uri, NULL))
|
|
{
|
|
if (evas_object_data_get(img, "__empc_downloading"))
|
|
E_FREE_FUNC(img, evas_object_del);
|
|
else
|
|
{
|
|
evas_object_ref(img);
|
|
filesystem_item_image(cur, NULL, img);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eina_stringshare_del(uri);
|
|
evas_object_del(img);
|
|
evas_object_del(cur);
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (ev->format == ELM_SEL_FORMAT_IMAGE)
|
|
{
|
|
if (elm_image_memfile_set(img, ev->data, ev->len, NULL, NULL))
|
|
{
|
|
evas_object_ref(img);
|
|
filesystem_item_image(cur, NULL, img);
|
|
}
|
|
else
|
|
E_FREE_FUNC(img, evas_object_del);
|
|
}
|
|
}
|
|
if (p)
|
|
{
|
|
char artist[PATH_MAX];
|
|
const char *pp;
|
|
|
|
memcpy(&artist, dir->uri, p - dir->uri);
|
|
artist[p - dir->uri] = 0;
|
|
p += 1;
|
|
pp = strchr(p, '/');
|
|
if (pp)
|
|
{
|
|
char album[PATH_MAX];
|
|
|
|
memcpy(&album, p, pp - p);
|
|
album[pp - p] = 0;
|
|
if (img || uri)
|
|
save_image(EINA_TRUE, uri ? NULL : img, uri, artist, album, uri ? filesystem_item_content_get_post_save : NULL);
|
|
else
|
|
req = metadata_fetch_begin(EMPC_METADATA_TYPE_IMAGE, obj, artist, album, dir->uri, EINA_FALSE, EINA_FALSE, filesystem_item_image, cur);
|
|
}
|
|
else
|
|
{
|
|
if (img || uri)
|
|
save_image(EINA_TRUE, uri ? NULL : img, uri, artist, p, uri ? filesystem_item_content_get_post_save : NULL);
|
|
else
|
|
req = metadata_fetch_begin(EMPC_METADATA_TYPE_IMAGE, obj, artist, p, dir->uri, EINA_FALSE, EINA_FALSE, filesystem_item_image, cur);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (img || uri)
|
|
save_image(EINA_TRUE, uri ? NULL : img, uri, dir->uri, NULL, uri ? filesystem_item_content_get_post_save : NULL);
|
|
else
|
|
req = metadata_fetch_begin(EMPC_METADATA_TYPE_IMAGE, obj, dir->uri, NULL, dir->uri, EINA_FALSE, EINA_FALSE, filesystem_item_image, cur);
|
|
}
|
|
if (img)
|
|
evas_object_unref(img);
|
|
else if (req && (!uri))
|
|
evas_object_event_callback_add(cur, EVAS_CALLBACK_DEL, filesystem_item_content_del, req);
|
|
eina_stringshare_del(uri);
|
|
break;
|
|
}
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
cur = elm_icon_add(obj);
|
|
//elm_icon_standard_set(cur, ic
|
|
break;
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
cur = elm_icon_add(obj);
|
|
elm_icon_standard_set(cur, "audio-x-generic");
|
|
break;
|
|
}
|
|
return cur;
|
|
}
|
|
|
|
static void
|
|
filesystem_item_add(Evas_Object *base, Empc_Entity *ent)
|
|
{
|
|
static Elm_Gengrid_Item_Class itc =
|
|
{
|
|
.item_style = "default",
|
|
.func = {
|
|
.content_get = (Elm_Gengrid_Item_Content_Get_Cb)filesystem_item_content_get,
|
|
.text_get = (Elm_Gengrid_Item_Text_Get_Cb)filesystem_item_text_get,
|
|
.del = (Elm_Gengrid_Item_Del_Cb)filesystem_item_del
|
|
},
|
|
.version = ELM_GENGRID_ITEM_CLASS_VERSION
|
|
};
|
|
|
|
elm_gengrid_item_append(base, &itc, ent, NULL, NULL);
|
|
}
|
|
|
|
static void
|
|
filesystem_base(Eldbus_Proxy *proxy EINA_UNUSED, void *data, Eldbus_Pending *pending EINA_UNUSED, Eldbus_Error_Info *error EINA_UNUSED, Eina_Value *args)
|
|
{
|
|
Eina_Value array;
|
|
unsigned int i;
|
|
Evas_Object *ly;
|
|
|
|
if (!args) return; //canceled
|
|
elm_gengrid_clear(data);
|
|
filesystems_realized = eina_list_free(filesystems_realized);
|
|
eina_value_struct_value_get(args, "arg0", &array);
|
|
for (i = 0; i < eina_value_array_count(&array); i++)
|
|
{
|
|
Eina_Value struc, val, realval;
|
|
int type;
|
|
Empc_Entity *ent;
|
|
|
|
eina_value_array_value_get(&array, i, &struc);
|
|
eina_value_struct_get(&struc, "arg0", &type);
|
|
eina_value_struct_value_get(&struc, "arg1", &val);
|
|
eina_value_struct_value_get(&val, "arg0", &realval);
|
|
ent = malloc(sizeof(Empc_Entity));
|
|
ent->type = type;
|
|
ent->value = NULL;
|
|
switch (type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
azy_value_to_Empd_Empdd_Directory(&realval, (Empd_Empdd_Directory**)&ent->value);
|
|
break;
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
azy_value_to_Empd_Empdd_Playlist(&realval, (Empd_Empdd_Playlist**)&ent->value);
|
|
break;
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
azy_value_to_Empd_Empdd_File(&realval, (Empd_Empdd_File**)&ent->value);
|
|
break;
|
|
}
|
|
filesystem_item_add(data, ent);
|
|
eina_value_flush(&struc);
|
|
eina_value_flush(&val);
|
|
eina_value_flush(&realval);
|
|
}
|
|
eina_value_flush(&array);
|
|
if (eina_list_count(filesystems) == 1) return;
|
|
if (data != eina_list_last_data_get(filesystems)) return;
|
|
ly = elm_object_part_content_get(layout, EMPC_SWALLOW_FILESYSTEM);
|
|
evas_object_hide(elm_object_part_content_unset(ly, EMPC_SWALLOW_FILESYSTEM));
|
|
evas_object_show(data);
|
|
elm_object_part_content_set(ly, EMPC_SWALLOW_FILESYSTEM, data);
|
|
elm_object_part_text_set(ly, "empc.text.path", evas_object_data_get(data, "uri"));
|
|
filesystem_entry_hide(ly);
|
|
E_FREE_FUNC(filesystem_idler, ecore_idler_del);
|
|
filesystem_idler_pos = NULL;
|
|
}
|
|
|
|
static void
|
|
filesystem_next(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
Elm_Object_Item *it = event_info;
|
|
Empc_Entity *ent;
|
|
|
|
if (!empd_connected) return;
|
|
ent = elm_object_item_data_get(it);
|
|
switch (ent->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
{
|
|
Empd_Empdd_Directory *dir = ent->value;
|
|
|
|
empd_empdd_list_info_call(empd_proxy, filesystem_base, filesystem_new(dir->uri), dir->uri);
|
|
}
|
|
break;
|
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
filesystem_prev(void)
|
|
{
|
|
Evas_Object *ly, *fs;
|
|
const Eina_List *l, *ll;
|
|
Elm_Object_Item *it;
|
|
|
|
filesystems_realized = eina_list_free(filesystems_realized);
|
|
filesystems = eina_list_remove_list(filesystems, eina_list_last(filesystems));
|
|
ly = elm_object_part_content_get(layout, EMPC_SWALLOW_FILESYSTEM);
|
|
fs = eina_list_last_data_get(filesystems);
|
|
elm_object_part_content_set(ly, EMPC_SWALLOW_FILESYSTEM, fs);
|
|
E_FREE_FUNC(filesystem_idler, ecore_idler_del);
|
|
elm_object_part_content_set(ly, "empc.swallow.search", filesystem_entry);
|
|
filesystem_entry_hide(ly);
|
|
filesystem_idler_pos = NULL;
|
|
EINA_LIST_FOREACH_SAFE(elm_gengrid_selected_items_get(fs), l, ll, it)
|
|
elm_gengrid_item_selected_set(it, 0);
|
|
if (eina_list_count(filesystems) == 1)
|
|
elm_layout_signal_emit(ly, "empc,back,hide", "empc");
|
|
else
|
|
elm_object_part_text_set(ly, "empc.text.path", evas_object_data_get(fs, "uri"));
|
|
evas_object_show(fs);
|
|
elm_object_focus_set(fs, 1);
|
|
}
|
|
|
|
static void
|
|
filesystem_button_back(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
filesystem_prev();
|
|
}
|
|
|
|
static void
|
|
filesystem_button_update(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
const Eina_List *items, *l;
|
|
Elm_Object_Item *it;
|
|
|
|
items = elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems));
|
|
EINA_LIST_FOREACH(items, l, it)
|
|
{
|
|
Empc_Entity *ent = elm_object_item_data_get(it);
|
|
Empd_Empdd_Directory *dir = ent->value;
|
|
Empd_Empdd_File *f = ent->value;
|
|
|
|
switch (ent->type)
|
|
{
|
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
|
empd_empdd_update_call(empd_proxy, dir->uri);
|
|
break;
|
|
case MPD_ENTITY_TYPE_SONG:
|
|
empd_empdd_update_call(empd_proxy, f->uri);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
if (!items)
|
|
empd_empdd_update_call(empd_proxy, evas_object_data_get(eina_list_last_data_get(filesystems), "uri"));
|
|
}
|
|
|
|
static void
|
|
filesystem_showing(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Eina_List *l;
|
|
|
|
EINA_LIST_FOREACH(filesystems_realized, l, it)
|
|
elm_object_item_signal_emit(it, "empc,state,visible", "empc");
|
|
}
|
|
|
|
static void
|
|
filesystem_show(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
filesystem_state = EINA_TRUE;
|
|
elm_object_focus_set(eina_list_last_data_get(filesystems), 1);
|
|
}
|
|
|
|
static void
|
|
filesystem_hide(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Eina_List *l;
|
|
|
|
EINA_LIST_FOREACH(filesystems_realized, l, it)
|
|
elm_object_item_signal_emit(it, "empc,state,hidden", "empc");
|
|
|
|
filesystem_entry_hide(obj);
|
|
elm_object_focus_set(queue_list, 1);
|
|
filesystem_state = EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
filesystem_hiding(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
evas_object_del(ctxpopup);
|
|
ctxpopup = NULL;
|
|
}
|
|
|
|
static void
|
|
queue_list_cached(Eldbus_Proxy *proxy EINA_UNUSED, void *data, Eldbus_Pending *pending EINA_UNUSED, Eldbus_Error_Info *error EINA_UNUSED, Eina_Value *value)
|
|
{
|
|
if (value)
|
|
queue_list_handler(value, EINA_FALSE);
|
|
if ((empd_songid == -1) && ((long)data == -1))
|
|
empd_empdd_status_call(empd_proxy);
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_bg_changed()
|
|
{
|
|
Empd_Empdd_Song *so;
|
|
const char *uri = NULL;
|
|
Empc_Fetch_Request *req;
|
|
|
|
if (bg_ignore)
|
|
{
|
|
bg_ignore = EINA_FALSE;
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
if (empd_song_item)
|
|
{
|
|
so = elm_object_item_data_get(empd_song_item);
|
|
uri = so->uri;
|
|
}
|
|
background_num = bg_next_get();
|
|
bgselector_clear(bg[background_num]);
|
|
req = bg_update(background_num, empd_song_artist, empd_song_album, uri);
|
|
metadata_fetch_cb_add(req, bg_changed_post, NULL);
|
|
elm_object_signal_emit(layout, "empc,bg,next", "empc");
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static void
|
|
config_cb(Eldbus_Proxy *proxy EINA_UNUSED, void *data EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED, Eldbus_Error_Info *error EINA_UNUSED, const char *music_directory)
|
|
{
|
|
if (music_directory && music_directory[0])
|
|
eina_stringshare_replace(&empd_music_directory, music_directory);
|
|
else
|
|
eina_stringshare_replace(&empd_music_directory, NULL);
|
|
config_call = NULL;
|
|
}
|
|
|
|
static void
|
|
onconnected(Eina_Bool diff, const char *host, unsigned int port)
|
|
{
|
|
empd_connected = EINA_TRUE;
|
|
elm_layout_signal_emit(layout, "empc,login,hidden", "empc");
|
|
login_visible = EINA_FALSE;
|
|
config_call = empd_empdd_config_call(empd_proxy, config_cb, NULL);
|
|
empd_empdd_status_call(empd_proxy);
|
|
if (!diff) return;
|
|
if (!overlay_locked_state)
|
|
elm_layout_signal_emit(layout, "empc,playlist,show,timed", "empc");
|
|
queue_list_clear();
|
|
if (filesystems)
|
|
{
|
|
while (filesystems->next)
|
|
{
|
|
evas_object_del(eina_list_data_get(filesystems->next));
|
|
filesystems = eina_list_remove_list(filesystems, filesystems->next);
|
|
}
|
|
elm_gengrid_clear(eina_list_data_get(filesystems));
|
|
}
|
|
eina_stringshare_replace(&empd_host, host);
|
|
empd_port = port;
|
|
}
|
|
|
|
static void
|
|
login_show(const char *header, const char *host, unsigned int port)
|
|
{
|
|
char buf[8];
|
|
Eina_Stringshare *str;
|
|
|
|
if (host && host[0])
|
|
elm_entry_entry_set(login_host, host);
|
|
else
|
|
{
|
|
str = elm_entry_entry_get(login_host);
|
|
if ((!str) || (!str[0]))
|
|
elm_entry_entry_set(login_host, "127.0.0.1");
|
|
}
|
|
|
|
elm_entry_cursor_begin_set(login_host);
|
|
elm_entry_select_all(login_host);
|
|
if (port)
|
|
{
|
|
snprintf(buf, sizeof(buf), "%u", port);
|
|
elm_entry_entry_set(login_port, buf);
|
|
}
|
|
else
|
|
{
|
|
str = elm_entry_entry_get(login_port);
|
|
if ((!str) || (!str[0]))
|
|
elm_entry_entry_set(login_port, "6600");
|
|
}
|
|
elm_entry_cursor_begin_set(login_port);
|
|
login_visible = EINA_TRUE;
|
|
elm_object_part_text_set(layout, EMPC_LOGIN_TEXT_HEADER, header);
|
|
elm_layout_signal_emit(layout, "empc,login,visible", "empc");
|
|
elm_object_focus_set(login_host, 1);
|
|
}
|
|
|
|
static void
|
|
empc_isconnected(Eldbus_Proxy *proxy EINA_UNUSED, void *data EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED, Eldbus_Error_Info *error, Eina_Bool connected, const char *host, unsigned int port)
|
|
{
|
|
if (error && error->error && error->error[0])
|
|
{
|
|
error_o_doom();
|
|
return;
|
|
}
|
|
if (connected)
|
|
onconnected(EINA_TRUE, host, port);
|
|
else
|
|
login_show("Enter server info", host, port);
|
|
}
|
|
|
|
static void
|
|
login_close_request(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
if (empd_connected)
|
|
{
|
|
elm_layout_signal_emit(layout, "empc,login,hidden", "empc");
|
|
login_visible = EINA_FALSE;
|
|
}
|
|
}
|
|
|
|
static void
|
|
login_connect(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
int port = -1;
|
|
const char *p;
|
|
|
|
p = elm_entry_entry_get(login_port);
|
|
if (p && p[0])
|
|
port = strtol(p, NULL, 10);
|
|
empd_empdd_connect_call(empd_proxy, elm_entry_entry_get(login_host), port, elm_entry_entry_get(login_password));
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_connected(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empdd_Connected_Data *ev)
|
|
{
|
|
onconnected((!empd_host) || ((strcmp(empd_host, ev->host)) || (empd_port != ev->port)), ev->host, ev->port);
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_disconnected(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empdd_Disconnected_Data *ev EINA_UNUSED)
|
|
{
|
|
empd_connected = EINA_FALSE;
|
|
if (empd_state != MPD_STATE_UNKNOWN)
|
|
status_update(MPD_STATE_STOP);
|
|
login_show("Connection lost", empd_host, empd_port);
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_login_fail(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empdd_LoginFailed_Data *ev)
|
|
{
|
|
if (login_visible)
|
|
{
|
|
elm_object_part_text_set(layout, EMPC_LOGIN_TEXT_HEADER, "Authentication failed");
|
|
elm_layout_signal_emit(layout, "empc,login,failed", "empc");
|
|
}
|
|
else
|
|
login_show("Authentication failed", ev->host, ev->port);
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_permission_fail(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empdd_PermissionFailed_Data *ev)
|
|
{
|
|
if (ev->code) //code 0 is non-local clients denied
|
|
login_show("Enter password", ev->host, ev->port);
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_database_end()
|
|
{
|
|
Evas_Object *o;
|
|
Eina_List *l;
|
|
|
|
EINA_LIST_REVERSE_FOREACH(filesystems, l, o)
|
|
empd_empdd_list_info_call(empd_proxy, filesystem_base, o, evas_object_data_get(o, "uri"));
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_status(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empdd_Status_Data *ev)
|
|
{
|
|
Eina_Bool up = EINA_FALSE;
|
|
Evas_Object *o;
|
|
|
|
elm_check_state_set(repeat, ev->repeat);
|
|
elm_check_state_set(shuffle, ev->random);
|
|
elm_check_state_set(single, ev->single);
|
|
elm_check_state_set(consume, ev->consume);
|
|
up = (empd_song_length != ev->song_length) || (empd_song_elapsed != ev->song_elapsed);
|
|
if (up)
|
|
{
|
|
o = evas_object_data_get(win, "slider");
|
|
empd_song_length = ev->song_length;
|
|
empd_song_elapsed = ev->song_elapsed;
|
|
if (evas_object_visible_get(win))
|
|
{
|
|
char buf[128];
|
|
|
|
snprintf(buf, sizeof(buf), "%.2d:%.2d", ev->song_elapsed / 60, ev->song_elapsed % 60);
|
|
elm_slider_value_set(o, (double)ev->song_elapsed / (double)ev->song_length);
|
|
elm_object_part_text_set(o, "empc.text.elapsed", buf);
|
|
}
|
|
if (empd_song_item && (empd_song_length - empd_song_elapsed == 5)) //try to fetch metadata at 5 seconds remaining
|
|
{
|
|
Elm_Object_Item *it;
|
|
Empd_Empdd_Song *so;
|
|
|
|
it = elm_genlist_item_next_get(empd_song_item);
|
|
if (!it)
|
|
it = elm_genlist_first_item_get(queue_list);
|
|
so = elm_object_item_data_get(it);
|
|
if ((so->artist != empd_song_artist) || (so->album != empd_song_album))
|
|
bg_update(bg_next_get(), so->artist, so->album, so->uri);
|
|
}
|
|
//if (empd_song_item && queue_list_state)
|
|
//elm_genlist_item_fields_update(empd_song_item, EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
if (songid_update(ev->songid) | status_update(ev->state))
|
|
title_update();
|
|
if (clipboard_paste_length)
|
|
{
|
|
long num = ev->queue_length - clipboard_paste_length;
|
|
|
|
if (num)
|
|
{
|
|
empd_empdd_move_list_call(empd_proxy, clipboard_paste_length, num, clipboard_paste_id);
|
|
/* handle paste insertions */
|
|
clipboard_paste_length = 0;
|
|
clipboard_paste_id = -1;
|
|
}
|
|
}
|
|
|
|
/* this should only run on startup...other updates are automatic */
|
|
if ((!empd_queue_length) && ev->queue_length && (empd_queue_length != ev->queue_length))
|
|
{
|
|
/* load current playlist incrementally (max 30):
|
|
* - don't block daemon forever with large playlists
|
|
* - GREATLY decreases startup delay when showing list
|
|
* - don't block ui when receiving huge playlists
|
|
*/
|
|
unsigned int i, step = ((ev->queue_length / 4) % 31) + 3;
|
|
for (i = 0; i < ev->queue_length; i += step)
|
|
{
|
|
long num = step;
|
|
|
|
if (i + num >= ev->queue_length)
|
|
num = -1;
|
|
|
|
empd_empdd_queue_list_cached_range_call(empd_proxy, queue_list_cached, (void*)num, i, num);
|
|
}
|
|
}
|
|
empd_queue_length = ev->queue_length;
|
|
if (!filesystems)
|
|
{
|
|
elm_object_part_content_set(layout_filesystem, EMPC_SWALLOW_FILESYSTEM, filesystem_new("/"));
|
|
empd_empdd_list_info_call(empd_proxy, filesystem_base, eina_list_data_get(filesystems), "/");
|
|
}
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Evas_Object *
|
|
queue_list_item_tooltip_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *tooltip, void *item)
|
|
{
|
|
return tooltip_create(tooltip, item);
|
|
}
|
|
|
|
static void
|
|
queue_list_item_unrealize(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
queue_list_realized = eina_list_remove(queue_list_realized, event_info);
|
|
}
|
|
|
|
static void
|
|
queue_list_item_realize(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
Elm_Object_Item *it = event_info;
|
|
Empd_Empdd_Song *so;
|
|
|
|
so = elm_object_item_data_get(it);
|
|
if (empd_songid == so->songid)
|
|
elm_object_item_signal_emit(it, "empc,state,playing", "empc");
|
|
else if (elm_genlist_item_subitems_count(it))
|
|
{
|
|
if (eina_list_data_find(elm_genlist_item_subitems_get(it), empd_song_item))
|
|
elm_object_item_signal_emit(it, "empc,state,playing", "empc");
|
|
else
|
|
elm_object_item_signal_emit(it, "empc,state,not_playing", "empc");
|
|
}
|
|
else
|
|
elm_object_item_signal_emit(it, "empc,state,not_playing", "empc");
|
|
elm_object_item_tooltip_content_cb_set(it, queue_list_item_tooltip_cb, NULL, NULL);
|
|
elm_object_item_tooltip_style_set(it, "empc");
|
|
elm_object_item_tooltip_window_mode_set(it, EINA_TRUE);
|
|
queue_list_realized = eina_list_append(queue_list_realized, it);
|
|
}
|
|
|
|
static void
|
|
queue_list_delete_list(const Eina_List *items)
|
|
{
|
|
Eina_List *l;
|
|
int start = -1, num = 0, total = 0;
|
|
Elm_Object_Item *it, *next;
|
|
Eina_Bool del_playing = EINA_FALSE;
|
|
Empd_Empdd_Song *so;
|
|
|
|
if (!items) return;
|
|
l = eina_list_sort(eina_list_clone(items), 0, (Eina_Compare_Cb)queue_list_sort);
|
|
EINA_LIST_FREE(l, it)
|
|
{
|
|
/* check for contiguous selection */
|
|
so = elm_object_item_data_get(it);
|
|
if (start == -1)
|
|
start = so->song_pos, num = 1;
|
|
if (empd_songid == so->songid)
|
|
del_playing = EINA_TRUE;
|
|
next = elm_genlist_item_next_get(it);
|
|
/* fragmentation detected */
|
|
if ((next != eina_list_data_get(l->next)) &&
|
|
(!elm_genlist_item_subitems_count(next)))
|
|
{
|
|
//fprintf(stderr, "DEL %d:%d\n", start, num);
|
|
empd_empdd_delete_list_range_call(empd_proxy, start, num);
|
|
if (del_playing && (empd_state == MPD_STATE_PLAY))
|
|
empd_empdd_play_pos_call(empd_proxy, start - total);
|
|
start = -1, num = 0;
|
|
if (!del_playing)
|
|
total += num;
|
|
}
|
|
else
|
|
num++;
|
|
}
|
|
if (!num) return;
|
|
empd_empdd_delete_list_range_call(empd_proxy, start, num - 1);
|
|
if ((!del_playing) || (empd_state != MPD_STATE_PLAY)) return;
|
|
if ((unsigned int)start < empd_queue_length - ((unsigned int)num - 1))
|
|
empd_empdd_play_pos_call(empd_proxy, start - total);
|
|
else
|
|
empd_empdd_play_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
queue_list_delete_selected(void)
|
|
{
|
|
queue_list_delete_list(elm_genlist_selected_items_get(queue_list));
|
|
}
|
|
|
|
static void
|
|
queue_list_delete_inverted(void)
|
|
{
|
|
const Eina_List *items;
|
|
Eina_List *l;
|
|
int start = -1;
|
|
Elm_Object_Item *it, *prev, *next, *hdr = NULL;
|
|
int del_playing = -1;
|
|
long long song_pos = -1;
|
|
Empd_Empdd_Song *so;
|
|
|
|
items = elm_genlist_selected_items_get(queue_list);
|
|
if (!items) return;
|
|
l = eina_list_clone(items);
|
|
l = eina_list_sort(l, 0, (Eina_Compare_Cb)queue_list_sort);
|
|
it = eina_list_data_get(l);
|
|
so = elm_object_item_data_get(empd_song_item);
|
|
if (so)
|
|
song_pos = so->song_pos;
|
|
so = elm_object_item_data_get(it);
|
|
/* clear songs before selection */
|
|
if (so->song_pos)
|
|
{
|
|
empd_empdd_delete_list_range_call(empd_proxy, 0, so->song_pos);
|
|
if (song_pos < so->song_pos)
|
|
{
|
|
del_playing = 0;
|
|
empd_empdd_play_id_call(empd_proxy, 0);
|
|
}
|
|
}
|
|
EINA_LIST_FREE(l, it)
|
|
{
|
|
if (hdr != elm_genlist_item_parent_get(it))
|
|
hdr = elm_genlist_item_parent_get(it);
|
|
next = elm_genlist_item_next_get(it);
|
|
prev = elm_genlist_item_prev_get(it);
|
|
so = elm_object_item_data_get(next);
|
|
if (it == empd_song_item)
|
|
del_playing = 0;
|
|
/* check for contiguous selection */
|
|
if ((del_playing == 1) && (empd_state == MPD_STATE_PLAY))
|
|
{
|
|
empd_empdd_play_id_call(empd_proxy, so->songid);
|
|
del_playing = 0;
|
|
}
|
|
/* fragmentation detected */
|
|
if (next != eina_list_data_get(l->next))
|
|
{
|
|
so = elm_object_item_data_get(next);
|
|
start = so->song_pos;
|
|
}
|
|
if ((start != -1) && (hdr != elm_genlist_item_parent_get(prev)))
|
|
{
|
|
//fprintf(stderr, "DEL %d:%d\n", start, num);
|
|
so = elm_object_item_data_get(prev);
|
|
empd_empdd_delete_list_range_call(empd_proxy, start, (so->song_pos - start) + 1);
|
|
if ((del_playing == -1) && (song_pos < so->song_pos))
|
|
{
|
|
empd_empdd_play_id_call(empd_proxy, so->songid);
|
|
del_playing = 0;
|
|
}
|
|
start = -1;
|
|
}
|
|
}
|
|
if (start == -1) return;
|
|
empd_empdd_delete_list_range_call(empd_proxy, start, -1);
|
|
if ((!del_playing) || (empd_state != MPD_STATE_PLAY)) return;
|
|
empd_empdd_play_pos_call(empd_proxy, 0);
|
|
}
|
|
|
|
static void
|
|
queue_list_ctxpopup_delete(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
queue_list_delete_selected();
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
queue_list_ctxpopup_crop(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
queue_list_delete_inverted();
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
queue_list_ctxpopup_cut(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
clipboard_copy();
|
|
queue_list_delete_selected();
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
queue_list_ctxpopup_paste(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
clipboard_paste(-1);
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
queue_list_ctxpopup_paste_selection(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
const Eina_List *items;
|
|
Eina_List *l;
|
|
Elm_Object_Item *it;
|
|
Empd_Empdd_Song *so;
|
|
intptr_t *after = data;
|
|
|
|
items = elm_genlist_selected_items_get(queue_list);
|
|
if (!items) return;
|
|
l = eina_list_clone(items);
|
|
l = eina_list_sort(l, 0, (Eina_Compare_Cb)queue_list_sort);
|
|
if (after)
|
|
it = eina_list_last_data_get(l);
|
|
else
|
|
it = eina_list_data_get(l);
|
|
so = elm_object_item_data_get(it);
|
|
clipboard_paste(so->song_pos + (long)after);
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
playlist_ctxpopup_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
Eina_Stringshare *uri;
|
|
|
|
EINA_LIST_FREE(data, uri)
|
|
eina_stringshare_del(uri);
|
|
}
|
|
|
|
static void
|
|
playlist_save(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
Eina_Stringshare *uri, *name;
|
|
|
|
name = elm_entry_entry_get(obj);
|
|
if ((!name) || (!name[0])) return;
|
|
if (data)
|
|
{
|
|
evas_object_event_callback_del(ctxpopup, EVAS_CALLBACK_DEL, playlist_ctxpopup_del);
|
|
EINA_LIST_FREE(data, uri)
|
|
{
|
|
empd_empdd_add_to_playlist_call(empd_proxy, name, uri);
|
|
eina_stringshare_del(uri);
|
|
}
|
|
}
|
|
else
|
|
empd_empdd_save_playlist_call(empd_proxy, name);
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
queue_list_ctxpopup_save(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
Evas_Object *ctx, *o;
|
|
int x, y, w, h, ox, oy, ow, oh;
|
|
Eina_List *save = NULL;
|
|
|
|
evas_object_geometry_get(ctxpopup, &ox, &oy, &ow, &oh);
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
if (data)
|
|
{
|
|
const Eina_List *items;
|
|
Eina_List *l;
|
|
Elm_Object_Item *it;
|
|
Empd_Empdd_Song *so;
|
|
|
|
items = elm_genlist_selected_items_get(queue_list);
|
|
if (!items) return;
|
|
l = eina_list_clone(items);
|
|
l = eina_list_sort(l, 0, (Eina_Compare_Cb)queue_list_sort);
|
|
EINA_LIST_FREE(l, it)
|
|
{
|
|
so = elm_object_item_data_get(it);
|
|
save = eina_list_append(save, eina_stringshare_ref(so->uri));
|
|
}
|
|
}
|
|
ctxpopup = ctx = ctxpopup_add(queue_list, "queue_list");
|
|
o = elm_entry_add(ctxpopup);
|
|
elm_entry_single_line_set(o, 1);
|
|
elm_entry_scrollable_set(o, 0);
|
|
elm_object_style_set(o, "playlist_save");
|
|
evas_object_smart_callback_add(o, "activated", playlist_save, save);
|
|
if (save)
|
|
evas_object_event_callback_add(ctxpopup, EVAS_CALLBACK_DEL, playlist_ctxpopup_del, save);
|
|
elm_entry_entry_set(o, "<Enter playlist name>");
|
|
evas_object_size_hint_min_set(o, 40, 10);
|
|
elm_object_content_set(ctx, o);
|
|
evas_object_show(ctx);
|
|
evas_object_geometry_get(ctx, NULL, NULL, &w, &h);
|
|
x = ox + (ow / 2);
|
|
y = oy + (oh / 2);
|
|
evas_object_move(ctx, x - (w / 2), y - (h / 2));
|
|
}
|
|
|
|
static void
|
|
queue_list_ctxpopup_show(Evas_Object *obj)
|
|
{
|
|
Evas_Object *ctx;
|
|
const Eina_List *sel;
|
|
unsigned int num = 0;
|
|
|
|
ctxpopup = ctx = ctxpopup_add(obj, "queue_list");
|
|
sel = elm_genlist_selected_items_get(queue_list);
|
|
ctxpopup_item_append(&num, ctx, "Save to playlist", NULL, queue_list_ctxpopup_save, NULL);
|
|
if (sel)
|
|
{
|
|
ctxpopup_item_append(&num, ctx, "Save selection to playlist", NULL, queue_list_ctxpopup_save, (void*)1);
|
|
ctxpopup_item_append(&num, ctx, "Delete selection", NULL, queue_list_ctxpopup_delete, NULL);
|
|
ctxpopup_item_append(&num, ctx, "Crop to selection", NULL, queue_list_ctxpopup_crop, NULL);
|
|
ctxpopup_item_append(&num, ctx, "Cut selection", NULL, queue_list_ctxpopup_cut, NULL);
|
|
ctxpopup_item_append(&num, ctx, "Copy selection", NULL, ctxpopup_copy, NULL);
|
|
}
|
|
if (eina_array_count(clipboard))
|
|
{
|
|
ctxpopup_item_append(&num, ctx, "Paste", NULL, queue_list_ctxpopup_paste, NULL);
|
|
if (sel)
|
|
{
|
|
ctxpopup_item_append(&num, ctx, "Paste before selection", NULL, queue_list_ctxpopup_paste_selection, NULL);
|
|
ctxpopup_item_append(&num, ctx, "Paste after selection", NULL, queue_list_ctxpopup_paste_selection, (void*)1);
|
|
}
|
|
}
|
|
|
|
ctxpopup_mouse_position(ctxpopup);
|
|
evas_object_show(ctxpopup);
|
|
}
|
|
|
|
static void
|
|
queue_list_item_longpress(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
queue_list_ctxpopup_show(obj);
|
|
}
|
|
|
|
static void
|
|
queue_list_item_click(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
{
|
|
Evas_Event_Mouse_Down *ev = event_info;
|
|
|
|
if (ev->button == 3)
|
|
queue_list_ctxpopup_show(obj);
|
|
}
|
|
|
|
static void
|
|
queue_list_double_click(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
Elm_Object_Item *it = event_info;
|
|
Empd_Empdd_Song *so;
|
|
|
|
so = elm_object_item_data_get(it);
|
|
empd_empdd_play_id_call(empd_proxy, so->songid);
|
|
}
|
|
|
|
static void
|
|
queue_list_scroll_stop()
|
|
{
|
|
queue_list_scroll_item = NULL;
|
|
}
|
|
|
|
static char *
|
|
queue_list_header_text_get(Empd_Empdd_Song *so, Evas_Object *obj EINA_UNUSED, const char *part)
|
|
{
|
|
char buf[1024];
|
|
const Eina_List *l;
|
|
Elm_Object_Item *it, *itg, *iti;
|
|
size_t t = 0;
|
|
|
|
if (!strcmp(part, EMPC_TEXT_ALBUM))
|
|
{
|
|
if (so->artist && so->album)
|
|
{
|
|
snprintf(buf, sizeof(buf), "%s: %s", so->artist, so->album);
|
|
return strdup(buf);
|
|
}
|
|
if (so->artist)
|
|
return strdup(so->artist);
|
|
return strdup(so->album);
|
|
}
|
|
it = eina_hash_find(empd_current_queue, &so->songid);
|
|
if (!it) return NULL; //redo later
|
|
itg = elm_genlist_item_parent_get(it);
|
|
EINA_LIST_FOREACH(elm_genlist_item_subitems_get(itg), l, iti)
|
|
{
|
|
Empd_Empdd_Song *soi = elm_object_item_data_get(iti);
|
|
|
|
t += soi->duration;
|
|
}
|
|
snprintf(buf, sizeof(buf), "%.2ld:%.2ld", t / 60, t % 60);
|
|
return strdup(buf);
|
|
}
|
|
|
|
static void
|
|
queue_list_header_content_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, queue_list_header_content_del);
|
|
metadata_fetch_cancel(data, NULL, queue_list_header_image, obj);
|
|
}
|
|
|
|
static void
|
|
queue_list_header_image(void *data, Empc_Fetch_Request *req, Evas_Object *obj)
|
|
{
|
|
Evas_Object *o;
|
|
|
|
evas_object_event_callback_del_full(data, EVAS_CALLBACK_DEL, queue_list_header_content_del, req);
|
|
if (!obj) return;
|
|
o = ee_image_add();
|
|
ee_image_copy(obj, o, 64);
|
|
EXPAND(o);
|
|
FILL(o);
|
|
evas_object_show(o);
|
|
evas_object_box_append(data, o);
|
|
evas_object_event_callback_add(data, EVAS_CALLBACK_DEL, item_box_del, o);
|
|
evas_object_del(obj);
|
|
}
|
|
|
|
static Evas_Object *
|
|
queue_list_header_content_get(Empd_Empdd_Song *so, Evas_Object *obj, const char *part EINA_UNUSED)
|
|
{
|
|
Evas_Object *o, *cur;
|
|
|
|
if ((so->album != empd_song_album) || (so->artist != empd_song_artist))
|
|
{
|
|
Empc_Fetch_Request *req;
|
|
|
|
cur = evas_object_box_add(evas_object_evas_get(obj));
|
|
EXPAND(cur);
|
|
FILL(cur);
|
|
req = metadata_fetch_begin(EMPC_METADATA_TYPE_IMAGE, obj, so->artist, so->album, so->uri, EINA_FALSE, EINA_FALSE, queue_list_header_image, cur);
|
|
evas_object_event_callback_add(cur, EVAS_CALLBACK_DEL, queue_list_header_content_del, req);
|
|
return cur;
|
|
}
|
|
|
|
o = elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND);
|
|
if ((bgselector_artist_get(o) != empd_song_artist) ||
|
|
(bgselector_album_get(o) != empd_song_album))
|
|
goto error;
|
|
cur = bgselector_get(o);
|
|
if (!cur) goto error;
|
|
|
|
o = ee_image_add();
|
|
ee_image_copy(cur, o, 64);
|
|
evas_object_size_hint_aspect_set(o, EVAS_ASPECT_CONTROL_NONE, 0, 0);
|
|
return o;
|
|
error:
|
|
bgheader_dirty = EINA_TRUE;
|
|
return NULL;
|
|
}
|
|
|
|
static char *
|
|
queue_list_item_text_get(Empd_Empdd_Song *so, Evas_Object *obj EINA_UNUSED, const char *part)
|
|
{
|
|
char buf[1024];
|
|
|
|
if (!strcmp(part, EMPC_TEXT_TITLE))
|
|
return strdup(so->title ?: so->uri);
|
|
if (!strcmp(part, EMPC_TEXT_TRACK))
|
|
{
|
|
if (!so->track) return NULL;
|
|
snprintf(buf, sizeof(buf), "%.2d", so->track);
|
|
return strdup(buf);
|
|
}
|
|
//if (empd_songid == so->songid) return NULL;
|
|
//snprintf(buf, sizeof(buf), "%.2d:%.2d / %.2d:%.2d",
|
|
//empd_song_elapsed / 60, empd_song_elapsed % 60,
|
|
//empd_song_length / 60, empd_song_length % 60);
|
|
//else
|
|
snprintf(buf, sizeof(buf), "%.2ld:%.2ld", so->duration / 60, so->duration % 60);
|
|
return strdup(buf);
|
|
}
|
|
|
|
static void
|
|
queue_list_header_del(Empd_Empdd_Song *so, Evas_Object *obj EINA_UNUSED)
|
|
{
|
|
Empd_Empdd_Song_free(so);
|
|
}
|
|
|
|
static void
|
|
queue_list_item_del(Empd_Empdd_Song *so, Evas_Object *obj EINA_UNUSED)
|
|
{
|
|
Elm_Object_Item *it, *itg;
|
|
Empd_Empdd_Song *sog = NULL;
|
|
|
|
if (empd_song_item && (elm_object_item_data_get(empd_song_item) == so))
|
|
empd_song_item = NULL;
|
|
it = eina_hash_set(empd_current_queue, &so->songid, NULL);
|
|
itg = elm_genlist_item_parent_get(it);
|
|
if (itg)
|
|
sog = elm_object_item_data_get(itg);
|
|
if (empd_songid == so->songid)
|
|
{
|
|
elm_object_item_signal_emit(itg, "empc,state,not_playing", "empc");
|
|
elm_genlist_item_fields_update(itg, EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
if (sog && (sog->songid == so->songid))
|
|
{
|
|
it = elm_genlist_item_next_get(it);
|
|
if (it && (elm_genlist_item_parent_get(it) == itg))
|
|
{
|
|
Empd_Empdd_Song_free(sog);
|
|
elm_object_item_data_set(itg, Empd_Empdd_Song_copy(elm_object_item_data_get(it)));
|
|
elm_genlist_item_fields_update(itg, EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
else if (!elm_genlist_item_subitems_count(itg))
|
|
{
|
|
char buf[1024];
|
|
|
|
snprintf(buf, sizeof(buf), "%s:::%s", so->artist, so->album);
|
|
//INF("DEL HEADER(%p): %s", itg, buf);
|
|
eina_hash_list_remove(empd_current_queue_headers, buf, itg);
|
|
if (itg == queue_list_scroll_item)
|
|
queue_list_scroll_item = NULL;
|
|
elm_object_item_del(itg);
|
|
}
|
|
else
|
|
elm_genlist_item_fields_update(itg, EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
Empd_Empdd_Song_free(so);
|
|
}
|
|
|
|
static void
|
|
queue_list_key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Empd_Empdd_Song *so;
|
|
Evas_Event_Key_Down *ev = event_info;
|
|
|
|
if ((!strcmp(ev->key, "KP_Enter")) || (!strcmp(ev->key, "Return")))
|
|
{
|
|
it = elm_genlist_selected_item_get(obj);
|
|
if (!it) return;
|
|
so = elm_object_item_data_get(it);
|
|
empd_empdd_play_id_call(empd_proxy, so->songid);
|
|
}
|
|
else if (!strcmp(ev->key, "Delete"))
|
|
queue_list_delete_selected();
|
|
else if (!strcmp(ev->key, "Home"))
|
|
{
|
|
it = elm_genlist_first_item_get(queue_list);
|
|
elm_genlist_item_selected_set(it, EINA_TRUE);
|
|
elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
|
|
}
|
|
else if (!strcmp(ev->key, "End"))
|
|
{
|
|
it = elm_genlist_last_item_get(queue_list);
|
|
if (elm_genlist_item_subitems_count(it))
|
|
it = eina_list_last_data_get(elm_genlist_item_subitems_get(it));
|
|
elm_genlist_item_selected_set(it, EINA_TRUE);
|
|
elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
|
|
}
|
|
}
|
|
|
|
static Elm_Object_Item *
|
|
queue_list_find_insert_point(Empd_Empdd_Song *so)
|
|
{
|
|
Elm_Object_Item *it, *itp;
|
|
Empd_Empdd_Song *soi;
|
|
|
|
if (!elm_genlist_items_count(queue_list)) return NULL;
|
|
if ((unsigned int)so->song_pos > (elm_genlist_items_count(queue_list) / 2))
|
|
{
|
|
it = elm_genlist_last_item_get(queue_list);
|
|
do
|
|
{
|
|
soi = elm_object_item_data_get(it);
|
|
if (so->song_pos >= soi->song_pos) return it;
|
|
it = elm_genlist_item_prev_get(it);
|
|
} while (it);
|
|
return NULL;
|
|
}
|
|
|
|
itp = it = elm_genlist_first_item_get(queue_list);
|
|
do
|
|
{
|
|
soi = elm_object_item_data_get(it);
|
|
if (so->song_pos <= soi->song_pos) return itp;
|
|
itp = it;
|
|
it = elm_genlist_item_next_get(it);
|
|
} while (it);
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
queue_list_item_select(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
{
|
|
Elm_Object_Item *i, *itp, *it = event_info;
|
|
const Eina_List *items;
|
|
Elm_Object_Item *(*fn)(const Elm_Object_Item*) = elm_genlist_item_prev_get;
|
|
|
|
if (selecting || unselecting) return;
|
|
if (!evas_key_modifier_is_set(evas_key_modifier_get(evas_object_evas_get(obj)), "Shift"))
|
|
{
|
|
const Eina_List *li, *lli;
|
|
if (evas_key_modifier_is_set(evas_key_modifier_get(evas_object_evas_get(obj)), "Control")) return;
|
|
selecting = EINA_TRUE;
|
|
items = elm_genlist_selected_items_get(obj);
|
|
EINA_LIST_FOREACH_SAFE(items, li, lli, i)
|
|
elm_genlist_item_selected_set(i, (i == it));
|
|
selecting = EINA_FALSE;
|
|
return;
|
|
}
|
|
items = elm_genlist_selected_items_get(obj);
|
|
if (eina_list_count(items) == 1) return;
|
|
selecting = EINA_TRUE;
|
|
itp = eina_list_data_get(items);
|
|
if (queue_list_sort(itp, it) >= 0)
|
|
fn = elm_genlist_item_next_get;
|
|
for (i = fn(it); i != itp; i = fn(i))
|
|
{
|
|
if (!elm_genlist_item_subitems_count(i))
|
|
elm_genlist_item_selected_set(i, EINA_TRUE);
|
|
}
|
|
selecting = EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
queue_list_item_unselect(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
{
|
|
Elm_Object_Item *i, *itp, *it = event_info;
|
|
const Eina_List *items, *l, *ll;
|
|
|
|
if (selecting || unselecting) return;
|
|
if (!evas_key_modifier_is_set(evas_key_modifier_get(evas_object_evas_get(obj)), "Shift"))
|
|
{
|
|
const Eina_List *li, *lli;
|
|
if (evas_key_modifier_is_set(evas_key_modifier_get(evas_object_evas_get(obj)), "Control")) return;
|
|
unselecting = EINA_TRUE;
|
|
items = elm_genlist_selected_items_get(obj);
|
|
EINA_LIST_FOREACH_SAFE(items, li, lli, i)
|
|
elm_genlist_item_selected_set(i, EINA_FALSE);
|
|
elm_genlist_item_selected_set(it, EINA_TRUE);
|
|
unselecting = EINA_FALSE;
|
|
return;
|
|
}
|
|
items = elm_genlist_selected_items_get(obj);
|
|
if (!items) return;
|
|
itp = eina_list_data_get(items);
|
|
unselecting = EINA_TRUE;
|
|
EINA_LIST_FOREACH_SAFE(items, l, ll, i)
|
|
{
|
|
if (((queue_list_sort(itp, i) < 0) && (queue_list_sort(it, i) < 0)) ||
|
|
((queue_list_sort(itp, i) >= 0) && (queue_list_sort(it, i) >= 0)))
|
|
elm_genlist_item_selected_set(i, EINA_FALSE);
|
|
}
|
|
elm_genlist_item_selected_set(itp, EINA_TRUE);
|
|
unselecting = EINA_FALSE;
|
|
elm_genlist_item_selected_set(it, EINA_TRUE);
|
|
}
|
|
|
|
static void
|
|
queue_list_handler(Eina_Value *value, Eina_Bool update)
|
|
{
|
|
Empd_Array_Songs *songs = NULL;
|
|
Empd_Empdd_Song *so;
|
|
const char *album = NULL, *artist = NULL;
|
|
Elm_Object_Item *itl = NULL, *ith = NULL;
|
|
static Elm_Genlist_Item_Class queue_itc = {
|
|
.item_style = "default",
|
|
.func = {
|
|
.text_get = (Elm_Genlist_Item_Text_Get_Cb)queue_list_item_text_get,
|
|
.del = (Elm_Genlist_Item_Del_Cb)queue_list_item_del
|
|
},
|
|
.version = ELM_GENLIST_ITEM_CLASS_VERSION
|
|
};
|
|
static Elm_Genlist_Item_Class header_itc = {
|
|
.item_style = "header",
|
|
.func = {
|
|
.content_get = (Elm_Genlist_Item_Content_Get_Cb)queue_list_header_content_get,
|
|
.text_get = (Elm_Genlist_Item_Text_Get_Cb)queue_list_header_text_get,
|
|
.del = (Elm_Genlist_Item_Del_Cb)queue_list_header_del
|
|
},
|
|
.version = ELM_GENLIST_ITEM_CLASS_VERSION
|
|
};
|
|
|
|
if (!azy_value_to_Empd_Array_Songs(value, &songs))
|
|
{
|
|
EINA_LOG_ERR("conversion failure");
|
|
return;
|
|
}
|
|
if (update && songs->songs)
|
|
{
|
|
Elm_Object_Item *insert;
|
|
Empd_Empdd_Song *exist;
|
|
|
|
so = eina_list_data_get(songs->songs);
|
|
/* find existing song with first updated song's id */
|
|
insert = eina_hash_find(empd_current_queue, &so->songid);
|
|
if (insert)
|
|
{
|
|
exist = elm_object_item_data_get(insert);
|
|
if (exist->song_pos > so->song_pos)
|
|
{
|
|
/* songs removed before existing item:
|
|
* - remove items until exist has target position
|
|
*/
|
|
int target = so->song_pos;
|
|
Elm_Object_Item *prev, *next = insert;
|
|
|
|
do
|
|
{
|
|
insert = elm_genlist_item_prev_get(next);
|
|
if (elm_genlist_item_subitems_count(insert))
|
|
insert = elm_genlist_item_prev_get(insert);
|
|
if (!insert) break;
|
|
exist = elm_object_item_data_get(insert);
|
|
if (exist->song_pos < target) break;
|
|
//fprintf(stderr, "DEL %s\n", exist->title);
|
|
elm_object_item_del(insert);
|
|
} while (insert);
|
|
prev = elm_genlist_item_prev_get(next);
|
|
if (prev)
|
|
{
|
|
Elm_Object_Item *parent;
|
|
Empd_Empdd_Song *a, *b;
|
|
|
|
parent = elm_genlist_item_parent_get(next);
|
|
if (!parent) parent = next;
|
|
a = elm_object_item_data_get(prev);
|
|
b = elm_object_item_data_get(parent);
|
|
/* check whether the previous album can be merged with the next one */
|
|
if ((a->artist == b->artist) && (a->album == b->album) &&
|
|
(parent != elm_genlist_item_parent_get(prev)))
|
|
elm_object_item_del(parent);
|
|
}
|
|
}
|
|
}
|
|
/* songs being inserted before end */
|
|
else if (so->song_pos < eina_hash_population(empd_current_queue))
|
|
{
|
|
int i, num;
|
|
|
|
/* delete #items until insert point reached */
|
|
num = eina_list_count(songs->songs) -
|
|
(empd_queue_length - eina_hash_population(empd_current_queue));
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
/* skip header item... */
|
|
it = elm_genlist_item_prev_get(elm_genlist_last_item_get(queue_list));
|
|
//Empd_Empdd_Song *ss = elm_object_item_data_get(it);
|
|
//fprintf(stderr, "2863 DEL %s\n", ss->title);
|
|
elm_object_item_del(it);
|
|
}
|
|
}
|
|
}
|
|
else if (update)
|
|
{
|
|
while ((unsigned int)eina_hash_population(empd_current_queue) > empd_queue_length)
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
/* skip header item... */
|
|
it = elm_genlist_item_prev_get(elm_genlist_last_item_get(queue_list));
|
|
//Empd_Empdd_Song *ss = elm_object_item_data_get(it);
|
|
//fprintf(stderr, "2863 DEL %s\n", ss->title);
|
|
elm_object_item_del(it);
|
|
}
|
|
}
|
|
EINA_LIST_FREE(songs->songs, so)
|
|
{
|
|
Elm_Object_Item *it = NULL;
|
|
Empd_Empdd_Song *sop;
|
|
|
|
it = eina_hash_find(empd_current_queue, &so->songid);
|
|
if (it)
|
|
{
|
|
Empd_Empdd_Song *ss = elm_object_item_data_get(it);
|
|
if (Empd_Empdd_Song_eq(so, ss))
|
|
{
|
|
Empd_Empdd_Song_free(so);
|
|
so = ss;
|
|
}
|
|
else
|
|
{
|
|
Elm_Object_Item *parent;
|
|
|
|
parent = elm_genlist_item_parent_get(it);
|
|
sop = elm_object_item_data_get(parent);
|
|
if (Empd_Empdd_Song_eq(sop, ss))
|
|
{
|
|
Empd_Empdd_Song_free(sop);
|
|
elm_object_item_data_set(parent, Empd_Empdd_Song_copy(so));
|
|
elm_genlist_item_update(parent);
|
|
}
|
|
Empd_Empdd_Song_free(ss);
|
|
elm_object_item_data_set(it, so);
|
|
elm_genlist_item_update(it);
|
|
if (so->songid == empd_songid)
|
|
{
|
|
if ((so->track != empd_song_track) || (empd_song_title != so->title))
|
|
{
|
|
empd_song_track = so->track;
|
|
eina_stringshare_refplace(&empd_song_title, so->title);
|
|
title_text_set();
|
|
elm_object_tooltip_hide(bg[background_num]);
|
|
}
|
|
}
|
|
}
|
|
ith = elm_genlist_item_parent_get(it);
|
|
}
|
|
|
|
if (!it)
|
|
{
|
|
Elm_Object_Item *itp = NULL;
|
|
Eina_Bool end = EINA_FALSE;
|
|
|
|
if (((!album) && (!artist)) || (album != so->album) || (artist != so->artist) || (!ith))
|
|
{
|
|
Eina_Bool use = EINA_FALSE;
|
|
if ((!ith) || ((!album) && (!artist)))
|
|
{
|
|
itp = queue_list_find_insert_point(so);
|
|
if (itp)
|
|
{
|
|
sop = elm_object_item_data_get(itp);
|
|
if ((sop->album == so->album) && (sop->artist == so->artist))
|
|
{
|
|
use = EINA_TRUE;
|
|
ith = elm_genlist_item_parent_get(itp);
|
|
if (!ith) ith = itp;
|
|
}
|
|
if (itp && (itp == elm_genlist_last_item_get(queue_list)))
|
|
end = EINA_TRUE;
|
|
}
|
|
}
|
|
if (!use)
|
|
{
|
|
char buf[1024];
|
|
|
|
if (end || (!itp))
|
|
ith = elm_genlist_item_append(queue_list, &header_itc, Empd_Empdd_Song_copy(so), NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
|
|
else
|
|
{
|
|
ith = elm_genlist_item_parent_get(itp);
|
|
if (!ith) ith = itp;
|
|
ith = elm_genlist_item_insert_after(queue_list, &header_itc,
|
|
Empd_Empdd_Song_copy(so), NULL, ith, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
|
|
}
|
|
snprintf(buf, sizeof(buf), "%s:::%s", so->artist, so->album);
|
|
//INF("NEW HEADER(%p): %s", ith, buf);
|
|
eina_hash_list_append(empd_current_queue_headers, buf, ith);
|
|
elm_genlist_item_select_mode_set(ith, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
|
|
itp = NULL;
|
|
}
|
|
}
|
|
if (!ith)
|
|
{
|
|
CRI("NO HEADER ITEM FOUND!!! BUG!!");
|
|
abort();
|
|
}
|
|
if (end || (!itp))
|
|
it = elm_genlist_item_append(queue_list, &queue_itc, so, ith, ELM_GENLIST_ITEM_NONE, queue_list_item_select, NULL);
|
|
else if (itp)
|
|
it = elm_genlist_item_insert_after(queue_list, &queue_itc, so, ith, itp, ELM_GENLIST_ITEM_NONE, queue_list_item_select, NULL);
|
|
else
|
|
it = elm_genlist_item_sorted_insert(queue_list, &queue_itc, so, ith, ELM_GENLIST_ITEM_NONE, (Eina_Compare_Cb)queue_list_sort, queue_list_item_select, NULL);
|
|
eina_hash_add(empd_current_queue, &so->songid, it);
|
|
}
|
|
if (so->songid == empd_songid)
|
|
{
|
|
Eina_Bool title;
|
|
|
|
empd_song_item = it;
|
|
/* force updates in case song info has changed */
|
|
if ((so->artist != empd_song_artist) || (so->album != empd_song_album))
|
|
bg_update(bg_next_get(), so->artist, so->album, so->uri);
|
|
eina_stringshare_refplace(&empd_song_album, so->album);
|
|
title = eina_stringshare_refplace(&empd_song_title, so->title);
|
|
if (title || (empd_song_track != so->track))
|
|
elm_object_signal_emit(layout, "empc,title,change,next", "empc");
|
|
empd_song_track = so->track;
|
|
if (eina_stringshare_refplace(&empd_song_artist, so->artist) || title)
|
|
title_update();
|
|
}
|
|
if ((album != so->album) || (artist != so->artist))
|
|
{
|
|
if (itl)
|
|
elm_genlist_item_fields_update(elm_genlist_item_parent_get(itl), EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
album = so->album;
|
|
artist = so->artist;
|
|
itl = it;
|
|
}
|
|
free(songs);
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_queue_list(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empdd_QueueList_Data *ev)
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
it = empd_song_item;
|
|
queue_list_handler(ev->value, EINA_FALSE);
|
|
if ((!it) || (it != empd_song_item))
|
|
elm_genlist_item_show(empd_song_item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_queue_list_changes(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empdd_QueueList_Data *ev)
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
it = empd_song_item;
|
|
queue_list_handler(ev->value, EINA_TRUE);
|
|
if (empd_song_item && ((!it) || (it != empd_song_item)))
|
|
elm_genlist_item_show(empd_song_item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Evas_Object *
|
|
button_add(const char *icon, const char *text, const char *style, Evas_Smart_Cb cb)
|
|
{
|
|
Evas_Object *o, *ic;
|
|
|
|
o = elm_button_add(win);
|
|
if (style)
|
|
elm_object_style_set(o, style);
|
|
elm_object_focus_allow_set(o, EINA_FALSE);
|
|
EXPAND(o);
|
|
FILL(o);
|
|
ic = elm_icon_add(win);
|
|
elm_image_resizable_set(ic, 0, 0);
|
|
elm_icon_order_lookup_set(ic, ELM_ICON_LOOKUP_THEME_FDO);
|
|
elm_icon_standard_set(ic, icon);
|
|
elm_object_part_content_set(o, "icon", ic);
|
|
if (text)
|
|
elm_object_text_set(o, _(text));
|
|
evas_object_show(ic);
|
|
evas_object_show(o);
|
|
evas_object_smart_callback_add(o, "clicked", cb, NULL);
|
|
return o;
|
|
}
|
|
|
|
static void
|
|
control_skip_back()
|
|
{
|
|
empd_empdd_previous_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
control_skip_back_album()
|
|
{
|
|
Empd_Empdd_Song *so;
|
|
Elm_Object_Item *pick;
|
|
|
|
if (!empd_song_item) return;
|
|
pick = queue_list_header_prev_get(elm_genlist_item_parent_get(empd_song_item));
|
|
if ((!pick) || (pick == elm_genlist_item_parent_get(empd_song_item)))
|
|
pick = elm_genlist_item_parent_get(elm_genlist_last_item_get(queue_list));
|
|
if (!pick)
|
|
pick = elm_genlist_last_item_get(queue_list);
|
|
so = elm_object_item_data_get(pick);
|
|
empd_empdd_play_id_call(empd_proxy, so->songid);
|
|
}
|
|
|
|
static void
|
|
control_stop()
|
|
{
|
|
empd_empdd_stop_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
control_toggle()
|
|
{
|
|
if (empd_state == MPD_STATE_PLAY)
|
|
empd_empdd_pause_call(empd_proxy, EINA_TRUE);
|
|
else
|
|
empd_empdd_play_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
control_skip_forward()
|
|
{
|
|
empd_empdd_next_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
control_skip_forward_album()
|
|
{
|
|
Empd_Empdd_Song *so;
|
|
Elm_Object_Item *pick;
|
|
|
|
if (!empd_song_item) return;
|
|
pick = queue_list_header_next_get(elm_genlist_item_parent_get(empd_song_item));
|
|
if (!pick)
|
|
pick = elm_genlist_item_parent_get(elm_genlist_first_item_get(queue_list));
|
|
so = elm_object_item_data_get(pick);
|
|
empd_empdd_play_id_call(empd_proxy, so->songid);
|
|
}
|
|
|
|
static void
|
|
controls_hiding()
|
|
{
|
|
elm_layout_signal_emit(evas_object_data_get(win, "slider"), "empc,controls,hiding", "empc");
|
|
}
|
|
|
|
static void
|
|
controls_showing()
|
|
{
|
|
elm_layout_signal_emit(evas_object_data_get(win, "slider"), "empc,controls,showing", "empc");
|
|
}
|
|
|
|
static void
|
|
slider_fmt(void *d EINA_UNUSED, Evas_Object *obj, const char *sig, const char *src EINA_UNUSED)
|
|
{
|
|
const char *num = sig + sizeof("guide,changed,") - 1;
|
|
char buf[1024];
|
|
double pct;
|
|
unsigned int t;
|
|
|
|
pct = strtof(num, NULL);
|
|
t = lround(pct * empd_song_length);
|
|
snprintf(buf, sizeof(buf), "%.2d:%.2d", t / 60, t % 60);
|
|
elm_slider_indicator_format_set(obj, buf);
|
|
}
|
|
|
|
static void
|
|
slider_seek(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
double val;
|
|
|
|
val = elm_slider_value_get(obj);
|
|
empd_empdd_seek_call(empd_proxy, empd_songid, lround(val * empd_song_length));
|
|
}
|
|
|
|
static int
|
|
mouse_wheel(void *data EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Wheel *ev)
|
|
{
|
|
Elm_Object_Item *it, *pit, *pick = NULL;
|
|
int x, y, w;
|
|
|
|
if (filesystem_state) return ECORE_CALLBACK_RENEW;
|
|
if (!(ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) return ECORE_CALLBACK_RENEW;
|
|
elm_layout_signal_emit(layout, "empc,mouse,wheel", "empc");
|
|
if (!queue_list_state)
|
|
{
|
|
if (!empd_song_item) return ECORE_CALLBACK_CANCEL;
|
|
if (ev->z < 0) //up
|
|
elm_layout_signal_emit(layout, "empc,mouse,wheel,0,-1,ctrl", "empc");
|
|
else if (ev->z > 0) //down
|
|
elm_layout_signal_emit(layout, "empc,mouse,wheel,0,1,ctrl", "empc");
|
|
return ECORE_CALLBACK_CANCEL;
|
|
}
|
|
|
|
if (queue_list_scroll_item)
|
|
{
|
|
if (ev->z < 0) //up
|
|
pick = queue_list_header_prev_get(queue_list_scroll_item);
|
|
else if (ev->z > 0) //down
|
|
pick = queue_list_header_next_get(queue_list_scroll_item);
|
|
elm_genlist_item_bring_in(pick, ELM_GENLIST_ITEM_SCROLLTO_TOP);
|
|
queue_list_scroll_item = pick;
|
|
return ECORE_CALLBACK_CANCEL;
|
|
}
|
|
elm_scroller_region_get(queue_list, NULL, NULL, &w, NULL);
|
|
evas_object_geometry_get(queue_list, &x, &y, NULL, NULL);
|
|
/* FIXME: this should actually calc the height of an item for y */
|
|
it = elm_genlist_at_xy_item_get(queue_list, x + (w / 2), y + 2, NULL);
|
|
if (!it) return ECORE_CALLBACK_RENEW;
|
|
pit = elm_genlist_item_parent_get(it);
|
|
if (!pit) pit = it; //already parent
|
|
if (!ev->z) return ECORE_CALLBACK_RENEW;
|
|
if (ev->z < 0) //up
|
|
{
|
|
if (pit != it) pick = pit;
|
|
else
|
|
pick = queue_list_header_prev_get(pit);
|
|
}
|
|
else if (ev->z > 0)
|
|
{
|
|
if (pit != it)
|
|
{
|
|
pick = elm_genlist_item_next_get(pit);
|
|
if (pick)
|
|
pick = elm_genlist_item_parent_get(pick);
|
|
}
|
|
else
|
|
pick = queue_list_header_next_get(pit);
|
|
if (!pick)
|
|
pick = elm_genlist_last_item_get(queue_list);
|
|
}
|
|
elm_genlist_item_bring_in(pick, ELM_GENLIST_ITEM_SCROLLTO_TOP);
|
|
queue_list_scroll_item = pick;
|
|
return ECORE_CALLBACK_CANCEL;
|
|
}
|
|
|
|
static int
|
|
mouse_down(void *data EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Key *ev EINA_UNUSED)
|
|
{
|
|
if (evas_object_visible_get(filesystem_entry))
|
|
{
|
|
Evas_Object *ly;
|
|
|
|
ly = elm_object_part_content_get(layout, EMPC_SWALLOW_FILESYSTEM);
|
|
filesystem_entry_hide(ly);
|
|
}
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static int
|
|
key_down(void *data EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Key *ev)
|
|
{
|
|
if (ctxpopup)
|
|
{
|
|
unsigned int n;
|
|
|
|
errno = 0;
|
|
n = strtoul(ev->key, NULL, 10);
|
|
if (!errno)
|
|
{
|
|
const Eina_List *items;
|
|
|
|
items = elm_list_items_get(elm_object_content_get(ctxpopup));
|
|
if (n && (n <= eina_list_count(items)))
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
it = eina_list_nth(items, n - 1);
|
|
elm_list_item_selected_set(it, 1);
|
|
return ECORE_CALLBACK_DONE;
|
|
}
|
|
}
|
|
}
|
|
if ((!strcmp(ev->key, "q")) && (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL))
|
|
ecore_main_loop_quit();
|
|
else if ((!(ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) && (!ctxpopup) &&
|
|
(!queue_list_state) && (!filesystem_state) && (!strcmp(ev->key, "Delete")))
|
|
{
|
|
if (empd_song_item)
|
|
{
|
|
Empd_Empdd_Song *so = elm_object_item_data_get(empd_song_item);
|
|
|
|
empd_empdd_delete_list_range_call(empd_proxy, so->song_pos, 1);
|
|
}
|
|
}
|
|
else if ((!(ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) && (!ctxpopup) &&
|
|
(!queue_list_state) && (!filesystem_state) && (!strcmp(ev->key, "space")))
|
|
{
|
|
control_toggle();
|
|
}
|
|
else if (!strcmp(ev->key, "Escape"))
|
|
{
|
|
if (ctxpopup)
|
|
elm_ctxpopup_dismiss(ctxpopup);
|
|
else if (bgchooser)
|
|
{
|
|
bgselector_cancel(elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND));
|
|
elm_layout_signal_emit(layout, "empc,bg_chooser,cancel", "empc");
|
|
}
|
|
return (!ctxpopup) && (!bgchooser);
|
|
}
|
|
else if (!strcmp(ev->key, "F1"))
|
|
{
|
|
if (login_visible || ctxpopup) return ECORE_CALLBACK_DONE;
|
|
if (filesystem_state)
|
|
elm_object_signal_emit(layout, "empc,filesystem,hide", "empc");
|
|
elm_object_signal_emit(layout, "empc,overlay,toggle", "empc");
|
|
}
|
|
else if (!strcmp(ev->key, "F2"))
|
|
{
|
|
if (login_visible || ctxpopup) return ECORE_CALLBACK_DONE;
|
|
if (filesystem_state)
|
|
{
|
|
if (overlay_locked_state)
|
|
elm_object_signal_emit(layout, "empc,overlay,toggle", "empc");
|
|
else
|
|
elm_object_signal_emit(layout, "empc,filesystem,hide", "empc");
|
|
}
|
|
else
|
|
{
|
|
if (!overlay_locked_state)
|
|
elm_object_signal_emit(layout, "empc,overlay,toggle", "empc");
|
|
elm_object_signal_emit(layout, "empc,filesystem,show", "empc");
|
|
}
|
|
}
|
|
else if (bgchooser && (!strcmp(ev->key, "Down")))
|
|
bgselector_next(elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND));
|
|
else if (bgchooser && (!strcmp(ev->key, "Up")))
|
|
bgselector_prev(elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND));
|
|
else if (filesystem_state && evas_object_visible_get(filesystem_entry) && (!strcmp(ev->key, "Down")))
|
|
filesystem_entry_key_select(1, 0, 1, ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT);
|
|
else if (filesystem_state && evas_object_visible_get(filesystem_entry) && (!strcmp(ev->key, "Up")))
|
|
filesystem_entry_key_select(0, 0, -1, ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT);
|
|
else if (filesystem_state && evas_object_visible_get(filesystem_entry) && (!strcmp(ev->key, "Left")))
|
|
filesystem_entry_key_select(0, -1, 0, ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT);
|
|
else if (filesystem_state && evas_object_visible_get(filesystem_entry) && (!strcmp(ev->key, "Right")))
|
|
filesystem_entry_key_select(1, 1, 0, ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT);
|
|
else if (bgchooser && ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter"))))
|
|
elm_layout_signal_emit(layout, "empc,bg_chooser,stop", "empc");
|
|
else if ((!filesystem_state) && (!queue_list_state) && elm_genlist_selected_item_get(queue_list) &&
|
|
((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter"))))
|
|
{
|
|
Empd_Empdd_Song *so;
|
|
|
|
so = elm_object_item_data_get(elm_genlist_selected_item_get(queue_list));
|
|
empd_empdd_play_id_call(empd_proxy, so->songid);
|
|
}
|
|
else if ((!(ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) && (!(ev->modifiers & ECORE_EVENT_MODIFIER_ALT)) &&
|
|
(!(ev->modifiers & ECORE_EVENT_MODIFIER_ALTGR)) && (!(ev->modifiers & ECORE_EVENT_MODIFIER_WIN)))
|
|
return ECORE_CALLBACK_RENEW;
|
|
if (login_visible) return ECORE_CALLBACK_RENEW;
|
|
while (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
|
|
{
|
|
if ((!ctxpopup) && empd_song_item &&
|
|
(!queue_list_state) && (!filesystem_state) && (!strcmp(ev->key, "Delete")))
|
|
{
|
|
Elm_Object_Item *it;
|
|
Empd_Empdd_Song *so;
|
|
Eina_List *l = NULL;
|
|
|
|
it = elm_genlist_item_parent_get(empd_song_item);
|
|
so = elm_object_item_data_get(it);
|
|
it = eina_hash_find(empd_current_queue, &so->songid);
|
|
do
|
|
{
|
|
l = eina_list_append(l, it);
|
|
it = elm_genlist_item_next_get(it);
|
|
} while (elm_genlist_item_parent_get(it));
|
|
queue_list_delete_list(l);
|
|
}
|
|
else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
|
|
{
|
|
if (filesystem_state && evas_object_visible_get(filesystem_entry)) return ECORE_CALLBACK_RENEW;
|
|
if (filesystem_state)
|
|
filesystem_ctxpopup_show(eina_list_last_data_get(filesystems));
|
|
else if (queue_list_state && elm_genlist_selected_items_get(queue_list))
|
|
queue_list_ctxpopup_show(queue_list);
|
|
}
|
|
else if (filesystem_state && evas_object_visible_get(filesystem_entry)) return ECORE_CALLBACK_RENEW;
|
|
else if (!strcmp(ev->key, "a"))
|
|
{
|
|
if (filesystem_state)
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
for (it = elm_gengrid_first_item_get(eina_list_last_data_get(filesystems)); it; it = elm_gengrid_item_next_get(it))
|
|
elm_gengrid_item_selected_set(it, EINA_TRUE);
|
|
}
|
|
else if (queue_list_state)
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
selecting = EINA_TRUE;
|
|
for (it = elm_genlist_first_item_get(queue_list); it; it = elm_genlist_item_next_get(it))
|
|
{
|
|
if (!elm_genlist_item_parent_get(it)) continue; //header
|
|
elm_genlist_item_selected_set(it, EINA_TRUE);
|
|
}
|
|
selecting = EINA_FALSE;
|
|
}
|
|
}
|
|
else if (!strcmp(ev->key, "x"))
|
|
{
|
|
if (!clipboard_copy())
|
|
return ECORE_CALLBACK_RENEW;
|
|
queue_list_delete_selected();
|
|
}
|
|
else if (!strcmp(ev->key, "c"))
|
|
{
|
|
if (!clipboard_copy())
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
else if (!strcmp(ev->key, "v"))
|
|
{
|
|
if (queue_list_state && (!filesystem_state))
|
|
{
|
|
Elm_Object_Item *it;
|
|
const Eina_List *l;
|
|
Empd_Empdd_Song *soi, *so = NULL;
|
|
|
|
EINA_LIST_FOREACH(elm_genlist_selected_items_get(queue_list), l, it)
|
|
{
|
|
soi = elm_object_item_data_get(it);
|
|
if ((!so) || (soi->song_pos > so->song_pos))
|
|
so = soi;
|
|
}
|
|
if (so && ((unsigned int)so->song_pos == empd_queue_length - 1))
|
|
so = NULL;
|
|
if (!clipboard_paste(so ? so->song_pos + 1 : (long long)empd_queue_length))
|
|
return ECORE_CALLBACK_RENEW;
|
|
break;
|
|
}
|
|
if ((!lyrics_visible) && (!bg_pasting) &&
|
|
((!filesystem_state) || (eina_list_count(elm_gengrid_selected_items_get(eina_list_last_data_get(filesystems))) == 1)))
|
|
elm_cnp_selection_get(win, ELM_SEL_TYPE_CLIPBOARD, ELM_SEL_FORMAT_IMAGE | ELM_SEL_FORMAT_TEXT, (Elm_Drop_Cb)bg_paste, NULL);
|
|
}
|
|
break;
|
|
}
|
|
return ECORE_CALLBACK_DONE;
|
|
}
|
|
|
|
static int
|
|
module_sort_cb(Empc_Module *a, Empc_Module *b)
|
|
{
|
|
return a->priority - b->priority;
|
|
}
|
|
|
|
static Eina_Bool
|
|
module_check(Eina_Module *m, void *d EINA_UNUSED)
|
|
{
|
|
const char *filename;
|
|
Empc_Module *mod;
|
|
Empc_Module_Type type = EMPC_MODULE_TYPE_LAST;
|
|
Empc_Module_Type_Cb type_cb;
|
|
Empc_Module_Remote_Cb remote_cb;
|
|
Empc_Module_Priority_Cb prio_cb;
|
|
|
|
filename = eina_module_file_get(m);
|
|
filename = strrchr(filename, '/') + 1;
|
|
if (strcmp(filename + (strlen(filename) - 3), SHARED_LIB_SUFFIX))
|
|
return EINA_FALSE;
|
|
|
|
if (!eina_module_load(m))
|
|
{
|
|
ERR("Could not verify module named '%s'. Error: '%s'", filename, eina_error_msg_get(eina_error_get()));
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
type_cb = eina_module_symbol_get(m, "empc_module_type");
|
|
if (!type_cb) goto error;
|
|
type = type_cb();
|
|
if (type >= EMPC_MODULE_TYPE_LAST)
|
|
{
|
|
ERR("Unimplemented module type!");
|
|
goto error;
|
|
}
|
|
prio_cb = eina_module_symbol_get(m, "empc_module_priority");
|
|
remote_cb = eina_module_symbol_get(m, "empc_module_remote");
|
|
|
|
mod = calloc(1, empc_module_size[type]);
|
|
mod->type = type;
|
|
if (prio_cb)
|
|
mod->priority = prio_cb();
|
|
if (remote_cb)
|
|
mod->remote = remote_cb();
|
|
mod->module = m;
|
|
empc_modules[type] = eina_inlist_sorted_insert(empc_modules[type], EINA_INLIST_GET(mod), (Eina_Compare_Cb)module_sort_cb);
|
|
|
|
switch (type)
|
|
{
|
|
case EMPC_MODULE_TYPE_METADATA_FETCH:
|
|
{
|
|
Empc_Module_Metadata_Fetch *em = (Empc_Module_Metadata_Fetch*)mod;
|
|
|
|
em->fetch = eina_module_symbol_get(m, "empc_module_metadata_fetch");
|
|
em->cancel = eina_module_symbol_get(m, "empc_module_metadata_cancel");
|
|
break;
|
|
}
|
|
case EMPC_MODULE_TYPE_METADATA_SAVER:
|
|
{
|
|
Empc_Module_Metadata_Save *es = (Empc_Module_Metadata_Save*)mod;
|
|
|
|
es->save_image = eina_module_symbol_get(m, "empc_module_metadata_save_image");
|
|
es->save_text = eina_module_symbol_get(m, "empc_module_metadata_save_text");
|
|
break;
|
|
}
|
|
case EMPC_MODULE_TYPE_MISC:
|
|
{
|
|
//Empc_Module_Misc *ems = (Empc_Module_Misc*)mod;
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
INF("MODULE LOAD(%s)", strrchr(eina_module_file_get(mod->module), '/') + 1);
|
|
|
|
return EINA_TRUE;
|
|
error:
|
|
eina_module_unload(m);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
lyrics_request()
|
|
{
|
|
if (elm_object_part_content_get(layout, EMPC_SWALLOW_LYRICS))
|
|
elm_object_signal_emit(layout, "empc,lyrics,show", "empc");
|
|
else
|
|
{
|
|
Empd_Empdd_Song *so;
|
|
const char *uri = NULL;
|
|
|
|
if (empd_song_item)
|
|
{
|
|
so = elm_object_item_data_get(empd_song_item);
|
|
uri = so->uri;
|
|
}
|
|
metadata_fetch_begin(EMPC_METADATA_TYPE_TEXT, layout, empd_song_artist, empd_song_title, uri, EINA_FALSE, EINA_FALSE, lyrics_set, NULL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
lyrics_show(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
lyrics_visible = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
lyrics_hide(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
lyrics_visible = EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
mode_toggle(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
if (obj == repeat)
|
|
empd_empdd_repeat_call(empd_proxy, !elm_check_state_get(obj));
|
|
else if (obj == shuffle)
|
|
empd_empdd_shuffle_call(empd_proxy, !elm_check_state_get(obj));
|
|
else if (obj == single)
|
|
empd_empdd_single_call(empd_proxy, !elm_check_state_get(obj));
|
|
else
|
|
empd_empdd_consume_call(empd_proxy, !elm_check_state_get(obj));
|
|
}
|
|
|
|
static void
|
|
bg_chooser_next(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
bgselector_next(elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND));
|
|
}
|
|
|
|
static void
|
|
bg_chooser_prev(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
bgselector_prev(elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND));
|
|
}
|
|
|
|
static void
|
|
bg_chooser_show(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
Evas_Object *bgs;
|
|
Empd_Empdd_Song *so;
|
|
const char *uri = NULL;
|
|
|
|
if (empd_song_item)
|
|
{
|
|
so = elm_object_item_data_get(empd_song_item);
|
|
uri = so->uri;
|
|
}
|
|
bgchooser = EINA_TRUE;
|
|
bgs = elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND);
|
|
bgfetch = metadata_fetch_begin(EMPC_METADATA_TYPE_IMAGE, bgs, empd_song_artist, empd_song_album, uri, EINA_TRUE, EINA_FALSE, bg_add, NULL);
|
|
bgselector_active_set(bgs, EINA_TRUE);
|
|
elm_object_tooltip_hide(bgs);
|
|
}
|
|
|
|
static void
|
|
bg_chooser_hide(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig, const char *src EINA_UNUSED)
|
|
{
|
|
Evas_Object *bgs, *img;
|
|
Eina_Stringshare *artist, *album;
|
|
|
|
if (!bgchooser) return;
|
|
bgs = elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND);
|
|
bgselector_prune(bgs);
|
|
bgselector_active_set(bgs, EINA_FALSE);
|
|
img = bgselector_get(bgs);
|
|
artist = bgselector_artist_get(bgs);
|
|
album = bgselector_album_get(bgs);
|
|
metadata_fetch_cancel(bgfetch, bgs, bg_add, NULL);
|
|
|
|
bgchooser = EINA_FALSE;
|
|
evas_event_feed_mouse_out(evas_object_evas_get(win), 0, NULL);
|
|
evas_event_feed_mouse_in(evas_object_evas_get(win), 0, NULL);
|
|
if (!img)
|
|
elm_object_signal_emit(layout, "empc,info,show", "empc");
|
|
if (!strcmp(sig + sizeof("empc,bg_chooser,") - 1, "canceled")) return;
|
|
save_image(EINA_TRUE, img, NULL, artist, album, bg_update_signal);
|
|
|
|
bg_update_propogate(artist, album);
|
|
}
|
|
|
|
static void
|
|
queue_list_show(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
queue_list_state = EINA_TRUE;
|
|
elm_object_focus_set(queue_list, !login_visible);
|
|
}
|
|
|
|
static void
|
|
queue_list_hide(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Eina_List *l;
|
|
|
|
queue_list_state = EINA_FALSE;
|
|
EINA_LIST_FOREACH(queue_list_realized, l, it)
|
|
elm_object_item_signal_emit(it, "empc,state,hidden", "empc");
|
|
}
|
|
|
|
static void
|
|
queue_list_showing(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Eina_List *l;
|
|
|
|
if (empd_song_item)
|
|
elm_genlist_item_fields_update(empd_song_item, EMPC_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
|
|
EINA_LIST_FOREACH(queue_list_realized, l, it)
|
|
elm_object_item_signal_emit(it, "empc,state,visible", "empc");
|
|
}
|
|
|
|
static void
|
|
queue_list_hiding(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
evas_object_del(ctxpopup);
|
|
ctxpopup = NULL;
|
|
}
|
|
|
|
static void
|
|
overlay_locked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
overlay_locked_state = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
overlay_unlocked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
overlay_locked_state = EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
theme_load(void)
|
|
{
|
|
const char *themepath;
|
|
char buf[PATH_MAX];
|
|
|
|
themepath = getenv("EMPC_THEME");
|
|
if (!themepath)
|
|
snprintf(buf, sizeof(buf), "%s/empc.edj", PACKAGE_DATA_DIR);
|
|
elm_theme_overlay_add(NULL, themepath ?: buf);
|
|
}
|
|
|
|
static void
|
|
login_port_filter(void *d EINA_UNUSED, Evas_Object *obj EINA_UNUSED, char **text)
|
|
{
|
|
char *p;
|
|
Eina_Bool done = EINA_FALSE;
|
|
|
|
if (eina_strlen_bounded(*text, 6) == 6)
|
|
*text[5] = 0;
|
|
for (p = *text; p[0]; p++)
|
|
{
|
|
if ((p[0] < '0') || (p[0] > '9'))
|
|
done = EINA_TRUE;
|
|
if (done)
|
|
p[0] = 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
dbus_name_changed(void *data EINA_UNUSED, const char *bus EINA_UNUSED, const char *old_id EINA_UNUSED, const char *new_id)
|
|
{
|
|
master = !strcmp(new_id, eldbus_connection_unique_name_get(dbus_conn));
|
|
}
|
|
|
|
static void
|
|
dbus_request_name(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
|
|
{
|
|
unsigned int reply;
|
|
|
|
if (eldbus_message_error_get(msg, NULL, NULL))
|
|
return;
|
|
if (!eldbus_message_arguments_get(msg, "u", &reply))
|
|
return;
|
|
master = reply == ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER;
|
|
}
|
|
|
|
static void
|
|
dbus_getbg_fetch_cb(void *data, Empc_Fetch_Request *req EINA_UNUSED, Evas_Object *obj)
|
|
{
|
|
Eldbus_Message *ret = data;
|
|
Eina_Stringshare *f = NULL, *g = NULL;
|
|
|
|
elm_image_file_get(obj, &f, &g);
|
|
eldbus_message_arguments_append(ret, "ss", f ?: "", g ?: "");
|
|
eldbus_connection_send(dbus_conn, ret, NULL, NULL, -1);
|
|
evas_object_del(obj);
|
|
}
|
|
|
|
static Eldbus_Message *
|
|
dbus_getbg(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
{
|
|
Eldbus_Message *ret;
|
|
Evas_Object *cur, *o;
|
|
Eina_Stringshare *f = NULL, *g = NULL;
|
|
Empd_Empdd_Song *so;
|
|
|
|
o = elm_object_part_content_get(layout, EMPC_SWALLOW_BACKGROUND);
|
|
cur = bgselector_get(o);
|
|
elm_image_file_get(cur, &f, &g);
|
|
|
|
ret = eldbus_message_method_return_new(msg);
|
|
if (f)
|
|
{
|
|
eldbus_message_arguments_append(ret, "ss", f ?: "", g ?: "");
|
|
return ret;
|
|
}
|
|
so = elm_object_item_data_get(empd_song_item);
|
|
metadata_fetch_begin(EMPC_METADATA_TYPE_IMAGE, win, empd_song_artist, empd_song_title, so->uri, EINA_FALSE, EINA_TRUE, dbus_getbg_fetch_cb, ret);
|
|
return NULL;
|
|
}
|
|
|
|
static Eldbus_Message *
|
|
dbus_setbgfile(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
{
|
|
const char *artist, *album, *file, *key;
|
|
Evas_Object *img;
|
|
|
|
if (!eldbus_message_arguments_get(msg, "ssss", &artist, &album, &file, &key))
|
|
return eldbus_message_method_return_new(msg);
|
|
img = elm_image_add(win);
|
|
elm_image_fill_outside_set(img, EINA_FALSE);
|
|
elm_image_smooth_set(img, EINA_FALSE);
|
|
elm_image_file_set(img, file, key);
|
|
save_image(EINA_TRUE, img, NULL, artist, album, bg_update_signal);
|
|
if (eina_streq(artist, empd_song_artist) && eina_streq(album, empd_song_album))
|
|
{
|
|
background_num = bg_next_get();
|
|
bgselector_clear(bg[background_num]);
|
|
bgselector_info_set(bg[background_num], empd_song_artist, empd_song_album);
|
|
bgselector_image_add(bg[background_num], img);
|
|
elm_object_signal_emit(layout, "empc,bg,next", "empc");
|
|
}
|
|
bg_update_propogate(artist, album);
|
|
return eldbus_message_method_return_new(msg);
|
|
}
|
|
|
|
static Eldbus_Message *
|
|
dbus_setbgdata(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
|
|
{
|
|
const char *artist, *album, *uri;
|
|
Eldbus_Message_Iter *array;
|
|
Evas_Object *img;
|
|
void *px;
|
|
int size;
|
|
|
|
if (!eldbus_message_arguments_get(msg, "sssay", &artist, &album, &uri, &array))
|
|
return eldbus_message_method_return_new(msg);
|
|
if (!eldbus_message_iter_fixed_array_get(array, 'y', &px, &size))
|
|
return eldbus_message_method_return_new(msg);
|
|
img = elm_image_add(win);
|
|
elm_image_fill_outside_set(img, EINA_FALSE);
|
|
elm_image_smooth_set(img, EINA_FALSE);
|
|
elm_image_memfile_set(img, px, size, NULL, NULL);
|
|
save_image(EINA_TRUE, img, uri, artist, album, bg_update_signal);
|
|
if (eina_streq(artist, empd_song_artist) && eina_streq(album, empd_song_album))
|
|
{
|
|
background_num = bg_next_get();
|
|
bgselector_clear(bg[background_num]);
|
|
bgselector_info_set(bg[background_num], empd_song_artist, empd_song_album);
|
|
bgselector_image_add(bg[background_num], img);
|
|
elm_object_signal_emit(layout, "empc,bg,next", "empc");
|
|
}
|
|
bg_update_propogate(artist, album);
|
|
return eldbus_message_method_return_new(msg);
|
|
}
|
|
|
|
static const Eldbus_Signal empc_signals[] =
|
|
{
|
|
[EMPC_SIGNAL_BACKGROUND_CHANGED] = {"BackgroundChanged", ELDBUS_ARGS({"s", "file"}, {"s", "key"}), 0},
|
|
{NULL, NULL, 0}
|
|
};
|
|
|
|
static const Eldbus_Method empc_methods[] =
|
|
{
|
|
{ "SetBackgroundFile", ELDBUS_ARGS({"s", "artist"}, {"s", "album"}, {"s", "file"}, {"s", "key"}), NULL, dbus_setbgfile, 0},
|
|
{ "SetBackgroundData", ELDBUS_ARGS({"s", "artist"}, {"s", "album"}, {"s", "uri"}, {"ay", "bytes"}), NULL, dbus_setbgdata, 0},
|
|
{ "GetBackground", NULL, ELDBUS_ARGS({"s", "file"}, {"s", "key"}), dbus_getbg, 0},
|
|
{NULL, NULL, NULL, NULL, 0}
|
|
};
|
|
|
|
static const Eldbus_Service_Interface_Desc base_desc =
|
|
{
|
|
EMPC_METHOD_BASE, empc_methods, empc_signals, NULL, NULL, NULL
|
|
};
|
|
|
|
static void
|
|
empd_send_connect(void)
|
|
{
|
|
const char *h, *pass = NULL, *p = NULL;
|
|
char host[PATH_MAX] = {0};
|
|
int port = DEFAULT_PORT;
|
|
|
|
pass = getenv("MPD_PASSWORD");
|
|
p = getenv("MPD_PORT");
|
|
h = getenv("MPD_HOST");
|
|
if (h)
|
|
{
|
|
if (!p)
|
|
p = strchr(h, ':');
|
|
if (p)
|
|
{
|
|
if (p - h > PATH_MAX - 1)
|
|
{
|
|
fprintf(stderr, "MPD_HOST longer than 4096 chars? I don't believe you.\n");
|
|
empd_empdd_is_connected_call(empd_proxy, empc_isconnected, NULL);
|
|
return;
|
|
}
|
|
port = strtol(p + 1, NULL, 10);
|
|
memcpy(host, h, p - h);
|
|
h = host;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
struct stat st;
|
|
|
|
if (!stat("/var/lib/mpd/socket", &st))
|
|
h = "/var/lib/mpd/socket";
|
|
else if (!stat("/run/mpd/socket", &st))
|
|
h = "/run/mpd/socket";
|
|
}
|
|
if (h)
|
|
empd_empdd_connect_call(empd_proxy, h ?: "", port, pass ?: "");
|
|
else
|
|
empd_empdd_is_connected_call(empd_proxy, empc_isconnected, NULL);
|
|
}
|
|
|
|
static void
|
|
empd_name_start(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
|
|
{
|
|
unsigned flag = 0;
|
|
|
|
if ((!eldbus_message_arguments_get(msg, "u", &flag)) || (!flag))
|
|
{
|
|
error_o_doom();
|
|
return;
|
|
}
|
|
if (flag == ELDBUS_NAME_START_REPLY_SUCCESS)
|
|
empd_send_connect();
|
|
else
|
|
empd_empdd_is_connected_call(empd_proxy, empc_isconnected, NULL);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
Evas_Object *o, *hbox;
|
|
int i;
|
|
const char *modpath;
|
|
Eina_Array *mods;
|
|
Eina_Free_Cb free_cbs[] =
|
|
{
|
|
[EMPC_METADATA_TYPE_IMAGE] = (Eina_Free_Cb)fetch_req_free,
|
|
[EMPC_METADATA_TYPE_TEXT] = (Eina_Free_Cb)fetch_req_free,
|
|
};
|
|
|
|
eina_init();
|
|
ecore_app_no_system_modules();
|
|
eldbus_init();
|
|
efreet_init();
|
|
ecore_event_init();
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_DOWN, key_down, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_down, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_WHEEL, mouse_wheel, NULL);
|
|
elm_init(argc, argv);
|
|
elm_config_scale_set(1.3);
|
|
elm_config_focus_highlight_enabled_set(0);
|
|
elm_config_focus_highlight_animate_set(0);
|
|
|
|
eina_log_domain_level_set("evas_main", EINA_LOG_LEVEL_CRITICAL);
|
|
eina_log_domain_level_set("edje", EINA_LOG_LEVEL_CRITICAL);
|
|
empc_log_dom = eina_log_domain_register("empc", EINA_COLOR_YELLOW);
|
|
eina_log_domain_level_set("empc", EINA_LOG_LEVEL_DBG);
|
|
|
|
{
|
|
char buf[PATH_MAX];
|
|
|
|
snprintf(buf, sizeof(buf), "%s/empc/metadata", efreet_cache_home_get());
|
|
ecore_file_mkpath(buf);
|
|
}
|
|
theme_load();
|
|
|
|
clipboard = eina_array_new(10);
|
|
|
|
empd_current_queue = eina_hash_int32_new(NULL);
|
|
empd_current_queue_headers = eina_hash_string_superfast_new(NULL);
|
|
for (i = 0; i < EMPC_METADATA_TYPE_LAST; i++)
|
|
empc_metadata_fetch_reqs[i] = eina_hash_string_superfast_new(free_cbs[i]);
|
|
|
|
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
|
|
|
dbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
|
|
eldbus_name_start(dbus_conn, EMPDD_METHOD_BASE, 0, empd_name_start, NULL);
|
|
empc_proxy = empd_empc_proxy_get(dbus_conn, EMPC_METHOD_BASE, NULL);
|
|
empd_proxy = empd_empdd_proxy_get(dbus_conn, EMPDD_METHOD_BASE, NULL);
|
|
eldbus_name_request(dbus_conn, EMPC_METHOD_BASE, 0, dbus_request_name, NULL);
|
|
eldbus_name_owner_changed_callback_add(dbus_conn, EMPC_METHOD_BASE, dbus_name_changed, NULL, EINA_FALSE);
|
|
empc_iface = eldbus_service_interface_register(dbus_conn, "/", &base_desc);
|
|
|
|
modpath = getenv("EMPC_MODULE_DIR");
|
|
mods = eina_module_list_get(NULL, modpath ?: EMPC_MODULE_PATH, EINA_FALSE, (Eina_Module_Cb)module_check, NULL);
|
|
eina_array_free(mods);
|
|
{
|
|
char buf[PATH_MAX];
|
|
|
|
snprintf(buf, sizeof(buf), "%s/empc/modules", efreet_config_home_get());
|
|
mods = eina_module_list_get(NULL, buf, EINA_FALSE, (Eina_Module_Cb)module_check, NULL);
|
|
eina_array_free(mods);
|
|
}
|
|
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_CONNECTED_EVENT, empc_connected, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_DISCONNECTED_EVENT, empc_disconnected, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_LOGIN_FAILED_EVENT, empc_login_fail, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_PERMISSION_FAILED_EVENT, empc_permission_fail, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_STATUS_EVENT, empc_status, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_QUEUE_LIST_EVENT, empc_queue_list, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_QUEUE_CHANGES_META_EVENT, empc_queue_list_changes, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_DATABASE_UPDATE_END_EVENT, empc_database_end, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPC_BACKGROUND_CHANGED_EVENT, empc_bg_changed, NULL);
|
|
|
|
win = elm_win_add(NULL, "empc", ELM_WIN_BASIC);
|
|
elm_object_style_set(win, "empc");
|
|
elm_win_title_set(win, "empc");
|
|
elm_win_autodel_set(win, 1);
|
|
layout = elm_layout_add(win);
|
|
elm_object_focus_allow_set(layout, 0);
|
|
EXPAND(layout);
|
|
FILL(layout);
|
|
elm_win_resize_object_add(win, layout);
|
|
elm_layout_theme_set(layout, "layout", "empc", "base");
|
|
elm_object_signal_callback_add(layout, "empc,artist,changed,1", "empc", artist_changed, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,album,changed,1", "empc", album_changed, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,title,changed,1", "empc", title_changed, NULL);
|
|
|
|
elm_object_signal_callback_add(layout, "empc,play,toggle", "empc", control_toggle, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,play,stop", "empc", control_stop, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,play,prev", "empc", control_skip_back, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,play,prev_album", "empc", control_skip_back_album, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,play,next", "empc", control_skip_forward, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,play,next_album", "empc", control_skip_forward_album, NULL);
|
|
|
|
elm_object_signal_callback_add(layout, "empc,lyrics,request", "empc", lyrics_request, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,lyrics,visible", "empc", lyrics_show, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,lyrics,hidden", "empc", lyrics_hide, NULL);
|
|
|
|
elm_object_signal_callback_add(layout, "empc,playlist,visible", "empc", queue_list_show, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,playlist,hidden", "empc", queue_list_hide, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,playlist,hiding", "empc", queue_list_hiding, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,playlist,showing", "empc", queue_list_showing, NULL);
|
|
|
|
elm_object_signal_callback_add(layout, "empc,controls,hiding", "empc", controls_hiding, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,controls,showing", "empc", controls_showing, NULL);
|
|
|
|
elm_object_signal_callback_add(layout, "empc,filesystem,showing", "empc", filesystem_showing, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,filesystem,visible", "empc", filesystem_show, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,filesystem,hidden", "empc", filesystem_hide, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,filesystem,hiding", "empc", filesystem_hiding, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,bg_chooser,active", "empc", bg_chooser_show, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,bg_chooser,inactive", "empc", bg_chooser_hide, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,bg_chooser,canceled", "empc", bg_chooser_hide, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,bg_chooser,next", "empc", bg_chooser_next, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,bg_chooser,prev", "empc", bg_chooser_prev, NULL);
|
|
|
|
elm_object_signal_callback_add(layout, "empc,overlay,locked", "empc", overlay_locked, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,overlay,unlocked", "empc", overlay_unlocked, NULL);
|
|
evas_object_show(layout);
|
|
|
|
{
|
|
const char *toggles[] =
|
|
{
|
|
EMPC_SWALLOW_REPEAT,
|
|
EMPC_SWALLOW_SHUFFLE,
|
|
EMPC_SWALLOW_SINGLE,
|
|
EMPC_SWALLOW_CONSUME
|
|
};
|
|
const char *icons[] =
|
|
{
|
|
"repeat",
|
|
"shuffle",
|
|
"single",
|
|
"consume"
|
|
};
|
|
Evas_Object **objs[] =
|
|
{
|
|
&repeat,
|
|
&shuffle,
|
|
&single,
|
|
&consume,
|
|
};
|
|
const char *tooltips[] =
|
|
{
|
|
"Toggle Repeat play mode",
|
|
"Toggle Random play mode",
|
|
"Toggle Repeat-Single mode",
|
|
"Toggle Consume-On-Play mode",
|
|
};
|
|
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
Evas_Object *img;
|
|
|
|
o = elm_check_add(win);
|
|
elm_object_tooltip_text_set(o, tooltips[i]);
|
|
elm_object_tooltip_style_set(o, "empc");
|
|
elm_object_style_set(o, "mode_toggle");
|
|
img = elm_icon_add(win);
|
|
elm_icon_order_lookup_set(img, ELM_ICON_LOOKUP_THEME);
|
|
elm_icon_standard_set(img, icons[i]);
|
|
elm_object_content_set(o, img);
|
|
elm_object_part_content_set(layout, toggles[i], o);
|
|
elm_object_signal_callback_add(o, "empc,check,toggle", "empc", mode_toggle, NULL);
|
|
*objs[i] = o;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
bg[i] = bgselector_add(win);
|
|
elm_object_tooltip_content_cb_set(bg[i], bg_tooltip_cb, NULL, NULL);
|
|
elm_object_tooltip_style_set(bg[i], "empc");
|
|
elm_object_tooltip_window_mode_set(bg[i], EINA_TRUE);
|
|
}
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_BACKGROUND, bg[0]);
|
|
|
|
controls = hbox = elm_box_add(win);
|
|
elm_box_horizontal_set(hbox, EINA_TRUE);
|
|
elm_box_homogeneous_set(hbox, EINA_TRUE);
|
|
EXPAND(hbox);
|
|
FILL(hbox);
|
|
evas_object_show(hbox);
|
|
|
|
o = button_add("media_player/prev", NULL, "empc", control_skip_back);
|
|
elm_object_tooltip_text_set(o, _("Previous song"));
|
|
elm_object_tooltip_style_set(o, "empc");
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
o = button_add("media_player/stop", NULL, "empc", control_stop);
|
|
elm_object_tooltip_text_set(o, _("Stop"));
|
|
elm_object_tooltip_style_set(o, "empc");
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
o = button_add("media_player/play", NULL, "empc", control_toggle);
|
|
elm_object_tooltip_text_set(o, _("Play/Pause"));
|
|
elm_object_tooltip_style_set(o, "empc");
|
|
evas_object_data_set(win, "play_button", o);
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
o = button_add("media_player/next", NULL, "empc", control_skip_forward);
|
|
elm_object_tooltip_text_set(o, _("Next song"));
|
|
elm_object_tooltip_style_set(o, "empc");
|
|
elm_box_pack_end(hbox, o);
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_CONTROLS, hbox);
|
|
|
|
o = elm_slider_add(win);
|
|
elm_object_style_set(o, "player");
|
|
evas_object_data_set(win, "slider", o);
|
|
WEIGHT(o, EVAS_HINT_EXPAND, 0);
|
|
FILL(o);
|
|
evas_object_smart_callback_add(o, "changed", slider_seek, NULL);
|
|
elm_object_signal_callback_add(o, "guide,changed,*", "empc", slider_fmt, NULL);
|
|
elm_slider_min_max_set(o, 0.0, 1.0);
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_POSITION, o);
|
|
evas_object_show(o);
|
|
|
|
queue_list = o = elm_genlist_add(win);
|
|
elm_object_style_set(o, "playlist");
|
|
evas_object_smart_callback_add(o, "longpressed", queue_list_item_longpress, NULL);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, queue_list_item_click, NULL);
|
|
evas_object_smart_callback_add(o, "realized", queue_list_item_realize, NULL);
|
|
evas_object_smart_callback_add(o, "unrealized", queue_list_item_unrealize, NULL);
|
|
evas_object_smart_callback_add(o, "unselected", queue_list_item_unselect, NULL);
|
|
evas_object_smart_callback_add(o, "clicked,double", queue_list_double_click, NULL);
|
|
evas_object_smart_callback_add(o, "scroll,anim,stop", queue_list_scroll_stop, NULL);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, queue_list_key_down, NULL);
|
|
elm_genlist_multi_select_mode_set(o, ELM_OBJECT_MULTI_SELECT_MODE_DEFAULT);
|
|
elm_genlist_homogeneous_set(o, EINA_TRUE);
|
|
elm_genlist_multi_select_set(o, 1);
|
|
elm_scroller_bounce_set(o, 0, 0);
|
|
elm_scroller_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
|
|
elm_genlist_mode_set(o, ELM_LIST_COMPRESS);
|
|
EXPAND(o);
|
|
FILL(o);
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_PLAYLIST, o);
|
|
evas_object_show(o);
|
|
evas_object_focus_set(o, EINA_TRUE);
|
|
|
|
{
|
|
const char *parts[] =
|
|
{
|
|
EMPC_LOGIN_SWALLOW_PORT,
|
|
EMPC_LOGIN_SWALLOW_HOST,
|
|
EMPC_LOGIN_SWALLOW_PASSWORD
|
|
};
|
|
Evas_Object **objs[] =
|
|
{
|
|
&login_port,
|
|
&login_host,
|
|
&login_password,
|
|
};
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
*objs[i] = o = elm_entry_add(win);
|
|
elm_entry_single_line_set(o, 1);
|
|
elm_entry_scrollable_set(o, 0);
|
|
elm_entry_password_set(o, i == 2);
|
|
if (!i)
|
|
elm_entry_markup_filter_append(o, login_port_filter, NULL);
|
|
elm_object_style_set(o, "login");
|
|
evas_object_smart_callback_add(o, "activated", login_connect, NULL);
|
|
elm_object_part_content_set(layout, parts[i], o);
|
|
}
|
|
elm_layout_signal_callback_add(layout, "empc,login,close,request", "empc", login_close_request, NULL);
|
|
}
|
|
|
|
{
|
|
Evas_Object *ly;
|
|
|
|
layout_filesystem = ly = elm_layout_add(win);
|
|
elm_object_focus_allow_set(ly, 0);
|
|
elm_layout_theme_set(ly, "layout", "empc", "filesystem");
|
|
elm_layout_signal_emit(ly, "empc,back,hide", "empc");
|
|
elm_layout_signal_callback_add(ly, "empc,search,hidden", "empc", filesystem_search_hidden, NULL);
|
|
elm_layout_signal_callback_add(ly, "empc,search,visible", "empc", filesystem_search_visible, NULL);
|
|
elm_object_part_content_set(layout, EMPC_SWALLOW_FILESYSTEM, ly);
|
|
|
|
filesystem_entry = o = elm_entry_add(win);
|
|
elm_object_style_set(o, "filesystem");
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, filesystem_entry_key, NULL);
|
|
elm_entry_single_line_set(o, 1);
|
|
elm_entry_scrollable_set(o, 0);
|
|
elm_object_part_content_set(ly, "empc.swallow.search", o);
|
|
|
|
o = button_add("fs-back", NULL, "empc", filesystem_button_back);
|
|
elm_object_tooltip_text_set(o, _("Go to parent directory"));
|
|
WEIGHT(o, EVAS_HINT_EXPAND, 0);
|
|
FILL(o);
|
|
elm_object_part_content_set(ly, "empc.swallow.back", o);
|
|
|
|
hbox = elm_box_add(win);
|
|
WEIGHT(hbox, EVAS_HINT_EXPAND, 0);
|
|
FILL(hbox);
|
|
elm_box_horizontal_set(hbox, 1);
|
|
elm_box_homogeneous_set(hbox, 1);
|
|
|
|
o = button_add("add", NULL, "empc", filesystem_button_add);
|
|
elm_object_tooltip_text_set(o, _("Add to play queue"));
|
|
elm_object_tooltip_style_set(o, "empc");
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
o = button_add("refresh", NULL, "empc", filesystem_button_update);
|
|
elm_object_tooltip_text_set(o, _("Rescan"));
|
|
elm_object_tooltip_style_set(o, "empc");
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
elm_object_part_content_set(ly, "empc.swallow.buttons", hbox);
|
|
evas_object_data_set(ly, "hbox", hbox);
|
|
}
|
|
|
|
elm_win_icon_name_set(win, "empc");
|
|
evas_object_resize(win, 357, 362);
|
|
evas_object_show(win);
|
|
|
|
elm_run();
|
|
/* crashing wooooooooo
|
|
metadata_shutdown();
|
|
|
|
empd_empdd_proxy_unref(empd_proxy);
|
|
empd_empdd_proxy_unref(empc_proxy);
|
|
E_FREE_LIST(handlers, ecore_event_handler_del);
|
|
eldbus_connection_unref(dbus_conn);
|
|
eldbus_shutdown();
|
|
efreet_shutdown();
|
|
elm_shutdown();
|
|
|
|
{
|
|
Empc_Module_Type t;
|
|
Empc_Module *mod;
|
|
Eina_Inlist *l;
|
|
|
|
for (t = 0; t < EMPC_MODULE_TYPE_LAST; t++)
|
|
EINA_INLIST_FOREACH_SAFE(empc_modules[t], l, mod)
|
|
{
|
|
eina_module_free(mod->module);
|
|
free(mod);
|
|
}
|
|
}
|
|
eina_list_free(filesystems);
|
|
|
|
eina_shutdown();
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
EAPI const Eina_List *
|
|
empc_modapi_queue_list_header_items_find(const char *artist, const char *album)
|
|
{
|
|
char buf[4096];
|
|
|
|
snprintf(buf, sizeof(buf), "%s:::%s", artist, album);
|
|
return eina_hash_find(empd_current_queue_headers, buf);
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
empc_modapi_queue_list_song_find(const Empd_Empdd_File *f)
|
|
{
|
|
const Eina_List *l, *ll;
|
|
Elm_Object_Item *it, *sit;
|
|
|
|
EINA_LIST_FOREACH(empc_modapi_queue_list_header_items_find(f->artist, f->album), l, it)
|
|
EINA_LIST_FOREACH(elm_genlist_item_subitems_get(it), ll, sit)
|
|
{
|
|
Empd_Empdd_Song *so = elm_object_item_data_get(sit);
|
|
|
|
if (so->uri == f->uri) return EINA_TRUE;
|
|
}
|
|
return EINA_FALSE;
|
|
}
|