File indexing completed on 2024-04-21 04:58:20

0001 /*
0002     SPDX-FileCopyrightText: 2009 David Faure <faure@kde.org>
0003     SPDX-FileCopyrightText: 2016 Anthony Fieroni <bvbfan@abv.bg>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "konqmouseeventfilter.h"
0009 #include "konqframe.h"
0010 #include "konqview.h"
0011 #include "konqmainwindow.h"
0012 #include "konqsettingsxt.h"
0013 
0014 #include <QApplication>
0015 #include <QMouseEvent>
0016 
0017 class KonqMouseEventFilterSingleton
0018 {
0019 public:
0020     KonqMouseEventFilter self;
0021 };
0022 
0023 Q_GLOBAL_STATIC(KonqMouseEventFilterSingleton, globalMouseEventFilter)
0024 
0025 KonqMouseEventFilter *KonqMouseEventFilter::self()
0026 {
0027     return &globalMouseEventFilter->self;
0028 }
0029 
0030 KonqMouseEventFilter::KonqMouseEventFilter()
0031     : QObject(nullptr)
0032 {
0033     reparseConfiguration();
0034     qApp->installEventFilter(this);
0035 }
0036 
0037 static KonqMainWindow* parentWindow(QWidget *w)
0038 {
0039     KonqFrame *frame = nullptr;
0040     while (w && !frame) {
0041         w = w->parentWidget(); // yes this fails if the initial widget itself is a KonqFrame, but this can't happen
0042         frame = qobject_cast<KonqFrame *>(w);
0043     }
0044     if (!frame) {
0045         return nullptr;
0046     }
0047     if (auto view = frame->childView()) {
0048         return view->mainWindow();
0049     }
0050     return nullptr;
0051 }
0052 
0053 bool KonqMouseEventFilter::eventFilter(QObject *obj, QEvent *e)
0054 {
0055     const int type = e->type();
0056     switch (type) {
0057     case QEvent::MouseButtonPress:
0058         switch (static_cast<QMouseEvent*>(e)->button()) {
0059         case Qt::RightButton:
0060             if (m_bBackRightClick) {
0061                 return true;
0062             }
0063             break;
0064         case Qt::ForwardButton:
0065             if (auto window = parentWindow(qobject_cast<QWidget*>(obj))) {
0066                 window->slotForward();
0067                 return true;
0068             }
0069             break;
0070         case Qt::BackButton:
0071             if (auto window = parentWindow(qobject_cast<QWidget*>(obj))) {
0072                 window->slotBack();
0073                 return true;
0074             }
0075             break;
0076         default:
0077             break;
0078         }
0079         break;
0080     case QEvent::MouseButtonRelease:
0081         if (!m_bBackRightClick) {
0082             break;
0083         }
0084         if (static_cast<QMouseEvent*>(e)->button() == Qt::RightButton) {
0085             if (auto window = parentWindow(qobject_cast<QWidget*>(obj))) {
0086                 window->slotBack();
0087                 return true;
0088             }
0089         }
0090         break;
0091     case QEvent::MouseMove: {
0092         QMouseEvent *ev = static_cast<QMouseEvent*>(e);
0093         if (m_bBackRightClick && ev->buttons() & Qt::RightButton) {
0094             qApp->removeEventFilter(this);
0095             QMouseEvent me(QEvent::MouseButtonPress, ev->pos(), Qt::RightButton, Qt::RightButton, Qt::NoModifier);
0096             QApplication::sendEvent(obj, &me);
0097             QContextMenuEvent ce(QContextMenuEvent::Mouse, ev->pos(), ev->globalPos());
0098             QApplication::sendEvent(obj, &ce);
0099             qApp->installEventFilter(this);
0100         }
0101         break;
0102     }
0103     case QEvent::ContextMenu: {
0104         QContextMenuEvent *ev = static_cast<QContextMenuEvent*>(e);
0105         if (m_bBackRightClick && ev->reason() == QContextMenuEvent::Mouse) {
0106             return true;
0107         }
0108         break;
0109     }
0110     default:
0111         break;
0112     }
0113 
0114     return false;
0115 }
0116 
0117 void KonqMouseEventFilter::reparseConfiguration()
0118 {
0119     m_bBackRightClick = KonqSettings::backRightClick();
0120 }