Fix UI issue / Launch issue / Mediadata issue
[profile/tv/apps/native/filebrowser.git] / src / views / BaseView / FileGrid.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 <Ecore.h>
20 #include <aul.h>
21 #include "dbg.h"
22 #include "i18n.h"
23 #include "define.h" 
24 #include "common.h"
25
26 #include <AppCommon.h>
27 #include "Mediadata.h"
28 #include "ExtNameInfo.h"
29 #include <Sort.h>
30 #include <SortMgr.h>
31 #include "GengridItemClass.h"
32 #include "InputHandler.h"
33 #include "FileGrid.h"
34 #include "Info.h"
35 #include <BaseView.h>
36 #include <InputHandler.h>
37 #include <ViewMgr.h>
38 #include "FbContextView.h"
39
40
41 #define GENGRID_ITEM_SIZE_W (263 + 20)
42 #define GENGRID_ITEM_SIZE_H (359 + 20)
43
44
45 static Elm_Object_Item *_find_item_by_id(Eina_List *list, char *fid)
46 {
47         Eina_List *l;
48         SItemInfo *pItemInfo;
49         void* obj;
50         char *id;
51
52         EINA_LIST_FOREACH(list, l, obj) {
53                 pItemInfo = (SItemInfo *)obj;
54                 id = pItemInfo->pInfo->Id();
55                 if (id && !strcmp(id, fid))
56                         return pItemInfo->item;
57         }
58
59         return NULL;
60 }
61
62 static SItemInfo *_find_item_info(Eina_List *list, Elm_Object_Item *item)
63 {
64         Eina_List *l;
65         SItemInfo *pItemInfo;
66         void* obj;
67
68         EINA_LIST_FOREACH(list, l, obj) {
69                 pItemInfo = (SItemInfo*)obj;
70                 if (pItemInfo->item == item)
71                         return pItemInfo;
72         }
73
74         return NULL;
75 }
76
77
78 struct SFileGrid {
79         CMediadata *pMediadata;
80
81         Evas_Object *eoWin;
82         Evas_Object *eoBase;
83         Evas_Object *eoGrid;
84
85         Eina_List   *elFile;
86         Eina_List   *elItemInfo;
87
88         CFileGrid::SCallback callback;
89
90         int depth;
91         SItemInfo *ctxt_itinfo;
92         SItemInfo *handle_itinfo;
93
94         char *fid;
95
96         CGengridItemClass *pGengridItemClass;
97
98         SFileGrid() {
99                 memset(this, 0, sizeof(SFileGrid));
100         }
101 };
102
103
104 void CFileGrid::sm_CbRealized(void *data, Evas_Object *obj, void *event_info)
105 {
106         _DBG();
107         if (!data || !obj || !event_info)
108                 return;
109
110         elm_object_item_signal_callback_add((Elm_Object_Item*)event_info,
111                 FBR_SIGNAL_BTN_CLICKED, FBR_BASE_VIEW,
112                 sm_CbSelectItem, data);
113 }
114
115 void CFileGrid::sm_CbUnrealized(void *data, Evas_Object *obj, void *event_info)
116 {
117         _DBG();
118         if (!data || !obj || !event_info)
119                 return;
120
121         elm_object_item_signal_callback_del((Elm_Object_Item*)event_info,
122                 FBR_SIGNAL_BTN_CLICKED, FBR_BASE_VIEW,
123                 sm_CbSelectItem);
124 }
125
126 void CFileGrid::Action(void)
127 {
128         _DBG();
129         m->handle_itinfo = m->ctxt_itinfo;
130         m_HandleSelection();
131         m_DeleteContextView();
132 }
133
134 void CFileGrid::m_DeleteContextView(void)
135 {
136         if(CViewMgr::GetInstance()->CheckTop(FBR_CONTEXT_VIEW))
137                 CViewMgr::GetInstance()->PopView();
138 }
139
140 void CFileGrid::sm_CbSelectItem(void *data, Elm_Object_Item *it, const char *emission, const char *source)
141 {
142         _DBG();
143         CFileGrid* root = (CFileGrid*)data;
144         SItemInfo *pItemInfo;
145
146         if (!data || !it)
147                 return;
148
149         pItemInfo = _find_item_info(root->m->elItemInfo, it);
150         if (!pItemInfo) {
151                 _ERR(" no item info found ");
152                 return;
153         }
154
155         root->m->handle_itinfo = pItemInfo;
156         root->m_HandleSelection();
157 }
158
159 void CFileGrid::m_HandleSelection(void)
160 {
161         char *path;
162         int type;
163         char *id;
164         SItemInfo *pItemInfo = m->handle_itinfo;
165
166         if (!pItemInfo)
167                 return;
168
169         type = pItemInfo->pInfo->Type();
170         if (type == E_GRP_FOLDER) {
171                 if (m->fid) {
172                         free(m->fid);
173                         m->fid = NULL;
174                 }
175                 id = pItemInfo->pInfo->Id();
176                 if (!id)
177                         return;
178
179                 m->fid = strdup(id);
180                 if (!m->fid)
181                         return;
182
183                 elm_object_tree_focus_allow_set(m->eoBase, EINA_FALSE);
184                 t_Update(m->fid, false);//_update_filegrid(m, m->fid, false);
185                 elm_object_tree_focus_allow_set(m->eoBase, EINA_TRUE);
186                 elm_object_focus_set(m->eoGrid, EINA_TRUE);
187         }
188         else {
189                 path = pItemInfo->pInfo->Path();
190                 if (!path)
191                         return;
192
193                 if (m->callback.cbLinkApp)
194                         m->callback.cbLinkApp(m->callback.cookie, type, CInfo::SourceType(), path);
195                 elm_gengrid_item_selected_set(pItemInfo->item, EINA_FALSE);
196         }
197 }
198
199 void CFileGrid::m_GetMediaList(char *fid)
200 {
201         bool ret;
202         ret = m->pMediadata->GetMediaList(fid, CInfo::GroupIndex(), CInfo::SourceType(), &m->elFile);
203         if (ret == false) {
204                 _ERR(" Fetching all list from file failed ");
205                 return;
206         }
207 }
208
209 void CFileGrid::m_GetFolderList(void)
210 {
211         bool ret;
212         ret = m->pMediadata->GetFolderList(CInfo::GroupIndex(), CInfo::SourceType(), &m->elFile);
213         if (ret == false) {
214                 _ERR(" Fetching all list from file failed ");
215                 return;
216         }
217 }
218
219 void CFileGrid::t_CreateFileGrid(void)
220 {
221         Evas_Object *grid;
222         
223         grid = elm_gengrid_add(m->eoBase);
224         if (!grid)
225                 return;
226         evas_object_size_hint_weight_set(grid,
227                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
228         elm_gengrid_align_set(grid, 0, 0);
229         elm_object_part_content_set(m->eoBase, FBR_PART_MEDIA_GRID, grid);
230
231
232         Connect(grid);
233
234         evas_object_smart_callback_add(grid, FBR_SIGNAL_REALIZED,      sm_CbRealized, this);
235         evas_object_smart_callback_add(grid, FBR_SIGNAL_UNREALIZED,    sm_CbUnrealized, this);
236         elm_gengrid_item_size_set(grid,
237                 elm_config_scale_get() * GENGRID_ITEM_SIZE_W,
238                 elm_config_scale_get() * GENGRID_ITEM_SIZE_H);
239
240         m->eoGrid = grid;
241
242         m->pGengridItemClass = new CGengridItemClass;
243         if (!m->pGengridItemClass->Create()) {
244                 delete m->pGengridItemClass;
245                 m->pGengridItemClass = NULL;
246                 evas_object_del(grid);
247                 _ERR(" elm_genlist_item_class_new failed ");
248                 return;
249         }
250         
251         evas_object_show(grid);
252 }
253
254
255 void CFileGrid::t_Empty(bool sort_flag)
256 {
257         if (m->eoGrid) {
258                 elm_gengrid_clear(m->eoGrid);
259                 evas_object_del(m->eoGrid);
260                 m->eoGrid = NULL;
261         }
262
263         if (m->pGengridItemClass)
264         {
265                 m->pGengridItemClass->Destroy();
266                 delete m->pGengridItemClass;
267                 m->pGengridItemClass = NULL;
268         }
269
270         if (sort_flag == false) {
271                 eina_list_free(m->elFile);
272                 m->elFile = NULL;
273         }
274
275         m->elItemInfo = NULL;
276         if (m->callback.cbUpdateEmptyFocusSequence)
277                 m->callback.cbUpdateEmptyFocusSequence(m->callback.cookie);
278 }
279
280
281 void CFileGrid::t_Update(char *fid, bool sort_flag)
282 {
283         _DBG("fid: %s, sort_flag: %d", fid, sort_flag);
284         t_Empty(sort_flag);
285         t_CreateFileGrid();
286
287         if (sort_flag == false) {
288                 if (fid)
289                         m_GetMediaList(fid);
290                 else
291                         m_GetFolderList();
292         }
293         
294         const char* sortType;
295         switch(CInfo::SortType())
296         {
297                 case 0:
298                         sortType = SORT_BY_NAME_AZ;
299                         break;
300                 case 1:
301                         sortType = SORT_BY_NAME_ZA;
302                         break;
303                 case 2:
304                         sortType = SORT_BY_DATE_ASC;
305                         break;
306                 case 3:
307                         sortType = SORT_BY_DATE_DES;
308                         break;
309                 case 4:
310                         sortType = SORT_BY_SIZE_ASC;
311                         break;
312                 case 5:
313                         sortType = SORT_BY_SIZE_DES;
314                         break;
315                 default:
316                         _DBG("Fix your code : sortType is invalid");
317                         sortType = SORT_BY_NAME_AZ;
318                         break;
319         }
320
321         //ASSERT(m->elFile);
322
323         m->elFile = CSort::Sort(m->elFile, sortType);
324         t_Fill();
325
326         if (fid)    // folder
327                 m->depth = 1;
328         else
329                 m->depth = 0;
330 }
331
332
333 void CFileGrid::t_Fill(void)
334 {
335         CExtNameInfo *pInfo;
336         Eina_List *l;
337         SItemInfo *pItemInfo;
338         void* obj;
339         int ts;
340
341         _DBG("grid: %x, flist: %x", m->eoGrid, m->elFile);
342         if (!m->eoGrid || !m->elFile)
343                 return;
344
345         ts = eina_list_count(m->elFile);
346         _DBG("count: %d", ts);
347         if (ts == 0) {
348                 t_Empty(false);
349                 return;
350         }
351
352         EINA_LIST_FOREACH(m->elFile, l, obj) {
353                 pInfo = (CExtNameInfo*)obj;
354                 pItemInfo = (SItemInfo *)calloc(1, sizeof(SItemInfo));
355                 if (!pItemInfo) {
356                         t_Empty(false);
357                         return;
358                 }
359
360                 pItemInfo->pInfo = pInfo;
361                 pItemInfo->item = elm_gengrid_item_append(m->eoGrid, m->pGengridItemClass->Handle(), pItemInfo, NULL, m);
362                 m->elItemInfo = eina_list_append(m->elItemInfo, pItemInfo);
363         }
364
365         if (m->callback.cbUpdatedGrid)
366                 m->callback.cbUpdatedGrid(m->callback.cookie);
367 }
368
369
370 bool CFileGrid::Create(Evas_Object* win, Evas_Object *base, const SCallback *cb)
371 {
372         ASSERT(!m);
373         ASSERT(cb);
374
375         _CREATE_BEGIN{
376                 _CHECK(m = new SFileGrid)
377                 _CHECK(m->pMediadata = new CMediadata )
378                 _CHECK(m->pMediadata->Create())
379
380                 _WHEN_SUCCESS{}
381
382                 _CHECK_FAIL{ m->pMediadata->Destroy(); }
383                 _CHECK_FAIL{ delete m->pMediadata; }
384                 _CHECK_FAIL{ delete m; m = NULL; }
385         } _CREATE_END_AND_CATCH{ return false; }
386
387         m->eoWin    = win;
388         m->eoBase   = base;
389         m->callback = *cb;
390
391         return true;
392 }
393
394
395 void CFileGrid::Destroy(void)
396 {
397         ASSERT(m);
398
399         t_Empty(false);
400
401         m_DeleteContextView();
402
403         free(m->fid);
404
405         m->pMediadata->Destroy();
406         delete m->pMediadata;
407         delete m;
408         m = NULL;
409 }
410
411
412 void CFileGrid::Update(bool sort_flag)
413 {
414         ASSERT(m);
415
416         char* fid = NULL;
417         if (sort_flag == true) {
418                 fid = m->fid;
419         }
420         t_Update(fid, sort_flag);
421 }
422
423
424 void CFileGrid::SetFocus(Eina_Bool flag)
425 {
426         ASSERT(m);
427
428         elm_object_focus_set(m->eoGrid, flag);
429 }
430
431
432 Evas_Object* CFileGrid::Grid(void)
433 {
434         ASSERT(m);
435
436         return m->eoGrid;
437 }
438
439
440 void CFileGrid::OnKeyUp(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Up *ev) {
441         Elm_Object_Item *it;
442         SItemInfo *pItemInfo;
443         
444         if(ev->keyname)
445                 _DBG("%s", ev->keyname);
446
447         if (strcmp(ev->keyname, KEY_BACK) == 0) {
448                 if (m->depth == 0) {
449                         if (m->callback.cbUnsetFocus)
450                                 m->callback.cbUnsetFocus(m->callback.cookie);
451                 }
452                 else {
453                         t_Update(NULL, false);
454                         it = _find_item_by_id(m->elItemInfo, m->fid);
455                         elm_gengrid_item_show(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
456                         elm_object_item_focus_set(it, EINA_TRUE);
457                 }
458         }
459         else if (strcmp(ev->keyname, KEY_MENU) == 0) {
460                 it = elm_object_focused_item_get(obj);
461                 if (!it) {
462                         _ERR(" unable to get focused item ");
463                         return;
464                 }
465                 pItemInfo = _find_item_info(m->elItemInfo, it);
466                 if (!pItemInfo)
467                         return;
468
469                 m->ctxt_itinfo = pItemInfo;
470
471                 CViewMgr::GetInstance()->PushView(FBR_CONTEXT_VIEW, pItemInfo->pInfo);
472         }
473 }
474
475
476 void CFileGrid::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev) {
477         _DBG();
478         Elm_Object_Item *item;
479
480         if (!obj)
481                 return;
482
483         item = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
484                 ev->cur.canvas.y, NULL, NULL);
485         if (!item)
486                 return;
487
488         elm_object_item_focus_set(item, EINA_TRUE);
489 }