blob: e792c6d03957c74b145b8c507295f2de3f15e8ee [file] [log] [blame]
/*
Copyright (C) 2010 ProFUSION embedded systems
Copyright (C) 2010 Samsung Electronics
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "ewk_contextmenu.h"
#include "ContextMenu.h"
#include "ContextMenuController.h"
#include "ContextMenuItem.h"
#include "ewk_contextmenu_private.h"
#include <Eina.h>
#include <eina_safety_checks.h>
#include <wtf/text/CString.h>
/**
* \struct _Ewk_Context_Menu
* @brief Contains the context menu data.
*/
struct _Ewk_Context_Menu {
unsigned int __ref; /**< the reference count of the object */
#if ENABLE(CONTEXT_MENUS)
WebCore::ContextMenuController* controller; /**< the WebCore's object which is responsible for the context menu */
#endif
Evas_Object* view; /**< the view object */
Eina_List* items; /**< the list of items */
};
/**
* \struct _Ewk_Context_Menu_Item
* @brief Represents one item of the context menu object.
*/
struct _Ewk_Context_Menu_Item {
Ewk_Context_Menu_Item_Type type; /**< contains the type of the item */
Ewk_Context_Menu_Action action; /**< contains the action of the item */
const char* title; /**< contains the title of the item */
Ewk_Context_Menu* submenu; /**< contains the pointer to the submenu of the item */
bool checked : 1;
bool enabled : 1;
};
void ewk_context_menu_ref(Ewk_Context_Menu* menu)
{
EINA_SAFETY_ON_NULL_RETURN(menu);
menu->__ref++;
}
void ewk_context_menu_unref(Ewk_Context_Menu* menu)
{
EINA_SAFETY_ON_NULL_RETURN(menu);
void* item;
if (--menu->__ref)
return;
EINA_LIST_FREE(menu->items, item)
ewk_context_menu_item_free(static_cast<Ewk_Context_Menu_Item*>(item));
delete menu;
}
Eina_Bool ewk_context_menu_destroy(Ewk_Context_Menu* menu)
{
#if ENABLE(CONTEXT_MENUS)
EINA_SAFETY_ON_NULL_RETURN_VAL(menu, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(menu->controller, false);
menu->controller->clearContextMenu();
ewk_context_menu_free(menu);
return true;
#else
return false;
#endif
}
const Eina_List* ewk_context_menu_item_list_get(const Ewk_Context_Menu* menu)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(menu, 0);
return menu->items;
}
Ewk_Context_Menu_Item* ewk_context_menu_item_new(Ewk_Context_Menu_Item_Type type,
Ewk_Context_Menu_Action action, Ewk_Context_Menu* submenu,
const char* title, Eina_Bool checked, Eina_Bool enabled)
{
Ewk_Context_Menu_Item* item = new Ewk_Context_Menu_Item;
item->type = type;
item->action = action;
item->title = eina_stringshare_add(title);
item->submenu = submenu;
item->checked = checked;
item->enabled = enabled;
return item;
}
Eina_Bool ewk_context_menu_item_select(Ewk_Context_Menu* menu, Ewk_Context_Menu_Item* item)
{
#if ENABLE(CONTEXT_MENUS)
EINA_SAFETY_ON_NULL_RETURN_VAL(menu, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
WebCore::ContextMenuAction action = static_cast<WebCore::ContextMenuAction>(item->action);
WebCore::ContextMenuItemType type = static_cast<WebCore::ContextMenuItemType>(item->type);
// Don't care about title and submenu as they're not used after this point.
WebCore::ContextMenuItem core(type, action, WTF::String());
menu->controller->contextMenuItemSelected(&core);
return true;
#else
return false;
#endif
}
void ewk_context_menu_item_free(Ewk_Context_Menu_Item* item)
{
EINA_SAFETY_ON_NULL_RETURN(item);
eina_stringshare_del(item->title);
delete item;
}
Ewk_Context_Menu_Item_Type ewk_context_menu_item_type_get(const Ewk_Context_Menu_Item* item)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, EWK_ACTION_TYPE);
return item->type;
}
Eina_Bool ewk_context_menu_item_type_set(Ewk_Context_Menu_Item* item, Ewk_Context_Menu_Item_Type type)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
item->type = type;
return true;
}
Ewk_Context_Menu_Action ewk_context_menu_item_action_get(const Ewk_Context_Menu_Item* item)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, EWK_CONTEXT_MENU_ITEM_TAG_NO_ACTION);
return item->action;
}
Eina_Bool ewk_context_menu_item_action_set(Ewk_Context_Menu_Item* item, Ewk_Context_Menu_Action action)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
item->action = action;
return true;
}
const char* ewk_context_menu_item_title_get(const Ewk_Context_Menu_Item* item)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, 0);
return item->title;
}
const char* ewk_context_menu_item_title_set(Ewk_Context_Menu_Item* item, const char* title)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, 0);
eina_stringshare_replace(&item->title, title);
return item->title;
}
Eina_Bool ewk_context_menu_item_checked_get(const Ewk_Context_Menu_Item* item)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
return item->checked;
}
Eina_Bool ewk_context_menu_item_checked_set(Ewk_Context_Menu_Item* item, Eina_Bool checked)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
item->checked = checked;
return true;
}
Eina_Bool ewk_context_menu_item_enabled_get(const Ewk_Context_Menu_Item* item)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
return item->enabled;
}
Eina_Bool ewk_context_menu_item_enabled_set(Ewk_Context_Menu_Item* item, Eina_Bool enabled)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(item, false);
item->enabled = enabled;
return true;
}
/* internal methods ****************************************************/
#if ENABLE(CONTEXT_MENUS)
/**
* @internal
*
* Creates an empty context menu on view.
*
* @param view the view object
* @param controller the WebCore's context menu controller
* @return newly allocated the context menu on success or @c 0 on errors
*
* @note emits a signal "contextmenu,new"
*/
Ewk_Context_Menu* ewk_context_menu_new(Evas_Object* view, WebCore::ContextMenuController* controller, WebCore::ContextMenu* coreMenu)
{
Ewk_Context_Menu* menu;
EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(controller, 0);
menu = new Ewk_Context_Menu;
menu->__ref = 1;
menu->view = view;
menu->controller = controller;
menu->items = 0;
evas_object_smart_callback_call(menu->view, "contextmenu,new", menu);
const Vector<WebCore::ContextMenuItem>* itemsList = coreMenu->platformDescription();
for (Vector<WebCore::ContextMenuItem>::const_iterator iter = itemsList->begin(); iter != itemsList->end(); ++iter)
ewk_context_menu_item_append(menu, *iter);
return menu;
}
/**
* @internal
*
* Frees the context menu.
*
* @param menu the view object
* @return @c true on success, or @c false on failure
*
* @note emits a signal "contextmenu,free"
*
* @see ewk_context_menu_unref
* @see ewk_context_menu_destroy
*/
bool ewk_context_menu_free(Ewk_Context_Menu* menu)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(menu, false);
evas_object_smart_callback_call(menu->view, "contextmenu,free", menu);
ewk_context_menu_unref(menu);
return true;
}
/**
* @internal
*
* Appends the WebCore's item to the context menu object.
*
* @param menu the context menu object
* @param core the WebCore's context menu item that will be added to the context menu
* @note emits a signal "contextmenu,item,appended"
*
* @see ewk_context_menu_item_new
*/
void ewk_context_menu_item_append(Ewk_Context_Menu* menu, const WebCore::ContextMenuItem& core)
{
Ewk_Context_Menu_Item_Type type = static_cast<Ewk_Context_Menu_Item_Type>(core.type());
Ewk_Context_Menu_Action action = static_cast<Ewk_Context_Menu_Action>(core.action());
Ewk_Context_Menu_Item* menu_item = ewk_context_menu_item_new
(type, action, 0, core.title().utf8().data(), core.checked(),
core.enabled());
EINA_SAFETY_ON_NULL_RETURN(menu_item);
menu->items = eina_list_append(menu->items, menu_item);
evas_object_smart_callback_call(menu->view, "contextmenu,item,appended", menu);
}
/**
* @internal
*
* Emits a signal "contextmenu,show"
*
* @param menu the context menu object
*/
void ewk_context_menu_show(Ewk_Context_Menu* menu)
{
EINA_SAFETY_ON_NULL_RETURN(menu);
evas_object_smart_callback_call(menu->view, "contextmenu,show", menu);
}
#endif