/src/webview.cpp

https://github.com/kiwix/kiwix-desktop · C++ · 145 lines · 131 code · 12 blank · 2 comment · 36 complexity · 99dbdb18f78bb491f17fc7187ba620a4 MD5 · raw file

  1. #include "webview.h"
  2. #include <QDesktopServices>
  3. #include <QMenu>
  4. #include <QAction>
  5. #include <iostream>
  6. #include "kiwixapp.h"
  7. #include "webpage.h"
  8. #include <QToolTip>
  9. #include <QWebEngineSettings>
  10. #include <QVBoxLayout>
  11. WebView::WebView(QWidget *parent)
  12. : QWebEngineView(parent)
  13. {
  14. setPage(new WebPage(this));
  15. QObject::connect(this, &QWebEngineView::urlChanged, this, &WebView::onUrlChanged);
  16. connect(this->page(), &QWebEnginePage::linkHovered, this, [=] (const QString& url) {
  17. m_linkHovered = url;
  18. });
  19. }
  20. WebView::~WebView()
  21. {}
  22. bool WebView::isWebActionEnabled(QWebEnginePage::WebAction webAction) const
  23. {
  24. return page()->action(webAction)->isEnabled();
  25. }
  26. QWebEngineView* WebView::createWindow(QWebEnginePage::WebWindowType type)
  27. {
  28. if ( type==QWebEnginePage::WebBrowserBackgroundTab
  29. || type==QWebEnginePage::WebBrowserTab )
  30. {
  31. auto tabWidget = KiwixApp::instance()->getTabWidget();
  32. return tabWidget->createNewTab(false, true)->getWebView();
  33. }
  34. return nullptr;
  35. }
  36. void WebView::onUrlChanged(const QUrl& url) {
  37. auto zimId = url.host().split('.')[0];
  38. if (m_currentZimId == zimId ) {
  39. return;
  40. }
  41. m_currentZimId = zimId;
  42. emit zimIdChanged(m_currentZimId);
  43. auto app = KiwixApp::instance();
  44. auto reader = app->getLibrary()->getReader(m_currentZimId);
  45. if (!reader) {
  46. return;
  47. }
  48. std::string favicon, _mimetype;
  49. reader->getFavicon(favicon, _mimetype);
  50. QPixmap pixmap;
  51. pixmap.loadFromData((const uchar*)favicon.data(), favicon.size());
  52. m_icon = QIcon(pixmap);
  53. emit iconChanged(m_icon);
  54. auto zoomFactor = app->getSettingsManager()->getZoomFactorByZimId(zimId);
  55. this->setZoomFactor(zoomFactor);
  56. }
  57. void WebView::wheelEvent(QWheelEvent *event) {
  58. if ((event->modifiers() & Qt::ControlModifier) != 0)
  59. {
  60. if (event->angleDelta().y() > 0) {
  61. KiwixApp::instance()->getAction(KiwixApp::ZoomInAction)->activate(QAction::Trigger);
  62. } else if (event->angleDelta().y() < 0) {
  63. KiwixApp::instance()->getAction(KiwixApp::ZoomOutAction)->activate(QAction::Trigger);
  64. }
  65. }
  66. }
  67. void WebView::contextMenuEvent(QContextMenuEvent *event)
  68. {
  69. auto menu = this->page()->createStandardContextMenu();
  70. pageAction(QWebEnginePage::OpenLinkInNewWindow)->setVisible(false);
  71. if (!m_linkHovered.isEmpty()) {
  72. if (!m_linkHovered.startsWith("zim://")) {
  73. pageAction(QWebEnginePage::OpenLinkInNewTab)->setVisible(false);
  74. auto openLinkInWebBrowserAction = new QAction(gt("open-link-in-web-browser"));
  75. menu->insertAction(pageAction(QWebEnginePage::DownloadLinkToDisk) , openLinkInWebBrowserAction);
  76. connect(menu, &QObject::destroyed, openLinkInWebBrowserAction, &QObject::deleteLater);
  77. connect(openLinkInWebBrowserAction, &QAction::triggered, this, [=](bool checked) {
  78. Q_UNUSED(checked);
  79. QDesktopServices::openUrl(m_linkHovered);
  80. });
  81. } else {
  82. pageAction(QWebEnginePage::OpenLinkInNewTab)->setVisible(true);
  83. }
  84. }
  85. menu->exec(event->globalPos());
  86. }
  87. bool WebView::eventFilter(QObject *src, QEvent *e)
  88. {
  89. Q_UNUSED(src)
  90. // work around QTBUG-43602
  91. if (e->type() == QEvent::Wheel) {
  92. auto we = static_cast<QWheelEvent *>(e);
  93. if (we->modifiers() == Qt::ControlModifier)
  94. return true;
  95. }
  96. if (e->type() == QEvent::MouseButtonRelease) {
  97. auto me = static_cast<QMouseEvent *>(e);
  98. if (!m_linkHovered.startsWith("zim://")
  99. && (me->modifiers() == Qt::ControlModifier || me->button() == Qt::MiddleButton))
  100. {
  101. QDesktopServices::openUrl(m_linkHovered);
  102. return true;
  103. }
  104. if (me->button() == Qt::BackButton)
  105. {
  106. back();
  107. return true;
  108. }
  109. if (me->button() == Qt::ForwardButton)
  110. {
  111. forward();
  112. return true;
  113. }
  114. }
  115. return false;
  116. }
  117. bool WebView::event(QEvent *event)
  118. {
  119. // work around QTBUG-43602
  120. if (event->type() == QEvent::ChildAdded) {
  121. auto ce = static_cast<QChildEvent *>(event);
  122. ce->child()->installEventFilter(this);
  123. } else if (event->type() == QEvent::ChildRemoved) {
  124. auto ce = static_cast<QChildEvent *>(event);
  125. ce->child()->removeEventFilter(this);
  126. }
  127. if (event->type() == QEvent::ToolTip) {
  128. return true;
  129. } else {
  130. return QWebEngineView::event(event);
  131. }
  132. return true;
  133. }