tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebKit / efl / ewk / ewk_contextmenu.cpp
1 /*
2     Copyright (C) 2010 ProFUSION embedded systems
3     Copyright (C) 2010 Samsung Electronics
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22 #include "ewk_contextmenu.h"
23
24 #include "ContextMenu.h"
25 #include "ContextMenuController.h"
26 #include "ContextMenuItem.h"
27 #include "EWebKit.h"
28 #include "ewk_private.h"
29
30 #include <Eina.h>
31 #include <eina_safety_checks.h>
32 #include <wtf/text/CString.h>
33
34 #if ENABLE(TIZEN_SAVE_IMAGE)
35 #include "ContextMenuClient.h"
36 #include "HTMLImageElement.h"
37 #include "InstallContentEfl.h"
38 #endif
39
40 /**
41  * \struct  _Ewk_Context_Menu
42  * @brief   Contains the context menu data.
43  */
44 struct _Ewk_Context_Menu {
45     unsigned int __ref; /**< the reference count of the object */
46 #if ENABLE(CONTEXT_MENUS)
47     WebCore::ContextMenuController* controller; /**< the WebCore's object which is responsible for the context menu */
48 #endif
49     Evas_Object* view; /**< the view object */
50
51     Eina_List* items; /**< the list of items */
52 };
53
54 /**
55  * \struct  _Ewk_Context_Menu_Item
56  * @brief   Represents one item of the context menu object.
57  */
58 struct _Ewk_Context_Menu_Item {
59     Ewk_Context_Menu_Item_Type type; /**< contains the type of the item */
60     Ewk_Context_Menu_Action action; /**< contains the action of the item */
61
62     const char* title; /**< contains the title of the item */
63     Ewk_Context_Menu* submenu; /**< contains the pointer to the submenu of the item */
64 #if ENABLE(TIZEN_CONTEXT_MENU) /* Restore ContextMenuClientEfl */
65     /// contains the pointer to the parent menu of the item
66     Ewk_Context_Menu* parentmenu;
67 #endif
68
69     bool checked : 1;
70     bool enabled : 1;
71 };
72
73 void ewk_context_menu_ref(Ewk_Context_Menu* menu)
74 {
75     EINA_SAFETY_ON_NULL_RETURN(menu);
76     menu->__ref++;
77 }
78
79 void ewk_context_menu_unref(Ewk_Context_Menu* menu)
80 {
81     EINA_SAFETY_ON_NULL_RETURN(menu);
82     void* item;
83
84     if (--menu->__ref)
85         return;
86
87     EINA_LIST_FREE(menu->items, item)
88         ewk_context_menu_item_free(static_cast<Ewk_Context_Menu_Item*>(item));
89
90     free(menu);
91 }
92
93 Eina_Bool ewk_context_menu_destroy(Ewk_Context_Menu* menu)
94 {
95 #if ENABLE(CONTEXT_MENUS)
96     EINA_SAFETY_ON_NULL_RETURN_VAL(menu, false);
97     EINA_SAFETY_ON_NULL_RETURN_VAL(menu->controller, false);
98     menu->controller->clearContextMenu();
99     return true;
100 #else
101     return false;
102 #endif
103 }
104
105 const Eina_List* ewk_context_menu_item_list_get(const Ewk_Context_Menu* menu)
106 {
107     EINA_SAFETY_ON_NULL_RETURN_VAL(menu, 0);
108
109     return menu->items;
110 }
111
112 Ewk_Context_Menu_Item* ewk_context_menu_item_new(Ewk_Context_Menu_Item_Type type,
113                                                  Ewk_Context_Menu_Action action, Ewk_Context_Menu* submenu,
114 #if ENABLE(TIZEN_CONTEXT_MENU)
115                                                  Ewk_Context_Menu* parentmenu,
116 #endif
117                                                  const char* title, Eina_Bool checked, Eina_Bool enabled)
118 {
119     Ewk_Context_Menu_Item* item = static_cast<Ewk_Context_Menu_Item*>(malloc(sizeof(*item)));
120     if (!item)
121         return 0;
122
123     item->type = type;
124     item->action = action;
125     item->title = eina_stringshare_add(title);
126     item->submenu = submenu;
127 #if ENABLE(TIZEN_CONTEXT_MENU)
128     item->parentmenu=parentmenu;
129 #endif
130     item->checked = checked;
131     item->enabled = enabled;
132
133     return item;
134 }
135
136 Eina_Bool ewk_context_menu_item_select(Ewk_Context_Menu* menu, Ewk_Context_Menu_Item* item)
137 {
138 #if ENABLE(CONTEXT_MENUS)
139     EINA_SAFETY_ON_NULL_RETURN_VAL(menu, false);
140     EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
141     WebCore::ContextMenuAction action = static_cast<WebCore::ContextMenuAction>(item->action);
142     WebCore::ContextMenuItemType type = static_cast<WebCore::ContextMenuItemType>(item->type);
143
144     // Don't care about title and submenu as they're not used after this point.
145     WebCore::ContextMenuItem core(type, action, WTF::String());
146     menu->controller->contextMenuItemSelected(&core);
147     return true;
148 #else
149     return false;
150 #endif
151 }
152
153 void ewk_context_menu_item_free(Ewk_Context_Menu_Item* item)
154 {
155     EINA_SAFETY_ON_NULL_RETURN(item);
156
157     eina_stringshare_del(item->title);
158     free(item);
159 }
160
161 Ewk_Context_Menu_Item_Type ewk_context_menu_item_type_get(const Ewk_Context_Menu_Item* item)
162 {
163     EINA_SAFETY_ON_NULL_RETURN_VAL(item, EWK_ACTION_TYPE);
164     return item->type;
165 }
166
167 Eina_Bool ewk_context_menu_item_type_set(Ewk_Context_Menu_Item* item, Ewk_Context_Menu_Item_Type type)
168 {
169     EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
170     item->type = type;
171     return true;
172 }
173
174 Ewk_Context_Menu_Action ewk_context_menu_item_action_get(const Ewk_Context_Menu_Item* item)
175 {
176     EINA_SAFETY_ON_NULL_RETURN_VAL(item, EWK_CONTEXT_MENU_ITEM_TAG_NO_ACTION);
177     return item->action;
178 }
179
180 Eina_Bool ewk_context_menu_item_action_set(Ewk_Context_Menu_Item* item, Ewk_Context_Menu_Action action)
181 {
182     EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
183     item->action = action;
184     return true;
185 }
186
187 const char* ewk_context_menu_item_title_get(const Ewk_Context_Menu_Item* item)
188 {
189     EINA_SAFETY_ON_NULL_RETURN_VAL(item, 0);
190     return item->title;
191 }
192
193 const char* ewk_context_menu_item_title_set(Ewk_Context_Menu_Item* item, const char* title)
194 {
195     EINA_SAFETY_ON_NULL_RETURN_VAL(item, 0);
196     eina_stringshare_replace(&item->title, title);
197     return item->title;
198 }
199
200 Eina_Bool ewk_context_menu_item_checked_get(const Ewk_Context_Menu_Item* item)
201 {
202     EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
203     return item->checked;
204 }
205
206 Eina_Bool ewk_context_menu_item_checked_set(Ewk_Context_Menu_Item* item, Eina_Bool checked)
207 {
208     EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
209     item->checked = checked;
210     return true;
211 }
212
213 Eina_Bool ewk_context_menu_item_enabled_get(const Ewk_Context_Menu_Item* item)
214 {
215     EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
216     return item->enabled;
217 }
218
219 Eina_Bool ewk_context_menu_item_enabled_set(Ewk_Context_Menu_Item* item, Eina_Bool enabled)
220 {
221     EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
222     item->enabled = enabled;
223     return true;
224 }
225
226 /**
227  * Gets the parent menu of the item object.
228  *
229  * @param o the item of the context menu to get the parent menu
230  * @return the parent context menu of the item or @c 0 if error occured
231  */
232 Ewk_Context_Menu* ewk_context_menu_item_parent_get(Ewk_Context_Menu_Item* o)
233 {
234 #if ENABLE(TIZEN_CONTEXT_MENU)
235     EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE);
236
237     return o->parentmenu;
238 #else
239     return 0;
240 #endif
241 }
242
243 /**
244  * Saves cached image to file manager.
245  * This API can only save cached image which is selected by context menu.
246  * In order to use this API, application should register callback for "contextmenu,save,as"
247  * signal. Please refer to ewk_context_menu_image_save_as_set() in ewk_contextmenu.cpp.
248  *
249  * @param file_name image name.
250  * @return @c integer result if the image file is saved successfully.
251  */
252 int ewk_context_menu_cached_image_save(const char* file_name)
253 {
254 #if ENABLE(TIZEN_SAVE_IMAGE)
255     int ret = 0;
256     WebCore::InstallContent *installContent = WebCore::InstallContent::getInstance();
257     ret = installContent->saveImage(file_name);
258     installContent->setHTMLImageElement(0);
259     return ret;
260 #else
261    LOG_ERROR("TIZEN_SAVE_IMAGE is disabled. \n");
262 #endif
263 }
264
265
266 /* internal methods ****************************************************/
267
268 #if ENABLE(CONTEXT_MENUS)
269 /**
270  * @internal
271  *
272  * Creates an empty context menu on view.
273  *
274  * @param view the view object
275  * @param controller the WebCore's context menu controller
276  * @return newly allocated the context menu on success or @c 0 on errors
277  *
278  * @note emits a signal "contextmenu,new"
279  */
280 Ewk_Context_Menu* ewk_context_menu_new(Evas_Object* view, WebCore::ContextMenuController* controller)
281 {
282     Ewk_Context_Menu* menu;
283     EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
284     EINA_SAFETY_ON_NULL_RETURN_VAL(controller, 0);
285
286     menu = static_cast<Ewk_Context_Menu*>(malloc(sizeof(*menu)));
287     if (!menu) {
288         CRITICAL("Could not allocate context menu memory.");
289         return 0;
290     }
291
292     menu->__ref = 1;
293     menu->view = view;
294     menu->controller = controller;
295     menu->items = 0;
296     evas_object_smart_callback_call(menu->view, "contextmenu,new", menu);
297
298     return menu;
299 }
300
301 /**
302  * @internal
303  *
304  * Frees the context menu.
305  *
306  * @param menu the view object
307  * @return @c true on success, or @c false on failure
308  *
309  * @note emits a signal "contextmenu,free"
310  *
311  * @see ewk_context_menu_unref
312  * @see ewk_context_menu_destroy
313  */
314 bool ewk_context_menu_free(Ewk_Context_Menu* menu)
315 {
316     EINA_SAFETY_ON_NULL_RETURN_VAL(menu, false);
317     evas_object_smart_callback_call(menu->view, "contextmenu,free", menu);
318     ewk_context_menu_unref(menu);
319     return true;
320 }
321
322 /**
323  * @internal
324  *
325  * Appends the WebCore's item to the context menu object.
326  *
327  * @param menu the context menu object
328  * @param core the WebCore's context menu item that will be added to the context menu
329  * @note emits a signal "contextmenu,item,appended"
330  *
331  * @see ewk_context_menu_item_new
332  */
333 void ewk_context_menu_item_append(Ewk_Context_Menu* menu, WebCore::ContextMenuItem& core)
334 {
335     Ewk_Context_Menu_Item_Type type = static_cast<Ewk_Context_Menu_Item_Type>(core.type());
336     Ewk_Context_Menu_Action action = static_cast<Ewk_Context_Menu_Action>(core.action());
337 #if ENABLE(TIZEN_CONTEXT_MENU)
338     Ewk_Context_Menu* submenu = static_cast<Ewk_Context_Menu*>(core.platformSubMenu());
339
340     Ewk_Context_Menu_Item* menu_item = ewk_context_menu_item_new
341                                            (type, action, submenu, menu, core.title().utf8().data(), core.checked(),
342                                            core.enabled());
343 #else
344     Ewk_Context_Menu_Item *menu_item = ewk_context_menu_item_new
345                                            (type, action, 0, core.title().utf8().data(), core.checked(),
346                                            core.enabled());
347 #endif
348     EINA_SAFETY_ON_NULL_RETURN(menu_item);
349
350     menu->items = eina_list_append(menu->items, menu_item);
351     evas_object_smart_callback_call(menu->view, "contextmenu,item,appended", menu);
352 }
353
354 /**
355  * @internal
356  *
357  * Emits a signal with the items of the context menu.
358  *
359  * @param menu the context menu object
360  * @return the same context menu object that was given through parameter
361  *
362  * @note emits a signal "contextmenu,customize"
363  *
364  * @see ewk_context_menu_item_list_get
365  */
366 Ewk_Context_Menu* ewk_context_menu_customize(Ewk_Context_Menu* menu)
367 {
368     EINA_SAFETY_ON_NULL_RETURN_VAL(menu, 0);
369
370     evas_object_smart_callback_call(menu->view, "contextmenu,customize", menu->items);
371     return menu;
372 }
373
374 /**
375  * @internal
376  *
377  * Emits a signal "contextmenu,show"
378  *
379  * @param menu the context menu object
380  */
381 void ewk_context_menu_show(Ewk_Context_Menu* menu)
382 {
383     EINA_SAFETY_ON_NULL_RETURN(menu);
384
385     evas_object_smart_callback_call(menu->view, "contextmenu,show", menu);
386 }
387
388 #if ENABLE(TIZEN_SAVE_IMAGE)
389 /**
390  * @internal
391  * Requests to save image to user with new name.
392  *
393  * @param o View.
394  * @param fileName
395  *
396  * Emits signal: "load,started" on main frame with no parameters.
397  */
398 void ewk_context_menu_image_save_as_set(Ewk_Context_Menu* o, const char* image_name)
399 {
400     EINA_SAFETY_ON_NULL_RETURN(o);
401     evas_object_smart_callback_call(o->view, "contextmenu,save,as", (void*)image_name);
402 }
403
404 /**
405  * @internal
406  * Send image path which is saved to temp directory.
407  *
408  * @param o View.
409  * @param file_path saved file full path
410  * @param Ewk_SendVia data
411  *
412  * Emits signal: "contextmenu,sendvia,email" on main frame with file path
413  */
414 void ewk_context_menu_image_send_via_email_set(Ewk_Context_Menu* o, const char* file_path)
415 {
416     EINA_SAFETY_ON_NULL_RETURN(o);
417     evas_object_smart_callback_call(o->view, "contextmenu,sendvia,email", (void*)file_path);
418 }
419
420 /**
421  * @internal
422  * Send image data which is saved to temp directory.
423  *
424  * @param o View.
425  * @param file_path saved file full path
426  * @param Ewk_SendVia data
427  *
428  * Emits signal: "context,sendvia,message" on main frame with file path.
429  */
430 void ewk_context_menu_image_send_via_message_set(Ewk_Context_Menu* o, const char* file_path)
431 {
432     EINA_SAFETY_ON_NULL_RETURN(o);
433     evas_object_smart_callback_call(o->view, "contextmenu,sendvia,message", (void*)file_path);
434 }
435 #endif
436
437 #endif