/**************************************************************************** * Copyright (c) 2022 Zheng Lei (realthunder) * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ****************************************************************************/ #ifndef GUI_SHORTCUT_MANAGER_H #define GUI_SHORTCUT_MANAGER_H #include #include #include #include #include #include #include #include #include #include namespace Gui { class Command; namespace bmi = boost::multi_index; class GuiExport ShortcutManager : public QObject, public ParameterGrp::ObserverType { Q_OBJECT public: ShortcutManager(); ~ShortcutManager() override; static ShortcutManager *instance(); static void destroy(); void OnChange(Base::Subject &, const char *reason) override; /// Clear all user defined shortcut void resetAll(); /// Clear the user defined shortcut of a given command void reset(const char *cmd); /// Set shortcut of a given command void setShortcut(const char *cmd, const char *accel); /** Get shortcut of a given command * @param cmd: command name * @param defaultAccel: default shortcut */ QString getShortcut(const char *cmd, const char *defaultAccel = nullptr); /// Return actions having a given shortcut in order of decreasing priority std::vector> getActionsByShortcut(const QKeySequence &shortcut); /// Set properties for a given list of actions in order of decreasing priority void setPriorities(const std::vector &actions); /** Set the priority of a given command * @param cmd: command name * @param priority: priority of the command, bigger value means higher priority */ void setPriority(const char *cmd, int priority); /// Get the priority of a given command int getPriority(const char *cmd); /** Set the top priority of a given command * Make the given command the top priority of all commands. * * @param cmd: command name */ void setTopPriority(const char *cmd); Q_SIGNALS: void shortcutChanged(const char *name, const QKeySequence &oldShortcut); void actionShortcutChanged(QAction *, const QKeySequence &oldShortcut); void priorityChanged(const char *name, int priority); protected: bool eventFilter(QObject *, QEvent *ev) override; bool checkShortcut(QObject *o, const QKeySequence &key); void onTimer(); private: ParameterGrp::handle hShortcuts; ParameterGrp::handle hPriorities; ParameterGrp::handle hSetting; bool busy = false; struct ActionKey { QKeySequence shortcut; QByteArray name; explicit ActionKey(const QKeySequence &shortcut, const char *name = "") : shortcut(shortcut) , name(name) {} bool operator<(const ActionKey &other) const { if (shortcut > other.shortcut) return false; if (shortcut < other.shortcut) return true; return name < other.name; } }; struct ActionData { ActionKey key; intptr_t pointer; QPointer action; explicit ActionData(QAction *action, const char *name = "") : key(action->shortcut(), name) , pointer(reinterpret_cast(action)) , action(action) {} }; bmi::multi_index_container< ActionData, bmi::indexed_by< // hashed index on ActionData::Action pointer bmi::hashed_unique>, // ordered index on shortcut + name bmi::ordered_non_unique> > > actionMap; std::unordered_map priorities; int topPriority; struct ActionInfo { QPointer action; int seq_length; int priority; ActionInfo(QAction *action, int l, int p) : action(action) , seq_length(l) , priority(p) {} }; std::vector pendingActions; QKeySequence pendingSequence; QPointer lastFocus; QTimer timer; int timeout; }; } #endif // GUI_SHORTCUT_MANAGER_H