merge with master
[apps/core/preloaded/quickpanel.git] / daemon / notifications / noti.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *  http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <appsvc.h>
18
19 #include <time.h>
20 #include <vconf.h>
21 #include <appcore-common.h>
22 #include <app_service.h>
23 #include <runtime_info.h>
24 #include <Ecore_X.h>
25
26 #include <unicode/uloc.h>
27 #include <unicode/udat.h>
28 #include <unicode/udatpg.h>
29 #include <unicode/ustring.h>
30 #include "noti_node.h"
31 #include <notification.h>
32
33 #include "quickpanel-ui.h"
34 #include "common.h"
35 #include "list_util.h"
36 #include "quickpanel_theme_def.h"
37 #include "noti_gridbox.h"
38 #include "noti_box.h"
39 #include "noti.h"
40
41 #ifndef VCONFKEY_QUICKPANEL_STARTED
42 #define VCONFKEY_QUICKPANEL_STARTED "memory/private/"PACKAGE_NAME"/started"
43 #endif /* VCONFKEY_QUICKPANEL_STARTED */
44
45 #define QP_DEFAULT_ICON ICONDIR"/quickpanel_icon_default.png"
46 #define QP_NOTI_DAY_DEC (24 * 60 * 60)
47
48 #define QP_NOTI_ONGOING_DBUS_PATH       "/dbus/signal"
49 #define QP_NOTI_ONGOING_DBUS_INTERFACE  "notification.ongoing"
50
51 static int suspended;
52
53 noti_node *g_noti_node;
54 static Eina_List *g_animated_image_list;
55
56 static Evas_Object *g_noti_gridbox;
57 static Elm_Genlist_Item_Class *itc_noti;
58 static Elm_Genlist_Item_Class *itc_ongoing;
59 static Elm_Genlist_Item_Class *g_itc;
60
61 static Evas_Object *g_window;
62
63 static Elm_Object_Item *noti_group;
64 static Elm_Object_Item *ongoing_first;
65 static Elm_Object_Item *noti_first;
66
67 static int quickpanel_noti_init(void *data);
68 static int quickpanel_noti_fini(void *data);
69 static int quickpanel_noti_suspend(void *data);
70 static int quickpanel_noti_resume(void *data);
71 static void quickpanel_noti_lang_changed(void *data);
72 static void quickpanel_noti_refresh(void *data);
73 static unsigned int quickpanel_noti_get_height(void *data);
74
75 QP_Module noti = {
76         .name = "noti",
77         .init = quickpanel_noti_init,
78         .fini = quickpanel_noti_fini,
79         .suspend = quickpanel_noti_suspend,
80         .resume = quickpanel_noti_resume,
81         .lang_changed = quickpanel_noti_lang_changed,
82         .hib_enter = NULL,
83         .hib_leave = NULL,
84         .refresh = quickpanel_noti_refresh,
85         .get_height = quickpanel_noti_get_height,
86 };
87
88 Eina_Bool _quickpanel_noti_update_notibox_idler(void *data)
89 {
90         retif(data == NULL, ECORE_CALLBACK_CANCEL, "data is null");
91
92         Elm_Object_Item *item = data;
93         elm_genlist_item_update(item);
94
95         return ECORE_CALLBACK_CANCEL;
96 }
97
98 static void _quickpanel_noti_update_notibox(void) {
99         if (noti_group != NULL) {
100                 ecore_idler_add(_quickpanel_noti_update_notibox_idler, noti_group);
101         }
102
103         if (noti_first != NULL) {
104                 ecore_idler_add(_quickpanel_noti_update_notibox_idler, noti_first);
105         }
106 }
107
108 static void _quickpanel_noti_clear_clicked_cb(void *data, Evas_Object * obj,
109                                         void *event_info)
110 {
111         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
112
113         noti_err = notifiation_clear(NOTIFICATION_TYPE_NOTI);
114
115         DBG("Clear Clicked : noti_err(%d)", noti_err);
116
117         quickpanel_play_feedback();
118 }
119
120 static char *_quickpanel_noti_get_progress(notification_h noti, char *buf,
121                                            int buf_len)
122 {
123         double size = 0.0;
124         double percentage = 0.0;
125
126         retif(noti == NULL, NULL, "Invalid parameter!");
127
128         notification_get_size(noti, &size);
129         notification_get_progress(noti, &percentage);
130
131         if (percentage < 1 && percentage > 0) {
132                 if (snprintf(buf, buf_len, "%d%%", (int)(percentage * 100))
133                         <= 0)
134                         return NULL;
135
136                 return buf;
137         } else if (size > 0) {
138                 if (size > (1 << 30)) {
139                         if (snprintf(buf, buf_len, "%.1lfGB",
140                                 size / 1000000000.0) <= 0)
141                                 return NULL;
142
143                         return buf;
144                 } else if (size > (1 << 20)) {
145                         if (snprintf(buf, buf_len, "%.1lfMB",
146                                 size / 1000000.0) <= 0)
147                                 return NULL;
148
149                         return buf;
150                 } else if (size > (1 << 10)) {
151                         if (snprintf(buf, buf_len, "%.1lfKB",
152                                 size / 1000.0) <= 0)
153                                 return NULL;
154
155                         return buf;
156                 } else {
157                         if (snprintf(buf, buf_len, "%lfB", size) <= 0)
158                                 return NULL;
159
160                         return buf;
161                 }
162         }
163
164         return NULL;
165 }
166
167 static notification_h _quickpanel_noti_update_item_progress(const char *pkgname,
168                                                             int priv_id,
169                                                             double progress)
170 {
171         char *noti_pkgname = NULL;
172         int noti_priv_id = 0;
173
174         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
175
176         if (node != NULL && node->noti != NULL) {
177                 notification_get_pkgname(node->noti, &noti_pkgname);
178                 notification_get_id(node->noti, NULL, &noti_priv_id);
179                 if (!strcmp(noti_pkgname, pkgname)
180                     && priv_id == noti_priv_id) {
181                         notification_set_progress(node->noti, progress);
182                         return node->noti;
183                 }
184         }
185
186         return NULL;
187 }
188
189 static notification_h _quickpanel_noti_update_item_size(const char *pkgname,
190                                                         int priv_id,
191                                                         double size)
192 {
193         char *noti_pkgname = NULL;
194         int noti_priv_id = 0;
195
196         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
197
198         if (node != NULL && node->noti != NULL) {
199                 notification_get_pkgname(node->noti, &noti_pkgname);
200                 notification_get_id(node->noti, NULL, &noti_priv_id);
201                 if (!strcmp(noti_pkgname, pkgname)
202                     && priv_id == noti_priv_id) {
203                         notification_set_size(node->noti, size);
204                         return node->noti;
205                 }
206         }
207
208         return NULL;
209 }
210
211 static notification_h _quickpanel_noti_update_item_content(const char *pkgname,
212                                                         int priv_id,
213                                                         char *content)
214 {
215         char *noti_pkgname = NULL;
216         int noti_priv_id = 0;
217
218         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
219
220         if (node != NULL && node->noti != NULL) {
221                 notification_get_pkgname(node->noti, &noti_pkgname);
222                 notification_get_id(node->noti, NULL, &noti_priv_id);
223                 if (!strcmp(noti_pkgname, pkgname)
224                     && priv_id == noti_priv_id) {
225                         notification_set_text(node->noti,
226                                 NOTIFICATION_TEXT_TYPE_CONTENT,
227                                 content, NULL,
228                                 NOTIFICATION_VARIABLE_TYPE_NONE);
229                         return node->noti;
230                 }
231         }
232
233         return NULL;
234 }
235
236 static void _quickpanel_noti_update_progressbar(void *data,
237                                                 notification_h update_noti)
238 {
239         struct appdata *ad = NULL;
240         Elm_Object_Item *found = NULL;
241
242         retif(!data, , "data is NULL");
243         ad = data;
244
245         retif(!ad->list, , "ad->list is NULL");
246
247         int priv_id = 0;
248
249         if (notification_get_id(update_noti, NULL, &priv_id) == NOTIFICATION_ERROR_NONE) {
250                 noti_node_item *node = noti_node_get(g_noti_node, priv_id);
251
252                 if (node != NULL) {
253                         found = node->view;
254                 }
255         }
256
257         retif(!found, , "fail to find %p related gl item", update_noti);
258
259         elm_genlist_item_fields_update(found, "*", ELM_GENLIST_ITEM_FIELD_ALL);
260 }
261
262 static void _quickpanel_noti_item_progress_update_cb(void *data,
263                                                 DBusMessage *msg)
264 {
265         DBusError err;
266         char *pkgname = 0;
267         int priv_id = 0;
268         double progress = 0;
269         notification_h noti = NULL;
270
271         retif(data == NULL || msg == NULL, , "Invalid parameter!");
272
273         dbus_error_init(&err);
274         dbus_message_get_args(msg, &err,
275                         DBUS_TYPE_STRING, &pkgname,
276                         DBUS_TYPE_INT32, &priv_id,
277                         DBUS_TYPE_DOUBLE, &progress,
278                         DBUS_TYPE_INVALID);
279
280         if (dbus_error_is_set(&err)) {
281                 ERR("dbus err: %s", err.message);
282                 dbus_error_free(&err);
283                 return;
284         }
285
286         if (pkgname == NULL) {
287                 ERR("pkgname is null");
288                 return;
289         }
290
291         /* check item on the list */
292         noti = _quickpanel_noti_update_item_progress(pkgname,
293                                                 priv_id, progress);
294         retif(noti == NULL, , "Can not found noti data.");
295
296         DBG("pkgname[%s], priv_id[%d], progress[%lf]",
297                                 pkgname, priv_id, progress);
298         if (!suspended)
299                 _quickpanel_noti_update_progressbar(data, noti);
300 }
301
302 static void _quickpanel_noti_item_size_update_cb(void *data, DBusMessage * msg)
303 {
304         DBusError err;
305         char *pkgname = 0;
306         int priv_id = 0;
307         double size = 0;
308         notification_h noti = NULL;
309
310         retif(data == NULL || msg == NULL, , "Invalid parameter!");
311
312         dbus_error_init(&err);
313         dbus_message_get_args(msg, &err,
314                         DBUS_TYPE_STRING, &pkgname,
315                         DBUS_TYPE_INT32, &priv_id,
316                         DBUS_TYPE_DOUBLE, &size, DBUS_TYPE_INVALID);
317         if (dbus_error_is_set(&err)) {
318                 ERR("dbus err: %s", err.message);
319                 dbus_error_free(&err);
320                 return;
321         }
322
323         if (pkgname == NULL) {
324                 ERR("pkgname is null");
325                 return;
326         }
327
328         /* check item on the list */
329         noti = _quickpanel_noti_update_item_size(pkgname, priv_id, size);
330         retif(noti == NULL, , "Can not found noti data.");
331
332         DBG("pkgname[%s], priv_id[%d], progress[%lf]",
333                                 pkgname, priv_id, size);
334
335         if (!suspended)
336                 _quickpanel_noti_update_progressbar(data, noti);
337 }
338
339 static void _quickpanel_noti_item_content_update_cb(void *data,
340                                                 DBusMessage *msg)
341 {
342         DBusError err;
343         char *pkgname = NULL;
344         int priv_id = 0;
345         char *content = NULL;
346         notification_h noti = NULL;
347
348         retif(data == NULL || msg == NULL, , "Invalid parameter!");
349
350         dbus_error_init(&err);
351         dbus_message_get_args(msg, &err,
352                         DBUS_TYPE_STRING, &pkgname,
353                         DBUS_TYPE_INT32, &priv_id,
354                         DBUS_TYPE_STRING, &content, DBUS_TYPE_INVALID);
355
356         if (pkgname == NULL) {
357                 ERR("pkgname  is null");
358                 return;
359         }
360         if (content == NULL) {
361                 ERR("content is null");
362                 return;
363         }
364
365         if (dbus_error_is_set(&err)) {
366                 ERR("dbus err: %s", err.message);
367                 dbus_error_free(&err);
368                 return;
369         }
370
371         DBG("pkgname[%s], priv_id[%d], content[%s]",
372                                 pkgname, priv_id, content);
373
374         /* check item on the list */
375         noti = _quickpanel_noti_update_item_content(pkgname, priv_id, content);
376         retif(noti == NULL, , "Can not found noti data.");
377
378         if (!suspended)
379                 _quickpanel_noti_update_progressbar(data, noti);
380 }
381
382 char *quickpanel_noti_get_time(time_t t, char *buf, int buf_len)
383 {
384         UErrorCode status = U_ZERO_ERROR;
385         UDateTimePatternGenerator *generator;
386         UDateFormat *formatter;
387         UChar skeleton[40] = { 0 };
388         UChar pattern[40] = { 0 };
389         UChar formatted[40] = { 0 };
390         int32_t patternCapacity, formattedCapacity;
391         int32_t skeletonLength, patternLength, formattedLength;
392         UDate date;
393         const char *locale;
394         const char customSkeleton[] = UDAT_YEAR_NUM_MONTH_DAY;
395         char bf1[32] = { 0, };
396         bool is_24hour_enabled = FALSE;
397
398         struct tm loc_time;
399         time_t today, yesterday;
400         int ret = 0;
401
402         today = time(NULL);
403         localtime_r(&today, &loc_time);
404
405         loc_time.tm_sec = 0;
406         loc_time.tm_min = 0;
407         loc_time.tm_hour = 0;
408         today = mktime(&loc_time);
409
410         yesterday = today - QP_NOTI_DAY_DEC;
411
412         localtime_r(&t, &loc_time);
413
414         if (t >= yesterday && t < today) {
415                 ret = snprintf(buf, buf_len, _S("IDS_COM_BODY_YESTERDAY"));
416         } else if (t < yesterday) {
417                 /* set UDate  from time_t */
418                 date = (UDate) t * 1000;
419
420                 /* get default locale  */
421                 /* for thread saftey  */
422                 uloc_setDefault(__secure_getenv("LC_TIME"), &status);
423                 locale = uloc_getDefault();
424
425                 /* open datetime pattern generator */
426                 generator = udatpg_open(locale, &status);
427                 if (generator == NULL)
428                         return NULL;
429
430                 /* calculate pattern string capacity */
431                 patternCapacity =
432                     (int32_t) (sizeof(pattern) / sizeof((pattern)[0]));
433
434                 /* ascii to unicode for input skeleton */
435                 u_uastrcpy(skeleton, customSkeleton);
436
437                 /* get skeleton length */
438                 skeletonLength = strlen(customSkeleton);
439
440                 /* get best pattern using skeleton */
441                 patternLength =
442                     udatpg_getBestPattern(generator, skeleton, skeletonLength,
443                                           pattern, patternCapacity, &status);
444
445                 /* open datetime formatter using best pattern */
446                 formatter =
447                     udat_open(UDAT_IGNORE, UDAT_DEFAULT, locale, NULL, -1,
448                               pattern, patternLength, &status);
449                 if (formatter == NULL) {
450                         udatpg_close(generator);
451                         return NULL;
452                 }
453
454                 /* calculate formatted string capacity */
455                 formattedCapacity =
456                     (int32_t) (sizeof(formatted) / sizeof((formatted)[0]));
457
458                 /* formatting date using formatter by best pattern */
459                 formattedLength =
460                     udat_format(formatter, date, formatted, formattedCapacity,
461                                 NULL, &status);
462
463                 /* unicode to ascii to display */
464                 u_austrcpy(bf1, formatted);
465
466                 /* close datetime pattern generator */
467                 udatpg_close(generator);
468
469                 /* close datetime formatter */
470                 udat_close(formatter);
471
472                 ret = snprintf(buf, buf_len, "%s", bf1);
473         } else {
474                 ret = runtime_info_get_value_bool(
475                                         RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, &is_24hour_enabled);
476                 if (ret == RUNTIME_INFO_ERROR_NONE && is_24hour_enabled == TRUE) {
477                         ret = strftime(buf, buf_len, "%H:%M", &loc_time);
478                 } else {
479                         strftime(bf1, sizeof(bf1), "%l:%M", &loc_time);
480
481                         if (loc_time.tm_hour >= 0 && loc_time.tm_hour < 12)
482                                 ret = snprintf(buf, buf_len, "%s%s", bf1, "AM");
483                         else
484                                 ret = snprintf(buf, buf_len, "%s%s", bf1, "PM");
485                 }
486
487         }
488
489         return ret <= 0 ? NULL : buf;
490 }
491
492 static void _quickpanel_noti_ani_image_control(Eina_Bool on)
493 {
494         const Eina_List *l = NULL;
495         const Eina_List *ln = NULL;
496         Evas_Object *entry_obj = NULL;
497
498         retif(g_animated_image_list == NULL, ,"");
499
500         EINA_LIST_FOREACH_SAFE(g_animated_image_list, l, ln, entry_obj) {
501                 if (entry_obj == NULL) continue;
502
503                 if (on == EINA_TRUE) {
504                         if (elm_image_animated_play_get(entry_obj) == EINA_FALSE) {
505                                 elm_image_animated_play_set(entry_obj, EINA_TRUE);
506                         }
507                 } else {
508                         if (elm_image_animated_play_get(entry_obj) == EINA_TRUE) {
509                                 elm_image_animated_play_set(entry_obj, EINA_FALSE);
510                         }
511                 }
512         }
513 }
514
515 static void _quickpanel_noti_ani_image_deleted_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
516 {
517         retif(obj == NULL, , "obj is NULL");
518         retif(g_animated_image_list == NULL, , "list is empty");
519
520         g_animated_image_list = eina_list_remove(g_animated_image_list, obj);
521 }
522
523 static Evas_Object *_quickpanel_noti_box_gl_get_content(void *data,
524                 Evas_Object *obj, const char *part) {
525         retif(part == NULL, NULL, "invalid parameter");
526
527         if (strcmp(part, "elm.icon") == 0) {
528                 DBG("returned:%p", g_noti_gridbox);
529                 return g_noti_gridbox;
530         }
531
532         return NULL;
533 }
534
535 static Evas_Object *_quickpanel_noti_gl_get_content(void *data,
536                                         Evas_Object *obj, const char *part)
537 {
538         qp_item_data *qid = NULL;
539         notification_h noti = NULL;
540         Evas_Object *ic = NULL;
541         char *icon_path = NULL;
542         char *thumbnail_path = NULL;
543         char *ret_path = NULL;
544         double size = 0.0;
545         double percentage = 0.0;
546         notification_type_e type = NOTIFICATION_TYPE_NONE;
547         char group_name[64] = {0,};
548         notification_ly_type_e layout = NOTIFICATION_LY_NONE ;
549
550         retif(!data, NULL, "data is NULL");
551         qid = data;
552
553         noti = quickpanel_list_util_item_get_data(qid);
554         retif(noti == NULL, NULL, "noti is NULL");
555
556         if (!strncmp
557             (part, "elm.swallow.progress", strlen("elm.swallow.progress"))) {
558                 notification_get_type(noti, &type);
559                 if (type == NOTIFICATION_TYPE_ONGOING) {
560                         notification_get_size(noti, &size);
561                         notification_get_progress(noti, &percentage);
562                         notification_get_layout(noti, &layout);
563
564                         if (layout != NOTIFICATION_LY_ONGOING_EVENT) {
565                                 if (percentage > 0 && percentage <= 1) {
566                                         ic = elm_progressbar_add(obj);
567                                         if (ic == NULL)
568                                                 return NULL;
569
570                                         elm_object_style_set(ic, "quickpanel/list_progress");
571                                         elm_progressbar_value_set(ic, percentage);
572                                         elm_progressbar_horizontal_set(ic, EINA_TRUE);
573                                         elm_progressbar_pulse(ic, EINA_FALSE);
574                                 } else if (size > 0) {
575                                         ic = elm_progressbar_add(obj);
576                                         if (ic == NULL)
577                                                 return NULL;
578
579                                         elm_object_style_set(ic, "quickpanel/pending_list");
580                                         elm_progressbar_horizontal_set(ic, EINA_TRUE);
581                                         elm_progressbar_pulse(ic, EINA_TRUE);
582                                 }
583                         }
584                 }
585                 return ic;
586         }
587
588         ic = elm_image_add(obj);
589         retif(ic == NULL, NULL, "Failed to create elm icon.");
590
591         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
592                                &thumbnail_path);
593         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
594
595         snprintf(group_name, sizeof(group_name) - 1, "notification_item_%d", eina_list_count(g_animated_image_list));
596
597         if (!strncmp
598             (part, "elm.swallow.thumbnail", strlen("elm.swallow.thumbnail"))) {
599                 if (thumbnail_path == NULL)
600                         ret_path = icon_path;
601                 else
602                         ret_path = thumbnail_path;
603
604                 elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
605
606                 if (ret_path == NULL
607                     || (elm_image_file_set(ic, ret_path, group_name) == EINA_FALSE))
608                         elm_image_file_set(ic, QP_DEFAULT_ICON, group_name);
609         } else if (!strncmp(part, "elm.swallow.icon",
610                         strlen("elm.swallow.icon"))) {
611                 if (thumbnail_path == NULL)
612                         ret_path = NULL;
613                 else
614                         ret_path = icon_path;
615
616                 if (ret_path != NULL)
617                         elm_image_file_set(ic, ret_path, group_name);
618         }
619
620         if (ic != NULL && elm_image_animated_available_get(ic) == EINA_TRUE) {
621                 elm_image_animated_set(ic, EINA_TRUE);
622                 g_animated_image_list = eina_list_append(g_animated_image_list, ic);
623                 evas_object_event_callback_add(ic, EVAS_CALLBACK_DEL, _quickpanel_noti_ani_image_deleted_cb, ic);
624
625                 if (suspended == 0)
626                         elm_image_animated_play_set(ic, EINA_TRUE);
627         }
628         return ic;
629 }
630
631 static char *_quickpanel_ongoing_noti_gl_get_text(void *data, Evas_Object * obj,
632                                            const char *part)
633 {
634         qp_item_data *qid = NULL;
635         notification_h noti = NULL;
636         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
637         char *text = NULL;
638         char *domain = NULL;
639         char *dir = NULL;
640         char *pkgname = NULL;
641         char *caller_pkgname = NULL;
642         int group_id = 0, priv_id = 0;
643         char buf[128] = { 0, };
644         notification_type_e type = NOTIFICATION_TYPE_NONE;
645         double size = 0.0;
646         double percentage = 0.0;
647         int isProgressBarEnabled = 1;
648         notification_ly_type_e layout = NOTIFICATION_LY_NONE ;
649
650         retif(!data, NULL, "data is NULL");
651         qid = data;
652
653         noti = quickpanel_list_util_item_get_data(qid);
654         retif(noti == NULL, NULL, "noti is NULL");
655
656         /* Set text domain */
657         notification_get_text_domain(noti, &domain, &dir);
658         if (domain != NULL && dir != NULL)
659                 bindtextdomain(domain, dir);
660
661         /* Get pkgname & id */
662         notification_get_pkgname(noti, &pkgname);
663         notification_get_application(noti, &caller_pkgname);
664         notification_get_id(noti, &group_id, &priv_id);
665         notification_get_type(noti, &type);
666         notification_get_size(noti, &size);
667         notification_get_progress(noti, &percentage);
668         notification_get_layout(noti, &layout);
669
670         DBG("percentage:%f size:%f", percentage, size);
671
672         if (percentage <= 0.0 && size <= 0.0) {
673                 isProgressBarEnabled = 0;
674         }
675
676         if (!strcmp(part, "elm.text.title")) {
677                 noti_err = notification_get_text(noti,
678                                                                 NOTIFICATION_TEXT_TYPE_TITLE,
679                                                                 &text);
680                 if (noti_err != NOTIFICATION_ERROR_NONE)
681                         text = NULL;
682         } else if (!strcmp(part, "elm.text.content")) {
683                 if (layout == NOTIFICATION_LY_ONGOING_EVENT) {
684                         return NULL;
685                 }
686
687                 noti_err = notification_get_text(noti,
688                                         NOTIFICATION_TEXT_TYPE_CONTENT,
689                                         &text);
690                 if (noti_err != NOTIFICATION_ERROR_NONE)
691                         text = NULL;
692         } else if (!strcmp(part, "elm.text.content.multiline")) {
693                 if (layout != NOTIFICATION_LY_ONGOING_EVENT) {
694                         return NULL;
695                 }
696
697                 noti_err = notification_get_text(noti,
698                                         NOTIFICATION_TEXT_TYPE_CONTENT,
699                                         &text);
700                 if (noti_err != NOTIFICATION_ERROR_NONE)
701                         text = NULL;
702         } else if (!strcmp(part, "elm.text.time")) {
703                 if (isProgressBarEnabled == 0)
704                         return NULL;
705
706                 if (layout == NOTIFICATION_LY_ONGOING_EVENT) {
707                         return NULL;
708                 }
709
710                 text = _quickpanel_noti_get_progress(noti, buf,
711                                                                           sizeof(buf));
712         }
713
714         if (text != NULL)
715                 return strdup(text);
716
717         return NULL;
718 }
719
720 static Eina_Bool _quickpanel_noti_gl_get_state(void *data, Evas_Object * obj,
721                                                const char *part)
722 {
723         qp_item_data *qid = NULL;
724         notification_h noti = NULL;
725         char *pkgname = NULL;
726         int group_id = 0, priv_id = 0;
727         char *content = NULL;
728         time_t time;
729         notification_ly_type_e layout = NOTIFICATION_LY_NONE;
730
731         retif(!data, EINA_FALSE, "data is NULL");
732         qid = data;
733
734         noti = quickpanel_list_util_item_get_data(qid);
735         retif(noti == NULL, EINA_FALSE, "noti is NULL");
736
737         notification_get_pkgname(noti, &pkgname);
738         notification_get_id(noti, &group_id, &priv_id);
739         notification_get_layout(noti, &layout);
740
741         if (!strcmp(part, "elm.text.content")) {
742                 notification_get_text(noti,
743                         NOTIFICATION_TEXT_TYPE_CONTENT, &content);
744                 if (content != NULL && layout != NOTIFICATION_LY_ONGOING_EVENT)
745                         return EINA_TRUE;
746         } else if (!strcmp(part, "elm.text.content.multiline")) {
747                 notification_get_text(noti,
748                         NOTIFICATION_TEXT_TYPE_CONTENT, &content);
749                 if (content != NULL && layout == NOTIFICATION_LY_ONGOING_EVENT)
750                         return EINA_TRUE;
751         } else if (!strcmp(part, "elm.text.time")) {
752                 notification_get_time(noti, &time);
753
754                 if ((int) time > 0)
755                         return EINA_TRUE;
756         }
757
758         return EINA_FALSE;
759 }
760
761 static void _quickpanel_do_noti_delete(notification_h noti) {
762         char *pkgname = NULL;
763         char *caller_pkgname = NULL;
764         int flags = 0, priv_id = 0, flag_delete = 0;
765         notification_type_e type = NOTIFICATION_TYPE_NONE;
766
767         quickpanel_play_feedback();
768
769         retif(noti == NULL, , "Invalid parameter!");
770
771         notification_get_pkgname(noti, &caller_pkgname);
772         notification_get_application(noti, &pkgname);
773         if (pkgname == NULL)
774                 pkgname = caller_pkgname;
775
776         notification_get_id(noti, NULL, &priv_id);
777         notification_get_property(noti, &flags);
778         notification_get_type(noti, &type);
779
780         if (flags & NOTIFICATION_PROP_PERMANENT_DISPLAY)
781                 flag_delete = 0;
782         else
783                 flag_delete = 1;
784
785         if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
786                 notification_delete_by_priv_id(caller_pkgname, NOTIFICATION_TYPE_NOTI,
787                                 priv_id);
788         }
789 }
790
791 static void _quickpanel_do_noti_press(notification_h noti) {
792         int ret = -1;
793         char *pkgname = NULL;
794         char *caller_pkgname = NULL;
795         bundle *args = NULL;
796         bundle *group_args = NULL;
797         bundle *single_service_handle = NULL;
798         bundle *multi_service_handle = NULL;
799         int flags = 0, group_id = 0, priv_id = 0, count = 0, flag_launch = 0,
800                         flag_delete = 0;
801         notification_type_e type = NOTIFICATION_TYPE_NONE;
802
803         quickpanel_play_feedback();
804
805         retif(noti == NULL, , "Invalid parameter!");
806
807         notification_get_pkgname(noti, &caller_pkgname);
808         notification_get_application(noti, &pkgname);
809         if (pkgname == NULL)
810                 pkgname = caller_pkgname;
811
812         notification_get_id(noti, &group_id, &priv_id);
813         notification_get_property(noti, &flags);
814         notification_get_type(noti, &type);
815
816         if (flags & NOTIFICATION_PROP_DISABLE_APP_LAUNCH)
817                 flag_launch = 0;
818         else
819                 flag_launch = 1;
820
821         if (flags & NOTIFICATION_PROP_DISABLE_AUTO_DELETE)
822                 flag_delete = 0;
823         else
824                 flag_delete = 1;
825
826         notification_get_execute_option(noti,
827                                 NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH,
828                                 NULL, &single_service_handle);
829         notification_get_execute_option(noti,
830                                 NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH,
831                                 NULL, &multi_service_handle);
832
833         if (flag_launch == 1) {
834                 /* Hide quickpanel */
835                 quickpanel_close_quickpanel(true);
836
837                 if (group_id != NOTIFICATION_GROUP_ID_NONE)
838                         notification_get_count(type,
839                                         caller_pkgname, group_id,
840                                         priv_id, &count);
841                 else
842                         count = 1;
843
844                 if (count > 1 && multi_service_handle != NULL) {
845                         ret = quickpanel_launch_app(NULL, multi_service_handle);
846                         quickpanel_launch_app_inform_result(pkgname, ret);
847                 }
848                 else if (single_service_handle != NULL) {
849                         ret = quickpanel_launch_app(NULL, single_service_handle);
850                         quickpanel_launch_app_inform_result(pkgname, ret);
851                 }
852                 else {
853                         notification_get_args(noti, &args, &group_args);
854
855                         if (count > 1 && group_args != NULL) {
856                                 ret = quickpanel_launch_app(pkgname, group_args);
857                                 quickpanel_launch_app_inform_result(pkgname, ret);
858                         } else {
859                                 ret = quickpanel_launch_app(pkgname, args);
860                                 quickpanel_launch_app_inform_result(pkgname, ret);
861                         }
862                 }
863         }
864
865
866         if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
867                 notification_delete_by_priv_id(caller_pkgname,
868                                 NOTIFICATION_TYPE_NOTI,
869                                 priv_id);
870         }
871 }
872
873 static void quickpanel_notibox_delete_cb(void *data, Evas_Object * obj) {
874         DBG("");
875         noti_node_item *item = data;
876         retif(item == NULL, , "Invalid parameter!");
877
878         notification_h noti = item->noti;
879         retif(noti == NULL, , "Invalid parameter!");
880
881         _quickpanel_do_noti_delete(noti);
882
883 }
884
885 static void quickpanel_notibox_select_cb(void *data, Evas_Object * obj) {
886         DBG("");
887         noti_node_item *item = data;
888         retif(item == NULL, , "Invalid parameter!");
889
890         notification_h noti = item->noti;
891         retif(noti == NULL, , "Invalid parameter!");
892
893         _quickpanel_do_noti_press(noti);
894 }
895
896 static void quickpanel_noti_select_cb(void *data, Evas_Object * obj,
897                 void *event_info) {
898         retif(data == NULL, , "Invalid parameter!");
899         notification_h noti = (notification_h) quickpanel_list_util_item_get_data(data);
900         retif(noti == NULL, , "Invalid parameter!");
901
902         elm_genlist_item_selected_set((Elm_Object_Item *) event_info, EINA_FALSE);
903
904         _quickpanel_do_noti_press(noti);
905 }
906
907 static Evas_Object *_quickpanel_noti_gl_get_group_content(void *data,
908                                                 Evas_Object *obj,
909                                                 const char *part)
910 {
911         Evas_Object *eo = NULL;
912
913         eo = elm_button_add(obj);
914         retif(eo == NULL, NULL, "Failed to create clear button!");
915
916         elm_object_style_set(eo, "quickpanel_standard");
917
918         elm_object_text_set(eo, _S("IDS_COM_BODY_CLEAR_ALL"));
919         evas_object_smart_callback_add(eo, "clicked",
920                                        _quickpanel_noti_clear_clicked_cb, NULL);
921
922         return eo;
923 }
924
925 static char *_quickpanel_noti_gl_get_group_text(void *data, Evas_Object * obj,
926                                                  const char *part)
927 {
928         char buf[128] = { 0, };
929         int noti_count = 0;
930
931         if (!strncmp(part, "elm.text", 8)) {
932                 char format[256] = { 0, };
933                 memset(buf, 0x00, sizeof(buf));
934
935                 if (g_noti_node != NULL) {
936                         noti_count =
937                                         noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_NOTI);
938                 } else {
939                         noti_count = 0;
940                 }
941
942                 snprintf(format, sizeof(format), "%s %%d", _("IDS_QP_BODY_NOTIFICATIONS_ABB2"));
943                 snprintf(buf, sizeof(buf), format, noti_count);
944
945                 return strdup(buf);
946         }
947
948         return NULL;
949 }
950
951 static void _quickpanel_list_noti_gl_del(void *data, Evas_Object *obj)
952 {
953         int noti_priv_id = 0;
954         qp_item_type_e item_type = QP_ITEM_TYPE_NONE;
955         notification_h noti = NULL;
956
957         if (data) {
958                 noti = quickpanel_list_util_item_get_data(data);
959                 item_type = quickpanel_list_util_item_get_item_type(data);
960
961                 DBG("item type:%d", item_type);
962                 if (noti != NULL) {
963                         if (item_type == QP_ITEM_TYPE_ONGOING_NOTI) {
964                                 notification_get_id(noti, NULL, &noti_priv_id);
965                                 noti_node_remove(g_noti_node, noti_priv_id);
966                                 DBG("noti:%d removed", noti_priv_id);
967                         }
968                 }
969                 free(data);
970         }
971
972         return;
973 }
974
975 static void _quickpanel_list_noti_group_gl_del(void *data, Evas_Object *obj) {
976         if (data != NULL) {
977                 free(data);
978         }
979         return;
980 }
981
982 static void _quickpanel_notibox_gl_del(void *data, Evas_Object *obj) {
983         if (data != NULL) {
984                 free(data);
985         }
986         return;
987 }
988
989 static void _quickpanel_noti_gl_style_init(void)
990 {
991         Elm_Genlist_Item_Class *noti = NULL;
992         Elm_Genlist_Item_Class *noti_ongoing = NULL;
993         Elm_Genlist_Item_Class *group = NULL;
994
995         /* item style for noti items*/
996         noti = elm_genlist_item_class_new();
997         if (noti) {
998                 noti->item_style = "qp_notibox/default";
999                 noti->func.text_get = NULL;
1000                 noti->func.content_get = _quickpanel_noti_box_gl_get_content;
1001                 noti->func.state_get = NULL;
1002                 noti->func.del = _quickpanel_notibox_gl_del;
1003                 itc_noti = noti;
1004         }
1005
1006         noti_ongoing = elm_genlist_item_class_new();
1007         if (noti_ongoing) {
1008                 noti_ongoing->item_style = "notification_ongoing_item";
1009                 noti_ongoing->func.text_get = _quickpanel_ongoing_noti_gl_get_text;
1010                 noti_ongoing->func.content_get = _quickpanel_noti_gl_get_content;
1011                 noti_ongoing->func.state_get = _quickpanel_noti_gl_get_state;
1012                 noti_ongoing->func.del = _quickpanel_list_noti_gl_del;
1013                 itc_ongoing = noti_ongoing;
1014         }
1015
1016         /* item style for noti group title */
1017         group = elm_genlist_item_class_new();
1018         if (group) {
1019                 group->item_style = "qp_group_title";
1020                 group->func.text_get = _quickpanel_noti_gl_get_group_text;
1021                 group->func.content_get = _quickpanel_noti_gl_get_group_content;
1022                 group->func.del = _quickpanel_list_noti_group_gl_del;
1023                 g_itc = group;
1024         }
1025 }
1026
1027 static void _quickpanel_noti_gl_style_fini(void)
1028 {
1029         if (itc_noti) {
1030                 elm_genlist_item_class_free(itc_noti);
1031                 itc_noti = NULL;
1032         }
1033
1034         if (itc_ongoing) {
1035                 elm_genlist_item_class_free(itc_ongoing);
1036                 itc_ongoing = NULL;
1037         }
1038
1039         if (g_itc) {
1040                 elm_genlist_item_class_free(g_itc);
1041                 g_itc = NULL;
1042         }
1043
1044         if (g_animated_image_list) {
1045                 g_animated_image_list = eina_list_free(g_animated_image_list);
1046         }
1047 }
1048
1049 static inline void __ongoing_comp_n_copy(notification_h old, notification_h new)
1050 {
1051         int priv_id = 0;
1052         int new_priv_id = 0;
1053         char *pkgname = NULL;
1054         char *new_pkgname = NULL;
1055
1056         if (!old)
1057                 return;
1058
1059         if (!new)
1060                 return;
1061
1062         notification_get_id(old, NULL, &priv_id);
1063         notification_get_id(new, NULL, &new_priv_id);
1064
1065         notification_get_pkgname(old, &pkgname);
1066         notification_get_pkgname(new, &new_pkgname);
1067
1068         if (!pkgname || !new_pkgname)
1069                 return;
1070
1071         if (!strcmp(pkgname, new_pkgname) && priv_id == new_priv_id) {
1072                 double percentage = 0.0;
1073                 double size = 0.0;
1074                 time_t insert_time = 0;
1075                 time_t new_insert_time = 0;
1076
1077                 notification_get_progress(old, &percentage);
1078                 notification_get_size(old, &size);
1079                 notification_set_progress(new, percentage);
1080                 notification_set_size(new, size);
1081                 notification_get_insert_time(old, &insert_time);
1082                 notification_get_insert_time(new, &new_insert_time);
1083
1084                 if (insert_time == new_insert_time) {
1085                         char *content = NULL;
1086                         notification_get_text(old,
1087                                 NOTIFICATION_TEXT_TYPE_CONTENT, &content);
1088                         notification_set_text(new,
1089                                 NOTIFICATION_TEXT_TYPE_CONTENT, content,
1090                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
1091                 }
1092         }
1093 }
1094
1095 static void _quickpanel_noti_clear_ongoinglist(Evas_Object *list)
1096 {
1097         if (!list)
1098                 return;
1099
1100         if (!ongoing_first)
1101                 return;
1102
1103         quickpanel_list_util_item_del_by_type(list, ongoing_first,
1104                         QP_ITEM_TYPE_ONGOING_NOTI);
1105 }
1106
1107 static void _quickpanel_noti_clear_notilist(Evas_Object *list)
1108 {
1109         if (!list)
1110                 return;
1111
1112         if (!g_noti_gridbox)
1113                 return;
1114
1115         if (g_noti_gridbox != NULL) {
1116                 gridbox_remove(g_noti_gridbox);
1117                 g_noti_gridbox = NULL;
1118         }
1119         if (noti_first != NULL) {
1120                 elm_object_item_del(noti_first);
1121                 noti_first= NULL;
1122         }
1123         if (noti_group != NULL) {
1124                 elm_object_item_del(noti_group);
1125                 noti_group= NULL;
1126         }
1127 }
1128
1129 static void _quickpanel_noti_clear_list_all(Evas_Object *list)
1130 {
1131         _quickpanel_noti_clear_ongoinglist(list);
1132         ongoing_first = NULL;
1133
1134         _quickpanel_noti_clear_notilist(list);
1135 }
1136
1137 static void _quickpanel_noti_ongoing_add(Evas_Object *list, void *data)
1138 {
1139         qp_item_data *qid = NULL;
1140         Elm_Object_Item *it = NULL;
1141
1142         if (!list)
1143                 return;
1144
1145         qid = quickpanel_list_util_item_new(QP_ITEM_TYPE_ONGOING_NOTI, data);
1146         if (!qid)
1147                 return;
1148
1149         it = quickpanel_list_util_sort_insert(list, itc_ongoing, qid, NULL,
1150                         ELM_GENLIST_ITEM_NONE, quickpanel_noti_select_cb, qid);
1151
1152         if (it) {
1153                 ongoing_first = it;
1154                 noti_node_add(g_noti_node, (void *)data, (void *)it);
1155         }
1156         else
1157                 ERR("fail to insert item to list : %p", data);
1158
1159         DBG("noti ongoing[%p] data[%p] added, it[%p]", qid, data, it);
1160 }
1161
1162 static void _quickpanel_noti_group_add(Evas_Object *list, void *data)
1163 {
1164         qp_item_data *qid = NULL;
1165         Elm_Object_Item *it = NULL;
1166
1167         if (!list)
1168                 return;
1169
1170         qid = quickpanel_list_util_item_new(QP_ITEM_TYPE_NOTI_GROUP, data);
1171         if (!qid)
1172                 return;
1173
1174         it = quickpanel_list_util_sort_insert(list, g_itc, qid, NULL,
1175                 ELM_GENLIST_ITEM_GROUP, NULL, NULL);
1176
1177         if (it)
1178                 noti_group = it;
1179         else
1180                 ERR("fail to insert item to list : %p", data);
1181
1182         DBG("noti group[%p] data[%p] added, it[%p]", qid, data, it);
1183 }
1184
1185 void _quickpanel_noti_box_deleted_cb(void *data, Evas_Object *obj) {
1186         DBG("deleting:%p", obj);
1187
1188         int priv_id = -1;
1189
1190         retif(data == NULL, , "Invalid parameter!");
1191         retif(obj == NULL, , "Invalid parameter!");
1192
1193         noti_node_item *item = data;
1194         notification_h noti = item->noti;
1195
1196         if (noti != NULL) {
1197                 notification_get_id(noti, NULL, &priv_id);
1198                 noti_node_remove(g_noti_node, priv_id);
1199         }
1200 }
1201
1202 static void _quickpanel_noti_noti_add(Evas_Object *list, void *data, int is_prepend)
1203 {
1204         retif(list == NULL, , "Invalid parameter!");
1205         qp_item_data *qid = NULL;
1206         Elm_Object_Item *it = NULL;
1207         notification_h noti = data;
1208         notification_ly_type_e layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
1209
1210         qid = quickpanel_list_util_item_new(QP_ITEM_TYPE_NOTI, NULL);
1211         retif(qid == NULL, , "Invalid parameter!");
1212
1213         if (!noti_group)
1214                 _quickpanel_noti_group_add(list, NULL);
1215
1216         if (noti_first == NULL) {
1217                 if (g_noti_gridbox == NULL) {
1218                         g_noti_gridbox = gridbox_create(list, quickpanel_get_app_data());
1219                         gridbox_set_item_deleted_cb(g_noti_gridbox, _quickpanel_noti_box_deleted_cb);
1220                 }
1221
1222                 it = quickpanel_list_util_sort_insert(list, itc_noti, qid, noti_group,
1223                                 ELM_GENLIST_ITEM_NONE, NULL, qid);
1224                 noti_first = it;
1225         }
1226
1227         if (noti != NULL) {
1228                 notification_get_layout(noti, &layout);
1229         }
1230         Evas_Object *noti_box = noti_box_create(list, layout);
1231
1232         if (noti_box != NULL) {
1233                 noti_node_item *item = noti_node_add(g_noti_node, (void*)data, (void*)noti_box);
1234                 if (item != NULL) {
1235                         noti_box_node_set(noti_box, item);
1236                         noti_box_set_item_selected_cb(noti_box, quickpanel_notibox_select_cb);
1237                         noti_box_set_item_deleted_cb(noti_box, quickpanel_notibox_delete_cb);
1238                         gridbox_add_item(g_noti_gridbox, noti_box, is_prepend);
1239                 }
1240         } else
1241                 ERR("fail to insert item to list : %p", data);
1242
1243         DBG("noti[%p] data[%p] added, it[%p] of gridbox[%p]",
1244                         qid, data, noti_box, g_noti_gridbox);
1245 }
1246
1247
1248 void _quickpanel_noti_update_notilist(struct appdata *ad)
1249 {
1250         Evas_Object *list = NULL;
1251         notification_h noti = NULL;
1252         notification_h noti_save = NULL;
1253         notification_list_h get_list = NULL;
1254         int applist = NOTIFICATION_DISPLAY_APP_ALL;
1255
1256         DBG("");
1257
1258         retif(ad == NULL, , "Invalid parameter!");
1259
1260         list = ad->list;
1261         retif(list == NULL, , "Failed to get noti genlist.");
1262
1263         _quickpanel_noti_clear_list_all(list);
1264
1265         notification_get_list(NOTIFICATION_TYPE_ONGOING, -1, &get_list);
1266         while (get_list != NULL) {
1267                 noti = notification_list_get_data(get_list);
1268                 notification_get_display_applist(noti, &applist);
1269
1270                 if (applist &
1271                     NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
1272                         notification_clone(noti, &noti_save);
1273                         _quickpanel_noti_ongoing_add(list, noti_save);
1274                 }
1275                 get_list = notification_list_get_next(get_list);
1276         }
1277         notification_free_list(get_list);
1278
1279         notification_get_list(NOTIFICATION_TYPE_NOTI , -1, &get_list);
1280         while (get_list != NULL) {
1281                 noti = notification_list_get_data(get_list);
1282                 notification_get_display_applist(noti, &applist);
1283
1284                 if (applist &
1285                     NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
1286                         notification_clone(noti, &noti_save);
1287                         _quickpanel_noti_noti_add(list, noti_save, GRIDBOX_APPEND);
1288                 }
1289                 get_list = notification_list_get_next(get_list);
1290         }
1291         notification_free_list(get_list);
1292
1293         if (g_noti_gridbox != NULL) {
1294                 elm_box_recalculate(g_noti_gridbox);
1295         }
1296 }
1297
1298 static void _quickpanel_noti_delete_volatil_data(void)
1299 {
1300         notification_list_h noti_list = NULL;
1301         notification_list_h noti_list_head = NULL;
1302         notification_h noti = NULL;
1303         int property = 0;
1304
1305         notification_get_grouping_list(NOTIFICATION_TYPE_NONE, -1, &noti_list);
1306
1307         noti_list_head = noti_list;
1308
1309         while (noti_list != NULL) {
1310                 noti = notification_list_get_data(noti_list);
1311                 notification_get_property(noti, &property);
1312
1313                 if (property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
1314                         notification_set_property(noti,
1315                                 property |
1316                                 NOTIFICATION_PROP_DISABLE_UPDATE_ON_DELETE);
1317                         notification_delete(noti);
1318                 }
1319
1320                 noti_list = notification_list_get_next(noti_list);
1321         }
1322
1323         notification_free_list(noti_list_head);
1324
1325         notification_update(NULL);
1326 }
1327
1328 static void _quickpanel_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
1329 {
1330         int i = 0;
1331         int op_type = 0;
1332         int priv_id = 0;
1333         struct appdata *ad = NULL;
1334         notification_h new_noti = NULL;
1335         notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
1336         int noti_applist = NOTIFICATION_DISPLAY_APP_ALL;
1337         notification_ly_type_e noti_layout = NOTIFICATION_LY_NONE;
1338
1339         retif(data == NULL, , "Invalid parameter!");
1340         ad = data;
1341
1342         DBG("test detailed quickpanel:%d", num_op);
1343
1344         for (i = 0; i < num_op; i++) {
1345                 notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_TYPE, &op_type);
1346                 DBG("op_type:%d", op_type);
1347                 notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
1348                 DBG("op_priv_id:%d", priv_id);
1349
1350                 if (op_type == NOTIFICATION_OP_INSERT) {
1351                         new_noti = notification_load(NULL, priv_id);
1352                         if (new_noti == NULL) continue;
1353
1354                         notification_get_type(new_noti, &noti_type);
1355                         notification_get_display_applist(new_noti, &noti_applist);
1356                         notification_get_layout(new_noti, &noti_layout);
1357
1358                         DBG("layout:%d", noti_layout);
1359
1360                         if (noti_applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
1361                                 noti_node_item *node = noti_node_get(g_noti_node, priv_id);
1362                                 if (node != NULL) {
1363                                         if (noti_type == NOTIFICATION_TYPE_NOTI) {
1364                                                 DBG("cb after inserted:%d", priv_id);
1365                                         }
1366                                 } else {
1367                                         if (noti_type == NOTIFICATION_TYPE_NOTI) {
1368                                                 _quickpanel_noti_noti_add(ad->list, new_noti, GRIDBOX_PREPEND);
1369                                         } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
1370                                                 _quickpanel_noti_ongoing_add(ad->list, new_noti);
1371                                         }
1372                                 }
1373                                 DBG("%d noti added", priv_id);
1374                         } else {
1375                                 notification_free(new_noti);
1376                         }
1377                 }
1378                 if (op_type == NOTIFICATION_OP_DELETE) {
1379                         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
1380
1381                         if (node != NULL && node->noti != NULL) {
1382                                 notification_h noti = node->noti;
1383                                 notification_get_type(noti, &noti_type);
1384
1385                                 if (noti_type == NOTIFICATION_TYPE_NOTI) {
1386                                         gridbox_remove_item(g_noti_gridbox, node->view, 0);
1387                                 } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
1388                                         elm_object_item_del(node->view);
1389                                 }
1390                         }
1391                         DBG("%d noti deleted", priv_id);
1392                 }
1393                 if (op_type == NOTIFICATION_OP_UPDATE) {
1394                         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
1395                         qp_item_data *qid = NULL;
1396                         notification_h old_noti = NULL;
1397
1398                         new_noti = notification_load(NULL, priv_id);
1399                         retif(new_noti == NULL, , "fail to load updated noti");
1400
1401                         if (node != NULL && node->view != NULL && node->noti != NULL) {
1402                                 notification_get_type(new_noti, &noti_type);
1403
1404                                 if (noti_type == NOTIFICATION_TYPE_NOTI) {
1405                                         gridbox_remove_item(g_noti_gridbox, node->view, 0);
1406                                         _quickpanel_noti_noti_add(ad->list, new_noti, GRIDBOX_PREPEND);
1407 /*
1408                                         gridbox_remove_and_add_item(g_noti_gridbox, node->view,
1409                                                         _quickpanel_noti_noti_add
1410                                                         ,ad->list, new_noti, GRIDBOX_PREPEND);
1411 */
1412                                 } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
1413                                         old_noti = node->noti;
1414                                         node->noti = new_noti;
1415
1416                                         qid = elm_object_item_data_get(node->view);
1417                                         retif(qid == NULL, , "noti is already deleted");
1418                                         quickpanel_list_util_item_set_data(qid, new_noti);
1419                                         elm_genlist_item_fields_update(node->view, "*",
1420                                                         ELM_GENLIST_ITEM_FIELD_ALL);
1421                                 }
1422
1423                                 if (old_noti != NULL) {
1424                                         notification_free(old_noti);
1425                                 }
1426                         } else {
1427                                 notification_get_display_applist(new_noti, &noti_applist);
1428
1429                                 if (noti_applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
1430
1431                                         if (noti_type == NOTIFICATION_TYPE_NOTI) {
1432                                                 _quickpanel_noti_noti_add(ad->list, new_noti, GRIDBOX_PREPEND);
1433                                         } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
1434                                                 _quickpanel_noti_ongoing_add(ad->list, new_noti);
1435                                         }
1436                                 }
1437                         }
1438
1439                         DBG("%d noti updated", priv_id);
1440                 }
1441         }
1442
1443         if (noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_NOTI)
1444                         <= 0) {
1445                 struct appdata *ad = quickpanel_get_app_data();
1446                 _quickpanel_noti_clear_notilist(ad->list);
1447         } else {
1448                 if (noti_group != NULL) {
1449                         elm_genlist_item_fields_update(noti_group, "*",
1450                                         ELM_GENLIST_ITEM_FIELD_ALL);
1451                 }
1452                 _quickpanel_noti_update_notibox();
1453         }
1454 }
1455
1456 static void _quickpanel_noti_update_sim_status_cb(keynode_t *node, void *data)
1457 {
1458         struct appdata *ad = data;
1459
1460         if (ad != NULL && ad->list != NULL) {
1461                 _quickpanel_noti_update_notilist(ad);
1462
1463                 _quickpanel_noti_update_notibox();
1464         }
1465 }
1466
1467 static int _quickpanel_noti_register_event_handler(struct appdata *ad)
1468 {
1469         int ret = 0;
1470         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1471
1472         /* Add dbus signal */
1473         e_dbus_init();
1474         ad->dbus_connection = e_dbus_bus_get(DBUS_BUS_SYSTEM);
1475         if (ad->dbus_connection == NULL) {
1476                 ERR("noti register : failed to get dbus bus");
1477                 return -1;
1478         }
1479
1480         ad->dbus_handler_size =
1481                 e_dbus_signal_handler_add(ad->dbus_connection, NULL,
1482                         QP_NOTI_ONGOING_DBUS_PATH,
1483                         QP_NOTI_ONGOING_DBUS_INTERFACE, "update_progress",
1484                         _quickpanel_noti_item_progress_update_cb,
1485                         ad);
1486         if (ad->dbus_handler_size == NULL)
1487                 ERR("fail to add size signal");
1488
1489         ad->dbus_handler_progress =
1490                 e_dbus_signal_handler_add(ad->dbus_connection, NULL,
1491                         QP_NOTI_ONGOING_DBUS_PATH,
1492                         QP_NOTI_ONGOING_DBUS_INTERFACE, "update_size",
1493                         _quickpanel_noti_item_size_update_cb,
1494                         ad);
1495         if (ad->dbus_handler_progress == NULL)
1496                 ERR("fail to add progress signal");
1497
1498         ad->dbus_handler_content =
1499                 e_dbus_signal_handler_add(ad->dbus_connection, NULL,
1500                         QP_NOTI_ONGOING_DBUS_PATH,
1501                         QP_NOTI_ONGOING_DBUS_INTERFACE, "update_content",
1502                         _quickpanel_noti_item_content_update_cb,
1503                         ad);
1504         if (ad->dbus_handler_content == NULL)
1505                 ERR("fail to add content signal");
1506
1507         /* Notify vconf key */
1508         ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SIM_SLOT,
1509                                        _quickpanel_noti_update_sim_status_cb,
1510                                        (void *)ad);
1511         if (ret != 0)
1512                 ERR("Failed to register SIM_SLOT change callback!");
1513
1514         /* Register notification changed cb */
1515         notification_register_detailed_changed_cb(_quickpanel_noti_detailed_changed_cb, ad);
1516
1517         return ret;
1518 }
1519
1520 static int _quickpanel_noti_unregister_event_handler(struct appdata *ad)
1521 {
1522         int ret = 0;
1523
1524         /* Unregister notification changed cb */
1525         notification_unregister_detailed_changed_cb(_quickpanel_noti_detailed_changed_cb, (void *)ad);
1526
1527         /* Ignore vconf key */
1528         ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SIM_SLOT,
1529                                 _quickpanel_noti_update_sim_status_cb);
1530         if (ret != 0)
1531                 ERR("Failed to ignore SIM_SLOT change callback!");
1532
1533         /* Delete dbus signal */
1534         if (ad->dbus_handler_size != NULL) {
1535                 e_dbus_signal_handler_del(ad->dbus_connection,
1536                                 ad->dbus_handler_size);
1537                 ad->dbus_handler_size = NULL;
1538         }
1539         if (ad->dbus_handler_progress != NULL) {
1540                 e_dbus_signal_handler_del(ad->dbus_connection,
1541                                 ad->dbus_handler_progress);
1542                 ad->dbus_handler_progress = NULL;
1543         }
1544         if (ad->dbus_handler_content != NULL) {
1545                 e_dbus_signal_handler_del(ad->dbus_connection,
1546                                 ad->dbus_handler_content);
1547                 ad->dbus_handler_content = NULL;
1548         }
1549
1550         if (ad->dbus_connection != NULL) {
1551                 e_dbus_connection_close(ad->dbus_connection);
1552                 ad->dbus_connection = NULL;
1553         }
1554
1555         return QP_OK;
1556 }
1557
1558 static int _quickpanel_noti_check_first_start(void)
1559 {
1560         int status = 0;
1561         int ret = 0;
1562
1563         ret = vconf_get_bool(VCONFKEY_QUICKPANEL_STARTED, &status);
1564         if (ret) {
1565                 INFO("fail to get %s", VCONFKEY_QUICKPANEL_STARTED);
1566                 /* reboot */
1567                 ret = vconf_set_bool(VCONFKEY_QUICKPANEL_STARTED, 1);
1568                 INFO("set : %s, result : %d", VCONFKEY_QUICKPANEL_STARTED, ret);
1569         }
1570
1571         if (status)
1572                 return 0;
1573
1574         return 1;
1575 }
1576
1577 static Eina_Bool quickpanel_noti_refresh_gridbox(void *data)
1578 {
1579         struct appdata *ad = NULL;
1580
1581         retif(data == NULL, EINA_FALSE, "Invalid parameter!");
1582         ad = data;
1583
1584         DBG("wr");
1585
1586         /* Update notification list */
1587         _quickpanel_noti_update_notilist(ad);
1588
1589         _quickpanel_noti_register_event_handler(ad);
1590
1591         _quickpanel_noti_update_notibox();
1592
1593         return EINA_FALSE;
1594 }
1595
1596 static int quickpanel_noti_init(void *data)
1597 {
1598         struct appdata *ad = data;
1599         int is_first = 0;
1600
1601         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1602
1603         g_window = ad->win;
1604
1605         noti_node_create(&g_noti_node);
1606
1607         is_first = _quickpanel_noti_check_first_start();
1608         if (is_first) {
1609                 /* Remove ongoing and volatile noti data */
1610                 notifiation_clear(NOTIFICATION_TYPE_ONGOING);
1611                 _quickpanel_noti_delete_volatil_data();
1612         }
1613
1614         _quickpanel_noti_gl_style_init();
1615
1616         ecore_timer_add(0.200, quickpanel_noti_refresh_gridbox, ad);
1617
1618         return QP_OK;
1619 }
1620
1621 static int quickpanel_noti_fini(void *data)
1622 {
1623         struct appdata *ad = data;
1624         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1625         if (g_noti_node != NULL) {
1626                 noti_node_destroy(&g_noti_node);
1627         }
1628
1629         /* Unregister event handler */
1630         _quickpanel_noti_unregister_event_handler(data);
1631         _quickpanel_noti_clear_list_all(ad->list);
1632         _quickpanel_noti_gl_style_fini();
1633         return QP_OK;
1634 }
1635
1636 static int quickpanel_noti_suspend(void *data)
1637 {
1638         struct appdata *ad = data;
1639         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1640
1641         suspended = 1;
1642
1643         if (ad->list) {
1644                 _quickpanel_noti_ani_image_control(EINA_FALSE);
1645         }
1646
1647         return QP_OK;
1648 }
1649
1650 static int quickpanel_noti_resume(void *data)
1651 {
1652         struct appdata *ad = data;
1653         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1654
1655         suspended = 0;
1656
1657         if (ad->list) {
1658                 quickpanel_list_util_item_update_by_type(ad->list,
1659                                 ongoing_first, QP_ITEM_TYPE_ONGOING_NOTI);
1660
1661                 _quickpanel_noti_ani_image_control(EINA_TRUE);
1662
1663                 _quickpanel_noti_update_notibox();
1664         }
1665
1666         return QP_OK;
1667 }
1668
1669 static void quickpanel_noti_refresh(void *data) {
1670         struct appdata *ad = NULL;
1671
1672         retif(data == NULL, , "Invalid parameter!");
1673         ad = data;
1674
1675         if (g_noti_gridbox != NULL) {
1676                 gridbox_rotation(g_noti_gridbox, ad->angle);
1677         }
1678         _quickpanel_noti_update_notibox();
1679 }
1680
1681 void quickpanel_noti_lang_changed(void *data)
1682 {
1683         struct appdata *ad = data;
1684
1685         retif(ad == NULL, , "Invalid parameter!");
1686
1687         _quickpanel_noti_update_notilist(ad);
1688
1689         _quickpanel_noti_update_notibox();
1690 }
1691
1692 static unsigned int quickpanel_noti_get_height(void *data)
1693 {
1694         int height = 0;
1695         struct appdata *ad = data;
1696
1697         retif(ad == NULL, 0, "Invalid parameter!");
1698
1699         if (noti_group) {
1700                 height = QP_THEME_LIST_ITEM_GROUP_HEIGHT;
1701         }
1702         height +=
1703                         noti_node_get_item_count(
1704                                         g_noti_node,
1705                                         NOTIFICATION_TYPE_NOTI) * QP_THEME_LIST_ITEM_NOTI_HEIGHT
1706                                         + noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_ONGOING) * (QP_THEME_LIST_ITEM_ONGOING_HEIGHT + QP_THEME_LIST_ITEM_ONGOING_SEPERATOR_HEIGHT);return
1707         height  * ad->scale;
1708 }