Tizen 2.4.0 rev3 SDK Public Release
[apps/home/quickpanel.git] / daemon / notifications / noti_view_listype.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
19 #include <Elementary.h>
20 #include <string.h>
21 #include <glib.h>
22
23 #include <notification.h>
24 #include <notification_text_domain.h>
25 #include <system_settings.h>
26 #include <vconf.h>
27 #include <tzsh.h>
28 #include <tzsh_quickpanel_service.h>
29
30 #include "quickpanel-ui.h"
31 #include "common_uic.h"
32 #include "common.h"
33 #include "list_util.h"
34 #include "quickpanel_def.h"
35 #include "vi_manager.h"
36 #include "noti_node.h"
37 #include "noti_list_item.h"
38 #include "noti.h"
39 #include "noti_util.h"
40 #include "animated_icon.h"
41
42 #ifdef QP_SCREENREADER_ENABLE
43 #include "accessibility.h"
44 #endif
45
46 #ifdef QP_ANIMATED_IMAGE_ENABLE
47 #include "animated_image.h"
48 #endif
49
50 #define LEN_UNIT_TEXTBLOCK 560
51 #define QP_DEFAULT_ICON RESDIR"/quickpanel_icon_default.png"
52
53 #ifdef QP_SCREENREADER_ENABLE
54 static inline void _check_and_add_to_buffer(Eina_Strbuf *str_buf, const char *text)
55 {
56         char buf_number[QP_UTIL_PHONE_NUMBER_MAX_LEN * 2] = { 0, };
57
58         retif(str_buf == NULL, , "Invalid parameter!");
59
60         if (text != NULL) {
61                 if (strlen(text) > 0) {
62                         if (quickpanel_common_util_is_phone_number(text)) {
63                                 quickpanel_common_util_phone_number_tts_make(buf_number, text,
64                                                 (QP_UTIL_PHONE_NUMBER_MAX_LEN * 2) - 1);
65                                 eina_strbuf_append(str_buf, buf_number);
66                         } else {
67                                 eina_strbuf_append(str_buf, text);
68                         }
69                         eina_strbuf_append_char(str_buf, '\n');
70                 }
71         }
72 }
73 #endif
74
75 static Evas_Object *_check_duplicated_image_loading(Evas_Object *obj, const char *part, const char *file_path)
76 {
77         Evas_Object *old_ic = NULL;
78         const char *old_ic_path = NULL;
79
80         retif(obj == NULL, NULL, "Invalid parameter!");
81         retif(part == NULL, NULL, "Invalid parameter!");
82         retif(file_path == NULL, NULL, "Invalid parameter!");
83
84         old_ic = elm_object_part_content_get(obj, part);
85
86         if (quickpanel_animated_icon_is_same_icon(old_ic, file_path) == 1) {
87                 return old_ic;
88         }
89
90         if (old_ic != NULL) {
91                 elm_image_file_get(old_ic, &old_ic_path, NULL);
92                 if (old_ic_path != NULL) {
93                         if (strcmp(old_ic_path, file_path) == 0)
94                                 return old_ic;
95                 }
96
97                 elm_object_part_content_unset(obj, part);
98                 evas_object_del(old_ic);
99                 old_ic = NULL;
100         }
101
102         return NULL;
103 }
104
105 static void _set_text_to_part(Evas_Object *obj, const char *part, const char *text)
106 {
107         const char *old_text = NULL;
108
109         retif(obj == NULL, , "Invalid parameter!");
110         retif(part == NULL, , "Invalid parameter!");
111         retif(text == NULL, , "Invalid parameter!");
112
113         old_text = elm_object_part_text_get(obj, part);
114         if (old_text != NULL) {
115                 if (strcmp(old_text, text) == 0) {
116                         return;
117                 }
118         }
119
120         elm_object_part_text_set(obj, part, text);
121 }
122
123 static void _set_icon(Evas_Object *item, notification_h noti)
124 {
125         Evas_Object *ic = NULL;
126         Evas_Object *old_ic = NULL;
127         char *icon_path = NULL;
128         char *icon_sub_path = NULL;
129         char *thumbnail_path = NULL;
130         char *main_icon_path = NULL;
131         char *sub_icon_path = NULL;
132         char *icon_default = NULL;
133         char *pkgname = NULL;
134
135         retif(item == NULL, , "Invalid parameter!");
136         retif(noti == NULL, , "noti is NULL");
137
138         notification_get_pkgname(noti, &pkgname);
139         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
140                         &thumbnail_path);
141         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
142         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON_SUB, &icon_sub_path);
143
144         if (thumbnail_path != NULL && icon_path != NULL) {
145                 main_icon_path = thumbnail_path;
146                 sub_icon_path = icon_path;
147         } else if (icon_path != NULL && thumbnail_path == NULL) {
148                 main_icon_path = icon_path;
149                 sub_icon_path = icon_sub_path;
150         } else if (icon_path == NULL && thumbnail_path != NULL) {
151                 main_icon_path = thumbnail_path;
152                 sub_icon_path = icon_sub_path;
153         } else {
154                 icon_default = quickpanel_common_ui_get_pkginfo_icon(pkgname);
155                 main_icon_path = icon_default;
156                 sub_icon_path = NULL;
157         }
158
159         if (main_icon_path != NULL) {
160                 old_ic = _check_duplicated_image_loading(item,
161                                 "elm.swallow.thumbnail", main_icon_path);
162
163                 if (old_ic == NULL) {
164                         ic = quickpanel_animated_icon_get(item, main_icon_path);
165                         if (ic == NULL) {
166                                 ic = elm_image_add(item);
167                                 elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
168                                 elm_image_file_set(ic, main_icon_path, quickpanel_animated_image_get_groupname(main_icon_path));
169 #ifdef QP_ANIMATED_IMAGE_ENABLE
170                                 quickpanel_animated_image_add(ic);
171 #endif
172
173                                 if (!strncmp(main_icon_path, QP_PRELOAD_NOTI_ICON_PATH, strlen(QP_PRELOAD_NOTI_ICON_PATH)))     {
174                                         DBG("Apply color theme [%s]", main_icon_path);
175                                         evas_object_color_set(ic, 155, 216, 226, 255);
176                                 } else {
177                                         elm_image_aspect_fixed_set(ic, EINA_TRUE);
178                                 }
179                         }
180                         elm_object_part_content_set(item, "elm.swallow.thumbnail", ic);
181                 }
182         }
183
184         if (sub_icon_path != NULL) {
185                 old_ic = _check_duplicated_image_loading(item,
186                                 "elm.swallow.icon", sub_icon_path);
187
188                 if (old_ic == NULL) {
189                         ic = elm_image_add(item);
190                         elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
191                         elm_image_file_set(ic, sub_icon_path, quickpanel_animated_image_get_groupname(sub_icon_path));
192                         elm_object_part_content_set(item, "elm.swallow.icon", ic);
193                         elm_object_signal_emit(item, "elm.icon.bg.show", "elm");
194                 }
195         }
196
197         if (main_icon_path == NULL && sub_icon_path == NULL) {
198                 old_ic = _check_duplicated_image_loading(item,
199                                 "elm.swallow.thumbnail", QP_DEFAULT_ICON);
200
201                 if (old_ic == NULL) {
202                         ic = elm_image_add(item);
203                         elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
204                         elm_image_file_set(ic, QP_DEFAULT_ICON, quickpanel_animated_image_get_groupname(QP_DEFAULT_ICON));
205                         elm_object_part_content_set(item, "elm.swallow.thumbnail", ic);
206 #ifdef QP_ANIMATED_IMAGE_ENABLE
207                         quickpanel_animated_image_add(ic);
208 #endif
209                 }
210         }
211
212         if (icon_default != NULL) {
213                 free(icon_default);
214         }
215 }
216
217 static void _set_text(Evas_Object *item, notification_h noti)
218 {
219         int noti_err = NOTIFICATION_ERROR_NONE;
220         char *text = NULL;
221         char *domain = NULL;
222         char *dir = NULL;
223         time_t noti_time;
224         char buf[512] = {0,};
225 #ifdef QP_SCREENREADER_ENABLE
226         Evas_Object *ao = NULL;
227         Eina_Strbuf *str_buf = NULL;
228 #endif
229         struct appdata *ad = quickpanel_get_app_data();
230
231         retif(ad == NULL, , "Invalid parameter!");
232         retif(item == NULL, , "Invalid parameter!");
233         retif(noti == NULL, , "noti is NULL");
234
235         /* Set text domain */
236         notification_get_text_domain(noti, &domain, &dir);
237         if (domain != NULL && dir != NULL) {
238                 bindtextdomain(domain, dir);
239         }
240
241 #ifdef QP_SCREENREADER_ENABLE
242         ao = quickpanel_accessibility_screen_reader_object_get(item,
243                         SCREEN_READER_OBJ_TYPE_ELM_OBJECT, "focus", item);
244         if (ao != NULL) {
245                 str_buf = eina_strbuf_new();
246                 elm_access_info_set(ao, ELM_ACCESS_TYPE, _("IDS_QP_BUTTON_NOTIFICATION"));
247         }
248 #endif
249
250         /* Get pkgname & id */
251
252         text = quickpanel_noti_util_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
253         if (text != NULL) {
254                 quickpanel_common_util_char_replace(text, _NEWLINE, _SPACE);
255                 _set_text_to_part(item, "elm.text.title", text);
256 #ifdef QP_SCREENREADER_ENABLE
257                 _check_and_add_to_buffer(str_buf, text);
258 #endif
259         }
260
261         noti_err = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &text);
262         if (noti_err == NOTIFICATION_ERROR_NONE && text != NULL) {
263                 quickpanel_common_util_char_replace(text, _NEWLINE, _SPACE);
264                 int count = atoi(text);
265                 if (count > 999) {
266                         _set_text_to_part(item, "elm.text.count", "999+");
267                 } else {
268                         _set_text_to_part(item, "elm.text.count", text);
269                 }
270 #ifdef QP_SCREENREADER_ENABLE
271                 _check_and_add_to_buffer(str_buf, text);
272 #endif
273         }
274
275         text = quickpanel_noti_util_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
276         if (text != NULL) {
277                 quickpanel_common_util_char_replace(text, _NEWLINE, _SPACE);
278                 _set_text_to_part(item, "elm.text.content", text);
279 #ifdef QP_SCREENREADER_ENABLE
280                 _check_and_add_to_buffer(str_buf, text);
281 #endif
282         }
283
284         noti_err = notification_get_time(noti, &noti_time);
285         if (noti_time == 0.0) {
286                 noti_err = notification_get_insert_time(noti, &noti_time);
287         }
288         if (noti_err == NOTIFICATION_ERROR_NONE) {
289                 quickpanel_noti_util_get_time(noti_time, buf, 512);
290                 _set_text_to_part(item, "elm.text.time", buf);
291 #ifdef QP_SCREENREADER_ENABLE
292                 _check_and_add_to_buffer(str_buf, buf);
293 #endif
294         }
295
296         if (elm_object_part_text_get(item, "elm.text.count") != NULL) {
297                 elm_object_signal_emit(item, "content.short", "prog");
298                 elm_object_signal_emit(item, "count.show", "prog");
299         }
300         if (elm_object_part_text_get(item, "elm.text.time") != NULL) {
301                 elm_object_signal_emit(item, "title.short", "prog");
302         }
303
304         const char *get_content = elm_object_part_text_get(item, "elm.text.content");
305         if (get_content == NULL || strlen(get_content) == 0) {
306                 // if there is no content, move title to vertical center.
307                 elm_object_signal_emit(item, "title.move.center", "prog");
308                 if (elm_object_part_text_get(item, "elm.text.time") != NULL) {
309                         elm_object_signal_emit(item, "title.short.center", "prog");
310                         elm_object_signal_emit(item, "time.move.center", "prog");
311                 }
312         } else {
313                 elm_object_signal_emit(item, "title.move.default", "prog");
314                 if (elm_object_part_text_get(item, "elm.text.time") != NULL) {
315                         elm_object_signal_emit(item, "time.move.default", "prog");
316                         elm_object_signal_emit(item, "title.short", "prog");
317                 } else {
318                         elm_object_signal_emit(item, "title.text.default", "prog");
319                 }
320         }
321 #ifdef QP_SCREENREADER_ENABLE
322         if (ao != NULL && str_buf != NULL) {
323                 elm_access_info_set(ao, ELM_ACCESS_INFO, eina_strbuf_string_get(str_buf));
324                 eina_strbuf_free(str_buf);
325         }
326 #endif
327 }
328
329 static Evas_Object *_create(notification_h noti, Evas_Object *parent)
330 {
331         int view_height = 0;
332         Evas_Object *view = NULL;
333         const char *view_layout_group = NULL;
334         retif(parent == NULL, NULL, "Invalid parameter!");
335         retif(noti == NULL, NULL, "Invalid parameter!");
336
337         notification_ly_type_e layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
338         notification_get_layout(noti, &layout);
339
340         view_layout_group = "quickpanel/listitem/notification";
341         view_height = QP_THEME_LIST_ITEM_NOTIFICATION_LISTTYPE_HEIGHT + QP_THEME_LIST_ITEM_SEPERATOR_HEIGHT;
342
343         view = elm_layout_add(parent);
344         if (view != NULL) {
345                 elm_layout_file_set(view, DEFAULT_EDJ, view_layout_group);
346                 evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
347                 evas_object_size_hint_align_set(view, EVAS_HINT_FILL, EVAS_HINT_FILL);
348                 quickpanel_uic_initial_resize(view, view_height);
349                 evas_object_show(view);
350         } else {
351                 ERR("failed to create ongoing notification view");
352         }
353
354         return view;
355 }
356
357 static void _update(noti_node_item *noti_node, notification_ly_type_e layout, Evas_Object *item)
358 {
359         retif(item == NULL, , "Invalid parameter!");
360         retif(noti_node == NULL, , "Invalid parameter!");
361
362         _set_icon(item, noti_node->noti);
363         _set_text(item, noti_node->noti);
364 }
365
366 Noti_View_H noti_view_listtype_h = {
367         .name                   = "noti_view_listtype",
368         .create                 = _create,
369         .update                 = _update,
370         .remove                 = NULL,
371 };