2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
22 #include "mf-widget.h"
23 #include "mf-fs-util.h"
24 #include "mf-fm-svc-wrapper.h"
26 void mf_otg_list_clean(void *data, mf_otg_list_e list_type)
29 struct appdata *ap = (struct appdata *)data;
35 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
36 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
37 free(((mf_otg_node *)node)->name);
38 ((mf_otg_node *)node)->name = NULL;
42 if (ap->mf_FileOperation.otg_dev_list) {
43 eina_list_free(ap->mf_FileOperation.otg_dev_list);
44 ap->mf_FileOperation.otg_dev_list = NULL;
47 case MF_OTG_LIST_REMOVED:
48 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_removed_list, l, node) {
49 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
50 free(((mf_otg_node *)node)->name);
51 ((mf_otg_node *)node)->name = NULL;
55 eina_list_free(ap->mf_FileOperation.otg_dev_removed_list);
56 ap->mf_FileOperation.otg_dev_removed_list = NULL;
63 int mf_otg_init(void *data)
66 struct appdata *ap = (struct appdata *)data;
68 if (ap->mf_FileOperation.otg_dev_list != NULL)
69 mf_otg_list_clean(ap, MF_OTG_LIST_DEV);
71 if(ap->mf_FileOperation.otg_dev_removed_list != NULL)
72 mf_otg_list_clean(ap, MF_OTG_LIST_REMOVED);
76 pDir = opendir(OTG_FOLDER);
79 return MYFILE_ERR_DIR_OPEN_FAIL;
82 while ((ent = readdir(pDir)) != NULL) {
83 mf_otg_node *pNode = NULL;
85 if (g_strcmp0(ent->d_name, ".") == 0 || g_strcmp0(ent->d_name, "..") == 0) {
89 if ((ent->d_type & DT_DIR) == 0 && (ent->d_type & DT_REG) == 0) {
93 pNode = (mf_otg_node *) malloc(sizeof(mf_otg_node));
98 memset(pNode, 0, sizeof(mf_otg_node));
100 pNode->name = g_strconcat(OTG_FOLDER, "/", ent->d_name, NULL);
102 pNode->flag_using = false;
103 pNode->flag_editstart = false;
105 ap->mf_FileOperation.otg_dev_list = eina_list_append(ap->mf_FileOperation.otg_dev_list, pNode);
108 return MYFILE_ERR_NONE;
111 bool mf_otg_is_in_list(void *data, const char *dev_name)
114 struct appdata *ap = (struct appdata *)data;
119 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
120 if (node && g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0)
126 int mf_otg_insert_node(void *data, const char *name)
129 struct appdata *ap = (struct appdata *)data;
131 if (mf_otg_is_in_list(ap, name)) {
132 return MYFILE_ERR_NONE;
134 mf_otg_node *pNode = NULL;
135 pNode = (mf_otg_node *)malloc(sizeof(mf_otg_node));
138 return MYFILE_ERR_ALLOCATE_MEMORY_FAIL;
140 memset(pNode, 0, sizeof(mf_otg_node));
143 pNode->name = g_strdup(name);
145 pNode->flag_using = false;
146 pNode->flag_editstart = false;
148 ap->mf_FileOperation.otg_dev_list = eina_list_append(ap->mf_FileOperation.otg_dev_list, pNode);
150 return MYFILE_ERR_NONE;
152 int mf_otg_delete_node(void *data, const char *name)
155 struct appdata *ap = (struct appdata *)data;
157 if (!mf_otg_is_in_list(ap, name)) {
159 return MYFILE_ERR_NONE;
163 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
164 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
165 if (g_strcmp0(((mf_otg_node *)node)->name, name) == 0){
166 free(((mf_otg_node *)node)->name);
167 ((mf_otg_node *)node)->name = NULL;
169 ap->mf_FileOperation.otg_dev_list = eina_list_remove_list(ap->mf_FileOperation.otg_dev_list, l);
174 return MYFILE_ERR_NONE;
182 int mf_otg_list_update(void *data, bool flag_inc_dec)
185 struct appdata *ap = (struct appdata *)data;
188 if (flag_inc_dec == TRUE) {
191 pDir = opendir(OTG_FOLDER);
194 return MYFILE_ERR_DIR_OPEN_FAIL;
197 while ((ent = readdir(pDir)) != NULL) {
198 if (g_strcmp0(ent->d_name, ".") == 0 || g_strcmp0(ent->d_name, "..") == 0) {
202 if ((ent->d_type & DT_DIR) == 0 && (ent->d_type & DT_REG) == 0) {
208 char *test_name = g_strconcat(OTG_FOLDER, "/", ent->d_name, NULL);
209 mf_debug("current test_name is %s", test_name);
210 if (test_name != NULL) {
212 /*we will check if the device is already in the list in mf_otg_insert_node*/
213 if (flag_inc_dec == true) {
214 mf_otg_insert_node(ap, test_name);
227 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
228 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
229 mf_debug("name is %s", ((mf_otg_node *)node)->name);
230 if (ecore_file_exists(((mf_otg_node *)node)->name) == false)
231 mf_otg_delete_node(ap, ((mf_otg_node *)node)->name);
235 return MYFILE_ERR_NONE;
238 bool mf_otg_is_empty(void *data)
240 return ecore_file_exists(OTG_FOLDER) && ecore_file_dir_is_empty(OTG_FOLDER);
243 char *mf_otg_get_node_in_use(void *data)
246 struct appdata *ap = (struct appdata *)data;
251 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
252 if ((mf_otg_node *)node != NULL) {
253 if (((mf_otg_node *)node)->flag_using == true) {
254 return ((mf_otg_node *)node)->name;
261 void mf_otg_set_node_using_flag(void *data, char *dev_name, bool status)
264 /*g_strcmp0 used, no need to check dev_name here*/
265 struct appdata *ap = (struct appdata *)data;
270 mf_debug("dev_name is %s", dev_name);
271 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
273 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
274 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
275 ((mf_otg_node *)node)->flag_using = status;
281 int mf_otg_get_node_using_flag(void *data, char *dev_name, bool *status)
285 /*g_strcmp0 used, no need to check dev_name here*/
286 struct appdata *ap = (struct appdata *)data;
291 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
292 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
293 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
294 *status = ((mf_otg_node *)node)->flag_using;
295 return MYFILE_ERR_NONE;
299 return MYFILE_ERR_GET_STAT_FAIL;
302 void mf_otg_set_node_editstart_flag(void *data, char *dev_name, bool status)
305 /*g_strcmp0 used, no need to check dev_name here*/
306 struct appdata *ap = (struct appdata *)data;
311 mf_debug("dev_name is %s", dev_name);
312 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
314 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
315 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
316 ((mf_otg_node *)node)->flag_editstart = status;
322 int mf_otg_get_node_editstart_flag(void *data, char *dev_name, bool *status)
326 /*g_strcmp0 used, no need to check dev_name here*/
327 struct appdata *ap = (struct appdata *)data;
332 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
334 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
335 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
336 *status = ((mf_otg_node *)node)->flag_editstart;
337 return MYFILE_ERR_NONE;
341 return MYFILE_ERR_GET_STAT_FAIL;
344 void mf_otg_generate_removed_list(void *data)
347 struct appdata *ap = (struct appdata *)data;
349 if (ap->mf_FileOperation.otg_dev_removed_list != NULL) {
351 mf_otg_list_clean(ap, MF_OTG_LIST_REMOVED);
356 mf_otg_node *pNode = NULL;
357 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
359 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
360 if (ecore_file_exists(((mf_otg_node *)node)->name) == false) {
361 pNode = (mf_otg_node *) malloc(sizeof(mf_otg_node));
366 memset(pNode, 0, sizeof(mf_otg_node));
368 pNode->name = g_strdup(((mf_otg_node *)node)->name);
370 pNode->flag_using = ((mf_otg_node *)node)->flag_using;
371 pNode->flag_editstart = ((mf_otg_node *)node)->flag_editstart;
373 ap->mf_FileOperation.otg_dev_removed_list = eina_list_append(ap->mf_FileOperation.otg_dev_removed_list, pNode);
380 void mf_otg_clear_removed_device(void *data)
383 struct appdata *ap = (struct appdata *)data;
385 const Eina_List *l = NULL;
388 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
389 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
390 if (ecore_file_exists(((mf_otg_node *)node)->name) == false) {
391 mf_otg_delete_node(ap, ((mf_otg_node *)node)->name);
397 /*do external operation according to the opt*/
398 static void __mf_otg_dev_removed_ex_operation(void *data, mf_otg_ex_opt_e opt)
401 struct appdata *ap = (struct appdata *)data;
403 /* try to remove all the popup and give an notice popup */
404 if (opt & MF_OTG_OPT_REQ_POPUP_DEL) { /*delete request popup in data transmit period*/
405 ap->mf_MainWindow.pMmcRemovedPopup = mf_popup_create_popup(ap, POPMODE_TEXT_NOT_DISABLED, NULL,
406 "OTG device removed...", NULL, NULL, NULL, NULL, NULL);
409 if (opt & MF_OTG_OPT_NOR_POPUP_DEL) { /*delete normal popup*/
410 if (ap->mf_MainWindow.pNormalPopup) {
411 evas_object_del(ap->mf_MainWindow.pNormalPopup);
412 ap->mf_MainWindow.pNormalPopup = NULL;
418 void mf_otg_dev_all_removed_update(void *data, mf_otg_ex_opt_e opt)
422 struct appdata *ap = (struct appdata *)data;
425 Evas_Object *entry = NULL;
426 myfileNaviBar *pNaviToShowStruct = NULL;
427 myfileNaviBar *pNaviOTG = NULL;
428 Evas_Object *pNaviBarStorageView = NULL;
430 /*otg tab destroyed, finalize otg*/
435 pNaviBarStorageView = ap->mf_MainWindow.pNaviBar;
436 pNaviOTG = mf_navi_bar_get_struct_by_label(ap, GET_STR(MF_LABEL_OTG));
438 char status = MF_OTG_STATUS_NONE;
440 if (pNaviOTG != NULL && pNaviOTG->naviFlagEditStart == TRUE)
441 status |= MF_OTG_STATUS_EDIT;
443 if (pNaviOTG != NULL && pNaviOTG->naviFlagInUse == TRUE)
444 status |= MF_OTG_STATUS_USING;
446 /*destroy otg navi bar*/
447 mf_debug("navi count is %d", eina_list_count(ap->mf_MainWindow.plistNaviBar));
448 mf_navi_bar_remove_list_item_by_label(ap, GET_STR(MF_LABEL_OTG));
452 if (status & MF_OTG_STATUS_EDIT) {
453 mf_navi_bar_recover_list(ap);
456 pNaviToShowStruct = mf_navi_bar_get_struct_by_label(ap, GET_SYS_STR(MF_LABEL_PHONE));
458 if (status & MF_OTG_STATUS_EDIT) {
459 ap->mf_Status.more = MORE_DEFAULT;
460 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
461 } else if (status & MF_OTG_STATUS_USING){
462 if ( ap->mf_Status.more == MORE_CREATE_FOLDER
463 && (ap->mf_Status.preMore == MORE_INTERNAL_COPY_MOVE || ap->mf_Status.preMore == MORE_INTERNAL_COPY || ap->mf_Status.preMore == MORE_INTERNAL_MOVE)) {
464 ap->mf_Status.more = ap->mf_Status.preMore;
465 } else if (ap->mf_Status.more != MORE_INTERNAL_COPY_MOVE && ap->mf_Status.preMore != MORE_INTERNAL_COPY && ap->mf_Status.preMore != MORE_INTERNAL_MOVE) {
466 ap->mf_Status.more = MORE_DEFAULT;
468 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
471 /*delete external storage from tab bar*/
472 mf_debug("navi count is %d", eina_list_count(ap->mf_MainWindow.plistNaviBar));
473 /*check tab bar item to decide if delete tab bar*/
474 mf_debug("navi count is %d", eina_list_count(ap->mf_MainWindow.plistNaviBar));
476 /*clear some external detail after remove otg device*/
479 __mf_otg_dev_removed_ex_operation(ap, opt);
481 mf_otg_ex_opt_e updated_opt = opt;
482 if (updated_opt & MF_OTG_OPT_NOR_POPUP_DEL)
483 updated_opt ^= MF_OTG_OPT_NOR_POPUP_DEL;
485 if (updated_opt & MF_OTG_OPT_REQ_POPUP_DEL)
486 updated_opt ^= MF_OTG_OPT_REQ_POPUP_DEL;
488 __mf_otg_dev_removed_ex_operation(ap, updated_opt);
491 if (ap->mf_Status.more == MORE_RENAME) {
492 entry = ap->mf_MainWindow.pEntry;
494 elm_object_focus_set(entry, EINA_TRUE);
499 void mf_otg_dev_removed_update(void *data, mf_otg_ex_opt_e opt)
502 struct appdata *ap = (struct appdata *)data;
504 Evas_Object *pNaviBarStorageView = NULL;
505 myfileNaviBar *pNavi_s = NULL;
506 myfileNaviBar *pNaviToShowStruct = NULL;
508 pNaviBarStorageView = ap->mf_MainWindow.pNaviBar;
509 pNavi_s = mf_navi_bar_get_struct_by_label(ap, GET_STR(MF_LABEL_OTG));
510 if (pNavi_s == NULL) {
517 char status = MF_OTG_STATUS_NONE;
518 EINA_LIST_FOREACH (ap->mf_FileOperation.otg_dev_removed_list, l, node) {
520 bool using_status = FALSE;
521 error_code = mf_otg_get_node_using_flag(ap, ((mf_otg_node *)node)->name, &using_status);
522 if (error_code == 0 && using_status == TRUE)
523 status |= MF_OTG_STATUS_USING;
524 bool edit_status = FALSE;
525 error_code = mf_otg_get_node_editstart_flag(ap, ((mf_otg_node *)node)->name, &edit_status);
526 if (error_code == 0 && edit_status == TRUE)
527 status |= MF_OTG_STATUS_EDIT;
532 mf_debug("status is %d", status);
533 mf_debug("status & MF_OTG_STATUS_EDIT is %d", status & MF_OTG_STATUS_EDIT);
535 if (status & MF_OTG_STATUS_EDIT) {
537 /*pop edit related view for each navi bar*/
538 pNaviToShowStruct = mf_navi_bar_recover_list(ap);
540 /*pop to the root view of OTG*/
541 Elm_Object_Item *bottom_it = elm_naviframe_bottom_item_get(pNaviBarStorageView);
543 elm_naviframe_item_pop_to(bottom_it);
545 /* set the navi's currentpath to be root path*/
546 if (pNavi_s->pCurrentPath != NULL) {
547 free(pNavi_s->pCurrentPath);
549 pNavi_s->pCurrentPath = g_strdup(OTG_FOLDER);
550 ap->mf_MainWindow.pNaviLayout = ap->mf_Otg.rootpath_layout;
551 ap->mf_MainWindow.pNaviBox = ap->mf_Otg.rootpath_box;
553 if (pNavi_s->naviFlagInUse == TRUE){
554 if (ap->mf_Status.path != NULL) {
555 g_string_free(ap->mf_Status.path, TRUE);
557 ap->mf_Status.path = g_string_new(OTG_FOLDER);
559 }else if (status & MF_OTG_STATUS_USING) {
560 if (ap->mf_Status.more == MORE_SEARCH) {
561 if (ap->mf_FileOperation.sync_pipe != NULL) {
562 ecore_pipe_del(ap->mf_FileOperation.sync_pipe);
563 ap->mf_FileOperation.sync_pipe = NULL;
566 if (ap->mf_FileOperation.search_IME_hide_timer != NULL) {
567 ecore_timer_del(ap->mf_FileOperation.search_IME_hide_timer);
568 ap->mf_FileOperation.search_IME_hide_timer = NULL;
571 if (ap->mf_Status.search_handler > 0) {
572 mf_search_stop(ap->mf_Status.search_handler);
575 if (ap->mf_Status.search_handler > 0) {
576 mf_search_finalize(&ap->mf_Status.search_handler);
579 if (ap->mf_Status.more == MORE_INTERNAL_COPY_MOVE || ap->mf_Status.more == MORE_INTERNAL_COPY || ap->mf_Status.more == MORE_INTERNAL_MOVE
580 || (ap->mf_Status.more == MORE_CREATE_FOLDER && (ap->mf_Status.preMore == MORE_INTERNAL_COPY_MOVE || ap->mf_Status.more == MORE_INTERNAL_COPY || ap->mf_Status.more == MORE_INTERNAL_MOVE))) {
581 /*pop unused path select view*/
582 /*create and push root view of OTG*/
583 SAFE_FREE_GSTRING(ap->mf_Status.path);
584 ap->mf_Status.path = g_string_new(OTG_FOLDER);
586 SAFE_FREE_CHAR(pNavi_s->pCurrentPath);
587 pNavi_s->pCurrentPath = g_strdup(OTG_FOLDER);
589 if (ap->mf_Status.more == MORE_CREATE_FOLDER)
590 ap->mf_Status.more = ap->mf_Status.preMore;
592 mf_navi_bar_create_path_select_view_otg_root(ap);
593 mf_navi_bar_remove_previous_contents(ap, ap->mf_MainWindow.pNaviBar);
595 ap->mf_Status.more = MORE_DEFAULT;
597 /*pop to the root view of OTG*/
598 Elm_Object_Item *bottom_it = elm_naviframe_bottom_item_get(pNaviBarStorageView);
600 elm_naviframe_item_pop_to(bottom_it);
602 /* set the navi's currentpath to be root path*/
603 if (pNavi_s->pCurrentPath != NULL) {
604 free(pNavi_s->pCurrentPath);
606 pNavi_s->pCurrentPath = g_strdup(OTG_FOLDER);
607 ap->mf_MainWindow.pNaviLayout = ap->mf_Otg.rootpath_layout;
608 ap->mf_MainWindow.pNaviBox = ap->mf_Otg.rootpath_box;
609 ap->mf_MainWindow.pNaviItem = ap->mf_Otg.rootpath_navi_item;
611 if (pNavi_s->naviFlagInUse == TRUE){
612 if (ap->mf_Status.path != NULL) {
613 g_string_free(ap->mf_Status.path, TRUE);
615 ap->mf_Status.path = g_string_new(OTG_FOLDER);
620 if ((status & MF_OTG_STATUS_EDIT)
621 || (pNavi_s && pNavi_s->naviFlagInUse && ((status & MF_OTG_STATUS_USING) || mf_fm_svc_wrapper_is_root_path(ap->mf_Status.path->str) == MYFILE_OTG))) {
622 mf_debug("status is %d", status);
624 mf_debug("status & MF_OTG_STATUS_EDIT is %d", status & MF_OTG_STATUS_EDIT);
625 if (status & MF_OTG_STATUS_USING) {
627 pNaviToShowStruct = pNavi_s;
629 if ( ap->mf_Status.more == MORE_CREATE_FOLDER && (ap->mf_Status.preMore == MORE_INTERNAL_COPY_MOVE
630 || ap->mf_Status.more == MORE_INTERNAL_COPY || ap->mf_Status.more == MORE_INTERNAL_MOVE)) {
631 ap->mf_Status.more = ap->mf_Status.preMore;
632 } else if (ap->mf_Status.more != MORE_INTERNAL_COPY_MOVE && ap->mf_Status.more != MORE_INTERNAL_COPY && ap->mf_Status.more != MORE_INTERNAL_MOVE) {
633 ap->mf_Status.more = MORE_DEFAULT;
636 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
639 /*clear some external detail after remove otg device*/
642 __mf_otg_dev_removed_ex_operation(ap, opt);
644 mf_otg_ex_opt_e updated_opt = opt;
645 if (updated_opt & MF_OTG_OPT_NOR_POPUP_DEL)
646 updated_opt ^= MF_OTG_OPT_NOR_POPUP_DEL;
648 if (updated_opt & MF_OTG_OPT_REQ_POPUP_DEL)
649 updated_opt ^= MF_OTG_OPT_REQ_POPUP_DEL;
651 __mf_otg_dev_removed_ex_operation(ap, updated_opt);
653 mf_debug("dev list count is %d", eina_list_count(ap->mf_FileOperation.otg_dev_list));
654 mf_otg_list_update(ap, FALSE);
655 mf_debug("dev list count is %d", eina_list_count(ap->mf_FileOperation.otg_dev_list));
658 void mf_otg_finalize(void *data)
661 struct appdata *ap = (struct appdata *)data;
663 mf_otg_list_clean(ap, MF_OTG_LIST_DEV);
664 mf_otg_list_clean(ap, MF_OTG_LIST_REMOVED);