Skip to content

Commit

Permalink
WebView: Port to Qt WebEngine (fixes Windows build)
Browse files Browse the repository at this point in the history
For displaying web pages, qolibri was using the Qt WebKit library, which
was removed years ago with Qt 5.6. These days it's pretty much only
still available on GNU/Linux and the BSDs, where distros maintain it to
keep old apps working for now.

This change ports to Qt WebKit's Chromium-based successor Qt WebEngine.

Among other things, this fixes Windows builds (only tested with official
prebuilt Qt 5.11.2 on Windows 10 x64 with VS2017 compiler).
  • Loading branch information
mvf committed Nov 4, 2018
1 parent facfc12 commit 1a99a7d
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 45 deletions.
4 changes: 3 additions & 1 deletion qolibri.pro
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ HEADERS += \
src/titlelabel.h \
src/toolbar.h \
src/treescrollpopup.h \
src/webpage.h \
src/webview.h \

SOURCES += \
Expand Down Expand Up @@ -69,6 +70,7 @@ SOURCES += \
src/textcodec.cpp \
src/toolbar.cpp \
src/treescrollpopup.cpp \
src/webpage.cpp \
src/webview.cpp \

RESOURCES += qolibri.qrc
Expand All @@ -77,7 +79,7 @@ FORMS += src/optiondialog.ui

lessThan(QT_MAJOR_VERSION, 5): error("Qt 5 or later required")

QT += multimedia network webkit webkitwidgets widgets
QT += multimedia network webengine webenginewidgets widgets

TARGET = qolibri
DESTDIR = .
Expand Down
2 changes: 1 addition & 1 deletion src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#include <QStatusBar>
#include <QTimer>
#include <QToolBar>
#include <QWebHistory>
#include <QWebEngineHistory>

const char *Program = { "qolibri" };

Expand Down
81 changes: 81 additions & 0 deletions src/webpage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "webpage.h"

#include <QMenu>
#include <QWebEngineContextMenuData>
#include <QWebEngineHistory>

WebPage::WebPage(QObject* parent)
: QWebEnginePage(parent)
, delegateLinks(false)
{
}

bool WebPage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
{
Q_UNUSED(isMainFrame);
if (type == NavigationTypeLinkClicked && delegateLinks) {
emit linkClicked(url);
return false;
}
return true;
}

// Stripped-down version of QWebEnginePage::createStandardContextMenu to
// have consistent menus across platforms and Qt versions and to only
// offer options that are actually supported
QMenu *WebPage::createContextMenu() const
{
const QWebEngineContextMenuData &cmdata = contextMenuData();
if (!cmdata.isValid())
return 0;

QWidget *const view = this->view();
QMenu *const menu = new QMenu(view);

if (cmdata.selectedText().isEmpty()) {
QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu);
connect(action, SIGNAL(triggered()), view, SLOT(back()));
action->setEnabled(history()->canGoBack());
menu->addAction(action);

action = new QAction(QIcon::fromTheme(QStringLiteral("go-next")), tr("&Forward"), menu);
connect(action, SIGNAL(triggered()), view, SLOT(forward()));
action->setEnabled(history()->canGoForward());
menu->addAction(action);

action = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), tr("&Reload"), menu);
connect(action, SIGNAL(triggered()), view, SLOT(reload()));
menu->addAction(action);
} else {
menu->addAction(action(Copy));
menu->addAction(action(Unselect));
}

if (!cmdata.linkText().isEmpty()) {
menu->addAction(action(OpenLinkInNewWindow));
menu->addAction(action(CopyLinkToClipboard));
}

if (cmdata.mediaUrl().isValid()) {
switch (cmdata.mediaType()) {
case QWebEngineContextMenuData::MediaTypeImage:
menu->addAction(action(CopyImageUrlToClipboard));
menu->addAction(action(CopyImageToClipboard));
break;
case QWebEngineContextMenuData::MediaTypeAudio:
case QWebEngineContextMenuData::MediaTypeVideo:
menu->addAction(action(CopyMediaUrlToClipboard));
menu->addAction(action(ToggleMediaPlayPause));
menu->addAction(action(ToggleMediaLoop));
menu->addAction(action(ToggleMediaMute));
break;
default:
break;
}
} else if (cmdata.mediaType() == QWebEngineContextMenuData::MediaTypeCanvas) {
menu->addAction(action(CopyImageToClipboard));
}

menu->setAttribute(Qt::WA_DeleteOnClose, true);
return menu;
}
20 changes: 20 additions & 0 deletions src/webpage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef WEBPAGE_H
#define WEBPAGE_H

#include <QWebEnginePage>

class WebPage : public QWebEnginePage
{
Q_OBJECT
public:
explicit WebPage(QObject* parent = 0);
bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
QMenu *createContextMenu() const;
void setDelegateLinks(bool enable) { delegateLinks = enable; }
signals:
void linkClicked(const QUrl &url);
private:
bool delegateLinks;
};

#endif // WEBPAGE_H
70 changes: 33 additions & 37 deletions src/webview.cpp
Original file line number Diff line number Diff line change
@@ -1,44 +1,46 @@
#include "webview.h"
#include "webpage.h"
#include "configure.h"

#include <QAction>
#include <QContextMenuEvent>
#include <QDebug>
#include <QMenu>
#include <QTabBar>
#include <QTextCodec>
#include <QWebEngineContextMenuData>
#include <QWebEngineHistory>
#include <QWebEngineSettings>

WebView::WebView(QWidget *parent)
: QWebView(parent)
: QWebEngineView(parent)
, loading_(false)
, popupBrowser_(false)
, progressCount_(0)
, tabBar_(0)
{
setObjectName("webpage");
page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);

WebPage *const webPage = new WebPage(this);
connect(webPage, SIGNAL(linkClicked(const QUrl&)), SLOT(openLink(const QUrl&)));
connect(webPage, SIGNAL(linkHovered(QString)), SLOT(copyHoveredLink(QString)));
connect(webPage->action(QWebEnginePage::OpenLinkInNewWindow), SIGNAL(triggered()), SLOT(openNewWin()));
setPage(webPage);

connect(this, SIGNAL(loadStarted()), SLOT(progressStart()));
connect(this, SIGNAL(loadFinished(bool)), SLOT(progressFinished(bool)));
connect(this, SIGNAL(loadProgress(int)), SLOT(progress(int)));
connect(this, SIGNAL(linkClicked(const QUrl&)),
SLOT(openLink(const QUrl&)));

QAction *newWinAct = pageAction(QWebPage::OpenLinkInNewWindow);
connect(newWinAct, SIGNAL(triggered()), SLOT(openNewWin()));
connect(page(), SIGNAL(linkHovered(QString,QString,QString)),
SLOT(copyHoveredLink(QString,QString,QString)));

QWebSettings *ws = settings();
ws->setAttribute(QWebSettings::JavascriptEnabled, true);
ws->setAttribute(QWebSettings::JavaEnabled, true);
ws->setAttribute(QWebSettings::PluginsEnabled, true);
QWebEngineSettings *ws = settings();
ws->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
ws->setAttribute(QWebEngineSettings::PluginsEnabled, true);
}

void WebView::openNewWin()
{
emit processRequested(CONF->browserProcess, QStringList(hoveredLink));
}

void WebView::copyHoveredLink(const QString &link, const QString&,
const QString&)
void WebView::copyHoveredLink(const QString &link)
{
if (!link.isEmpty()) {
hoveredLink = link;
Expand All @@ -64,11 +66,11 @@ void WebView::load(const QString &url, const Query &query)

void WebView::contextMenuEvent(QContextMenuEvent* event)
{
QWebView::contextMenuEvent(event);
//QMenu *menu = createStandardContextMenu();
//QAction *a = menu->exec(event->globalPos());
//delete menu;

if (WebPage *webPage = qobject_cast<WebPage *>(page())) {
if (QMenu *menu = webPage->createContextMenu()) {
menu->popup(event->globalPos());
}
}
}

QByteArray WebView::encString(const QString &url)
Expand Down Expand Up @@ -162,11 +164,11 @@ QString WebView::setDirectionString(const QString &url, const QString &dstr,

void WebView::changeFontSize(int delta)
{
QWebSettings *s = settings();
int dsz = s->fontSize(QWebSettings::DefaultFontSize);
int fsz = s->fontSize(QWebSettings::DefaultFixedFontSize);
s->setFontSize(QWebSettings::DefaultFontSize, dsz + delta);
s->setFontSize(QWebSettings::DefaultFixedFontSize, fsz + delta);
QWebEngineSettings *s = settings();
int dsz = s->fontSize(QWebEngineSettings::DefaultFontSize);
int fsz = s->fontSize(QWebEngineSettings::DefaultFixedFontSize);
s->setFontSize(QWebEngineSettings::DefaultFontSize, dsz + delta);
s->setFontSize(QWebEngineSettings::DefaultFixedFontSize, fsz + delta);
}

void WebView::progressStart()
Expand Down Expand Up @@ -197,22 +199,14 @@ void WebView::progressFinished(bool)

void WebView::openLink(const QUrl &url)
{
if (!popupBrowser_) {
QUrl u = QUrl::fromEncoded(url.toEncoded(), QUrl::TolerantMode);
qDebug() << url.toEncoded();
qDebug() << u.toString();
load(u);
} else {
emit processRequested(CONF->browserProcess, QStringList(url.toString()));
}

emit processRequested(CONF->browserProcess, QStringList(url.toString()));
}

void WebView::changeFont(const QFont &font)
{

qDebug() << "WebPage::changeFont" << font.family();
settings()->setFontFamily(QWebSettings::StandardFont, font.family());
settings()->setFontFamily(QWebEngineSettings::StandardFont, font.family());

}

Expand All @@ -228,6 +222,8 @@ void WebView::zoomOut()

void WebView::setPopupBrowser(bool popup)
{
popupBrowser_ = popup;
if (WebPage *webPage = qobject_cast<WebPage *>(page())) {
webPage->setDelegateLinks(popup);
}
}

10 changes: 4 additions & 6 deletions src/webview.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

#include "method.h"

#include <QWebView>
#include <QWebEngineView>

struct QTabBar;
struct Query;

class WebView : public QWebView
class WebView : public QWebEngineView
{
Q_OBJECT
public:
Expand All @@ -18,7 +18,7 @@ class WebView : public QWebView
void setTabIndex(int index) { tabIndex_ = index; }
void setTabBar(QTabBar *bar) { tabBar_ = bar; }
SearchMethod method() { return method_; }
using QWebView::load;
using QWebEngineView::load;
void load(const QString &url, const Query &query);
bool loading() { return loading_; }

Expand All @@ -31,8 +31,7 @@ private slots:
void progressFinished(bool ok);
void openLink(const QUrl &url);
void openNewWin();
void copyHoveredLink(const QString &link, const QString &title,
const QString &text);
void copyHoveredLink(const QString &link);
void changeFont(const QFont &font);
void setPopupBrowser(bool);

Expand All @@ -49,7 +48,6 @@ private slots:
void changeFontSize(int delta);
QString hoveredLink;
bool loading_;
bool popupBrowser_;
SearchMethod method_;
int progressCount_;
int tabIndex_;
Expand Down

0 comments on commit 1a99a7d

Please sign in to comment.