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