initial upload for tizen 2.0 beta
[apps/home/gallery.git] / src / util / gl-util.c
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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 <sys/stat.h>
18 #include <sys/statvfs.h>
19 #include <vconf.h>
20 #include <vconf-keys.h>
21 #include <errno.h>
22 #include <haptic.h>
23 #include <media-thumbnail.h>
24 #include "gl-debug.h"
25 #include "gallery.h"
26 #include "gl-albums.h"
27 #include "gl-gridview.h"
28 #include "gl-listview.h"
29 #include "gl-util.h"
30 #include "gl-ui-util.h"
31 #include "gl-controlbar.h"
32 #include "gl-thread-util.h"
33 #include "gl-popup.h"
34 #include "gl-progressbar.h"
35 #include "gl-ext-ug-load.h"
36 #include "gl-ext-exec.h"
37 #include "gl-drm.h"
38 #include "gl-nocontents.h"
39 #include "gl-notify.h"
40 #include "gl-editfield.h"
41 #include "gl-strings.h"
42 #include "gl-data-type.h"
43 #ifdef _USE_ROTATE_BG
44 #include "gl-exif.h"
45 #endif
46
47 #define GL_FILE_COPY_BUF_MAX 16384
48 #define GL_CREATE_DIR_MASK_DEFAULT 0775
49 /* Time for displaying progressbar UI compeletely */
50 #define GL_TIMER_INTERVAL_PBAR_SHOWED 0.5
51 #define GL_TIMER_INTERVAL_VIBRATION 0.5
52 #define GL_VIBRATION_DEVICE 0
53 #define GL_VIBRATION_DURATION 500
54 #ifdef _USE_ROTATE_BG
55 #define GL_ROTATE_DELAY 0.25
56 #endif
57
58 /* Use timer to show progressbar totally before write pipe */
59 static Eina_Bool _gl_start_thread_op_timer_cb(void *data)
60 {
61         gl_dbg("Emit START signal...");
62         GL_CHECK_CANCEL(data);
63         gl_appdata *ad = (gl_appdata *)data;
64         /* Emit signal to notice child thread to handle next item. */
65         gl_thread_emit_next_signal(ad);
66         if (ad->pbarinfo.start_thread_timer) {
67                 ecore_timer_del(ad->pbarinfo.start_thread_timer);
68                 ad->pbarinfo.start_thread_timer = NULL;
69         }
70         return ECORE_CALLBACK_CANCEL;
71 }
72
73 /**
74 * Use thread to move/delete medias
75 * for displaying progrssabar UI
76 */
77 static int _gl_use_thread_operate_medias(void *data, char *pbar_title, int all_cnt, int op_type)
78 {
79         gl_dbg("all_cnt: %d, op_type: %d.", all_cnt, op_type);
80         GL_CHECK_VAL(data, -1);
81         gl_appdata *ad = (gl_appdata *)data;
82
83         /* Initialize thread mutex lock */
84         gl_thread_init_lock(ad);
85         /* Make progressbar */
86         gl_pb_make_thread_pbar(ad, ad->maininfo.win, pbar_title);
87         /* Set pb_cancel, indicates thread operation is beginning */
88         gl_thread_set_cancel_state(ad, GL_PB_CANCEL_NORMAL);
89         /* Initialize progressbar */
90         gl_pb_refresh_thread_pbar(ad, 0, all_cnt);
91         /* Use timer to emit next signal to show progressbarbar totally */
92         if (ad->pbarinfo.start_thread_timer) {
93                 ecore_timer_del(ad->pbarinfo.start_thread_timer);
94                 ad->pbarinfo.start_thread_timer = NULL;
95         }
96         Ecore_Timer *timer = NULL;
97         timer = ecore_timer_add(GL_TIMER_INTERVAL_PBAR_SHOWED,
98                                 _gl_start_thread_op_timer_cb, ad);
99         ad->pbarinfo.start_thread_timer = timer;
100         /* Set media operation type */
101         ad->maininfo.medias_op_type = op_type;
102         /* Generate child thread */
103         gl_thread_gen_data_thread(ad);
104         return 0;
105 }
106
107 static void _gl_db_update_noti_cb(keynode_t *key, void *data)
108 {
109         GL_CHECK(data);
110         gl_appdata *ad = (gl_appdata *)data;
111         gl_dbgW("VCONFKEY_FILEMANAGER_DB_STATUS changed!");
112         int mmc_state = -1;
113
114         vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_state);
115
116         if (mmc_state == -1)
117         {
118                 gl_dbg("Error when check MMC Status");
119                 return;
120         }
121
122         if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED)
123         {
124                 gl_dbg("mmc_state[%d] : VCONFKEY_SYSMAN_MMC_MOUNTED", mmc_state);
125                 if (ad->maininfo.mmc_state == GL_MMC_STATE_REMOVED)
126                         ad->maininfo.mmc_state = GL_MMC_STATE_ADDING_MOVING;
127                 else
128                         ad->maininfo.mmc_state = GL_MMC_STATE_ADDED;
129
130                 gl_update_view(ad, GL_UPDATE_VIEW_MMC_ADDED);
131
132                 /* Update popup content after albums list updated */
133                 if (ad->popupinfo.popup &&
134                     (ad->popupinfo.popup_mode == GL_POPUP_THUMB_MOVE)) {
135                         gl_dbg("Add MMC albums to popup.");
136                         gl_popup_update_content(ad, GL_POPUP_THUMB_MOVE);
137                 }
138         }
139         else if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED ||
140                  mmc_state == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED)
141         {
142                 gl_dbg("mmc_state[%d] : VCONFKEY_SYSMAN_MMC_REMOVED", mmc_state);
143                 if (ad->maininfo.mmc_state == GL_MMC_STATE_ADDED_MOVING)
144                 {
145                         /*
146                          * Set pb_cancel status,
147                          * indicates MMC removed while moving or deleting.
148                          */
149                         gl_thread_set_cancel_state(ad, GL_PB_CANCEL_MMC);
150                         /* MMC moved while moving or deleting */
151                         ad->maininfo.mmc_state = GL_MMC_STATE_REMOVED_MOVING;
152                 } else if (ad->maininfo.mmc_state == GL_MMC_STATE_REMOVED_MOVING) {
153                         gl_dbgW("View updated on GL_MMC_STATE_ADDED_MOVING");
154                         return;
155                 } else
156                 {
157                         /* MMC is extracted */
158                         ad->maininfo.mmc_state = GL_MMC_STATE_REMOVED;
159                 }
160
161                 gl_update_view(ad, GL_UPDATE_VIEW_MMC_REMOVED);
162
163                 /* Update popup content after albums list updated */
164                 if (ad->popupinfo.popup &&
165                     (ad->popupinfo.popup_mode == GL_POPUP_THUMB_MOVE)) {
166                         gl_dbg("Remove MMC albums from popup.");
167                         gl_popup_update_content(ad, GL_POPUP_THUMB_MOVE);
168                 }
169         }
170 }
171
172
173 /**
174 * @param: b_update_albums_list
175 *       True: Update albums list and medias list, then update normal view.
176 *       False: Get new medias for current view from DB
177 *                 then update view to synchronize data with Myfile.
178 *                 Use case:
179 *               Update edit gridview/listview.
180 */
181 static int _gl_update_thumb_items(void *data, bool b_update_albums_list)
182 {
183         GL_CHECK_VAL(data, -1);
184         gl_appdata *ad = (gl_appdata *)data;
185         int view_mode = gl_get_view_mode(ad);
186         bool b_edit_m = false;
187
188         gl_dbg("view_mode: %d, b_update_albums_list: %d.", view_mode,
189                b_update_albums_list);
190         if (view_mode == GL_VIEW_THUMBS_EDIT ||
191             view_mode == GL_VIEW_VIDEOLIST_EDIT) {
192                 gl_dbg("Edit view.");
193                 b_edit_m = true;
194         }
195
196         if (view_mode == GL_VIEW_VIDEOLIST &&
197             ad->listinfo.played_uuid == NULL &&
198             _gl_data_check_update(ad, false) == false) {
199                 gl_dbg("Nothing changed.");
200                 return 0;
201         }
202
203         /**
204         * 1, Update albums list and medias_elist,
205         * 2, Update medias_elist.
206         */
207         if (b_update_albums_list)
208                 gl_refresh_albums_list(ad);
209         else
210                 _gl_data_update_item_list(ad);
211
212         if (ad->maininfo.medias_cnt == 0) {
213                 /* All items deleted, change to albms view */
214                 gl_pop_to_ctrlbar_ly(ad, !b_update_albums_list);
215         } else {
216                 if (view_mode == GL_VIEW_VIDEOLIST) {
217                         gl_list_update_view(ad);
218                 } else if (_gl_nocontents_show(ad)) {
219                         gl_dbg("none video/image, show nocontents");
220                         /* Remove invalid widgets */
221                         gl_del_invalid_widgets(ad, GL_INVALID_NEW_ENTRY_NOC);
222                 } else if (view_mode == GL_VIEW_THUMBS) {
223                         gl_grid_update_items(ad);
224                 } else if (view_mode == GL_VIEW_THUMBS_EDIT) {
225                         gl_grid_change_to_edit(ad);
226                 } else if (view_mode == GL_VIEW_VIDEOLIST_EDIT) {
227                         gl_list_change_to_edit(ad);
228                 }
229
230                 /* Normal view, return */
231                 if (!b_edit_m)
232                         return 0;
233
234                 /* Get selected medias count */
235                 int sel_cnt = _gl_data_selected_list_count(ad);
236                 /* Remove invalid widgets */
237                 if (sel_cnt == 0)
238                         gl_del_invalid_widgets(ad, GL_INVALID_NEW_ENTRY);
239                 /* Display selectioninfo */
240                 _gl_notify_create_selinfo(ad, ad->gridinfo.edit_layout,
241                                           ad->gridinfo.nf_it_edit,
242                                           ad->maininfo.medias_cnt, sel_cnt,
243                                           true);
244
245                 /**
246                 * Update albums list when change to normal view.
247                 * Maybe some empty albums exist.
248                 */
249                 if (!b_update_albums_list) {
250                         gl_dbg("Update albums list when cancelled.");
251                         ad->albuminfo.update_albums_list = true;
252                 } else if (ad->popupinfo.popup_mode == GL_POPUP_THUMB_MOVE) {
253                         gl_popup_update_content(ad, GL_POPUP_THUMB_MOVE);
254                 }
255         }
256
257         return 0;
258 }
259
260 /*
261 *   return file extension, f.e. jpg; then return new path without ext.
262 */
263 static bool
264 _gl_get_file_ext(const char *file_path, char *file_ext, char *new_path)
265 {
266         int i = 0;
267
268         for (i = strlen(file_path); i >= 0; i--)
269         {
270                 if ((file_path[i] == '.') && (i < GL_FILE_PATH_LEN_MAX))
271                 {
272                         g_strlcpy(file_ext, &file_path[i + 1], GL_FILE_EXT_LEN_MAX);
273                         g_strlcpy(new_path, file_path, i + 1);
274                         new_path[i] = '\0';
275                         gl_dbg("path without extension :%s", new_path);
276                         return true;
277                 }
278
279                 if (file_path[i] == '/')        //meet the dir. no ext
280                 {
281                         return true;
282                 }
283         }
284         return true;
285 }
286
287 /* Check if there is any MMC file contained in select_medias_elist */
288 static bool _gl_check_mmc_file_selected(void *data)
289 {
290         gl_dbg("");
291         GL_CHECK_FALSE(data);
292         gl_appdata *ad = (gl_appdata *)data;
293         gl_item *gitem = NULL;
294         int i = 0;
295         int on_mmc = -1;
296         int cnt = _gl_data_selected_list_count(ad);
297         for (i = 0; i < cnt; i++) {
298                 gitem = NULL;
299                 on_mmc = -1;
300
301                 gitem = _gl_data_selected_list_get_nth(ad, i);
302                 /* File on MMC is selected */
303                 if (gitem && gitem->item && gitem->item->file_url) {
304                         on_mmc = strncmp(GL_ROOT_PATH_MMC,
305                                          gitem->item->file_url,
306                                          strlen(GL_ROOT_PATH_MMC));
307                         if (on_mmc == 0)
308                                 return true;;
309                 }
310         }
311         return false;
312 }
313
314 /* Stop vibrate device */
315 static int _gl_stop_vibration(void *data)
316 {
317         gl_dbg("");
318         GL_CHECK_VAL(data, -1);
319         gl_appdata *ad = (gl_appdata *)data;
320         int ret = -1;
321
322         if (ad->entryinfo.haptic_handle >= 0) {
323                 ret = haptic_stop_device(GL_VIBRATION_DEVICE);
324                 if (ret != 0)
325                         gl_dbgE("haptic_stop_device failed[%d]!", ret);
326
327                 ret = haptic_deinitialize();
328                 if (ret != HAPTIC_ERROR_NONE)
329                         gl_dbgE("haptic_deinitialize failed[%d]!", ret);
330                 ad->entryinfo.haptic_handle = -1;
331         }
332
333         return 0;
334 }
335
336 static Eina_Bool _gl_vibration_timer_cb(void *data)
337 {
338         gl_dbg("");
339         GL_CHECK_VAL(data, -1);
340         gl_appdata *ad = (gl_appdata *)data;
341
342         _gl_stop_vibration(data);
343
344         if (ad->entryinfo.vibration_timer) {
345                 ecore_timer_del(ad->entryinfo.vibration_timer);
346                 ad->entryinfo.vibration_timer = NULL;
347         }
348         return ECORE_CALLBACK_CANCEL;
349 }
350
351 /* one copy of function "ecore_file_mv" from the file "ecore_file.c" for lock debugging */
352 /*
353 * Use gl_file_mv() to move medias to other album.
354 * Media-server, which is different with libmedia-info, watches src and dest folder,
355 * it updates libmedia-info DB asynchronously.
356 * While move/copy mass data in My Files appliation,
357 * After move/copy done in My files, check the dest folder in Gallery.
358 * You'll find its content is changing.
359 * gl_file_mv() operate libmedia-info DB synchronously, so it's faster than media-server.
360 */
361
362 /*
363 *  stop using "rename" when moving from mmc to phone for correct db update.
364 */
365 static Eina_Bool __gl_file_mv(gl_item *gitem, const char *src, const char *dst, int type)
366 {
367         GL_CHECK_FALSE(src);
368         GL_CHECK_FALSE(dst);
369         GL_CHECK_FALSE(gitem);
370
371         gl_dbg("\n\tSrc: %s\n\tDest: %s", src, dst);
372
373         /* Move thumb first */
374         if (_gl_local_data_move_media(gitem->item, dst) < 0) {
375                 gl_dbgE("Move media thumbnail failed!");
376                 return EINA_FALSE;
377         }
378
379         /*
380          * From->To: MMC->MMC or Phone->Phone
381          */
382         if (rename(src, dst)) {
383                 /*
384                  * File cannot be moved directly because
385                  * it resides on a different mount point.
386                  */
387                 if (errno == EXDEV) {
388                         /*
389                          * From->To: MMC->Phone or Phone->MMC
390                          */
391                         gl_dbgW("errno = EXDEV(%d): Cross-device link", errno);
392                         struct stat st;
393
394                         /*
395                          * Make sure this is a regular file before
396                          * we do anything fancy.
397                          */
398                         stat(src, &st);
399                         if (S_ISREG(st.st_mode)) {
400                                 /*
401                                  * Copy to dst file
402                                  */
403                                 if (!ecore_file_cp(src, dst)) {
404                                         gl_dbgE("Copy file failed[%d]!", errno);
405                                         return EINA_FALSE;
406                                 }
407
408
409                                 /*
410                                  * Delete src file
411                                  */
412                                 if (!ecore_file_unlink(src))
413                                         gl_dbgE("Delete file failed[%d]!", errno);
414
415                                 return EINA_TRUE;
416                         }
417                         gl_dbgE("S_ISREG fail[%d]!", errno);
418                         return EINA_FALSE;
419                 }
420
421                 gl_dbgE("Fail[%d]!", errno);
422                 return EINA_FALSE;
423         }
424
425         return EINA_TRUE;
426 }
427
428 #ifdef _USE_ROTATE_BG
429 /* b_path == true, Use saved folder path to check cluster uuid */
430 static int __gl_refresh_albums_list(void *data, bool b_path)
431 {
432         GL_CHECK_VAL(data, -1);
433         gl_appdata *ad = (gl_appdata *)data;
434         gl_cluster *current_album = ad->albuminfo.current_album;
435         char *uuid = NULL;
436         gl_cluster *current = NULL;
437         bool b_get_cur_album = false;
438         /* Albums list would be update, reset flag */
439         ad->albuminfo.update_albums_list = false;
440
441         uuid = calloc(1, GL_MTYPE_ITEN_ID_LEN_MAX);
442         GL_CHECK_VAL(uuid, -1);
443
444         /* Save cluster ID to set new current_album from new albums list */
445         if (current_album && current_album->cluster &&
446             current_album->cluster->uuid) {
447                 g_strlcpy(uuid, current_album->cluster->uuid,
448                           GL_MTYPE_ITEN_ID_LEN_MAX);
449                 b_get_cur_album = true;
450         } else {
451                 gl_dbg("None album selected, current album is unavailable.");
452         }
453
454         _gl_data_get_cluster_list(ad);
455         /* need to reset current album */
456         ad->albuminfo.current_album = NULL;
457
458         if (b_get_cur_album) {
459                 if (b_path) {
460                         gl_dbg("Path: %s", ad->albuminfo.dest_folder);
461                         if (strlen(ad->albuminfo.dest_folder) > 0 &&
462                             GL_FILE_EXISTS(ad->albuminfo.dest_folder)) {
463                                 gl_dbgW("Cluster record updated!");
464                                 _gl_data_get_cluster_by_path(ad,
465                                                              ad->albuminfo.dest_folder,
466                                                              &current);
467                         } else {
468                                 gl_dbgE("Invalid folder path!");
469                                 _gl_data_get_cluster_by_id(ad, uuid, &current);
470                         }
471                 } else {
472                         _gl_data_get_cluster_by_id(ad, uuid, &current);
473                 }
474
475                 if(current && current->cluster) {
476                         ad->albuminfo.current_album = current;
477                         gl_dbg("Reset current album: %s",
478                                current->cluster->display_name);
479                         _gl_data_update_item_list(ad);
480                 } else {
481                         /* Clear items list if current album doesn't exist */
482                         if (ad->selectedinfo.medias_elist)
483                                 _gl_data_selected_list_finalize(ad);
484                         _gl_data_clear_default_item_list(ad);
485                         ad->maininfo.medias_cnt = 0;
486                 }
487         }
488
489         if (uuid)
490                 free(uuid);
491         return 0;
492 }
493
494 #endif
495
496 static char *__gl_get_unique_full_path(char *file_path, char *ext)
497 {
498         char *file_name = file_path;
499         char *extension = ext;
500         char *final_path = NULL;
501         int final_path_len = 0;
502         int extension_len = 0;
503         int suffix_count = 0;
504         /* means suffix on file name. up to "_99999" */
505         const int max_suffix_count = 99999;
506         /* 1 means "_" */
507         int suffix_len = (int)log10(max_suffix_count + 1) + 1;
508
509         if (!file_path)
510                 return NULL;
511
512         gl_dbg("file_path=[%s], ext=[%s]", file_path, ext);
513
514         if (extension)
515                 extension_len = strlen(extension);
516
517         /* first 1 for ".", last 1 for NULL */
518         final_path_len = strlen(file_name) + 1 + suffix_len + extension_len + 1;
519
520         final_path = (char*)calloc(1, final_path_len);
521         if (!final_path) {
522                 gl_dbgE("calloc failed!");
523                 return NULL;
524         }
525
526         do {
527                 /* e.g) /tmp/abc.jpg
528                  * if there is no extension name, just make a file name without extension */
529                 if (0 == extension_len) {
530                         if (suffix_count == 0) {
531                                 snprintf(final_path, final_path_len, "%s",
532                                          file_name);
533                         } else {
534                                 snprintf(final_path, final_path_len, "%s_%d",
535                                          file_name, suffix_count);
536                         }
537                 } else {
538                         if (suffix_count == 0) {
539                                 snprintf(final_path, final_path_len, "%s.%s",
540                                          file_name, extension);
541                         } else {
542                                 snprintf(final_path, final_path_len, "%s_%d.%s",
543                                          file_name, suffix_count, extension);
544                         }
545                 }
546
547                 if (ecore_file_exists(final_path)) {
548                         suffix_count++;
549                         if (suffix_count > max_suffix_count) {
550                                 gl_dbgE("Max suffix count!");
551                                 free(final_path);
552                                 final_path = NULL;
553                                 break;
554                         } else {
555                                 memset(final_path, 0x00, final_path_len);
556                                 continue;
557                         }
558                 }
559
560                 break;
561         } while (1);
562
563         gl_dbg("Decided path = [%s]", final_path);
564         return final_path;
565 }
566
567 bool
568 gl_validate_album_name(const char *new_name)
569 {
570         GL_CHECK_FALSE(new_name);
571         char invalid_chars[] = { '/', '\\', ':', '*', '?', '"', '<', '>', '|', '\0' };
572         char *ptr = invalid_chars;
573
574         gl_dbg("new album name is %s\n", new_name);
575         while (*ptr != '\0')
576         {
577                 gl_dbg("invalid character is %c", *ptr);
578                 if (strchr(new_name, (*ptr)) != NULL)
579                 {
580                         return false;
581                 }
582                 ++ptr;
583         }
584
585         return true;
586 }
587
588 int
589 gl_get_entry_text(Evas_Object * entry, char *entry_text, int len_max)
590 {
591         gl_dbg("");
592         GL_CHECK_VAL(entry_text, -1);
593         GL_CHECK_VAL(entry, -1);
594
595         memset(entry_text, 0x00, len_max);
596
597         char *entry_str = (char *)elm_entry_entry_get(entry);
598         if (entry_str)
599         {
600                 if (strlen(entry_str) == 0)
601                 {
602                         gl_dbg("Entry string is empty!");
603                         //free(entry_str);
604                 }
605                 else
606                 {
607                         char *entry_utf8 = elm_entry_markup_to_utf8(entry_str); // changes user input to utf-8 encoding format
608                         if (entry_utf8 == NULL)
609                         {
610                                 gl_dbgE("Make entry string to UTF8 failed!");
611                                 return -1;
612                         }
613                         else if (strlen(entry_utf8) == 0)
614                         {
615                                 gl_dbg("Entry text is empty!");
616                         }
617                         else
618                         {
619                                 g_strlcpy(entry_text, entry_utf8, len_max);
620                                 entry_text[len_max - 1] = '\0';
621                         }
622
623                         free(entry_utf8);
624                         entry_utf8 = NULL;
625                 }
626         }
627         else
628         {
629                 gl_dbgE("Get entry string failed!");
630                 return -1;
631         }
632
633         return 0;
634 }
635
636 /**
637 * Change utf8 string to markup, then set it as entry text.
638 * To fix special character "&" issue,  to convert "&" to "&amp;". f.e.
639 * Myfiles->rename folder to AB&C->Gallery/Rename ->displayed as "AB"
640 */
641 int gl_set_entry_text(Evas_Object *entry, char *entry_text)
642 {
643         GL_CHECK_VAL(entry, -1);
644         char *entry_makeup = NULL;
645         gl_dbg("Entry UTF8 text: %s.", entry_text);
646
647         if (entry_text) {
648                 entry_makeup = elm_entry_utf8_to_markup(entry_text);
649                 if (entry_makeup == NULL) {
650                         gl_dbgE("Make utf8 string to makeup failed!");
651                         return -1;
652                 }
653                 gl_dbg("Entry makeup text: %s.", entry_makeup);
654         }
655         /* Empty string set if entry_makeup is NULL */
656         elm_entry_entry_set(entry, entry_makeup);
657
658         if (entry_makeup) {
659                 free(entry_makeup);
660                 entry_makeup = NULL;
661         }
662
663         return 0;
664 }
665
666 int
667 gl_get_default_images_path(char *directory_path)
668 {
669         int len = 0;
670         GL_CHECK_VAL(directory_path, -1);
671
672         len = snprintf(directory_path, GL_DIR_PATH_LEN_MAX, "%s",
673                        GL_ROOT_PATH_PHONE);
674         if (len < 0) {
675                 gl_dbgE("snprintf returns failure!");
676                 return -1;
677         } else {
678                 directory_path[len] = '\0';
679                 len = -1;
680         }
681
682         len = g_strlcat(directory_path, GL_DEFAULT_PATH_IMAGES,
683                         GL_DIR_PATH_LEN_MAX);
684         if (len >= GL_DIR_PATH_LEN_MAX) {
685                 gl_dbgE("strlcat returns failure(%d)!", len);
686                 return -1;
687         }
688         gl_dbg("Default images path: %s.", directory_path);
689
690         return 0;
691 }
692
693 int gl_get_selected_files_path_str(void *data, gchar sep_c, char **path_str, int *sel_cnt)
694 {
695         GL_CHECK_VAL(path_str, -1);
696         GL_CHECK_VAL(data, -1);
697         gl_appdata *ad = (gl_appdata *)data;
698         GL_CHECK_VAL(ad->selectedinfo.medias_elist, -1);
699         GString *selected_path_list = g_string_new(NULL);
700         gl_item *current = NULL;
701         int selected_item_cnt = 0;
702         Eina_List *l = NULL;
703
704         EINA_LIST_FOREACH(ad->selectedinfo.medias_elist, l, current) {
705                 if (current == NULL || current->item == NULL) {
706                         if (selected_path_list) {
707                                 g_string_free(selected_path_list, true);
708                                 selected_path_list = NULL;
709                         }
710                         return -1;
711                 }
712                 selected_item_cnt++;
713                 g_string_append(selected_path_list, current->item->file_url);
714                 g_string_append_c(selected_path_list, sep_c);
715
716         }
717         gl_dbg("Selected items count: %d.", selected_item_cnt);
718         if (sel_cnt)
719                 *sel_cnt = selected_item_cnt;
720         int len = strlen(selected_path_list->str);
721         g_string_truncate(selected_path_list, len - 1);
722         /**
723         * Frees the memory allocated for the GString.
724         * If free_segment is true it also frees the character data.
725         * If it's false, the caller gains ownership of the buffer
726         * and must free it after use with g_free().
727         */
728         *path_str = g_string_free(selected_path_list, false);
729         GL_CHECK_VAL(*path_str, -1);
730         gl_dbg("Total string:\n\n\t>>@@:> %s <:@@<<\n", *path_str);
731         return 0;
732 }
733
734 int
735 gl_make_dir(const char *dir_full_path)
736 {
737         GL_CHECK_VAL(dir_full_path, -1);
738
739         return mkdir(dir_full_path, GL_CREATE_DIR_MASK_DEFAULT);
740 }
741
742 int
743 gl_make_new_album(const char *name)
744 {
745         gl_dbg("");
746         char path[GL_DIR_PATH_LEN_MAX] = { 0, };
747         char dir_path[GL_DIR_PATH_LEN_MAX] = { 0, };
748
749         if (gl_get_default_images_path(dir_path) != 0)
750         {
751                 gl_dbg("FAIL to get dir path");
752                 return -1;
753         }
754
755         snprintf(path, GL_DIR_PATH_LEN_MAX, "%s/%s", dir_path, name);
756         path[strlen(path)] = '\0';
757         gl_dbg("Making %s directory", path);
758
759         if (ecore_file_dir_is_empty(path) == -1)        // new folder doesn't exist
760         {
761                 if (ecore_file_dir_is_empty(dir_path) == -1)    // default images folder doesn't exist
762                 {
763                         gl_dbgE("[Error] Default images path[%s] doesn't exist. Create it...");
764                         gl_make_dir(dir_path);
765                 }
766
767                 return gl_make_dir(path);
768         }
769         else
770         {
771                 gl_dbg("new folder already exists, no need to make!");
772                 return 0;
773         }
774 }
775
776 int
777 gl_move_media_item(gl_item * gitem, char *new_dir_name, bool is_full_path, int *popup_op)
778 {
779         gl_dbg("Move media item START>>>");
780         char new_path[GL_FILE_PATH_LEN_MAX] = { 0, };
781         char ext[GL_FILE_EXT_LEN_MAX] = { 0, };
782         char new_path_noext[GL_FILE_PATH_LEN_MAX] = { 0, };
783         char dir_path[GL_DIR_PATH_LEN_MAX] = { 0, };
784         if (gitem == NULL || gitem->item == NULL || gitem->item->uuid == NULL ||
785             popup_op == NULL)
786         {
787                 gl_dbg("gitem == NULL || gitem->item == NULL");
788                 return -1;
789         }
790
791         *popup_op = GL_POPUP_OP_NONE;
792
793         if (is_full_path)
794         {
795                 if (!gitem->item->file_url ||
796                         !strlen(gitem->item->file_url) ||
797                         !gitem->item->display_name)
798                 {
799                         gl_dbg("file url or name is error.");
800                         return -1;
801                 }
802                 snprintf(new_path, sizeof(new_path), "%s/%s",
803                         new_dir_name, (char *)(gitem->item->display_name));
804                 gl_dbg("New path : %s", new_path);
805
806                 if (!g_strcmp0(new_path, gitem->item->file_url))        //do not need to move. ("All" album case)
807                 {
808                         //create popup in pipe callback
809                         *popup_op = GL_POPUP_OP_SAME_ALBUM;
810                         gl_dbg("File already in destination, do not need to move, just return...");
811                         /*
812                            snprintf(msg, sizeof(msg), "Cann't move %s to the same album!", gitem->item->display_name);
813                            gl_popup_create_popup(ad, GL_POPUP_NOBUT_MOV_DEL, msg);
814                          */
815
816                         return -1;
817                 }
818                 else if (ecore_file_exists(new_path))   // return true if file exists, rename new file.
819                 {
820                         _gl_get_file_ext(new_path, ext, new_path_noext);
821                         char *final_path = NULL;
822                         final_path = __gl_get_unique_full_path(new_path_noext, ext);
823                         if (final_path == NULL)
824                                 return -1;
825                         gl_dbg("Created unique path: %s", final_path);
826                         memset(new_path, 0x00, GL_FILE_PATH_LEN_MAX);
827                         g_strlcpy(new_path, final_path, GL_FILE_PATH_LEN_MAX);
828                         free(final_path);
829                         final_path = NULL;
830                         //create popup in pipe callback
831                         *popup_op = GL_POPUP_OP_DUPLICATED_NAME;
832                         /*memset(msg, 0x00, GL_FILE_PATH_LEN_MAX);
833                            snprintf(msg, sizeof(msg), "%s is duplicated, rename it!", gitem->item->display_name);
834                            gl_popup_create_popup(ad, GL_POPUP_NOBUT_MOV_DEL, msg);
835                          */
836                 }
837         }
838         else
839         {
840                 if (gl_get_default_images_path(dir_path) != 0)
841                 {
842                         gl_dbg("FAIL to get dir path!");
843                         return -1;
844                 }
845                 snprintf(new_path, GL_FILE_PATH_LEN_MAX, "%s/%s/%s",
846                                 dir_path, new_dir_name, (char *)(gitem->item->display_name));
847         }
848
849         new_path[strlen(new_path)] = '\0';
850
851         // stop using "rename" when moving from mmc to phone for correct db update.
852         if (!__gl_file_mv(gitem, gitem->item->file_url, new_path, gitem->item->type))
853         {
854                 gl_dbg("Move media item OVER<<<");
855                 return -1;
856         }
857         else
858         {
859                 gl_dbg("Move media item OVER<<<");
860                 return 0;
861         }
862 }
863
864 /**
865 * Check if there is any media in Gallery.
866 *
867 * False returned if none medias exist, other return True.
868 */
869 bool gl_check_gallery_empty(void* data)
870 {
871         GL_CHECK_FALSE(data);
872         gl_appdata *ad = (gl_appdata *)data;
873
874         if (ad->albuminfo.cluster_list == NULL) {
875                 gl_dbgE("ad->albuminfo.cluster_list is empty!");
876                 return true;
877         }
878
879         Eina_List *clist = ad->albuminfo.cluster_list->clist;
880         if (clist == NULL) {
881                 gl_dbgW("Albums list is invalid!");
882                 return true;
883         }
884
885         int len = eina_list_count(clist);
886         if (len == 0) {
887                 gl_dbgW("Albums list is empty!");
888                 return true;
889         }
890
891         return false;
892 }
893
894 bool gl_is_image_valid(void *data, char *filepath)
895 {
896         GL_CHECK_FALSE(data);
897         gl_appdata *ad = (gl_appdata *)data;
898         GL_CHECK_FALSE(filepath);
899
900         Evas_Object *image = NULL;
901         int width = 0;
902         int height = 0;
903         Evas *evas = NULL;
904
905         evas = evas_object_evas_get(ad->maininfo.win);
906         GL_CHECK_FALSE(evas);
907
908         image = evas_object_image_add(evas);
909         GL_CHECK_FALSE(image);
910
911         evas_object_image_filled_set(image, 0);
912         evas_object_image_load_scale_down_set(image, 0);
913         evas_object_image_file_set(image, filepath, NULL);
914         evas_object_image_size_get(image, &width, &height);
915         if(image) {
916                 evas_object_del(image);
917                 image = NULL;
918         }
919
920         if (width <= 0 || height <= 0) {
921                 gl_dbg("Cannot load file : %s", filepath);
922                 return false;
923         }
924
925         return true;
926 }
927
928 bool
929 gl_is_rotation_locked(void)
930 {
931         gl_dbg_launch("    gl_is_rotation_locked:start");
932         int lock = -1;
933
934         if (!vconf_get_bool(VCONFKEY_SETAPPL_ROTATE_LOCK_BOOL, &lock))
935         {
936                 gl_dbg("Rotation locked state[%d].", lock);
937                 gl_dbg_launch("    gl_is_rotation_locked:end");
938                 return lock;
939         }
940         else
941         {
942                 gl_dbgE("Get rotation lock state failed!");
943                 gl_dbg_launch("    gl_is_rotation_locked:end");
944                 return false;
945         }
946 }
947
948 /*
949 * Check MMC state(Inserted/Removed) for Move/Delete
950 */
951 int
952 gl_check_mmc_state(void *data, char *dest_folder)
953 {
954         GL_CHECK_VAL(data, -1);
955         gl_appdata *ad = (gl_appdata *)data;
956
957         /* MMC hasn't been inserted */
958         if (ad->maininfo.mmc_state == GL_MMC_STATE_REMOVED)
959                 return 0;
960
961         int on_mmc = -1;
962
963         /* Move files to MMC album */
964         if (dest_folder) {
965                 on_mmc = strncmp(GL_ROOT_PATH_MMC, dest_folder,
966                                  strlen(GL_ROOT_PATH_MMC));
967                 if (on_mmc == 0)
968                         goto ON_MMC;
969         }
970
971         gl_cluster *cur_album = ad->albuminfo.current_album;
972         char src_folder_path[GL_DIR_PATH_LEN_MAX] = { 0, };
973         GL_CHECK_VAL(cur_album, -1);
974         GL_CHECK_VAL(cur_album->cluster, -1);
975         /* Move files from MMC album */
976         GL_CHECK_VAL(cur_album->cluster->uuid, -1);
977         g_strlcpy(src_folder_path, cur_album->cluster->path,
978                   GL_DIR_PATH_LEN_MAX);
979         on_mmc = strncmp(GL_ROOT_PATH_MMC, src_folder_path,
980                          strlen(GL_ROOT_PATH_MMC));
981         /* Check MMC files selected in album [All albums] */
982         if (on_mmc == 0) {
983                 goto ON_MMC;
984         } else if (!g_strcmp0(cur_album->cluster->uuid, GL_ALBUM_ALL_ID)) {
985                 gl_dbg("In album [All albums].");
986                 if (_gl_check_mmc_file_selected(ad))
987                         goto ON_MMC;
988         }
989
990         return 0;
991
992  ON_MMC:
993         gl_dbgW("Operate medias on MMC!");
994         ad->maininfo.mmc_state = GL_MMC_STATE_ADDED_MOVING;
995         return 0;
996 }
997
998 int gl_reg_db_update_noti(void *data)
999 {
1000         GL_CHECK_VAL(data, -1);
1001         gl_appdata *ad = (gl_appdata *)data;
1002         int error_code = -1;
1003         int mmc_state = -1;
1004
1005         vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_state);
1006         /* Save the init status of MMC */
1007         if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED)
1008         {
1009                 gl_dbg("###### :::::: MMC loaded! :::::: ######");
1010                 ad->maininfo.mmc_state = GL_MMC_STATE_ADDED;
1011         }
1012         else if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED ||
1013                  mmc_state ==  VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED)
1014         {
1015                 gl_dbg("###### :::::: MMC removed! :::::: ######");
1016                 ad->maininfo.mmc_state = GL_MMC_STATE_REMOVED;
1017         }
1018
1019         gl_dbg("Enable the noti handle for DB update status!");
1020         /* Set DB update status callback */
1021         error_code = vconf_notify_key_changed(VCONFKEY_FILEMANAGER_DB_STATUS,
1022                                               _gl_db_update_noti_cb, ad);
1023         if (error_code == -1) {
1024                 gl_dbgE("vconf_notify_key_changed for DB_STATUS failed!");
1025                 return -1;
1026         }
1027
1028         return 0;
1029 }
1030
1031 int gl_dereg_db_update_noti(void)
1032 {
1033         int error_code = -1;
1034
1035         gl_dbg("Disable the noti handle for DB update status!");
1036         error_code = vconf_ignore_key_changed(VCONFKEY_FILEMANAGER_DB_STATUS,
1037                                               _gl_db_update_noti_cb);
1038         if (error_code == -1) {
1039                 gl_dbgE("vconf_ignore_key_changed for DB_STATUS failed!");
1040                 return -1;
1041         }
1042
1043         return 0;
1044 }
1045
1046 /*
1047 * Get view mode of app
1048 */
1049 int gl_get_view_mode(void *data)
1050 {
1051         GL_CHECK_VAL(data, GL_VIEW_NONE);
1052         gl_appdata *ad = (gl_appdata *)data;
1053         return ad->maininfo.view_mode;
1054 }
1055
1056 /*
1057 * Set view mode of app
1058 */
1059 int gl_set_view_mode(void *data, int mode)
1060 {
1061         GL_CHECK_VAL(data, -1);
1062         gl_appdata *ad = (gl_appdata *)data;
1063
1064         ad->maininfo.view_mode = mode;
1065
1066         return 0;
1067 }
1068
1069 int gl_del_invalid_widgets(void *data, int invalid_m)
1070 {
1071         GL_CHECK_VAL(data, -1);
1072         gl_appdata *ad = (gl_appdata *)data;
1073         gl_dbg("");
1074         if (ad->popupinfo.popup) {
1075                 /* Remove popup */
1076                 evas_object_del(ad->popupinfo.popup);
1077                 ad->popupinfo.popup = NULL;
1078         } else if (ad->uginfo.ug_called_by_me) {
1079                 /* Destroy UG */
1080                 gl_dbg("Destroy UG!");
1081                 if (ad->uginfo.ug_called_by_me) {
1082                         ug_destroy(ad->uginfo.ug_called_by_me);
1083                         ad->uginfo.ug_called_by_me = NULL;
1084                         ad->uginfo.ug_type = -1;
1085                 }
1086                 if (ad->uginfo.gallery_ug_called_by_me) {
1087                         ug_destroy(ad->uginfo.gallery_ug_called_by_me);
1088                         ad->uginfo.gallery_ug_called_by_me = NULL;
1089                 }
1090         }
1091
1092         switch (invalid_m) {
1093         case GL_INVALID_RENAME_ALBUM:
1094                 /* gl_ui_edit_cancel pop navigationbar */
1095                 gl_dbgW("Destroy Rename album view!");
1096                 elm_naviframe_item_pop(ad->maininfo.naviframe);
1097                 gl_set_view_mode(ad, GL_VIEW_ALBUMS_EDIT);
1098                 _gl_editfield_destroy_imf(ad);
1099                 break;
1100         case GL_INVALID_NEW_ENTRY:
1101         case GL_INVALID_NEW_ENTRY_NOC:
1102                 if (ad->entryinfo.entry_mode == GL_ENTRY_NEW_ALBUM) {
1103                         gl_dbg("Destroy New album view!");
1104                         if (invalid_m == GL_INVALID_NEW_ENTRY) {
1105                                 gl_dbg("Pop to nf_it_edit");
1106                                 elm_naviframe_item_pop_to(ad->gridinfo.nf_it_edit);
1107                         }
1108                         _gl_editfield_destroy_imf(ad);
1109                         Evas_Object *edit_ly = NULL;
1110                         edit_ly = ad->gridinfo.edit_layout;
1111                         const char *sig = NULL;
1112                         sig = "elm,swallow_view,state,edit";
1113                         edje_object_signal_emit(_EDJ(edit_ly), sig, "elm");
1114                 }
1115                 break;
1116         default:
1117                 ad->entryinfo.entry_mode = GL_ENTRY_NONE;
1118                 break;
1119         }
1120         return 0;
1121 }
1122
1123 int gl_del_medias(void *data)
1124 {
1125         gl_dbg("");
1126         GL_CHECK_VAL(data, -1);
1127         gl_appdata *ad = (gl_appdata *)data;
1128         /* Get all selected medias count */
1129         int cnt = _gl_data_selected_list_count(ad);
1130         /* Check MMC state for cancel operation */
1131         gl_check_mmc_state(ad, NULL);
1132         gl_dbg("MMC state: %d.", ad->maininfo.mmc_state);
1133         _gl_use_thread_operate_medias(ad, GL_STR_DELETING, cnt,
1134                                       GL_MEDIA_OP_DELETE);
1135
1136         return 0;
1137 }
1138
1139 /* 'Delete medias' is available in Albums view */
1140 int gl_del_selected(void *data)
1141 {
1142         GL_CHECK_VAL(data, -1);
1143         gl_appdata *ad = (gl_appdata *)data;
1144         /* Get all selected medias count */
1145         int cnt = _gl_data_selected_list_count(ad);
1146         gl_item *gitem = NULL;
1147         int i = 0;
1148         int popup_op = GL_POPUP_OP_NONE;
1149
1150         /* Removed media from selected_media_elist */
1151         for (i = 1; i <= cnt; i++) {
1152                 _gl_data_get_item_by_index(ad, i, true, &gitem);
1153                 if (gitem != NULL && gitem->item != NULL)
1154                         _gl_data_remove_item(gitem);
1155                 else
1156                         gl_dbgE("Invalid item!");
1157
1158                 gl_dbg("Write pipe, make progressbar updated!");
1159                 gl_thread_write_pipe(ad, i, popup_op);
1160                 gitem = NULL;
1161         }
1162
1163         return 0;
1164 }
1165
1166 int _gl_update_operation_view(void *data, const char *noti_str)
1167 {
1168         GL_CHECK_VAL(data, -1);
1169         gl_appdata *ad = (gl_appdata *)data;
1170         gl_dbg("String: %s", noti_str);
1171
1172         if (ad->maininfo.medias_cnt > 0) {
1173                 /* Deleting process done, change to normal view */
1174                 _gl_ui_pop_to_thumb(ad);
1175
1176                 if (gl_get_view_mode(ad) == GL_VIEW_THUMBS)
1177                         _gl_nocontents_show(ad);
1178
1179                 /* Add notification */
1180                 _gl_notify_create_notiinfo(ad, ad->gridinfo.layout,
1181                                            noti_str);
1182         } else {
1183                 gl_dbgW("Empty album, change to Albums view!");
1184                 gl_albums_comeback_from_view(ad);
1185                 elm_naviframe_item_pop_to(ad->albuminfo.nf_it);
1186
1187                 if (gl_check_gallery_empty(ad)) {
1188                         _gl_ctrl_disable_toolbar_item(ad, true, GL_NAVI_ALBUMS,
1189                                                       true);
1190                 } else if (ad->albuminfo.cluster_list->edit_cnt == 0) {
1191                         _gl_ctrl_disable_toolbar_item(ad, true, GL_NAVI_ALBUMS,
1192                                                       true);
1193                 }
1194
1195                 _gl_notify_destroy_selinfo(ad);
1196                 /* Add notification */
1197                 _gl_notify_create_notiinfo(ad, ad->albuminfo.layout,
1198                                            noti_str);
1199         }
1200         return 0;
1201 }
1202
1203 /* Update view after deleting process done */
1204 int gl_update_del_view(void *data)
1205 {
1206         GL_CHECK_VAL(data, -1);
1207         gl_appdata *ad = (gl_appdata *)data;
1208         _gl_data_selected_list_finalize(ad);
1209
1210         int view_mode = gl_get_view_mode(ad);
1211         gl_dbg("view_mode: %d.", view_mode);
1212         gl_refresh_albums_list(ad);
1213
1214         _gl_update_operation_view(ad, GL_STR_DELETED);
1215
1216         return 0;
1217 }
1218
1219 /* Delete video file */
1220 int _gl_del_video(void *data)
1221 {
1222         GL_CHECK_VAL(data, -1);
1223         gl_item *gitem = (gl_item *) data;
1224         GL_CHECK_VAL(gitem->ad, -1);
1225         gl_appdata *ad = (gl_appdata *)gitem->ad;
1226
1227         /* Mode item */
1228         Elm_Object_Item *it = NULL;
1229         it = (Elm_Object_Item *)elm_genlist_decorated_item_get(ad->listinfo.videos_view);
1230         /* Finish genlist sweep*/
1231         if (it) {
1232                 elm_genlist_item_decorate_mode_set(it, "slide", EINA_FALSE);
1233                 elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DEFAULT);
1234         }
1235         if (ad->listinfo.sweep_file_path) {
1236                 free(ad->listinfo.sweep_file_path);
1237                 ad->listinfo.sweep_file_path = NULL;
1238         }
1239
1240         /* Destroy it and remove its record from DB */
1241         _gl_data_remove_item(gitem);
1242
1243         int view_mode = gl_get_view_mode(ad);
1244         gl_dbg("view_mode: %d.", view_mode);
1245         gl_refresh_albums_list(ad);
1246
1247         if (ad->maininfo.medias_cnt > 0) {
1248                 gl_list_update_view(ad);
1249                 /* Add notification */
1250                 _gl_notify_create_notiinfo(ad, ad->gridinfo.layout,
1251                                            GL_STR_DELETED);
1252         } else {
1253                 gl_dbgW("Empty album, change to Albums view!");
1254                 gl_albums_comeback_from_view(ad);
1255                 elm_naviframe_item_pop_to(ad->albuminfo.nf_it);
1256                 if (gl_check_gallery_empty(ad)) {
1257                         _gl_ctrl_disable_toolbar_item(ad, true, GL_NAVI_ALBUMS,
1258                                                       true);
1259                 } else if (ad->albuminfo.cluster_list->edit_cnt == 0) {
1260                         _gl_ctrl_disable_toolbar_item(ad, true, GL_NAVI_ALBUMS,
1261                                                       true);
1262                 }
1263
1264                 /* Add notification */
1265                 _gl_notify_create_notiinfo(ad, ad->albuminfo.layout,
1266                                            GL_STR_DELETED);
1267         }
1268
1269         return 0;
1270 }
1271
1272 int gl_remove_album(void *data, gl_cluster * album_item)
1273 {
1274         GL_CHECK_VAL(data, -1);
1275         gl_appdata *ad = (gl_appdata *)data;
1276         int res = -1;
1277         char dir_path[GL_DIR_PATH_LEN_MAX] = { 0, };
1278
1279         if (album_item == NULL || album_item->cluster == NULL ||
1280             album_item->cluster->uuid == NULL) {
1281                 gl_dbgE("Invalid album!");
1282                 return -1;
1283         }
1284
1285         gl_dbg("Remove album: %s, id=%s", album_item->cluster->display_name,
1286                album_item->cluster->uuid);
1287
1288         /* get folder path of album */
1289         if (album_item->cluster->path &&
1290             strlen(album_item->cluster->path) > 0) {
1291                 gl_dbg("Folder fullpath: %s", dir_path);
1292                 g_strlcpy(dir_path, album_item->cluster->path,
1293                           GL_DIR_PATH_LEN_MAX);
1294         } else {
1295                 gl_dbgE("Get folder fullpath failed[%d]!", res);
1296                 return -1;
1297         }
1298         /* remove all items in the album from file system and db */
1299         _gl_data_get_item_list(ad, album_item, GL_GET_ALL_RECORDS,
1300                                GL_GET_ALL_RECORDS);
1301
1302         gl_item *gitem = NULL;
1303         int i = 0;
1304         /* Get all medias count of current album */
1305         int cnt = ad->maininfo.medias_cnt;
1306         gl_dbg("cnt: %d", cnt);
1307         /* Remove files, _gl_local_data_delete_album would delete medias record */
1308         for (i = cnt; i >= 1; i--) {
1309                 _gl_data_get_item_by_index(ad, i, false, &gitem);
1310                 if (gitem && gitem->item && gitem->item->file_url) {
1311                         if (!ecore_file_unlink(gitem->item->file_url))
1312                                 gl_dbgE("ecore_file_unlink failed!");
1313                 }
1314         }
1315
1316         /* remove album from db*/
1317         res = _gl_local_data_delete_album(album_item->cluster->uuid);
1318         if (res != 0)
1319                 gl_dbgE("_gl_local_data_delete_album failed[%d]!", res);
1320
1321         /* remove album from file system */
1322         if (ecore_file_rmdir(dir_path) == EINA_FALSE) {
1323                 gl_dbg("ecore_file_rmdir failed!");
1324                 return -1;
1325         }
1326
1327         return 0;
1328 }
1329
1330 int gl_del_albums(void *data)
1331 {
1332         GL_CHECK_VAL(data, -1);
1333         gl_appdata *ad = (gl_appdata *)data;
1334         gl_cluster *album_item = NULL;
1335         int cnt = _gl_data_get_albums_selected_cnt(ad);
1336         int i = 0;
1337         int ret = -1;
1338         gl_dbg("");
1339         // delete albums
1340
1341         Eina_List *selected_list = ad->albuminfo.selected_albums_elist;
1342         if ((selected_list == NULL) || (eina_list_count(selected_list) == 0))
1343         {
1344                 gl_dbg("zero length, return!");
1345                 return -1;
1346         }
1347         else
1348         {
1349                 gl_dbg("cnt= %d, list length=%d", cnt, eina_list_count(selected_list));
1350         }
1351         for (i = 0; i < cnt; i++)
1352         {
1353                 album_item = eina_list_nth(selected_list, i);
1354
1355                 if (album_item && album_item->cluster &&
1356                     album_item->cluster->uuid) {
1357                         gl_dbg("Delete album: %s, id=%s",
1358                                album_item->cluster->display_name,
1359                                album_item->cluster->uuid);
1360
1361                         ret = gl_remove_album(ad, album_item);
1362                         if (ret < 0)
1363                         {
1364                                 gl_dbg("gl_remove_album failed, error=%d", ret);
1365                                 //return -1;
1366                         }
1367                 }
1368         }
1369
1370         // update the albums view
1371         gl_ui_edit_cancel(ad);
1372
1373         //add notification
1374         _gl_notify_create_notiinfo(ad, ad->albuminfo.layout,
1375                                    GL_STR_DELETED);
1376         return 0;
1377 }
1378
1379 int gl_refresh_albums_list(void *data)
1380 {
1381 #ifdef _USE_ROTATE_BG
1382         return __gl_refresh_albums_list(data, false);
1383 #else
1384         GL_CHECK_VAL(data, -1);
1385         gl_appdata *ad = (gl_appdata *)data;
1386         gl_cluster *old_current_album = ad->albuminfo.current_album;
1387         char cluster_id[GL_MTYPE_ITEN_ID_LEN_MAX] = { 0, };
1388         gl_cluster *current = NULL;
1389         bool b_get_cur_album = false;
1390         /* Albums list would be update, reset flag */
1391         ad->albuminfo.update_albums_list = false;
1392
1393         /* Save cluster ID to set new current_album from new albums list */
1394         if (old_current_album && old_current_album->cluster &&
1395             old_current_album->cluster->uuid) {
1396                 g_strlcpy(cluster_id, old_current_album->cluster->uuid,
1397                           GL_MTYPE_ITEN_ID_LEN_MAX);
1398                 b_get_cur_album = true;
1399         } else {
1400                 gl_dbg("None album selected, current album is unavailable.");
1401         }
1402
1403         _gl_data_get_cluster_list(ad);
1404         /* need to reset current album */
1405         ad->albuminfo.current_album = NULL;
1406
1407         if (b_get_cur_album) {
1408                 _gl_data_get_cluster_by_id(ad, cluster_id, &current);
1409                 if(current && current->cluster) {
1410                         ad->albuminfo.current_album = current;
1411                         gl_dbg("Reset current album: %s",
1412                                current->cluster->display_name);
1413                         _gl_data_update_item_list(ad);
1414                         return 0;
1415                 } else {
1416                         /* Clear items list if current album doesn't exist */
1417                         if (ad->selectedinfo.medias_elist)
1418                                 _gl_data_selected_list_finalize(ad);
1419                         _gl_data_clear_default_item_list(ad);
1420                         ad->maininfo.medias_cnt = 0;
1421                 }
1422         }
1423
1424         return 0;
1425 #endif
1426 }
1427
1428 /**
1429 * Move files under root album [/opt/media or /opt/storage/sdcard] to a newly created album.
1430 * Used in 'Rename' album case.
1431 */
1432 int
1433 gl_move_root_album(void* data, gl_cluster* cur_album, char* dest_path)
1434 {
1435         GL_CHECK_VAL(data, -1);
1436         GL_CHECK_VAL(cur_album, -1);
1437         GL_CHECK_VAL(cur_album->cluster, -1);
1438         gl_appdata *ad = (gl_appdata *)data;
1439
1440         /* Get all medias of current album */
1441         _gl_data_get_item_list(ad, cur_album, GL_GET_ALL_RECORDS,
1442                                GL_GET_ALL_RECORDS);
1443
1444         Eina_List* tmp_elist = NULL;
1445         gl_item* gitem = NULL;
1446         int popup_op = GL_POPUP_OP_NONE;
1447         GL_CHECK_VAL(ad->maininfo.medias_elist, -1);
1448
1449         /* Move medias of album to dest folder */
1450         EINA_LIST_FOREACH(ad->maininfo.medias_elist, tmp_elist, gitem)
1451         {
1452                 if (gitem && gitem->item)
1453                 {
1454                         gl_dbg("Move [%s]", gitem->item->file_url);
1455                         if (gl_move_media_item(gitem, dest_path, true, &popup_op) != 0)
1456                         {
1457                                 gl_dbgW("Failed to move this item");
1458                         }
1459
1460                         gitem = NULL;
1461                 }
1462                 else
1463                 {
1464                         gl_dbgE("Invalid item!");
1465                         _gl_data_clear_default_item_list(ad);
1466                         return -1;
1467                 }
1468         }
1469
1470         /* Free item list */
1471         _gl_data_clear_default_item_list(ad);
1472
1473     return 0;
1474 }
1475
1476 /* 'Move medias' is only available in tab Albums */
1477 int gl_move_selected(void *data)
1478 {
1479         GL_CHECK_VAL(data, -1);
1480         gl_appdata *ad = (gl_appdata *)data;
1481         int i = 0;
1482         /* Get selected medias count */
1483         int cnt = _gl_data_selected_list_count(ad);
1484         gl_item *gitem = NULL;
1485         int popup_op = GL_POPUP_OP_NONE;
1486
1487         for (i = 1; i <= cnt; i++)
1488         {
1489                 _gl_data_get_item_by_index(ad, i, true, &gitem);
1490                 if (gitem && gitem->item)
1491                 {
1492                         gl_dbg("Selected [%s]", gitem->item->file_url);
1493                         if (gl_move_media_item(gitem, ad->albuminfo.dest_folder, true, &popup_op) != 0)
1494                         {
1495                                 gl_dbg("Failed to move this item");
1496                         }
1497                         gl_dbg("File Moved:::::::%d/%d-->try to update progressbar", i, cnt);
1498                 }
1499                 else
1500                 {
1501                         gl_dbg("Invalid item!");
1502                 }
1503
1504                 gl_dbg("Write pipe, make progressbar updated!");
1505                 gl_thread_write_pipe(ad, i, popup_op);
1506
1507                 popup_op = GL_POPUP_OP_NONE;
1508         }
1509
1510         return 0;
1511 }
1512
1513 int gl_move_to_album(void *data)
1514 {
1515         GL_CHECK_VAL(data, -1);
1516         gl_appdata *ad = (gl_appdata *)data;
1517         char folder_fullpath[GL_DIR_PATH_LEN_MAX] = { 0, };
1518         char default_path[GL_DIR_PATH_LEN_MAX] = { 0, };
1519         gl_cluster *cur_album = ad->albuminfo.current_album;
1520         int cnt = _gl_data_selected_list_count(ad);
1521
1522         /**
1523          * 'move_album_id == NULL' is new album case,
1524          * other move/save to some existed album.
1525          */
1526         if (ad->albuminfo.path == NULL) {
1527                 gl_dbg("---Popup list item: New album---");
1528                 ad->albuminfo.move_new_album = true;
1529
1530                 if (gl_make_new_album(ad->albuminfo.new_album_name) != 0)
1531                 {
1532                         gl_popup_create_popup(ad, GL_POPUP_NOBUT,
1533                                         GL_STR_SAME_NAME_ALREADY_IN_USE);
1534                         gl_dbgE("Failed to make a new directory!");
1535                         gl_ui_update_select_widgets(ad);
1536                         return -1;
1537                 }
1538                 if (gl_get_default_images_path(default_path) != 0)
1539                 {
1540                         gl_dbgE("Failed to get default images path!");
1541                         gl_ui_update_select_widgets(ad);
1542                         return -1;
1543                 }
1544                 snprintf(folder_fullpath, GL_DIR_PATH_LEN_MAX, "%s/%s",
1545                         default_path, ad->albuminfo.new_album_name);
1546         } else {
1547                 ad->albuminfo.move_new_album = false;
1548                 g_strlcpy(folder_fullpath, ad->albuminfo.path,
1549                           GL_DIR_PATH_LEN_MAX);
1550                 free(ad->albuminfo.path);
1551                 ad->albuminfo.path = NULL;
1552         }
1553
1554         if (cur_album == NULL || cur_album->cluster == NULL)
1555         {
1556                 gl_dbgE("[Error] Current album is NULL!");
1557                 gl_ui_update_select_widgets(ad);
1558                 return -1;
1559         }
1560
1561         memset(ad->albuminfo.dest_folder, 0x00, GL_DIR_PATH_LEN_MAX);
1562         g_strlcpy(ad->albuminfo.dest_folder, folder_fullpath, GL_DIR_PATH_LEN_MAX);
1563         /* Check MMC state for cancel operation */
1564         gl_check_mmc_state(ad, folder_fullpath);
1565         gl_dbg("MMC state: %d.", ad->maininfo.mmc_state);
1566         _gl_use_thread_operate_medias(ad, GL_STR_MOVING, cnt,
1567                                       GL_MEDIA_OP_MOVE);
1568         return 0;
1569 }
1570
1571 /* Update view after moving process done */
1572 int gl_update_move_view(void *data)
1573 {
1574         GL_CHECK_VAL(data, -1);
1575         gl_appdata *ad = (gl_appdata *)data;
1576         int view_mode = gl_get_view_mode(ad);
1577         gl_dbg("view_mode: %d", view_mode);
1578         _gl_data_selected_list_finalize(ad);
1579         _gl_notify_destroy_selinfo(ad);
1580         /* Update albums list and items list */
1581         gl_refresh_albums_list(ad);
1582
1583         _gl_update_operation_view(ad, GL_STR_MOVED);
1584
1585         return 0;
1586 }
1587
1588 /* Share album's content */
1589 int _gl_share_select_album(void *data)
1590 {
1591         GL_CHECK_VAL(data, -1);
1592         gl_appdata *ad = (gl_appdata *)data;
1593         char *label = ad->popupinfo.popup_item_label;
1594         gl_dbg("label : %s ", label);
1595
1596         int cnt = _gl_data_get_albums_selected_cnt(ad);
1597         gl_dbg("Selected album(s) count: %d.", cnt);
1598         if (cnt < 1) {
1599                 gl_dbgE("None album selected!");
1600                 gl_popup_create_popup(ad, GL_POPUP_NOBUT,
1601                                       GL_STR_NO_ALBUMS_SELECTED);
1602                 return -1;
1603         }
1604         if (_gl_data_is_albums_selected_empty(ad)) {
1605                 gl_dbgE("None thumb selected!");
1606                 gl_popup_create_popup(ad, GL_POPUP_NOBUT,
1607                                       GL_STR_NO_FILES_SELECTED);
1608                 return -1;
1609         }
1610
1611         if (!g_strcmp0(label, GL_SHARE_MESSAGE)) {
1612                 gl_ext_load_ug(ad, GL_UG_MSG);
1613         } else if (!g_strcmp0(label, GL_SHARE_EMAIL)) {
1614                 gl_ext_load_ug(ad, GL_UG_EMAIL);
1615         } else if (!g_strcmp0(label, GL_SHARE_BLUETOOTH))       {
1616                 gl_ext_load_ug(ad, GL_UG_BT);
1617         } else {
1618                 gl_dbgE("Wrong UG name!");
1619                 return -1;
1620         }
1621         return 0;
1622 }
1623
1624 int gl_share_select_item(void *data)
1625 {
1626         GL_CHECK_VAL(data, -1);
1627         gl_appdata *ad = (gl_appdata *)data;
1628         char *label = ad->popupinfo.popup_item_label;
1629         gl_dbg("label : %s ", label);
1630         int cnt = 0;
1631
1632         int view_mode = gl_get_view_mode(ad);
1633         if (view_mode == GL_VIEW_VIDEOLIST)
1634                 cnt = 1;
1635         else
1636                 cnt = _gl_data_selected_list_count(ad);
1637
1638         gl_dbg("Selected item(s) count: %d.", cnt);
1639         if (cnt < 1) {
1640                 gl_dbgE("None items selected!");
1641                 gl_popup_create_popup(ad, GL_POPUP_NOBUT,
1642                                       GL_STR_NO_FILES_SELECTED);
1643                 return -1;
1644         }
1645
1646         if (!g_strcmp0(label, GL_SHARE_MESSAGE)) {
1647                 gl_ext_load_ug(ad, GL_UG_MSG);
1648         } else if (!g_strcmp0(label, GL_SHARE_EMAIL)) {
1649                 gl_ext_load_ug(ad, GL_UG_EMAIL);
1650         } else if (!g_strcmp0(label, GL_SHARE_BLUETOOTH)) {
1651                 gl_ext_load_ug(ad, GL_UG_BT);
1652         }
1653 #ifdef _USE_WIFI
1654         else if (!g_strcmp0(label, GL_SHARE_WIFI)) {
1655                 gl_ext_load_ug(ad, GL_UG_WIFI);
1656         }
1657 #endif
1658         else {
1659                 gl_dbgE("Wrong UG name!");
1660                 return -1;
1661         }
1662
1663         return 0;
1664 }
1665
1666 #ifdef _USE_ROTATE_BG
1667
1668 int _gl_delay(double sec)
1669 {
1670         gl_dbg("Start");
1671         struct timeval tv;
1672         unsigned int start_t = 0;
1673         unsigned int end_t = 0;
1674         unsigned int delay_t = (unsigned int)(sec * GL_TIME_USEC_PER_SEC);
1675
1676         gettimeofday(&tv, NULL);
1677         start_t = tv.tv_sec * GL_TIME_USEC_PER_SEC + tv.tv_usec;
1678
1679         for(end_t = start_t; end_t - start_t < delay_t;) {
1680                 gettimeofday(&tv, NULL);
1681                 end_t = tv.tv_sec * GL_TIME_USEC_PER_SEC + tv.tv_usec;
1682         }
1683
1684         gl_dbg("End");
1685         return 0;
1686 }
1687
1688 int _gl_rotate_images(void *data, bool b_left)
1689 {
1690         gl_dbg("");
1691         GL_CHECK_VAL(data, -1);
1692         gl_appdata *ad = (gl_appdata *)data;
1693         /* Get all selected medias count */
1694         int cnt = _gl_data_selected_list_count(ad);
1695         /* Check MMC state for cancel operation */
1696         gl_check_mmc_state(ad, NULL);
1697         gl_dbg("MMC state: %d.", ad->maininfo.mmc_state);
1698         /* Rotate left */
1699         int op_type = GL_MEDIA_OP_ROTATING_LEFT;
1700         /* Rotate right */
1701         if (!b_left)
1702                 op_type = GL_MEDIA_OP_ROTATING_RIGHT;
1703         _gl_use_thread_operate_medias(ad, GL_STR_ROTATING, cnt, op_type);
1704
1705         return 0;
1706 }
1707
1708 int _gl_rotate_selected(void *data, int op_type)
1709 {
1710         GL_CHECK_VAL(data, -1);
1711         gl_appdata *ad = (gl_appdata *)data;
1712         /* Get all selected medias count */
1713         int cnt = _gl_data_selected_list_count(ad);
1714         gl_item *gitem = NULL;
1715         gl_media_s *new_item= NULL;
1716         int i = 0;
1717         int popup_op = GL_POPUP_OP_NONE;
1718         unsigned int orient = GL_ORIENTATION_ROT_ERR;
1719         unsigned int new_orient = GL_ORIENTATION_ROT_ERR;
1720         int ret = -1;
1721         bool b_left = false;
1722
1723         if (op_type == GL_MEDIA_OP_ROTATING_LEFT)
1724                 b_left = true;
1725
1726         gl_cluster *current_album = ad->albuminfo.current_album;
1727         /* Save cluster path to set new current_album from new albums list */
1728         if (current_album && current_album->cluster &&
1729             current_album->cluster->path &&
1730             strlen(current_album->cluster->path))
1731                 g_strlcpy(ad->albuminfo.dest_folder,
1732                           current_album->cluster->path, GL_DIR_PATH_LEN_MAX);
1733         else
1734                 gl_dbgE("Invalid folder path!");
1735
1736         /* Removed media from selected_media_elist */
1737         for (i = 1; i <= cnt; i++) {
1738                 _gl_data_get_item_by_index(ad, i, true, &gitem);
1739                 if (gitem != NULL && gitem->item != NULL &&
1740                     gitem->item->file_url &&
1741                     gitem->item->type == MEDIA_CONTENT_TYPE_IMAGE &&
1742                     GL_FILE_EXISTS(gitem->item->file_url)) {
1743                         /* Save orient in file */
1744                         ret = _gl_exif_get_orientation(gitem->item->file_url,
1745                                                        &orient);
1746                         if (ret == 0) {
1747                                 new_orient = _gl_exif_get_rotated_orientation(orient,
1748                                                                               b_left);
1749
1750                                 /* Delete old record */
1751                                 ret = _gl_data_delete_media(ad, gitem->item);
1752                                 if (ret != 0)
1753                                         gl_dbgE("media_info_delete_from_db failed[%d]!",
1754                                                 ret);
1755
1756                                 _gl_exif_set_orientation(gitem->item->file_url,
1757                                                          new_orient);
1758
1759                                 /* Add new record */
1760                                 ret = _gl_local_data_add_media(gitem->item->file_url,
1761                                                                NULL);
1762                                 if (ret != 0)
1763                                         gl_dbgE("Add media failed[%d]!", ret);
1764                                 /* Get handle via file_url */
1765                                 new_item = NULL;
1766                                 _gl_local_data_get_media_by_path(gitem->item->file_url,
1767                                                                  &new_item);
1768                         }
1769                 } else {
1770                         gl_dbgE("Invalid item!");
1771                 }
1772
1773                 /* Add some delay for last two images to wait for thumb updated */
1774                 if (i > cnt - 2)
1775                         _gl_delay(GL_ROTATE_DELAY);
1776
1777                 /* Check new thumb of last image */
1778                 if (i == cnt) {
1779                         gl_dbgW("Last image rotated, check thumb!");
1780                         /* Fetch thumbnail from media-service */
1781                         char *thumb = calloc(1, GL_FILE_PATH_LEN_MAX);
1782                         GL_CHECK_VAL(thumb, -1);
1783
1784                         if (new_item && new_item->media_h)
1785                                 _gl_local_data_get_thumb(new_item, &thumb);
1786                         gl_dbg("Thumbnail[%s]", thumb);
1787                         /* Add another delay if thumb is invalid */
1788                         if (!GL_FILE_EXISTS(thumb))
1789                                 _gl_delay(GL_ROTATE_DELAY);
1790                 }
1791
1792                 /* Free gl_media_s item */
1793                 if (new_item)
1794                         _gl_data_type_free_glitem((void **)(&new_item));
1795
1796                 gl_dbg("Write pipe, make progressbar updated!");
1797                 gl_thread_write_pipe(ad, i, popup_op);
1798                 gitem = NULL;
1799         }
1800
1801         return 0;
1802 }
1803
1804 /* Update view after deleting process done */
1805 int _gl_update_rotate_view(void *data)
1806 {
1807         GL_CHECK_VAL(data, -1);
1808         gl_appdata *ad = (gl_appdata *)data;
1809         _gl_data_selected_list_finalize(ad);
1810
1811         int view_mode = gl_get_view_mode(ad);
1812         gl_dbg("view_mode: %d.", view_mode);
1813         __gl_refresh_albums_list(ad, true);
1814
1815         memset(ad->albuminfo.dest_folder, 0x00, GL_DIR_PATH_LEN_MAX);
1816
1817         _gl_update_operation_view(ad, GL_STR_ROTATED);
1818
1819         return 0;
1820 }
1821
1822 #endif
1823
1824 Eina_Bool gl_update_view(void *data, int mode)
1825 {
1826         GL_CHECK_FALSE(data);
1827         gl_appdata *ad = (gl_appdata *)data;
1828         int view_mode = gl_get_view_mode(ad);
1829         gl_dbg("view_mode: %d", view_mode);
1830         if (mode == GL_UPDATE_VIEW_NONE) {
1831                 gl_dbg("Don't need to update");
1832                 return EINA_FALSE;
1833         }
1834
1835         if (view_mode == GL_VIEW_ALBUMS ||
1836                    view_mode == GL_VIEW_ALBUMS_EDIT ||
1837                    view_mode == GL_VIEW_ALBUMS_RENAME) {
1838                 /* Albums list should be updated first */
1839                 gl_albums_update_view(ad);
1840         } else if (view_mode == GL_VIEW_THUMBS ||
1841                    view_mode == GL_VIEW_VIDEOLIST) {
1842                 gl_cluster *cur_album = ad->albuminfo.current_album;
1843                 /* MMC removed, change to albums view if in mmc album */
1844                 if (mode == GL_UPDATE_VIEW_MMC_REMOVED && cur_album &&
1845                     cur_album->cluster &&
1846                     cur_album->cluster->type == GL_MMC) {
1847                         gl_dbgW("MMC removed, change to albums view!");
1848                         gl_pop_to_ctrlbar_ly(ad, true);
1849                         return EINA_TRUE;
1850                 }
1851
1852                 /* Albums list should be updated first */
1853                 _gl_update_thumb_items(ad, true);
1854         } else if (view_mode == GL_VIEW_THUMBS_EDIT ||
1855                    view_mode == GL_VIEW_VIDEOLIST_EDIT) {
1856                 /* Check thread operation case */
1857                 if (ad->pbarinfo.sync_pipe) {
1858                         gl_dbgW("Thread operation is in process!");
1859                         return EINA_TRUE;
1860                 }
1861
1862                 gl_cluster *cur_album = ad->albuminfo.current_album;
1863                 /* MMC removed, change to albums view if in mmc album */
1864                 if (mode == GL_UPDATE_VIEW_MMC_REMOVED && cur_album &&
1865                     cur_album->cluster &&
1866                     cur_album->cluster->type == GL_MMC) {
1867                         gl_dbgW("MMC removed, change to albums view!");
1868                         gl_pop_to_ctrlbar_ly(ad, true);
1869                         return EINA_TRUE;
1870                 }
1871
1872                 /* Albums list should be updated first */
1873                 _gl_update_thumb_items(ad, true);
1874                 return EINA_TRUE;
1875         }
1876         return EINA_TRUE;
1877 }
1878
1879 /**
1880 * Parse medias type and count of selected items,
1881 * and set different type for share items.
1882 */
1883 int gl_get_share_mode(void *data)
1884 {
1885         GL_CHECK_VAL(data, -1);
1886         gl_appdata *ad = (gl_appdata *)data;
1887         int share_mode = GL_SHARE_NONE;
1888         int image_cnt = 0;
1889         int video_cnt = 0;
1890         int sel_cnt = 0;
1891         int view_m = gl_get_view_mode(ad);
1892         if (view_m == GL_VIEW_ALBUMS_EDIT) {
1893                 GL_CHECK_VAL(ad->albuminfo.selected_albums_elist, -1);
1894                 gl_cluster *cur_album = NULL;
1895                 cur_album = eina_list_nth(ad->albuminfo.selected_albums_elist, 0);
1896                 GL_CHECK_VAL(cur_album, -1);
1897                 GL_CHECK_VAL(cur_album->cluster, -1);
1898                 sel_cnt = ad->selectedinfo.sel_cnt;
1899         } else if (view_m == GL_VIEW_VIDEOLIST) {
1900                 return GL_SHARE_VIDEO_ONE;
1901         } else if (view_m == GL_VIEW_ALBUMS) {
1902                 sel_cnt = ad->selectedinfo.sel_cnt;
1903         } else {
1904                 GL_CHECK_VAL(ad->selectedinfo.medias_elist, -1);
1905                 sel_cnt = eina_list_count(ad->selectedinfo.medias_elist);
1906         }
1907         image_cnt = ad->selectedinfo.images_cnt;
1908         if(image_cnt > sel_cnt) {
1909                 gl_dbgE("Images count is wrong!");
1910                 return -1;
1911         }
1912
1913         video_cnt = sel_cnt - image_cnt;
1914         gl_dbg("Selected items count: %d, image count: %d, video count: %d.",
1915                sel_cnt, image_cnt, video_cnt);
1916
1917         if (ad->selectedinfo.drms_cnt) {
1918                 share_mode = GL_SHARE_DRM;
1919         } else if (image_cnt && video_cnt) {
1920                 share_mode = GL_SHARE_IMAGE_VIDEO;
1921         } else if (image_cnt) {
1922                 if (ad->selectedinfo.jpeg_cnt == sel_cnt) {
1923                         if (image_cnt == 1)
1924                                 share_mode = GL_SHARE_IMAGE_ONE_JPEG;
1925                         else
1926                                 share_mode = GL_SHARE_IMAGE_MULTI_JPEG;
1927                 } else {
1928                         if (image_cnt == 1)
1929                                 share_mode = GL_SHARE_IMAGE_ONE;
1930                         else
1931                                 share_mode = GL_SHARE_IMAGE_MULTI;
1932                 }
1933         } else if (video_cnt) {
1934                 if (video_cnt == 1) {
1935                         share_mode = GL_SHARE_VIDEO_ONE;
1936                 } else {
1937                         share_mode = GL_SHARE_VIDEO_MULTI;
1938                 }
1939         } else {
1940                 gl_dbgE("Error: no video and image!");
1941                 return -1;
1942         }
1943         gl_dbg("share_mode is %d.", share_mode);
1944
1945         return share_mode;
1946 }
1947
1948 int _gl_destroy_albums_edit_view(void *data)
1949 {
1950         GL_CHECK_VAL(data, -1);
1951         gl_appdata *ad = (gl_appdata *)data;
1952
1953         if (ad->albuminfo.edit_layout) {
1954                 evas_object_del(ad->albuminfo.edit_layout);
1955                 ad->albuminfo.edit_view = NULL;
1956                 ad->albuminfo.edit_layout = NULL;
1957         }
1958         return 0;
1959 }
1960
1961 int _gl_destroy_thumbs_edit_view(void *data)
1962 {
1963         GL_CHECK_VAL(data, -1);
1964         gl_appdata *ad = (gl_appdata *)data;
1965
1966         if (ad->gridinfo.edit_layout) {
1967                 evas_object_del(ad->gridinfo.edit_layout);
1968                 ad->gridinfo.edit_view = NULL;
1969                 ad->gridinfo.edit_layout = NULL;
1970         }
1971         return 0;
1972 }
1973
1974 int gl_destroy_thumbs_view(void *data)
1975 {
1976         GL_CHECK_VAL(data, -1);
1977         gl_appdata *ad = (gl_appdata *)data;
1978         int view_mode = gl_get_view_mode(ad);
1979         gl_dbg("view_mode: %d.", view_mode);
1980
1981         gl_del_invalid_widgets(ad, GL_INVALID_NONE);
1982
1983         if(ad->gridinfo.edit_view) {
1984                 _gl_destroy_thumbs_edit_view(ad);
1985                 _gl_data_selected_list_finalize(ad);
1986         } else {
1987                 _gl_grid_del_append_idler(ad);
1988         }
1989         _gl_notify_destroy_selinfo(ad);
1990         /* destroy imf */
1991         _gl_editfield_destroy_imf(ad);
1992
1993         gl_grid_clear_view(ad);
1994         gl_list_clear_view(ad);
1995
1996         ad->albuminfo.current_album = NULL;
1997         ad->maininfo.seg_mode = GL_CTRL_SEG_ALL;
1998
1999         /* Pop to controlbar layout */
2000         elm_naviframe_item_pop_to(ad->albuminfo.nf_it);
2001
2002         return 0;
2003 }
2004
2005 /**
2006 * b_update_albums_list
2007 *       True: Update albums list. False: Albums list already updated.
2008 *
2009 * It's in thumbnails view, video list view, or selectioinfo view.
2010 * Destroy invalid widegets or UGs.
2011 * Pop current invalid view to controlbar layout,
2012 * to show Albums view
2013 */
2014 int gl_pop_to_ctrlbar_ly(void *data, bool b_update_albums_list)
2015 {
2016         GL_CHECK_VAL(data, -1);
2017         gl_appdata *ad = (gl_appdata *)data;
2018         gl_dbg("b_update_albums_list: %d", b_update_albums_list);
2019
2020         /* Destroy thumbnails/video_list view then pop to ctrlbar_ly */
2021         gl_destroy_thumbs_view(ad);
2022
2023         /* Update albums list */
2024         if (b_update_albums_list)
2025                 gl_refresh_albums_list(ad);
2026
2027         if (gl_check_gallery_empty(ad)) {
2028                 gl_albums_comeback_from_view(ad);
2029                 /* None albums, disable edit button/controlbar */
2030                 _gl_ctrl_disable_toolbar_item(ad, true, GL_NAVI_ALBUMS, true);
2031         } else {
2032                 /* Change to albums view. */
2033                 gl_dbg("Change to Albums view.");
2034                 gl_albums_comeback_from_view(ad);
2035                 /* None editable albums, disable edit button */
2036                 if (ad->albuminfo.cluster_list->edit_cnt == 0)
2037                         _gl_ctrl_disable_toolbar_item(ad, true, GL_NAVI_ALBUMS,
2038                                                       true);
2039         }
2040         return 0;
2041 }
2042
2043 /* Vibrate device */
2044 int gl_play_vibration(void *data)
2045 {
2046         gl_dbg("");
2047         GL_CHECK_VAL(data, -1);
2048         gl_appdata *ad = (gl_appdata *)data;
2049         int ret = -1;
2050
2051         if (ad->entryinfo.haptic_handle >= 0) {
2052                 gl_dbg("Remove previous haptic handle.");
2053                 _gl_stop_vibration(ad);
2054         }
2055
2056         ret = haptic_initialize();
2057         if (ret != HAPTIC_ERROR_NONE) {
2058                 gl_dbgE("haptic_initialize failed[%d]!", ret);
2059                 return -1;
2060         }
2061
2062         if (ad->entryinfo.vibration_timer) {
2063                 ecore_timer_del(ad->entryinfo.vibration_timer);
2064                 ad->entryinfo.vibration_timer = NULL;
2065         }
2066         Ecore_Timer *vibration_timer = NULL;
2067         vibration_timer = ecore_timer_add(GL_TIMER_INTERVAL_VIBRATION,
2068                                           _gl_vibration_timer_cb, data);
2069         ad->entryinfo.vibration_timer = vibration_timer;
2070         ret = haptic_vibrate_monotone(GL_VIBRATION_DEVICE,
2071                                       GL_VIBRATION_DURATION, HAPTIC_LEVEL_AUTO);
2072         if (ret != HAPTIC_ERROR_NONE) {
2073                 gl_dbgE("haptic_play_pattern failed[%d]!", ret);
2074                 return -1;
2075         }
2076         ad->entryinfo.haptic_handle = GL_VIBRATION_DEVICE;
2077
2078         return 0;
2079 }
2080
2081 /* Change int to char * of video duration, caller need to free the allocated memory */
2082 char *_gl_get_duration_string(unsigned int v_dur)
2083 {
2084         char *dur_str = calloc(1, GL_FILE_PATH_LEN_MAX);
2085         GL_CHECK_NULL(dur_str);
2086         if (v_dur > 0) {
2087                 int duration = floor(v_dur / GL_TIME_MSEC_PER_SEC);
2088                 int dur_hr = 0;
2089                 int dur_min = 0;
2090                 int dur_sec = 0;
2091                 int tmp = 0;
2092
2093                 if (duration >= GL_TIME_SEC_PER_HOUR) {
2094                         dur_sec = duration % GL_TIME_SEC_PER_MIN;
2095                         tmp = floor(duration / GL_TIME_SEC_PER_MIN);
2096                         dur_min = tmp % GL_TIME_MIN_PER_HOUR;
2097                         dur_hr = floor(tmp / GL_TIME_MIN_PER_HOUR);
2098                 } else if (duration >= GL_TIME_SEC_PER_MIN) {
2099                         dur_hr = 0;
2100                         dur_min = floor(duration / GL_TIME_SEC_PER_MIN);
2101                         dur_sec = duration % GL_TIME_SEC_PER_MIN;
2102                 } else {
2103                         dur_hr = 0;
2104                         dur_min = 0;
2105                         dur_sec = duration % GL_TIME_SEC_PER_MIN;
2106                 }
2107
2108                 snprintf(dur_str, GL_FILE_PATH_LEN_MAX, "%02d:%02d:%02d",
2109                          dur_hr, dur_min, dur_sec);
2110         } else {
2111                 snprintf(dur_str, GL_FILE_PATH_LEN_MAX, "00:00:00");
2112         }
2113         dur_str[strlen(dur_str)] = '\0';
2114         return dur_str;
2115 }
2116
2117 /* Fetch thumbnail from media-service, if it's invalid, generate new one */
2118 int _gl_get_thumb(void *data, const char *file_path, char **thumb_path)
2119 {
2120         GL_CHECK_VAL(thumb_path, -1);
2121         GL_CHECK_VAL(file_path, -1);
2122         GL_CHECK_VAL(data, -1);
2123         /* Return if thumbnail is valid */
2124         if (*thumb_path && ecore_file_exists(*thumb_path) &&
2125             (ecore_file_size(*thumb_path) > 0)) {
2126                 return 0;
2127         }
2128
2129         /* Free allocated memory first */
2130         if (*thumb_path) {
2131                 gl_dbgW("Wrong thumb path[%s]", *thumb_path);
2132                 free(*thumb_path);
2133                 *thumb_path = NULL;
2134         }
2135         gl_dbg("File[%s]", file_path);
2136
2137         char *new_path = calloc(1, GL_FILE_PATH_LEN_MAX);
2138         GL_CHECK_VAL(new_path, -1);
2139
2140         /* Generate thumbnail via thumbnail-service */
2141         int ret = -1;
2142         ret = thumbnail_request_from_db(file_path, new_path,
2143                                         GL_FILE_PATH_LEN_MAX);
2144         if (ret < 0) {
2145                 gl_dbgE("thumbnail_request_from_db failed!");
2146                 return -1;
2147         }
2148
2149         *thumb_path = new_path;
2150         gl_dbg("Request thumbnail[%s]", new_path);
2151         return 0;
2152 }
2153