1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#include "webview.h"
#include <QContextMenuEvent>
#include <QMenu>
#include <QWebEngineContextMenuData>
#include <QWebEngineProfile>
#include <mainwindow.h>
WebView::WebView(QWidget *parent, QStringList dictionaries)
: QWebEngineView(parent) {
dictionaries = dictionaries;
QObject *parentMainWindow = this->parent();
while (!parentMainWindow->objectName().contains("MainWindow")) {
parentMainWindow = parentMainWindow->parent();
}
MainWindow *mainWindow = dynamic_cast<MainWindow *>(parentMainWindow);
connect(this, &WebView::titleChanged, mainWindow,
&MainWindow::handleWebViewTitleChanged);
connect(this, &WebView::loadFinished, mainWindow,
&MainWindow::handleLoadFinished);
connect(this, &WebView::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::StandardButton btn =
QMessageBox::question(window(), status,
tr("Render process exited with code: %1\n"
"Do you want to reload the page ?")
.arg(statusCode));
if (btn == QMessageBox::Yes)
QTimer::singleShot(0, this, [this] { this->reload(); });
});
}
void WebView::wheelEvent(QWheelEvent *event) {
bool controlKeyIsHeld =
QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
// this doesn't work, (even after checking the global QApplication keyboard
// modifiers) as expected, the Ctrl+wheel is managed by Chromium
// WebenginePage directly. So, we manage it by injecting js to page using
// WebEnginePage::injectPreventScrollWheelZoomHelper
if ((event->modifiers() & Qt::ControlModifier) != 0 || controlKeyIsHeld) {
qDebug() << "skipped ctrl + m_wheel event on webengineview";
event->ignore();
} else {
QWebEngineView::wheelEvent(event);
}
}
void WebView::contextMenuEvent(QContextMenuEvent *event) {
auto menu = page()->createStandardContextMenu();
menu->setAttribute(Qt::WA_DeleteOnClose, true);
// hide reload, back, forward, savepage, copyimagelink menus
foreach (auto *action, menu->actions()) {
if (action == page()->action(QWebEnginePage::SavePage) ||
action == page()->action(QWebEnginePage::Reload) ||
action == page()->action(QWebEnginePage::Back) ||
action == page()->action(QWebEnginePage::Forward) ||
action == page()->action(QWebEnginePage::CopyImageUrlToClipboard)) {
action->setVisible(false);
}
}
const QWebEngineContextMenuData &data = page()->contextMenuData();
Q_ASSERT(data.isValid());
// allow context menu on image
if (data.mediaType() == QWebEngineContextMenuData::MediaTypeImage) {
QWebEngineView::contextMenuEvent(event);
return;
}
// if content is not editable
if (data.selectedText().isEmpty() && !data.isContentEditable()) {
event->ignore();
return;
}
auto pageWebengineProfile = page()->profile();
const QStringList &languages = pageWebengineProfile->spellCheckLanguages();
menu->addSeparator();
auto *spellcheckAction = new QAction(tr("Check Spelling"), menu);
spellcheckAction->setCheckable(true);
spellcheckAction->setChecked(pageWebengineProfile->isSpellCheckEnabled());
connect(spellcheckAction, &QAction::toggled, this,
[pageWebengineProfile, this](bool toogled) {
pageWebengineProfile->setSpellCheckEnabled(toogled);
settings.setValue("sc_enabled", toogled);
});
menu->addAction(spellcheckAction);
if (pageWebengineProfile->isSpellCheckEnabled()) {
auto subMenu = menu->addMenu(tr("Select Language"));
for (const QString &dict : qAsConst(dictionaries)) {
auto action = subMenu->addAction(dict);
action->setCheckable(true);
action->setChecked(languages.contains(dict));
connect(action, &QAction::triggered, this, [pageWebengineProfile, dict, this]() {
pageWebengineProfile->setSpellCheckLanguages(QStringList() << dict);
settings.setValue("sc_dict", dict);
});
}
}
connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
menu->popup(event->globalPos());
}
|