merge with master
[apps/core/preloaded/ug-myfile-efl.git] / src / widget / mf-ug-search-view.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://floralicense.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
18
19
20 #include <Eina.h>
21 #include <Ecore_X.h>
22
23 #include "mf-ug-main.h"
24 #include "mf-ug-util.h"
25 #include "mf-ug-winset.h"
26 #include "mf-ug-fs-util.h"
27 #include "mf-ug-resource.h"
28 #include "mf-ug-cb.h"
29
30 #define MF_SEARCH_OPTION_DEF (MF_SEARCH_OPT_EXT)
31 #define MF_SEARCH_ROOT_NUM 2
32 #define MF_SEARCH_TIMER_INTERVAL 0.5
33
34 extern int flagSearchMsg;
35 extern pthread_mutex_t gLockSearchMsg;
36 extern pthread_cond_t gCondSearchMsg;
37
38 typedef struct {
39         char *size;
40         char *create_date;
41 } mf_search_detail_infor_s;
42
43 static void __mf_ug_search_select_all_check_changed_cb(void *data, Evas_Object * obj, void *event_info);
44
45 Evas_Object *mf_ug_search_view_create_no_content(Evas_Object *parent)
46 {
47         Evas_Object *nocontent = elm_layout_add(parent);
48         elm_layout_theme_set(nocontent, "layout", "nocontents", "text");
49         elm_object_focus_set(nocontent, EINA_FALSE);
50         elm_object_part_text_set(nocontent, "elm.text", MF_UG_LABEL_NO_RESULT);
51         return nocontent;
52 }
53
54 void mf_ug_search_view_item_append(void *data, void *user_data)
55 {
56         UG_TRACE_BEGIN;
57         ugData *ugd = (ugData *)user_data;
58         ug_mf_retm_if(ugd == NULL, "ugd is NULL");
59
60         ugNaviBar *pNavi_s = mf_ug_navi_bar_get_in_use_navi(ugd);
61         ug_mf_retm_if(pNavi_s == NULL, "get navi failed");
62
63         char *item_name = (char *)data;
64         ug_mf_retm_if(item_name == NULL, "input item_name error");
65
66         ugListItemData *m_TempItem = NULL;
67         GString *search_path = g_string_new(item_name);
68
69
70         g_string_free(search_path, TRUE);
71         search_path = NULL;
72
73         m_TempItem = (ugListItemData *) malloc(sizeof(ugListItemData));
74
75         if (m_TempItem == NULL) {
76                 return;
77         }
78         memset(m_TempItem, 0, sizeof(ugListItemData));
79
80         m_TempItem->ug_pItemName = g_string_new(item_name);
81         m_TempItem->ug_iGroupValue = 0;
82         m_TempItem->ug_pRadioBox = NULL;
83         m_TempItem->ug_bChecked = FALSE;
84         m_TempItem->ug_pCheckBox = NULL;
85         m_TempItem->ug_pThumbPath = NULL;
86         m_TempItem->ug_bRealThumbFlag = FALSE;
87         m_TempItem->ug_pData = ugd;
88         m_TempItem->ug_pItem = NULL;
89
90         /*delete timer if exists*/
91
92 #ifdef  UG_THUMB_REAL_TIME_UPDATE
93         if (ugd->ug_Status.ug_pThumbUpdateTimer != NULL) {
94                 ecore_timer_del(ugd->ug_Status.ug_pThumbUpdateTimer);
95                 ugd->ug_Status.ug_pThumbUpdateTimer = NULL;
96         }
97 #endif
98         Elm_Object_Item *it = NULL;
99
100         it = elm_genlist_item_append(ugd->ug_MainWindow.ug_pNaviGenlist, &ugd->ug_Status.ug_itc, m_TempItem, NULL, ELM_GENLIST_ITEM_NONE, NULL, ugd);
101         m_TempItem->ug_pItem = it;
102         UG_TRACE_END;
103
104 }
105
106 Evas_Object *mf_ug_search_create_select_all_layout(Evas_Object *parent)
107 {
108
109         ug_mf_retvm_if(parent == NULL, NULL, "parent is NULL");
110
111         Evas_Object *pSelectedAllLayout = NULL;
112         pSelectedAllLayout = elm_layout_add(parent);
113         elm_object_focus_set(pSelectedAllLayout, EINA_FALSE);
114         elm_layout_theme_set(pSelectedAllLayout, "genlist", "item", "select_all/default");
115         evas_object_size_hint_weight_set(pSelectedAllLayout, EVAS_HINT_EXPAND, EVAS_HINT_FILL);
116         evas_object_size_hint_align_set(pSelectedAllLayout, EVAS_HINT_FILL, EVAS_HINT_FILL);
117         elm_object_part_text_set(pSelectedAllLayout, "elm.text", MF_UG_LABEL_SELECT_ALL);
118         evas_object_show(pSelectedAllLayout);
119         return pSelectedAllLayout;
120 }
121
122 Evas_Object *mf_ug_search_create_check_box(Evas_Object *parent)
123 {
124         ug_mf_retvm_if(parent == NULL, NULL, "parent is NULL");
125
126         Evas_Object *checkbox = NULL;
127         checkbox = elm_check_add(parent);
128         elm_object_focus_set(checkbox, EINA_FALSE);
129         evas_object_propagate_events_set(checkbox, EINA_FALSE);
130         evas_object_show(checkbox);
131         return checkbox;
132 }
133
134 void __mf_ug_search_select_all_layout_mouse_down_cb(void *data, Evas * evas, Evas_Object * obj, void *event_info)
135 {
136         UG_TRACE_BEGIN;
137         ugData *ugd = (ugData *)data;
138         ug_mf_retm_if(ugd == NULL, "ugd is NULL");
139
140         ugd->ug_Status.ug_bSelectAllChecked = !ugd->ug_Status.ug_bSelectAllChecked;
141         elm_check_state_pointer_set(ugd->ug_MainWindow.ug_pSelectAllCheckBox, &ugd->ug_Status.ug_bSelectAllChecked);
142
143         __mf_ug_search_select_all_check_changed_cb(ugd, NULL, NULL);
144         UG_TRACE_END;
145 }
146
147 static void __mf_ug_search_select_all_check_changed_cb(void *data, Evas_Object * obj, void *event_info)
148 {
149         UG_TRACE_BEGIN;
150         ugData *ugd = (ugData *)data;
151         ug_mf_retm_if(ugd == NULL, "ugd is NULL");
152         Evas_Object *genlist = ugd->ug_MainWindow.ug_pNaviGenlist;
153         ug_debug("ugd->ug_Status.ug_iTotalCount is [%d]", ugd->ug_Status.ug_iTotalCount);
154         if (ugd->ug_Status.ug_bSelectAllChecked) {
155                 ug_debug();
156                 ugd->ug_Status.ug_iCheckedCount = ugd->ug_Status.ug_iTotalCount;
157         } else {
158                 ug_debug();
159                 ugd->ug_Status.ug_iCheckedCount = 0;
160         }
161
162         ugListItemData *it_data;
163         Elm_Object_Item *it;
164         int count = 0;
165
166         it = elm_genlist_first_item_get(genlist);
167         while (it) {
168                 ug_debug();
169                 it_data = elm_object_item_data_get(it);
170                 if (it_data) {
171                         ug_debug();
172                         it_data->ug_bChecked = ugd->ug_Status.ug_bSelectAllChecked;
173                         count++;
174                 }
175                 it = elm_genlist_item_next_get(it);
176         }
177         elm_genlist_realized_items_update(genlist);
178
179         if (count > 0 && ugd->ug_Status.ug_bSelectAllChecked) {
180                 Evas_Object *notify_popup = NULL;
181                 char lable_file[UG_LABEL_STRING_LENGTH] = { '\0', };
182                 char *label = NULL;
183                 /*1 TODO: need to update for multi-language */
184
185                 snprintf(lable_file, sizeof(lable_file), "%d", count);
186                 label = g_strconcat(MF_UG_LABEL_SELECTED, "(", lable_file, ")", NULL);
187                 notify_popup = mf_ug_navibar_create_notify_popup(ugd, ugd->ug_MainWindow.ug_pNaviLayout, label, false, NULL);
188                 ugd->ug_MainWindow.ug_pSelectInfoLayout = notify_popup;
189                 UG_SAFE_FREE_CHAR(label);
190
191         } else {
192                 UG_SAFE_FREE_OBJ(ugd->ug_MainWindow.ug_pSelectInfoLayout);
193         }
194         mf_ug_ctrl_bar_set_item_disable(ugd);
195
196         UG_TRACE_END;
197 }
198
199
200 static void __mf_ug_search_view_result_cb(mf_search_result_t *result, void *user_data)
201 {
202         ug_mf_retm_if(result == NULL, "result is NULL");
203
204         ugData *ugd = (ugData *)user_data;
205         ug_mf_retm_if(ugd == NULL, "ugd is NULL");
206
207         ugNaviBar *pNavi_s = mf_ug_navi_bar_get_in_use_navi(ugd);
208         ug_mf_retm_if(pNavi_s == NULL, "get navi failed");
209
210         Evas_Object *playout = ugd->ug_MainWindow.ug_pNaviLayout;
211         ug_mf_retm_if(playout == NULL, "get conformant failed");
212         Evas_Object *newContent = NULL;
213         Evas_Object *unUsed = elm_object_part_content_unset(playout, "part1");
214         if (unUsed) {
215                 evas_object_del(unUsed);
216                 unUsed = NULL;
217         }
218
219         if (g_list_length(result->dir_list) + g_list_length(result->file_list) == 0) {
220                 ug_ecore_idler_del(ugd->ug_Status.popup_create_idler);
221                 newContent = mf_ug_search_view_create_no_content(playout);
222                 elm_object_part_content_set(playout, "part1", newContent);
223                 mf_ug_navi_bar_button_set_disable(ugd, true);
224         } else {
225
226
227
228                 //newContent = mf_ug_genlist_create_content_list_view(ugd);
229                 newContent = __mf_ug_genlist_create_gl(ugd);
230                 ugd->ug_MainWindow.ug_pNaviGenlist = newContent;
231
232                 elm_object_part_content_set(playout, "part1", newContent);
233
234                 if (result->file_list != NULL) {
235                         Evas_Object *pSelectAllLayout = NULL;
236                         Evas_Object *pSelectAllCheckBox = NULL;
237                         ugd->ug_Status.ug_bSelectAllChecked = false;
238                         ugd->ug_Status.ug_iTotalCount = g_list_length(result->file_list);
239                         ugd->ug_Status.ug_iCheckedCount = 0;
240
241                         pSelectAllLayout = mf_ug_search_create_select_all_layout(ugd->ug_MainWindow.ug_pNaviBox);
242                         ug_mf_retm_if(pSelectAllLayout == NULL, "pSelectAllLayout is NULL");
243                         ugd->ug_MainWindow.ug_pSelectAllLayout = pSelectAllLayout;
244                         evas_object_event_callback_add(pSelectAllLayout, EVAS_CALLBACK_MOUSE_DOWN, __mf_ug_search_select_all_layout_mouse_down_cb, ugd);
245                         pSelectAllCheckBox = mf_ug_search_create_check_box(pSelectAllLayout);
246                         ugd->ug_MainWindow.ug_pSelectAllCheckBox = pSelectAllCheckBox;
247                         elm_check_state_pointer_set(pSelectAllCheckBox, &ugd->ug_Status.ug_bSelectAllChecked);
248                         evas_object_smart_callback_add(pSelectAllCheckBox, "changed", __mf_ug_search_select_all_check_changed_cb, ugd);
249
250                         elm_object_part_content_set(pSelectAllLayout, "elm.icon", pSelectAllCheckBox);
251                         elm_box_pack_start(ugd->ug_MainWindow.ug_pNaviBox, pSelectAllLayout);
252                 }
253                 if (result->dir_list != NULL) {
254                         g_list_foreach(result->dir_list, mf_ug_search_view_item_append, ugd);
255                 }
256                 if (result->file_list != NULL) {
257                         g_list_foreach(result->file_list, mf_ug_search_view_item_append, ugd);
258                 }
259         }
260 }
261
262
263 static Eina_Bool __mf_ug_search_view_stop(void *data)
264 {
265         UG_TRACE_BEGIN;
266         ugData *ugd = (ugData *)data;
267         ug_mf_retvm_if(ugd == NULL, ECORE_CALLBACK_CANCEL, "ugd is NULL");
268
269
270         UG_SAFE_FREE_OBJ(ugd->ug_MainWindow.ug_pSearchPopup);
271
272         if (ugd->ug_UiGadget.ug_pSyncPipe != NULL) {
273                 ecore_pipe_del(ugd->ug_UiGadget.ug_pSyncPipe);
274                 ugd->ug_UiGadget.ug_pSyncPipe = NULL;
275         }
276         __mf_ug_search_view_result_cb(((ms_handle_t *) ugd->ug_Status.search_handler)->result, ugd);
277
278         if (ugd->ug_Status.search_handler > 0) {
279                 mf_ug_search_stop(ugd->ug_Status.search_handler);
280         }
281
282
283         if (ugd->ug_Status.search_handler > 0) {
284                 mf_ug_search_finalize(&ugd->ug_Status.search_handler);
285         }
286
287         UG_TRACE_END;
288         return ECORE_CALLBACK_CANCEL;
289 }
290
291 static void __mf_ug_search_view_stop_cb(void *data, Evas_Object * obj, void *event_info) {
292
293         UG_TRACE_BEGIN;
294         ugData *ugd = (ugData *)data;
295         ug_mf_retm_if(ugd == NULL, "ugd is NULL");
296
297         __mf_ug_search_view_stop(ugd);
298
299         UG_TRACE_END;
300 }
301
302
303 static int __mf_ug_search_view_idle_search_msg_cope_finished(void *data)
304 {
305         UG_TRACE_BEGIN;
306         ugData *ugd = (ugData *)data;
307         if (ugd == NULL || ugd->ug_Status.msg_finish_idler == NULL) {
308                 return ECORE_CALLBACK_CANCEL;
309         }
310         pthread_mutex_lock(&gLockSearchMsg);
311         if (flagSearchMsg == 0) {
312                 flagSearchMsg = 1;
313                 pthread_cond_signal(&gCondSearchMsg);
314         }
315         pthread_mutex_unlock(&gLockSearchMsg);
316         ugd->ug_Status.msg_finish_idler = NULL;
317
318         return ECORE_CALLBACK_CANCEL;
319 }
320
321 static void __mf_ug_search_view_pipe_cb(void *data, void *buffer, unsigned int nbyte)
322 {
323         UG_TRACE_BEGIN;
324         ugData *ugd = (ugData *)data;
325         if (ugd == NULL) {
326                 ug_debug("input ugd is NULL");
327                 return;
328         }
329
330         mf_search_pipe_msg *pSearchMsg = (mf_search_pipe_msg *) buffer;
331         if (pSearchMsg == NULL) {
332                 ug_debug("received message is NULL");
333                 goto MF_CONTINURE_SEARCH;
334         }
335
336         if (pSearchMsg->mf_sp_msg_type == MF_SEARCH_PIPE_MSG_RESULT_REPORT) {
337                 ug_debug("result get");
338         } else if (pSearchMsg->mf_sp_msg_type == MF_SEARCH_PIPE_MSG_ROOT_CHANGE) {
339                 ug_debug("root change ");
340
341                 char *new_desc = mf_ug_fm_svc_wrapper_translate_path(pSearchMsg->current_path);
342                 //elm_object_text_set(ugd->ug_MainWindow.ug_pSearchPopup, new_desc);
343                 elm_object_text_set(ugd->ug_MainWindow.ug_pSearchLabel, new_desc);
344                 //elm_object_part_text_set(ugd->ug_MainWindow.ug_pSearchLabel, "path", new_desc);
345                 if (pSearchMsg->current_path) {
346                         free(pSearchMsg->current_path);
347                         pSearchMsg->current_path = NULL;
348                 }
349                 if (new_desc != NULL) {
350                         free(new_desc);
351                         new_desc = NULL;
352                 }
353         } else if (pSearchMsg->mf_sp_msg_type == MF_SEARCH_PIPE_MSG_FINISHED) {
354
355                 ug_ecore_idler_del(ugd->ug_Status.popup_del_idler);
356                 UG_SAFE_FREE_OBJ(ugd->ug_MainWindow.ug_pSearchPopup);
357                 //ugd->ug_Status.popup_del_idler = ecore_idler_add(mf_ug_cb_popup_del_idler_cb, ugd);
358                 __mf_ug_search_view_result_cb((mf_search_result_t *) pSearchMsg->report_result, data);
359         }
360
361 MF_CONTINURE_SEARCH:
362         ug_ecore_idler_del(ugd->ug_Status.msg_finish_idler);
363         ugd->ug_Status.msg_finish_idler = ecore_idler_add((Ecore_Task_Cb)__mf_ug_search_view_idle_search_msg_cope_finished, ugd);
364         //__mf_ug_search_view_idle_search_msg_cope_finished(NULL);
365         UG_TRACE_END;
366 }
367
368 static void __mf_ug_search_view_idle_search_start(void *data)
369 {
370         UG_TRACE_BEGIN;
371         ugData *ugd = (ugData *)data;
372         ug_mf_retm_if(ugd == NULL, "ugd is NULL");
373
374         ugNaviBar *pNavi_s = mf_ug_navi_bar_get_in_use_navi(ugd);
375         ug_mf_retm_if(pNavi_s == NULL, "pNavi_s is NULL");
376         char *text = NULL;
377
378         if (ugd->ug_UiGadget.ug_pExtension)
379                 text = g_strdup(ugd->ug_UiGadget.ug_pExtension);
380
381         int root_num = 0;
382         const char *SearchRoot[MF_SEARCH_ROOT_NUM] = {0};
383         ug_debug("text is [%s] path is [%s]", text, ugd->ug_Status.ug_pPath->str);
384         if (ugd->ug_UiGadget.ug_iSelectMode == IMPORT_MODE || ugd->ug_UiGadget.ug_iSelectMode == IMPORT_SINGLE) {
385                 root_num = 2;
386                 SearchRoot[0] = PHONE_FOLDER;
387
388                 SearchRoot[1] = MEMORY_FOLDER;
389         } else {
390                 root_num = 1;
391                 SearchRoot[0] = ugd->ug_Status.ug_pPath->str;
392
393         }
394         //const char *SearchRoot[MF_SEARCH_ROOT_NUM] = { ugd->ug_Status.ug_pPath->str};
395         //ug_debug("search path is [%s]", ugd->ug_Status.ug_pPath->str);
396         /*Start Search routine*/
397         if (!mf_ug_search_start(ugd->ug_Status.search_handler, SearchRoot, root_num, \
398                              ((text) ? text : NULL), MF_SEARCH_OPTION_DEF, (void *)ugd)) {
399                 ug_debug("start success");
400                 /*generate the popup used to show search path
401                 **it's sure that new_desc is not NULL even if original path is NULL*/
402                 //ugd->ug_MainWindow.ug_pSearchPopup = mf_ug_popup_create(ugd, UG_POPMODE_SEARCH, NULL, MF_UG_LABEL_SEARCH, NULL, NULL, NULL, __mf_ug_search_view_stop_cb, ugd);
403                 ugd->ug_MainWindow.ug_pSearchPopup = mf_ug_popup_create_search(ugd, __mf_ug_search_view_stop_cb, ugd);
404         } else {
405                 ug_debug("start failed");
406         }
407         ug_debug();
408
409
410         if (text != NULL) {
411                 free(text);
412                 text = NULL;
413         }
414
415 }
416
417 void mf_ug_search_view_enter_search_routine(void *data, Evas_Object * obj, void *event_info)
418 {
419         UG_TRACE_BEGIN;
420         ugData *ugd = (ugData *)data;
421         ug_mf_retm_if(ugd == NULL, "ugd is NULL");
422
423 #ifdef  UG_THUMB_REAL_TIME_UPDATE
424         if (ugd->ug_Status.ug_pThumbUpdateTimer != NULL) {
425                 ecore_timer_del(ugd->ug_Status.ug_pThumbUpdateTimer);
426                 ugd->ug_Status.ug_pThumbUpdateTimer = NULL;
427         }
428 #endif
429         //ugd->ug_Status.ug_iMore = UG_MORE_SEARCH;
430
431         if (ugd->ug_Status.search_handler > 0)
432                 mf_ug_search_finalize(&ugd->ug_Status.search_handler);
433
434         int ret = mf_ug_search_init(&ugd->ug_Status.search_handler);
435         ug_mf_retm_if(ret < 0, "Fail to mf_ug_search_init()");
436
437         if (ugd->ug_UiGadget.ug_pSyncPipe != NULL) {
438                 ecore_pipe_del(ugd->ug_UiGadget.ug_pSyncPipe);
439                 ugd->ug_UiGadget.ug_pSyncPipe = NULL;
440         }
441         ugd->ug_UiGadget.ug_pSyncPipe = ecore_pipe_add(__mf_ug_search_view_pipe_cb, ugd);
442
443         if (ugd->ug_UiGadget.ug_pSyncPipe == NULL) {
444                 ug_debug("add pipe failed");
445         }
446         /*this is to init global variable to ensure the first message can be transmitted correctly*/
447         /*flagSearchMsg is to indicate the condition wait to sync data of threads*/
448         pthread_mutex_lock(&gLockSearchMsg);
449         flagSearchMsg = 1;
450         pthread_mutex_unlock(&gLockSearchMsg);
451
452         /*delete guide text label in the box*/
453         /*evas_object_del(elm_object_content_unset(pNavi_s->pNaviConform));*/
454         __mf_ug_search_view_idle_search_start(ugd);
455
456         UG_TRACE_END;
457 }
458