bd508606f3cf22098d3f55b38f19032e5a1780a6
[framework/uifw/e17.git] / src / modules / fileman_opinfo / e_mod_main.c
1 #include "e.h"
2 #include "e_mod_main.h"
3
4 typedef struct _Instance
5 {
6    char            *theme_file;
7    E_Gadcon_Client *gcc;
8
9    Evas_Object     *o_box, *o_status;
10
11    Ecore_Event_Handler *fm_op_entry_add_handler, *fm_op_entry_del_handler;
12 } Instance;
13
14 /* gadcon requirements */
15
16 static E_Gadcon_Client *_gc_init    (E_Gadcon *gc, const char *name, const char *id, const char *style);
17 static void             _gc_shutdown(E_Gadcon_Client *gcc);
18 static void             _gc_orient  (E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
19 static char            *_gc_label   (E_Gadcon_Client_Class *client_class);
20 static Evas_Object     *_gc_icon    (E_Gadcon_Client_Class *client_class, Evas *evas);
21 static const char      *_gc_id_new  (E_Gadcon_Client_Class *client_class);
22
23 static const E_Gadcon_Client_Class _gadcon_class = {
24    GADCON_CLIENT_CLASS_VERSION, "efm_info",
25    {
26       _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
27       e_gadcon_site_is_desktop
28    },
29    E_GADCON_CLIENT_STYLE_PLAIN
30 };
31
32 /********************   PROTOS   *******************************************/
33
34 static Eina_Bool  _opinfo_op_registry_entry_add_cb     (void *data, int type, void *event);
35 static Eina_Bool  _opinfo_op_registry_entry_del_cb     (void *data, int type, void *event);
36 static void _opinfo_op_registry_update_all       (Instance *inst);
37 static void _opinfo_op_registry_listener         (void *data, const E_Fm2_Op_Registry_Entry *ere);
38 static void _opinfo_op_registry_free_data        (void *data);
39 static Eina_Bool  _opinfo_op_registry_free_data_delayed(void *data);
40 static void _opinfo_op_registry_abort_cb         (void *data, Evas_Object *obj, const char *emission, const char *source);
41 static void _opinfo_op_registry_summary_cb       (void *data, Evas_Object *obj, const char *emission, const char *source);
42 static void _opinfo_op_registry_detailed_cb      (void *data, Evas_Object *obj, const char *emission, const char *source);
43 static void _opinfo_op_registry_window_jump_cb   (void *data, Evas_Object *obj, const char *emission, const char *source);
44 static void _opinfo_op_registry_update_status    (Instance *inst);
45
46 /********************   GLOBALS   ******************************************/
47
48 static E_Module *opinfo_module = NULL;
49
50 /********************   OP_REGISTRY   *************************************/
51
52 static void
53 _opinfo_op_registry_listener(void *data, const E_Fm2_Op_Registry_Entry *ere)
54 {
55    Evas_Object *o = data;
56    char *total, buf[PATH_MAX];
57
58    if (!o || !ere) return;
59    
60    // Update icon
61    switch (ere->op)
62    {
63       case E_FM_OP_COPY:
64          edje_object_signal_emit(o, "e,action,icon,copy", "e");
65          break;
66       case E_FM_OP_MOVE:
67          edje_object_signal_emit(o, "e,action,icon,move", "e");
68          break;
69       case E_FM_OP_REMOVE:
70          edje_object_signal_emit(o, "e,action,icon,delete", "e");
71          break;
72       default:
73          edje_object_signal_emit(o, "e,action,icon,unknow", "e");
74    }
75    
76    // Update has/none linked efm window
77    if (e_win_evas_object_win_get(ere->e_fm))
78       edje_object_signal_emit(o, "state,set,window,exist", "fileman_opinfo");
79    else
80       edje_object_signal_emit(o, "state,set,window,absent", "fileman_opinfo");
81    
82    // Update information text
83    switch (ere->status)
84    {
85       case E_FM2_OP_STATUS_ABORTED:
86          switch (ere->op)
87          {
88             case E_FM_OP_COPY:
89                snprintf(buf, sizeof(buf), _("Copying is aborted"));
90                break;
91             case E_FM_OP_MOVE:
92                snprintf(buf, sizeof(buf), _("Moving is aborted"));
93                break;
94             case E_FM_OP_REMOVE:
95                snprintf(buf, sizeof(buf), _("Deleting is aborted"));
96                break;
97             default:
98                snprintf(buf, sizeof(buf), _("Unknown operation from slave is aborted"));
99          }
100          break;
101
102       default:
103          total = e_util_size_string_get(ere->total);
104          switch (ere->op)
105          {
106             case E_FM_OP_COPY:
107                if (ere->finished)
108                   snprintf(buf, sizeof(buf), _("Copy of %s done"), total);
109                else
110                   snprintf(buf, sizeof(buf), _("Copying %s (eta: %d sec)"), total, ere->eta);
111                break;
112             case E_FM_OP_MOVE:
113                if (ere->finished)
114                   snprintf(buf, sizeof(buf), _("Move of %s done"), total);
115                else
116                   snprintf(buf, sizeof(buf), _("Moving %s (eta: %d sec)"), total, ere->eta);
117                break;
118             case E_FM_OP_REMOVE:
119                if (ere->finished)
120                   snprintf(buf, sizeof(buf), _("Delete done"));
121                else
122                   snprintf(buf, sizeof(buf), _("Deleting files..."));
123                break;
124             default:
125                snprintf(buf, sizeof(buf), _("Unknow operation from slave %d"), ere->id);
126          }
127          E_FREE(total);
128    }
129    edje_object_part_text_set(o, "e.text.info", buf);
130    
131    // Update detailed information
132    if (!ere->src)
133       edje_object_part_text_set(o, "e.text.src", _("(no information)"));
134    else
135      {
136         if (ere->op == E_FM_OP_REMOVE)
137            snprintf(buf, sizeof(buf), _("File: %s"), ere->src);
138         else
139            snprintf(buf, sizeof(buf), _("From: %s"), ere->src);
140         edje_object_part_text_set(o, "e.text.src", buf);
141      }
142    if (!ere->dst || ere->op == E_FM_OP_REMOVE)
143       edje_object_part_text_set(o, "e.text.dest", _("(no information)"));
144    else
145      {
146         snprintf(buf, sizeof(buf), _("To: %s"), ere->dst);
147         edje_object_part_text_set(o, "e.text.dest", buf);
148      }
149    
150    // Update gauge
151    edje_object_part_drag_size_set(o, "e.gauge.bar", ere->percent / 100.0, 1.0);
152    snprintf(buf, sizeof(buf), "%3i%%", ere->percent);
153    edje_object_part_text_set(o, "e.text.percent", buf);
154    
155    // Update attention
156    if (ere->needs_attention)
157       edje_object_signal_emit(o, "e,action,set,need_attention", "e");
158    else
159       edje_object_signal_emit(o, "e,action,set,normal", "e");
160 }
161
162 static void
163 _opinfo_op_registry_free_data(void *data)
164 {
165    ecore_timer_add(5.0, _opinfo_op_registry_free_data_delayed, data);
166 }
167
168 static Eina_Bool
169 _opinfo_op_registry_free_data_delayed(void *data)
170 {
171    Evas_Object *o = data;
172    
173    if (o)
174      {
175         e_box_unpack(o);
176         evas_object_del(o);
177      }
178    
179    return ECORE_CALLBACK_CANCEL;
180 }
181
182 static void 
183 _opinfo_op_registry_abort_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
184 {
185    int id;
186    
187    id = (long)data;
188    if (!id) return;
189    
190    e_fm2_operation_abort(id);
191 }
192
193 static void 
194 _opinfo_op_registry_summary_cb(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
195 {
196    int mw, mh;
197    
198    edje_object_signal_emit(obj, "state,set,summary", "fileman_opinfo");
199
200    edje_object_size_min_get(obj, &mw, &mh);
201    e_box_pack_options_set(obj, 1, 0, 1, 0, 0.0, 0.0, mw, mh, 9999, mh);
202 }
203
204 static void 
205 _opinfo_op_registry_detailed_cb(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
206 {
207    int mw, xh;
208
209    edje_object_signal_emit(obj, "state,set,detailed", "fileman_opinfo");
210
211    edje_object_size_min_calc(obj, &mw, NULL);
212    edje_object_size_max_get(obj, NULL, &xh);
213    e_box_pack_options_set(obj, 1, 0, 1, 0, 0.0, 0.0, mw, xh, 9999, xh);
214 }
215
216 static void 
217 _opinfo_op_registry_window_jump_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
218 {
219    int id = (long)data;
220    E_Fm2_Op_Registry_Entry *ere;
221    E_Win *win;
222    
223    if (!id) return;
224    ere = e_fm2_op_registry_entry_get(id);
225    if (!ere) return;
226
227    // if attention dialog is present then raise it, otherwise raise the efm window
228    win = (ere->needs_attention && ere->dialog) ? ere->dialog->win
229                                                : e_win_evas_object_win_get(ere->e_fm);
230    if (!win) return;
231    
232    if (win->border)
233      {
234         if (win->border->iconic)
235            e_border_uniconify(win->border);
236         if (win->border->shaded)
237            e_border_unshade(win->border, win->border->shade.dir);
238      }
239    else
240      e_win_show(win);
241    e_win_raise(win);
242    e_desk_show(win->border->desk);
243    e_border_focus_set_with_pointer(win->border);
244    
245    if (ere->needs_attention && e_config->pointer_slide)
246       e_border_pointer_warp_to_center(win->border);
247 }
248
249 static Eina_Bool
250 _opinfo_op_registry_entry_add_cb(void *data, __UNUSED__ int type, void *event)
251 {
252    E_Fm2_Op_Registry_Entry *ere = event;
253    Instance *inst = data;
254    Evas_Object *o;
255    
256    if (!inst || !ere)
257       return ECORE_CALLBACK_RENEW;
258
259    _opinfo_op_registry_update_status(inst);
260
261    if (!(ere->op == E_FM_OP_COPY || ere->op == E_FM_OP_MOVE || ere->op == E_FM_OP_REMOVE))
262       return ECORE_CALLBACK_RENEW;
263    
264    o = edje_object_add(evas_object_evas_get(inst->o_box));
265    if (!e_theme_edje_object_set(o, "base/theme/modules/fileman_opinfo", 
266                                 "modules/fileman_opinfo/main"))
267       edje_object_file_set(o, inst->theme_file, "modules/fileman_opinfo/main");
268    _opinfo_op_registry_listener(o, ere);
269    e_box_pack_before(inst->o_box, o, inst->o_status);
270    evas_object_show(o);
271    _opinfo_op_registry_summary_cb(inst, o, NULL, NULL);
272    
273    edje_object_signal_callback_add(o, "e,fm,operation,abort", "",
274                                    _opinfo_op_registry_abort_cb, (void*)(long)ere->id);
275    edje_object_signal_callback_add(o, "state,request,summary", "fileman_opinfo",
276                                    _opinfo_op_registry_summary_cb, inst);
277    edje_object_signal_callback_add(o, "state,request,detailed", "fileman_opinfo",
278                                    _opinfo_op_registry_detailed_cb, inst);
279    edje_object_signal_callback_add(o, "e,fm,window,jump", "",
280                                    _opinfo_op_registry_window_jump_cb, (void*)(long)ere->id);
281    
282    e_fm2_op_registry_entry_listener_add(ere, _opinfo_op_registry_listener,
283                                         o, _opinfo_op_registry_free_data);
284    
285    return ECORE_CALLBACK_RENEW;
286 }
287
288 static Eina_Bool
289 _opinfo_op_registry_entry_del_cb(void *data, __UNUSED__ int type, __UNUSED__ void *event)
290 {
291    Instance *inst = data;
292    
293    if (!inst)
294       return ECORE_CALLBACK_RENEW;
295
296    _opinfo_op_registry_update_status(inst);
297
298    return ECORE_CALLBACK_RENEW;
299 }
300
301 static void
302 _opinfo_op_registry_update_all(Instance *inst)
303 {
304    Eina_Iterator *itr;
305    E_Fm2_Op_Registry_Entry *ere;
306
307    itr = e_fm2_op_registry_iterator_new();
308    EINA_ITERATOR_FOREACH(itr, ere)
309       _opinfo_op_registry_entry_add_cb(inst, 0, ere);
310    eina_iterator_free(itr);
311
312    _opinfo_op_registry_update_status(inst);
313 }
314
315 static void 
316 _opinfo_op_registry_update_status(Instance *inst)
317 {
318    int cnt;
319    char buf[256];
320    
321    cnt = e_fm2_op_registry_count();
322    if (cnt)
323      {
324         snprintf(buf, sizeof(buf), _("Processing %d operation(s)"), cnt);
325         edje_object_part_text_set(inst->o_status, "e.text.info", buf);
326      }
327    else
328      edje_object_part_text_set(inst->o_status, "e.text.info", _("Filemanager is idle"));
329 }
330
331 /********************   GADCON   *******************************************/
332
333 static E_Gadcon_Client *
334 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
335 {
336    E_Gadcon_Client *gcc;
337    Instance *inst;
338    int mw, mh;
339
340    inst = E_NEW(Instance, 1);
341
342    asprintf(&inst->theme_file, "%s/e-module-fileman_opinfo.edj",
343             e_module_dir_get(opinfo_module));
344
345    // main object
346    inst->o_box = e_box_add(gc->evas);
347    e_box_homogenous_set(inst->o_box, 0);
348    e_box_orientation_set(inst->o_box, 0);
349    e_box_align_set(inst->o_box, 0, 0);
350
351    // status line
352    inst->o_status = edje_object_add(evas_object_evas_get(inst->o_box));
353    if (!e_theme_edje_object_set(inst->o_status, "base/theme/modules/fileman_opinfo",
354                                 "modules/fileman_opinfo/status"))
355       edje_object_file_set(inst->o_status, inst->theme_file, "modules/fileman_opinfo/status");
356    e_box_pack_end(inst->o_box, inst->o_status);
357    evas_object_show(inst->o_status);
358    edje_object_size_min_get(inst->o_status, &mw, &mh);
359    e_box_pack_options_set(inst->o_status, 1, 0, 1, 0, 0.0, 0.0, mw, mh, 9999, mh);
360
361    _opinfo_op_registry_update_all(inst);
362
363    gcc = e_gadcon_client_new(gc, name, id, style, inst->o_box);
364    gcc->data = inst;
365    inst->gcc = gcc;
366
367    e_gadcon_client_util_menu_attach(gcc);
368
369    inst->fm_op_entry_add_handler =
370       ecore_event_handler_add(E_EVENT_FM_OP_REGISTRY_ADD,
371                               _opinfo_op_registry_entry_add_cb, inst);
372    inst->fm_op_entry_del_handler =
373       ecore_event_handler_add(E_EVENT_FM_OP_REGISTRY_DEL,
374                               _opinfo_op_registry_entry_del_cb, inst);
375
376    return gcc;
377 }
378
379 static void
380 _gc_shutdown(E_Gadcon_Client *gcc)
381 {
382    Instance *inst = gcc->data;
383
384    if (inst->fm_op_entry_add_handler)
385      ecore_event_handler_del(inst->fm_op_entry_add_handler);
386    if (inst->fm_op_entry_del_handler)
387      ecore_event_handler_del(inst->fm_op_entry_del_handler);
388    e_box_unpack(inst->o_status);
389    evas_object_del(inst->o_status);
390    evas_object_del(inst->o_box);
391    free(inst->theme_file);
392    E_FREE(inst);
393 }
394
395 static void
396 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient __UNUSED__)
397 {
398    Instance *inst = gcc->data;
399    Evas_Coord mw = 200, mh = 100;
400
401    evas_object_size_hint_min_set(inst->o_box, mw, mh);
402    e_gadcon_client_aspect_set(gcc, mw, mh);
403    e_gadcon_client_min_size_set(gcc, mw, mh);
404 }
405
406 static char *
407 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
408 {
409    return _("EFM Operation Info");
410 }
411
412 static Evas_Object *
413 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__, Evas *evas)
414 {
415    Evas_Object *o;
416    char buf[PATH_MAX];
417
418    o = edje_object_add(evas);
419    snprintf(buf, sizeof(buf), "%s/e-module-fileman_opinfo.edj",
420             e_module_dir_get(opinfo_module));
421    edje_object_file_set(o, buf, "icon");
422    
423    return o;
424 }
425
426 static const char *
427 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
428 {
429    return _gadcon_class.name;
430 }
431
432 /********************   E MODULE   ****************************************/
433
434 EAPI E_Module_Api e_modapi = 
435 {
436    E_MODULE_API_VERSION,
437    "EFM Info"
438 };
439
440 EAPI void *
441 e_modapi_init(E_Module *m)
442 {
443    opinfo_module = m;
444    e_gadcon_provider_register(&_gadcon_class);
445    return m;
446 }
447
448 EAPI int
449 e_modapi_shutdown(E_Module *m __UNUSED__)
450 {
451    opinfo_module = NULL;
452    e_gadcon_provider_unregister(&_gadcon_class);
453    return 1;
454 }
455
456 EAPI int
457 e_modapi_save(E_Module *m __UNUSED__)
458 {
459    return 1;
460 }