2
* Copyright (C) 2007 Holger Hans Peter Freyther
3
* Copyright (C) 2010 Igalia S.L
4
* Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
#if ENABLE(CONTEXT_MENUS)
25
#include "ContextMenuItem.h"
27
#include "ContextMenu.h"
28
#include <wtf/gobject/GOwnPtr.h>
29
#include <wtf/gobject/GRefPtr.h>
31
#include <wtf/text/CString.h>
33
#define WEBKIT_CONTEXT_MENU_ACTION "webkit-context-menu"
37
static const char* gtkStockIDFromContextMenuAction(const ContextMenuAction& action)
40
case ContextMenuItemTagCopyLinkToClipboard:
41
case ContextMenuItemTagCopyImageToClipboard:
42
case ContextMenuItemTagCopyMediaLinkToClipboard:
43
case ContextMenuItemTagCopy:
44
return GTK_STOCK_COPY;
45
case ContextMenuItemTagOpenLinkInNewWindow:
46
case ContextMenuItemTagOpenImageInNewWindow:
47
case ContextMenuItemTagOpenFrameInNewWindow:
48
case ContextMenuItemTagOpenMediaInNewWindow:
49
return GTK_STOCK_OPEN;
50
case ContextMenuItemTagDownloadLinkToDisk:
51
case ContextMenuItemTagDownloadImageToDisk:
52
return GTK_STOCK_SAVE;
53
case ContextMenuItemTagGoBack:
54
return GTK_STOCK_GO_BACK;
55
case ContextMenuItemTagGoForward:
56
return GTK_STOCK_GO_FORWARD;
57
case ContextMenuItemTagStop:
58
return GTK_STOCK_STOP;
59
case ContextMenuItemTagReload:
60
return GTK_STOCK_REFRESH;
61
case ContextMenuItemTagCut:
63
case ContextMenuItemTagPaste:
64
return GTK_STOCK_PASTE;
65
case ContextMenuItemTagDelete:
66
return GTK_STOCK_DELETE;
67
case ContextMenuItemTagSelectAll:
68
return GTK_STOCK_SELECT_ALL;
69
case ContextMenuItemTagSpellingGuess:
71
case ContextMenuItemTagIgnoreSpelling:
73
case ContextMenuItemTagLearnSpelling:
75
case ContextMenuItemTagOther:
76
return GTK_STOCK_MISSING_IMAGE;
77
case ContextMenuItemTagSearchInSpotlight:
78
return GTK_STOCK_FIND;
79
case ContextMenuItemTagSearchWeb:
80
return GTK_STOCK_FIND;
81
case ContextMenuItemTagOpenWithDefaultApplication:
82
return GTK_STOCK_OPEN;
83
case ContextMenuItemPDFZoomIn:
84
return GTK_STOCK_ZOOM_IN;
85
case ContextMenuItemPDFZoomOut:
86
return GTK_STOCK_ZOOM_OUT;
87
case ContextMenuItemPDFAutoSize:
88
return GTK_STOCK_ZOOM_FIT;
89
case ContextMenuItemPDFNextPage:
90
return GTK_STOCK_GO_FORWARD;
91
case ContextMenuItemPDFPreviousPage:
92
return GTK_STOCK_GO_BACK;
93
// New tags, not part of API
94
case ContextMenuItemTagOpenLink:
95
return GTK_STOCK_OPEN;
96
case ContextMenuItemTagCheckSpelling:
97
return GTK_STOCK_SPELL_CHECK;
98
case ContextMenuItemTagFontMenu:
99
return GTK_STOCK_SELECT_FONT;
100
case ContextMenuItemTagShowFonts:
101
return GTK_STOCK_SELECT_FONT;
102
case ContextMenuItemTagBold:
103
return GTK_STOCK_BOLD;
104
case ContextMenuItemTagItalic:
105
return GTK_STOCK_ITALIC;
106
case ContextMenuItemTagUnderline:
107
return GTK_STOCK_UNDERLINE;
108
case ContextMenuItemTagShowColors:
109
return GTK_STOCK_SELECT_COLOR;
110
case ContextMenuItemTagToggleMediaControls:
111
case ContextMenuItemTagToggleMediaLoop:
112
case ContextMenuItemTagCopyImageUrlToClipboard:
115
case ContextMenuItemTagEnterVideoFullscreen:
116
return GTK_STOCK_FULLSCREEN;
122
static PlatformMenuItemDescription createPlatformMenuItemDescription(ContextMenuItemType type, ContextMenuAction action, const String& title, bool enabled, bool checked)
124
if (type == SeparatorType)
125
return GTK_MENU_ITEM(gtk_separator_menu_item_new());
127
GOwnPtr<char> actionName(g_strdup_printf("context-menu-action-%d", action));
128
GRefPtr<GtkAction> platformAction;
130
if (type == CheckableActionType) {
131
platformAction = adoptGRef(GTK_ACTION(gtk_toggle_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action))));
132
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(platformAction.get()), checked);
134
platformAction = adoptGRef(gtk_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action)));
135
gtk_action_set_sensitive(platformAction.get(), enabled);
137
GtkMenuItem* item = GTK_MENU_ITEM(gtk_action_create_menu_item(platformAction.get()));
138
g_object_set_data(G_OBJECT(item), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action));
143
// Extract the ActionType from the menu item
144
ContextMenuItem::ContextMenuItem(PlatformMenuItemDescription item)
145
: m_platformDescription(item)
147
// Don't show accel labels in context menu items.
148
GtkAction* action = gtkAction();
152
if (!gtk_action_get_accel_path(action))
155
GtkWidget* child = gtk_bin_get_child(GTK_BIN(item));
156
if (GTK_IS_ACCEL_LABEL(child))
157
gtk_accel_label_set_accel_closure(GTK_ACCEL_LABEL(child), 0);
160
ContextMenuItem::ContextMenuItem(ContextMenu* subMenu)
162
m_platformDescription = GTK_MENU_ITEM(gtk_menu_item_new());
167
ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu)
169
m_platformDescription = createPlatformMenuItemDescription(type, action, title, true, false);
174
ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, bool enabled, bool checked)
176
m_platformDescription = createPlatformMenuItemDescription(type, action, title, enabled, checked);
179
ContextMenuItem::ContextMenuItem(ContextMenuAction action, const String& title, bool enabled, bool checked, Vector<ContextMenuItem>& subMenuItems)
181
m_platformDescription = createPlatformMenuItemDescription(SubmenuType, action, title, enabled, checked);
182
setSubMenu(subMenuItems);
185
ContextMenuItem::~ContextMenuItem()
189
PlatformMenuItemDescription ContextMenuItem::releasePlatformDescription()
191
PlatformMenuItemDescription platformDescription = m_platformDescription;
192
m_platformDescription = 0;
193
return platformDescription;
196
ContextMenuItemType ContextMenuItem::type() const
198
if (GTK_IS_SEPARATOR_MENU_ITEM(m_platformDescription))
199
return SeparatorType;
200
if (GTK_IS_CHECK_MENU_ITEM(m_platformDescription))
201
return CheckableActionType;
202
if (gtk_menu_item_get_submenu(m_platformDescription))
207
void ContextMenuItem::setType(ContextMenuItemType type)
209
if (type == SeparatorType)
210
m_platformDescription = GTK_MENU_ITEM(gtk_separator_menu_item_new());
213
ContextMenuAction ContextMenuItem::action() const
215
return static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION)));
218
void ContextMenuItem::setAction(ContextMenuAction action)
220
g_object_set_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action));
223
String ContextMenuItem::title() const
225
GtkAction* action = gtkAction();
226
return action ? String::fromUTF8(gtk_action_get_label(action)) : String();
229
void ContextMenuItem::setTitle(const String& title)
231
GtkAction* action = gtkAction();
233
gtk_action_set_label(action, title.utf8().data());
236
PlatformMenuDescription ContextMenuItem::platformSubMenu() const
238
GtkWidget* subMenu = gtk_menu_item_get_submenu(m_platformDescription);
239
return subMenu ? GTK_MENU(subMenu) : 0;
242
void ContextMenuItem::setSubMenu(ContextMenu* menu)
244
gtk_menu_item_set_submenu(m_platformDescription, GTK_WIDGET(menu->releasePlatformDescription()));
247
void ContextMenuItem::setSubMenu(Vector<ContextMenuItem>& subMenuItems)
249
ContextMenu menu(platformMenuDescription(subMenuItems));
253
void ContextMenuItem::setChecked(bool shouldCheck)
255
GtkAction* action = gtkAction();
256
if (action && GTK_IS_TOGGLE_ACTION(action))
257
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), shouldCheck);
260
bool ContextMenuItem::checked() const
262
GtkAction* action = gtkAction();
263
if (action && GTK_IS_TOGGLE_ACTION(action))
264
return gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
268
bool ContextMenuItem::enabled() const
270
GtkAction* action = gtkAction();
271
return action ? gtk_action_get_sensitive(action) : false;
274
void ContextMenuItem::setEnabled(bool shouldEnable)
276
GtkAction* action = gtkAction();
278
gtk_action_set_sensitive(action, shouldEnable);
281
GtkAction* ContextMenuItem::gtkAction() const
283
return gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription));
288
#endif // ENABLE(CONTEXT_MENUS)