Base code / protex done / 64bit build check done
[profile/tv/apps/native/filebrowser.git] / src / views / BaseView / FbBaseView.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 <utilX.h>
21 #include <aul.h>
22 #include "i18n.h"
23 #include "define.h"
24
25 #include "AppCommon.h"
26 #include "ExtNameInfo.h"
27 #include "common.h"
28 #include "dbg.h"
29 #include "ManagerUsb.h"
30 #include "SortName.h"
31 #include "Popup.h"
32 #include "InputHandler.h"
33
34 #include <CtxPopup.h>
35
36 #include <BaseView.h>
37 #include "FbBaseView.h"
38 #include "Info.h"
39
40 #include "SourceCtxPopup.h"
41 #include "SortCtxPopup.h"
42
43 #include <ViewMgr.h>
44 #include <LayoutMgr.h>
45 #include <BaseLayout.h>
46 #include "FbBaseLayout.h"
47
48 #define TOTAL_GROUP_BTNS        4
49 #define TOTAL_TOP_BTNS          2
50 #define TOTAL_UPDATE_CALLBACKS  2
51 #define PARAM_URI               "uri"
52 #define PARAM_SOURCE            "source"
53
54 struct _btn_info {
55         const char *txt;
56         const char *part;
57         const char *style;
58         const char *icon_path;
59 };
60
61 enum topbtns {
62         TOPBTN_SOURCE,
63         TOPBTN_SORT,
64 };
65
66 const char *source_arg[] = {
67         "all",
68         "tv",
69         "pUsb"
70 };
71
72 const char *linked_app[] = {
73         N_(""),
74         N_("org.tizen.gallery-tv-ref"),
75         N_("org.tizen.video-player-tv-ref"),
76         N_("org.tizen.music-player-tv-ref"),
77         N_(""),
78 };
79
80 struct SFbBaseView {
81         Evas_Object *eoWin;
82         Evas_Object *eoBase;
83         Evas_Object *eoBtnGroup[TOTAL_GROUP_BTNS];
84         Evas_Object *eoSelectedBtnGroup;//Evas_Object *c_grpbtn;
85         Evas_Object *eoBtnSource;
86         Evas_Object *eoBtnSort;
87
88         CCtxPopup   *pCtxPopup;
89
90         CPopup      *pPopup;
91
92         CLayoutMgr    *pLayoutMgr;
93         CFbBaseLayout *pFbBaseLayout;
94
95         SFbBaseView() {
96                 int a;
97
98                 memset(eoBtnGroup, 0, sizeof(eoBtnGroup));
99                 pHandlerBase = new CHandlerBase(this);
100                 for (a = 0; a < TOTAL_TOP_BTNS; a++)
101                         pHandlerButton[a] = new CHandlerButton(this);
102                 for (a = 0; a < TOTAL_GROUP_BTNS; a++){
103                         pHandlerGroup[a] = new CHandlerGroup(this);
104                 }
105         }
106         virtual ~SFbBaseView() {
107                 int a;
108
109                 delete pHandlerBase;
110                 for (a = 0; a < TOTAL_TOP_BTNS; a++)
111                         delete pHandlerButton[a];
112                 for (a = 0; a < TOTAL_GROUP_BTNS; a++)
113                         delete pHandlerGroup[a];
114         }
115         
116         class CHandlerBase : public CListenerMgr, public IKeyDownListener {
117                 SFbBaseView *m;
118
119         public:
120                 CHandlerBase(SFbBaseView *ins) : IKeyDownListener(this) { m = ins; }
121
122                 virtual void OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev) {
123                         if (!strcmp(ev->keyname, KEY_EXIT))
124                                 elm_exit();
125                         else if (!strcmp(ev->keyname, KEY_ENTER)) {
126                                 if (elm_object_focus_get(m->eoSelectedBtnGroup)) {
127                                         m->pFbBaseLayout->SetFocus(EINA_TRUE);
128                                 }
129                         }
130                 }
131         } *pHandlerBase;
132
133         class CHandlerButton : public CListenerMgr, protected IKeyDownListener, IMouseMoveListener, IMouseClickedListener {
134         private:
135                 SFbBaseView *m;
136         private:
137                 static void sm_CbCtxPopupSelected(void* cookie, CCtxPopup* instance, const char* text)
138                 {
139                         SFbBaseView* m = (SFbBaseView*)cookie;
140                         if (!m)
141                                 return;
142
143                         _DBG(" instance->Type(): %d", instance->Type());
144                         switch (instance->Type()) {
145                         case CCtxPopup::TOPBTN_SORT:
146                                 elm_object_text_set(m->eoBtnSort, text);
147                                 m->pFbBaseLayout->Update(true);
148                                 break;
149
150                         case CCtxPopup::TOPBTN_SOURCE:
151                                 elm_object_text_set(m->eoBtnSource, text);
152                                 m->pFbBaseLayout->Update(false);
153                                 break;
154
155                         default:
156                                 break;
157                         }
158                 }
159
160         public:
161                 CHandlerButton(SFbBaseView *ins) : IKeyDownListener(this), IMouseMoveListener(this), IMouseClickedListener(this) { m = ins; }
162
163                 virtual void OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev) {
164                         if (!strcmp(ev->keyname, KEY_BACK))
165                                 elm_object_focus_set(m->eoSelectedBtnGroup, EINA_TRUE);
166                 }
167                 virtual void OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev) {
168                         if (!elm_object_focus_get(obj))
169                                 elm_object_focus_set(obj, EINA_TRUE);
170                 }
171                 virtual void OnMouseClicked(int id, Evas_Object *obj) {
172                         CSourceCtxPopup::SCallback cb;
173                         cb.cookie = m;
174                         cb.onSelected = sm_CbCtxPopupSelected;
175
176                         if (obj == m->eoBtnSource) {
177                                 CSourceCtxPopup* pCtxPopup = new CSourceCtxPopup;
178                                 m->pCtxPopup = pCtxPopup;
179                                 pCtxPopup->Create(m->eoBase, &cb);
180                         }
181                         else if (obj == m->eoBtnSort) {
182                                 CSortCtxPopup* pCtxPopup = new CSortCtxPopup;
183                                 m->pCtxPopup = pCtxPopup;
184                                 pCtxPopup->Create(m->eoBase, &cb);
185                         }
186                 }
187         } *pHandlerButton[TOTAL_TOP_BTNS];
188
189         class CHandlerGroup : public CListenerMgr, IMouseMoveListener, IKeyDownListener, IMouseClickedListener {
190         private:
191                 SFbBaseView *m;
192         public:
193                 CHandlerGroup(SFbBaseView *ins) :
194                         IMouseMoveListener(this),
195                         IKeyDownListener(this),
196                         IMouseClickedListener(this) { m = ins; }
197
198                 virtual void OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev) {
199                         if (!elm_object_focus_get(obj))
200                                 elm_object_focus_set(obj, EINA_TRUE);
201                 }
202                 virtual void OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev) {
203                         if (!strcmp(ev->keyname, KEY_BACK))
204                                 elm_exit();
205                 }
206                 virtual void OnMouseClicked(int id, Evas_Object *obj) {
207                         if (m->eoSelectedBtnGroup == obj)
208                                 return;
209
210                         elm_object_signal_emit(m->eoSelectedBtnGroup, FBR_SIGNAL_GROUP_UNSELECTED, "");
211                         m->eoSelectedBtnGroup = obj;
212                         elm_object_signal_emit(m->eoSelectedBtnGroup, FBR_SIGNAL_GROUP_SELECTED, "");
213
214                         m->pFbBaseLayout->Update(false);
215                 }
216         } *pHandlerGroup[TOTAL_GROUP_BTNS];
217 };
218
219
220
221 Evas_Object *_add_button(Evas_Object *box)
222 {
223         Evas_Object *button;
224
225         if (!box)
226                 return NULL;
227
228         button = elm_button_add(box);
229         if (!button)
230                 return NULL;
231
232         evas_object_size_hint_weight_set(button,
233                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
234         evas_object_show(button);
235
236         return button;
237 }
238
239 void CFbBaseView::UpdateEmptyFocusSequence(void)
240 {
241         int i;
242         _DBG("");
243
244         for (i = 0; i < TOTAL_GROUP_BTNS; i++)
245                 elm_object_focus_next_object_set(m->eoBtnGroup[i], m->eoBtnSort, ELM_FOCUS_RIGHT);
246
247         elm_object_focus_next_object_set(m->eoBtnGroup[E_GRP_ALL], m->eoBtnSort,              ELM_FOCUS_UP);
248         elm_object_focus_next_object_set(m->eoBtnSort,              m->eoBtnGroup[E_GRP_ALL], ELM_FOCUS_DOWN);
249         elm_object_focus_next_object_set(m->eoBtnSource,               m->eoBtnGroup[E_GRP_ALL], ELM_FOCUS_DOWN);
250
251         if (t_SelectedGroupButton() == m->eoBtnGroup[E_GRP_ALL]) {
252                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT,     _(NO_FILE_MESSAGE));
253                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT_SUB, _(NO_FILE_MESSAGE_SUB));
254         }
255         else if (t_SelectedGroupButton() == m->eoBtnGroup[E_GRP_PHOTO]) {
256                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT,     _(NO_PHOTO_MESSAGE));
257                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT_SUB, _(NO_PHOTO_MESSAGE_SUB));
258         }
259         else if (t_SelectedGroupButton() == m->eoBtnGroup[E_GRP_VIDEO]) {
260                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT,     _(NO_VIDEO_MESSAGE));
261                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT_SUB, _(NO_VIDEO_MESSAGE_SUB));
262         }
263         else if (t_SelectedGroupButton() == m->eoBtnGroup[E_GRP_MUSIC]) {
264                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT,     _(NO_MUSIC_MESSAGE));
265                 elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT_SUB, _(NO_MUSIC_MESSAGE_SUB));
266         }
267 }
268
269 void CFbBaseView::UnsetFocus(void)
270 {
271         elm_object_focus_set(t_SelectedGroupButton(), EINA_TRUE);
272 }
273
274 void CFbBaseView::CbLinkApp(int type, int source_type, char *path)
275 {
276         bundle *args;
277         int r;
278
279         args = bundle_create();
280         if (!args) {
281                 _ERR("unable to create bundle");
282                 return;
283         }
284
285         bundle_add(args, PARAM_SOURCE, source_arg[source_type]);
286         bundle_add(args, PARAM_URI, path);
287
288         r = aul_launch_app(linked_app[type], args);
289         if (args)
290                 bundle_free(args);
291         if (r < 0) {
292                 _ERR(" Unable to launch linked app");
293                 return;
294         }
295
296         return;
297 }
298
299 void CFbBaseView::UpdatedGrid(void)
300 {
301         int i;
302
303         for (i = 0; i < TOTAL_GROUP_BTNS; i++)
304                 elm_object_focus_next_object_set(m->eoBtnGroup[i],
305                 m->pFbBaseLayout->Grid(), ELM_FOCUS_RIGHT);
306
307         elm_object_focus_next_object_set(m->eoBtnGroup[E_GRP_ALL],
308                 m->eoBtnSort, ELM_FOCUS_UP);
309         elm_object_focus_next_object_set(m->eoBtnSort,
310                 m->eoBtnGroup[E_GRP_ALL], ELM_FOCUS_LEFT);
311         elm_object_focus_next_object_set(m->eoBtnSort,
312                 m->pFbBaseLayout->Grid(), ELM_FOCUS_DOWN);
313         elm_object_focus_next_object_set(m->eoBtnSource,
314                 m->pFbBaseLayout->Grid(), ELM_FOCUS_DOWN);
315
316         elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT, "");
317         elm_object_part_text_set(m->eoBase, FBR_PART_NO_CONTENT_SUB, "");
318 }
319
320 void CFbBaseView::t_CreateTopSession(void)
321 {
322         _DBG();
323         int i;
324         Evas_Object *btn;
325         struct _btn_info btninfo[TOTAL_TOP_BTNS];
326         btninfo[TOPBTN_SOURCE].style = FBR_STYLE_SOURCE_BTN;
327         btninfo[TOPBTN_SOURCE].part  = FBR_PART_SOURCE_HOVERSEL;
328         
329         btninfo[TOPBTN_SORT].style = FBR_STYLE_SORT_BTN;
330         btninfo[TOPBTN_SORT].part  = FBR_PART_SORT_HOVERSEL;
331
332         elm_object_part_text_set(m->eoBase, FBR_PART_TITLE,
333                 _(FBR_TEXT_TITLE));
334
335         for (i = 0; i < TOTAL_TOP_BTNS; i++) {
336                 btn = _add_button(m->eoBase);
337                 if (!btn) {
338                         _ERR(" Adding btn failed ");
339                         return;
340                 }
341
342                 elm_object_style_set(btn, btninfo[i].style);
343                 elm_object_part_content_set(m->eoBase, btninfo[i].part, btn);
344
345                 m->pHandlerButton[i]->Connect(btn);
346
347                 if (i == TOPBTN_SOURCE)
348                         m->eoBtnSource = btn;
349                 else if (i == TOPBTN_SORT)
350                         m->eoBtnSort = btn;
351         }
352
353         elm_object_text_set(m->eoBtnSource, _(CSourceCtxPopup::SourceText(CInfo::SourceType())));
354         elm_object_text_set(m->eoBtnSort, _(CSortCtxPopup::SortText(CInfo::SortType())));
355 }
356
357 void CFbBaseView::t_CreateLeftSession(void)
358 {
359         _DBG();
360         Evas_Object *box, *ic;
361         int i;
362         char buf[MAX_LENGTH];
363         static struct _btn_info btninfo[TOTAL_GROUP_BTNS];
364         btninfo[E_GRP_ALL].txt = N_("ALL");
365         btninfo[E_GRP_ALL].icon_path = FBR_IMAGE_GRPBTN_ALL;
366         btninfo[E_GRP_PHOTO].txt = N_("PHOTO");
367         btninfo[E_GRP_PHOTO].icon_path = FBR_IMAGE_GRPBTN_PHOTO;
368         btninfo[E_GRP_VIDEO].txt = N_("VIDEO");
369         btninfo[E_GRP_VIDEO].icon_path = FBR_IMAGE_GRPBTN_VIDEO;
370         btninfo[E_GRP_MUSIC].txt = N_("MUSIC");
371         btninfo[E_GRP_MUSIC].icon_path = FBR_IMAGE_GRPBTN_MUSIC;
372
373         box = elm_box_add(m->eoBase);
374         if (!box)
375                 return;
376         evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
377         evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
378         evas_object_show(box);
379
380         for (i = 0; i < TOTAL_GROUP_BTNS; i++) {
381                 m->eoBtnGroup[i] = _add_button(box);
382                 if (!m->eoBtnGroup[i]) {
383                         _ERR(" failed to add button to box ");
384                         continue;
385                 }
386
387                 elm_box_pack_end(box, m->eoBtnGroup[i]);
388                 elm_object_style_set(m->eoBtnGroup[i], FBR_STYLE_GROUPBTN);
389                 elm_object_text_set(m->eoBtnGroup[i], _(btninfo[i].txt));
390                 
391                 m->pHandlerGroup[i]->Connect(m->eoBtnGroup[i]);
392                 ic = elm_image_add(m->eoBtnGroup[i]);
393                 if (!ic)
394                         continue;
395                 _DBG("");
396
397                 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
398                         btninfo[i].icon_path);
399                 elm_image_file_set(ic, buf, NULL);
400                 elm_object_part_content_set(m->eoBtnGroup[i],
401                         FBR_PART_ELM_SWALLOWICON, ic);
402         }
403         _DBG("");
404
405         t_SetSelectedGroupButton(m->eoBtnGroup[E_GRP_ALL]);
406         _DBG("");
407
408         elm_object_signal_emit(m->eoBtnGroup[E_GRP_ALL],
409                 FBR_SIGNAL_GROUP_SELECTED, "");
410         elm_object_focus_set(m->eoBtnGroup[E_GRP_ALL], EINA_TRUE);
411         elm_object_part_content_set(m->eoBase, FBR_PART_GROUPBTN_BOX, box);
412 }
413
414 void CFbBaseView::t_CreateFullView(void)
415 {
416         t_CreateTopSession();
417         t_CreateLeftSession();
418         _DBG("UpdateLayout");
419         m->pFbBaseLayout->Update(false);
420 }
421
422 void CFbBaseView::t_SetSelectedGroupButton(Evas_Object* obj)
423 {
424         m->eoSelectedBtnGroup = obj;
425         int idx = -1;
426
427         int a;
428         for (a = 0; a < TOTAL_GROUP_BTNS; a++) {
429                 if (m->eoBtnGroup[a] == obj)
430                         idx = a;
431         }
432         CInfo::SetGroupIndex(idx);
433 }
434
435 Evas_Object* CFbBaseView::t_SelectedGroupButton(void)
436 {
437         return m->eoSelectedBtnGroup;
438 }
439
440 void CFbBaseView::t_OnShow(void)
441 {
442         _DBG();
443                         
444         evas_object_show(m->eoBase);
445
446         CBaseView::t_OnShow();
447 }
448
449 void CFbBaseView::t_OnUpdate(void *data)
450 {
451         _DBG();
452         m->pFbBaseLayout->Action();
453 }
454
455 void CFbBaseView::t_OnHide(void)
456 {
457         evas_object_hide(m->eoBase);
458
459         CBaseView::t_OnHide();
460 }
461
462 bool CFbBaseView::Create(void *data)
463 {
464         ASSERT(!m);
465
466         Evas_Object *eoWin = CViewMgr::GetInstance()->Window();
467         Evas_Object *eoBase = NULL;
468
469         int source_type = E_ALL;
470
471         _CREATE_BEGIN{
472                 _CHECK(m = new SFbBaseView)
473                 _CHECK(eoBase = elm_layout_add(eoWin))
474                 _CHECK(elm_layout_file_set(eoBase, EDJEFILE, FBR_BASE_VIEW))
475                 _COMMAND{
476                         evas_object_size_hint_weight_set(eoBase, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
477                         elm_win_resize_object_add(eoWin, eoBase);
478
479                         /* get the source_type using 'data' string */
480                         if (data) {
481                                 // Find Index
482                                 int i;
483                                 int arrsize = ARRAY_SIZE(source_arg);
484                                 for (i = 0; i < arrsize; i++) {
485                                         if (source_arg[i] && !strcmp(source_arg[i], (const char*)data)) {
486                                                 source_type = i;
487                                                 break;
488                                         }
489                                 }
490                                 if (source_type < E_ALL || source_type > E_USB)
491                                         source_type = E_ALL;
492                                 CInfo::SetSourceType(source_type);
493                                 m->eoWin = eoWin;
494                                 m->eoBase = eoBase;
495                         }
496                 }
497                 _CHECK(m->pLayoutMgr = new CLayoutMgr)
498                 _CHECK(m->pLayoutMgr->Create(eoBase, NULL))
499                 _CHECK(m->pFbBaseLayout = new CFbBaseLayout(FB_BASE_LAYOUT))
500                 _CHECK(m->pFbBaseLayout->Create(m->pLayoutMgr, NULL))
501                 _CHECK(m->pLayoutMgr->AddLayout(m->pFbBaseLayout))
502                 _CHECK(CUsbConnectionListener::Create())
503
504                 _WHEN_SUCCESS{}
505
506                 _CHECK_FAIL{ CUsbConnectionListener::Destroy(); }
507                 _CHECK_FAIL{ m->pLayoutMgr->RemoveLayout(m->pFbBaseLayout); }
508                 _CHECK_FAIL{ m->pFbBaseLayout->Destroy(); }
509                 _CHECK_FAIL{ delete m->pFbBaseLayout; m->pFbBaseLayout = NULL; }
510                 _CHECK_FAIL{ m->pLayoutMgr->Destroy(); }
511                 _CHECK_FAIL{ delete m->pLayoutMgr; m->pLayoutMgr = NULL; }
512                 _CHECK_FAIL{ /* elm_layout_file_set*/ }
513                 _CHECK_FAIL{ evas_object_del(eoBase); }
514                 _CHECK_FAIL{ delete m; m = NULL; }
515         } _CREATE_END_AND_CATCH{ return false; }
516
517
518         // original create grid
519         m->pLayoutMgr->Show(FB_BASE_LAYOUT);
520         CInfo::SetSortType(0/*CSort::SORT_NAME_AZ*/);
521         evas_object_data_set(eoBase, BASE_VIEW_DATA, this);
522         t_CreateFullView();
523         elm_object_focus_allow_set(eoBase, EINA_FALSE);
524         m->pHandlerBase->Connect(eoBase);
525         CBaseView::Create(NULL);
526         return true;
527 }
528
529 void CFbBaseView::Destroy(void)
530 {
531         ASSERT(m);
532
533         CBaseView::Destroy();
534         CUsbConnectionListener::Destroy();
535
536         m->pLayoutMgr->RemoveLayout(m->pFbBaseLayout);
537         m->pFbBaseLayout->Destroy();
538         delete m->pFbBaseLayout;
539
540         m->pLayoutMgr->Destroy();
541         delete m->pLayoutMgr;
542
543         evas_object_del(m->eoBase);
544
545         delete m;
546         m = NULL;
547 }
548
549
550 Evas_Object* CFbBaseView::Base(void)
551 {
552         ASSERT(m);
553
554         return m->eoBase;
555 }
556
557
558 void CFbBaseView::OnConnect(void)
559 {
560         m->pPopup = new CPopup;
561         if (!m->pPopup)
562                 return;
563         if (!m->pPopup->Create(m->eoBase)) {
564                 delete m->pPopup;
565                 m->pPopup = NULL;
566                 return;
567         }
568
569         if (CInfo::SourceType() == E_USB) {
570                 if (!FlagConnected()) {
571                         CInfo::SetSourceType(E_ALL);
572                         elm_object_text_set(m->eoBtnSource,
573                                 _(CSourceCtxPopup::SourceText(CInfo::SourceType())));
574                 }
575         }
576 }
577
578
579 void CFbBaseView::OnUpdated(const SEntity *entity)
580 {
581         m->pPopup->Destroy();
582         delete m->pPopup;
583         m->pPopup = NULL;
584
585         if (m->pCtxPopup) {
586                 m->pCtxPopup->Destroy();
587                 delete m->pCtxPopup;
588                 m->pCtxPopup = NULL;
589         }
590         if (CInfo::SourceType() != E_TV) {
591                 m->pFbBaseLayout->Update(false);
592                 elm_object_focus_set(t_SelectedGroupButton(), EINA_TRUE);
593         }
594 }
595