From 5be38086b81622942bcb22dd1da61528d6020f8d Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 3 Feb 2017 03:00:46 +0100 Subject: [PATCH] refs #617, CGuiActionBindHandler to use QAction with hotkeys * QMenu can be automatically turned into a list of CActionBind objects for hotkeys * trigger QAction from hotkeys --- src/blackgui/guiactionbind.cpp | 85 ++++++++++++++++++++++++++++++++++ src/blackgui/guiactionbind.h | 60 ++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 src/blackgui/guiactionbind.cpp create mode 100644 src/blackgui/guiactionbind.h diff --git a/src/blackgui/guiactionbind.cpp b/src/blackgui/guiactionbind.cpp new file mode 100644 index 000000000..5fad2a1a9 --- /dev/null +++ b/src/blackgui/guiactionbind.cpp @@ -0,0 +1,85 @@ +/* Copyright (C) 2017 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "guiactionbind.h" +#include "blackmisc/fileutils.h" + +using namespace BlackMisc; +using namespace BlackCore; + +namespace BlackGui +{ + CGuiActionBindHandler::CGuiActionBindHandler(QAction *action) : QObject(action) + { + this->setAction(action); + } + + CGuiActionBindHandler::~CGuiActionBindHandler() + { + this->unbind(); + } + + CActionBindings CGuiActionBindHandler::bindMenu(QMenu *menu, const QString &path) + { + CActionBindings boundActions; + if (!menu || menu->isEmpty()) { return boundActions; } + for (QAction *action : menu->actions()) + { + if (action->text().isEmpty()) { continue; } + if (action->isSeparator()) { continue; } + + const QString pathNew = CGuiActionBindHandler::appendPath(path, action->text()).remove('&'); // remove E&xit key codes + if (action->menu()) + { + CGuiActionBindHandler::bindMenu(action->menu(), pathNew); + } + + CGuiActionBindHandler *bindHandler = new CGuiActionBindHandler(action); + QSharedPointer actionBind(new CActionBind(pathNew, bindHandler, &CGuiActionBindHandler::boundFunction, [bindHandler]() { bindHandler->deleteLater(); })); + bindHandler->m_index = actionBind->getIndex(); + boundActions.append(actionBind); // takes ownership + } + return boundActions; + } + + void CGuiActionBindHandler::setAction(QAction *action) + { + this->m_action = action; + + // if the action is destroyed from somewhere else I unbind myself + QObject::connect(action, &QAction::destroyed, [ = ] + { + this->unbind(); + }); + } + + void CGuiActionBindHandler::unbind() + { + if (!this->m_action) { return; } + this->m_action = nullptr; + if (CInputManager::instance()) + { + CInputManager::instance()->unbind(this->m_index); + m_index = -1; + } + } + + void CGuiActionBindHandler::boundFunction(bool enabled) + { + if (!enabled) { return; } + if (!m_action) { return; } + if (m_index < 0) { return; } + m_action->trigger(); + } + + QString CGuiActionBindHandler::appendPath(const QString &path, const QString &name) + { + return CFileUtils::appendFilePaths(path, name); + } +} // namespace diff --git a/src/blackgui/guiactionbind.h b/src/blackgui/guiactionbind.h new file mode 100644 index 000000000..26ecc24e3 --- /dev/null +++ b/src/blackgui/guiactionbind.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2017 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKGUI_GUIACTIONBIND_H +#define BLACKGUI_GUIACTIONBIND_H + +#include "blackgui/blackguiexport.h" +#include "blackcore/actionbind.h" + +#include +#include +#include + +namespace BlackGui +{ + //! QObject derived handler to be registered with BlackCore::CActionBind + class BLACKGUI_EXPORT CGuiActionBindHandler : public QObject + { + Q_OBJECT + + public: + //! Constructor + CGuiActionBindHandler(QAction *action); + + //! Destructor + virtual ~CGuiActionBindHandler(); + + //! Bound function for BlackCore::CActionBind + void boundFunction(bool enabled); + + //! Bind whole menu + static BlackCore::CActionBindings bindMenu(QMenu *menu, const QString &path = {}); + + private: + //! Corresponding action destroyed + void destroyed(); + + //! Set the action + void setAction(QAction *action); + + //! Unbind this action + void unbind(); + + //! Append path for action + static QString appendPath(const QString &path, const QString &name); + + int m_index = -1; + QAction *m_action = nullptr; + }; +} // namespace + +#endif // guard