276 lines
7.8 KiB
C++
276 lines
7.8 KiB
C++
#include "webviewwindow.h"
|
|
|
|
#include "webviewqt.h"
|
|
#include "rktwebview_qt.h"
|
|
#include "rktutils.h"
|
|
#include "command.h"
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonParseError>
|
|
#include <QJsonObject>
|
|
#include <QWebEngineScriptCollection>
|
|
#include <QWebEngineScript>
|
|
#include <QMoveEvent>
|
|
#include <QWindow>
|
|
|
|
|
|
WebviewWindow::WebviewWindow(WebviewWindow *parent)
|
|
: QMainWindow{parent}
|
|
{
|
|
_view = nullptr;
|
|
_must_close = false;
|
|
|
|
_devtools = nullptr;
|
|
_parent = parent;
|
|
|
|
_window_created = false;
|
|
_moved = 0;
|
|
_resized = 0;
|
|
|
|
if (parent != nullptr) {
|
|
setWindowModality(Qt::WindowModality::WindowModal);
|
|
setWindowFlag(Qt::WindowType::Dialog, true);
|
|
}
|
|
|
|
connect(&_resize_timer, &QTimer::timeout, this, &WebviewWindow::triggerResize);
|
|
connect(&_move_timer, &QTimer::timeout, this, &WebviewWindow::triggerMove);
|
|
}
|
|
|
|
|
|
void WebviewWindow::handleCertificate(const QWebEngineCertificateError &certificateError)
|
|
{
|
|
QList<QSslCertificate> chain = certificateError.certificateChain();
|
|
int i;
|
|
for(i = 0; i < chain.size(); i++) {
|
|
const QSslCertificate &cert = chain[i];
|
|
if (cert.isSelfSigned()) {
|
|
QStringList l = cert.issuerInfo(QSslCertificate::OrganizationalUnitName);
|
|
if (!l.empty()) {
|
|
QString ou = l[0];
|
|
if (ou != "" && ou == _ou_token) {
|
|
QWebEngineCertificateError &e = const_cast<QWebEngineCertificateError &>(certificateError);
|
|
e.acceptCertificate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void WebviewWindow::processJsEvents()
|
|
{
|
|
QWebEnginePage *p = _view->page();
|
|
p->runJavaScript("if (window.rkt_get_events) { window.rkt_get_events(); } else { JSON.stringify([]); }",
|
|
[this](const QVariant &v) {
|
|
QString s = v.toString();
|
|
QJsonParseError err;
|
|
QJsonDocument doc(QJsonDocument::fromJson(s.toUtf8(), &err));
|
|
if (err.error == QJsonParseError::NoError) {
|
|
QJsonArray a = doc.array();
|
|
int i, N;
|
|
for(i = 0, N = a.size(); i < N; i++) {
|
|
QJsonObject js_evt = a[i].toObject();
|
|
|
|
EventContainer e("js-evt");
|
|
e["js-evt"] = js_evt;
|
|
|
|
this->_container->triggerEvent(_view->id(), e);
|
|
}
|
|
} else {
|
|
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
void WebviewWindow::closeEvent(QCloseEvent *evt)
|
|
{
|
|
if (_must_close) {
|
|
EventContainer e("closed");
|
|
_container->triggerEvent(_view->id(), e);
|
|
_container->removeView(_view->id());
|
|
this->deleteLater();
|
|
if (_devtools != nullptr) {
|
|
_devtools->deleteLater();
|
|
}
|
|
} else {
|
|
evt->ignore();
|
|
EventContainer e("can-close?");
|
|
_container->triggerEvent(_view->id(), e);
|
|
}
|
|
}
|
|
|
|
void WebviewWindow::closeView()
|
|
{
|
|
_must_close = true;
|
|
close();
|
|
}
|
|
|
|
bool WebviewWindow::windowCreated()
|
|
{
|
|
return _window_created;
|
|
}
|
|
|
|
int WebviewWindow::moveCount()
|
|
{
|
|
return _moved;
|
|
}
|
|
|
|
int WebviewWindow::resizeCount()
|
|
{
|
|
return _resized;
|
|
}
|
|
|
|
void WebviewWindow::setOUToken(const QString &token)
|
|
{
|
|
_ou_token = token;
|
|
}
|
|
|
|
void WebviewWindow::addView(WebViewQt *v, Rktwebview_qt *c)
|
|
{
|
|
_container = c;
|
|
_view = v;
|
|
this->setCentralWidget(v);
|
|
|
|
QWebEnginePage *page = _view->page();
|
|
|
|
// Inject event handling code for the javascript side
|
|
QWebEngineScriptCollection &col = page->scripts();
|
|
QWebEngineScript evt_script;
|
|
evt_script.setInjectionPoint(QWebEngineScript::DocumentReady);
|
|
evt_script.setName("rkt_webview_event_handling");
|
|
evt_script.setSourceCode(
|
|
"window.rkt_event_queue = [];\n"
|
|
"window.rkt_send_event = function(obj) {\n"
|
|
" console.log('Sending event: ' + obj);\n"
|
|
" window.rkt_event_queue.push(obj);\n"
|
|
"};\n"
|
|
"window.rkt_get_events = function() {\n"
|
|
" let q = window.rkt_event_queue;\n"
|
|
" window.rkt_event_queue = [];\n"
|
|
" let json_q = JSON.stringify(q);\n"
|
|
" return json_q;\n"
|
|
"};\n"
|
|
"console.log('We have set:');\n"
|
|
"console.log('window.rkt_event_queue:');\n"
|
|
"console.log(window.rkt_event_queue);\n"
|
|
"console.log('window.rkt_send_event:');\n"
|
|
"console.log(window.rkt_send_event);\n"
|
|
"console.log('window.rkt_get_events:');\n"
|
|
"console.log(window.rkt_get_events);\n"
|
|
);
|
|
evt_script.setWorldId(QWebEngineScript::ApplicationWorld);
|
|
//col.insert(evt_script);
|
|
|
|
connect(page, &QWebEnginePage::loadFinished, this, [this](bool ok) {
|
|
_container->pageLoaded(_view->id(), ok);
|
|
});
|
|
connect(page, &QWebEnginePage::loadStarted, this, [this]() {
|
|
_container->onPageLoad(_view->id());
|
|
});
|
|
connect(page, &QWebEnginePage::certificateError, this, &WebviewWindow::handleCertificate);
|
|
}
|
|
|
|
WebViewQt *WebviewWindow::view()
|
|
{
|
|
return _view;
|
|
}
|
|
|
|
void WebviewWindow::runJs(const QString &js)
|
|
{
|
|
QWebEnginePage *p = _view->page();
|
|
p->runJavaScript(js);
|
|
}
|
|
|
|
void WebviewWindow::callJs(const QString &js, Command *c)
|
|
{
|
|
QWebEnginePage *p = _view->page();
|
|
QString _js = QString("{\n") +
|
|
" let f = function() {\n" +
|
|
" " + js + "\n" +
|
|
" };\n" +
|
|
" try {\n" +
|
|
" let obj = { oke: true, result: f(), exn: false };\n" +
|
|
" obj;\n" +
|
|
" } catch(e) {\n" +
|
|
" let obj = { oke: false, result: false, exn: e.message };\n" +
|
|
" obj;\n" +
|
|
" }\n" +
|
|
"}";
|
|
p->runJavaScript(_js, [c](const QVariant &v) {
|
|
c->result = v;
|
|
QJsonObject obj = v.toJsonObject();
|
|
bool ok = obj["oke"].toBool();
|
|
c->js_result_ok = ok;
|
|
c->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact));
|
|
c->done = true;
|
|
});
|
|
}
|
|
|
|
void WebviewWindow::openDevTools()
|
|
{
|
|
_devtools = new QMainWindow(this);
|
|
QWebEngineView *devtools_view = new QWebEngineView(_devtools);
|
|
_devtools->setCentralWidget(devtools_view);
|
|
_devtools->resize(800, 600);
|
|
_devtools->show();
|
|
_view->page()->setDevToolsPage(devtools_view->page());
|
|
connect(_devtools, &WebviewWindow::destroyed, this, [this](QObject *) {
|
|
_devtools = nullptr;
|
|
});
|
|
}
|
|
|
|
|
|
void WebviewWindow::moveEvent(QMoveEvent *event)
|
|
{
|
|
_x = event->pos().x();
|
|
_y = event->pos().y();
|
|
_move_timer.setSingleShot(true);
|
|
_move_timer.start(500);
|
|
_moved += 1;
|
|
//triggerMove();
|
|
}
|
|
|
|
void WebviewWindow::triggerMove()
|
|
{
|
|
EventContainer xy("move");
|
|
xy["x"] = _x;
|
|
xy["y"] = _y;
|
|
_container->triggerEvent(_view->id(), xy);
|
|
}
|
|
|
|
void WebviewWindow::resizeEvent(QResizeEvent *event)
|
|
{
|
|
_w = event->size().width();
|
|
_h = event->size().height();
|
|
_resize_timer.setSingleShot(true);
|
|
_resize_timer.start(500);
|
|
_resized += 1;
|
|
//triggerResize();
|
|
}
|
|
|
|
void WebviewWindow::triggerResize()
|
|
{
|
|
EventContainer s("resize");
|
|
s["w"] = _w;
|
|
s["h"] = _h;
|
|
_container->triggerEvent(_view->id(), s);
|
|
}
|
|
|
|
void WebviewWindow::showEvent(QShowEvent *event)
|
|
{
|
|
_window_created = true;
|
|
|
|
EventContainer show("show");
|
|
_container->triggerEvent(_view->id(), show);
|
|
}
|
|
|
|
void WebviewWindow::hideEvent(QHideEvent *event)
|
|
{
|
|
if (!_must_close) {
|
|
EventContainer hide("hide");
|
|
_container->triggerEvent(_view->id(), hide);
|
|
}
|
|
}
|
|
|
|
|