Merge with EFL svn repo
[framework/uifw/elementary.git] / src / modules / popup_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 *hoversel;
13    Ecore_Job *deferred_recalc_job;
14    Ecore_Event_Handler *sel_notify_handler;
15    Ecore_Event_Handler *sel_clear_handler;
16    Ecore_Timer *longpress_timer;
17    const char *cut_sel;
18    const char *text;
19    Evas_Coord lastw;
20    Evas_Coord downx, downy;
21    Evas_Coord cx, cy, cw, ch;
22    Eina_List *items;
23    Eina_List *item_providers;
24    Mod_Api *api; // module api if supplied
25    int max_no_of_bytes;
26    Eina_Bool changed : 1;
27    Eina_Bool linewrap : 1;
28    Eina_Bool char_linewrap : 1;
29    Eina_Bool single_line : 1;
30    Eina_Bool password : 1;
31    Eina_Bool show_last_character : 1;
32    Eina_Bool editable : 1;
33    Eina_Bool selection_asked : 1;
34    Eina_Bool have_selection : 1;
35    Eina_Bool selmode : 1;
36    Eina_Bool deferred_cur : 1;
37    Eina_Bool disabled : 1;
38    Eina_Bool context_menu : 1;
39    Eina_Bool autoreturnkey : 1;
40 };
41
42 struct _Elm_Entry_Context_Menu_Item
43 {
44    Evas_Object *obj;
45    const char *label;
46    const char *icon_file;
47    const char *icon_group;
48    Elm_Icon_Type icon_type;
49    Evas_Smart_Cb func;
50    void *data;
51 };
52
53
54 static void
55 _store_selection(Evas_Object *obj)
56 {
57    Widget_Data *wd = elm_widget_data_get(obj);
58    const char *sel = edje_object_part_text_selection_get(wd->ent, "elm.text");
59    if (!wd) return;
60    if (wd->cut_sel) eina_stringshare_del(wd->cut_sel);
61    wd->cut_sel = eina_stringshare_add(sel);
62 }
63
64 static void
65 _select(void *data, Evas_Object *obj, void *event_info)
66 {
67    Widget_Data *wd = elm_widget_data_get(data);
68    wd->selmode = EINA_TRUE;
69    edje_object_part_text_select_none(wd->ent, "elm.text");
70    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 1);
71    if (!wd->password)
72       edje_object_signal_emit(wd->ent, "elm,state,select,on", "elm");
73    elm_widget_scroll_hold_push(data);
74     evas_object_hide(wd->popup);
75 }
76
77 static void
78 _paste(void *data, Evas_Object *obj, void *event_info)
79 {
80    Widget_Data *wd = elm_widget_data_get(data);
81     if (!wd) return;
82    evas_object_smart_callback_call(data, "selection,paste", NULL);
83    if (wd->sel_notify_handler)
84      {
85 #ifdef HAVE_ELEMENTARY_X
86         Evas_Object *top;
87
88         top = elm_widget_top_get(data);
89         if ((top) && (elm_win_xwindow_get(top)))
90           {
91              ecore_x_selection_primary_request
92                (elm_win_xwindow_get(top),
93                 ECORE_X_SELECTION_TARGET_UTF8_STRING);
94              wd->selection_asked = EINA_TRUE;
95           }
96 #endif
97      }  
98    evas_object_hide(wd->popup);
99 }
100
101 static void
102 _cut(void *data, Evas_Object *obj, void *event_info)
103 {       
104    Widget_Data *wd = elm_widget_data_get(data);
105    wd->selmode = EINA_FALSE;
106    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
107    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
108    elm_widget_scroll_hold_pop(data);
109    _store_selection(data);
110    edje_object_part_text_insert(wd->ent, "elm.text", "");
111    edje_object_part_text_select_none(wd->ent, "elm.text");
112    evas_object_hide(wd->popup);
113 }
114
115 static void
116 _copy(void *data, Evas_Object *obj, void *event_info)
117 {
118    Widget_Data *wd = elm_widget_data_get(data);
119    if (!wd) return;
120    wd->selmode = EINA_FALSE;
121    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
122    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
123    elm_widget_scroll_hold_pop(data);
124    _store_selection(data);
125    edje_object_part_text_select_none(wd->ent, "elm.text");
126    evas_object_hide(wd->popup);
127 }
128
129 static void
130 _cancel(void *data, Evas_Object *obj, void *event_info)
131 {
132    Widget_Data *wd = elm_widget_data_get(data);
133    if (!wd) return;
134    wd->selmode = EINA_FALSE;
135    edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
136    edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
137    elm_widget_scroll_hold_pop(data);
138    edje_object_part_text_select_none(wd->ent, "elm.text");
139    evas_object_hide(wd->popup);
140 }
141
142 static void
143 _item_clicked(void *data, Evas_Object *obj, void *event_info)
144 {
145    Elm_Entry_Context_Menu_Item *it = data;
146    Evas_Object *obj2 = it->obj;
147
148    if (it->func) it->func(it->data, obj2, NULL);
149 }
150
151 // module api funcs needed
152 EAPI int
153 elm_modapi_init(void *m)
154 {
155    return 1; // succeed always
156 }
157
158 EAPI int
159 elm_modapi_shutdown(void *m)
160 {
161    return 1; // succeed always
162 }
163
164 // module fucns for the specific module type
165 EAPI void
166 obj_hook(Evas_Object *obj)
167 {
168         
169 }
170
171 EAPI void
172 obj_unhook(Evas_Object *obj)
173 {
174    
175 }
176
177 EAPI void
178 obj_longpress(Evas_Object *obj)
179 {
180                         Widget_Data *wd = elm_widget_data_get(obj);
181                         Evas_Object *top;
182                         const Eina_List *l;
183                         Evas_Object *list;
184                         const Elm_Entry_Context_Menu_Item *it;
185                         
186                         if (wd->popup) evas_object_del(wd->popup);
187                        else elm_widget_scroll_freeze_push(obj);
188                         top = elm_widget_top_get(obj);
189                         if(top)
190                                 wd->popup = elm_popup_add(top);
191                         elm_object_style_set(wd->popup,"menustyle");
192                         elm_popup_set_mode(wd->popup, ELM_POPUP_TYPE_ALERT);
193                         elm_popup_title_label_set(wd->popup,"CopyPaste");
194                         list = elm_list_add(wd->popup);
195                         elm_object_style_set(list,"popup");
196                         elm_list_horizontal_mode_set(list, ELM_LIST_COMPRESS);
197                         elm_widget_sub_object_add(obj, wd->popup);
198                         if (!wd->selmode)
199                                 {       
200                                         if (!wd->password)
201                                                 elm_list_item_append(list, "Select", NULL, NULL,_select, obj);
202
203                                         if (1) // need way to detect if someone has a selection
204                                                 {
205                                                         if (wd->editable)
206                                                                 elm_list_item_append(list, "Paste", NULL, NULL,_paste, obj);
207
208                                                 }
209                                                 //elm_list_item_append(list, "Selectall", NULL, NULL,_select_all, data);
210                                 }
211                         else
212                                 {
213                                           if (!wd->password)
214                                                 {
215                                                         if (wd->have_selection)
216                                                                 {
217                                                                         elm_list_item_append(list, "Copy", NULL, NULL,_copy, obj);
218                                                                         if (wd->editable)
219                                                                                 elm_list_item_append(list, "Cut", NULL, NULL,_cut, obj);
220                                                                 }
221                                                         else
222                                                                 {
223                                                                         _cancel(obj,wd->popup,NULL);                                                    
224                                                                         if (1) // need way to detect if someone has a selection
225                                                                                 {
226                                                                                         if (wd->editable)
227                                                                                                 elm_list_item_append(list, "Paste", NULL, NULL,_paste, obj);
228                                                                                 }
229                                                                                 elm_list_item_append(list, "Select", NULL, NULL,_select, obj);
230                                                                 }
231                                                 }
232                                 }
233                                 EINA_LIST_FOREACH(wd->items, l, it)
234                                 {
235                                         elm_list_item_append(list, it->label, NULL, NULL,_item_clicked, it);
236                                 }
237                         if (wd->popup)
238                                 {
239                                         elm_list_go(list);
240                                         elm_popup_content_set(wd->popup, list);
241                                         evas_object_show(wd->popup);    
242                                         evas_render( evas_object_evas_get( wd->popup ) );
243                                 }
244                         wd->longpress_timer = NULL;
245         }
246
247 EAPI void
248 obj_mouseup(Evas_Object *obj)
249 {
250         Widget_Data *wd = elm_widget_data_get(obj);
251    if (wd->longpress_timer)
252      {          
253                 ecore_timer_del(wd->longpress_timer);
254                 wd->longpress_timer = NULL;
255                 if (wd->have_selection )
256                         {                               
257                                 _cancel(obj,wd->popup,NULL);
258                         }
259      }     
260 }
261
262