Apply modified Listeners
[profile/tv/apps/native/musicplayer.git] / src / views / category-layout.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <Elementary.h>
18 #include <Eina.h>
19 #include <utilX.h>
20 #include "AppCommon.h"
21 #include "dbg.h"
22 #include "i18n.h"
23 #include "define.h"
24
25 #include <InputHandler.h>
26 #include "category_info.h"
27 #include "album_info.h"
28 #include "song_info.h"
29 #include "music-controller.h"
30 #include "LayoutMgr.h"
31 #include "entry-popup.h"
32 #include "common.h"
33 #include "common-ui.h"
34 #include "BaseView.h"
35 #include "ExtBaseLayout.h"
36 #include "ViewMgr.h"
37 #include "category-layout.h"
38 #include "base-view.h"
39
40 #define TOTAL_ADD_BTNS 3
41 #define TOTAL_SELECT_BTNS 3
42 #define GENGRID_ITEM_SIZE_W (263+20)
43 #define GENGRID_ITEM_SIZE_H (359+20)
44
45
46 enum EObjectType {
47         CATEGORY_LAYOUT,
48         CATEGORY_LAYOUT_GENGRID,
49         CATEGORY_LAYOUT_GENLIST,
50         CATEGORY_LAYOUT_PLAY_BUTTON,
51         CATEGORY_LAYOUT_NEXT_BUTTON,
52         CATEGORY_LAYOUT_LAST_BUTTON,
53         CATEGORY_LAYOUT_SELECT_ALL_BUTTON,
54         CATEGORY_LAYOUT_DONE_BUTTON,
55         CATEGORY_LAYOUT_CANCEL_BUTTON
56 };
57
58 enum EAddBtns {
59         ABTN_PLAY,
60         ABTN_NEXT,
61         ABTN_LAST
62 };
63
64 enum ESelectBtns {
65         SBTN_SELECT_ALL,
66         SBTN_DONE,
67         SBTN_CANCEL
68 };
69
70 enum EIdType {
71         ID_TYPE_MEDIA,
72         ID_TYPE_MEMBER
73 };
74
75 struct SBtnInfo {
76         const char *name;
77         const char *part;
78         const char *style;
79         const char *icon;
80         EObjectType type;
81 };
82
83 struct SCategoryLayout {
84         Evas_Object *win;
85         Evas_Object *layout;
86         Evas_Object *glist;
87         Evas_Object *add_btn[TOTAL_ADD_BTNS];
88         Evas_Object *select_btn[TOTAL_SELECT_BTNS];
89         Evas_Object *albumCover;
90         Evas_Object *def_foc_btn;
91         Eina_List *catlist;
92         Eina_List *alblist;
93         Eina_List *songlist;
94         Eina_List *it_infolist;
95         Ecore_Idler *focus_idler;
96         CMusicController *pMusicController;
97         CLayoutMgr *lmgr;
98         CViewMgr *vmgr;
99         SSongInfo *c_sinfo;
100         int total_duration;
101         int count;
102
103         SCategoryLayout() {
104                 memset(this, 0, sizeof(SCategoryLayout));
105         }
106
107         ~SCategoryLayout() {
108         }
109 };
110
111
112 Eina_Bool CCategoryLayout::sm_CbFocusIdler(void *dt)
113 {
114         CCategoryLayout *root = (CCategoryLayout *)dt;
115
116         Eina_Bool ret = EINA_FALSE;
117         if (root)
118                 ret = root->m_OnFocusIdler();
119
120         return ret;
121 }
122
123
124 Eina_Bool CCategoryLayout::m_OnFocusIdler(void)
125 {
126         Elm_Object_Item *it = NULL;
127         SCatItemInfo *itinfo = NULL;
128
129         m->focus_idler = NULL;
130         elm_object_tree_focus_allow_set(t.base, EINA_TRUE);
131
132         if (t.depth == E_DEPTH_CATEGORY) {
133                 it = m_FindItemByInfo(m->it_infolist, t.c_catinfo);
134                 if (!it) {
135                         itinfo = (SCatItemInfo *)eina_list_nth(m->it_infolist, 0);
136                         it = itinfo->item;
137                 }
138                 elm_gengrid_item_show(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
139                 elm_object_item_focus_set(it, EINA_TRUE);
140         }
141         else
142                 elm_object_focus_set(m->def_foc_btn, EINA_TRUE);
143
144         return ECORE_CALLBACK_CANCEL;
145 }
146
147
148 void CCategoryLayout::sm_CbEntrynameSet(void *dt, const char *name)
149 {
150         CCategoryLayout *root = (CCategoryLayout *)dt;
151         if (root)
152                 root->m_OnEntrynameSet(name);
153 }
154
155
156 void CCategoryLayout::m_OnEntrynameSet(const char *name)
157 {
158         Eina_List *idlist = NULL;
159         char *str = NULL;
160
161         if (!name)
162                 return;
163
164         idlist = m_GetSelectedList(m->it_infolist, (int)ID_TYPE_MEDIA);
165         str = strdup(name);
166         t.epopup->Destroy();
167
168         if (!strcmp(str, MUSIC_STR_EMPTY)) {
169                 _create_message_box(Layout(), MUSIC_TEXT_EMPTY_NAME);
170                 free(str);
171                 return;
172         }
173
174         if (m->pMusicController->MediaExistPlaylist(str)) {
175                 _create_message_box(Layout(), MUSIC_TEXT_INUSE_MSG);
176                 free(str);
177                 return;
178         }
179
180         if (!m->pMusicController->MediaInsertPlaylist(str, idlist)) {
181                 _ERR("Playlist creation failed ");
182                 free(str);
183                 return;
184         }
185
186         t.depth = E_DEPTH_CATEGORY;
187         t_UpdateLayoutWithFocus();
188 }
189
190
191 char *CCategoryLayout::sm_CbGetSelectlistItemText(void *data, Evas_Object *obj, const char *part)
192 {
193         SCatItemInfo *itinfo = (SCatItemInfo *)data;
194         char *str = NULL;
195         int index;
196
197         if (!itinfo || !obj || !part)
198                 return NULL;
199
200         if (!strcmp(part, "elm.text")) {
201                 str = song_info_get_title(itinfo->sinfo);
202
203                 index = elm_genlist_item_index_get(itinfo->item);
204                 if ((index & 1) == 1)
205                         elm_object_item_signal_emit(itinfo->item,
206                         MUSIC_SIGNAL_EVEN_ROW, MUSIC_BASE_VIEW);
207                 else
208                         elm_object_item_signal_emit(itinfo->item,
209                         MUSIC_SIGNAL_ODD_ROW, MUSIC_BASE_VIEW);
210
211                 if (itinfo->check_status)
212                         elm_object_item_signal_emit(itinfo->item,
213                         MUSIC_SIGNAL_CHECK_ON, MUSIC_BASE_VIEW);
214                 else
215                         elm_object_item_signal_emit(itinfo->item,
216                         MUSIC_SIGNAL_CHECK_OFF, MUSIC_BASE_VIEW);
217         }
218         else if (!strcmp(part, "elm.text1")) {
219                 str = song_info_get_artist(itinfo->sinfo);
220         }
221         else if (!strcmp(part, "elm.text2")) {
222                 str = song_info_get_album(itinfo->sinfo);
223         }
224
225         if (str)
226                 return strdup(str);
227
228         return NULL;
229 }
230
231
232 char *CCategoryLayout::sm_CbGetListItemText(void *data, Evas_Object *obj, const char *part)
233 {
234         SCatItemInfo *itinfo = (SCatItemInfo *)data;
235         SSongInfo *sinfo = NULL;
236         char buf[MAX_LENGTH];
237         char *timestr = NULL;
238         int duration;
239         int index;
240
241         if (!itinfo || !obj || !part)
242                 return NULL;
243
244         sinfo = itinfo->sinfo;
245
246         snprintf(buf, sizeof(buf), "%s", MUSIC_STR_EMPTY);
247
248         if (!strcmp(part, "elm.text")) {
249                 index = elm_genlist_item_index_get(itinfo->item);
250                 if ((index & 1) == 1) {
251                         elm_object_item_signal_emit(itinfo->item,
252                                 MUSIC_SIGNAL_EVEN_ROW, MUSIC_BASE_VIEW);
253                 }
254                 else {
255                         elm_object_item_signal_emit(itinfo->item,
256                                 MUSIC_SIGNAL_ODD_ROW, MUSIC_BASE_VIEW);
257                 }
258                 snprintf(buf, sizeof(buf), "%d", index + 1);
259         }
260         else if (!strcmp(part, "elm.text1")) {
261                 snprintf(buf, sizeof(buf), "%s", song_info_get_title(sinfo));
262         }
263         else if (!strcmp(part, "elm.text2")) {
264                 snprintf(buf, sizeof(buf), "%s", song_info_get_artist(sinfo));
265         }
266         else if (!strcmp(part, "elm.text3")) {
267                 if (song_info_get_duration(sinfo, &duration)) {
268                         timestr = _get_timestr_from_milseconds(duration);
269                         if (timestr) {
270                                 snprintf(buf, sizeof(buf), "%s", timestr);
271                                 free(timestr);
272                         }
273                 }
274         }
275
276         if (strcmp(buf, MUSIC_STR_EMPTY))
277                 return strdup(buf);
278
279         return NULL;
280 }
281
282
283 void CCategoryLayout::sm_CbRemoveListItem(void *data, Evas_Object *obj)
284 {
285         free(data);
286 }
287
288
289 void CCategoryLayout::sm_CbSongItemSelect(void *data, Evas_Object *obj, void *event_info)
290 {
291         CCategoryLayout *root = (CCategoryLayout *)data;
292         if (root)
293                 root->m_OnSongItemSelect(obj, (Elm_Object_Item *)event_info);
294 }
295
296
297 void CCategoryLayout::m_OnSongItemSelect(Evas_Object *obj, Elm_Object_Item *event_info)
298 {
299         SCatItemInfo *itinfo = NULL;
300         char *id = NULL;
301
302         if (!m || !obj)
303                 return;
304
305         itinfo = m_FindItemInfo(m->it_infolist, (Elm_Object_Item *)event_info);
306         if (!itinfo) {
307                 _ERR(" no item info found ");
308                 return;
309         }
310
311         if (m->c_sinfo) {
312                 song_info_destroy(m->c_sinfo);
313                 m->c_sinfo = NULL;
314         }
315         m->c_sinfo = song_info_duplicate(itinfo->sinfo);
316         if (!m->c_sinfo)
317                 return;
318
319         id = song_info_get_media_id(m->c_sinfo);
320         if (!id) {
321                 song_info_destroy(m->c_sinfo);
322                 m->c_sinfo = NULL;
323                 return;
324         }
325
326         m_GotoPlayback(ADD_TYPE_FRESH, id);
327 }
328
329
330 void CCategoryLayout::sm_CbSelectlistItemSelect(void *data, Evas_Object *obj, void *event_info)
331 {
332         CCategoryLayout *root = (CCategoryLayout *)data;
333         if (root)
334                 root->m_OnSelectlistItemSelect(obj, (Elm_Object_Item *)event_info);
335 }
336
337
338 void CCategoryLayout::m_OnSelectlistItemSelect(Evas_Object *obj, void *event_info)
339 {
340         SCatItemInfo *itinfo = NULL;
341         int tc;
342
343         if (!obj)
344                 return;
345
346         itinfo = m_FindItemInfo(m->it_infolist, (Elm_Object_Item *)event_info);
347         if (!itinfo) {
348                 _ERR(" no item info found ");
349                 return;
350         }
351
352         tc = eina_list_count(m->it_infolist);
353         if (itinfo->check_status) {
354                 if (tc == m->count)
355                         elm_object_text_set(m->select_btn[SBTN_SELECT_ALL],
356                         _(MUSIC_TEXT_SELECT_ALL));
357                 m->count = m->count - 1;
358                 elm_object_item_signal_emit(itinfo->item,
359                         MUSIC_SIGNAL_CHECK_OFF, MUSIC_BASE_VIEW);
360                 itinfo->check_status = false;
361         }
362         else {
363                 m->count = m->count + 1;
364                 if (tc == m->count)
365                         elm_object_text_set(m->select_btn[SBTN_SELECT_ALL],
366                         _(MUSIC_TEXT_DESELECT_ALL));
367                 elm_object_item_signal_emit(itinfo->item,
368                         MUSIC_SIGNAL_CHECK_ON, MUSIC_BASE_VIEW);
369                 itinfo->check_status = true;
370         }
371 }
372
373
374 void CCategoryLayout::sm_CbCtxtUpdate(void *dt, enum EActionType type, int lid)
375 {
376         CCategoryLayout *root = (CCategoryLayout *)dt;
377
378         if (root)
379                 root->t_OnCtxtUpdate(type, lid);
380 }
381
382
383 void CCategoryLayout::t_OnCtxtUpdate(enum EActionType type, int lid)
384 {
385         Eina_List *list = NULL;
386         Eina_List *alist = NULL, *slist = NULL, *l = NULL, *sl = NULL;
387         SSongInfo *sinfo = NULL;
388         album_info *alinfo = NULL;
389         void *obj = NULL;
390         EAddType mode;
391
392         if (!t.ctxtinfo || !t.ctxtinfo->context)
393                 return;
394
395         if (type == ACTION_TYPE_ADDNEXT)
396                 mode = ADD_TYPE_NEXT;
397         else
398                 mode = ADD_TYPE_END;
399
400         if (t.depth == E_DEPTH_SONG) {
401                 sinfo = (SSongInfo *)t.ctxtinfo->context;
402                 list = eina_list_append(list, sinfo);
403         }
404         else if (t.depth == E_DEPTH_ALBUM) {
405                 m->pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG,
406                         t.ctxtinfo->context, &list);
407                 sinfo = (SSongInfo *)eina_list_data_get(list);
408         }
409         else {
410                 alist = category_info_get_albumlist((category_info *)t.ctxtinfo->context);
411                 EINA_LIST_FOREACH(alist, l, obj) {
412                         alinfo = (album_info *)obj;
413                         slist = NULL;
414                         if (!m->pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG, (void *)alinfo, &slist)) {
415                                 _ERR(" Failed to get album songlist ");
416                                 continue;
417                         }
418                         EINA_LIST_FOREACH(slist, sl, obj) {
419                                 sinfo = (SSongInfo *)obj;
420                                 list = eina_list_append(list,
421                                         song_info_duplicate((SSongInfo *)sinfo));
422                         }
423                         eina_list_free(slist);
424                 }
425                 sinfo = (SSongInfo *)eina_list_data_get(list);
426         }
427
428         if (type ==  ACTION_TYPE_ADDTO) {
429                 if (!m->pMusicController->MediaAddsongsPlaylist(lid, list))
430                         _ERR(" Adding songs to playlist failed ");
431                 else
432                         _create_message_box(t.base, MUSIC_TEXT_ADDTO_MSG);
433
434                 if (t.depth == E_DEPTH_CATEGORY) {
435                         EINA_LIST_FREE(list, obj) {
436                                 sinfo = (SSongInfo *)obj;
437                                 song_info_destroy(sinfo);
438                         }
439                 }
440
441                 return;
442         }
443
444         m->pMusicController->UpdatePlaylist(list, mode);
445         if (type == ACTION_TYPE_PLAY) {
446                 m->pMusicController->Stop();
447                 m->pMusicController->SetCurrentSong(song_info_get_media_id((SSongInfo *)sinfo));
448         }
449
450         if (t.depth == E_DEPTH_CATEGORY) {
451                 EINA_LIST_FREE(list, obj) {
452                         sinfo = (SSongInfo *)obj;
453                         song_info_destroy(sinfo);
454                 }
455         }
456         else {
457                 eina_list_free(list);
458         }
459
460         _update_playback_view((EAddType)type, Layout(), t.focused_item);
461 }
462
463
464 void CCategoryLayout::sm_CbCtxtClose(void *dt)
465 {
466         CCategoryLayout *root = (CCategoryLayout *)dt;
467         if (root)
468                 root->m_OnCtxtClose();
469 }
470
471
472 void CCategoryLayout::m_OnCtxtClose(void)
473 {
474         m->vmgr->PopView();
475         m->vmgr->PushView(MUSIC_BASE_VIEW, NULL);
476         elm_object_item_focus_set(t.focused_item, EINA_TRUE);
477 }
478
479
480 char *CCategoryLayout::sm_CbGetGridItemText(void *data, Evas_Object *obj, const char *part)
481 {
482         SCatItemInfo *itinfo = (SCatItemInfo *)data;
483         int scount, acount;
484         const char *txt = NULL;
485         char buf[MAX_LENGTH];
486
487         if (!itinfo || !obj || !part)
488                 return NULL;
489
490         if (!strcmp(part, "elm.text")) {
491                 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW)
492                         return strdup(_(MUSIC_TEXT_CREATE_PLAYLIST));
493
494                 txt = category_info_get_name(itinfo->catinfo);
495                 if (txt)
496                         return strdup(txt);
497         }
498         else if (!strcmp(part, "elm.text1")) {
499                 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW) {
500                         return NULL;
501                 }
502                 else if (itinfo->type == CAT_TYPE_PLAYLISTS) {
503                         scount = category_info_get_songcount(itinfo->catinfo);
504                         snprintf(buf, sizeof(buf), "%d %s", scount, _("Songs"));
505                 }
506                 else {
507                         acount = category_info_get_albumcount(itinfo->catinfo);
508                         scount = category_info_get_songcount(itinfo->catinfo);
509                         snprintf(buf, sizeof(buf), "%d %s, %d %s", acount,
510                                 _("Albums"), scount, _("Songs"));
511                 }
512                 return strdup(buf);
513         }
514
515         return NULL;
516 }
517
518
519 char *CCategoryLayout::sm_CbGetGridAlbumItemText(void *data, Evas_Object *obj, const char *part)
520 {
521         SCatItemInfo *itinfo = (SCatItemInfo *)data;
522         album_info *alinfo = NULL;
523         char *txt = NULL;
524
525         if (!itinfo || !obj || !part)
526                 return NULL;
527
528         alinfo = itinfo->alinfo;
529
530         if (!strcmp(part, "elm.text")) {
531                 txt = album_info_get_name(alinfo);
532                 if (txt)
533                         return strdup(txt);
534         }
535         else if (!strcmp(part, "elm.text1")) {
536                 if (itinfo->type == CAT_TYPE_ARTIST)
537                         txt = album_info_get_artist(alinfo);
538                 else
539                         txt = album_info_get_genre(alinfo);
540                 if (txt)
541                         return strdup(txt);
542         }
543
544         return NULL;
545 }
546
547
548 Evas_Object *CCategoryLayout::sm_CbGetGridItemContent(void *data, Evas_Object *obj, const char *part)
549 {
550         SCatItemInfo *itinfo = (SCatItemInfo *)data;
551         album_info *alinfo = NULL;
552         void *list_obj = NULL;
553         Eina_List *l = NULL, *alist = NULL;
554         Evas_Object *img = NULL;
555         char *path = NULL;
556         char buf[MAX_LENGTH];
557
558         if (!itinfo || !obj || !part)
559                 return NULL;
560
561         if (!itinfo->catinfo && itinfo->type != CAT_TYPE_PLAYLIST_NEW)
562                 return NULL;
563
564         if (strcmp(part, "elm.swallow.icon"))
565                 return NULL;
566
567         img = elm_image_add(obj);
568         if (!img)
569                 return NULL;
570
571         path = NULL;
572
573         if (itinfo->type == CAT_TYPE_ARTIST || itinfo->type == CAT_TYPE_GENRE) {
574                 alist = category_info_get_albumlist(itinfo->catinfo);
575                 if (alist) {
576                         EINA_LIST_FOREACH(alist, l, list_obj) {
577                                 alinfo = (album_info *)list_obj;
578                                 path = album_info_get_thumb(alinfo);
579                                 if (path)
580                                         break;
581                         }
582                 }
583         }
584         else if (itinfo->type == CAT_TYPE_PLAYLISTS) {
585                 path = category_info_get_thumb(itinfo->catinfo);
586         }
587
588         if (!path) {
589                 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW)
590                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
591                         MUSIC_IMAGE_CREATE_PLAYLIST);
592                 else
593                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
594                         MUSIC_IMAGE_DEFAULT_THUMB_126);
595                 elm_image_file_set(img, buf, NULL);
596                 elm_image_no_scale_set(img, EINA_TRUE);
597         }
598         else {
599                 elm_image_file_set(img, path, NULL);
600                 elm_image_aspect_fixed_set(img, EINA_FALSE);
601         }
602
603         return img;
604 }
605
606
607 Evas_Object *CCategoryLayout::sm_CbGetGridAlbumitemContent(void *data, Evas_Object *obj, const char *part)
608 {
609         SCatItemInfo *itinfo = (SCatItemInfo *)data;
610         album_info *alinfo = NULL;
611         char *path = NULL;
612         Evas_Object *img = NULL;
613         char buf[MAX_LENGTH];
614
615         if (!itinfo || !obj || !part)
616                 return NULL;
617
618         alinfo = itinfo->alinfo;
619
620         if (strcmp(part, "elm.swallow.icon"))
621                 return NULL;
622
623         img = elm_image_add(obj);
624         if (!img)
625                 return NULL;
626
627         path = album_info_get_thumb(alinfo);
628         if (!path) {
629                 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
630                         MUSIC_IMAGE_DEFAULT_THUMB_126);
631                 elm_image_file_set(img, buf, NULL);
632                 elm_image_no_scale_set(img, EINA_TRUE);
633         }
634         else {
635                 elm_image_file_set(img, path, NULL);
636                 elm_image_aspect_fixed_set(img, EINA_FALSE);
637         }
638
639         return img;
640 }
641
642
643 void CCategoryLayout::sm_CbRemoveGridItem(void *data, Evas_Object *obj)
644 {
645         free(data);
646 }
647
648
649 void CCategoryLayout::sm_CbItemSelect(void *data, Elm_Object_Item *it, const char *emission, const char *source)
650 {
651         CCategoryLayout *root = (CCategoryLayout *)data;
652         if (root)
653                 root->m_OnItemSelect(it, emission, source);
654 }
655
656
657 void CCategoryLayout::m_OnItemSelect(Elm_Object_Item *it, const char *emission, const char *source)
658 {
659         SCatItemInfo *itinfo = NULL;
660
661         itinfo = m_FindItemInfo(m->it_infolist, it);
662         if (!itinfo) {
663                 _ERR(" no item info found ");
664                 return;
665         }
666
667         if (t.depth == E_DEPTH_ALBUM) {
668                 if (t.c_alinfo) {
669                         album_info_destroy(t.c_alinfo);
670                         t.c_alinfo = NULL;
671                 }
672                 t.c_alinfo = album_info_duplicate(itinfo->alinfo);
673                 t.depth = E_DEPTH_SONG;
674         }
675         else {
676                 if (t.c_catinfo) {
677                         category_info_destroy(t.c_catinfo);
678                         t.c_catinfo = NULL;
679                 }
680
681                 t_HandleItemSelect(itinfo);
682         }
683
684         t_UpdateLayoutWithFocus();
685 }
686
687
688 int CCategoryLayout::m_ConvertToMin(int milsec)
689 {
690         int min;
691
692         min = milsec / 60000;  /*milli seconds per minute*/
693
694         return min;
695 }
696
697
698 void CCategoryLayout::m_RemoveFocusIdler(void)
699 {
700         if (!m->focus_idler)
701                 return;
702
703         ecore_idler_del(m->focus_idler);
704         m->focus_idler = NULL;
705 }
706
707
708 Elm_Object_Item *CCategoryLayout::m_FindItemByInfo(Eina_List *list, void *info)
709 {
710         Eina_List *l = NULL;
711         SCatItemInfo *itinfo = NULL;
712         void *obj = NULL;
713         int id;
714
715         if (!list || !info)
716                 return NULL;
717
718         EINA_LIST_FOREACH(list, l, obj) {
719                 itinfo = (SCatItemInfo *)obj;
720                 if (!itinfo->catinfo)
721                         continue;
722
723                 id = category_info_get_category_id(itinfo->catinfo);
724                 if (id == category_info_get_category_id((category_info *)info))
725                         return itinfo->item;
726         }
727
728         return NULL;
729 }
730
731
732 CCategoryLayout::SCatItemInfo *CCategoryLayout::m_FindItemInfo(Eina_List *list, Elm_Object_Item *item)
733 {
734         Eina_List *l = NULL;
735         SCatItemInfo *itinfo = NULL;
736         void *obj = NULL;
737
738         if (!list || !item)
739                 return NULL;
740
741         EINA_LIST_FOREACH(list, l, obj) {
742                 itinfo = (SCatItemInfo *)obj;
743                 if (itinfo->item == item)
744                         return itinfo;
745         }
746
747         return NULL;
748 }
749
750
751 void CCategoryLayout::m_GotoPlayback(int mode, char *id)
752 {
753         if (!m->it_infolist || eina_list_count(m->it_infolist) == 0) {
754                 _create_message_box(Layout(), MUSIC_TEXT_NO_SONGS);
755                 _ERR(" No songs for playback ");
756                 return;
757         }
758
759         if (t.depth == E_DEPTH_ALBUM)
760                 m_AddAlbumsToPlayback(mode);
761         else if (t.depth == E_DEPTH_SONG ||
762                 t.depth == E_DEPTH_SHOW_LIST)
763                 m_AddSongsToPlayback(mode);
764         else
765                 return;
766
767         if (mode == ADD_TYPE_FRESH) {
768                 m->pMusicController->Stop();
769                 if (id)   /* If want to play selected song */
770                         m->pMusicController->SetCurrentSong(id);
771         }
772
773         _update_playback_view((EAddType)mode, Layout(), NULL);
774 }
775
776
777 Eina_List *CCategoryLayout::m_GetSelectedList(Eina_List *infolist, int type)
778 {
779         Eina_List *idlist = NULL, *l = NULL;
780         SCatItemInfo *itinfo = NULL;
781         void *obj = NULL;
782         char *id = NULL;
783         EIdType eType = (EIdType)type;
784
785         if (!infolist)
786                 return NULL;
787
788         idlist = NULL;
789         EINA_LIST_FOREACH(infolist, l, obj) {
790                 itinfo = (SCatItemInfo *)obj;
791                 if (!itinfo->check_status)
792                         continue;
793
794                 if (eType == ID_TYPE_MEDIA) {
795                         id = song_info_get_media_id(itinfo->sinfo);
796                         if (id)
797                                 idlist = eina_list_append(idlist, id);
798                 }
799                 else {
800                         idlist = eina_list_append(idlist,
801                                 itinfo->sinfo);
802                 }
803         }
804
805         return idlist;
806 }
807
808
809 void CCategoryLayout::m_AddSelectedSongs(void)
810 {
811         Eina_List *idlist = NULL;
812         int lid;
813
814         if (!t.c_catinfo)
815                 return;
816
817         lid = category_info_get_category_id(t.c_catinfo);
818         idlist = m_GetSelectedList(m->it_infolist, (int)ID_TYPE_MEDIA);
819
820         if (!lid || !idlist)
821                 return;
822
823         if (!m->pMusicController->MediaAddmediaPlaylist(lid, idlist)) {
824                 _ERR(" Failed to add songs to playlist ");
825                 return;
826         }
827
828         t.depth = E_DEPTH_CATEGORY;
829         t_UpdateLayoutWithFocus();
830 }
831
832
833 void CCategoryLayout::m_RemoveSelectedSongs(void)
834 {
835         Eina_List *idlist = NULL;
836         int lid;
837
838         if (!t.c_catinfo)
839                 return;
840
841         lid = category_info_get_category_id(t.c_catinfo);
842         idlist = m_GetSelectedList(m->it_infolist, (int)ID_TYPE_MEMBER);
843
844         if (!lid || !idlist)
845                 return;
846
847         if (!m->pMusicController->MediaRemovemediaPlaylist(lid, idlist)) {
848                 _ERR(" Failed to remove songs from playlist ");
849                 return;
850         }
851
852         t.depth = E_DEPTH_CATEGORY;
853         t_UpdateLayoutWithFocus();
854 }
855
856
857 void CCategoryLayout::m_AddAlbumsToPlayback(int mode)
858 {
859         Eina_List *l = NULL, *sl = NULL;
860         Eina_List *slist = NULL;
861         Eina_List *list = NULL;
862         SSongInfo *sinfo = NULL;
863         SCatItemInfo *itinfo = NULL;
864         void *obj = NULL;
865         Eina_List *infolist = m->it_infolist;
866         CMusicController *pMusicController = m->pMusicController;
867
868         list = NULL;
869         EINA_LIST_FOREACH(infolist, l, obj) {
870                 itinfo = (SCatItemInfo *)obj;
871                 slist = NULL;
872                 if (!pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG, itinfo->alinfo, &slist)) {
873                         _ERR(" Failed to get album songlist ");
874                         continue;
875                 }
876
877                 EINA_LIST_FOREACH(slist, sl, obj) {
878                         sinfo = (SSongInfo *)obj;
879                         list = eina_list_append(list,
880                                 song_info_duplicate(sinfo));
881                 }
882
883                 eina_list_free(slist);
884         }
885
886         pMusicController->UpdatePlaylist(list, mode);
887         EINA_LIST_FREE(list, obj) {
888                 sinfo = (SSongInfo *)obj;
889                 song_info_destroy(sinfo);
890         }
891 }
892
893
894 void CCategoryLayout::m_AddSongsToPlayback(int mode)
895 {
896         Eina_List *l = NULL;
897         Eina_List *list = NULL;
898         struct SCatItemInfo *itinfo = NULL;
899         void *obj = NULL;
900         Eina_List *infolist = m->it_infolist;
901         CMusicController *pMusicController = m->pMusicController;
902
903         list = NULL;
904         EINA_LIST_FOREACH(infolist, l, obj) {
905                 itinfo = (SCatItemInfo *)obj;
906                 list = eina_list_append(list, itinfo->sinfo);
907         }
908
909         pMusicController->UpdatePlaylist(list, mode);
910         eina_list_free(list);
911 }
912
913
914 Evas_Object *CCategoryLayout::m_AddAlbumCover(void)
915 {
916         Evas_Object *album_cover = NULL;
917
918         album_cover = elm_image_add(Layout());
919         if (!album_cover)
920                 return NULL;
921
922         evas_object_size_hint_weight_set(album_cover, EVAS_HINT_EXPAND,
923                 EVAS_HINT_EXPAND);
924
925         return album_cover;
926 }
927
928
929 Evas_Object *CCategoryLayout::m_AddGrid(void)
930 {
931         Evas_Object *grid = NULL;
932
933         grid = elm_gengrid_add(Layout());
934         if (!grid)
935                 return NULL;
936
937         evas_object_size_hint_weight_set(grid,
938                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
939         elm_gengrid_align_set(grid, 0, 0);
940
941         Connect(grid, CATEGORY_LAYOUT_GENGRID, TYPE_MOUSE_MOVE | TYPE_KEY_DOWN | TYPE_REALIZED | TYPE_UNREALIZED);
942
943         elm_gengrid_item_size_set(grid,
944                 elm_config_scale_get() * GENGRID_ITEM_SIZE_W,
945                 elm_config_scale_get() * GENGRID_ITEM_SIZE_H);
946
947         return grid;
948 }
949
950
951 void CCategoryLayout::m_AddCategoryItem(Elm_Gengrid_Item_Class *grid_item, ECategoryType type, void *info)
952 {
953         SCatItemInfo *itinfo = NULL;
954         Elm_Object_Item *item = NULL;
955
956         if (!grid_item)
957                 return;
958
959         itinfo = (SCatItemInfo *)calloc(1, sizeof(*itinfo));
960         if (!itinfo)
961                 return;
962
963         itinfo->catinfo = (category_info *)info;
964         itinfo->type = type;
965         item = elm_gengrid_item_append(t.grid,
966                 grid_item, itinfo, NULL, m);
967         itinfo->item = item;
968         m->it_infolist = eina_list_append(m->it_infolist,
969                 itinfo);
970 }
971
972
973 void CCategoryLayout::m_AddButtons(void)
974 {
975         int i;
976         Evas_Object *img = NULL;
977         char buf[MAX_LENGTH];
978         SBtnInfo btninfo[TOTAL_ADD_BTNS];
979
980         btninfo[ABTN_PLAY].name = MUSIC_STR_PLAY;
981         btninfo[ABTN_PLAY].part = MUSIC_PART_CATEGORY_PLAYBTN;
982         btninfo[ABTN_PLAY].style = MUSIC_STYLE_ADD_PLAY_BTN;
983         btninfo[ABTN_PLAY].icon = MUSIC_IMAGE_ADD_PLAY;
984         btninfo[ABTN_PLAY].type = CATEGORY_LAYOUT_PLAY_BUTTON;
985
986         btninfo[ABTN_NEXT].name = MUSIC_STR_ADDNEXT;
987         btninfo[ABTN_NEXT].part = MUSIC_PART_CATEGORY_NEXTBTN;
988         btninfo[ABTN_NEXT].style = MUSIC_STYLE_ADD_NEXT_BTN;
989         btninfo[ABTN_NEXT].icon = MUSIC_IMAGE_ADD_NEXT;
990         btninfo[ABTN_NEXT].type = CATEGORY_LAYOUT_NEXT_BUTTON;
991
992         btninfo[ABTN_LAST].name = MUSIC_STR_ADDLAST;
993         btninfo[ABTN_LAST].part = MUSIC_PART_CATEGORY_LASTBTN;
994         btninfo[ABTN_LAST].style = MUSIC_STYLE_ADD_LAST_BTN;
995         btninfo[ABTN_LAST].icon = MUSIC_IMAGE_ADD_LAST;
996         btninfo[ABTN_LAST].type = CATEGORY_LAYOUT_LAST_BUTTON;
997
998         if (t.depth == E_DEPTH_SHOW_LIST) {
999                 btninfo[ABTN_PLAY].part = MUSIC_PART_ALBUM_PLAYBTN;
1000                 btninfo[ABTN_NEXT].part = MUSIC_PART_ALBUM_NEXTBTN;
1001                 btninfo[ABTN_LAST].part = MUSIC_PART_ALBUM_LASTBTN;
1002         }
1003
1004         for (i = 0; i < TOTAL_ADD_BTNS; i++) {
1005                 m->add_btn[i] = elm_button_add(Layout());
1006                 if (!m->add_btn[i])
1007                         continue;
1008
1009                 evas_object_size_hint_weight_set(m->add_btn[i],
1010                         EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1011                 elm_object_text_set(m->add_btn[i], _(btninfo[i].name));
1012                 elm_object_style_set(m->add_btn[i], btninfo[i].style);
1013
1014                 Connect(m->add_btn[i], btninfo[ABTN_LAST].type, TYPE_CLICKED | TYPE_MOUSE_MOVE);
1015
1016                 img = elm_image_add(m->add_btn[i]);
1017                 if (img) {
1018                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
1019                                 btninfo[i].icon);
1020                         elm_image_file_set(img, buf, NULL);
1021                         elm_object_part_content_set(m->add_btn[i],
1022                                 MUSIC_PART_ELM_SWALLOWICON, img);
1023                 }
1024
1025                 elm_object_part_content_set(Layout(), btninfo[i].part, m->add_btn[i]);
1026         }
1027
1028         elm_object_focus_set(m->add_btn[ABTN_PLAY], EINA_TRUE);
1029         m->def_foc_btn = m->add_btn[ABTN_PLAY];
1030 }
1031
1032
1033 void CCategoryLayout::m_AddSelectlistButtons(void)
1034 {
1035         int i;
1036         Evas_Object *btn = NULL;
1037         SBtnInfo btninfo[TOTAL_SELECT_BTNS];
1038
1039         btninfo[SBTN_SELECT_ALL].name = MUSIC_TEXT_SELECT_ALL;
1040         btninfo[SBTN_SELECT_ALL].part = MUSIC_PART_LIST_SELECT_ALL;
1041         btninfo[SBTN_SELECT_ALL].style = MUSIC_STYLE_LIST_BTN;
1042         btninfo[SBTN_SELECT_ALL].type = CATEGORY_LAYOUT_SELECT_ALL_BUTTON;
1043
1044         btninfo[SBTN_DONE].name = MUSIC_TEXT_LIST_DONE;
1045         btninfo[SBTN_DONE].part = MUSIC_PART_LIST_DONE_BTN;
1046         btninfo[SBTN_DONE].style = MUSIC_STYLE_LIST_BTN;
1047         btninfo[SBTN_DONE].type = CATEGORY_LAYOUT_DONE_BUTTON;
1048
1049         btninfo[SBTN_CANCEL].name = MUSIC_TEXT_LIST_CANCEL;
1050         btninfo[SBTN_CANCEL].part = MUSIC_PART_LIST_CANCEL_BTN;
1051         btninfo[SBTN_CANCEL].style = MUSIC_STYLE_LIST_BTN;
1052         btninfo[SBTN_CANCEL].type = CATEGORY_LAYOUT_CANCEL_BUTTON;
1053
1054         if (t.sel_type == SELECT_CREATE) {
1055                 elm_object_part_text_set(Layout(), MUSIC_PART_LIST_MSG,
1056                         _(MUSIC_TEXT_LIST_CREATE_MSG));
1057         }
1058         else if (t.sel_type == SELECT_ADD) {
1059                 elm_object_part_text_set(Layout(), MUSIC_PART_LIST_MSG,
1060                         _(MUSIC_TEXT_LIST_ADD_MSG));
1061         }
1062         else if (t.sel_type == SELECT_REMOVE) {
1063                 elm_object_part_text_set(Layout(), MUSIC_PART_LIST_MSG,
1064                         _(MUSIC_TEXT_LIST_REMOVE_MSG));
1065         }
1066
1067         for (i = 0; i < TOTAL_SELECT_BTNS; i++) {
1068                 btn = elm_button_add(Layout());
1069                 if (!btn)
1070                         continue;
1071
1072                 evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND,
1073                         EVAS_HINT_EXPAND);
1074                 elm_object_text_set(btn, _(btninfo[i].name));
1075                 elm_object_style_set(btn, btninfo[i].style);
1076
1077                 Connect(btn, btninfo[i].type, TYPE_MOUSE_MOVE | TYPE_CLICKED);
1078
1079                 elm_object_part_content_set(Layout(), btninfo[i].part, btn);
1080                 m->select_btn[i] = btn;
1081         }
1082
1083         elm_object_focus_set(btn, EINA_TRUE);
1084         m->def_foc_btn = btn;
1085 }
1086
1087
1088 void CCategoryLayout::m_CreateSongsTopSection(void)
1089 {
1090         char *path = NULL;
1091         char buf[MAX_LENGTH];
1092
1093         m_AddButtons();
1094
1095         m->albumCover = m_AddAlbumCover();
1096         if (!m->albumCover)
1097                 return;
1098
1099         if (t.depth == E_DEPTH_SHOW_LIST)
1100                 path = category_info_get_thumb(t.c_catinfo);
1101         else
1102                 path = album_info_get_thumb(t.c_alinfo);
1103
1104         if (path) {
1105                 elm_image_file_set(m->albumCover, path, NULL);
1106                 elm_image_aspect_fixed_set(m->albumCover, EINA_FALSE);
1107         }
1108         else {
1109                 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
1110                         MUSIC_IMAGE_DEFAULT_THUMB_126);
1111                 elm_image_file_set(m->albumCover, buf, NULL);
1112                 elm_image_no_scale_set(m->albumCover, EINA_TRUE);
1113         }
1114         elm_object_part_content_set(Layout(), MUSIC_PART_ALBUM_THUMB, m->albumCover);
1115
1116         if (t.depth == E_DEPTH_SHOW_LIST) {
1117                 elm_object_part_text_set(Layout(), MUSIC_PART_ALBUM_NAME,
1118                         category_info_get_name(t.c_catinfo));
1119         }
1120         else {
1121                 elm_object_part_text_set(Layout(),
1122                         MUSIC_PART_CATEGORY_NAME,
1123                         category_info_get_name(t.c_catinfo));
1124                 elm_object_part_text_set(Layout(), MUSIC_PART_ALBUM_NAME,
1125                         album_info_get_name(t.c_alinfo));
1126                 elm_object_part_text_set(Layout(), MUSIC_PART_ALBUM_ARTIST,
1127                         album_info_get_artist(t.c_alinfo));
1128         }
1129
1130         snprintf(buf, sizeof(buf), "%d %s",
1131                 m_ConvertToMin(m->total_duration), _("min"));
1132         elm_object_part_text_set(Layout(), MUSIC_PART_ALBUM_TIME, buf);
1133         snprintf(buf, sizeof(buf), "%d", eina_list_count(m->songlist));
1134         elm_object_part_text_set(Layout(), MUSIC_PART_ALBUM_SONGCOUNT, buf);
1135 }
1136
1137
1138 void CCategoryLayout::m_CreateSongList(void)
1139 {
1140         Evas_Object *genlist = NULL;
1141         Elm_Genlist_Item_Class *list_item = NULL;
1142         bool r;
1143         struct SSongInfo *sinfo = NULL;
1144         void *obj = NULL;
1145         Eina_List *l = NULL;
1146         struct SCatItemInfo *itinfo = NULL;
1147         Elm_Object_Item *item = NULL;
1148         int dur;
1149         void (*item_select_fn)(void *, Evas_Object *, void *) = NULL;
1150
1151         genlist = elm_genlist_add(Layout());
1152         if (!genlist)
1153                 return;
1154
1155         elm_genlist_homogeneous_set(genlist, EINA_TRUE);
1156
1157         evas_object_size_hint_weight_set(genlist,
1158                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1159         elm_object_part_content_set(Layout(), MUSIC_PART_SONGLIST, genlist);
1160
1161         Connect(genlist, CATEGORY_LAYOUT_GENLIST, TYPE_MOUSE_MOVE | TYPE_KEY_DOWN);
1162
1163         m->glist = genlist;
1164
1165         list_item = elm_genlist_item_class_new();
1166         if (!list_item) {
1167                 evas_object_del(genlist);
1168                 _ERR(" elm_genlist_item_class_new failed ");
1169                 return;
1170         }
1171         list_item->func.content_get = NULL;
1172         list_item->func.state_get = NULL;
1173         list_item->func.del = sm_CbRemoveListItem;
1174         m->count = 0;
1175
1176         if (t.depth == E_DEPTH_SELECT_LIST) {
1177                 list_item->func.text_get = sm_CbGetSelectlistItemText;
1178                 list_item->item_style = MUSIC_STYLE_SELECT_LIST;
1179                 item_select_fn = sm_CbSelectlistItemSelect;
1180                 if (t.sel_type == SELECT_REMOVE) {
1181                         r = m->pMusicController->MediaGetList(LIST_TYPE_PLAYLISTS_SONG, t.c_catinfo, &(m->songlist));
1182                 }
1183                 else {
1184                         r = m->pMusicController->MediaGetList(LIST_TYPE_SONG, NULL, &(m->songlist));
1185                 }
1186         }
1187         else {
1188                 list_item->func.text_get = sm_CbGetListItemText;
1189                 list_item->item_style = MUSIC_STYLE_ALBUM_SONGLIST;
1190                 item_select_fn = sm_CbSongItemSelect;
1191                 if (t.depth == E_DEPTH_SHOW_LIST)
1192                         r = m->pMusicController->MediaGetList(LIST_TYPE_PLAYLISTS_SONG, t.c_catinfo, &(m->songlist));
1193                 else
1194                         r = m->pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG, t.c_alinfo, &(m->songlist));
1195         }
1196
1197         if (r == false) {
1198                 _ERR(" Fetching song list from media failed ");
1199                 evas_object_del(genlist);
1200                 elm_genlist_item_class_free(list_item);
1201                 return;
1202         }
1203
1204         EINA_LIST_FOREACH(m->songlist, l, obj) {
1205                 sinfo = (SSongInfo *)obj;
1206                 itinfo = (SCatItemInfo *)calloc(1, sizeof(*itinfo));
1207                 if (!itinfo)
1208                         return;
1209
1210                 itinfo->sinfo = sinfo;
1211                 item = elm_genlist_item_append(genlist, list_item,
1212                         itinfo, NULL, ELM_GENLIST_ITEM_NONE,
1213                         item_select_fn, this);
1214                 itinfo->item = item;
1215                 m->it_infolist = eina_list_append(m->it_infolist, itinfo);
1216                 dur = 0;
1217                 song_info_get_duration(sinfo, &dur);
1218                 m->total_duration = m->total_duration + dur;
1219         }
1220         elm_genlist_item_class_free(list_item);
1221 }
1222
1223
1224 void CCategoryLayout::m_CreateAlbumgrid(void)
1225 {
1226         album_info *alinfo = NULL;
1227         void *obj = NULL;
1228         Eina_List *l = NULL;
1229         SCatItemInfo *itinfo = NULL;
1230         Elm_Object_Item *item = NULL;
1231         char buf[MAX_LENGTH];
1232         Elm_Gengrid_Item_Class *grid_item = NULL;
1233
1234         t.grid = m_AddGrid();
1235         if (!t.grid)
1236                 return;
1237
1238         grid_item = elm_gengrid_item_class_new();
1239         if (!grid_item) {
1240                 evas_object_del(t.grid);
1241                 _ERR(" elm_genlist_item_class_new failed ");
1242                 return;
1243         }
1244         grid_item->item_style = MUSIC_STYLE_CATEGORY_GRID;
1245         grid_item->func.text_get = sm_CbGetGridAlbumItemText;
1246         grid_item->func.content_get = sm_CbGetGridAlbumitemContent;
1247         grid_item->func.state_get = NULL;
1248         grid_item->func.del = sm_CbRemoveGridItem;
1249
1250         m->alblist = category_info_get_albumlist(t.c_catinfo);
1251         if (!m->alblist || eina_list_count(m->alblist) == 0) {
1252                 _ERR(" Fetching album list failed ");
1253                 evas_object_del(t.grid);
1254                 elm_gengrid_item_class_free(grid_item);
1255                 return;
1256         }
1257
1258         EINA_LIST_FOREACH(m->alblist, l, obj) {
1259                 alinfo = (album_info *)obj;
1260                 itinfo = (SCatItemInfo *)calloc(1, sizeof(*itinfo));
1261                 if (!itinfo)
1262                         return;
1263                 itinfo->alinfo = alinfo;
1264                 item = elm_gengrid_item_append(t.grid,
1265                         grid_item, itinfo, NULL, m);
1266                 itinfo->item = item;
1267                 m->it_infolist = eina_list_append(m->it_infolist,
1268                         itinfo);
1269         }
1270         elm_gengrid_item_class_free(grid_item);
1271
1272         elm_object_part_text_set(Layout(),
1273                 MUSIC_PART_CATEGORY_NAME,
1274                 category_info_get_name(t.c_catinfo));
1275         snprintf(buf, sizeof(buf), "%d",
1276                 category_info_get_albumcount(t.c_catinfo));
1277         elm_object_part_text_set(Layout(),
1278                 MUSIC_PART_CATEGORY_ALBUMCOUNT, buf);
1279         snprintf(buf, sizeof(buf), "%d",
1280                 category_info_get_songcount(t.c_catinfo));
1281         elm_object_part_text_set(Layout(),
1282                 MUSIC_PART_CATEGORY_SONGCOUNT, buf);
1283         elm_object_part_content_set(Layout(),
1284                 MUSIC_PART_CATEGORY_ALBUM_GRID, t.grid);
1285 }
1286
1287
1288 void CCategoryLayout::m_CreateCatgrid(bool sort_flag)
1289 {
1290         void *info = NULL;
1291         Eina_List *l = NULL;
1292         Elm_Gengrid_Item_Class *grid_item = NULL;
1293
1294         t.grid = m_AddGrid();
1295         if (!t.grid)
1296                 return;
1297
1298         grid_item = elm_gengrid_item_class_new();
1299         if (!grid_item) {
1300                 evas_object_del(t.grid);
1301                 _ERR(" elm_genlist_item_class_new failed ");
1302                 return;
1303         }
1304         grid_item->item_style = MUSIC_STYLE_CATEGORY_GRID;
1305         grid_item->func.text_get = sm_CbGetGridItemText;
1306         grid_item->func.content_get = sm_CbGetGridItemContent;
1307         grid_item->func.state_get = NULL;
1308         grid_item->func.del = sm_CbRemoveGridItem;
1309
1310         if (!sort_flag) {
1311                 if (!t_GetMediaList(&m->catlist)) {
1312                         if (t_CategoryType() != CAT_TYPE_PLAYLISTS)  {
1313                                 _ERR(" Fetching list  failed ");
1314                                 SetEmptyStatus(true);
1315                                 elm_gengrid_item_class_free(grid_item);
1316                                 return;
1317                         }
1318                 }
1319         }
1320         m_SortCatgrid();
1321
1322         if (t_CategoryType() == CAT_TYPE_PLAYLISTS)
1323                 m_AddCategoryItem(grid_item, CAT_TYPE_PLAYLIST_NEW, NULL);
1324
1325         EINA_LIST_FOREACH(m->catlist, l, info)
1326                 m_AddCategoryItem(grid_item, t_CategoryType(), info);
1327
1328         elm_gengrid_item_class_free(grid_item);
1329
1330         elm_object_part_content_set(Layout(),
1331                 MUSIC_PART_CATEGORY_GRID, t.grid);
1332 }
1333
1334
1335 void CCategoryLayout::m_SortCatgrid(void)
1336 {
1337         int(*_sort[])(const void *d1, const void *d2) = {
1338                 sortcategorys_az,
1339                 sortcategorys_za
1340         };
1341         int sort_type;
1342
1343         if (!m->catlist)
1344                 return;
1345
1346         sort_type = m->pMusicController->SortType();
1347         m->catlist = eina_list_sort(m->catlist, 0,
1348                 _sort[sort_type]);
1349 }
1350
1351
1352 void CCategoryLayout::m_EmptyLayout(bool sort_flag)
1353 {
1354         if (t.grid)
1355                 elm_gengrid_clear(t.grid);
1356
1357         if (m->glist)
1358                 elm_genlist_clear(m->glist);
1359
1360         if (!sort_flag) {
1361                 if (m->catlist) {
1362                         eina_list_free(m->catlist);
1363                         m->catlist = NULL;
1364                 }
1365         }
1366
1367         if (m->alblist) {
1368                 eina_list_free(m->alblist);
1369                 m->alblist = NULL;
1370         }
1371
1372         if (m->songlist) {
1373                 eina_list_free(m->songlist);
1374                 m->songlist = NULL;
1375         }
1376
1377         if (m->it_infolist) {
1378                 eina_list_free(m->it_infolist);
1379                 m->it_infolist = NULL;
1380         }
1381
1382         m->total_duration = 0;
1383
1384         int i;
1385
1386         for (i = 0; i < TOTAL_ADD_BTNS; i++) {
1387                 if (m->add_btn[i])
1388                         evas_object_del(m->add_btn[i]);
1389                 m->add_btn[i] = NULL;
1390         }
1391
1392         for (i = 0; i < TOTAL_SELECT_BTNS; i++) {
1393                 if (m->select_btn[i])
1394                         evas_object_del(m->select_btn[i]);
1395                 m->select_btn[i] = NULL;
1396         }
1397
1398         if (m->albumCover)
1399                 evas_object_del(m->albumCover);
1400         m->albumCover = NULL;
1401
1402         evas_object_hide(Layout());
1403         elm_object_part_content_unset(t.base, MUSIC_PART_CONTENT);
1404 }
1405
1406
1407
1408 bool CCategoryLayout::t_SetEdje(const char *szLayout)
1409 {
1410         ASSERT(szLayout);
1411         if (!elm_layout_file_set(Layout(), EDJEFILE, szLayout)) {
1412                 _ERR(" elm szLayout file set failed ");
1413                 return false;
1414         }
1415         return true;
1416 }
1417
1418
1419 void CCategoryLayout::t_UpdateLayout(bool sort_flag)
1420 {
1421         /* Remove existing grid and prepare afresh */
1422         m_EmptyLayout(sort_flag);
1423
1424         SParcel parcel;
1425         parcel.ctxtInfo = NULL;
1426
1427         if (t.depth == E_DEPTH_SONG) {
1428                 if (!t_SetEdje(MUSIC_CATEGORY_SONGS_LAYOUT)) {
1429                         _ERR(" get layout failed ");
1430                         return;
1431                 }
1432                 m_CreateSongList();
1433                 m_CreateSongsTopSection();
1434
1435                 parcel.updateType = E_LAYOUT_UPDATE;
1436                 parcel.layoutId = MUSIC_CATEGORY_SONGS_LAYOUT;
1437                 parcel.keyEvent = NULL;
1438                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1439         }
1440         else if (t.depth == E_DEPTH_SHOW_LIST) {
1441                 if (!t_SetEdje(MUSIC_ALBUM_SONGS_LAYOUT)) {
1442                         _ERR(" get layout failed ");
1443                         return;
1444                 }
1445                 m_CreateSongList();
1446                 m_CreateSongsTopSection();
1447
1448                 parcel.updateType = E_LAYOUT_UPDATE;
1449                 parcel.layoutId = MUSIC_CATEGORY_SONGS_LAYOUT;
1450                 parcel.keyEvent = NULL;
1451                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1452         }
1453         else if (t.depth == E_DEPTH_ALBUM) {
1454                 if (!t_SetEdje(MUSIC_CATEGORY_ALBUM_LAYOUT)) {
1455                         _ERR(" get layout failed ");
1456                         return;
1457                 }
1458                 m_AddButtons();
1459                 m_CreateAlbumgrid();
1460
1461                 parcel.updateType = E_LAYOUT_UPDATE;
1462                 parcel.layoutId = MUSIC_CATEGORY_ALBUM_LAYOUT;
1463                 parcel.keyEvent = NULL;
1464                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1465         }
1466         else if (t.depth == E_DEPTH_SELECT_LIST) {
1467                 if (!t_SetEdje(MUSIC_CATEGORY_SELECTLIST_LAYOUT)) {
1468                         _ERR(" get layout failed ");
1469                         return;
1470                 }
1471                 m_CreateSongList();
1472                 m_AddSelectlistButtons();
1473
1474                 parcel.updateType = E_LAYOUT_UPDATE;
1475                 parcel.layoutId = MUSIC_CATEGORY_SELECTLIST_LAYOUT;
1476                 parcel.keyEvent = NULL;
1477                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1478                 elm_object_focus_next_object_set(m->glist,
1479                         m->select_btn[SBTN_DONE], ELM_FOCUS_RIGHT);
1480         }
1481         else {
1482                 if (!t_SetEdje(MUSIC_CATEGORY_LAYOUT)) {
1483                         _ERR(" get layout failed ");
1484                         return;
1485                 }
1486                 m_CreateCatgrid(sort_flag);
1487
1488                 parcel.updateType = E_LAYOUT_UPDATE;
1489                 parcel.layoutId = MUSIC_CATEGORY_LAYOUT;
1490                 parcel.keyEvent = NULL;
1491                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1492         }
1493 }
1494
1495
1496 void CCategoryLayout::t_UpdateLayoutWithFocus(void)
1497 {
1498         elm_object_tree_focus_allow_set(t.base, EINA_FALSE);
1499         t_UpdateLayout(false);
1500         elm_object_part_content_set(t.base, MUSIC_PART_CONTENT, Layout());
1501         evas_object_show(Layout());
1502         m_RemoveFocusIdler();
1503         m->focus_idler = ecore_idler_add(sm_CbFocusIdler, this);
1504 }
1505
1506
1507 bool CCategoryLayout::Create(CLayoutMgr *mgr)
1508 {
1509         ASSERT(!m);
1510
1511         Evas_Object *base = NULL;
1512         Evas_Object *win = NULL;
1513         Evas_Object *layout = NULL;
1514         CMusicController *pMusicController = NULL;
1515         CViewMgr *vmgr = NULL;
1516
1517         if (!mgr)
1518                 return false;
1519
1520         m = new SCategoryLayout;
1521         if (!m) {
1522                 _ERR(" calloc failed ");
1523                 return false;
1524         }
1525
1526         vmgr = CViewMgr::GetInstance();
1527         if (!vmgr) {
1528                 _ERR(" get view mgr failed ");
1529                 delete m;
1530                 m = NULL;
1531                 return false;
1532         }
1533
1534         base = mgr->Base();
1535         if (!base) {
1536                 _ERR(" get base failed ");
1537                 delete m;
1538                 m = NULL;
1539                 return false;
1540         }
1541
1542         win = vmgr->Window();
1543         if (!win) {
1544                 _ERR(" vimewmgr get win failed ");
1545                 delete m;
1546                 m = NULL;
1547                 return false;
1548         }
1549
1550         pMusicController = CMusicController::GetInstance();
1551         if (!pMusicController) {
1552                 _ERR(" music controller get music instance failed ");
1553                 delete m;
1554                 m = NULL;
1555                 return false;
1556         }
1557
1558         layout = elm_layout_add(base);
1559         if (!layout) {
1560                 _ERR(" layout creation failed ");
1561                 delete m;
1562                 m = NULL;
1563                 return false;
1564         }
1565
1566         bool r = CExtBaseLayout::Create(layout);
1567         if (!r) {
1568                 _ERR(" CBaseLayout creation failed ");
1569                 evas_object_del(layout);
1570                 delete m;
1571                 m = NULL;
1572                 return false;
1573         }
1574
1575         t.epopup = new CEntryPopup;
1576         if (!t.epopup) {
1577                 _ERR(" CEntryPopup creation failed ");
1578                 CExtBaseLayout::Destroy();
1579                 evas_object_del(layout);
1580                 delete m;
1581                 m = NULL;
1582                 return false;
1583         }
1584
1585         m->win = win;
1586         t.base = base;
1587         m->vmgr = vmgr;
1588         m->pMusicController = pMusicController;
1589         m->lmgr = mgr;
1590         t.depth = E_DEPTH_CATEGORY;
1591
1592         t_UpdateLayout(false);
1593
1594         Connect(Layout(), CATEGORY_LAYOUT, TYPE_KEY_DOWN);
1595
1596         return true;
1597 }
1598
1599
1600 void CCategoryLayout::Destroy(void)
1601 {
1602         ASSERT(m);
1603
1604         Disconnect(Layout());
1605         if (t.epopup->FlagCreate())
1606                 t.epopup->Destroy();
1607
1608         m_RemoveFocusIdler();
1609         m_EmptyLayout(false);
1610         category_info_destroy(t.c_catinfo);
1611         album_info_destroy(t.c_alinfo);
1612         song_info_destroy(m->c_sinfo);
1613         delete t.epopup;
1614         CExtBaseLayout::Destroy();
1615         evas_object_del(Layout());
1616
1617         delete m;
1618         m = NULL;
1619 }
1620
1621
1622 void CCategoryLayout::t_OnShow(void)
1623 {;
1624         ASSERT(m);
1625
1626         t.depth = E_DEPTH_CATEGORY;
1627         t_UpdateLayout(false);
1628         elm_object_part_content_set(t.base, MUSIC_PART_CONTENT, Layout());
1629         evas_object_show(Layout());
1630 }
1631
1632
1633 void CCategoryLayout::Update(bool focusFlag)
1634 {
1635         ASSERT(m);
1636
1637         if (!focusFlag) {
1638                 if (t.depth != E_DEPTH_CATEGORY)
1639                         return;
1640                 t_UpdateLayout(true);
1641                 elm_object_part_content_set(t.base, MUSIC_PART_CONTENT, Layout());
1642                 evas_object_show(Layout());
1643                 return;
1644         }
1645
1646         elm_object_focus_set(t.grid, EINA_TRUE);
1647 }
1648
1649
1650 void CCategoryLayout::OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev)
1651 {
1652         switch (id) {
1653         case CATEGORY_LAYOUT:
1654                 {
1655                         int count;
1656                         Eina_List *alist = NULL;
1657
1658                         if (!strcmp(ev->keyname, KEY_BACK)) {
1659                                 if (t.depth == E_DEPTH_CATEGORY) {
1660                                         SParcel parcel;
1661                                         parcel.ctxtInfo = NULL;
1662                                         parcel.updateType = E_FOCUS_UPDATE;
1663                                         parcel.layoutId = NULL;
1664                                         parcel.keyEvent = NULL;
1665                                         m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1666                                         return;
1667                                 }
1668                                 else if (t.depth == E_DEPTH_ALBUM) {
1669                                         t.depth = E_DEPTH_CATEGORY;
1670                                 }
1671                                 else if (t.depth == E_DEPTH_SELECT_LIST) {
1672                                         t.depth = E_DEPTH_CATEGORY;
1673                                 }
1674                                 else if (t.depth == E_DEPTH_SHOW_LIST) {
1675                                         t.depth = E_DEPTH_CATEGORY;
1676                                 }
1677                                 else if (t.depth == E_DEPTH_SONG) {
1678                                         count = 0;
1679                                         alist = category_info_get_albumlist(t.c_catinfo);
1680                                         if (alist)
1681                                                 count = eina_list_count(alist);
1682                                         if (count == 1)
1683                                                 t.depth = E_DEPTH_CATEGORY;
1684                                         else
1685                                                 t.depth = E_DEPTH_ALBUM;
1686                                 }
1687
1688                                 t_UpdateLayoutWithFocus();
1689                         }
1690                 }
1691                 break;
1692
1693         case CATEGORY_LAYOUT_GENGRID:
1694         case CATEGORY_LAYOUT_GENLIST:
1695                 {
1696                         Elm_Object_Item *it = NULL;
1697                         SContentInfo *ctxtinfo = NULL;
1698                         SCatItemInfo *itinfo = NULL;
1699
1700                         if (!obj)
1701                                 return;
1702
1703                         if (strcmp(ev->keyname, KEY_MENU) || t.depth ==
1704                                 E_DEPTH_SELECT_LIST || t.depth ==
1705                                 E_DEPTH_SHOW_LIST)
1706                                 return;
1707
1708                         it = elm_object_focused_item_get(obj);
1709                         if (!it) {
1710                                 _ERR(" unable to get focused item ");
1711                                 return;
1712                         }
1713                         t.focused_item = it;
1714
1715                         if (t.ctxtinfo) {
1716                                 free(t.ctxtinfo);
1717                                 t.ctxtinfo = NULL;
1718                         }
1719
1720                         ctxtinfo = (SContentInfo *)calloc(1, sizeof(*ctxtinfo));
1721                         if (!ctxtinfo)
1722                                 return;
1723
1724                         itinfo = m_FindItemInfo(m->it_infolist, it);
1725                         if (!itinfo || itinfo->type == CAT_TYPE_PLAYLIST_NEW) {
1726                                 free(ctxtinfo);
1727                                 return;
1728                         }
1729
1730                         ctxtinfo->cbdata = this;
1731                         ctxtinfo->update = sm_CbCtxtUpdate;
1732                         ctxtinfo->close = sm_CbCtxtClose;
1733                         if (t.depth == E_DEPTH_SONG) {
1734                                 ctxtinfo->type = CONTEXT_TYPE_SONG;
1735                                 ctxtinfo->context = itinfo->sinfo;
1736                         }
1737                         else if (t.depth == E_DEPTH_ALBUM) {
1738                                 ctxtinfo->type = CONTEXT_TYPE_ALBUM;
1739                                 ctxtinfo->context = itinfo->alinfo;
1740                         }
1741                         else {
1742                                 ctxtinfo->type = t_ContextType();
1743                                 ctxtinfo->context = itinfo->catinfo;
1744                         }
1745
1746                         t.ctxtinfo = ctxtinfo;
1747
1748                         SParcel parcel;
1749                         parcel.ctxtInfo = ctxtinfo;
1750                         if (!m->vmgr->PushView(MUSIC_CONTEXT_VIEW, &parcel))
1751                                 _ERR("viewmgr push view MUSIC_CONTEXT_VIEW failed");
1752                 }
1753                 break;
1754
1755         default:
1756                 break;
1757         }
1758 }
1759
1760
1761 void CCategoryLayout::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
1762 {
1763         switch (id) {
1764         case CATEGORY_LAYOUT_GENGRID:
1765                 {
1766                         Elm_Object_Item *item;
1767
1768                         if (!obj)
1769                                 return;
1770
1771                         item = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
1772                                 ev->cur.canvas.y, NULL, NULL);
1773                         if (!item)
1774                                 return;
1775
1776                         if (!elm_object_item_focus_get(item))
1777                                 elm_object_item_focus_set(item, EINA_TRUE);
1778                 }
1779                 break;
1780
1781         case CATEGORY_LAYOUT_GENLIST:
1782                 {
1783                         Elm_Object_Item *item;
1784
1785                         if (!obj)
1786                                 return;
1787
1788                         item = elm_genlist_at_xy_item_get(obj, ev->cur.canvas.x,
1789                                 ev->cur.canvas.y, NULL);
1790
1791                         if (!elm_object_item_focus_get(item))
1792                                 elm_object_item_focus_set(item, EINA_TRUE);
1793                 }
1794                 break;
1795
1796         case CATEGORY_LAYOUT_PLAY_BUTTON:
1797         case CATEGORY_LAYOUT_NEXT_BUTTON:
1798         case CATEGORY_LAYOUT_LAST_BUTTON:
1799         case CATEGORY_LAYOUT_SELECT_ALL_BUTTON:
1800         case CATEGORY_LAYOUT_DONE_BUTTON:
1801         case CATEGORY_LAYOUT_CANCEL_BUTTON:
1802                 if (!elm_object_focus_get(obj))
1803                         elm_object_focus_set(obj, EINA_TRUE);
1804                 break;
1805
1806         default:
1807                 break;
1808         }
1809 }
1810
1811
1812 void CCategoryLayout::OnMouseClicked(int id, Evas_Object *obj)
1813 {
1814         switch (id) {
1815         case CATEGORY_LAYOUT_PLAY_BUTTON:
1816                 m_GotoPlayback(ADD_TYPE_FRESH, NULL);
1817                 break;
1818
1819         case CATEGORY_LAYOUT_NEXT_BUTTON:
1820                 m_GotoPlayback(ADD_TYPE_NEXT, NULL);
1821                 break;
1822
1823         case CATEGORY_LAYOUT_LAST_BUTTON:
1824                 m_GotoPlayback(ADD_TYPE_END, NULL);
1825                 break;
1826
1827         case CATEGORY_LAYOUT_SELECT_ALL_BUTTON:
1828                 {
1829                         Eina_List *l = NULL;
1830                         SCatItemInfo *itinfo = NULL;
1831                         void *list_obj = NULL;
1832                         int tc;
1833
1834                         tc = eina_list_count(m->it_infolist);
1835
1836                         if (m->count == tc) {
1837                                 elm_object_text_set(m->select_btn[SBTN_SELECT_ALL],
1838                                         _(MUSIC_TEXT_SELECT_ALL));
1839                                 m->count = 0;
1840                                 EINA_LIST_FOREACH(m->it_infolist, l, list_obj) {
1841                                         itinfo = (SCatItemInfo *)list_obj;
1842                                         itinfo->check_status = false;
1843                                 }
1844                                 elm_genlist_realized_items_update(m->glist);
1845
1846                                 return;
1847                         }
1848
1849                         elm_object_text_set(m->select_btn[SBTN_SELECT_ALL],
1850                                 _(MUSIC_TEXT_DESELECT_ALL));
1851                         m->count = tc;
1852                         EINA_LIST_FOREACH(m->it_infolist, l, list_obj) {
1853                                 itinfo = (SCatItemInfo *)list_obj;
1854                                 itinfo->check_status = true;
1855                         }
1856                         elm_genlist_realized_items_update(m->glist);
1857                 }
1858                 break;
1859
1860         case CATEGORY_LAYOUT_DONE_BUTTON:
1861                 {
1862                         if (t.sel_type == SELECT_ADD) {
1863                                 m_AddSelectedSongs();
1864                                 return;
1865                         }
1866                         else if (t.sel_type == SELECT_REMOVE) {
1867                                 m_RemoveSelectedSongs();
1868                                 return;
1869                         }
1870
1871                         if (t.epopup->FlagCreate())
1872                                 t.epopup->Destroy();
1873
1874                         t.epopup->Create(t.base, MUSIC_STR_EMPTY, sm_CbEntrynameSet, this);
1875                 }
1876                 break;
1877
1878         case CATEGORY_LAYOUT_CANCEL_BUTTON:
1879                 {
1880                         t.depth = E_DEPTH_CATEGORY;
1881                         t_UpdateLayoutWithFocus();
1882                 }
1883                 break;
1884
1885         default:
1886                 break;
1887         }
1888 }
1889
1890
1891 void CCategoryLayout::OnRealized(int id, Evas_Object *obj, Elm_Object_Item *item)
1892 {
1893         switch (id) {
1894         case CATEGORY_LAYOUT_GENGRID:
1895                 elm_object_item_signal_callback_add(item,
1896                         MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
1897                         sm_CbItemSelect, this);
1898                 break;
1899
1900         default:
1901                 break;
1902         }
1903 }
1904
1905
1906 void CCategoryLayout::OnUnrealized(int id, Evas_Object *obj, Elm_Object_Item *item)
1907 {
1908         switch (id) {
1909         case CATEGORY_LAYOUT_GENGRID:
1910                 elm_object_item_signal_callback_del(item,
1911                         MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
1912                         sm_CbItemSelect);
1913                 break;
1914
1915         default:
1916                 break;
1917         }
1918 }