[education/rkward/kf5] rkward: Port away from QtWebkit completely
Thomas Friedrichsmeier
null at kde.org
Wed Apr 10 16:12:08 BST 2024
Git commit de620b291c766c30beaa15565417dc2f01699290 by Thomas Friedrichsmeier, on behalf of Carl Schwan.
Committed on 01/04/2024 at 11:45.
Pushed by tfry into branch 'kf5'.
Port away from QtWebkit completely
Not available anymore with Qt6
M +0 -6 rkward/main.cpp
M +0 -4 rkward/rbackend/rksessionvars.cpp
M +37 -141 rkward/windows/rkhtmlwindow.cpp
https://invent.kde.org/education/rkward/-/commit/de620b291c766c30beaa15565417dc2f01699290
diff --git a/rkward/main.cpp b/rkward/main.cpp
index 46cbad8ba..83dbe592f 100644
--- a/rkward/main.cpp
+++ b/rkward/main.cpp
@@ -224,21 +224,15 @@ QString resolveRSpecOrFail (QString input, const QString &message) {
return QString(); // not reached
}
-#ifndef NO_QT_WEBENGINE
#include <QWebEngineUrlScheme>
-#endif
int main (int argc, char *argv[]) {
RK_Debug::RK_Debug_Level = DL_WARNING;
- QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
-#ifndef NO_QT_WEBENGINE
// annoyingly, QWebEngineUrlSchemes have to be registered before creating the app.
QWebEngineUrlScheme scheme("help");
scheme.setSyntax (QWebEngineUrlScheme::Syntax::Path);
scheme.setFlags (QWebEngineUrlScheme::LocalScheme|QWebEngineUrlScheme::LocalAccessAllowed);
QWebEngineUrlScheme::registerScheme (scheme);
-#endif
QApplication app (argc, argv);
#ifdef WITH_KCRASH
KCrash::setDrKonqiEnabled (true);
diff --git a/rkward/rbackend/rksessionvars.cpp b/rkward/rbackend/rksessionvars.cpp
index ba536325d..05b70ef0c 100644
--- a/rkward/rbackend/rksessionvars.cpp
+++ b/rkward/rbackend/rksessionvars.cpp
@@ -90,11 +90,7 @@ QStringList RKSessionVars::frontendSessionInfo () {
lines.append ("KDE Frameworks version (compile time): " KCOREADDONS_VERSION_STRING);
lines.append (QString ("Qt version (runtime): ") + qVersion ());
lines.append ("Qt version (compile time): " QT_VERSION_STR);
-#ifdef NO_QT_WEBENGINE
- lines.append ("Using QtWebKit for HTML rendering");
-#else
lines.append ("Using QWebEngine for HTML rendering");
-#endif
#if defined Q_OS_WIN
lines.append ("Windows runtime version (refer to QSysInfo documentation to translate code into human readable form): 0x" + QString::number (QSysInfo::windowsVersion (), 16));
#elif defined Q_OS_MACOS
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index 094e7d90e..d22730345 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -7,8 +7,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
#include "rkhtmlwindow.h"
#include <KLocalizedString>
-#include <kmessagebox.h>
-#include <kparts/plugin.h>
+#include <KMessageBox>
#include <kactioncollection.h>
#include <kdirwatch.h>
#include <kio/job.h>
@@ -22,8 +21,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
#include <qfileinfo.h>
#include <qwidget.h>
#include <qlayout.h>
-#include <qtimer.h>
-#include <qdir.h>
+#include <QTimer>
+#include <QDir>
#include <QHBoxLayout>
#include <QHostInfo>
#include <QPrintDialog>
@@ -37,6 +36,18 @@ SPDX-License-Identifier: GPL-2.0-or-later
#include <QMimeDatabase>
#include <QCheckBox>
#include <QFileDialog>
+#include <QStringEncoder>
+#include <QWebEngineUrlSchemeHandler>
+#include <QWebEngineUrlRequestJob>
+#include <QBuffer>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+#include <QWebEngineSettings>
+#include <QWebEngineProfile>
+#include <QWebEngineScript>
+#include <QWebEngineScriptCollection>
+#include <QWheelEvent>
+#include <QWebEngineFindTextResult>
#include "../rbackend/rkrinterface.h"
#include "rkhelpsearchwindow.h"
@@ -66,76 +77,23 @@ QUrl restorableUrl(const QUrl &url) {
return QUrl(url.url().replace(RKSettingsModuleR::helpBaseUrl(), "rkward://RHELPBASE"));
}
-#ifdef NO_QT_WEBENGINE
-# include <QWebFrame>
-# include <QNetworkRequest>
-# include <kwebpage.h>
-# include <kwebview.h>
-class RKWebPage : public KWebPage {
-#else
-# include <QWebEnginePage>
-# include <QWebEngineView>
-# include <QWebEngineSettings>
-# include <QWebEngineProfile>
-# include <QWebEngineScript>
-# include <QWebEngineScriptCollection>
class RKWebPage : public QWebEnginePage {
-#endif
Q_OBJECT
public:
-#ifdef NO_QT_WEBENGINE
-// NOTE: According to an earlier note at this place, KIOIntegration used to be very buggy around KF5 5.9.0. It seem to just work,
-// at 5.44.0, and the symptoms are probably not terrible for earlier versions, so we use it here (allows us to render help:/-pages
-// inside the help window.
- explicit RKWebPage (RKHTMLWindow* window): KWebPage (window, KPartsIntegration | KIOIntegration) {
-#else
explicit RKWebPage (RKHTMLWindow* window): QWebEnginePage (window) {
-#endif
RK_TRACE (APP);
RKWebPage::window = window;
direct_load = false;
-#ifdef NO_QT_WEBENGINE
- settings ()->setFontFamily (QWebSettings::StandardFont, QFontDatabase::systemFont(QFontDatabase::GeneralFont).family ());
- settings ()->setFontFamily (QWebSettings::FixedFont, QFontDatabase::systemFont(QFontDatabase::FixedFont).family ());
-#else
settings ()->setFontFamily (QWebEngineSettings::StandardFont, QFontDatabase::systemFont(QFontDatabase::GeneralFont).family ());
settings ()->setFontFamily (QWebEngineSettings::FixedFont, QFontDatabase::systemFont(QFontDatabase::FixedFont).family ());
-#endif
}
void load (const QUrl& url) {
RK_TRACE (APP);
direct_load = true;
-#ifdef NO_QT_WEBENGINE
- mainFrame ()->load (url);
-#else
QWebEnginePage::load (url);
-#endif
}
-#ifdef NO_QT_WEBENGINE
- QUrl url () {
- return mainFrame ()->url ();
- }
- void setHtmlWrapper(const QString &html, const QUrl &baseurl) {
- direct_load = true;
- mainFrame()->setHtml(html, baseurl);
- }
- QPointF scrollPosition () const {
- return mainFrame ()->scrollPosition ();
- }
- void setScrollPosition (const QPoint &pos) {
- mainFrame ()->setScrollPosition (pos);
- }
- void setScrollPositionWhenDone(const QPoint &pos) {
- QMetaObject::Connection * const connection = new QMetaObject::Connection;
- *connection = connect(this, &QWebPage::loadFinished, [this, pos, connection](){
- QObject::disconnect(*connection);
- delete connection;
- setScrollPosition(pos);
- });
- }
-#else
void setHtmlWrapper(const QString &html, const QUrl &baseurl) {
direct_load = true;
setHtml(html, baseurl);
@@ -159,21 +117,12 @@ public:
setScrollPosition(pos);
});
}
-#endif
Q_SIGNALS:
void pageInternalNavigation (const QUrl& url);
protected:
-#ifdef NO_QT_WEBENGINE
-/** reimplemented to always Q_EMIT linkClicked() for pages that need special handling (importantly, rkward://-urls). */
- bool acceptNavigationRequest (QWebFrame* frame, const QNetworkRequest& request, QWebPage::NavigationType type) override {
- QUrl navurl = request.url ();
- QUrl cururl (mainFrame ()->url ());
- bool is_main_frame = frame == mainFrame ();
-#else
bool acceptNavigationRequest (const QUrl &navurl, QWebEnginePage::NavigationType type, bool is_main_frame) override {
QUrl cururl (url ());
-#endif
Q_UNUSED (type);
RK_TRACE (APP);
@@ -207,16 +156,10 @@ protected:
return false;
}
-#ifdef NO_QT_WEBENGINE
-/** reimplemented to schedule new window creation for the next page to load */
- QWebPage* createWindow (QWebPage::WebWindowType) override {
-#else
QWebEnginePage* createWindow (QWebEnginePage::WebWindowType) override {
-#endif
RK_TRACE (APP);
RKWebPage *ret = new RKWebPage (nullptr);
RKHTMLWindow::new_window = ret; // Don't actually create a full window, until we know which URL we're talking about.
-#ifndef NO_QT_WEBENGINE
// sigh: acceptNavigationRequest() does not get called on the new page...
QMetaObject::Connection * const connection = new QMetaObject::Connection;
*connection = connect (ret, &RKWebPage::loadStarted, [ret, connection
@@ -228,7 +171,6 @@ protected:
delete connection;
ret->acceptNavigationRequest (ret->url (), QWebEnginePage::NavigationTypeLinkClicked, true);
});
-#endif
return (ret);
}
@@ -237,18 +179,12 @@ friend class RKHTMLWindow;
bool direct_load;
};
-#ifdef NO_QT_WEBENGINE
-class RKWebView : public KWebView {
-public:
- RKWebView (QWidget *parent) : KWebView (parent, false) {};
-#else
-#include <QWheelEvent>
class RKWebView : public QWebEngineView {
public:
RKWebView (QWidget *parent) : QWebEngineView (parent) {};
void print (QPrinter *printer) {
if (!page ()) return;
- page ()->print (printer, [](bool){});
+ QWebEngineView::forPage(page ())->print (printer);
};
protected:
bool eventFilter(QObject *, QEvent *event) override {
@@ -270,13 +206,8 @@ protected:
/* void wheelEvent (QWheelEvent *event) override {
[handle zooming]
} */
-#endif
};
-#ifndef NO_QT_WEBENGINE
-#include <QWebEngineUrlSchemeHandler>
-#include <QWebEngineUrlRequestJob>
-#include <QBuffer>
class RKWebEngineKIOForwarder : public QWebEngineUrlSchemeHandler {
public:
RKWebEngineKIOForwarder (QObject *parent) : QWebEngineUrlSchemeHandler (parent) {}
@@ -301,14 +232,13 @@ private:
}
QMap<KIO::StoredTransferJob*,QPointer<QWebEngineUrlRequestJob>> jobs;
};
-#endif
RKWebPage* RKHTMLWindow::new_window = nullptr;
RKHTMLWindow::RKHTMLWindow (QWidget *parent, WindowMode mode) : RKMDIWindow (parent, RKMDIWindow::HelpWindow) {
RK_TRACE (APP);
- current_cache_file = 0;
+ current_cache_file = nullptr;
QVBoxLayout* layout = new QVBoxLayout (this);
layout->setContentsMargins (0, 0, 0, 0);
view = new RKWebView (this);
@@ -322,15 +252,11 @@ RKHTMLWindow::RKHTMLWindow (QWidget *parent, WindowMode mode) : RKMDIWindow (par
view->setPage (page);
view->setContextMenuPolicy (Qt::CustomContextMenu);
layout->addWidget (view, 1);
-#ifdef NO_QT_WEBENGINE
- findbar = new RKFindBar (this);
-#else
findbar = new RKFindBar (this, true);
findbar->setPrimaryOptions (QList<QWidget*>() << findbar->getOption (RKFindBar::FindAsYouType) << findbar->getOption (RKFindBar::MatchCase));
if (!QWebEngineProfile::defaultProfile ()->urlSchemeHandler ("help")) {
QWebEngineProfile::defaultProfile ()->installUrlSchemeHandler ("help", new RKWebEngineKIOForwarder (RKWardMainWindow::getMain()));
}
-#endif
// Apply current color scheme to page. This needs support in the CSS of the page, so will only work for RKWard help and output pages.
// Note that the CSS in those pages also has "automatic" support for dark mode ("prefers-color-scheme: dark"; but see https://bugreports.qt.io/browse/QTBUG-89753), however,
// for a seamless appearance, the only option is to set the theme colors dynamically, via javascript.
@@ -343,21 +269,18 @@ RKHTMLWindow::RKHTMLWindow (QWidget *parent, WindowMode mode) : RKMDIWindow (par
"rksetcolor('--shadow-color', '%5');").arg(scheme->foreground().color().name(), scheme->background().color().name(),
scheme->foreground(KColorScheme::VisitedText).color().name(), scheme->foreground(KColorScheme::LinkText).color().name(),
scheme->shade(KColorScheme::MidShade).name());
-#ifdef NO_QT_WEBENGINE
- connect(page, &RKWebPage::loadFinished, [this, color_scheme_js](){
- page->mainFrame()->evaluateJavaScript(color_scheme_js);
- });
-#else
auto p = QWebEngineProfile::defaultProfile();
QWebEngineScript fix_color_scheme;
- QString id = QStringLiteral("fix_color_scheme");
- p->scripts()->remove(p->scripts()->findScript(id)); // remove any existing variant of the script. It might have been created for the wrong theme.
+ const QString id = QStringLiteral("fix_color_scheme");
+ const auto scripts = p->scripts()->find(id);
+ for (const auto &script : scripts) {
+ p->scripts()->remove(script); // remove any existing variant of the script. It might have been created for the wrong theme.
+ }
fix_color_scheme.setName(id);
fix_color_scheme.setInjectionPoint(QWebEngineScript::DocumentReady);
fix_color_scheme.setSourceCode(color_scheme_js);
p->scripts()->insert(fix_color_scheme);
//page->setBackgroundColor(scheme.background().color()); // avoids brief white blink while loading, but is too risky on pages that are not dark scheme aware.
-#endif
layout->addWidget (findbar);
findbar->hide ();
@@ -368,36 +291,22 @@ RKHTMLWindow::RKHTMLWindow (QWidget *parent, WindowMode mode) : RKMDIWindow (par
setPart (part);
part->initActions ();
initializeActivationSignals ();
-#if KPARTS_VERSION < QT_VERSION_CHECK(5, 72, 0)
- part->setSelectable (true);
-#endif
setFocusPolicy (Qt::StrongFocus);
setFocusProxy (view);
// We have to connect this in order to allow browsing.
connect (page, &RKWebPage::pageInternalNavigation, this, &RKHTMLWindow::internalNavigation);
-#ifdef NO_QT_WEBENGINE
- connect (page, &QWebPage::downloadRequested, [this](const QNetworkRequest &request) { page->downloadUrl (request.url ()); });
-#else
- connect (page->profile (), &QWebEngineProfile::downloadRequested, this, [this](QWebEngineDownloadItem* item) {
+ connect (page->profile (), &QWebEngineProfile::downloadRequested, this, [this](QWebEngineDownloadRequest* item) {
QString defpath;
-#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
defpath = QDir(item->downloadDirectory()).absoluteFilePath(item->downloadFileName());
-#else
- defpath = item->path();
-#endif
QString path = QFileDialog::getSaveFileName(this, i18n("Save as"), defpath);
if (path.isEmpty()) return;
-#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QFileInfo fi(path);
item->setDownloadDirectory(fi.absolutePath());
item->setDownloadFileName(fi.fileName());
-#else
- item->setPath(path);
-#endif
item->accept();
});
-#endif
+
connect (page, &RKWebPage::printRequested, this, &RKHTMLWindow::slotPrint);
connect (view, &QWidget::customContextMenuRequested, this, &RKHTMLWindow::makeContextMenu);
@@ -431,7 +340,7 @@ bool RKHTMLWindow::isModified () {
void RKHTMLWindow::makeContextMenu (const QPoint& pos) {
RK_TRACE (APP);
- QMenu *menu = page->createStandardContextMenu ();
+ QMenu *menu = QWebEngineView::forPage(page)->createStandardContextMenu ();
menu->addAction (part->run_selection);
menu->exec (view->mapToGlobal (pos));
delete (menu);
@@ -457,26 +366,16 @@ void RKHTMLWindow::runSelection () {
void RKHTMLWindow::findRequest (const QString& text, bool backwards, const RKFindBar* findbar, bool* found) {
RK_TRACE (APP);
-#ifdef NO_QT_WEBENGINE
- QWebPage::FindFlags flags = QWebPage::FindWrapsAroundDocument;
- if (backwards) flags |= QWebPage::FindBackward;
- bool highlight = findbar->isOptionSet (RKFindBar::HighlightAll);
- if (highlight) flags |= QWebPage::HighlightAllOccurrences;
- if (findbar->isOptionSet (RKFindBar::MatchCase)) flags |= QWebPage::FindCaseSensitively;
-
- // clear previous highlight, if any
- if (have_highlight) page->findText (QString (), QWebPage::HighlightAllOccurrences);
-
- *found = page->findText (text, flags);
- have_highlight = found && highlight;
-#else
// QWebEngine does not offer highlight all
*found = true;
QWebEnginePage::FindFlags flags;
if (backwards) flags |= QWebEnginePage::FindBackward;
if (findbar->isOptionSet (RKFindBar::MatchCase)) flags |= QWebEnginePage::FindCaseSensitively;
- page->findText (text, flags, [this](bool found) { if (!found) this->findbar->indicateSearchFail(); });
-#endif
+ page->findText (text, flags, [this](QWebEngineFindTextResult result) {
+ if (result.numberOfMatches() == 0) {
+ this->findbar->indicateSearchFail();
+ }
+ });
}
@@ -858,11 +757,7 @@ void RKHTMLWindow::scrollToBottom () {
RK_TRACE (APP);
RK_ASSERT (window_mode == HTMLOutputWindow);
-#ifdef NO_QT_WEBENGINE
- page->mainFrame ()->setScrollBarValue (Qt::Vertical, view->page ()->mainFrame ()->scrollBarMaximum (Qt::Vertical));
-#else
page->runJavaScript(QString("{ let se = (document.scrollingElement || document.body); se.scrollTop = se.scrollHeight; }"));
-#endif
}
void RKHTMLWindow::zoomIn () {
@@ -875,10 +770,11 @@ void RKHTMLWindow::zoomOut () {
view->setZoomFactor (view->zoomFactor () / 1.1);
}
-void RKHTMLWindow::setTextEncoding (QTextCodec* encoding) {
+void RKHTMLWindow::setTextEncoding (QStringConverter::Encoding encoding) {
RK_TRACE (APP);
- page->settings ()->setDefaultTextEncoding (encoding->name ());
+ QStringEncoder converter(encoding);
+ page->settings ()->setDefaultTextEncoding (converter.name ());
view->reload ();
}
@@ -1312,7 +1208,7 @@ QString RKHelpRenderer::renderHelpFragment (QDomElement &fragment) {
int npos;
QString ret;
while ((npos = text.indexOf ("<link", pos)) >= 0) {
- ret += text.midRef(pos, npos - pos);
+ ret += QStringView{text}.mid(pos, npos - pos);
QString href;
int href_start = text.indexOf (" href=\"", npos + 5);
@@ -1332,14 +1228,14 @@ QString RKHelpRenderer::renderHelpFragment (QDomElement &fragment) {
ret += prepareHelpLink (href, linktext);
pos = end;
}
- ret += text.midRef(pos);
+ ret += QStringView{text}.mid(pos);
if (component_xml) {
text = ret;
ret.clear ();
pos = 0;
while ((npos = text.indexOf ("<label ", pos)) >= 0) {
- ret += text.midRef(pos, npos - pos);
+ ret += QStringView{text}.mid(pos, npos - pos);
QString id;
int id_start = text.indexOf ("id=\"", npos + 6);
@@ -1351,7 +1247,7 @@ QString RKHelpRenderer::renderHelpFragment (QDomElement &fragment) {
}
ret += resolveLabel (id);
}
- ret += text.midRef(pos);
+ ret += QStringView{text}.mid(pos);
}
RK_DEBUG (APP, DL_DEBUG, "%s", qPrintable (ret));
More information about the rkward-tracker
mailing list