aboutsummaryrefslogtreecommitdiff
path: root/src/webview.cpp
blob: 38de33022e0faa26637dc076e9b888b666a5b5f5 (plain) (blame)
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
#include "webview.h"

#include <QContextMenuEvent>
#include <QMenu>
#include <QWebEngineContextMenuData>
#include <QWebEngineProfile>
#include <mainwindow.h>

WebView::WebView(QWidget *parent, QStringList dictionaries)
    : QWebEngineView(parent) {
  m_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::contextMenuEvent(QContextMenuEvent *event) {

  QMenu *menu = page()->createStandardContextMenu();
  // 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;
  }

  QWebEngineProfile *profile = page()->profile();
  const QStringList &languages = profile->spellCheckLanguages();

  menu->addSeparator();

  QAction *spellcheckAction = new QAction(tr("Check Spelling"), menu);
  spellcheckAction->setCheckable(true);
  spellcheckAction->setChecked(profile->isSpellCheckEnabled());
  connect(spellcheckAction, &QAction::toggled, this,
          [profile, this](bool toogled) {
            profile->setSpellCheckEnabled(toogled);
            settings.setValue("sc_enabled", toogled);
          });
  menu->addAction(spellcheckAction);

  if (profile->isSpellCheckEnabled()) {
    QMenu *subMenu = menu->addMenu(tr("Select Language"));
    for (const QString &dict : qAsConst(m_dictionaries)) {
      QAction *action = subMenu->addAction(dict);
      action->setCheckable(true);
      action->setChecked(languages.contains(dict));
      connect(action, &QAction::triggered, this, [profile, dict, this]() {
        profile->setSpellCheckLanguages(QStringList() << dict);
        settings.setValue("sc_dict", dict);
      });
    }
  }
  connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
  menu->popup(event->globalPos());
}