File indexing completed on 2024-05-19 04:59:17

0001 /* ============================================================
0002 * Mouse Gestures plugin for Falkon
0003 * Copyright (C) 2013-2017 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "mousegestures.h"
0019 #include "webpage.h"
0020 #include "tabbedwebview.h"
0021 #include "tabwidget.h"
0022 #include "mainapplication.h"
0023 #include "browserwindow.h"
0024 #include "locationbar.h"
0025 #include "mousegesturessettingsdialog.h"
0026 
0027 #include "QjtMouseGestureFilter.h"
0028 #include "QjtMouseGesture.h"
0029 
0030 #include <QMouseEvent>
0031 #include <QWebEngineHistory>
0032 #include <QSettings>
0033 
0034 MouseGestures::MouseGestures(const QString &settingsPath, QObject* parent)
0035     : QObject(parent)
0036     , m_filter(nullptr)
0037     , m_settingsFile(settingsPath + QL1S("/extensions.ini"))
0038     , m_button(Qt::MiddleButton)
0039 {
0040     loadSettings();
0041 }
0042 
0043 void MouseGestures::initFilter()
0044 {
0045     if (m_filter) {
0046         m_filter->clearGestures(true);
0047         delete m_filter;
0048     }
0049 
0050     m_filter = new QjtMouseGestureFilter(false, m_button, 20);
0051 
0052     auto* upGesture = new QjtMouseGesture(DirectionList() << Up, m_filter);
0053     connect(upGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upGestured);
0054 
0055     auto* downGesture = new QjtMouseGesture(DirectionList() << Down, m_filter);
0056     connect(downGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downGestured);
0057 
0058     auto* leftGesture = new QjtMouseGesture(DirectionList() << Left, m_filter);
0059     connect(leftGesture, &QjtMouseGesture::gestured, this, &MouseGestures::leftGestured);
0060 
0061     auto* rightGesture = new QjtMouseGesture(DirectionList() << Right, m_filter);
0062     connect(rightGesture, &QjtMouseGesture::gestured, this, &MouseGestures::rightGestured);
0063 
0064     auto* downRightGesture = new QjtMouseGesture(DirectionList() << Down << Right, m_filter);
0065     connect(downRightGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downRightGestured);
0066 
0067     auto* downLeftGesture = new QjtMouseGesture(DirectionList() << Down << Left, m_filter);
0068     connect(downLeftGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downLeftGestured);
0069 
0070     auto* downUpGesture = new QjtMouseGesture(DirectionList() << Down << Up, m_filter);
0071     connect(downUpGesture, &QjtMouseGesture::gestured, this, &MouseGestures::downUpGestured);
0072 
0073     auto* upDownGesture = new QjtMouseGesture(DirectionList() << Up << Down, m_filter);
0074     connect(upDownGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upDownGestured);
0075 
0076     auto* upLeftGesture = new QjtMouseGesture(DirectionList() << Up << Left, m_filter);
0077     connect(upLeftGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upLeftGestured);
0078 
0079     auto* upRightGesture = new QjtMouseGesture(DirectionList() << Up << Right, m_filter);
0080     connect(upRightGesture, &QjtMouseGesture::gestured, this, &MouseGestures::upRightGestured);
0081 
0082     m_filter->addGesture(upGesture);
0083     m_filter->addGesture(downGesture);
0084     m_filter->addGesture(leftGesture);
0085     m_filter->addGesture(rightGesture);
0086 
0087     m_filter->addGesture(downRightGesture);
0088     m_filter->addGesture(downLeftGesture);
0089     m_filter->addGesture(downUpGesture);
0090     m_filter->addGesture(upDownGesture);
0091     m_filter->addGesture(upLeftGesture);
0092     m_filter->addGesture(upRightGesture);
0093 }
0094 
0095 bool MouseGestures::mousePress(QObject* obj, QMouseEvent* event)
0096 {
0097     m_view = qobject_cast<WebView*>(obj);
0098 
0099     if (m_enableRockerNavigation && event->buttons() == (Qt::RightButton | Qt::LeftButton)) {
0100         bool accepted = false;
0101 
0102         if (event->button() == Qt::LeftButton && m_view.data()->history()->canGoBack()) {
0103             m_view.data()->back();
0104             accepted = true;
0105         }
0106         else if (event->button() == Qt::RightButton && m_view.data()->history()->canGoForward()) {
0107             m_view.data()->forward();
0108             accepted = true;
0109         }
0110 
0111         if (accepted) {
0112             m_blockNextLeftMouseRelease = true;
0113             m_blockNextRightMouseRelease = true;
0114             return true;
0115         }
0116     }
0117 
0118     m_filter->mouseButtonPressEvent(event);
0119 
0120     return false;
0121 }
0122 
0123 bool MouseGestures::mouseRelease(QObject* obj, QMouseEvent* event)
0124 {
0125     Q_UNUSED(obj)
0126 
0127     if (m_blockNextRightMouseRelease && event->button() == Qt::RightButton) {
0128         m_blockNextRightMouseRelease = false;
0129         return true;
0130     }
0131 
0132     if (m_blockNextLeftMouseRelease && event->button() == Qt::LeftButton) {
0133         m_blockNextLeftMouseRelease = false;
0134         return true;
0135     }
0136 
0137     return m_filter->mouseButtonReleaseEvent(event);
0138 }
0139 
0140 bool MouseGestures::mouseMove(QObject* obj, QMouseEvent* event)
0141 {
0142     Q_UNUSED(obj)
0143 
0144     m_filter->mouseMoveEvent(event);
0145 
0146     return false;
0147 }
0148 
0149 void MouseGestures::showSettings(QWidget* parent)
0150 {
0151     if (!m_settings) {
0152         m_settings = new MouseGesturesSettingsDialog(this, parent);
0153     }
0154 
0155     m_settings.data()->show();
0156     m_settings.data()->raise();
0157 }
0158 
0159 void MouseGestures::unloadPlugin()
0160 {
0161     delete m_settings.data();
0162 }
0163 
0164 void MouseGestures::upGestured()
0165 {
0166     if (!m_view) {
0167         return;
0168     }
0169 
0170     m_view.data()->stop();
0171 }
0172 
0173 void MouseGestures::downGestured()
0174 {
0175     auto* view = qobject_cast<TabbedWebView*>(m_view.data());
0176     if (!view)
0177         return;
0178 
0179     BrowserWindow* window = view->browserWindow();
0180     if (!window)
0181         return;
0182 
0183     TabWidget* tabWidget = window->tabWidget();
0184     tabWidget->addView(QUrl(), Qz::NT_SelectedNewEmptyTab, true);
0185     tabWidget->setCurrentTabFresh(true);
0186 
0187     if (window->isFullScreen())
0188         window->showNavigationWithFullScreen();
0189 }
0190 
0191 void MouseGestures::leftGestured()
0192 {
0193     if (!m_view) {
0194         return;
0195     }
0196 
0197     if (QApplication::isRightToLeft()) {
0198         m_view.data()->forward();
0199     }
0200     else {
0201         m_view.data()->back();
0202     }
0203 }
0204 
0205 void MouseGestures::rightGestured()
0206 {
0207     if (!m_view) {
0208         return;
0209     }
0210 
0211     if (QApplication::isRightToLeft()) {
0212         m_view.data()->back();
0213     }
0214     else {
0215         m_view.data()->forward();
0216     }
0217 }
0218 
0219 void MouseGestures::downRightGestured()
0220 {
0221     auto *view = qobject_cast<TabbedWebView*>(m_view.data());
0222     if (!view)
0223         return;
0224 
0225     BrowserWindow *window = view->browserWindow();
0226     if (!window)
0227         return;
0228 
0229     TabWidget *tabWidget = window->tabWidget();
0230     if (!m_view) {
0231         return;
0232     }
0233 
0234     tabWidget->requestCloseTab(view->tabIndex());
0235 }
0236 
0237 void MouseGestures::downLeftGestured()
0238 {
0239     if (!m_view) {
0240         return;
0241     }
0242 
0243     m_view.data()->load(mApp->getWindow()->homepageUrl());
0244 }
0245 
0246 void MouseGestures::downUpGestured()
0247 {
0248     auto* view = qobject_cast<TabbedWebView*>(m_view.data());
0249     if (!view)
0250         return;
0251 
0252     BrowserWindow* window = view->browserWindow();
0253     if (!window)
0254         return;
0255 
0256     TabWidget* tabWidget = window->tabWidget();
0257     tabWidget->duplicateTab(tabWidget->currentIndex());
0258 }
0259 
0260 void MouseGestures::upDownGestured()
0261 {
0262     if (!m_view) {
0263         return;
0264     }
0265 
0266     m_view.data()->reload();
0267 }
0268 
0269 void MouseGestures::upLeftGestured()
0270 {
0271     auto* view = qobject_cast<TabbedWebView*>(m_view.data());
0272     if (!view)
0273         return;
0274 
0275     BrowserWindow* window = view->browserWindow();
0276     if (!window)
0277         return;
0278 
0279     if (QApplication::isRightToLeft())
0280         window->tabWidget()->nextTab();
0281     else
0282         window->tabWidget()->previousTab();
0283 }
0284 
0285 void MouseGestures::upRightGestured()
0286 {
0287     auto* view = qobject_cast<TabbedWebView*>(m_view.data());
0288     if (!view)
0289         return;
0290 
0291     BrowserWindow* window = view->browserWindow();
0292     if (!window)
0293         return;
0294 
0295     if (QApplication::isRightToLeft())
0296         window->tabWidget()->previousTab();
0297     else
0298         window->tabWidget()->nextTab();
0299 }
0300 
0301 void MouseGestures::init()
0302 {
0303     initFilter();
0304 
0305     // We need to override right mouse button events
0306     m_oldWebViewForceContextMenuOnRelease = WebView::forceContextMenuOnMouseRelease();
0307     WebView::setForceContextMenuOnMouseRelease(m_button == Qt::RightButton || m_enableRockerNavigation);
0308 }
0309 
0310 void MouseGestures::setGestureButton(Qt::MouseButton button)
0311 {
0312     m_button = button;
0313     init();
0314 }
0315 
0316 void MouseGestures::setGestureButtonByIndex(int index)
0317 {
0318     switch (index) {
0319     case 0:
0320         m_button = Qt::MiddleButton;
0321         break;
0322 
0323     case 1:
0324         m_button = Qt::RightButton;
0325         break;
0326 
0327     default:
0328         m_button = Qt::NoButton;
0329     }
0330 
0331     setGestureButton(m_button);
0332 }
0333 
0334 Qt::MouseButton MouseGestures::gestureButton() const
0335 {
0336     return m_button;
0337 }
0338 
0339 int MouseGestures::buttonToIndex() const
0340 {
0341     switch (m_button) {
0342     case Qt::MiddleButton:
0343         return 0;
0344 
0345     case Qt::RightButton:
0346         return 1;
0347 
0348     default:
0349         return 2;
0350     }
0351 }
0352 
0353 bool MouseGestures::rockerNavigationEnabled() const
0354 {
0355     return m_enableRockerNavigation;
0356 }
0357 
0358 void MouseGestures::setRockerNavigationEnabled(bool enable)
0359 {
0360     m_enableRockerNavigation = enable;
0361     init();
0362 }
0363 
0364 void MouseGestures::loadSettings()
0365 {
0366     QSettings settings(m_settingsFile, QSettings::IniFormat);
0367 
0368     settings.beginGroup("MouseGestures");
0369     setGestureButtonByIndex(settings.value("Button", 0).toInt());
0370     m_enableRockerNavigation = settings.value("RockerNavigation", true).toBool();
0371     settings.endGroup();
0372 
0373     init();
0374 }
0375 
0376 void MouseGestures::saveSettings()
0377 {
0378     QSettings settings(m_settingsFile, QSettings::IniFormat);
0379 
0380     settings.beginGroup("MouseGestures");
0381     settings.setValue("Button", buttonToIndex());
0382     settings.setValue("RockerNavigation", m_enableRockerNavigation);
0383     settings.endGroup();
0384 }
0385 
0386 MouseGestures::~MouseGestures()
0387 {
0388     m_filter->clearGestures(true);
0389     delete m_filter;
0390 
0391     // Restore original value
0392     WebView::setForceContextMenuOnMouseRelease(m_oldWebViewForceContextMenuOnRelease);
0393 }