File indexing completed on 2024-05-19 05:01:23
0001 /* 0002 This file is part of the KDE project. 0003 0004 SPDX-FileCopyrightText: 2007 Trolltech ASA 0005 SPDX-FileCopyrightText: 2008 Urs Wolfer <uwolfer @ kde.org> 0006 SPDX-FileCopyrightText: 2008 Laurent Montel <montel@kde.org> 0007 SPDX-FileCopyrightText: 2009 Dawit Alemayehu <adawit@kde.org> 0008 0009 SPDX-License-Identifier: LGPL-2.1-or-later 0010 */ 0011 #ifndef WEBENGINEVIEW_H 0012 #define WEBENGINEVIEW_H 0013 0014 #include <QPointer> 0015 #include "kf5compat.h" //For NavigationExtension 0016 #include "qtwebengine6compat.h" //For QWebEngineContextMenuRequest 0017 #include "browserarguments.h" 0018 0019 #include <QWebEngineView> 0020 0021 class QUrl; 0022 class WebEnginePart; 0023 0024 class WebEngineView : public QWebEngineView 0025 { 0026 Q_OBJECT 0027 public: 0028 WebEngineView(WebEnginePart* part, QWidget* parent); 0029 ~WebEngineView() override; 0030 0031 /** 0032 * Same as QWebEnginePage::load, but with KParts style arguments instead. 0033 * 0034 * @see KParts::OpenUrlArguments, BrowserArguments. 0035 * 0036 * @param url the url to load. 0037 * @param args reference to a OpenUrlArguments object. 0038 * @param bargs reference to a BrowserArguments object. 0039 */ 0040 void loadUrl(const QUrl& url, const KParts::OpenUrlArguments& args, const BrowserArguments& bargs); 0041 0042 const QWebEngineContextMenuRequest* contextMenuResult() const; 0043 0044 protected: 0045 /** 0046 * Reimplemented for internal reasons, the API is not affected. 0047 * 0048 * @see QWidget::contextMenuEvent 0049 * @internal 0050 */ 0051 void contextMenuEvent(QContextMenuEvent*) override; 0052 0053 /** 0054 * @brief Improve drag and drop functionality provided by `QWebEngineView` 0055 * 0056 * Before Qt 5.15.5, `QWebEngineView` didn't allow to open remote URLs by drag and drop. This function, together with 0057 * dragEnterEvent(), dragMoveEvent() and m_dragAndDropHandledBySuperclass allow that. 0058 * 0059 * In Qt 5.15.5, `QWebEngineView` allows opening remote URLs by drag and drop, but forces doing so in a new tab. 0060 * This reimplemented method, instead, opens it in the current view. 0061 * 0062 * @note Implementing this function with the behavior of `QWebEngineView` from Qt 5.15.5 is impossible without resorting 0063 * to an ugly hack. The problem is that we can't know whether the dropped URL should actually be opened or not because there 0064 * can be pages (or part of them) where dropping an URL has a special meaning (for example, uploading a file). In this case, 0065 * this function shouldn't interfere with the base class implementation. Unfortunately, `QWebEngineView` doesn't provide any 0066 * way to find out whether the URL should be opened or if the drop had 0067 * another effect, so we always should rely only on the base class implementation, which isn't configurable. To trick it, 0068 * we use WebEnginePage::setDropOperationStarted() to tell the page that a drop operation has started: this changes the way 0069 * WebEnginePage::createWindow() works so that it returns the page itself rather than creating a new page. The main problem, 0070 * however, is that there's no way to find out when the drop operation has ended, so we have to resort to a crude heuristic 0071 * to decide when this happens (as described in WebEnginePage::setDropOperationStarted()) 0072 * 0073 * @see m_dragAndDropHandledBySuperclass 0074 * @see acceptDragMoveEventIfPossible() 0075 * @see WebEnginePage::setDropOperationStarted(): 0076 */ 0077 void dropEvent(QDropEvent *e) override; 0078 0079 #ifdef REMOTE_DND_NOT_HANDLED_BY_WEBENGINE 0080 void dragEnterEvent(QDragEnterEvent *e) override; 0081 0082 void dragMoveEvent(QDragMoveEvent *e) override; 0083 #endif 0084 0085 /** 0086 * Reimplemented for internal reasons, the API is not affected. 0087 * 0088 * @see QWidget::keyPressEvent 0089 * @internal 0090 */ 0091 void keyPressEvent(QKeyEvent*) override; 0092 0093 /** 0094 * Reimplemented for internal reasons, the API is not affected. 0095 * 0096 * @see QWidget::keyReleaseEvent 0097 * @internal 0098 */ 0099 void keyReleaseEvent(QKeyEvent*) override; 0100 0101 /** 0102 * Reimplemented for internal reasons, the API is not affected. 0103 * 0104 * @see QWidget::mouseReleaseEvent 0105 * @internal 0106 */ 0107 void mouseReleaseEvent(QMouseEvent*) override; 0108 0109 /** 0110 * Reimplemented for internal reasons, the API is not affected. 0111 * 0112 * @see QObject::timerEvent 0113 * @internal 0114 */ 0115 void timerEvent(QTimerEvent*) override; 0116 0117 /** 0118 * Reimplemented for internal reasons, the API is not affected. 0119 * 0120 * @see QWidget::wheelEvent 0121 * @internal 0122 */ 0123 void wheelEvent(QWheelEvent*) override; 0124 0125 private Q_SLOTS: 0126 void slotConfigureWebShortcuts(); 0127 void slotStopAutoScroll(); 0128 0129 private: 0130 void editableContentActionPopupMenu(KParts::NavigationExtension::ActionGroupMap&); 0131 void selectActionPopupMenu(KParts::NavigationExtension::ActionGroupMap&); 0132 void linkActionPopupMenu(KParts::NavigationExtension::ActionGroupMap&); 0133 void partActionPopupMenu(KParts::NavigationExtension::ActionGroupMap &); 0134 void multimediaActionPopupMenu(KParts::NavigationExtension::ActionGroupMap&); 0135 void addSearchActions(QList<QAction*>& selectActions, QWebEngineView*); 0136 0137 //TODO KF6: when dropping compatibility with KF5, remove these and use m_result directly 0138 QWebEngineContextMenuRequest* result(); 0139 const QWebEngineContextMenuRequest* result() const; 0140 0141 KActionCollection* m_actionCollection; 0142 #if QT_VERSION_MAJOR < 6 0143 QWebEngineContextMenuRequest m_result; 0144 #else 0145 QPointer<QWebEngineContextMenuRequest> m_result = nullptr; 0146 #endif 0147 QPointer<WebEnginePart> m_part; 0148 0149 qint32 m_autoScrollTimerId; 0150 qint32 m_verticalAutoScrollSpeed; 0151 qint32 m_horizontalAutoScrollSpeed; 0152 0153 QHash<QString, QChar> m_duplicateLinkElements; 0154 QMenu *m_spellCheckMenu; 0155 0156 #ifdef REMOTE_DND_NOT_HANDLED_BY_WEBENGINE 0157 /** 0158 * @brief Whether a drop enter or move event should be accepted even if the superclass wants to reject it 0159 * 0160 * If the event hasn't already been accepted, it contains urls and Konqueror has been configured to allow opening 0161 * remote URLs by drag & drop, the event is accepted and #m_dragAndDropHandledBySuperclass is set to @c true; 0162 * otherwise the variable is set to @c false 0163 * @note This function should only be called from dragEnterEvent() or dragMoveEvent() 0164 * 0165 * @param e the event, which should have already been passed to `QWebEngineView::dragEnterEvent` or 0166 * `QWebEngineView::dragMoveEvent`, according to which method called this. 0167 */ 0168 void acceptDragMoveEventIfPossible(QDragMoveEvent *e); 0169 0170 /** 0171 * @brief Whether a drop action should be handled by `QWebEngineView` or not 0172 * 0173 * `QWebEngineView` rejects drop actions except for some cases, in particular local URLs. However, 0174 * since its documentation doesn't explicitly tell what it accepts and what it rejects, a way to keep 0175 * trace of whether WebEngineView should handle the drop action itself or not must be used. This is 0176 * the scope of this variable: if the drop action was rejected by `QWebEngine` but accepted by 0177 * acceptDragMoveEventIfPossible, this variable is set to @c false; otherwise it's set to @c true. 0178 */ 0179 bool m_dragAndDropHandledBySuperclass = true; 0180 #endif 0181 }; 0182 0183 #endif // WEBENGINEVIEW_H