1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWebEngine module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include <QtCore/QCoreApplication>
41 #include "render_view_context_menu_qt.h"
42 
43 namespace QtWebEngineCore {
44 
getMenuItemName(RenderViewContextMenuQt::ContextMenuItem menuItem)45     const QString RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem menuItem) {
46         Q_ASSERT(menuItem <= ContextMenuItem::ViewSource);
47         static const char *names[ContextMenuItem::ViewSource + 1] = {
48             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Back"),
49             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Forward"),
50             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Reload"),
51             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Cut"),
52             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Copy"),
53             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Paste"),
54             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Undo"),
55             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Redo"),
56             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Select all"),
57             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Paste and match style"),
58             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Open link in new window"),
59             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Open link in new tab"),
60             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Copy link address"),
61             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Save link"),
62             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Copy image"),
63             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Copy image address"),
64             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Save image"),
65             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Copy media address"),
66             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Show controls"),
67             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Loop"),
68             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Save media"),
69             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Inspect"),
70             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Exit full screen"),
71             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Save page"),
72             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "View page source")
73         };
74         return QCoreApplication::translate("RenderViewContextMenuQt", qUtf8Printable(names[menuItem]));
75     }
76 
RenderViewContextMenuQt(const WebEngineContextMenuData & data)77     RenderViewContextMenuQt::RenderViewContextMenuQt(const WebEngineContextMenuData &data)
78         : m_contextData(data)
79     {
80     }
81 
initMenu()82     void RenderViewContextMenuQt::initMenu()
83     {
84         if (isFullScreenMode()) {
85             appendExitFullscreenItem();
86             appendSeparatorItem();
87         }
88 
89         if (m_contextData.isEditable() && !m_contextData.spellCheckerSuggestions().isEmpty()) {
90             appendSpellingSuggestionItems();
91             appendSeparatorItem();
92         }
93 
94         if (m_contextData.linkText().isEmpty() && !m_contextData.linkUrl().isValid() && !m_contextData.mediaUrl().isValid()) {
95             if (m_contextData.isEditable())
96                 appendEditableItems();
97             else if (!m_contextData.selectedText().isEmpty())
98                 appendCopyItem();
99             else
100                 appendPageItems();
101         } else {
102             appendPageItems();
103         }
104 
105         if (m_contextData.linkUrl().isValid() || !m_contextData.unfilteredLinkUrl().isEmpty() || !m_contextData.linkUrl().isEmpty())
106             appendLinkItems();
107 
108         if (m_contextData.mediaUrl().isValid()) {
109             switch (m_contextData.mediaType()) {
110             case WebEngineContextMenuData::MediaTypeImage:
111                 appendSeparatorItem();
112                 appendImageItems();
113                 break;
114             case WebEngineContextMenuData::MediaTypeCanvas:
115                 Q_UNREACHABLE();    // mediaUrl is invalid for canvases
116                 break;
117             case WebEngineContextMenuData::MediaTypeAudio:
118             case WebEngineContextMenuData::MediaTypeVideo:
119                 appendSeparatorItem();
120                 appendMediaItems();
121                 break;
122             default:
123                 break;
124             }
125         } else if (m_contextData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) {
126             appendSeparatorItem();
127             appendCanvasItems();
128         }
129 
130         if (canViewSource() || hasInspector()) {
131             appendSeparatorItem();
132             appendDeveloperItems();
133         }
134     }
135 
appendCanvasItems()136     void RenderViewContextMenuQt::appendCanvasItems()
137     {
138         addMenuItem(RenderViewContextMenuQt::DownloadImageToDisk);
139         addMenuItem(RenderViewContextMenuQt::CopyImageToClipboard);
140     }
141 
appendCopyItem()142     void RenderViewContextMenuQt::appendCopyItem()
143     {
144         addMenuItem(RenderViewContextMenuQt::Copy);
145     }
146 
appendDeveloperItems()147     void RenderViewContextMenuQt::appendDeveloperItems()
148     {
149         if (canViewSource())
150             addMenuItem(RenderViewContextMenuQt::ViewSource);
151         if (hasInspector())
152             addMenuItem(RenderViewContextMenuQt::InspectElement);
153     }
154 
appendEditableItems()155     void RenderViewContextMenuQt::appendEditableItems()
156     {
157         addMenuItem(RenderViewContextMenuQt::Undo);
158         addMenuItem(RenderViewContextMenuQt::Redo);
159         appendSeparatorItem();
160         addMenuItem(RenderViewContextMenuQt::Cut);
161         addMenuItem(RenderViewContextMenuQt::Copy);
162         addMenuItem(RenderViewContextMenuQt::Paste);
163         if (m_contextData.misspelledWord().isEmpty()) {
164             addMenuItem(RenderViewContextMenuQt::PasteAndMatchStyle);
165             addMenuItem(RenderViewContextMenuQt::SelectAll);
166         }
167     }
168 
appendExitFullscreenItem()169     void RenderViewContextMenuQt::appendExitFullscreenItem()
170     {
171         addMenuItem(RenderViewContextMenuQt::ExitFullScreen);
172     }
173 
appendImageItems()174     void RenderViewContextMenuQt::appendImageItems()
175     {
176         addMenuItem(RenderViewContextMenuQt::DownloadImageToDisk);
177         addMenuItem(RenderViewContextMenuQt::CopyImageToClipboard);
178         addMenuItem(RenderViewContextMenuQt::CopyImageUrlToClipboard);
179     }
180 
appendLinkItems()181     void RenderViewContextMenuQt::appendLinkItems()
182     {
183         addMenuItem(RenderViewContextMenuQt::OpenLinkInNewTab);
184         addMenuItem(RenderViewContextMenuQt::OpenLinkInNewWindow);
185         appendSeparatorItem();
186         addMenuItem(RenderViewContextMenuQt::DownloadLinkToDisk);
187         addMenuItem(RenderViewContextMenuQt::CopyLinkToClipboard);
188     }
189 
appendMediaItems()190     void RenderViewContextMenuQt::appendMediaItems()
191     {
192         addMenuItem(RenderViewContextMenuQt::ToggleMediaLoop);
193         if (m_contextData.mediaFlags() & QtWebEngineCore::WebEngineContextMenuData::MediaCanToggleControls)
194             addMenuItem(RenderViewContextMenuQt::ToggleMediaControls);
195         addMenuItem(RenderViewContextMenuQt::DownloadMediaToDisk);
196         addMenuItem(RenderViewContextMenuQt::CopyMediaUrlToClipboard);
197     }
198 
appendPageItems()199     void RenderViewContextMenuQt::appendPageItems()
200     {
201         addMenuItem(RenderViewContextMenuQt::Back);
202         addMenuItem(RenderViewContextMenuQt::Forward);
203         addMenuItem(RenderViewContextMenuQt::Reload);
204         appendSeparatorItem();
205         addMenuItem(RenderViewContextMenuQt::SavePage);
206     }
207 
appendSpellingSuggestionItems()208     void RenderViewContextMenuQt::appendSpellingSuggestionItems()
209     {
210         addMenuItem(RenderViewContextMenuQt::SpellingSuggestions);
211     }
212 
appendSeparatorItem()213     void RenderViewContextMenuQt::appendSeparatorItem()
214     {
215         addMenuItem(RenderViewContextMenuQt::Separator);
216     }
217 
canViewSource()218     bool RenderViewContextMenuQt::canViewSource()
219     {
220         return m_contextData.linkText().isEmpty()
221                && !m_contextData.linkUrl().isValid()
222                && !m_contextData.mediaUrl().isValid()
223                && !m_contextData.isEditable()
224                && m_contextData.selectedText().isEmpty();
225     }
226 }
227