1 //========================================================= 2 // MusE 3 // Linux Music Editor 4 // $Id: popupmenu.h,v 1.1.1.1 2010/07/18 03:18:00 terminator356 Exp $ 5 // 6 // (C) Copyright 1999-2010 Werner Schweer (ws@seh.de) 7 // 8 // PopupMenu sub-class of QMenu created by Tim. 9 // (C) Copyright 2010-2015 Tim E. Real (terminator356 A T sourceforge D O T net) 10 // 11 // This program is free software; you can redistribute it and/or 12 // modify it under the terms of the GNU General Public License 13 // as published by the Free Software Foundation; version 2 of 14 // the License, or (at your option) any later version. 15 // 16 // This program is distributed in the hope that it will be useful, 17 // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 // GNU General Public License for more details. 20 // 21 // You should have received a copy of the GNU General Public License 22 // along with this program; if not, write to the Free Software 23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 24 // 25 //========================================================= 26 27 #ifndef __POPUPMENU_H__ 28 #define __POPUPMENU_H__ 29 30 // Just in case Qt ever adds these features natively, we would need to turn our features off! 31 //#define POPUP_MENU_DISABLE_STAY_OPEN 32 //#define POPUP_MENU_DISABLE_AUTO_SCROLL 33 34 #include <QMenu> 35 #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL 36 #include <QTimer> 37 #endif 38 39 #include <QVariant> 40 #include <QPointer> 41 #include <QAction> 42 43 44 // Forward declarations: 45 class QWidget; 46 class QMouseEvent; 47 class QContextMenuEvent; 48 class QHideEvent; 49 class QEvent; 50 51 namespace MusEGui { 52 53 /** offers a QMenu-like menu, which stays open once the user 54 * clicked a checkable action. */ 55 class PopupMenu : public QMenu 56 { 57 Q_OBJECT 58 59 bool _stayOpen; 60 #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL 61 QTimer* timer; 62 #endif 63 int moveDelta; 64 PopupMenu* _cur_menu; // For auto-breakup. 65 int _cur_menu_count; 66 int _max_items_in_breakup; 67 68 QMenu* _contextMenu; 69 QAction* _lastHoveredAction; 70 QPointer<QAction> _highlightedAction; 71 72 void init(); 73 void showContextMenu(const QPoint&); 74 // Auto-breakup a too-wide menu. 75 // If a new menu is created, parentText will be used as the parent item's text. 76 PopupMenu* getMenu(const QString& parentText); 77 78 private slots: 79 void popHovered(QAction*); 80 81 #ifndef POPUP_MENU_DISABLE_AUTO_SCROLL 82 void timerHandler(); 83 #endif 84 85 protected: 86 virtual void mouseReleaseEvent(QMouseEvent*); 87 virtual void mousePressEvent(QMouseEvent*); 88 virtual void contextMenuEvent(QContextMenuEvent*); 89 virtual void hideEvent(QHideEvent*); 90 virtual bool event(QEvent*); 91 virtual void closeUp(); 92 93 // For auto-breakup of a too-wide menu. Virtual. 94 virtual PopupMenu* cloneMenu(const QString& title, QWidget* parent = 0, bool stayOpen = false, bool showTooltips = false); 95 96 public: signals: 97 void aboutToShowContextMenu(PopupMenu* menu, QAction* menuAction, QMenu* ctxMenu); 98 99 public: 100 PopupMenu(bool stayOpen); 101 PopupMenu(QWidget* parent=0, bool stayOpen = false); 102 PopupMenu(const QString& title, QWidget* parent = 0, bool stayOpen = false); 103 ~PopupMenu(); 104 QAction* findActionFromData(const QVariant&) const; stayOpen()105 bool stayOpen() const { return _stayOpen; } 106 void clearAllChecks() const; 107 108 QMenu* contextMenu(); 109 void hideContextMenu(); 110 static PopupMenu* contextMenuFocus(); 111 static QAction* contextMenuFocusAction(); 112 113 // Need to catch these to auto-breakup a too-big menu. 114 QAction* addAction(const QString& text); 115 QAction* addAction(const QIcon& icon, const QString& text); 116 QAction* addAction(const QString& text, const QObject* receiver, const char* member, const QKeySequence& shortcut = 0); 117 QAction* addAction(const QIcon& icon, const QString& text, const QObject* receiver, const char* member, const QKeySequence& shortcut = 0); 118 void addAction(QAction* action); 119 QAction* addMenu(QMenu* menu); 120 QMenu* addMenu(const QString &title); 121 QMenu* addMenu(const QIcon &icon, const QString &title); 122 }; 123 124 // A handy structure for use with PopupMenu context menu action data. 125 // The variant holds the ORIGINAL data as set by the programmer. 126 class PopupMenuContextData { 127 private: 128 PopupMenu* _menu; 129 QAction* _action; 130 QVariant _variant; 131 132 public: PopupMenuContextData()133 PopupMenuContextData() : _menu(0), _action(0), _variant(0) { } PopupMenuContextData(const PopupMenuContextData & o)134 PopupMenuContextData(const PopupMenuContextData& o) : _menu(o._menu), _action(o._action), _variant(o._variant) { } PopupMenuContextData(PopupMenu * menu,QAction * action,QVariant var)135 PopupMenuContextData(PopupMenu* menu, QAction* action, QVariant var) : _menu(menu), _action(action), _variant(var) { } 136 menu()137 inline PopupMenu* menu() const { return _menu; } action()138 inline QAction* action() const { return _action; } varValue()139 inline QVariant varValue() const { return _variant; } 140 }; 141 142 } // namespace MusEGui 143 144 Q_DECLARE_METATYPE(MusEGui::PopupMenuContextData) 145 146 #endif 147 148