#include "browser.h"
#include "browserwindow.h"
#include "tabwidget.h"
#include "webpage.h"
#include "webpopupwindow.h"
#include "webview.h"
#include <QContextMenuEvent>
#include <QDebug>
#include <QMenu>
#include <QMessageBox>
#include <QNetworkReply>
#include <QTimer>
WebView::WebView(QWidget *parent)
: QWebEngineView(parent)
, m_loadProgress(0)
{
connect(this, &QWebEngineView::loadProgress, [this](int progress) {
m_loadProgress = progress;
});
connect(this, &QWebEngineView::loadFinished, [this](bool success) {
if (!success) {
qWarning() << "Could not load page: " << url();
m_loadProgress = 0;
}
});
connect(this, &QWebEngineView::iconUrlChanged, this, &WebView::handleIconUrlChanged);
connect(this, &QWebEngineView::renderProcessTerminated,
[this](QWebEnginePage::RenderProcessTerminationStatus termStatus, int statusCode) {
QString status;
switch (termStatus) {
case QWebEnginePage::NormalTerminationStatus:
status = tr("Render process normal exit");
break;
case QWebEnginePage::AbnormalTerminationStatus:
status = tr("Render process abnormal exit");
break;
case QWebEnginePage::CrashedTerminationStatus:
status = tr("Render process crashed");
break;
case QWebEnginePage::KilledTerminationStatus:
status = tr("Render process killed");
break;
}
QMessageBox::critical(window(), status, tr("Render process exited with code: %1").arg(statusCode));
QTimer::singleShot(0, [this] { reload(); });
});
}
void WebView::setPage(WebPage *page)
{
createWebActionTrigger(page,QWebEnginePage::Forward);
createWebActionTrigger(page,QWebEnginePage::Back);
createWebActionTrigger(page,QWebEnginePage::Reload);
createWebActionTrigger(page,QWebEnginePage::Stop);
QWebEngineView::setPage(page);
}
QIcon WebView::icon() const
{
if (!m_icon.isNull())
return m_icon;
return QIcon(QLatin1String(":defaulticon.png"));
}
int WebView::loadProgress() const
{
return m_loadProgress;
}
void WebView::createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction webAction)
{
QAction *action = page->action(webAction);
connect(action, &QAction::changed, [this, action, webAction]{
emit webActionEnabledChanged(webAction, action->isEnabled());
});
}
bool WebView::isWebActionEnabled(QWebEnginePage::WebAction webAction) const
{
return page()->action(webAction)->isEnabled();
}
QNetworkAccessManager &WebView::networkAccessManager()
{
static QNetworkAccessManager networkAccessManager;
return networkAccessManager;
}
QWebEngineView *WebView::createWindow(QWebEnginePage::WebWindowType type)
{
switch (type) {
case QWebEnginePage::WebBrowserTab: {
BrowserWindow *mainWindow = qobject_cast<BrowserWindow*>(window());
return mainWindow->tabWidget()->createTab();
}
case QWebEnginePage::WebBrowserWindow: {
BrowserWindow *mainWindow = new BrowserWindow();
Browser::instance().addWindow(mainWindow);
return mainWindow->currentTab();
}
case QWebEnginePage::WebDialog: {
WebPopupWindow *popup = new WebPopupWindow(page()->profile());
return popup->view();
}
}
return nullptr;
}
void WebView::contextMenuEvent(QContextMenuEvent *event)
{
QMenu *menu = page()->createStandardContextMenu();
const QList<QAction*> actions = menu->actions();
auto it = std::find(actions.cbegin(), actions.cend(), page()->action(QWebEnginePage::OpenLinkInThisWindow));
if (it != actions.cend()) {
(*it)->setText(tr("Open Link in This Tab"));
++it;
QAction *before(it == actions.cend() ? nullptr : *it);
menu->insertAction(before, page()->action(QWebEnginePage::OpenLinkInNewWindow));
menu->insertAction(before, page()->action(QWebEnginePage::OpenLinkInNewTab));
}
connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
menu->popup(event->globalPos());
}
void WebView::handleIconUrlChanged(const QUrl &url)
{
QNetworkRequest iconRequest(url);
#ifndef QT_NO_OPENSSL
QSslConfiguration conf = iconRequest.sslConfiguration();
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
iconRequest.setSslConfiguration(conf);
#endif
QNetworkReply *iconReply = networkAccessManager().get(iconRequest);
iconReply->setParent(this);
connect(iconReply, &QNetworkReply::finished, this, &WebView::handleIconLoaded);
}
void WebView::handleIconLoaded()
{
QNetworkReply *iconReply = qobject_cast<QNetworkReply*>(sender());
if (iconReply && iconReply->error() == QNetworkReply::NoError) {
QByteArray data = iconReply->readAll();
QPixmap pixmap;
pixmap.loadFromData(data);
m_icon.addPixmap(pixmap);
iconReply->deleteLater();
} else {
m_icon = QIcon(QStringLiteral(":defaulticon.png"));
}
emit iconChanged(m_icon);
}
webview.cpp
最新推荐文章于 2024-07-30 15:56:19 发布