update for beta release
[framework/uifw/e17.git] / src / modules / clock / e_mod_main.c
1 #include "e.h"
2 #include "e_mod_main.h"
3
4 #include <sys/time.h>
5 #include <time.h>
6
7 /* gadcon requirements */
8 static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style);
9 static void _gc_shutdown(E_Gadcon_Client *gcc);
10 static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
11 static const char *_gc_label(E_Gadcon_Client_Class *client_class);
12 static Evas_Object *_gc_icon(E_Gadcon_Client_Class *client_class, Evas *evas);
13 static const char *_gc_id_new(E_Gadcon_Client_Class *client_class);
14 static Config_Item *_conf_item_get(const char *id);
15
16
17 /* and actually define the gadcon class that this module provides (just 1) */
18 static const E_Gadcon_Client_Class _gadcon_class =
19 {
20    GADCON_CLIENT_CLASS_VERSION,
21      "clock",
22      {
23         _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL, NULL
24      },
25    E_GADCON_CLIENT_STYLE_PLAIN
26 };
27
28 /* actual module specifics */
29 typedef struct _Instance Instance;
30
31 struct _Instance
32 {
33    E_Gadcon_Client *gcc;
34    Evas_Object     *o_clock, *o_table, *o_popclock, *o_cal;
35    E_Gadcon_Popup  *popup;
36    E_Menu          *menu;
37
38    int madj;
39
40    char year[8];
41    char month[32];
42    const char *daynames[7];
43    unsigned char daynums[7][6];
44    Eina_Bool dayweekends[7][6];
45    Eina_Bool dayvalids[7][6];
46    Eina_Bool daytoday[7][6];
47    Config_Item *cfg;
48 };
49
50 Config *clock_config = NULL;
51
52 static E_Config_DD *conf_edd = NULL;
53 static E_Config_DD *conf_item_edd = NULL;
54 static Eina_List *clock_instances = NULL;
55 static E_Action *act = NULL;
56 static Ecore_Timer *update_today = NULL;
57
58 static void
59 _clear_timestrs(Instance *inst)
60 {
61    int x;
62
63    for (x = 0; x < 7; x++)
64      {
65         if (inst->daynames[x])
66           {
67              eina_stringshare_del(inst->daynames[x]);
68              inst->daynames[x] = NULL;
69           }
70      }
71 }
72
73 static void
74 _time_eval(Instance *inst)
75 {
76    struct timeval      timev;
77    struct tm          *tm, tms, tmm, tm2;
78    time_t              tt;
79    int                 started = 0, num, i;
80
81    tzset();
82    gettimeofday(&timev, NULL);
83    tt = (time_t)(timev.tv_sec);
84    tm = localtime(&tt);
85
86    _clear_timestrs(inst);
87    if (tm)
88      {
89         int day;
90
91         // tms == current date time "saved"
92         // tm2 == date to look at adjusting for madj
93         // tm2 == month baseline @ 1st
94         memcpy(&tms, tm, sizeof(struct tm));
95         num = 0;
96         for (day = (0 - 6); day < (31 + 16); day++)
97           {
98              memcpy(&tmm, &tms, sizeof(struct tm));
99              tmm.tm_sec = 0;
100              tmm.tm_min = 0;
101              tmm.tm_hour = 10;
102              tmm.tm_mon += inst->madj;
103              tmm.tm_mday = 1; // start at the 1st of the month
104              tmm.tm_wday = 0; // ignored by mktime
105              tmm.tm_yday = 0; // ignored by mktime
106              tmm.tm_isdst = 0; // ignored by mktime
107              tt = mktime(&tmm);
108              tm = localtime(&tt);
109              memcpy(&tm2, tm, sizeof(struct tm));
110
111              tt = mktime(&tmm);
112              tt += (day * 60 * 60 * 24);
113              tm = localtime(&tt);
114              memcpy(&tmm, tm, sizeof(struct tm));
115              if (!started)
116                {
117                   if (tm->tm_wday == inst->cfg->week.start) started = 1;
118                }
119              if (started)
120                {
121                   int y = num / 7;
122                   int x = num % 7;
123
124                   if (y < 6)
125                     {
126                        inst->daynums[x][y] = tmm.tm_mday;
127
128                        inst->dayvalids[x][y] = 0;
129                        if (tmm.tm_mon == tm2.tm_mon) inst->dayvalids[x][y] = 1;
130
131                        inst->daytoday[x][y] = 0;
132                        if ((tmm.tm_mon == tms.tm_mon) &&
133                            (tmm.tm_year == tms.tm_year) &&
134                            (tmm.tm_mday == tms.tm_mday))
135                           inst->daytoday[x][y] = 1;
136
137                        inst->dayweekends[x][y] = 0;
138                        for (i = inst->cfg->weekend.start;
139                             i < (inst->cfg->weekend.start + inst->cfg->weekend.len);
140                             i++)
141                          {
142                             if (tmm.tm_wday == (i % 7))
143                               {
144                                  inst->dayweekends[x][y] = 1;
145                                  break;
146                               }
147                          }
148                        if (!inst->daynames[x])
149                          {
150                             char buf[32];
151
152                             buf[sizeof(buf) - 1] = 0;
153                             strftime(buf, sizeof(buf) - 1, "%a", (const struct tm *)&tmm); // %A full weekeday
154                             inst->daynames[x] = eina_stringshare_add(buf);
155                          }
156                     }
157                   num++;
158                }
159           }
160
161         memcpy(&tmm, &tms, sizeof(struct tm));
162         tmm.tm_sec = 0;
163         tmm.tm_min = 0;
164         tmm.tm_hour = 10;
165         tmm.tm_mon += inst->madj;
166         tmm.tm_mday = 1; // start at the 1st of the month
167         tmm.tm_wday = 0; // ignored by mktime
168         tmm.tm_yday = 0; // ignored by mktime
169         tmm.tm_isdst = 0; // ignored by mktime
170         tt = mktime(&tmm);
171         tm = localtime(&tt);
172         memcpy(&tm2, tm, sizeof(struct tm));
173         inst->year[sizeof(inst->year) - 1] = 0;
174         strftime(inst->year, sizeof(inst->year) - 1, "%Y", (const struct tm *)&tm2);
175         inst->month[sizeof(inst->month) - 1] = 0;
176         strftime(inst->month, sizeof(inst->month) - 1, "%B", (const struct tm *)&tm2); // %b for short month
177      }
178 }
179
180 static void
181 _clock_month_update(Instance *inst)
182 {
183    Evas_Object *od, *oi;
184    int x, y;
185
186    oi = inst->o_cal;
187    edje_object_part_text_set(oi, "e.text.month", inst->month);
188    edje_object_part_text_set(oi, "e.text.year", inst->year);
189    for (x = 0; x < 7; x++)
190      {
191         od = edje_object_part_table_child_get(oi, "e.table.daynames", x, 0);
192         edje_object_part_text_set(od, "e.text.label", inst->daynames[x]);
193      }
194
195    for (y = 0; y < 6; y++)
196      {
197         for (x = 0; x < 7; x++)
198           {
199              char buf[32];
200
201              od = edje_object_part_table_child_get(oi, "e.table.days", x, y);
202              snprintf(buf, sizeof(buf), "%i", (int)inst->daynums[x][y]);
203              edje_object_part_text_set(od, "e.text.label", buf);
204              if (inst->dayweekends[x][y])
205                 edje_object_signal_emit(od, "e,state,weekend", "e");
206              else
207                 edje_object_signal_emit(od, "e,state,weekday", "e");
208              if (inst->dayvalids[x][y])
209                 edje_object_signal_emit(od, "e,state,visible", "e");
210              else
211                 edje_object_signal_emit(od, "e,state,hidden", "e");
212              if (inst->daytoday[x][y])
213                 edje_object_signal_emit(od, "e,state,today", "e");
214              else
215                 edje_object_signal_emit(od, "e,state,someday", "e");
216           }
217      }
218 }
219
220 static void
221 _clock_month_prev_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
222 {
223    Instance *inst = data;
224    inst->madj--;
225    _time_eval(inst);
226    _clock_month_update(inst);
227 }
228
229 static void
230 _clock_month_next_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
231 {
232    Instance *inst = data;
233    inst->madj++;
234    _time_eval(inst);
235    _clock_month_update(inst);
236 }
237
238 static void
239 _clock_settings_cb(void *d1, void *d2 __UNUSED__)
240 {
241    Instance *inst = d1;
242    e_int_config_clock_module(inst->popup->win->zone->container, inst->cfg);
243    e_object_del(E_OBJECT(inst->popup));
244    inst->popup = NULL;
245 }
246
247 static void
248 _clock_popup_new(Instance *inst)
249 {
250    Evas *evas;
251    Evas_Object *o, *oi;
252    Evas_Coord mw = 128, mh = 128;
253    char todaystr[32];
254    time_t t;
255    struct tm *tm;
256
257    t = time(NULL);
258    tm = localtime(&t);
259    strftime(todaystr, sizeof(todaystr) - 1, "%a, %x", tm);
260
261    if (inst->popup) return;
262
263    inst->madj = 0;
264
265    _time_eval(inst);
266
267    inst->popup = e_gadcon_popup_new(inst->gcc);
268    evas = inst->popup->win->evas;
269
270    inst->o_table = e_widget_table_add(evas, 0);
271
272    oi = edje_object_add(evas);
273    inst->o_popclock = oi;
274    if (inst->cfg->digital_clock)
275       e_theme_edje_object_set(oi, "base/theme/modules/clock",
276                               "e/modules/clock/digital");
277    else
278       e_theme_edje_object_set(oi, "base/theme/modules/clock",
279                               "e/modules/clock/main");
280    if (inst->cfg->digital_24h)
281       edje_object_signal_emit(oi, "e,state,24h,on", "e");
282    else
283       edje_object_signal_emit(oi, "e,state,24h,off", "e");
284    if (inst->cfg->show_seconds)
285       edje_object_signal_emit(oi, "e,state,seconds,on", "e");
286    else
287       edje_object_signal_emit(oi, "e,state,seconds,off", "e");
288
289    edje_object_part_text_set(oi, "e.text.today", todaystr);
290
291    o = e_widget_image_add_from_object(evas, oi, 128, 128);
292    evas_object_show(oi);
293    e_widget_table_object_align_append(inst->o_table, o,
294                                       0, 0, 1, 1, 0, 0, 0, 0, 0.5, 0.5);
295
296    o = e_widget_button_add(evas, _("Settings"), "preferences-system",
297                            _clock_settings_cb, inst, NULL);
298    e_widget_table_object_align_append(inst->o_table, o,
299                                       0, 1, 1, 1, 0, 0, 0, 0, 0.5, 1.0);
300
301    oi = edje_object_add(evas);
302    inst->o_cal = oi;
303    e_theme_edje_object_set(oi, "base/theme/modules/clock",
304                            "e/modules/clock/calendar");
305    _clock_month_update(inst);
306
307    edje_object_signal_callback_add(oi, "e,action,prev", "*",
308                                    _clock_month_prev_cb, inst);
309    edje_object_signal_callback_add(oi, "e,action,next", "*",
310                                    _clock_month_next_cb, inst);
311    evas_object_resize(oi, 500, 500);
312    edje_object_size_min_restricted_calc(oi, &mw, &mh, 128, 128);
313
314    o = e_widget_image_add_from_object(evas, oi, mw, mh);
315    evas_object_show(oi);
316    e_widget_table_object_align_append(inst->o_table, o,
317                                       1, 0, 1, 2, 0, 0, 0, 0, 0.5, 0.5);
318
319    e_gadcon_popup_content_set(inst->popup, inst->o_table);
320    e_gadcon_popup_show(inst->popup);
321 }
322
323 static void
324 _eval_instance_size(Instance *inst)
325 {
326    Evas_Coord mw, mh, omw, omh;
327
328    edje_object_size_min_get(inst->o_clock, &mw, &mh);
329    omw = mw;
330    omh = mh;
331
332    if ((mw < 1) || (mh < 1))
333      {
334         Evas_Coord x, y, sw = 0, sh = 0, ow, oh;
335         Eina_Bool horiz;
336         const char *orient;
337
338         switch (inst->gcc->gadcon->orient)
339           {
340            case E_GADCON_ORIENT_TOP:
341            case E_GADCON_ORIENT_CORNER_TL:
342            case E_GADCON_ORIENT_CORNER_TR:
343            case E_GADCON_ORIENT_BOTTOM:
344            case E_GADCON_ORIENT_CORNER_BL:
345            case E_GADCON_ORIENT_CORNER_BR:
346            case E_GADCON_ORIENT_HORIZ:
347               horiz = EINA_TRUE;
348               orient = "e,state,horizontal";
349               break;
350
351            case E_GADCON_ORIENT_LEFT:
352            case E_GADCON_ORIENT_CORNER_LB:
353            case E_GADCON_ORIENT_CORNER_LT:
354            case E_GADCON_ORIENT_RIGHT:
355            case E_GADCON_ORIENT_CORNER_RB:
356            case E_GADCON_ORIENT_CORNER_RT:
357            case E_GADCON_ORIENT_VERT:
358               horiz = EINA_FALSE;
359               orient = "e,state,vertical";
360               break;
361
362            default:
363               horiz = EINA_TRUE;
364               orient = "e,state,float";
365           }
366
367         if (inst->gcc->gadcon->shelf)
368           {
369              if (horiz)
370                sh = inst->gcc->gadcon->shelf->h;
371              else
372                sw = inst->gcc->gadcon->shelf->w;
373           }
374
375         evas_object_geometry_get(inst->o_clock, NULL, NULL, &ow, &oh);
376         if (orient)
377           edje_object_signal_emit(inst->o_clock, orient, "e");
378         evas_object_resize(inst->o_clock, sw, sh);
379         edje_object_message_signal_process(inst->o_clock);
380
381         edje_object_parts_extends_calc(inst->o_clock, &x, &y, &mw, &mh);
382         evas_object_resize(inst->o_clock, ow, oh);
383      }
384
385    if (mw < 4) mw = 4;
386    if (mh < 4) mh = 4;
387
388    if (mw < omw) mw = omw;
389    if (mh < omh) mh = omh;
390
391    e_gadcon_client_aspect_set(inst->gcc, mw, mh);
392    e_gadcon_client_min_size_set(inst->gcc, mw, mh);
393 }
394
395 void
396 e_int_clock_instances_redo(void)
397 {
398    Eina_List *l;
399    Instance *inst;
400    char todaystr[32];
401    time_t t;
402    struct tm *tm;
403
404    t = time(NULL);
405    tm = localtime(&t);
406    strftime(todaystr, sizeof(todaystr) - 1, "%a, %x", tm);
407
408    EINA_LIST_FOREACH(clock_instances, l, inst)
409      {
410         Evas_Object *o = inst->o_clock;
411
412         if (inst->cfg->digital_clock)
413            e_theme_edje_object_set(o, "base/theme/modules/clock",
414                                    "e/modules/clock/digital");
415         else
416            e_theme_edje_object_set(o, "base/theme/modules/clock",
417                                    "e/modules/clock/main");
418         if (inst->cfg->digital_24h)
419            edje_object_signal_emit(o, "e,state,24h,on", "e");
420         else
421            edje_object_signal_emit(o, "e,state,24h,off", "e");
422         if (inst->cfg->show_seconds)
423            edje_object_signal_emit(o, "e,state,seconds,on", "e");
424         else
425            edje_object_signal_emit(o, "e,state,seconds,off", "e");
426
427         edje_object_part_text_set(o, "e.text.today", todaystr);
428         _eval_instance_size(inst);
429
430         if (inst->o_popclock)
431           {
432              o = inst->o_popclock;
433
434              if (inst->cfg->digital_clock)
435                e_theme_edje_object_set(o, "base/theme/modules/clock",
436                                        "e/modules/clock/digital");
437              else
438                e_theme_edje_object_set(o, "base/theme/modules/clock",
439                                        "e/modules/clock/main");
440              if (inst->cfg->digital_24h)
441                edje_object_signal_emit(o, "e,state,24h,on", "e");
442              else
443                edje_object_signal_emit(o, "e,state,24h,off", "e");
444              if (inst->cfg->show_seconds)
445                edje_object_signal_emit(o, "e,state,seconds,on", "e");
446              else
447                edje_object_signal_emit(o, "e,state,seconds,off", "e");
448
449              edje_object_part_text_set(o, "e.text.today", todaystr);
450           }
451      }
452 }
453
454 static Eina_Bool
455 _update_today_timer(void *data __UNUSED__)
456 {
457    time_t t, t_tomorrow;
458    const struct tm *now;
459    struct tm today;
460
461    e_int_clock_instances_redo();
462    if (!clock_instances)
463      {
464         update_today = NULL;
465         return EINA_FALSE;
466      }
467
468    t = time(NULL);
469    now = localtime(&t);
470    memcpy(&today, now, sizeof(today));
471    today.tm_sec = 1;
472    today.tm_min = 0;
473    today.tm_hour = 0;
474
475    t_tomorrow = mktime(&today) + 24 * 60 * 60;
476    update_today = ecore_timer_add(t_tomorrow - t, _update_today_timer, NULL);
477    return EINA_FALSE;
478 }
479
480 static void
481 _clock_popup_free(Instance *inst)
482 {
483    if (!inst->popup) return;
484    if (inst->popup) e_object_del(E_OBJECT(inst->popup));
485    inst->popup = NULL;
486    inst->o_popclock = NULL;
487 }
488
489 static void
490 _clock_menu_cb_post(void *data, E_Menu *menu __UNUSED__)
491 {
492    Instance *inst = data;
493    if ((!inst) || (!inst->menu))
494       return;
495    if (inst->menu)
496      {
497         e_object_del(E_OBJECT(inst->menu));
498         inst->menu = NULL;
499      }
500 }
501
502 static void
503 _clock_menu_cb_cfg(void *data, E_Menu *menu __UNUSED__, E_Menu_Item *mi __UNUSED__)
504 {
505    Instance *inst = data;
506    E_Container *con;
507
508    if (inst->popup)
509      {
510         e_object_del(E_OBJECT(inst->popup));
511         inst->popup = NULL;
512      }
513    con = e_container_current_get(e_manager_current_get());
514    e_int_config_clock_module(con, inst->cfg);
515 }
516
517 static void
518 _clock_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
519 {
520    Instance *inst = data;
521    Evas_Event_Mouse_Down *ev = event;
522
523    if (ev->button == 1)
524      {
525         if (inst->popup) _clock_popup_free(inst);
526         else _clock_popup_new(inst);
527      }
528    else if ((ev->button == 3) && (!inst->menu))
529      {
530         E_Zone *zone;
531         E_Menu *m;
532         E_Menu_Item *mi;
533         int x, y;
534
535         zone = e_util_zone_current_get(e_manager_current_get());
536
537         m = e_menu_new();
538
539         mi = e_menu_item_new(m);
540         e_menu_item_label_set(mi, _("Settings"));
541         e_util_menu_item_theme_icon_set(mi, "configure");
542         e_menu_item_callback_set(mi, _clock_menu_cb_cfg, inst);
543
544         m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
545         e_menu_post_deactivate_callback_set(m, _clock_menu_cb_post, inst);
546         inst->menu = m;
547
548         e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL);
549         e_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y,
550                               1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
551         evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
552                                  EVAS_BUTTON_NONE, ev->timestamp, NULL);
553      }
554 }
555
556 static void
557 _clock_sizing_changed_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
558 {
559    _eval_instance_size(data);
560 }
561
562 static E_Gadcon_Client *
563 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
564 {
565    Evas_Object *o;
566    E_Gadcon_Client *gcc;
567    Instance *inst;
568    char todaystr[32];
569    time_t t;
570    struct tm *tm;
571
572    t = time(NULL);
573    tm = localtime(&t);
574    strftime(todaystr, sizeof(todaystr) - 1, "%a, %x", tm);
575
576    inst = E_NEW(Instance, 1);
577    inst->cfg = _conf_item_get(id);
578
579    o = edje_object_add(gc->evas);
580    edje_object_signal_callback_add(o, "e,state,sizing,changed", "*",
581                                    _clock_sizing_changed_cb, inst);
582    if (inst->cfg->digital_clock)
583       e_theme_edje_object_set(o, "base/theme/modules/clock",
584                               "e/modules/clock/digital");
585    else
586       e_theme_edje_object_set(o, "base/theme/modules/clock",
587                               "e/modules/clock/main");
588    if (inst->cfg->digital_24h)
589       edje_object_signal_emit(o, "e,state,24h,on", "e");
590    else
591       edje_object_signal_emit(o, "e,state,24h,off", "e");
592    if (inst->cfg->show_seconds)
593       edje_object_signal_emit(o, "e,state,seconds,on", "e");
594    else
595       edje_object_signal_emit(o, "e,state,seconds,off", "e");
596
597    edje_object_part_text_set(o, "e.text.today", todaystr);
598    evas_object_show(o);
599
600    gcc = e_gadcon_client_new(gc, name, id, style, o);
601    gcc->data = inst;
602
603    inst->gcc = gcc;
604    inst->o_clock = o;
605
606    evas_object_event_callback_add(inst->o_clock,
607                                   EVAS_CALLBACK_MOUSE_DOWN,
608                                   _clock_cb_mouse_down,
609                                   inst);
610
611    clock_instances = eina_list_append(clock_instances, inst);
612
613    if (!update_today) _update_today_timer(NULL);
614
615    return gcc;
616 }
617
618 static void
619 _gc_shutdown(E_Gadcon_Client *gcc)
620 {
621    Instance *inst;
622
623    inst = gcc->data;
624    if (inst->menu)
625      {
626         e_menu_post_deactivate_callback_set(inst->menu, NULL, NULL);
627         e_object_del(E_OBJECT(inst->menu));
628         inst->menu = NULL;
629      }
630    clock_instances = eina_list_remove(clock_instances, inst);
631    evas_object_del(inst->o_clock);
632    _clock_popup_free(inst);
633    _clear_timestrs(inst);
634    free(inst);
635
636    if ((!clock_instances) && (update_today))
637      {
638         ecore_timer_del(update_today);
639         update_today = NULL;
640      }
641 }
642
643 static void
644 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient __UNUSED__)
645 {
646    _eval_instance_size(gcc->data);
647 }
648
649 static const char *
650 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
651 {
652    return _("Clock");
653 }
654
655 static Evas_Object *
656 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__, Evas *evas)
657 {
658    Evas_Object *o;
659    char buf[4096];
660
661    o = edje_object_add(evas);
662    snprintf(buf, sizeof(buf), "%s/e-module-clock.edj",
663             e_module_dir_get(clock_config->module));
664    edje_object_file_set(o, buf, "icon");
665    return o;
666 }
667
668
669 static const char *
670 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
671 {
672    Config_Item *ci = NULL;
673
674    ci = _conf_item_get(NULL);
675    return ci->id;
676 }
677
678 static Config_Item *
679 _conf_item_get(const char *id)
680 {
681    Config_Item *ci;
682
683    GADCON_CLIENT_CONFIG_GET(Config_Item, clock_config->items, _gadcon_class, id);
684
685    ci = E_NEW(Config_Item, 1);
686    ci->id = eina_stringshare_add(id);
687    ci->weekend.start = 6;
688    ci->weekend.len = 2;
689    ci->week.start = 1;
690    ci->digital_clock = 0;
691    ci->digital_24h = 0;
692    ci->show_seconds = 1;
693
694    clock_config->items = eina_list_append(clock_config->items, ci);
695    e_config_save_queue();
696
697    return ci;
698 }
699
700 static void
701 _e_mod_action(const char *params)
702 {
703    Eina_List *l;
704    Instance *inst;
705
706    if (!params) return ;
707    if (strcmp(params, "show_calendar")) return ;
708
709    EINA_LIST_FOREACH(clock_instances, l, inst)
710      if (inst->popup)
711        _clock_popup_free(inst);
712      else
713        _clock_popup_new(inst);
714 }
715
716 static void
717 _e_mod_action_cb_edge(E_Object *obj __UNUSED__, const char *params, E_Event_Zone_Edge *ev __UNUSED__)
718 {
719    _e_mod_action(params);
720 }
721
722 static void
723 _e_mod_action_cb(E_Object *obj __UNUSED__, const char *params)
724 {
725    _e_mod_action(params);
726 }
727
728 static void
729 _e_mod_action_cb_key(E_Object *obj __UNUSED__, const char *params, Ecore_Event_Key *ev __UNUSED__)
730 {
731    _e_mod_action(params);
732 }
733
734 static void
735 _e_mod_action_cb_mouse(E_Object *obj __UNUSED__, const char *params, Ecore_Event_Mouse_Button *ev __UNUSED__)
736 {
737    _e_mod_action(params);
738 }
739
740 /* module setup */
741 EAPI E_Module_Api e_modapi =
742 {
743    E_MODULE_API_VERSION,
744      "Clock"
745 };
746
747 EAPI void *
748 e_modapi_init(E_Module *m)
749 {
750    conf_item_edd = E_CONFIG_DD_NEW("Config_Item", Config_Item);
751 #undef T
752 #undef D
753 #define T Config_Item
754 #define D conf_item_edd
755    E_CONFIG_VAL(D, T, id, STR);
756    E_CONFIG_VAL(D, T, weekend.start, INT);
757    E_CONFIG_VAL(D, T, weekend.len, INT);
758    E_CONFIG_VAL(D, T, week.start, INT);
759    E_CONFIG_VAL(D, T, digital_clock, INT);
760    E_CONFIG_VAL(D, T, digital_24h, INT);
761    E_CONFIG_VAL(D, T, show_seconds, INT);
762
763    conf_edd = E_CONFIG_DD_NEW("Config", Config);
764 #undef T
765 #undef D
766 #define T Config
767 #define D conf_edd
768    E_CONFIG_LIST(D, T, items, conf_item_edd);
769
770    clock_config = e_config_domain_load("module.clock", conf_edd);
771
772    if (!clock_config)
773      clock_config = E_NEW(Config, 1);
774
775    act = e_action_add("clock");
776    if (act)
777      {
778        act->func.go = _e_mod_action_cb;
779        act->func.go_key = _e_mod_action_cb_key;
780        act->func.go_mouse = _e_mod_action_cb_mouse;
781        act->func.go_edge = _e_mod_action_cb_edge;
782
783        e_action_predef_name_set(_("Clock"), _("Show calendar"), "clock", "show_calendar", NULL, 0);
784      }
785
786    clock_config->module = m;
787
788    e_gadcon_provider_register(&_gadcon_class);
789    return m;
790 }
791
792 EAPI int
793 e_modapi_shutdown(E_Module *m __UNUSED__)
794 {
795    if (act)
796      {
797         e_action_predef_name_del(_("Clock"), _("Show calendar"));
798         e_action_del("clock");
799         act = NULL;
800      }
801    if (clock_config)
802      {
803         Config_Item *ci;
804
805         if (clock_config->config_dialog)
806           e_object_del(E_OBJECT(clock_config->config_dialog));
807
808         EINA_LIST_FREE(clock_config->items, ci)
809           {
810              eina_stringshare_del(ci->id);
811              free(ci);
812           }
813
814         free(clock_config);
815         clock_config = NULL;
816      }
817    E_CONFIG_DD_FREE(conf_edd);
818    E_CONFIG_DD_FREE(conf_item_edd);
819    conf_item_edd = NULL;
820    conf_edd = NULL;
821
822    e_gadcon_provider_unregister(&_gadcon_class);
823
824    if (update_today)
825      {
826         ecore_timer_del(update_today);
827         update_today = NULL;
828      }
829
830    return 1;
831 }
832
833 EAPI int
834 e_modapi_save(E_Module *m __UNUSED__)
835 {
836    e_config_domain_save("module.clock", conf_edd, clock_config);
837    return 1;
838 }