File indexing completed on 2024-05-12 04:58:27

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2014  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 "enhancedmenu.h"
0019 
0020 #include <QMouseEvent>
0021 #include <QApplication>
0022 
0023 Menu::Menu(QWidget* parent)
0024     : QMenu(parent)
0025 {
0026 }
0027 
0028 Menu::Menu(const QString &title, QWidget* parent)
0029     : QMenu(title, parent)
0030 {
0031 }
0032 
0033 bool Menu::closeOnMiddleClick() const
0034 {
0035     return m_closeOnMiddleClick;
0036 }
0037 
0038 void Menu::setCloseOnMiddleClick(bool close)
0039 {
0040     m_closeOnMiddleClick = close;
0041 }
0042 
0043 void Menu::mouseReleaseEvent(QMouseEvent* e)
0044 {
0045     QAction* qact = activeAction();
0046     auto* act = qobject_cast<Action*> (qact);
0047 
0048     if (qact && qact->menu()) {
0049         Menu* m = qobject_cast<Menu*> (qact->menu());
0050         if (!m) {
0051             QMenu::mouseReleaseEvent(e);
0052             return;
0053         }
0054 
0055         if (e->button() == Qt::MiddleButton || (e->button() == Qt::LeftButton && e->modifiers() == Qt::ControlModifier)) {
0056             closeAllMenus();
0057             Q_EMIT menuMiddleClicked(m);
0058         }
0059     }
0060 
0061     if (!act) {
0062         QMenu::mouseReleaseEvent(e);
0063         return;
0064     }
0065 
0066     if ((e->button() == Qt::LeftButton || e->button() == Qt::RightButton) && e->modifiers() == Qt::NoModifier) {
0067         closeAllMenus();
0068         act->trigger();
0069         e->accept();
0070     }
0071     else if (e->button() == Qt::MiddleButton || (e->button() == Qt::LeftButton && e->modifiers() == Qt::ControlModifier)) {
0072         if ((e->button() == Qt::MiddleButton && m_closeOnMiddleClick) || e->button() != Qt::MiddleButton) {
0073             closeAllMenus();
0074         }
0075         act->emitCtrlTriggered();
0076         e->accept();
0077     }
0078     else if (e->button() == Qt::LeftButton && e->modifiers() == Qt::ShiftModifier) {
0079         closeAllMenus();
0080         act->emitShiftTriggered();
0081         e->accept();
0082     }
0083 }
0084 
0085 void Menu::keyPressEvent(QKeyEvent* e)
0086 {
0087     if (e->key() != Qt::Key_Enter && e->key() != Qt::Key_Return) {
0088         QMenu::keyPressEvent(e);
0089         return;
0090     }
0091 
0092     QAction* qact = activeAction();
0093     auto* act = qobject_cast<Action*> (qact);
0094 
0095     if (!act) {
0096         QMenu::keyPressEvent(e);
0097         return;
0098     }
0099 
0100     if (e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier) {
0101         closeAllMenus();
0102         act->trigger();
0103         e->accept();
0104     }
0105     else if (e->modifiers() == Qt::ControlModifier) {
0106         closeAllMenus();
0107         act->emitCtrlTriggered();
0108         e->accept();
0109     }
0110     else if (e->modifiers() == Qt::ShiftModifier) {
0111         closeAllMenus();
0112         act->emitShiftTriggered();
0113         e->accept();
0114     }
0115 }
0116 
0117 void Menu::closeAllMenus()
0118 {
0119     QMenu* menu = this;
0120 
0121     while (menu) {
0122         menu->close();
0123         menu = qobject_cast<QMenu*>(QApplication::activePopupWidget());
0124     }
0125 }
0126 
0127 Action::Action(QObject* parent)
0128     : QAction(parent)
0129 {
0130 }
0131 
0132 Action::Action(const QString &text, QObject* parent)
0133     : QAction(text, parent)
0134 {
0135 }
0136 
0137 Action::Action(const QIcon &icon, const QString &text, QObject* parent)
0138     : QAction(icon, text, parent)
0139 {
0140 }
0141 
0142 void Action::emitCtrlTriggered()
0143 {
0144     Q_EMIT ctrlTriggered();
0145 }
0146 
0147 void Action::emitShiftTriggered()
0148 {
0149     Q_EMIT shiftTriggered();
0150 }