221e20bb1b46c3d5fec47aa3e7d661a14410fdf5
[apps/core/preloaded/email.git] / composer / src / email-composer-attachment.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 <metadata_extractor.h>
19 #include <image_util.h>
20 #include <Ethumb.h>
21 #include <app.h>
22
23 #include "email-debug.h"
24 #include "email-composer.h"
25 #include "email-composer-util.h"
26 #include "email-composer-attachment.h"
27 #include "email-composer-filetype.h"
28 #include "email-composer-callback.h"
29 #include "email-composer-recipient.h"
30 #include "email-composer-js.h"
31
32 static int toggle = 0;
33 static Evas_Object *_g_attach_btn;
34
35 EmailComposerUGD *g_ugd;
36
37 static void _composer_attachment_delete_icon_clicked_cb(void *data, Evas_Object *obj, void *event_info);
38 static void _composer_attachment_contracted_item_clicked_cb(void *data, Evas_Object *obj, void *event_info);
39 static void _composer_attachment_unfocus(void *data, Evas_Object *obj, const char *emission, const char *source);
40 static void _composer_attachment_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
41
42 /**
43  * Returns total size of attachments including attachments, inline images and new files to be attached/inserted.
44  *
45  * @param [in] ugd composer ui gadget data
46  * @param [in] files_list contains 'to be attached/inserted' filepaths. NULL is passed if there is no new files
47  *
48  * @return total size or -1 incase of 'stat' error
49  */
50 int _composer_get_attachments_total_size(EmailComposerUGD *ugd)
51 {
52         debug_log("");
53
54         int attach_size = 0;
55         int inline_size = 0;
56         int total_attachments_size = 0;
57
58         struct stat file_info;
59         int return_stat;
60
61         Eina_Iterator *it = NULL;
62         Evas_Object *attachment_obj = NULL;
63         email_attachment_data_t *attachment_data = NULL;
64
65         it = eina_list_iterator_new(ugd->attachment_item_obj_list);
66
67         while (eina_iterator_next(it, (void **)&attachment_obj)) {
68
69                 attachment_data = evas_object_data_get(attachment_obj, "attachment_data");
70
71                 if (attachment_data) {
72
73                         if ((return_stat = stat(attachment_data->attachment_path, &file_info)) == -1) {
74                                 debug_error("stat Error(%d): %s", errno, strerror(errno));
75                                 attach_size += attachment_data->attachment_size;
76                                 continue;
77                         }
78
79                         debug_log("file size in byte : %d", file_info.st_size);
80
81                         attach_size += file_info.st_size;
82                 }
83         }
84
85         if (it) {
86                 eina_iterator_free(it);
87         }
88
89         if (EINA_TRUE == ugd->has_body_html) {
90
91                 inline_size = _composer_get_inline_images_size(ugd);
92                 if (inline_size < 0) {
93                         debug_log("Failed to get inline images total size");
94                         return COMPOSER_ERROR_INVALID_FILE_SIZE;
95                 }
96         }
97
98         debug_log("existing attachments size = %d, existing inline images size = %d", attach_size, inline_size);
99
100         total_attachments_size = inline_size + attach_size;
101
102         debug_log("total size = %d", total_attachments_size);
103
104         return total_attachments_size;
105 }
106
107 /**
108  * Returns total size of files
109  *
110  * @param [in] files_list contains file paths
111  *
112  * @return total size or -1 incase of 'stat' error
113  */
114 int _composer_get_files_size(Eina_List *files_list)
115 {
116         debug_log("");
117
118         if (!files_list)
119                 return COMPOSER_ERROR_NULL_POINTER;
120
121         Eina_List *list = files_list;
122         Eina_List *l = NULL;
123         char *recv = NULL;
124
125         int temp_size = 0;
126         int file_size = 0;
127
128         EINA_LIST_FOREACH(list, l, recv) {
129                 debug_log("File : %s", recv);
130
131                 if (ecore_file_exists(recv))
132                         file_size = ecore_file_size(recv);
133                 else
134                         file_size = 0;
135                 debug_log("file_size : %d", file_size);
136                 temp_size = temp_size + file_size;
137                 debug_log("total_size : %d", temp_size);
138         }
139
140         debug_log("Files total size : %d", temp_size);
141         return temp_size;
142 }
143
144 /**
145  * Returns total size of inline images in mail body
146  *
147  * @param [in] ugd composer ui gadget data
148  *
149  * @return total size or -1 incase of 'stat' error
150  */
151 int _composer_get_inline_images_size(EmailComposerUGD *ugd)
152 {
153         debug_log("");
154         int total_size = 0;
155
156         if (EINA_TRUE == ugd->has_body_html) {
157                 debug_log("listOfImageUrls count : %d", eina_list_count(ugd->listOfImageUrls));
158                 if (eina_list_count(ugd->listOfImageUrls) > 0) {
159
160                         Eina_List *list = ugd->listOfImageUrls;
161                         Eina_List *l = NULL;
162                         char *recv = NULL;
163
164                         Eina_List *inline_list = NULL;
165
166                         EINA_LIST_FOREACH(list, l, recv) {
167                                 if (strncmp(recv, "file://", 7) == 0) {
168                                         debug_log("Inline image : %s", recv + 7);
169                                         inline_list = eina_list_append(inline_list, recv + 7);
170                                 }
171                         }
172                         if (eina_list_count(inline_list) > 0 && (inline_list != NULL)) {
173                                 total_size = _composer_get_files_size(inline_list); // -1 on 'stat' error of inline image file
174                         }
175
176                         eina_list_free(inline_list);
177                 }
178         }
179
180         debug_log("Inline images total size : %d", total_size);
181         return total_size;
182 }
183
184 void _composer_attachment_reset(EmailComposerUGD *ugd)
185 {
186         debug_log("");
187
188         Eina_Iterator *it = NULL;
189         Evas_Object *attachment_obj = NULL;
190         email_attachment_data_t *attachment_data = NULL;
191
192         it = eina_list_iterator_new(ugd->attachment_item_obj_list);
193
194         while (eina_iterator_next(it, (void **)&attachment_obj)) {
195
196                 attachment_data = evas_object_data_get(attachment_obj, "attachment_data");
197
198                 if (attachment_data) {
199                         debug_log("attachment_data file name to be removed : %s", attachment_data->attachment_path);
200
201                         email_free_attachment_data(&attachment_data, 1);
202                         attachment_data = NULL;
203                 }
204
205                 elm_box_unpack(ugd->attachment_item_box, attachment_obj);
206                 evas_object_del(attachment_obj);
207         }
208
209         if (ugd->new_mail_info) {
210                 if (ugd->new_mail_info->mail_data) {
211                         ugd->new_mail_info->mail_data->attachment_count = 0;
212                 }
213         }
214
215         if (ugd->attachment_item_box) {
216                 evas_object_del(ugd->attachment_item_box);
217                 ugd->attachment_item_box = NULL;
218         }
219
220         if (it) {
221                 eina_iterator_free(it);
222         }
223
224         if (ugd->attachment_item_obj_list) {
225                 eina_list_free(ugd->attachment_item_obj_list);
226                 ugd->attachment_item_obj_list = NULL;
227         }
228
229         if (ugd->attachment_contracted_item) {
230                 elm_box_unpack(ugd->attachment_item_box, ugd->attachment_contracted_item);
231                 evas_object_del(ugd->attachment_contracted_item);
232                 ugd->attachment_contracted_item = NULL;
233         }
234 }
235
236 void _composer_attachment_create_list(EmailComposerUGD *ugd, Eina_List *attachment_list, Eina_Bool is_inline)
237 {
238         debug_log("");
239
240         if (attachment_list == NULL)
241                 return;
242
243         int nTobeAttachedCount = eina_list_count(attachment_list);
244         debug_log("nTobeAttachedCount : %d", nTobeAttachedCount);
245
246         if (nTobeAttachedCount <= 0)
247                 return;
248
249         int nAttachmentObjListCount = eina_list_count(ugd->attachment_item_obj_list);
250         debug_log("nAttachmentObjListCount : %d", nAttachmentObjListCount);
251
252         if (ugd->attachment_item_box == NULL) {
253                 Evas_Object *attachment_item_box;
254                 attachment_item_box = _composer_create_box(ugd->main_layout);
255                 elm_object_focus_allow_set(attachment_item_box, EINA_TRUE);
256                 elm_object_part_content_set(ugd->c_layout, "_attachment_field", attachment_item_box);
257                 ugd->attachment_item_box = attachment_item_box;
258         } else {
259                 _composer_attachment_expand_items(ugd);
260         }
261
262         bool bDuplicated = FALSE;
263         char *recv = NULL;
264         Eina_List *l = NULL;
265
266         struct stat file_info;
267         int return_stat;
268
269         email_attachment_data_t *attachment_data = NULL;
270
271         int nCount = nAttachmentObjListCount;
272         int total_attachments_size = _composer_get_attachments_total_size(ugd);
273
274         EINA_LIST_FOREACH(attachment_list, l, recv) {
275
276                 bDuplicated = _composer_attachment_duplicate_check(ugd, recv);
277
278                 if (bDuplicated) {
279                         debug_log("Attachment is duplicated");
280
281                         if (ugd->composer_noti) {
282                                 evas_object_del(ugd->composer_noti);
283                                 ugd->composer_noti = NULL;
284                         }
285                         ugd->composer_noti = _composer_create_noti(ugd, false, dgettext("sys_string", "IDS_COM_POP_WARNING"), _("IDS_EMAIL_POP_FILE_ALREADY_EXISTS"), 0, NULL, NULL, 2.0,
286                                 _composer_noti_response_cb);
287
288                         break;
289                 }
290         }
291
292         EINA_LIST_FOREACH(attachment_list, l, recv) {
293
294                 bDuplicated = _composer_attachment_duplicate_check(ugd, recv);
295
296                 if (bDuplicated)
297                         continue;
298
299                 if ((return_stat = stat(recv, &file_info)) == -1) {
300                         debug_error("stat Error(%d): %s", errno, strerror(errno));
301                         eina_list_free(attachment_list);
302                         attachment_list = NULL;
303
304                         if (ugd->composer_noti) {
305                                 evas_object_del(ugd->composer_noti);
306                                 ugd->composer_noti = NULL;
307                         }
308                         ugd->composer_noti = _composer_create_noti(ugd, false, dgettext("sys_string", "IDS_COM_POP_WARNING"),
309                                 _("IDS_EMAIL_POP_UNABLE_TO_ATTACH_FILE"), 0, NULL, NULL, 1.5, _composer_noti_response_cb);
310                         break;
311                 }
312
313                 total_attachments_size += file_info.st_size;
314
315                 if (total_attachments_size > MAX_ATTACHMENT_SIZE) {
316                         debug_log("Total size is over");
317
318                         char msg[MAX_STR_LEN] = { 0, };
319                         snprintf(msg, sizeof(msg), _("IDS_EMAIL_POP_UNABLE_TO_ATTACH_MAXIMUM_SIZE_OF_FILES_IS_PD_KB"), MAX_ATTACHMENT_SIZE / 1024);
320
321                         if (ugd->composer_noti) {
322                                 evas_object_del(ugd->composer_noti);
323                                 ugd->composer_noti = NULL;
324                         }
325                         ugd->composer_noti = _composer_create_noti(ugd, false, dgettext("sys_string", "IDS_COM_POP_WARNING"), msg, 0, NULL, NULL, 2.0,
326                                 _composer_noti_response_cb);
327
328                         eina_list_free(attachment_list);
329                         attachment_list = NULL;
330
331                         break;
332                 }
333
334                 if (nCount >= MAX_ATTACHMENT_ITEM) {
335                         debug_log("Total count is over");
336
337                         char msg[MAX_STR_LEN] = { 0, };
338                         snprintf(msg, sizeof(msg), _("IDS_EMAIL_POP_UNABLE_TO_ATTACH_MAXIMUM_NUMBER_OF_FILES_IS_PD"), MAX_ATTACHMENT_ITEM);
339
340                         if (ugd->composer_noti) {
341                                 evas_object_del(ugd->composer_noti);
342                                 ugd->composer_noti = NULL;
343                         }
344                         ugd->composer_noti = _composer_create_noti(ugd, false, dgettext("sys_string", "IDS_COM_POP_WARNING"), msg, 0, NULL, NULL, 2.0,
345                                 _composer_noti_response_cb);
346
347                         eina_list_free(attachment_list);
348                         attachment_list = NULL;
349
350                         break;
351                 }
352
353                 attachment_data = (email_attachment_data_t *)calloc(1, sizeof(email_attachment_data_t));
354
355                 gchar **tokens;
356                 tokens = g_strsplit(recv, "/", -1);
357
358                 attachment_data->attachment_name = COMPOSER_STRDUP(tokens[g_strv_length(tokens) - 1]);
359                 attachment_data->attachment_path = COMPOSER_STRDUP(recv);
360                 attachment_data->save_status = 1;
361                 attachment_data->attachment_size = file_info.st_size;
362
363                 if (is_inline)
364                         attachment_data->inline_content_status = 1;
365
366                 debug_log("attachment_name = %s, attachment_path = %s", attachment_data->attachment_name, attachment_data->attachment_path);
367
368                 g_strfreev(tokens);
369
370                 _composer_attachment_create_list_box(ugd, attachment_data);
371
372                 nCount++;
373         }
374
375         if (_composer_check_recipient_is_empty(ugd)) {
376                 if (!ugd->bSendBtnDisabled) {
377                         elm_object_disabled_set(ugd->send_btn, EINA_TRUE);
378                         elm_object_disabled_set(ugd->send_btm_btn, EINA_TRUE);
379                         ugd->bSendBtnDisabled = true;
380                 }
381         } else {
382                 if (ugd->bSendBtnDisabled) {
383                         elm_object_disabled_set(ugd->send_btn, EINA_FALSE);
384                         elm_object_disabled_set(ugd->send_btm_btn, EINA_FALSE);
385                         ugd->bSendBtnDisabled = false;
386                 }
387         }
388
389         eina_list_free(attachment_list);
390         attachment_list = NULL;
391
392         _composer_attachment_contract_items(ugd);
393 }
394
395 void _composer_attachment_create_list_box(EmailComposerUGD *ugd, email_attachment_data_t *attachment_data)
396 {
397         debug_log("file path: %s", attachment_data->attachment_path);
398
399         if (attachment_data->inline_content_status == EINA_FALSE) {
400                 g_ugd = ugd;
401
402                 Evas_Object *attachment_item = elm_layout_add(ugd->attachment_item_box);
403
404                 elm_layout_file_set(attachment_item, COMPOSER_EDJ_NAME, "layout.attachment");
405                 evas_object_size_hint_weight_set(attachment_item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
406                 evas_object_size_hint_align_set(attachment_item, EVAS_HINT_FILL, EVAS_HINT_FILL);
407
408                 Evas_Object *delete_icon = NULL;
409
410                 _composer_attachment_add_thumbnail(ugd, attachment_item, attachment_data->attachment_path);
411                 delete_icon = _composer_attachment_add_delete_icon(ugd, attachment_item);
412                 _composer_attachment_add_filename(ugd, attachment_data, attachment_item);
413
414                 Evas_Object *attachment_base = elm_layout_add(ugd->attachment_item_box);
415                 elm_layout_theme_set(attachment_base, "layout", "application", "noindicator");
416                 evas_object_size_hint_weight_set(attachment_base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
417                 evas_object_size_hint_align_set(attachment_base, EVAS_HINT_FILL, EVAS_HINT_FILL);
418                 evas_object_show(attachment_base);
419                 elm_object_part_content_set(attachment_base, "elm.swallow.content", attachment_item);
420
421                 elm_box_pack_end(ugd->attachment_item_box, attachment_base);
422                 evas_object_show(attachment_base);
423
424                 evas_object_data_set(delete_icon, "delete_attachment", attachment_base);
425
426                 ugd->attachment_item_obj_list = eina_list_append(ugd->attachment_item_obj_list, attachment_base);
427                 _composer_attachment_set_attach_data(ugd, attachment_base, attachment_data);
428
429                 if (attachment_data->attachment_path) {
430                         edje_object_signal_callback_add(_EDJ(attachment_item), "clicked", "*", _composer_attachment_mouse_clicked, attachment_data);
431                 }
432                 edje_object_signal_callback_add(_EDJ(attachment_item), "clicked", "*", _composer_attachment_unfocus, ugd);
433         } else {
434                 Evas_Object *attachment_base = elm_layout_add(ugd->attachment_item_box);
435
436                 ugd->attachment_item_obj_list = eina_list_append(ugd->attachment_item_obj_list, attachment_base);
437                 _composer_attachment_set_attach_data(ugd, attachment_base, attachment_data);
438         }
439 }
440
441 void _composer_attachment_update_thumbnail(EmailComposerUGD *ugd, Evas_Object *parent, char *filePath)
442 {
443         debug_log("");
444
445         Evas_Object *thumb_nail;
446         const char *path = NULL;
447
448         thumb_nail = elm_object_part_content_get(parent, "attachment.thumbnail.icon");
449
450         if (thumb_nail != NULL) {
451                 evas_object_del(thumb_nail);
452                 thumb_nail = NULL;
453         }
454
455         if (ugd->attachment_list_compressed) {
456                 thumb_nail = elm_icon_add(parent);
457
458                 path = g_strdup(COMPOSER_ICON_DIR "/05_email_icon_attach_40x40.png");
459                 debug_log("path = %s", path);
460                 elm_image_file_set(thumb_nail, path, NULL);
461         } else {
462                 if (!filePath) {
463                         debug_log("savename = %s", filePath);
464
465                         thumb_nail = elm_icon_add(parent);
466
467                         path = g_strdup(MYFILE_IMGE_PATH "/myfile_icon_etc.png");
468                         elm_image_file_set(thumb_nail, path, NULL);
469                 } else {
470                         thumb_nail = _composer_attachment_make_thumbnail(ugd, filePath, parent);
471                 }
472         }
473
474         elm_object_part_content_set(parent, "attachment.thumbnail.icon", thumb_nail);
475         evas_object_show(thumb_nail);
476
477         if (path)
478                 g_free((char *)path);
479 }
480
481 void _composer_attachment_add_thumbnail(EmailComposerUGD *ugd, Evas_Object *parent, char *filePath)
482 {
483         debug_log("");
484
485         Evas_Object *thumb_nail;
486         const char *path = NULL;
487
488         if (ugd->attachment_list_compressed) {
489                 thumb_nail = elm_icon_add(parent);
490
491                 path = g_strdup(COMPOSER_ICON_DIR "/05_email_icon_attach_40x40.png");
492                 debug_log("path = %s", path);
493                 elm_image_file_set(thumb_nail, path, NULL);
494         } else {
495                 if (!filePath) {
496                         debug_log("savename = %s", filePath);
497
498                         thumb_nail = elm_icon_add(parent);
499
500                         path = g_strdup(MYFILE_IMGE_PATH "/myfile_icon_etc.png");
501                         elm_image_file_set(thumb_nail, path, NULL);
502                 } else {
503                         thumb_nail = _composer_attachment_make_thumbnail(ugd, filePath, parent);
504                 }
505         }
506
507         elm_object_part_content_set(parent, "attachment.thumbnail.icon", thumb_nail);
508         evas_object_show(thumb_nail);
509
510         if (path)
511                 g_free((char *)path);
512 }
513
514 Evas_Object *_composer_attachment_add_delete_icon(EmailComposerUGD *ugd, Evas_Object *parent)
515 {
516         debug_log("");
517
518         Evas_Object *delete_icon = elm_button_add(parent);
519         evas_object_show(delete_icon);
520
521         if (ugd->attachment_list_compressed) {
522                 _g_attach_btn = delete_icon;
523                 elm_object_style_set(delete_icon, "expand/closed");
524                 elm_object_part_content_set(parent, "attachment.delete.icon", delete_icon);
525                 toggle = 0;
526                 evas_object_smart_callback_add(delete_icon, "clicked", _composer_attachment_contracted_item_clicked_cb, ugd);
527         } else {
528                 elm_object_style_set(delete_icon, "minus");
529                 elm_object_part_content_set(parent, "attachment.delete.icon", delete_icon);
530
531                 evas_object_smart_callback_add(delete_icon, "clicked", _composer_attachment_delete_icon_clicked_cb, ugd);
532         }
533
534         return delete_icon;
535 }
536
537 void _composer_attachment_add_filename(EmailComposerUGD *ugd, email_attachment_data_t * attachment_data, Evas_Object *parent)
538 {
539         debug_log("");
540
541         int size = 0;
542         char *file_name;
543         char file_string[256] = { 0, };
544
545         if (ugd->attachment_list_compressed) {
546                 size = _composer_get_attachments_total_size(ugd);
547
548                 char temp_name[128] = { 0, };
549                 snprintf(temp_name, sizeof(temp_name), _("IDS_EMAIL_BODY_PD_ATTACHMENTS"), eina_list_count(ugd->attachment_item_obj_list));
550                 file_name = g_strdup(temp_name);
551         } else {
552                 if (ugd->new_mail_info->mail_data->file_path_html && (g_strcmp0(ugd->new_mail_info->mail_data->file_path_html, attachment_data->attachment_path) == 0)) {
553                         size = email_get_file_size(attachment_data->attachment_path);
554                         debug_log("Original html body size(%d)", size);
555                 } else {
556                         size = attachment_data->attachment_size;
557                         debug_log("Attachment size(%d)", size);
558                 }
559                 file_name = g_strdup(attachment_data->attachment_name);
560         }
561
562         char *file_size = (char *)email_get_file_size_string((guint64)size);
563
564         snprintf(file_string, sizeof(file_string), "%s (%s)", file_name, file_size);
565         edje_object_part_text_set(_EDJ(parent), "attachment.filename", file_string);
566
567         g_free(file_size);
568         g_free(file_name);
569 }
570
571 Evas_Object *_composer_attachment_make_thumbnail(EmailComposerUGD *ugd, char *filePath, Evas_Object *parent)
572 {
573         debug_log("");
574
575         Evas_Object *icon = NULL;
576         icon = elm_icon_add(parent);
577
578         char *path = NULL;
579         const char *key = NULL;
580
581         char *type = NULL;
582
583         debug_log("file path: %s", filePath);
584         efreet_mime_init();
585         char *m_type = (char *)efreet_mime_type_get(ecore_file_file_get(filePath));
586
587         if (m_type != NULL)
588                 type = g_strdup(m_type);
589
590         debug_log("mime type: %s", type);
591         efreet_mime_shutdown();
592
593         char thumb_path[MAX_ATTACHMENT_FILE_LEN + 1] = { 0, };
594
595         path = g_strdup(ATTACHMENT_ETC_FILE_PATH);
596
597         char *temp = g_strdup(filePath);
598         char *temp_filepath = g_strdup(filePath);
599         char *token = strtok(temp, "/");
600
601         if (temp)
602                 token = strtok(NULL, "/");
603
604         if (token) {
605                 if (type) {
606                         struct _mtd *mtd = (struct _mtd *)mtd_main;
607
608                         while (mtd && mtd->key) {
609                                 if (strncmp(type, mtd->key, strlen(type)) == 0) {
610                                         if (path) {
611                                                 free(path);
612                                                 path = NULL;
613                                         }
614
615                                         path = g_strdup(mtd->icon_path);
616                                         break;
617                                 }
618                                 mtd++;
619                         }
620
621                         debug_log("file path : %s", filePath);
622
623                         if (strncmp(type, ATTACHMENT_MEDIA_IMAGE, 5) == 0 || strncmp(type, ATTACHMENT_MEDIA_VIDEO, 5) == 0) {
624                                 int err = _composer_attachment_make_ethumb(filePath, thumb_path);
625
626                                 if (err != COMPOSER_ERROR_NONE)
627                                         goto FINISH_OFF;
628                         } else if (strncmp(type, ATTACHMENT_MEDIA_AUDIO, 5) == 0) {
629                                 metadata_extractor_h metadata = NULL;
630                                 int ret = METADATA_EXTRACTOR_ERROR_NONE;
631                                 void *artwork = NULL;
632                                 int artwork_size = 0;
633                                 char *artwork_mime = NULL;
634
635                                 ret = metadata_extractor_create(&metadata);
636                                 debug_log("metadata_extractor_create: %d", ret);
637                                 if (!metadata) {
638                                         debug_log("metadata extractor create failed");
639                                         return NULL;
640                                 }
641
642                                 ret = metadata_extractor_set_path(metadata, filePath);
643                                 debug_log("metadata_extractor_set_path: %d", ret);
644
645                                 ret = metadata_extractor_get_artwork(metadata, &artwork, &artwork_size, &artwork_mime);
646                                 debug_log("metadata_extractor_get_artwork: %d", ret);
647                                 debug_log("artwork_mime: %s, artwork_size: %d", artwork_mime, artwork_size);
648
649                                 if (artwork) {
650                                         gchar *mm_path = NULL;
651                                         int fd = g_file_open_tmp(NULL, &mm_path, NULL);
652
653                                         if (fd != -1) {
654                                                 FILE *fp = fdopen(fd, "w");
655                                                 if (fp == NULL) {
656                                                         debug_log("fail to fdopen()");
657                                                         close(fd);
658                                                 } else {
659                                                         if (fwrite((unsigned char *)artwork, 1, artwork_size, fp) != artwork_size/*1*/) {
660                                                                 debug_log("fail to fwrite()");
661                                                                 fclose(fp);
662                                                                 close(fd);
663                                                         } else {
664                                                                 fflush(fp);
665                                                                 fclose(fp);
666                                                                 close(fd);
667                                                         }
668                                                 }
669                                         }
670
671                                         snprintf(thumb_path, sizeof(thumb_path), "%s", mm_path);
672
673                                         debug_log("file : %s, album art_path : %s", filePath, thumb_path);
674
675                                         if (mm_path) {
676                                                 free(mm_path);
677                                                 mm_path = NULL;
678                                         }
679
680                                         g_free(artwork);
681                                 }
682
683                                 if (artwork_mime)
684                                         g_free(artwork_mime);
685
686                                 ret = metadata_extractor_destroy(metadata);
687                                 debug_log("metadata_extractor_destroy: %d", ret);
688                         }
689                 }
690
691                 token = strtok(temp_filepath, ".");
692                 if (token) {
693                         token = strtok(NULL, ".");
694
695                         if (g_strcmp0(token, ATTACHMENT_MEDIA_VCALENDAR) == 0) {
696                                 snprintf(thumb_path, sizeof(thumb_path), "%s", ATTACHMENT_VCALENDAR_FILE_PATH);
697                         } else if (g_strcmp0(token, ATTACHMENT_MEDIA_VCARD) == 0) {
698                                 snprintf(thumb_path, sizeof(thumb_path), "%s", ATTACHMENT_VCARD_FILE_PATH);
699                         }
700
701                         debug_log("thumb_path: %s", thumb_path);
702                 }
703
704                 if (strlen(thumb_path)) {
705                         elm_image_file_set(icon, thumb_path, NULL);
706                 } else {
707                         elm_image_file_set(icon, path, key);
708                 }
709
710         } else {
711                 if (type != NULL) {
712                         if (strncmp(type, ATTACHMENT_MEDIA_IMAGE, 5) == 0) {
713                                 _composer_make_default_thumbnail(icon, filePath, COMPOSER_ATTACHMENT_ITEM_IMAGE);
714                         } else if (strncmp(type, ATTACHMENT_MEDIA_AUDIO, 5) == 0) {
715                                 _composer_make_default_thumbnail(icon, filePath, COMPOSER_ATTACHMENT_ITEM_SOUND);
716                         } else if (strncmp(type, ATTACHMENT_MEDIA_VIDEO, 5) == 0) {
717                                 _composer_make_default_thumbnail(icon, filePath, COMPOSER_ATTACHMENT_ITEM_VIDEO);
718                         } else {
719                                 _composer_make_default_thumbnail(icon, filePath, COMPOSER_ATTACHMENT_ITEM_ETC);
720                         }
721                 }
722         }
723
724  FINISH_OFF:
725
726         if (path) {
727                 free(path);
728                 path = NULL;
729         }
730         if (type) {
731                 free(type);
732                 type = NULL;
733         }
734
735         if (temp) {
736                 free(temp);
737                 temp = NULL;
738         }
739         if (temp_filepath) {
740                 free(temp_filepath);
741                 temp_filepath = NULL;
742         }
743
744         return icon;
745 }
746
747 int _composer_attachment_make_ethumb(const char *source, char *target)
748 {
749         debug_log("");
750
751         debug_log("file path: %s", source);
752         efreet_mime_init();
753         char *type = (char *)efreet_mime_type_get(ecore_file_file_get(source));
754         char *mime_type = g_strdup(type);
755         debug_log("mime type: %s", mime_type);
756         efreet_mime_shutdown();
757
758         if (mime_type) {
759                 if (strncmp(mime_type, "image", 5) == 0) {
760                         strncpy(target, source, MAX_ATTACHMENT_FILE_LEN);
761                 } else if (strncmp(mime_type, "video", 5) == 0) {
762                         metadata_extractor_h metadata = NULL;
763                         int ret = METADATA_EXTRACTOR_ERROR_NONE;
764                         char *video_width = NULL;
765                         char *video_height = NULL;
766                         char *video_track_cnt = NULL;
767                         void *video_thumbnail = NULL;
768                         int video_thumbnail_len = 0;
769                         int video_w = 0;
770                         int video_h = 0;
771
772                         ret = metadata_extractor_create(&metadata);
773                         debug_log("metadata_extractor_create: %d", ret);
774                         if (!metadata) {
775                                 debug_log("metadata extractor create failed");
776                                 return COMPOSER_ERROR_ETHUMB_FAIL;
777                         }
778
779                         ret = metadata_extractor_set_path(metadata, source);
780                         debug_log("metadata_extractor_set_path: %d", ret);
781
782                         ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_WIDTH, &video_width);
783                         debug_log("metadata_extractor_get_metadata: %d [video_width:%s]", ret, video_width);
784                         ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_HEIGHT, &video_height);
785                         debug_log("metadata_extractor_get_metadata: %d [video_height:%s]", ret, video_height);
786                         ret = metadata_extractor_get_metadata(metadata, METADATA_HAS_VIDEO, &video_track_cnt);
787                         debug_log("metadata_extractor_get_metadata: %d [video_track_cnt:%s]", ret, video_track_cnt);
788
789                         ret = metadata_extractor_get_frame(metadata, &video_thumbnail, &video_thumbnail_len);
790                         debug_log("metadata_extractor_get_frame: %d (video_thumbnail_len:%d)", ret, video_thumbnail_len);
791
792                         if (video_thumbnail) {
793                                 int mm_ret = 0;
794                                 char filename[MAX_ATTACHMENT_FILE_LEN] = { 0, };
795                                 char *file_name = NULL;
796                                 char *file_ext = NULL;
797
798                                 email_parse_get_filename_n_ext_from_path(source, &file_name, &file_ext);
799                                 snprintf(filename, sizeof(filename), "%s%s%s%s", EMAIL_TMP_FOLDER"/", file_name, file_ext, ".jpg");
800                                 g_free(file_name);
801                                 g_free(file_ext);
802
803                                 if (video_width)
804                                         video_w = atoi(video_width);
805                                 if (video_height)
806                                         video_h = atoi(video_height);
807                                 mm_ret = image_util_encode_jpeg(video_thumbnail,
808                                                                                                         video_w, video_h,
809                                                                                                         IMAGE_UTIL_COLORSPACE_RGB888, 70, filename);
810
811                                 if (ecore_file_exists(filename)) {
812                                         strncpy(target, filename, MAX_ATTACHMENT_FILE_LEN);
813                                         debug_log("file : %s, thumb_path : %s", source, target);
814                                 }
815                                 g_free(video_thumbnail);
816                         }
817
818                         if (video_width)
819                                 g_free(video_width);
820                         if (video_height)
821                                 g_free(video_height);
822                         if (video_track_cnt)
823                                 g_free(video_track_cnt);
824
825                         ret = metadata_extractor_destroy(metadata);
826                         debug_log("metadata_extractor_destroy: %d", ret);
827                 }
828         }
829
830         g_free(mime_type);
831
832         return COMPOSER_ERROR_NONE;
833 }
834
835 void _composer_ethumb_generate_cb(void *data, Ethumb *e, Eina_Bool success)
836 {
837         if (success == EINA_TRUE) {
838                 debug_log("Succeed in thumbnail generation");
839         } else {
840                 debug_log("Fail to create thumbnail");
841         }
842 }
843
844 void _composer_attachment_set_attach_data(EmailComposerUGD *ugd, Evas_Object *parent, email_attachment_data_t *attachment_data)
845 {
846         debug_log("");
847
848         evas_object_data_set(parent, "attachment_data", attachment_data);
849 }
850
851 static void _composer_attachment_delete_item_from_fw_attachment_list(EmailComposerUGD *ugd, email_attachment_data_t *attachment_data)
852 {
853         debug_log("");
854         int i = 0;
855         if(ugd == NULL) {
856                 debug_log("ugd == NULL");
857                 return;
858         }
859         debug_log("1. %d", g_list_length(ugd->fw_attachment_list));
860
861         for (i = 0; i < g_list_length(ugd->fw_attachment_list); ++i) {
862                 EMAIL_ATTACHMENT_INFO_S *info = (EMAIL_ATTACHMENT_INFO_S *) g_list_nth_data(ugd->fw_attachment_list, i);
863                 debug_log("%x", info);
864                 if (info) {
865                         debug_log("%d , %d", info->attach_id, attachment_data->attachment_id);
866                         if (info->attach_id == attachment_data->attachment_id) {
867                                 ugd->fw_attachment_list = g_list_remove(ugd->fw_attachment_list, info);
868                                 debug_log("2. %d", g_list_length(ugd->fw_attachment_list));
869                                 ugd->fw_dn_cnt = g_list_length(ugd->fw_attachment_list);
870                         }
871                 }
872         }
873
874         if (ugd->fw_dn_cnt == 0)
875                 ugd->need_download = EINA_FALSE;
876 }
877
878 static void _composer_attachment_delete_icon_clicked_cb(void *data, Evas_Object *obj, void *event_info)
879 {
880         debug_log("");
881
882         if (data == NULL)
883                 return;
884
885         if (obj == NULL)
886                 return;
887
888         EmailComposerUGD *ugd = (EmailComposerUGD *)data;
889
890         if (EINA_FALSE == ewk_view_script_execute(ugd->body_ewkview, COMPOSER_JS_GET_IMAGE_LIST, _composer_get_image_list_cb, (void *)ugd)) {
891                 debug_log("COMPOSER_JS_GET_IMAGE_LIST error.");
892         }
893
894         Evas_Object *object = NULL;
895         object = evas_object_data_get(obj, "delete_attachment");
896
897         ugd->attachment_item_obj_list = eina_list_remove(ugd->attachment_item_obj_list, object);
898
899         email_attachment_data_t *attachment_data = NULL;
900         attachment_data = evas_object_data_get(object, "attachment_data");
901
902         _composer_attachment_delete_item_from_fw_attachment_list(ugd, attachment_data);
903
904         elm_box_unpack(ugd->attachment_item_box, object);
905         evas_object_del(object);
906
907         if (ugd->attachment_contracted_item) {
908                 Evas_Object *contracted_item = evas_object_data_get(ugd->attachment_contracted_item, "attachment_item");
909                 debug_log("contracted_item = %p", contracted_item);
910                 if (eina_list_count(ugd->attachment_item_obj_list) < 2) {
911                         elm_box_unpack(ugd->attachment_item_box, ugd->attachment_contracted_item);
912                         evas_object_del(ugd->attachment_contracted_item);
913                         ugd->attachment_contracted_item = NULL;
914                         ugd->attachment_list_compressed = FALSE;
915                         _composer_attachment_add_filename(ugd, attachment_data, contracted_item);
916                 } else {
917                         ugd->attachment_list_compressed = TRUE;
918                         _composer_attachment_add_filename(ugd, attachment_data, contracted_item);
919                         ugd->attachment_list_compressed = FALSE;
920                 }
921         }
922
923         if (ugd->attachment_item_obj_list == NULL) {
924                 ugd->selected_entry = ugd->priv_selected_entry;
925                 ugd->priv_selected_entry = NULL;
926         }
927
928         if (attachment_data) {
929                 debug_log("attachment_data file name = %s", attachment_data->attachment_path);
930
931                 email_free_attachment_data(&attachment_data, 1);
932                 attachment_data = NULL;
933         }
934
935         _composer_mbe_set_focus(ugd);
936
937         elm_box_recalculate(ugd->attachment_item_box);
938         elm_layout_sizing_eval(ugd->main_layout);
939 }
940
941 bool _composer_attachment_duplicate_check(EmailComposerUGD *ugd, char *pszAttachedFilePath)
942 {
943         debug_log("to be attached file path : %s", pszAttachedFilePath);
944
945         if (ugd == NULL)
946                 return FALSE;
947
948         bool bDuplicated = FALSE;
949
950         Eina_Iterator *it = NULL;
951         Evas_Object *attachment_obj = NULL;
952         email_attachment_data_t *attachment_data = NULL;
953
954         it = eina_list_iterator_new(ugd->attachment_item_obj_list);
955
956         while (eina_iterator_next(it, (void **)&attachment_obj)) {
957                 attachment_data = evas_object_data_get(attachment_obj, "attachment_data");
958
959                 debug_log("attachment_data->attachment_path = %s", attachment_data->attachment_path);
960                 if (attachment_data->attachment_path != NULL) {
961                         if (strcmp(pszAttachedFilePath, attachment_data->attachment_path) == 0) {
962                                 debug_log("Attached file path is duplicated");
963                                 bDuplicated = TRUE;
964                                 break;
965                         }
966                 }
967         }
968
969         if (it) {
970                 eina_iterator_free(it);
971         }
972
973         return bDuplicated;
974 }
975
976 void _composer_attachment_expand_items(EmailComposerUGD *ugd)
977 {
978         debug_log("");
979
980         if (ugd->attachment_list_compressed == EINA_FALSE)
981                 return;
982
983         Eina_List *list = NULL;
984         Evas_Object *attachment_item = NULL;
985
986         EINA_LIST_FOREACH(ugd->attachment_item_obj_list, list, attachment_item) {
987                 if (attachment_item) {
988                         elm_box_pack_end(ugd->attachment_item_box, attachment_item);
989                         evas_object_show(attachment_item);
990                 }
991         }
992
993         ugd->attachment_list_compressed = EINA_FALSE;
994
995         elm_box_recalculate(ugd->attachment_item_box);
996         elm_layout_sizing_eval(ugd->main_layout);
997 }
998
999 void _composer_attachment_contract_items(EmailComposerUGD *ugd)
1000 {
1001         debug_log("");
1002
1003         int nAttachmentObjCount = eina_list_count(ugd->attachment_item_obj_list);
1004
1005         debug_log("attachment_count = %d", nAttachmentObjCount);
1006         debug_log("attachment_list_compressed = %d", ugd->attachment_list_compressed);
1007
1008         if (nAttachmentObjCount > 1 && !ugd->attachment_list_compressed) {
1009                 ugd->attachment_list_compressed = EINA_TRUE;
1010
1011                 Eina_List *list = NULL;
1012                 Evas_Object *attachment_item = NULL;
1013
1014                 EINA_LIST_FOREACH(ugd->attachment_item_obj_list, list, attachment_item) {
1015                         if (attachment_item) {
1016                                 elm_box_unpack(ugd->attachment_item_box, attachment_item);
1017                                 evas_object_hide(attachment_item);
1018                         }
1019                 }
1020
1021                 if (ugd->attachment_contracted_item) {
1022                         Evas_Object *contracted_item = evas_object_data_get(ugd->attachment_contracted_item, "attachment_item");
1023                         debug_log("contracted_item = %p", contracted_item);
1024                         _composer_attachment_add_filename(ugd, NULL, contracted_item);
1025                 } else {
1026                         _composer_attachment_create_contracted_box(ugd);
1027                 }
1028
1029                 if (toggle == 0) {
1030                         char buf[PATH_MAX];
1031                         snprintf(buf, sizeof(buf), "expand/closed");
1032                         elm_object_style_set(_g_attach_btn, buf);
1033                         toggle = 1;
1034                 }
1035         }
1036
1037         elm_box_recalculate(ugd->attachment_item_box);
1038         elm_layout_sizing_eval(ugd->main_layout);
1039 }
1040
1041 void _composer_attachment_create_contracted_box(EmailComposerUGD *ugd)
1042 {
1043         debug_log("");
1044
1045         Evas_Object *contracted_item = NULL;
1046         contracted_item = elm_layout_add(ugd->attachment_item_box);
1047
1048         elm_layout_file_set(contracted_item, COMPOSER_EDJ_NAME, "layout.attachment");
1049         evas_object_size_hint_weight_set(contracted_item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1050         evas_object_size_hint_align_set(contracted_item, EVAS_HINT_FILL, EVAS_HINT_FILL);
1051
1052         _composer_attachment_add_thumbnail(ugd, contracted_item, NULL);
1053         _composer_attachment_add_delete_icon(ugd, contracted_item);
1054         _composer_attachment_add_filename(ugd, NULL, contracted_item);
1055
1056         Evas_Object *contracted_base = elm_layout_add(ugd->attachment_item_box);
1057         elm_layout_theme_set(contracted_base, "layout", "application", "noindicator");
1058         evas_object_size_hint_weight_set(contracted_base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1059         evas_object_size_hint_align_set(contracted_base, EVAS_HINT_FILL, EVAS_HINT_FILL);
1060
1061         evas_object_show(contracted_base);
1062         elm_object_part_content_set(contracted_base, "elm.swallow.content", contracted_item);
1063
1064         elm_box_pack_start(ugd->attachment_item_box, contracted_base);
1065
1066         ugd->attachment_contracted_item = contracted_base;
1067
1068         evas_object_show(contracted_base);
1069
1070         evas_object_data_set(ugd->attachment_contracted_item, "attachment_item", contracted_item);
1071 }
1072
1073 static void _composer_attachment_contracted_item_clicked_cb(void *data, Evas_Object *obj, void *event_info)
1074 {
1075         debug_log("");
1076
1077         EmailComposerUGD *ugd = (EmailComposerUGD *)data;
1078
1079         char buf[PATH_MAX];
1080         Evas_Object *btn = obj;
1081
1082         if (toggle == 1) {
1083                 /* expand button closed style */
1084                 snprintf(buf, sizeof(buf), "expand/opened");
1085                 elm_object_style_set(btn, buf);
1086
1087                 if (ugd->selected_entry == ugd->body_ewkview) {
1088                         debug_log("Webkit unfocused");
1089                         evas_object_focus_set(ugd->body_ewkview, EINA_FALSE);
1090                         if (ewk_view_script_execute(ugd->body_ewkview, COMPOSER_JS_SET_UNFOCUS, _composer_script_executed_cb, NULL) == EINA_FALSE)
1091                                 debug_log("COMPOSER_JS_SET_UNFOCUS failed.");
1092                 }
1093
1094                 elm_object_focus_set(obj, EINA_TRUE);
1095
1096                 _composer_attachment_expand_items(ugd);
1097
1098                 ugd->priv_selected_entry = ugd->selected_entry;
1099                 ugd->selected_entry = ugd->attachment_contracted_item;
1100
1101                 toggle = 0;
1102         } else {
1103                 /* expand button opened style */
1104                 snprintf(buf, sizeof(buf), "expand/closed");
1105                 elm_object_style_set(btn, buf);
1106
1107                 if (ugd->selected_entry == ugd->body_ewkview) {
1108                         debug_log("Webkit unfocused");
1109                         evas_object_focus_set(ugd->body_ewkview, EINA_FALSE);
1110                         if (ewk_view_script_execute(ugd->body_ewkview, COMPOSER_JS_SET_UNFOCUS, _composer_script_executed_cb, NULL) == EINA_FALSE)
1111                                 debug_log("COMPOSER_JS_SET_UNFOCUS failed.");
1112                 }
1113
1114                 elm_object_focus_set(obj, EINA_TRUE);
1115
1116                 _composer_attachment_contract_items(ugd);
1117
1118                 ugd->priv_selected_entry = ugd->selected_entry;
1119                 ugd->selected_entry = ugd->attachment_contracted_item;
1120
1121                 toggle = 1;
1122         }
1123 }
1124
1125 static void _composer_attachment_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
1126 {
1127         debug_log("");
1128
1129         email_attachment_data_t *item_list = (email_attachment_data_t *) data;
1130
1131         debug_log("savename = %s", item_list->attachment_path);
1132
1133         int ret;
1134         service_h service = NULL;
1135         ret = service_create(&service);
1136         debug_log("service_create: %d", ret);
1137         if (!service) {
1138                 debug_log("service create failed");
1139                 return;
1140         }
1141         ret = service_set_operation(service, SERVICE_OPERATION_VIEW);
1142         debug_log("service_set_operation: %d", ret);
1143         ret = service_set_uri(service, item_list->attachment_path);
1144         debug_log("service_set_uri: %d", ret);
1145         ret = service_add_extra_data(service, EMAIL_BUNDLE_KEY_VIDEO_PLAYER_LAUNCH_APP, "email");
1146         debug_log("service_add_extra_data: %d", ret);
1147         ret = service_send_launch_request(service, NULL, NULL);
1148         debug_log("service_send_launch_request: %d", ret);
1149         if (ret != SERVICE_ERROR_NONE) {
1150                 if (g_ugd->composer_noti) {
1151                         evas_object_del(g_ugd->composer_noti);
1152                         g_ugd->composer_noti = NULL;
1153                 }
1154                 g_ugd->composer_noti = _composer_create_noti(g_ugd, false, dgettext("sys_string", "IDS_COM_POP_WARNING"),
1155                         _("IDS_EMAIL_POP_THIS_ATTACHMENT_CANNOT_BE_DISPLAYED"), 0, NULL, NULL, 1.5, _composer_noti_response_cb);
1156         }
1157         ret = service_destroy(service);
1158         debug_log("service_destroy: %d", ret);
1159 }
1160
1161 static void _composer_attachment_unfocus(void *data, Evas_Object *obj, const char *emission, const char *source)
1162 {
1163         debug_log("");
1164
1165         EmailComposerUGD *ugd = (EmailComposerUGD *)data;
1166
1167         Evas_Object *mbe = NULL;
1168         if (ugd->selected_entry == ugd->to_mbe_entry)
1169                 mbe = ugd->to_mbe;
1170         else if (ugd->selected_entry == ugd->cc_mbe_entry)
1171                 mbe = ugd->cc_mbe;
1172         else if (ugd->selected_entry == ugd->bcc_mbe_entry)
1173                 mbe = ugd->bcc_mbe;
1174
1175         /* For unfocus TO mbe */
1176         if (ugd->to_mbe)
1177                 elm_object_focus_set(ugd->to_mbe, EINA_FALSE);
1178         if (ugd->cc_mbe)
1179                 elm_object_focus_set(ugd->cc_mbe, EINA_FALSE);
1180         if (ugd->bcc_mbe)
1181                 elm_object_focus_set(ugd->bcc_mbe, EINA_FALSE);
1182 }