1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 * THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28#include "WebContextMenuProxyQt.h" 29 30#include <IntPoint.h> 31#include <OwnPtr.h> 32#include <WebContextMenuItemData.h> 33#include <qmenu.h> 34#include <qwkpage.h> 35 36using namespace WebCore; 37 38namespace WebKit { 39 40static QWKPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action) 41{ 42 switch (action) { 43 case WebCore::ContextMenuItemTagOpenLink: 44 return QWKPage::OpenLink; 45 case WebCore::ContextMenuItemTagOpenLinkInNewWindow: 46 return QWKPage::OpenLinkInNewWindow; 47 case WebCore::ContextMenuItemTagCopyLinkToClipboard: 48 return QWKPage::CopyLinkToClipboard; 49 case WebCore::ContextMenuItemTagOpenImageInNewWindow: 50 return QWKPage::OpenImageInNewWindow; 51 case WebCore::ContextMenuItemTagGoBack: 52 return QWKPage::Back; 53 case WebCore::ContextMenuItemTagGoForward: 54 return QWKPage::Forward; 55 case WebCore::ContextMenuItemTagStop: 56 return QWKPage::Stop; 57 case WebCore::ContextMenuItemTagReload: 58 return QWKPage::Reload; 59 case WebCore::ContextMenuItemTagCut: 60 return QWKPage::Cut; 61 case WebCore::ContextMenuItemTagCopy: 62 return QWKPage::Copy; 63 case WebCore::ContextMenuItemTagPaste: 64 return QWKPage::Paste; 65 case WebCore::ContextMenuItemTagSelectAll: 66 return QWKPage::SelectAll; 67 default: 68 break; 69 } 70 return QWKPage::NoWebAction; 71} 72 73WebContextMenuProxyQt::WebContextMenuProxyQt(QWKPage* page) 74 : m_page(page) 75{ 76} 77 78PassRefPtr<WebContextMenuProxyQt> WebContextMenuProxyQt::create(QWKPage* page) 79{ 80 return adoptRef(new WebContextMenuProxyQt(page)); 81} 82 83void WebContextMenuProxyQt::showContextMenu(const IntPoint& position, const Vector<WebContextMenuItemData>& items) 84{ 85 if (items.isEmpty()) 86 return; 87 88 OwnPtr<QMenu> menu = createContextMenu(items); 89 90 // We send the signal, even with no items, because the client should be able to show custom items 91 // even if WebKit has nothing to show. 92 if (!menu) 93 menu = adoptPtr(new QMenu); 94 95 menu->move(position); 96 emit m_page->showContextMenu(QSharedPointer<QMenu>(menu.leakPtr())); 97} 98 99void WebContextMenuProxyQt::hideContextMenu() 100{ 101} 102 103PassOwnPtr<QMenu> WebContextMenuProxyQt::createContextMenu(const Vector<WebContextMenuItemData>& items) const 104{ 105 OwnPtr<QMenu> menu = adoptPtr(new QMenu); 106 for (int i = 0; i < items.size(); ++i) { 107 const WebContextMenuItemData& item = items.at(i); 108 switch (item.type()) { 109 case WebCore::CheckableActionType: /* fall through */ 110 case WebCore::ActionType: { 111 QWKPage::WebAction action = webActionForContextMenuAction(item.action()); 112 QAction* qtAction = m_page->action(action); 113 if (qtAction) { 114 qtAction->setEnabled(item.enabled()); 115 qtAction->setChecked(item.checked()); 116 qtAction->setCheckable(item.type() == WebCore::CheckableActionType); 117 118 menu->addAction(qtAction); 119 } 120 break; 121 } 122 case WebCore::SeparatorType: 123 menu->addSeparator(); 124 break; 125 case WebCore::SubmenuType: 126 if (OwnPtr<QMenu> subMenu = createContextMenu(item.submenu())) { 127 subMenu->setParent(menu.get()); 128 QMenu* const subMenuPtr = subMenu.leakPtr(); 129 subMenu->setTitle(item.title()); 130 menu->addMenu(subMenuPtr); 131 } 132 133 break; 134 } 135 } 136 137 // Do not show sub-menus with just disabled actions. 138 if (menu->isEmpty()) 139 return PassOwnPtr<QMenu>(); 140 141 bool isAnyActionEnabled = false; 142 QList<QAction *> actions = menu->actions(); 143 for (int i = 0; i < actions.count(); ++i) { 144 if (actions.at(i)->isVisible()) 145 isAnyActionEnabled |= actions.at(i)->isEnabled(); 146 } 147 if (!isAnyActionEnabled) 148 return PassOwnPtr<QMenu>(); 149 150 return menu.release(); 151} 152 153} // namespace WebKit 154