[entry-modules]: modified the widget data structure
[framework/uifw/elementary.git] / src / modules / ctxpopup_copypasteUI / copypaste.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Mod_Api Mod_Api;
5 typedef struct _Widget_Data Widget_Data;
6 typedef struct _Elm_Entry_Context_Menu_Item Elm_Entry_Context_Menu_Item;
7 struct _Widget_Data
8 {
9    Evas_Object *ent;
10    Evas_Object *popup;/*copy paste UI - elm_popup*/
11    Evas_Object *ctxpopup;/*copy paste UI - elm_ctxpopup*/
12    Evas_Object *bg;   
13    Evas_Object *hoversel;
14    Ecore_Job *deferred_recalc_job;
15    Ecore_Event_Handler *sel_notify_handler;
16    Ecore_Event_Handler *sel_clear_handler;
17    Ecore_Timer *longpress_timer;
18    const char *cut_sel;
19    const char *text;
20    Evas_Coord wrap_w;
21    Evas_Coord lastw;
22    Evas_Coord downx, downy;
23    Evas_Coord cx, cy, cw, ch;
24    Eina_List *items;
25    Eina_List *item_providers;
26    Mod_Api *api; // module api if supplied
27    int max_no_of_bytes;
28    Eina_Bool changed : 1;
29    Eina_Bool linewrap : 1;
30    Eina_Bool char_linewrap : 1;
31    Eina_Bool single_line : 1;
32    Eina_Bool password : 1;
33    Eina_Bool show_last_character : 1;
34    Eina_Bool editable : 1;
35    Eina_Bool selection_asked : 1;
36    Eina_Bool have_selection : 1;
37    Eina_Bool selmode : 1;
38    Eina_Bool deferred_cur : 1;
39    Eina_Bool disabled : 1;
40    Eina_Bool context_menu : 1;
41    Eina_Bool bgcolor : 1;
42    Eina_Bool ellipsis : 1;
43    Eina_Bool autoreturnkey : 1;
44 };
45
46 struct _Elm_Entry_Context_Menu_Item
47 {
48    Evas_Object *obj;
49    const char *label;
50    const char *icon_file;
51    const char *icon_group;
52    Elm_Icon_Type icon_type;
53    Evas_Smart_Cb func;
54    void *data;
55 };
56
57
58 static void
59 _store_selection(Evas_Object *obj)
60 {
61    Widget_Data *wd = elm_widget_data_get(obj);
62    const char *sel = edje_object_part_text_selection_get(wd->ent, "elm.text");
63    if (!wd) return;
64    if (wd->cut_sel) eina_stringshare_del(wd->cut_sel);
65    wd->cut_sel = eina_stringshare_add(sel);
66 }
67
68 static void
69 _ctxpopup_position(Evas_Object *obj)
70 {
71    Widget_Data *wd = elm_widget_data_get(obj);
72    Evas_Coord cx, cy, cw, ch, x, y, mw, mh;
73    if (!wd) return;
74    evas_object_geometry_get(wd->ent, &x, &y, NULL, NULL);
75    edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text",
76                                              &cx, &cy, &cw, &ch);
77    evas_object_size_hint_min_get(wd->ctxpopup, &mw, &mh);
78    if (cw < mw)
79      {
80         cx += (cw - mw) / 2;
81         cw = mw;
82      }
83    if (ch < mh)
84      {
85         cy += (ch - mh) / 2;
86         ch = mh;
87      }
88    evas_object_move(wd->ctxpopup, x + cx, y + cy);
89    evas_object_resize(wd->ctxpopup, cw, ch);
90 }
91
92 static void
93 _select(void *data, Evas_Object *obj, void *event_info)
94 {
95    Widget_Data *wd = elm_widget_data_get(data);
96    wd->selmode = EINA_TRUE;
97    edje_object_part_text_select_none(wd->ent, "elm.text");
98    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 1);
99    if (!wd->password)
100       edje_object_signal_emit(wd->ent, "elm,state,select,on", "elm");
101    elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
102    elm_widget_scroll_hold_push(data);
103    evas_object_hide(obj);
104 }
105
106 static void
107 _paste(void *data, Evas_Object *obj, void *event_info)
108 {
109    Widget_Data *wd = elm_widget_data_get(data);
110     if (!wd) return;
111    evas_object_smart_callback_call(data, "selection,paste", NULL);
112    if (wd->sel_notify_handler)
113      {
114 #ifdef HAVE_ELEMENTARY_X
115         Evas_Object *top;
116
117         top = elm_widget_top_get(data);
118         if ((top) && (elm_win_xwindow_get(top)))
119           {
120              ecore_x_selection_primary_request
121                (elm_win_xwindow_get(top),
122                 ECORE_X_SELECTION_TARGET_UTF8_STRING);
123              wd->selection_asked = EINA_TRUE;
124           }
125 #endif
126      }  
127    elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
128    evas_object_hide(obj);
129 }
130
131 static void
132 _cut(void *data, Evas_Object *obj, void *event_info)
133 {
134    Widget_Data *wd = elm_widget_data_get(data);
135    wd->selmode = EINA_FALSE;
136    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
137    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
138    elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
139    elm_widget_scroll_hold_pop(data);
140    _store_selection(data);
141    edje_object_part_text_insert(wd->ent, "elm.text", "");
142    edje_object_part_text_select_none(wd->ent, "elm.text");
143    evas_object_hide(obj);
144 }
145
146 static void
147 _copy(void *data, Evas_Object *obj, void *event_info)
148 {
149    Widget_Data *wd = elm_widget_data_get(data);
150    if (!wd) return;
151    wd->selmode = EINA_FALSE;
152    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
153    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
154    elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
155    elm_widget_scroll_hold_pop(data);
156    _store_selection(data);
157    edje_object_part_text_select_none(wd->ent, "elm.text");
158    evas_object_hide(obj);
159 }
160
161 static void
162 _cancel(void *data, Evas_Object *obj, void *event_info)
163 {
164    Widget_Data *wd = elm_widget_data_get(data);
165    if (!wd) return;
166    wd->selmode = EINA_FALSE;
167    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
168    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
169    elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
170    elm_widget_scroll_hold_pop(data);
171    edje_object_part_text_select_none(wd->ent, "elm.text");
172    evas_object_hide(obj);
173 }
174
175 static void
176 _item_clicked(void *data, Evas_Object *obj, void *event_info)
177 {
178    Elm_Entry_Context_Menu_Item *it = data;
179    Evas_Object *obj2 = it->obj;
180
181    if (it->func) it->func(it->data, obj2, NULL);
182 }
183
184 // module api funcs needed
185 EAPI int
186 elm_modapi_init(void *m)
187 {
188    return 1; // succeed always
189 }
190
191 EAPI int
192 elm_modapi_shutdown(void *m)
193 {
194    return 1; // succeed always
195 }
196
197 // module fucns for the specific module type
198 EAPI void
199 obj_hook(Evas_Object *obj)
200 {
201   
202 }
203
204 EAPI void
205 obj_unhook(Evas_Object *obj)
206 {
207    
208 }
209
210 EAPI void
211 obj_longpress(Evas_Object *obj)
212 {
213                         
214                         Widget_Data *wd = elm_widget_data_get(obj);
215                         Evas_Object *top;
216                         const Eina_List *l;
217                         const Elm_Entry_Context_Menu_Item *it;
218                         const char *context_menu_orientation;
219
220                         if (wd->ctxpopup) evas_object_del(wd->ctxpopup);
221                        else elm_widget_scroll_freeze_push(obj);
222                         top = elm_widget_top_get(obj);
223                         if(top)
224                                 wd->ctxpopup = elm_ctxpopup_add(top);
225                         elm_object_style_set(wd->ctxpopup,"entry");
226                         elm_ctxpopup_scroller_disabled_set(wd->ctxpopup, EINA_TRUE);
227                         context_menu_orientation = edje_object_data_get
228                         (wd->ent, "context_menu_orientation");
229                         if ((context_menu_orientation) &&
230                         (!strcmp(context_menu_orientation, "horizontal")))
231                                 elm_ctxpopup_horizontal_set(wd->ctxpopup, EINA_TRUE);
232
233                         elm_widget_sub_object_add(obj, wd->ctxpopup);
234                         if (!wd->selmode)
235                                 {       
236                                         if (!wd->password)
237                                                 elm_ctxpopup_label_add(wd->ctxpopup, "Select",_select, obj );
238                                         if (1) // need way to detect if someone has a selection
239                                                 {
240                                                         if (wd->editable)
241                                                                 elm_ctxpopup_label_add(wd->ctxpopup, "Paste",   _paste, obj );
242                                                 }
243                         //              elm_ctxpopup_label_add(wd->ctxpopup, "Selectall",_select_all, obj );
244                                 }
245                         else
246                                 {
247                                           if (!wd->password)
248                                                 {
249                                                         if (wd->have_selection)
250                                                                 {
251                                                                         elm_ctxpopup_label_add(wd->ctxpopup, "Copy",_copy, obj );
252                                                                         if (wd->editable)
253                                                                                 elm_ctxpopup_label_add(wd->ctxpopup, "Cut",_cut, obj );                                                 
254                                                                 }
255                                                         else
256                                                                 {
257                                                                         _cancel(obj,wd->ctxpopup,NULL);                                                 
258                                                                         if (1) // need way to detect if someone has a selection
259                                                                                 {
260                                                                                         if (wd->editable)
261                                                                                                 elm_ctxpopup_label_add(wd->ctxpopup, "Paste",   _paste, obj );
262                                                                                 }
263                                                                         elm_ctxpopup_label_add(wd->ctxpopup, "Select",_select, obj );
264                                                                 }
265                                                 }
266                                 }
267                                 EINA_LIST_FOREACH(wd->items, l, it)
268                                 {
269                                         elm_ctxpopup_label_add(wd->ctxpopup, it->label,_item_clicked, it );
270                                 }
271                         if (wd->ctxpopup)
272                                 {
273                                         _ctxpopup_position(obj);
274                                         evas_object_show(wd->ctxpopup);           
275                                 }
276                         wd->longpress_timer = NULL;
277         }
278
279 EAPI void
280 obj_mouseup(Evas_Object *obj)
281 {
282         Widget_Data *wd = elm_widget_data_get(obj);
283    if (wd->longpress_timer)
284      {          
285                 ecore_timer_del(wd->longpress_timer);
286                 wd->longpress_timer = NULL;
287                 if (wd->have_selection )
288                         {                               
289                                 _cancel(obj,wd->ctxpopup,NULL);
290                         }
291      }     
292    else
293    {
294                 if (wd->have_selection )
295                         {
296                                 obj_longpress( obj );
297                         }
298    }
299 }
300
301