1/* 2 * Copyright (C) 2012 Igalia S.L. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "WebKitContextMenu.h" 22 23#include "APIArray.h" 24#include "WebContextMenuItem.h" 25#include "WebKitContextMenuItemPrivate.h" 26#include "WebKitContextMenuPrivate.h" 27 28using namespace WebKit; 29using namespace WebCore; 30 31/** 32 * SECTION: WebKitContextMenu 33 * @Short_description: Represents the context menu in a #WebKitWebView 34 * @Title: WebKitContextMenu 35 * 36 * #WebKitContextMenu represents a context menu containing 37 * #WebKitContextMenuItem<!-- -->s in a #WebKitWebView. 38 * 39 * When a #WebKitWebView is about to display the context menu, it 40 * emits the #WebKitWebView::context-menu signal, which has the 41 * #WebKitContextMenu as an argument. You can modify it, adding new 42 * submenus that you can create with webkit_context_menu_new(), adding 43 * new #WebKitContextMenuItem<!-- -->s with 44 * webkit_context_menu_prepend(), webkit_context_menu_append() or 45 * webkit_context_menu_insert(), maybe after having removed the 46 * existing ones with webkit_context_menu_remove_all(). 47 * 48 */ 49 50struct _WebKitContextMenuPrivate { 51 GList* items; 52 WebKitContextMenuItem* parentItem; 53}; 54 55WEBKIT_DEFINE_TYPE(WebKitContextMenu, webkit_context_menu, G_TYPE_OBJECT) 56 57static void webkitContextMenuDispose(GObject* object) 58{ 59 webkit_context_menu_remove_all(WEBKIT_CONTEXT_MENU(object)); 60 G_OBJECT_CLASS(webkit_context_menu_parent_class)->dispose(object); 61} 62 63static void webkit_context_menu_class_init(WebKitContextMenuClass* listClass) 64{ 65 GObjectClass* gObjectClass = G_OBJECT_CLASS(listClass); 66 gObjectClass->dispose = webkitContextMenuDispose; 67} 68 69void webkitContextMenuPopulate(WebKitContextMenu* menu, Vector<ContextMenuItem>& contextMenuItems) 70{ 71 for (GList* item = menu->priv->items; item; item = g_list_next(item)) { 72 WebKitContextMenuItem* menuItem = WEBKIT_CONTEXT_MENU_ITEM(item->data); 73 contextMenuItems.append(ContextMenuItem(webkitContextMenuItemRelease(menuItem))); 74 } 75} 76 77WebKitContextMenu* webkitContextMenuCreate(API::Array* items) 78{ 79 WebKitContextMenu* menu = webkit_context_menu_new(); 80 for (size_t i = 0; i < items->size(); ++i) { 81 WebContextMenuItem* item = static_cast<WebContextMenuItem*>(items->at(i)); 82 webkit_context_menu_prepend(menu, webkitContextMenuItemCreate(item)); 83 } 84 menu->priv->items = g_list_reverse(menu->priv->items); 85 86 return menu; 87} 88 89void webkitContextMenuSetParentItem(WebKitContextMenu* menu, WebKitContextMenuItem* item) 90{ 91 menu->priv->parentItem = item; 92} 93 94WebKitContextMenuItem* webkitContextMenuGetParentItem(WebKitContextMenu* menu) 95{ 96 return menu->priv->parentItem; 97} 98 99/** 100 * webkit_context_menu_new: 101 * 102 * Creates a new #WebKitContextMenu object to be used as a submenu of an existing 103 * #WebKitContextMenu. The context menu of a #WebKitWebView is created by the view 104 * and passed as an argument of #WebKitWebView::context-menu signal. 105 * To add items to the menu use webkit_context_menu_prepend(), 106 * webkit_context_menu_append() or webkit_context_menu_insert(). 107 * See also webkit_context_menu_new_with_items() to create a #WebKitContextMenu with 108 * a list of initial items. 109 * 110 * Returns: The newly created #WebKitContextMenu object 111 */ 112WebKitContextMenu* webkit_context_menu_new() 113{ 114 return WEBKIT_CONTEXT_MENU(g_object_new(WEBKIT_TYPE_CONTEXT_MENU, NULL)); 115} 116 117/** 118 * webkit_context_menu_new_with_items: 119 * @items: (element-type WebKitContextMenuItem): a #GList of #WebKitContextMenuItem 120 * 121 * Creates a new #WebKitContextMenu object to be used as a submenu of an existing 122 * #WebKitContextMenu with the given initial items. 123 * See also webkit_context_menu_new() 124 * 125 * Returns: The newly created #WebKitContextMenu object 126 */ 127WebKitContextMenu* webkit_context_menu_new_with_items(GList* items) 128{ 129 WebKitContextMenu* menu = webkit_context_menu_new(); 130 g_list_foreach(items, reinterpret_cast<GFunc>(g_object_ref_sink), 0); 131 menu->priv->items = g_list_copy(items); 132 133 return menu; 134} 135 136/** 137 * webkit_context_menu_prepend: 138 * @menu: a #WebKitContextMenu 139 * @item: the #WebKitContextMenuItem to add 140 * 141 * Adds @item at the beginning of the @menu. 142 */ 143void webkit_context_menu_prepend(WebKitContextMenu* menu, WebKitContextMenuItem* item) 144{ 145 webkit_context_menu_insert(menu, item, 0); 146} 147 148/** 149 * webkit_context_menu_append: 150 * @menu: a #WebKitContextMenu 151 * @item: the #WebKitContextMenuItem to add 152 * 153 * Adds @item at the end of the @menu. 154 */ 155void webkit_context_menu_append(WebKitContextMenu* menu, WebKitContextMenuItem* item) 156{ 157 webkit_context_menu_insert(menu, item, -1); 158} 159 160/** 161 * webkit_context_menu_insert: 162 * @menu: a #WebKitContextMenu 163 * @item: the #WebKitContextMenuItem to add 164 * @position: the position to insert the item 165 * 166 * Inserts @item into the @menu at the given position. 167 * If @position is negative, or is larger than the number of items 168 * in the #WebKitContextMenu, the item is added on to the end of 169 * the @menu. The first position is 0. 170 */ 171void webkit_context_menu_insert(WebKitContextMenu* menu, WebKitContextMenuItem* item, int position) 172{ 173 g_return_if_fail(WEBKIT_IS_CONTEXT_MENU(menu)); 174 g_return_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item)); 175 176 g_object_ref_sink(item); 177 menu->priv->items = g_list_insert(menu->priv->items, item, position); 178} 179 180/** 181 * webkit_context_menu_move_item: 182 * @menu: a #WebKitContextMenu 183 * @item: the #WebKitContextMenuItem to add 184 * @position: the new position to move the item 185 * 186 * Moves @item to the given position in the @menu. 187 * If @position is negative, or is larger than the number of items 188 * in the #WebKitContextMenu, the item is added on to the end of 189 * the @menu. 190 * The first position is 0. 191 */ 192void webkit_context_menu_move_item(WebKitContextMenu* menu, WebKitContextMenuItem* item, int position) 193{ 194 g_return_if_fail(WEBKIT_IS_CONTEXT_MENU(menu)); 195 g_return_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item)); 196 197 if (!g_list_find(menu->priv->items, item)) 198 return; 199 200 menu->priv->items = g_list_remove(menu->priv->items, item); 201 menu->priv->items = g_list_insert(menu->priv->items, item, position); 202} 203 204/** 205 * webkit_context_menu_get_items: 206 * @menu: a #WebKitContextMenu 207 * 208 * Returns the item list of @menu. 209 * 210 * Returns: (element-type WebKitContextMenuItem) (transfer none): a #GList of 211 * #WebKitContextMenuItem<!-- -->s 212 */ 213GList* webkit_context_menu_get_items(WebKitContextMenu* menu) 214{ 215 g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), 0); 216 217 return menu->priv->items; 218} 219 220/** 221 * webkit_context_menu_get_n_items: 222 * @menu: a #WebKitContextMenu 223 * 224 * Gets the length of the @menu. 225 * 226 * Returns: the number of #WebKitContextMenuItem<!-- -->s in @menu 227 */ 228guint webkit_context_menu_get_n_items(WebKitContextMenu* menu) 229{ 230 g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), 0); 231 232 return g_list_length(menu->priv->items); 233} 234 235/** 236 * webkit_context_menu_first: 237 * @menu: a #WebKitContextMenu 238 * 239 * Gets the first item in the @menu. 240 * 241 * Returns: (transfer none): the first #WebKitContextMenuItem of @menu, 242 * or %NULL if the #WebKitContextMenu is empty. 243 */ 244WebKitContextMenuItem* webkit_context_menu_first(WebKitContextMenu* menu) 245{ 246 g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), 0); 247 248 return menu->priv->items ? WEBKIT_CONTEXT_MENU_ITEM(menu->priv->items->data) : 0; 249} 250 251/** 252 * webkit_context_menu_last: 253 * @menu: a #WebKitContextMenu 254 * 255 * Gets the last item in the @menu. 256 * 257 * Returns: (transfer none): the last #WebKitContextMenuItem of @menu, 258 * or %NULL if the #WebKitContextMenu is empty. 259 */ 260WebKitContextMenuItem* webkit_context_menu_last(WebKitContextMenu* menu) 261{ 262 g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), 0); 263 264 GList* last = g_list_last(menu->priv->items); 265 return last ? WEBKIT_CONTEXT_MENU_ITEM(last->data) : 0; 266} 267 268/** 269 * webkit_context_menu_get_item_at_position: 270 * @menu: a #WebKitContextMenu 271 * @position: the position of the item, counting from 0 272 * 273 * Gets the item at the given position in the @menu. 274 * 275 * Returns: (transfer none): the #WebKitContextMenuItem at position @position in @menu, 276 * or %NULL if the position is off the end of the @menu. 277 */ 278WebKitContextMenuItem* webkit_context_menu_get_item_at_position(WebKitContextMenu* menu, unsigned position) 279{ 280 g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), 0); 281 282 gpointer item = g_list_nth_data(menu->priv->items, position); 283 return item ? WEBKIT_CONTEXT_MENU_ITEM(item) : 0; 284} 285 286/** 287 * webkit_context_menu_remove: 288 * @menu: a #WebKitContextMenu 289 * @item: the #WebKitContextMenuItem to remove 290 * 291 * Removes @item from the @menu. 292 * See also webkit_context_menu_remove_all() to remove all items. 293 */ 294void webkit_context_menu_remove(WebKitContextMenu* menu, WebKitContextMenuItem* item) 295{ 296 g_return_if_fail(WEBKIT_IS_CONTEXT_MENU(menu)); 297 g_return_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item)); 298 299 if (!g_list_find(menu->priv->items, item)) 300 return; 301 302 menu->priv->items = g_list_remove(menu->priv->items, item); 303 g_object_unref(item); 304} 305 306/** 307 * webkit_context_menu_remove_all: 308 * @menu: a #WebKitContextMenu 309 * 310 * Removes all items of the @menu. 311 */ 312void webkit_context_menu_remove_all(WebKitContextMenu* menu) 313{ 314 g_return_if_fail(WEBKIT_IS_CONTEXT_MENU(menu)); 315 316 g_list_free_full(menu->priv->items, reinterpret_cast<GDestroyNotify>(g_object_unref)); 317 menu->priv->items = 0; 318} 319