xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/imxwayland/simplebrowser/tabwidget.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
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 ** BSD License Usage
18 ** Alternatively, you may use this file under the terms of the BSD license
19 ** as follows:
20 **
21 ** "Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions are
23 ** met:
24 **   * Redistributions of source code must retain the above copyright
25 **     notice, this list of conditions and the following disclaimer.
26 **   * Redistributions in binary form must reproduce the above copyright
27 **     notice, this list of conditions and the following disclaimer in
28 **     the documentation and/or other materials provided with the
29 **     distribution.
30 **   * Neither the name of The Qt Company Ltd nor the names of its
31 **     contributors may be used to endorse or promote products derived
32 **     from this software without specific prior written permission.
33 **
34 **
35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46 **
47 ** $QT_END_LICENSE$
48 **
49 ****************************************************************************/
50 
51 #include "tabwidget.h"
52 #include "webpage.h"
53 #include "webview.h"
54 #include <QMenu>
55 #include <QTabBar>
56 #include <QWebEngineProfile>
57 
TabWidget(QWebEngineProfile * profile,QWidget * parent)58 TabWidget::TabWidget(QWebEngineProfile *profile, QWidget *parent)
59     : QTabWidget(parent)
60     , m_profile(profile)
61 {
62     QTabBar *tabBar = this->tabBar();
63     tabBar->setTabsClosable(true);
64     tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
65     tabBar->setMovable(true);
66     tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
67     connect(tabBar, &QTabBar::customContextMenuRequested, this, &TabWidget::handleContextMenuRequested);
68     connect(tabBar, &QTabBar::tabCloseRequested, this, &TabWidget::closeTab);
69     connect(tabBar, &QTabBar::tabBarDoubleClicked, [this](int index) {
70         if (index == -1)
71             createTab();
72     });
73 
74     setDocumentMode(true);
75     setElideMode(Qt::ElideRight);
76 
77     connect(this, &QTabWidget::currentChanged, this, &TabWidget::handleCurrentChanged);
78 }
79 
handleCurrentChanged(int index)80 void TabWidget::handleCurrentChanged(int index)
81 {
82     if (index != -1) {
83         WebView *view = webView(index);
84         if (!view->url().isEmpty())
85             view->setFocus();
86         emit titleChanged(view->title());
87         emit loadProgress(view->loadProgress());
88         emit urlChanged(view->url());
89         emit favIconChanged(view->favIcon());
90         emit webActionEnabledChanged(QWebEnginePage::Back, view->isWebActionEnabled(QWebEnginePage::Back));
91         emit webActionEnabledChanged(QWebEnginePage::Forward, view->isWebActionEnabled(QWebEnginePage::Forward));
92         emit webActionEnabledChanged(QWebEnginePage::Stop, view->isWebActionEnabled(QWebEnginePage::Stop));
93         emit webActionEnabledChanged(QWebEnginePage::Reload,view->isWebActionEnabled(QWebEnginePage::Reload));
94     } else {
95         emit titleChanged(QString());
96         emit loadProgress(0);
97         emit urlChanged(QUrl());
98         emit favIconChanged(QIcon());
99         emit webActionEnabledChanged(QWebEnginePage::Back, false);
100         emit webActionEnabledChanged(QWebEnginePage::Forward, false);
101         emit webActionEnabledChanged(QWebEnginePage::Stop, false);
102         emit webActionEnabledChanged(QWebEnginePage::Reload, true);
103     }
104 }
105 
handleContextMenuRequested(const QPoint & pos)106 void TabWidget::handleContextMenuRequested(const QPoint &pos)
107 {
108     QMenu menu;
109     menu.addAction(tr("New &Tab"), this, &TabWidget::createTab, QKeySequence::AddTab);
110     int index = tabBar()->tabAt(pos);
111     if (index != -1) {
112         QAction *action = menu.addAction(tr("Clone Tab"));
113         connect(action, &QAction::triggered, this, [this,index]() {
114             cloneTab(index);
115         });
116         menu.addSeparator();
117         action = menu.addAction(tr("&Close Tab"));
118         action->setShortcut(QKeySequence::Close);
119         connect(action, &QAction::triggered, this, [this,index]() {
120             closeTab(index);
121         });
122         action = menu.addAction(tr("Close &Other Tabs"));
123         connect(action, &QAction::triggered, this, [this,index]() {
124             closeOtherTabs(index);
125         });
126         menu.addSeparator();
127         action = menu.addAction(tr("Reload Tab"));
128         action->setShortcut(QKeySequence::Refresh);
129         connect(action, &QAction::triggered, this, [this,index]() {
130             reloadTab(index);
131         });
132     } else {
133         menu.addSeparator();
134     }
135     menu.addAction(tr("Reload All Tabs"), this, &TabWidget::reloadAllTabs);
136     menu.exec(QCursor::pos());
137 }
138 
currentWebView() const139 WebView *TabWidget::currentWebView() const
140 {
141     return webView(currentIndex());
142 }
143 
webView(int index) const144 WebView *TabWidget::webView(int index) const
145 {
146     return qobject_cast<WebView*>(widget(index));
147 }
148 
setupView(WebView * webView)149 void TabWidget::setupView(WebView *webView)
150 {
151     QWebEnginePage *webPage = webView->page();
152 
153     connect(webView, &QWebEngineView::titleChanged, [this, webView](const QString &title) {
154         int index = indexOf(webView);
155         if (index != -1) {
156             setTabText(index, title);
157             setTabToolTip(index, title);
158         }
159         if (currentIndex() == index)
160             emit titleChanged(title);
161     });
162     connect(webView, &QWebEngineView::urlChanged, [this, webView](const QUrl &url) {
163         int index = indexOf(webView);
164         if (index != -1)
165             tabBar()->setTabData(index, url);
166         if (currentIndex() == index)
167             emit urlChanged(url);
168     });
169     connect(webView, &QWebEngineView::loadProgress, [this, webView](int progress) {
170         if (currentIndex() == indexOf(webView))
171             emit loadProgress(progress);
172     });
173     connect(webPage, &QWebEnginePage::linkHovered, [this, webView](const QString &url) {
174         if (currentIndex() == indexOf(webView))
175             emit linkHovered(url);
176     });
177     connect(webView, &WebView::favIconChanged, [this, webView](const QIcon &icon) {
178         int index = indexOf(webView);
179         if (index != -1)
180             setTabIcon(index, icon);
181         if (currentIndex() == index)
182             emit favIconChanged(icon);
183     });
184     connect(webView, &WebView::webActionEnabledChanged, [this, webView](QWebEnginePage::WebAction action, bool enabled) {
185         if (currentIndex() ==  indexOf(webView))
186             emit webActionEnabledChanged(action,enabled);
187     });
188     connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() {
189         int index = indexOf(webView);
190         if (index >= 0)
191             closeTab(index);
192     });
193 }
194 
createTab()195 WebView *TabWidget::createTab()
196 {
197     WebView *webView = createBackgroundTab();
198     setCurrentWidget(webView);
199     return webView;
200 }
201 
createBackgroundTab()202 WebView *TabWidget::createBackgroundTab()
203 {
204     WebView *webView = new WebView;
205     WebPage *webPage = new WebPage(m_profile, webView);
206     webView->setPage(webPage);
207     setupView(webView);
208     int index = addTab(webView, tr("(Untitled)"));
209     setTabIcon(index, webView->favIcon());
210     // Workaround for QTBUG-61770
211     webView->resize(currentWidget()->size());
212     webView->show();
213     return webView;
214 }
215 
reloadAllTabs()216 void TabWidget::reloadAllTabs()
217 {
218     for (int i = 0; i < count(); ++i)
219         webView(i)->reload();
220 }
221 
closeOtherTabs(int index)222 void TabWidget::closeOtherTabs(int index)
223 {
224     for (int i = count() - 1; i > index; --i)
225         closeTab(i);
226     for (int i = index - 1; i >= 0; --i)
227         closeTab(i);
228 }
229 
closeTab(int index)230 void TabWidget::closeTab(int index)
231 {
232     if (WebView *view = webView(index)) {
233         bool hasFocus = view->hasFocus();
234         removeTab(index);
235         if (hasFocus && count() > 0)
236             currentWebView()->setFocus();
237         if (count() == 0)
238             createTab();
239         view->deleteLater();
240     }
241 }
242 
cloneTab(int index)243 void TabWidget::cloneTab(int index)
244 {
245     if (WebView *view = webView(index)) {
246         WebView *tab = createTab();
247         tab->setUrl(view->url());
248     }
249 }
250 
setUrl(const QUrl & url)251 void TabWidget::setUrl(const QUrl &url)
252 {
253     if (WebView *view = currentWebView()) {
254         view->setUrl(url);
255         view->setFocus();
256     }
257 }
258 
triggerWebPageAction(QWebEnginePage::WebAction action)259 void TabWidget::triggerWebPageAction(QWebEnginePage::WebAction action)
260 {
261     if (WebView *webView = currentWebView()) {
262         webView->triggerPageAction(action);
263         webView->setFocus();
264     }
265 }
266 
nextTab()267 void TabWidget::nextTab()
268 {
269     int next = currentIndex() + 1;
270     if (next == count())
271         next = 0;
272     setCurrentIndex(next);
273 }
274 
previousTab()275 void TabWidget::previousTab()
276 {
277     int next = currentIndex() - 1;
278     if (next < 0)
279         next = count() - 1;
280     setCurrentIndex(next);
281 }
282 
reloadTab(int index)283 void TabWidget::reloadTab(int index)
284 {
285     if (WebView *view = webView(index))
286         view->reload();
287 }
288