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