Files
pilotclient/src/blackgui/hotkeydialog.cpp
2015-11-19 20:58:02 +00:00

252 lines
8.5 KiB
C++

#include "hotkeydialog.h"
#include "ui_hotkeydialog.h"
#include "blackgui/stylesheetutility.h"
#include "blackmisc/input/hotkeycombination.h"
#include "blackmisc/icon.h"
#include "blackmisc/logmessage.h"
#include <QIcon>
#include <QMessageBox>
using namespace BlackMisc;
using namespace BlackMisc::Input;
namespace BlackGui
{
CKeySelectionBox::CKeySelectionBox(QWidget *parent) :
QComboBox(parent)
{
connect(this, static_cast<void(CKeySelectionBox::*)(int)>(&CKeySelectionBox::currentIndexChanged), this, &CKeySelectionBox::ps_updateSelectedIndex);
}
void CKeySelectionBox::setSelectedIndex(int index)
{
m_oldIndex = index;
setCurrentIndex(m_oldIndex);
}
void CKeySelectionBox::ps_updateSelectedIndex(int index)
{
emit keySelectionChanged(m_oldIndex, index);
m_oldIndex = index;
}
CHotkeyDialog::CHotkeyDialog(const BlackMisc::Input::CActionHotkey &actionHotkey, QWidget *parent) :
QDialog(parent),
ui(new Ui::CHotkeyDialog),
m_actionHotkey(actionHotkey),
m_actionModel(this)
{
m_inputManager = BlackCore::CInputManager::instance();
ui->setupUi(this);
ui->advancedFrame->hide();
ui->tv_actions->setModel(&m_actionModel);
ui->pb_advancedMode->setIcon(BlackMisc::CIcons::arrowMediumSouth16());
selectAction();
if (!actionHotkey.getCombination().isEmpty()) { ui->pb_selectedHotkey->setText(actionHotkey.getCombination().toQString()); }
connect(ui->pb_advancedMode, &QPushButton::clicked, this, &CHotkeyDialog::ps_advancedModeChanged);
connect(ui->pb_selectedHotkey, &QPushButton::clicked, this, &CHotkeyDialog::ps_selectHotkey);
connect(ui->pb_accept, &QPushButton::clicked, this, &CHotkeyDialog::ps_accept);
connect(ui->pb_cancel, &QPushButton::clicked, this, &CHotkeyDialog::reject);
connect(m_inputManager, &BlackCore::CInputManager::combinationSelectionChanged, this, &CHotkeyDialog::ps_combinationSelectionChanged);
connect(m_inputManager, &BlackCore::CInputManager::combinationSelectionFinished, this, &CHotkeyDialog::ps_combinationSelectionFinished);
connect(ui->tv_actions->selectionModel(), &QItemSelectionModel::selectionChanged, this, &CHotkeyDialog::ps_changeSelectedAction);
initStyleSheet();
}
CHotkeyDialog::~CHotkeyDialog()
{
}
void CHotkeyDialog::setRegisteredApplications(const BlackMisc::CIdentifierList &applications)
{
for (const auto & app : applications)
{
ui->cb_identifier->addItem(app.getMachineName(), QVariant::fromValue(app));
}
}
void CHotkeyDialog::initStyleSheet()
{
const QString s = CStyleSheetUtility::instance().styles(
{
CStyleSheetUtility::fileNameFonts(),
CStyleSheetUtility::fileNameStandardWidget()
}
);
setStyleSheet(s);
}
CActionHotkey CHotkeyDialog::getActionHotkey(const CActionHotkey &initial, const CIdentifierList &applications, QWidget *parent)
{
CHotkeyDialog editDialog(initial, parent);
editDialog.setWindowModality(Qt::WindowModal);
// add local application
editDialog.setRegisteredApplications(applications);
if (editDialog.exec()) { return editDialog.getSelectedActionHotkey(); }
else { return {}; }
}
void CHotkeyDialog::ps_advancedModeChanged()
{
if (m_actionHotkey.getCombination().isEmpty()) return;
if (!ui->advancedFrame->isVisible())
{
setupAdvancedFrame();
ui->advancedFrame->show();
ui->pb_advancedMode->setIcon(BlackMisc::CIcons::arrowMediumNorth16());
}
else
{
ui->pb_advancedMode->setIcon(BlackMisc::CIcons::arrowMediumSouth16());
ui->advancedFrame->hide();
ui->gb_hotkey->resize(0, 0);
}
}
void CHotkeyDialog::ps_selectHotkey()
{
ui->pb_selectedHotkey->setText("Press any key/button...");
m_inputManager->startCapture();
}
void CHotkeyDialog::ps_combinationSelectionChanged(const BlackMisc::Input::CHotkeyCombination &combination)
{
ui->pb_selectedHotkey->setText(combination.toFormattedQString());
}
void CHotkeyDialog::ps_combinationSelectionFinished(const BlackMisc::Input::CHotkeyCombination &combination)
{
m_actionHotkey.setCombination(combination);
synchronize();
}
void CHotkeyDialog::ps_changeSelectedAction(const QItemSelection &selected, const QItemSelection &deselected)
{
Q_UNUSED(deselected);
const auto index = selected.indexes().first();
m_actionHotkey.setAction(index.data(Models::CActionModel::ActionRole).toString());
}
void CHotkeyDialog::ps_accept()
{
if (m_actionHotkey.getApplicableMachine().getMachineName().isEmpty())
{
CLogMessage().validationWarning("Missing %1") << ui->gb_machine->title();
return;
}
if (m_actionHotkey.getCombination().isEmpty())
{
CLogMessage().validationWarning("Missing %1") << ui->gb_hotkey->title();
return;
}
if (m_actionHotkey.getAction().isEmpty())
{
CLogMessage().validationWarning("Missing %1") << ui->gb_action->title();
return;
}
QDialog::accept();
}
void CHotkeyDialog::synchronize()
{
synchronizeSimpleSelection();
synchronizeAdvancedSelection();
}
void CHotkeyDialog::synchronizeSimpleSelection()
{
ui->pb_selectedHotkey->setText(m_actionHotkey.getCombination().toFormattedQString());
}
void CHotkeyDialog::synchronizeAdvancedSelection()
{
if (ui->advancedFrame->isVisible()) { setupAdvancedFrame(); }
}
void CHotkeyDialog::setupAdvancedFrame()
{
clearAdvancedFrame();
auto allSupportedKeys = CKeyboardKeyList::allSupportedKeys();
QStringList splittedKeys = m_actionHotkey.getCombination().toQString().split('+', QString::SkipEmptyParts);
for (const auto &splittedKey : splittedKeys)
{
if (splittedKey == "+") continue;
int currentIndex = -1;
CKeySelectionBox *ksb = new CKeySelectionBox(ui->advancedFrame);
for (const auto &supportedKey : allSupportedKeys)
{
QString supportedKeyAsString = supportedKey.toQString();
ksb->addItem(supportedKeyAsString, QVariant::fromValue(supportedKey));
if (supportedKeyAsString == splittedKey)
{
currentIndex = ksb->count() - 1;
}
}
ksb->setSelectedIndex(currentIndex);
ui->advancedFrame->layout()->addWidget(ksb);
int position = ui->advancedFrame->layout()->count() - 1;
ksb->setProperty("position", position);
connect(ksb, &CKeySelectionBox::keySelectionChanged, this, &CHotkeyDialog::advancedKeyChanged);
}
}
void CHotkeyDialog::clearAdvancedFrame()
{
QLayout *layout = ui->advancedFrame->layout();
QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0)
{
if (child->widget()) child->widget()->deleteLater();
delete child;
}
}
void CHotkeyDialog::advancedKeyChanged(int oldIndex, int newIndex)
{
CKeySelectionBox* ksb = qobject_cast<CKeySelectionBox *>(sender());
Q_ASSERT(ksb);
CKeyboardKey oldKey = ksb->itemData(oldIndex).value<CKeyboardKey>();
CKeyboardKey newKey = ksb->itemData(newIndex).value<CKeyboardKey>();
auto combination = m_actionHotkey.getCombination();
combination.replaceKey(oldKey, newKey);
m_actionHotkey.setCombination(combination);
synchronize();
}
void CHotkeyDialog::selectAction()
{
if (m_actionHotkey.getAction().isEmpty()) return;
const auto tokens = m_actionHotkey.getAction().split("/", QString::SkipEmptyParts);
QModelIndex parentIndex = QModelIndex();
for (const auto &token : tokens)
{
QModelIndex startIndex = m_actionModel.index(0, 0, parentIndex);
auto indexList = m_actionModel.match(startIndex, Qt::DisplayRole, QVariant::fromValue(token));
if (indexList.isEmpty()) return;
parentIndex = indexList.first();
ui->tv_actions->expand(parentIndex);
}
QItemSelectionModel * selectionModel = ui->tv_actions->selectionModel();
selectionModel->select(parentIndex, QItemSelectionModel::Select);
}
}