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
36 using namespace WebCore;
37
38 namespace WebKit {
39
webActionForContextMenuAction(WebCore::ContextMenuAction action)40 static 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
WebContextMenuProxyQt(QWKPage * page)73 WebContextMenuProxyQt::WebContextMenuProxyQt(QWKPage* page)
74 : m_page(page)
75 {
76 }
77
create(QWKPage * page)78 PassRefPtr<WebContextMenuProxyQt> WebContextMenuProxyQt::create(QWKPage* page)
79 {
80 return adoptRef(new WebContextMenuProxyQt(page));
81 }
82
showContextMenu(const IntPoint & position,const Vector<WebContextMenuItemData> & items)83 void 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
hideContextMenu()99 void WebContextMenuProxyQt::hideContextMenu()
100 {
101 }
102
createContextMenu(const Vector<WebContextMenuItemData> & items) const103 PassOwnPtr<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