Files
pilotclient/src/blackgui/guiactionbind.cpp
Roland Winklmeier f6ea2a9107 Move CInputManager from singleton to CApplication member
The main reason why CInputManager was singleton is the easy access across
the code. That had the negative side effect that time of destruction was
at a very late stage of the shutdown and could not be controlled by us.
My moving it to CApplication, the access is equally easy (using sApp) and
allows to be cleaned up properly during graceful shutdown.

ref T391
2018-11-04 17:42:42 +01:00

141 lines
4.9 KiB
C++

/* 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"
#include "blackmisc/imageutils.h"
using namespace BlackMisc;
using namespace BlackCore;
namespace BlackGui
{
CGuiActionBindHandler::CGuiActionBindHandler(QAction *action) : QObject(action), m_action(action)
{
this->connectDestroy(action);
connect(sApp, &CApplication::aboutToShutdown, this, &CGuiActionBindHandler::unbind);
}
CGuiActionBindHandler::CGuiActionBindHandler(QAbstractButton *button) : QObject(button), m_button(button)
{
this->connectDestroy(button);
connect(sApp, &CApplication::aboutToShutdown, this, &CGuiActionBindHandler::unbind);
}
CGuiActionBindHandler::~CGuiActionBindHandler()
{
}
CActionBindings CGuiActionBindHandler::bindMenu(QMenu *menu, const QString &path)
{
Q_ASSERT(menu);
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);
}
const bool hasIcon = !action->icon().isNull();
CGuiActionBindHandler *bindHandler = new CGuiActionBindHandler(action);
CActionBinding actionBinding(CActionBinding::create(pathNew, hasIcon ? action->icon().pixmap(CIcons::empty16().size()) : CIcons::empty16(), bindHandler, &CGuiActionBindHandler::boundFunction, [bindHandler]() { CGuiActionBindHandler::actionBindWasDestroyed(bindHandler); }));
bindHandler->m_index = actionBinding->getIndex();
boundActions.append(actionBinding); // takes ownership
}
return boundActions;
}
CActionBinding CGuiActionBindHandler::bindButton(QAbstractButton *button, const QString &path, bool absoluteName)
{
Q_ASSERT(button);
const QString pathNew = absoluteName ?
path :
CGuiActionBindHandler::appendPath(path, button->text()).remove('&'); // remove E&xit key codes
CGuiActionBindHandler *bindHandler = new CGuiActionBindHandler(button);
const bool hasIcon = !button->icon().isNull();
CActionBinding actionBinding(CActionBinding::create(pathNew, hasIcon ? button->icon().pixmap(CIcons::empty16().size()) : CIcons::empty16(), bindHandler, &CGuiActionBindHandler::boundFunction, [bindHandler]() { CGuiActionBindHandler::actionBindWasDestroyed(bindHandler); }));
bindHandler->m_index = actionBinding->getIndex();
return actionBinding;
}
void CGuiActionBindHandler::actionBindWasDestroyed(CGuiActionBindHandler *bindHandler)
{
if (!bindHandler) { return; }
bindHandler->reset();
// do not delete, as it might be still referenced somewhere
}
void CGuiActionBindHandler::connectDestroy(QObject *object)
{
// if the action is destroyed from somewhere else I unbind myself
QObject::connect(object, &QObject::destroyed, [ = ]
{
this->unbind();
});
}
void CGuiActionBindHandler::unbind()
{
if (this->hasTarget())
{
Q_ASSERT_X(sApp && sApp->getInputManager(), Q_FUNC_INFO, "Missing input manager");
sApp->getInputManager()->unbind(m_index);
}
this->reset();
}
void CGuiActionBindHandler::reset()
{
m_index = -1;
m_button = nullptr;
m_action = nullptr;
}
bool CGuiActionBindHandler::hasTarget() const
{
return (m_button || m_action) && m_index >= 0;
}
void CGuiActionBindHandler::boundFunction(bool enabled)
{
if (!enabled || !this->hasTarget()) { return; }
if (m_action)
{
m_action->trigger();
}
else if (m_button)
{
m_button->click();
}
}
QString CGuiActionBindHandler::appendPath(const QString &path, const QString &name)
{
return CFileUtils::appendFilePaths(path, name);
}
const QString &CGuiActionBindHandler::pathSwiftPilotClient()
{
static const QString s("Pilot client UI/");
return s;
}
const QString &CGuiActionBindHandler::pathSwiftCore()
{
static const QString s("Core UI/");
return s;
}
} // namespace