Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  *  Copyright (C) 2008 Nuanti Ltd.
      3  *  Copyright (C) 2009 Gustavo Noronha Silva <gns (at) gnome.org>
      4  *
      5  *  This library is free software; you can redistribute it and/or
      6  *  modify it under the terms of the GNU Lesser 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  *  Lesser General Public License for more details.
     14  *
     15  *  You should have received a copy of the GNU Lesser General Public
     16  *  License along with this library; if not, write to the Free Software
     17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     18  */
     19 
     20 #include "config.h"
     21 #include "ContextMenuClientGtk.h"
     22 
     23 #include "ContextMenu.h"
     24 #include "ContextMenuController.h"
     25 #include "HitTestResult.h"
     26 #include "KURL.h"
     27 #include "NotImplemented.h"
     28 #include "Page.h"
     29 #include "webkitwebviewprivate.h"
     30 #include <glib-object.h>
     31 #include <glib/gi18n-lib.h>
     32 #include <gtk/gtk.h>
     33 #include <wtf/text/CString.h>
     34 
     35 using namespace WebCore;
     36 
     37 namespace WebKit {
     38 
     39 ContextMenuClient::ContextMenuClient(WebKitWebView *webView)
     40     : m_webView(webView)
     41 {
     42 }
     43 
     44 void ContextMenuClient::contextMenuDestroyed()
     45 {
     46     delete this;
     47 }
     48 
     49 static GtkWidget* inputMethodsMenuItem (WebKitWebView* webView)
     50 {
     51     if (gtk_major_version > 2 || (gtk_major_version == 2 && gtk_minor_version >= 10)) {
     52         GtkSettings* settings = webView ? gtk_widget_get_settings(GTK_WIDGET(webView)) : gtk_settings_get_default();
     53 
     54         gboolean showMenu = TRUE;
     55         if (settings)
     56             g_object_get(settings, "gtk-show-input-method-menu", &showMenu, NULL);
     57         if (!showMenu)
     58             return 0;
     59     }
     60 
     61     GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic(
     62         _("Input _Methods"));
     63 
     64     WebKitWebViewPrivate* priv = webView->priv;
     65     GtkWidget* imContextMenu = gtk_menu_new();
     66     gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(priv->imContext.get()), GTK_MENU_SHELL(imContextMenu));
     67 
     68     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), imContextMenu);
     69 
     70     return menuitem;
     71 }
     72 
     73 // Values taken from gtktextutil.c
     74 typedef struct {
     75   const char *label;
     76   gunichar ch;
     77 } GtkUnicodeMenuEntry;
     78 static const GtkUnicodeMenuEntry bidi_menu_entries[] = {
     79   { N_("LRM _Left-to-right mark"), 0x200E },
     80   { N_("RLM _Right-to-left mark"), 0x200F },
     81   { N_("LRE Left-to-right _embedding"), 0x202A },
     82   { N_("RLE Right-to-left e_mbedding"), 0x202B },
     83   { N_("LRO Left-to-right _override"), 0x202D },
     84   { N_("RLO Right-to-left o_verride"), 0x202E },
     85   { N_("PDF _Pop directional formatting"), 0x202C },
     86   { N_("ZWS _Zero width space"), 0x200B },
     87   { N_("ZWJ Zero width _joiner"), 0x200D },
     88   { N_("ZWNJ Zero width _non-joiner"), 0x200C }
     89 };
     90 
     91 static void insertControlCharacter(GtkWidget* widget)
     92 {
     93     // GtkUnicodeMenuEntry* entry = (GtkUnicodeMenuEntry*)g_object_get_data(G_OBJECT(widget), "gtk-unicode-menu-entry");
     94     notImplemented();
     95 }
     96 
     97 static GtkWidget* unicodeMenuItem(WebKitWebView* webView)
     98 {
     99     if (gtk_major_version > 2 || (gtk_major_version == 2 && gtk_minor_version >= 10)) {
    100         GtkSettings* settings = webView ? gtk_widget_get_settings(GTK_WIDGET(webView)) : gtk_settings_get_default();
    101 
    102         gboolean showMenu = TRUE;
    103         if (settings)
    104             g_object_get(settings, "gtk-show-unicode-menu", &showMenu, NULL);
    105         if (!showMenu)
    106             return 0;
    107     }
    108 
    109     GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic(
    110         _("_Insert Unicode Control Character"));
    111 
    112     GtkWidget* unicodeContextMenu = gtk_menu_new();
    113     unsigned i;
    114     for (i = 0; i < G_N_ELEMENTS(bidi_menu_entries); i++) {
    115         GtkWidget* menuitem = gtk_menu_item_new_with_mnemonic(_(bidi_menu_entries[i].label));
    116         g_object_set_data(G_OBJECT(menuitem), "gtk-unicode-menu-entry", (gpointer)&bidi_menu_entries[i]);
    117         g_signal_connect(menuitem, "activate", G_CALLBACK(insertControlCharacter), 0);
    118         gtk_widget_show(menuitem);
    119         gtk_menu_shell_append(GTK_MENU_SHELL(unicodeContextMenu), menuitem);
    120         // FIXME: Make the item sensitive as insertControlCharacter() is implemented
    121         gtk_widget_set_sensitive(menuitem, FALSE);
    122     }
    123 
    124     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), unicodeContextMenu);
    125 
    126     return menuitem;
    127 }
    128 
    129 PlatformMenuDescription ContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu)
    130 {
    131     GtkMenu* gtkmenu = menu->releasePlatformDescription();
    132 
    133     WebKitWebView* webView = m_webView;
    134     HitTestResult result = core(webView)->contextMenuController()->hitTestResult();
    135 
    136     if (result.isContentEditable()) {
    137 
    138         GtkWidget* imContextMenu = inputMethodsMenuItem(webView);
    139         GtkWidget* unicodeContextMenu = unicodeMenuItem(webView);
    140 
    141         if (imContextMenu || unicodeContextMenu) {
    142             GtkWidget* separator = gtk_separator_menu_item_new();
    143             gtk_menu_shell_append(GTK_MENU_SHELL(gtkmenu), separator);
    144             gtk_widget_show(separator);
    145         }
    146 
    147         if (imContextMenu) {
    148             gtk_menu_shell_append(GTK_MENU_SHELL(gtkmenu), imContextMenu);
    149             gtk_widget_show(imContextMenu);
    150         }
    151 
    152         if (unicodeContextMenu) {
    153             gtk_menu_shell_append(GTK_MENU_SHELL(gtkmenu), unicodeContextMenu);
    154             gtk_widget_show(unicodeContextMenu);
    155         }
    156 
    157     }
    158 
    159     return gtkmenu;
    160 }
    161 
    162 void ContextMenuClient::contextMenuItemSelected(ContextMenuItem*, const ContextMenu*)
    163 {
    164     notImplemented();
    165 }
    166 
    167 void ContextMenuClient::downloadURL(const KURL& url)
    168 {
    169     WebKitNetworkRequest* networkRequest = webkit_network_request_new(url.string().utf8().data());
    170 
    171     webkit_web_view_request_download(m_webView, networkRequest);
    172     g_object_unref(networkRequest);
    173 }
    174 
    175 void ContextMenuClient::copyImageToClipboard(const HitTestResult&)
    176 {
    177     notImplemented();
    178 }
    179 
    180 void ContextMenuClient::searchWithGoogle(const Frame*)
    181 {
    182     notImplemented();
    183 }
    184 
    185 void ContextMenuClient::lookUpInDictionary(Frame*)
    186 {
    187     notImplemented();
    188 }
    189 
    190 void ContextMenuClient::speak(const String&)
    191 {
    192     notImplemented();
    193 }
    194 
    195 void ContextMenuClient::stopSpeaking()
    196 {
    197     notImplemented();
    198 }
    199 
    200 bool ContextMenuClient::isSpeaking()
    201 {
    202     notImplemented();
    203     return false;
    204 }
    205 
    206 }
    207 
    208