workaround: modify query string (due to sqlite bug)
[profile/tv/apps/native/air_mediahub.git] / src / layout / gallery.c
1 /*
2  * Copyright (c) 2015 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 <media_content.h>
19 #include <app_debug.h>
20 #include <app_media.h>
21 #include <gridmgr.h>
22 #include <layoutmgr.h>
23 #include <viewmgr.h>
24
25 #include "define.h"
26 #include "view.h"
27 #include "data/mediadata.h"
28 #include "util/listmgr.h"
29 #include "util/util.h"
30
31 /*
32    FIXME
33 #define LIST_MEDIA_COND "media_type=0 OR \
34                         (media_type=1 AND copyright LIKE \"Unknown\")"
35 */
36 #define LIST_MEDIA_COND "(media_type=0 OR media_type=1) AND copyright LIKE \"Unknown\""
37
38 #define TEXT_NOCONTENT "No Photo & Video"
39
40 #define GRID_ITEM_X 206
41 #define GRID_ITEM_Y 206
42 #define GRID_NUM_ITEM 3
43
44 #define BOX_PADDING 62
45
46 struct _priv {
47         Evas_Object *base;
48         Evas_Object *layout;
49         Evas_Object *menu_btn;
50
51         layoutmgr *lmgr;
52
53         struct listmgr *listmgr;
54         struct listmgr_data *ldata;
55
56         struct mediadata *md;
57         int cur_index;
58
59         Eina_List *media_list;
60 };
61
62 static char *_grid_text_get(void *data, Evas_Object *obj, const char *part)
63 {
64         app_media *am;
65         app_media_info *info;
66         char buf[32];
67
68         if (!data)
69                 return NULL;
70
71         am = data;
72         info = app_media_get_info(am);
73         if (!info) {
74                 _ERR("failed to get media info");
75                 return NULL;
76         }
77
78         if (info->media_type != MEDIA_CONTENT_TYPE_VIDEO)
79                 return NULL;
80
81         if (!strcmp(part, PART_ELM_TEXT_PLAYTIME)) {
82                 util_time_string(buf, sizeof(buf),
83                                         info->video->duration, false);
84
85                 return strdup(buf);
86         }
87
88         return NULL;
89 }
90
91 static Evas_Object *_grid_content_get(void *data,
92                         Evas_Object *obj, const char *part)
93 {
94         Evas_Object *image;
95         app_media *am;
96         app_media_info *info;
97
98         if (!data)
99                 return NULL;
100
101         am = data;
102         info = app_media_get_info(am);
103         if (!info) {
104                 _ERR("failed to get media info");
105                 return NULL;
106         }
107
108         image = NULL;
109         if (!strcmp(part, PART_ELM_SWALLOW_THUMBNAIL)) {
110                 image = util_add_image(obj, info->thumbnail_path);
111                 if (!image) {
112                         _ERR("failed to create image object");
113                         return NULL;
114                 }
115
116                 evas_object_show(image);
117         } else if (!strcmp(part, PART_ELM_SWALLOW_VIDEO)) {
118                 if (info->media_type == MEDIA_CONTENT_TYPE_VIDEO) {
119                         image = util_add_image(obj, IMAGE_THUMBNAIL_PLAY);
120                         if (!image) {
121                                 _ERR("failed to create image object");
122                                 return NULL;
123                         }
124
125                         evas_object_show(image);
126                 }
127         }
128
129         return image;
130 }
131
132 static struct grid_class _gclass = {
133         .item_style = STYLE_GRID_GALLERY_ITEM,
134         .text_get = _grid_text_get,
135         .content_get = _grid_content_get
136 };
137
138 static void _grid_selected_cb(void *data, Elm_Object_Item *it)
139 {
140         app_media *am;
141         struct view_update_data vdata;
142         struct _priv *priv;
143
144         if (!data || !it) {
145                 _ERR("invalid argument");
146                 return;
147         }
148
149         priv = data;
150
151         am = elm_object_item_data_get(it);
152         if (!am) {
153                 _ERR("failed to get app media");
154                 return;
155         }
156
157         vdata.list = mediadata_get_medialist(priv->md);
158         vdata.index = util_get_media_index(vdata.list, am);
159         priv->cur_index = vdata.index;
160
161         viewmgr_update_view(VIEW_VIEWER, UPDATE_CONTENT, &vdata);
162         viewmgr_push_view(VIEW_VIEWER);
163 }
164
165 static struct listmgr_data *_create_listmgr_data(struct _priv *priv)
166 {
167         struct listmgr_data *data;
168         struct grid_ops *gops;
169
170         data = calloc(1, sizeof(*data));
171         if (!data)
172                 goto err;
173
174         data->menu_btn = priv->menu_btn;
175
176         data->grid_item_x = GRID_ITEM_X;
177         data->grid_item_y = GRID_ITEM_Y;
178         data->grid_num_item = GRID_NUM_ITEM;
179         data->box_padding = BOX_PADDING;
180
181         gops = calloc(1, sizeof(*gops));
182         if (!gops)
183                 goto err;
184
185         gops->gclass = &_gclass;
186         gops->selected_cb = _grid_selected_cb;
187         gops->ops_data = priv;
188
189         data->gops = gops;
190
191         return data;
192
193 err:
194         _ERR("failed to allocate memory");
195         return NULL;
196 }
197
198 static void _update_content_info(struct _priv *priv)
199 {
200         int photo, video;
201         char buf[128];
202
203         photo = mediadata_get_media_count(priv->md, E_MEDIA_PHOTO);
204         video = mediadata_get_media_count(priv->md, E_MEDIA_VIDEO);
205
206         if (photo < 0 || video < 0) {
207                 _ERR("failed to get media count");
208                 return;
209         }
210
211         snprintf(buf, sizeof(buf), "%d Photos, %d Videos", photo, video);
212
213         elm_object_part_text_set(priv->layout, PART_CONTENT_INFO, buf);
214 }
215
216 static void _update_content_list(struct _priv *priv)
217 {
218         Eina_List *list;
219
220         if (priv->media_list)
221                 return;
222
223         list = mediadata_get_list(priv->md, E_LIST_DATE);
224         if (!list) {
225                 elm_object_part_text_set(priv->layout,
226                                 PART_NOCONTENT, TEXT_NOCONTENT);
227                 return;
228         }
229
230         if (!listmgr_update_content_list(priv->listmgr, list))
231                 _ERR("failed to update list area");
232
233         priv->media_list = list;
234
235         _update_content_info(priv);
236 }
237
238 static bool _create(layoutmgr *lmgr, void *data)
239 {
240         struct listmgr *listmgr;
241         struct listmgr_data *ldata;
242         struct mediadata *md;
243         struct _priv *priv;
244         Evas_Object *base, *layout;
245
246         if (!lmgr) {
247                 _ERR("failed to get layoutmgr");
248                 return false;
249         }
250
251         if (!data) {
252                 _ERR("invalid argument");
253                 return false;
254         }
255
256         priv = calloc(1, sizeof(*priv));
257         if (!priv) {
258                 _ERR("failed to allocate priv");
259                 return false;
260         }
261
262         priv->menu_btn = (Evas_Object *)data;
263
264         base = layoutmgr_get_base(lmgr);
265         if (!base) {
266                 _ERR("failed to get base object");
267                 goto err;
268         }
269
270         layout = elm_layout_add(base);
271         if (!layout) {
272                 _ERR("failed to create layout");
273                 goto err;
274         }
275
276         if (!elm_layout_file_set(layout, EDJEFILE, GRP_GALLERY_LAYOUT)) {
277                 _ERR("failed to set layout file");
278                 goto err2;
279         }
280
281         ldata = _create_listmgr_data(priv);
282         if (!ldata) {
283                 _ERR("failed to create listmgr data");
284                 goto err2;
285         }
286
287         listmgr = listmgr_create(layout, (void *)ldata);
288         if (!listmgr) {
289                 _ERR("failed to create listmgr");
290                 goto err3;
291         }
292
293         md = mediadata_create(LIST_MEDIA_COND, E_SOURCE_ALL, E_SORT_DATE);
294         if (!md) {
295                 _ERR("failed to create mediadata");
296                 listmgr_destroy(listmgr);
297                 goto err3;
298         }
299
300         priv->base = base;
301         priv->layout = layout;
302         priv->lmgr = lmgr;
303         priv->listmgr = listmgr;
304         priv->ldata = ldata;
305         priv->md = md;
306
307         layoutmgr_set_layout_data(lmgr, LAYOUT_GALLERY, priv);
308
309         if (!listmgr_draw_list_area(listmgr)) {
310                 _ERR("failed to draw list area");
311                 mediadata_destroy(md);
312                 listmgr_destroy(listmgr);
313                 goto err3;
314         }
315
316         return true;
317
318 err3:
319         free(ldata);
320 err2:
321         evas_object_del(layout);
322 err:
323         free(priv);
324         return false;
325 }
326
327 static void _destroy(void *layout_data)
328 {
329         struct _priv *priv;
330
331         if (!layout_data) {
332                 _ERR("failed to get layout data");
333                 return;
334         }
335
336         priv = layout_data;
337
338         mediadata_free_list(priv->media_list);
339         mediadata_destroy(priv->md);
340
341         listmgr_destroy(priv->listmgr);
342         free(priv->ldata->gops);
343         free(priv->ldata);
344
345         evas_object_del(priv->layout);
346
347         free(priv);
348 }
349
350 static void _show(void *layout_data)
351 {
352         struct _priv *priv;
353
354         if (!layout_data) {
355                 _ERR("failed to layout data");
356                 return;
357         }
358
359         priv = layout_data;
360
361         evas_object_show(priv->layout);
362         elm_object_part_content_set(priv->base,
363                         PART_THUMBNAIL_AREA, priv->layout);
364 }
365
366 static void _hide(void *layout_data)
367 {
368         struct _priv *priv;
369
370         if (!layout_data) {
371                 _ERR("failed to get layout data");
372                 return;
373         }
374
375         priv = layout_data;
376
377         evas_object_hide(priv->layout);
378         elm_object_part_content_unset(priv->base, PART_THUMBNAIL_AREA);
379 }
380
381 static void _update(void *layout_data, int update_type, void *data)
382 {
383         struct view_update_data *vdata;
384         struct _priv *priv;
385         bool update;
386
387         if (!layout_data) {
388                 _ERR("failed to get layout data");
389                 return;
390         }
391
392         priv = layout_data;
393         vdata = data;
394
395         switch (update_type) {
396         case UPDATE_CONTENT:
397                 _update_content_list(priv);
398                 break;
399         case UPDATE_FOCUS:
400                 if (!vdata) {
401                         _ERR("invalid argument");
402                         return;
403                 }
404
405                 if (priv->cur_index != vdata->index)
406                         update = true;
407                 else
408                         update = false;
409
410                 listmgr_focus_content_list(priv->listmgr, vdata->index, update);
411
412                 break;
413         default:
414                 break;
415         }
416 }
417
418 static layout_class _lclass = {
419         .layout_id = LAYOUT_GALLERY,
420         .create = _create,
421         .show = _show,
422         .hide = _hide,
423         .destroy = _destroy,
424         .update = _update,
425 };
426
427 layout_class *layout_gallery_get_lclass(void)
428 {
429         return &_lclass;
430 }