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