bdd396270b45e4112b8751eadbc264d30292da25
[WebKit-https.git] / Source / WebCore / platform / gtk / ContextMenuItemGtk.cpp
1 /*
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.
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #include "ContextMenuItem.h"
24
25 #include "ContextMenu.h"
26 #include "GOwnPtr.h"
27 #include "NotImplemented.h"
28 #include <gtk/gtk.h>
29 #include <wtf/text/CString.h>
30
31 #define WEBKIT_CONTEXT_MENU_ACTION "webkit-context-menu"
32
33 namespace WebCore {
34
35 static const char* gtkStockIDFromContextMenuAction(const ContextMenuAction& action)
36 {
37     switch (action) {
38     case ContextMenuItemTagCopyLinkToClipboard:
39     case ContextMenuItemTagCopyImageToClipboard:
40     case ContextMenuItemTagCopyMediaLinkToClipboard:
41     case ContextMenuItemTagCopy:
42         return GTK_STOCK_COPY;
43     case ContextMenuItemTagOpenLinkInNewWindow:
44     case ContextMenuItemTagOpenImageInNewWindow:
45     case ContextMenuItemTagOpenFrameInNewWindow:
46     case ContextMenuItemTagOpenMediaInNewWindow:
47         return GTK_STOCK_OPEN;
48     case ContextMenuItemTagDownloadLinkToDisk:
49     case ContextMenuItemTagDownloadImageToDisk:
50         return GTK_STOCK_SAVE;
51     case ContextMenuItemTagGoBack:
52         return GTK_STOCK_GO_BACK;
53     case ContextMenuItemTagGoForward:
54         return GTK_STOCK_GO_FORWARD;
55     case ContextMenuItemTagStop:
56         return GTK_STOCK_STOP;
57     case ContextMenuItemTagReload:
58         return GTK_STOCK_REFRESH;
59     case ContextMenuItemTagCut:
60         return GTK_STOCK_CUT;
61     case ContextMenuItemTagPaste:
62         return GTK_STOCK_PASTE;
63     case ContextMenuItemTagDelete:
64         return GTK_STOCK_DELETE;
65     case ContextMenuItemTagSelectAll:
66         return GTK_STOCK_SELECT_ALL;
67     case ContextMenuItemTagSpellingGuess:
68         return 0;
69     case ContextMenuItemTagIgnoreSpelling:
70         return GTK_STOCK_NO;
71     case ContextMenuItemTagLearnSpelling:
72         return GTK_STOCK_OK;
73     case ContextMenuItemTagOther:
74         return GTK_STOCK_MISSING_IMAGE;
75     case ContextMenuItemTagSearchInSpotlight:
76         return GTK_STOCK_FIND;
77     case ContextMenuItemTagSearchWeb:
78         return GTK_STOCK_FIND;
79     case ContextMenuItemTagOpenWithDefaultApplication:
80         return GTK_STOCK_OPEN;
81     case ContextMenuItemPDFZoomIn:
82         return GTK_STOCK_ZOOM_IN;
83     case ContextMenuItemPDFZoomOut:
84         return GTK_STOCK_ZOOM_OUT;
85     case ContextMenuItemPDFAutoSize:
86         return GTK_STOCK_ZOOM_FIT;
87     case ContextMenuItemPDFNextPage:
88         return GTK_STOCK_GO_FORWARD;
89     case ContextMenuItemPDFPreviousPage:
90         return GTK_STOCK_GO_BACK;
91     // New tags, not part of API
92     case ContextMenuItemTagOpenLink:
93         return GTK_STOCK_OPEN;
94     case ContextMenuItemTagCheckSpelling:
95         return GTK_STOCK_SPELL_CHECK;
96     case ContextMenuItemTagFontMenu:
97         return GTK_STOCK_SELECT_FONT;
98     case ContextMenuItemTagShowFonts:
99         return GTK_STOCK_SELECT_FONT;
100     case ContextMenuItemTagBold:
101         return GTK_STOCK_BOLD;
102     case ContextMenuItemTagItalic:
103         return GTK_STOCK_ITALIC;
104     case ContextMenuItemTagUnderline:
105         return GTK_STOCK_UNDERLINE;
106     case ContextMenuItemTagShowColors:
107         return GTK_STOCK_SELECT_COLOR;
108     case ContextMenuItemTagToggleMediaControls:
109     case ContextMenuItemTagToggleMediaLoop:
110     case ContextMenuItemTagCopyImageUrlToClipboard:
111         // No icon for this.
112         return 0;
113     case ContextMenuItemTagEnterVideoFullscreen:
114         return GTK_STOCK_FULLSCREEN;
115     default:
116         return 0;
117     }
118 }
119
120 // Extract the ActionType from the menu item
121 ContextMenuItem::ContextMenuItem(PlatformMenuItemDescription item)
122     : m_platformDescription(item)
123 {
124 }
125
126 ContextMenuItem::ContextMenuItem(ContextMenu*)
127 {
128     notImplemented();
129 }
130
131 ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu)
132 {
133     if (type == SeparatorType) {
134         m_platformDescription = GTK_MENU_ITEM(gtk_separator_menu_item_new());
135         return;
136     }
137
138     GOwnPtr<char> actionName(g_strdup_printf("context-menu-action-%d", action));
139     GtkAction* platformAction = 0;
140
141     if (type == CheckableActionType)
142         platformAction = GTK_ACTION(gtk_toggle_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action)));
143     else
144         platformAction = gtk_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action));
145
146     m_platformDescription = GTK_MENU_ITEM(gtk_action_create_menu_item(platformAction));
147     g_object_unref(platformAction);
148
149     g_object_set_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action));
150
151     if (subMenu)
152         setSubMenu(subMenu);
153 }
154
155 ContextMenuItem::ContextMenuItem(ContextMenuItemType, ContextMenuAction, const String&, bool, bool)
156 {
157     // FIXME: Implement with WebKit2 ContextMenu changes.
158     notImplemented();
159 }
160
161 ContextMenuItem::ContextMenuItem(ContextMenuAction, const String&, bool, bool, Vector<ContextMenuItem>&)
162 {
163     // FIXME: Implement with WebKit2 ContextMenu changes.
164     notImplemented();
165 }
166
167 ContextMenuItem::~ContextMenuItem()
168 {
169 }
170
171 PlatformMenuItemDescription ContextMenuItem::releasePlatformDescription()
172 {
173     PlatformMenuItemDescription platformDescription = m_platformDescription;
174     m_platformDescription = 0;
175     return platformDescription;
176 }
177
178 ContextMenuItemType ContextMenuItem::type() const
179 {
180     if (GTK_IS_SEPARATOR_MENU_ITEM(m_platformDescription))
181         return SeparatorType;
182     if (GTK_IS_CHECK_MENU_ITEM(m_platformDescription))
183         return CheckableActionType;
184     if (gtk_menu_item_get_submenu(m_platformDescription))
185         return SubmenuType;
186     return ActionType;
187 }
188
189 void ContextMenuItem::setType(ContextMenuItemType type)
190 {
191     if (type == SeparatorType)
192         m_platformDescription = GTK_MENU_ITEM(gtk_separator_menu_item_new());
193 }
194
195 ContextMenuAction ContextMenuItem::action() const
196 {
197     return static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION)));
198 }
199
200 void ContextMenuItem::setAction(ContextMenuAction action)
201 {
202     g_object_set_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action));
203 }
204
205 String ContextMenuItem::title() const
206 {
207     GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription));
208     return action ? String(gtk_action_get_label(action)) : String();
209 }
210
211 void ContextMenuItem::setTitle(const String& title)
212 {
213     GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription));
214     if (action)
215         gtk_action_set_label(action, title.utf8().data());
216 }
217
218 PlatformMenuDescription ContextMenuItem::platformSubMenu() const
219 {
220     GtkWidget* subMenu = gtk_menu_item_get_submenu(m_platformDescription);
221     return subMenu ? GTK_MENU(subMenu) : 0;
222 }
223
224 void ContextMenuItem::setSubMenu(ContextMenu* menu)
225 {
226     gtk_menu_item_set_submenu(m_platformDescription, GTK_WIDGET(menu->platformDescription()));
227 }
228
229 void ContextMenuItem::setChecked(bool shouldCheck)
230 {
231     GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription));
232     if (action && GTK_IS_TOGGLE_ACTION(action))
233         gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), shouldCheck);
234 }
235
236 bool ContextMenuItem::checked() const
237 {
238     // FIXME: Implement with WebKit2 ContextMenu changes.
239     notImplemented();
240     return false;
241 }
242
243 bool ContextMenuItem::enabled() const
244 {
245     // FIXME: Implement with WebKit2 ContextMenu changes.
246     notImplemented();
247     return false;
248 }
249
250 void ContextMenuItem::setEnabled(bool shouldEnable)
251 {
252     GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription));
253     if (action)
254         gtk_action_set_sensitive(action, shouldEnable);
255 }
256
257 }