Tizen 2.4.0 rev3 SDK Public Release
[apps/home/quickpanel.git] / daemon / notifications / noti_view_ongoing.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <glib.h>
21
22 #include <Elementary.h>
23
24 #include <vconf.h>
25 #include <notification.h>
26 #include <notification_internal.h>
27 #include <notification_text_domain.h>
28 #include <system_settings.h>
29 #include <tzsh.h>
30 #include <tzsh_quickpanel_service.h>
31
32 #include "quickpanel-ui.h"
33 #include "common_uic.h"
34 #include "common.h"
35 #include "list_util.h"
36 #include "quickpanel_def.h"
37 #include <vi_manager.h>
38 #include "noti_node.h"
39 #include "noti_list_item.h"
40 #include "noti.h"
41 #include "noti_util.h"
42 #include "animated_icon.h"
43
44 #ifdef QP_SCREENREADER_ENABLE
45 #include "accessibility.h"
46 #endif
47
48 #ifdef QP_ANIMATED_IMAGE_ENABLE
49 #include "animated_image.h"
50 #endif
51
52 #define LEN_UNIT_TEXTBLOCK 555
53 #define QP_DEFAULT_ICON RESDIR"/quickpanel_icon_default.png"
54
55 #ifdef QP_SCREENREADER_ENABLE
56 static inline void _check_and_add_to_buffer(Eina_Strbuf *str_buf, const char *text)
57 {
58         char buf_number[QP_UTIL_PHONE_NUMBER_MAX_LEN * 2] = { 0, };
59
60         retif(str_buf == NULL, , "Invalid parameter!");
61
62         if (text != NULL) {
63                 if (strlen(text) > 0) {
64                         if (quickpanel_common_util_is_phone_number(text)) {
65                                 quickpanel_common_util_phone_number_tts_make(buf_number, text,
66                                                 (QP_UTIL_PHONE_NUMBER_MAX_LEN * 2) - 1);
67                                 eina_strbuf_append(str_buf, buf_number);
68                         } else {
69                                 eina_strbuf_append(str_buf, text);
70                         }
71                         eina_strbuf_append_char(str_buf, '\n');
72                 }
73         }
74 }
75 #endif
76
77 static Evas_Object *_check_duplicated_progress_loading(Evas_Object *obj, const char *part, const char *style_name)
78 {
79         Evas_Object *old_content = NULL;
80         const char *old_style_name = NULL;
81
82         retif(obj == NULL, NULL, "Invalid parameter!");
83         retif(part == NULL, NULL, "Invalid parameter!");
84         retif(style_name == NULL, NULL, "Invalid parameter!");
85
86         old_content = elm_object_part_content_get(obj, part);
87         if (old_content != NULL) {
88                 old_style_name = elm_object_style_get(old_content);
89                 if (old_style_name != NULL) {
90                         if (strcmp(old_style_name, style_name) == 0) {
91                                 return old_content;
92                         }
93
94                         elm_object_part_content_unset(obj, part);
95                         evas_object_del(old_content);
96                         old_content = NULL;
97                 }
98         }
99
100         return NULL;
101 }
102
103 static Evas_Object *_check_duplicated_image_loading(Evas_Object *obj, const char *part, const char *file_path)
104 {
105         Evas_Object *old_ic = NULL;
106         const char *old_ic_path = NULL;
107
108         retif(obj == NULL, NULL, "Invalid parameter!");
109         retif(part == NULL, NULL, "Invalid parameter!");
110         retif(file_path == NULL, NULL, "Invalid parameter!");
111
112         old_ic = elm_object_part_content_get(obj, part);
113
114         if (quickpanel_animated_icon_is_same_icon(old_ic, file_path) == 1) {
115                 return old_ic;
116         }
117
118         if (old_ic != NULL) {
119                 elm_image_file_get(old_ic, &old_ic_path, NULL);
120                 if (old_ic_path != NULL) {
121                         if (strcmp(old_ic_path, file_path) == 0)
122                                 return old_ic;
123                 }
124
125                 elm_object_part_content_unset(obj, part);
126                 evas_object_del(old_ic);
127                 old_ic = NULL;
128         }
129
130         return NULL;
131 }
132
133 static void _set_text_to_part(Evas_Object *obj, const char *part, const char *text)
134 {
135         const char *old_text;
136
137         if (!obj || !part || !text) {
138                 ERR("Invalid parameters");
139                 return;
140         }
141
142         old_text = elm_object_part_text_get(obj, part);
143         if (old_text != NULL) {
144                 if (strcmp(old_text, text) == 0) {
145                         return;
146                 }
147         }
148
149         elm_object_part_text_set(obj, part, text);
150 }
151
152 static char *_noti_get_progress(notification_h noti, char *buf, int buf_len)
153 {
154         double size = 0.0;
155         double percentage = 0.0;
156
157         retif(noti == NULL, NULL, "Invalid parameter!");
158         retif(buf == NULL, NULL, "Invalid parameter!");
159
160         notification_get_size(noti, &size);
161         notification_get_progress(noti, &percentage);
162
163         if (percentage > 0) {
164                 if (percentage < 1.0 ) {
165                         if (snprintf(buf, buf_len, "%d%%", (int)(percentage * 100.0 + 0.5)) <= 0) {
166                                 return NULL;
167                         }
168                 }
169                 if (percentage >= 1.0) {
170                         snprintf(buf, buf_len, "%d%%", 100);
171                 }
172
173                 return buf;
174         } else if (size > 0 && percentage == 0) {
175                 if (size > (1 << 30)) {
176                         if (snprintf(buf, buf_len, "%.1lfGB",
177                                                 size / 1000000000.0) <= 0)
178                                 return NULL;
179
180                         return buf;
181                 } else if (size > (1 << 20)) {
182                         if (snprintf(buf, buf_len, "%.1lfMB",
183                                                 size / 1000000.0) <= 0)
184                                 return NULL;
185
186                         return buf;
187                 } else if (size > (1 << 10)) {
188                         if (snprintf(buf, buf_len, "%.1lfKB",
189                                                 size / 1000.0) <= 0)
190                                 return NULL;
191
192                         return buf;
193                 } else {
194                         if (snprintf(buf, buf_len, "%.0lfB", size) <= 0)
195                                 return NULL;
196
197                         return buf;
198                 }
199         }
200
201         return NULL;
202 }
203
204 static void _set_progressbar(Evas_Object *item, notification_h noti)
205 {
206         Evas_Object *ic = NULL;
207         Evas_Object *old_ic = NULL;
208         double size = 0.0;
209         double percentage = 0.0;
210         notification_type_e type = NOTIFICATION_TYPE_NONE;
211         notification_ly_type_e layout = NOTIFICATION_LY_NONE ;
212
213         retif(item == NULL, , "Invalid parameter!");
214         retif(noti == NULL, , "noti is NULL");
215
216         notification_get_type(noti, &type);
217         if (type == NOTIFICATION_TYPE_ONGOING) {
218                 notification_get_size(noti, &size);
219                 notification_get_progress(noti, &percentage);
220                 notification_get_layout(noti, &layout);
221
222                 if (layout != NOTIFICATION_LY_ONGOING_EVENT) {
223                         if (percentage > 0.0 && percentage <= 1.0) {
224                                 old_ic = _check_duplicated_progress_loading(item, "elm.swallow.progress", "list_progress");
225                                 if (old_ic == NULL) {
226                                         ic = elm_progressbar_add(item);
227                                         elm_progressbar_unit_format_set(ic, "%0.0f%%");
228                                         if (ic == NULL)
229                                                 return;
230                                         elm_object_style_set(ic, "list_progress");
231                                 } else {
232                                         ic = old_ic;
233                                 }
234
235                                 elm_progressbar_value_set(ic, percentage);
236                                 elm_progressbar_horizontal_set(ic, EINA_TRUE);
237                                 elm_progressbar_pulse(ic, EINA_FALSE);
238                         } else if ((size >= 0.0 && percentage == 0.0) || ((size < 0.0 && percentage == 0.0)|| (size == 0.0 && percentage < 0.0))) {
239                                 old_ic = _check_duplicated_progress_loading(item, "elm.swallow.progress", "pending");
240                                 if (old_ic == NULL) {
241                                         ic = elm_progressbar_add(item);
242                                         elm_progressbar_unit_format_set(ic, "%0.0f%%");
243                                         if (ic == NULL)
244                                                 return;
245                                         elm_object_style_set(ic, "pending");
246                                 } else {
247                                         ic = old_ic;
248                                 }
249
250                                 elm_progressbar_horizontal_set(ic, EINA_TRUE);
251                                 elm_progressbar_pulse(ic, EINA_TRUE);
252                         }
253                 }
254         }
255
256         if (ic != NULL) {
257                 elm_object_part_content_set(item, "elm.swallow.progress", ic);
258         }
259 }
260
261 static void _set_icon(Evas_Object *item, notification_h noti)
262 {
263         Evas_Object *ic = NULL;
264         Evas_Object *old_ic = NULL;
265         char *icon_path = NULL;
266         char *icon_sub_path = NULL;
267         char *thumbnail_path = NULL;
268         char *main_icon_path = NULL;
269         char *sub_icon_path = NULL;
270         char *icon_default = NULL;
271         char *pkgname = NULL;
272
273         retif(item == NULL, , "Invalid parameter!");
274         retif(noti == NULL, , "noti is NULL");
275
276         notification_get_pkgname(noti, &pkgname);
277         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
278                         &thumbnail_path);
279         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
280         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB, &icon_sub_path);
281
282         if (thumbnail_path != NULL && icon_path != NULL) {
283                 main_icon_path = thumbnail_path;
284                 sub_icon_path = icon_path;
285         } else if (icon_path != NULL && thumbnail_path == NULL) {
286                 main_icon_path = icon_path;
287                 sub_icon_path = icon_sub_path;
288         } else if (icon_path == NULL && thumbnail_path != NULL) {
289                 main_icon_path = thumbnail_path;
290                 sub_icon_path = icon_sub_path;
291         } else {
292                 icon_default = quickpanel_common_ui_get_pkginfo_icon(pkgname);
293                 main_icon_path = icon_default;
294                 sub_icon_path = NULL;
295         }
296
297         if (main_icon_path != NULL) {
298                 old_ic = _check_duplicated_image_loading(item,
299                                 "elm.swallow.thumbnail", main_icon_path);
300
301                 if (old_ic == NULL) {
302                         ic = quickpanel_animated_icon_get(item, main_icon_path);
303                         if (ic == NULL) {
304                                 ic = elm_image_add(item);
305                                 elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
306                                 elm_image_file_set(ic, main_icon_path, quickpanel_animated_image_get_groupname(main_icon_path));
307 #ifdef QP_ANIMATED_IMAGE_ENABLE
308                                 quickpanel_animated_image_add(ic);
309 #endif
310                                 if (!strncmp(main_icon_path, QP_PRELOAD_NOTI_ICON_PATH, strlen(QP_PRELOAD_NOTI_ICON_PATH)))     {
311                                         DBG("Apply color theme [%s]", main_icon_path);
312                                         evas_object_color_set(ic, 155, 216, 226, 255);
313                                 } else {
314                                         elm_image_aspect_fixed_set(ic, EINA_TRUE);
315                                 }
316                         }
317                         elm_object_part_content_set(item, "elm.swallow.thumbnail", ic);
318                 }
319         }
320
321         if (sub_icon_path != NULL) {
322                 old_ic = _check_duplicated_image_loading(item,
323                                 "elm.swallow.icon", sub_icon_path);
324
325                 if (old_ic == NULL) {
326                         ic = elm_image_add(item);
327                         elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
328                         elm_image_file_set(ic, sub_icon_path, quickpanel_animated_image_get_groupname(sub_icon_path));
329                         elm_object_part_content_set(item, "elm.swallow.icon", ic);
330                         elm_object_signal_emit(item, "elm.icon.bg.show", "elm");
331                 }
332         }
333
334         if (main_icon_path == NULL && sub_icon_path == NULL) {
335                 old_ic = _check_duplicated_image_loading(item,
336                                 "elm.swallow.thumbnail", QP_DEFAULT_ICON);
337
338                 if (old_ic == NULL) {
339                         ic = elm_image_add(item);
340                         elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
341                         elm_image_file_set(ic, QP_DEFAULT_ICON, quickpanel_animated_image_get_groupname(QP_DEFAULT_ICON));
342                         elm_object_part_content_set(item, "elm.swallow.thumbnail", ic);
343 #ifdef QP_ANIMATED_IMAGE_ENABLE
344                         quickpanel_animated_image_add(ic);
345 #endif
346                 }
347         }
348
349         if (icon_default != NULL) {
350                 free(icon_default);
351         }
352 }
353
354 static void _set_text(Evas_Object *item, notification_h noti)
355 {
356         char *text = NULL;
357         char *text_utf8 = NULL;
358         char *domain = NULL;
359         char *dir = NULL;
360         char *pkgname = NULL;
361         //      char *caller_pkgname = NULL;
362         int group_id = 0, priv_id = 0;
363         char buf[128] = { 0, };
364         notification_type_e type = NOTIFICATION_TYPE_NONE;
365         double size = 0.0;
366         double percentage = 0.0;
367         notification_ly_type_e layout = NOTIFICATION_LY_NONE ;
368 #ifdef QP_SCREENREADER_ENABLE
369         Evas_Object *ao = NULL;
370         Eina_Strbuf *str_buf = NULL;
371 #endif
372         Evas_Object *textblock = NULL;
373         int len_w = 0, num_line = 1, view_height = 0;
374         struct appdata *ad = quickpanel_get_app_data();
375         char *text_count = NULL;
376         int ret;
377
378         if (!ad || !item || !noti) {
379                 ERR("Invalid parameters: %p %p %p", ad, item, noti);
380                 return;
381         }
382
383         /* Set text domain */
384         notification_get_text_domain(noti, &domain, &dir);
385         if (domain != NULL && dir != NULL) {
386                 bindtextdomain(domain, dir);
387         }
388
389 #ifdef QP_SCREENREADER_ENABLE
390         ao = quickpanel_accessibility_screen_reader_object_get(item, SCREEN_READER_OBJ_TYPE_ELM_OBJECT, "focus", item);
391         if (ao != NULL) {
392                 str_buf = eina_strbuf_new();
393                 elm_access_info_set(ao, ELM_ACCESS_TYPE, _("IDS_QP_BUTTON_NOTIFICATION"));
394         }
395 #endif
396
397         /* Get pkgname & id */
398         ret = notification_get_pkgname(noti, &pkgname);
399         if (ret != NOTIFICATION_ERROR_NONE) {
400                 ERR("Unable to get the pkgname");
401         }
402         //      notification_get_application(noti, &caller_pkgname);
403         ret = notification_get_id(noti, &group_id, &priv_id);
404         if (ret != NOTIFICATION_ERROR_NONE) {
405                 ERR("Unable to get id");
406         }
407         ret = notification_get_type(noti, &type);
408         if (ret != NOTIFICATION_ERROR_NONE) {
409                 ERR("Unable to get type");
410         }
411         ret = notification_get_size(noti, &size);
412         if (ret != NOTIFICATION_ERROR_NONE) {
413                 ERR("Unable to get size");
414         }
415         ret = notification_get_progress(noti, &percentage);
416         if (ret != NOTIFICATION_ERROR_NONE) {
417                 ERR("Unable to get progress");
418         }
419         ret = notification_get_layout(noti, &layout);
420         if (ret != NOTIFICATION_ERROR_NONE) {
421                 ERR("Unable to get layout");
422         }
423         ret = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &text_count);
424         if (ret != NOTIFICATION_ERROR_NONE) {
425                 ERR("Unable to get event_count");
426         } 
427
428         SDBG("percentage:%f size:%f", percentage, size);
429
430         text = quickpanel_noti_util_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
431         if (ret == NOTIFICATION_ERROR_NONE && text != NULL) {
432                 quickpanel_common_util_char_replace(text, _NEWLINE, _SPACE);
433                 _set_text_to_part(item, "elm.text.title", text);
434 #ifdef QP_SCREENREADER_ENABLE
435                 _check_and_add_to_buffer(str_buf, text);
436 #endif
437         }
438
439         text = quickpanel_noti_util_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
440         if (text != NULL) {
441                 if (layout == NOTIFICATION_LY_ONGOING_EVENT) {
442                         text_utf8 = elm_entry_utf8_to_markup(text);
443                         if (text_utf8 != NULL) {
444                                 _set_text_to_part(item, "elm.text.content", text_utf8);
445                                 free(text_utf8);
446                         } else {
447                                 _set_text_to_part(item, "elm.text.content", text);
448                         }
449                         textblock = (Evas_Object *)edje_object_part_object_get(_EDJ(item), "elm.text.content");
450                         evas_object_textblock_size_native_get(textblock, &len_w, NULL);
451                         num_line = len_w / (LEN_UNIT_TEXTBLOCK * ad->scale);
452                         num_line = (len_w - (num_line * (LEN_UNIT_TEXTBLOCK * ad->scale))) > 0 ? num_line + 1 : num_line;
453                         if (num_line <= 1) {
454                                 elm_object_signal_emit(item, "line1.set", "prog");
455                                 view_height = QP_THEME_LIST_ITEM_ONGOING_EVENT_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT;
456                         } else /*if (num_line >= 2 && num_line < 3)*/ {
457                                 elm_object_signal_emit(item, "line2.set", "prog");
458                                 view_height = QP_THEME_LIST_ITEM_ONGOING_EVENT_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT;
459                         } /*else {
460                                 elm_object_signal_emit(item, "line3.set", "prog");
461                                 view_height = QP_THEME_LIST_ITEM_ONGOING_EVENT_LINE3_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT;
462                                 }*/
463                         quickpanel_uic_initial_resize(item, view_height);
464 #ifdef QP_SCREENREADER_ENABLE
465                         _check_and_add_to_buffer(str_buf, text);
466 #endif
467                 } else {
468                         quickpanel_common_util_char_replace(text, _NEWLINE, _SPACE);
469                         _set_text_to_part(item, "elm.text.content", text);
470 #ifdef QP_SCREENREADER_ENABLE
471                         _check_and_add_to_buffer(str_buf, text);
472 #endif
473                 }
474         }
475
476         if (layout != NOTIFICATION_LY_ONGOING_EVENT) {
477                 text = _noti_get_progress(noti, buf,  sizeof(buf));
478                 if (text != NULL) {
479                         quickpanel_common_util_char_replace(text, _NEWLINE, _SPACE);
480 #ifdef QP_SCREENREADER_ENABLE
481                         _check_and_add_to_buffer(str_buf, text);
482 #endif
483                 } else {
484                         _set_text_to_part(item, "elm.text.time", "");
485                 }
486         } else {
487                 const char *get_content;
488
489                 get_content = elm_object_part_text_get(item, "elm.text.content");
490                 if (get_content == NULL || strlen(get_content) == 0) {
491                         // if there is no content, move title to vertical center.
492                         elm_object_signal_emit(item, "title.move.center", "prog");
493                 }
494         }
495
496         if (layout == NOTIFICATION_LY_ONGOING_PROGRESS && text_count != NULL) {
497                 _set_text_to_part(item, "elm.text.count", text_count);
498                 if (elm_object_part_text_get(item, "elm.text.count") != NULL) {
499                         elm_object_signal_emit(item, "content.short", "prog");
500                         elm_object_signal_emit(item, "count.show", "prog");
501                 }
502         }
503
504 #ifdef QP_SCREENREADER_ENABLE
505         if (ao != NULL && str_buf != NULL) {
506                 elm_access_info_set(ao, ELM_ACCESS_INFO, eina_strbuf_string_get(str_buf));
507                 eina_strbuf_free(str_buf);
508         }
509 #endif
510 }
511
512 static Evas_Object *_create(notification_h noti, Evas_Object *parent)
513 {
514         int view_height = 0;
515         Evas_Object *view = NULL;
516         const char *view_layout_group = NULL;
517         retif(parent == NULL, NULL, "Invalid parameter!");
518         retif(noti == NULL, NULL, "Invalid parameter!");
519
520         notification_ly_type_e layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
521         notification_get_layout(noti, &layout);
522
523         if (layout == NOTIFICATION_LY_ONGOING_EVENT) {
524                 view_layout_group = "quickpanel/listitem/event";
525                 view_height = QP_THEME_LIST_ITEM_ONGOING_EVENT_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT;
526         } else if (layout == NOTIFICATION_LY_ONGOING_PROGRESS) {
527                 view_layout_group = "quickpanel/listitem/progress";
528                 view_height = QP_THEME_LIST_ITEM_ONGOING_PROGRESS_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT;
529         }
530
531         view = elm_layout_add(parent);
532         if (view != NULL) {
533                 elm_layout_file_set(view, DEFAULT_EDJ, view_layout_group);
534                 evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
535                 evas_object_size_hint_align_set(view, EVAS_HINT_FILL, EVAS_HINT_FILL);
536                 quickpanel_uic_initial_resize(view, view_height);
537                 evas_object_show(view);
538         } else {
539                 ERR("failed to create ongoing notification view");
540         }
541
542         return view;
543 }
544
545 static void _update(noti_node_item *noti_node, notification_ly_type_e layout, Evas_Object *item)
546 {
547         retif(item == NULL, , "Invalid parameter!");
548         retif(noti_node == NULL, , "Invalid parameter!");
549
550         _set_progressbar(item, noti_node->noti);
551         _set_icon(item, noti_node->noti);
552         _set_text(item, noti_node->noti);
553 }
554
555 Noti_View_H ongoing_noti_view_h = {
556         .name                   = "ongoing_noti_view",
557         .create                 = _create,
558         .update                 = _update,
559         .remove                 = NULL,
560 };