/* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original * location: https://neueland.iserlohn-fortress.net/smolbote.hg * * SPDX-License-Identifier: GPL-3.0 */ #include "webview.h" // copy page URL #include #include // zoom widget #include #include #include #include #include #include // printer support #include #include #include #include #include "src/mainwindow/mainwindow.h" #include // ssl errors #include "lib/navigation/urllineedit.h" WebView::WebView(MainWindow *parentMainWindow, QWidget *parent) : QWebEngineView(parent) { Q_CHECK_PTR(parentMainWindow); m_parent = parentMainWindow; // load status and progress connect(this, &QWebEngineView::loadStarted, this, [this]() { m_loaded = false; }); connect(this, &QWebEngineView::loadFinished, this, [this]() { m_loaded = true; }); connect(this, &QWebEngineView::loadProgress, this, [this](int progress) { m_loadProgress = progress; }); m_pageMenu = new QMenu(); m_pageMenu->setMinimumWidth(240); QAction *copyUrlAction = m_pageMenu->addAction(tr("Copy page URL")); connect(copyUrlAction, &QAction::triggered, [this]() { qApp->clipboard()->setText(this->url().toString()); }); QAction *bookmarkAction = m_pageMenu->addAction(tr("TODO: Bookmark page")); connect(bookmarkAction, &QAction::triggered, this, [this]() { emit newBookmark(this->title(), this->url()); }); m_pageMenu->addSeparator(); QWidgetAction *zoomWidgetAction = new QWidgetAction(m_pageMenu); { QWidget *widget = new QWidget(m_pageMenu); zoomWidgetAction->setDefaultWidget(widget); QVBoxLayout *layout = new QVBoxLayout(widget); widget->setLayout(layout); QLabel *zoomLabel = new QLabel(tr("Zoom: 1x")); layout->addWidget(zoomLabel); QHBoxLayout *zoomLayout = new QHBoxLayout(); layout->addLayout(zoomLayout); QSlider *zoomSlider = new QSlider(Qt::Horizontal); zoomSlider->setMinimum(5); zoomSlider->setMaximum(50); zoomSlider->setValue(10); zoomLayout->addWidget(zoomSlider); QToolButton *zoomResetButton = new QToolButton(widget); zoomResetButton->setIcon(widget->style()->standardIcon(QStyle::SP_BrowserReload)); zoomLayout->addWidget(zoomResetButton); connect(zoomResetButton, &QToolButton::clicked, [zoomSlider]() { zoomSlider->setValue(10); }); connect(zoomSlider, &QSlider::valueChanged, this, [this, zoomLabel](int value) { zoomLabel->setText(tr("Zoom: %1x").arg(static_cast(value) / 10)); this->setZoomFactor(static_cast(value) / 10); }); } m_pageMenu->addAction(zoomWidgetAction); m_pageMenu->addSeparator(); QAction *savePageAction = m_pageMenu->addAction(tr("TODO: Save Page")); connect(savePageAction, &QAction::triggered, this, [this]() { this->triggerPageAction(QWebEnginePage::SavePage); }); #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) QAction *printAction = m_pageMenu->addAction(tr("Print page")); connect(printAction, &QAction::triggered, [this]() { QPrinter *printer = new QPrinter(QPrinterInfo::defaultPrinter()); QPrintDialog *dlg = new QPrintDialog(printer, nullptr); if(dlg->exec() == QDialog::Accepted) { this->page()->print(printer, [printer](bool success) { qDebug("print %s", success ? "ok" : "failed"); delete printer; }); } delete dlg; }); #endif QAction *printPdfAction = m_pageMenu->addAction(tr("Print to PDF")); connect(printPdfAction, &QAction::triggered, [this]() { const QString path = QFileDialog::getSaveFileName(this, tr("Print to PDF"), QDir::homePath(), tr("PDF files (*.pdf)")); this->page()->printToPdf(path); }); } WebView::~WebView() { delete m_pageMenu; } QMenu *WebView::pageMenu() { Q_CHECK_PTR(m_pageMenu); return m_pageMenu; } void WebView::setPage(WebPage *page) { Q_CHECK_PTR(page); // make sure the page gets cleaned up if we replace it by taking ownership page->setParent(this); connect(page, &WebPage::linkHovered, this, &WebView::handleLinkHovered); connect(page, &WebPage::certificateErrorMessage, this, &WebView::handleCertificateError); QWebEngineView::setPage(page); } bool WebView::isLoaded() const { return m_loaded; } int WebView::loadProgress() const { return m_loadProgress; } WebView *WebView::createWindow(QWebEnginePage::WebWindowType type) { WebView *view = new WebView(m_parent); switch(type) { case QWebEnginePage::WebBrowserWindow: // a complete web browser window m_parent->newWindow()->tabBar->addTab(view); break; case QWebEnginePage::WebBrowserTab: // a web browser tab m_parent->tabBar->setCurrentIndex(m_parent->tabBar->addTab(view)); break; case QWebEnginePage::WebDialog: // a window without decorations m_parent->newWindow()->tabBar->addTab(view); break; case QWebEnginePage::WebBrowserBackgroundTab: // a web browser tab, but don't swap to it m_parent->tabBar->addTab(view); break; } return view; } void WebView::handleLinkHovered(const QString &url) { if(isVisible()) { m_parent->statusBar()->showMessage(url); } } void WebView::handleCertificateError(const QString &message) { m_parent->m_addressBar->showSslError(message); }