refs #139 , based on RW's class added a platform independent CKeyboardKey class

* Key value stored similar to Qt::Key
* 2 modifiers
This commit is contained in:
Klaus Basan
2014-02-17 02:06:06 +01:00
parent 3df3c86386
commit 141706158f
2 changed files with 557 additions and 0 deletions

View File

@@ -0,0 +1,327 @@
/* Copyright (C) 2013 VATSIM Community / contributors
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "hwkeyboardkey.h"
#include "blackmiscfreefunctions.h"
#include <QCoreApplication>
namespace BlackMisc
{
namespace Hardware
{
CKeyboardKey::CKeyboardKey() :
m_key(0), m_modifier1(ModifierNone), m_modifier2(ModifierNone), m_function(HotkeyNone), m_pressed(false)
{}
CKeyboardKey::CKeyboardKey(int keyCode, Modifier modifier1, Modifier modifier2, const HotkeyFunction &function, bool isPressed) :
m_key(keyCode), m_modifier1(modifier1), m_modifier2(modifier2), m_function(function), m_pressed(isPressed)
{}
uint CKeyboardKey::getValueHash() const
{
QList<uint> hashs;
hashs << qHash(this->m_key);
hashs << qHash(this->m_function);
hashs << qHash(static_cast<uint>(this->m_modifier1));
hashs << qHash(static_cast<uint>(this->m_modifier2));
return BlackMisc::calculateHash(hashs, "CKeyboardKey");
}
void CKeyboardKey::registerMetadata()
{
qRegisterMetaType<CKeyboardKey>();
qDBusRegisterMetaType<CKeyboardKey>();
}
QString CKeyboardKey::convertToQString(bool /* i18n */) const
{
QString s = this->getModifier1AsString();
s.append(" ").append(this->getModifier2AsString()).append(" ");
if (this->m_key != 0) this->getKeyAsStringRepresentation();
return s.trimmed();
}
int CKeyboardKey::getMetaTypeId() const
{
return qMetaTypeId<CKeyboardKey>();
}
bool CKeyboardKey::isA(int metaTypeId) const
{
return (metaTypeId == qMetaTypeId<CKeyboardKey>());
}
int CKeyboardKey::compareImpl(const CValueObject &otherBase) const
{
const auto &other = static_cast<const CKeyboardKey &>(otherBase);
QString k1(this->m_key);
QString k2(other.getKey());
return k1.compare(k2);
}
void CKeyboardKey::marshallToDbus(QDBusArgument &argument) const
{
argument << this->m_key;
argument << static_cast<uint>(this->m_modifier1);
argument << static_cast<uint>(this->m_modifier2);
argument << static_cast<uint>(this->m_function);
argument << this->m_pressed;
}
void CKeyboardKey::unmarshallFromDbus(const QDBusArgument &argument)
{
uint c;
argument >> this->m_key;
argument >> c;
this->m_modifier1 = static_cast<Modifier>(c);
argument >> c;
this->m_modifier2 = static_cast<Modifier>(c);
argument >> c;
this->m_function = static_cast<HotkeyFunction>(c);
argument >> this->m_pressed;
}
QString CKeyboardKey::modifierToString(CKeyboardKey::Modifier modifier)
{
switch (modifier)
{
case ModifierNone: return "";
case ModifierAltAny: return "Alt";
case ModifierAltLeft: return "Alt Left";
case ModifierAltRight: return "Alt Right";
case ModifierShiftAny: return "Shift";
case ModifierShiftLeft: return "Shift Left";
case ModifierShiftRight: return "Shift Right";
case ModifierCtrlAny: return "Ctrl";
case ModifierCtrlLeft: return "Ctrl Left";
case ModifierCtrlRight: return "Ctrl Right";
case ModifierMeta: return "Meta";
default:
qFatal("Wrong modifier");
return "";
}
}
CKeyboardKey::Modifier CKeyboardKey::modifierFromString(const QString &modifier)
{
QString mod = modifier.toLower().replace('&', ' ');
if (mod == "ctrl" || mod == "ctl") return ModifierCtrlAny;
if (mod.startsWith("ctrl l") || mod.startsWith("ctl l")) return ModifierCtrlLeft;
if (mod.startsWith("ctrl r") || mod.startsWith("ctl r")) return ModifierCtrlRight;
if (mod == "shift") return ModifierShiftAny;
if (mod.startsWith("shift l")) return ModifierShiftLeft;
if (mod.startsWith("shift r")) return ModifierShiftRight;
if (mod == "alt") return ModifierAltAny;
if (mod.startsWith("alt l")) return ModifierAltLeft;
if (mod.startsWith("alt r")) return ModifierAltRight;
if (mod == "meta") return ModifierMeta;
return ModifierNone;
}
CKeyboardKey::Modifier CKeyboardKey::modifierFromQtModifier(Qt::Modifier qtModifier)
{
switch (qtModifier)
{
case Qt::META : return ModifierMeta;
case Qt::SHIFT : return ModifierShiftAny;
case Qt::CTRL: return ModifierShiftAny;
case Qt::ALT: return ModifierAltAny;
default:
return ModifierNone;
}
}
const QStringList &CKeyboardKey::modifiers()
{
static QStringList modifiers;
if (modifiers.isEmpty())
{
modifiers << modifierToString(ModifierNone);
modifiers << modifierToString(ModifierCtrlAny);
modifiers << modifierToString(ModifierCtrlLeft);
modifiers << modifierToString(ModifierCtrlRight);
modifiers << modifierToString(ModifierShiftAny);
modifiers << modifierToString(ModifierShiftLeft);
modifiers << modifierToString(ModifierShiftRight);
modifiers << modifierToString(ModifierAltAny);
modifiers << modifierToString(ModifierAltLeft);
modifiers << modifierToString(ModifierAltRight);
modifiers << modifierToString(ModifierMeta);
}
return modifiers;
}
bool CKeyboardKey::operator ==(const CKeyboardKey &other) const
{
return (other.getKey() != this->getKey()) &&
other.isPressed() == this->isPressed() &&
other.getFunction() == this->getFunction() &&
other.getModifier1() == this->getModifier1() &&
other.getModifier2() == this->getModifier2();
}
bool CKeyboardKey::operator< (CKeyboardKey const &other) const
{
if (this->getKey() < other.getKey())
return true;
else
return false;
}
void CKeyboardKey::cleanup()
{
if (!this->hasModifier()) return;
if (this->m_modifier1 == ModifierNone) qSwap(this->m_modifier1, this->m_modifier2);
if (this->numberOfModifiers() == 1) return;
if (this->m_modifier1 == this->m_modifier2)
{
// redundant
this->m_modifier2 = ModifierNone;
return;
}
// order
if (static_cast<uint>(this->m_modifier1) < static_cast<uint>(this->m_modifier2))
qSwap(this->m_modifier1, this->m_modifier2);
}
int CKeyboardKey::numberOfModifiers() const
{
if (!this->hasModifier()) return 0;
if (this->m_modifier1 == ModifierNone || this->m_modifier2 == ModifierNone) return 1;
return 2;
}
void CKeyboardKey::setKey(const QString &key)
{
if (key.isEmpty())
this->m_key = 0;
else if (key.contains(QRegExp("\\((\\d+)\\)")))
{
QString code = key.mid(key.indexOf("(") + 1).replace(")", "");
if (code.isEmpty())
this->m_key = 0;
else
this->m_key = code.toInt();
}
else
this->setKey(key.at(0));
}
void CKeyboardKey::setKey(const QChar key)
{
if (key.isNull())
this->m_key = 0;
else
this->m_key = key.digitValue();
}
QString CKeyboardKey::getFunctionAsString() const
{
switch (this->m_function)
{
case HotkeyNone: return "";
case HotkeyPtt: return QCoreApplication::translate("Hotkey", "PTT");
case HotkeyOpacity50: return QCoreApplication::translate("Hotkey", "Opacity 50%");
case HotkeyOpacity100: return QCoreApplication::translate("Hotkey", "Opacity 100%");
case HotkeyToggleCom1: return QCoreApplication::translate("Hotkey", "Toggle COM1");
case HotkeyToggleCom2: return QCoreApplication::translate("Hotkey", "Toggle COM2");
default:
qFatal("Wrong function");
return "";
}
// force strings for translation in resource files
(void)QT_TRANSLATE_NOOP("Hotkey", "PTT");
(void)QT_TRANSLATE_NOOP("Hotkey", "Opacity 50%");
(void)QT_TRANSLATE_NOOP("Hotkey", "Opacity 100%");
(void)QT_TRANSLATE_NOOP("Hotkey", "Toggle COM1");
(void)QT_TRANSLATE_NOOP("Hotkey", "Toggle COM2");
}
QVariant CKeyboardKey::propertyByIndex(int index) const
{
switch (index)
{
case IndexFunction:
return QVariant(this->m_function);
case IndexFunctionAsString:
return QVariant(this->getFunctionAsString());
case IndexModifier1:
return QVariant(static_cast<uint>(this->m_modifier1));
case IndexModifier2:
return QVariant(static_cast<uint>(this->m_modifier2));
case IndexModifier1AsString:
return QVariant(this->getModifier1AsString());
case IndexModifier2AsString:
return QVariant(this->getModifier2AsString());
case IndexKey:
return QVariant(this->m_key);
case IndexKeyAsString:
return QVariant(QString(QChar(this->m_key)));
case IndexKeyAsStringRepresentation:
return QVariant(this->getKeyAsStringRepresentation());
case IndexIsPressed:
return QVariant(this->m_pressed);
default:
break;
}
Q_ASSERT_X(false, "CKeyboardKey", "index unknown");
QString m = QString("no property, index ").append(QString::number(index));
return QVariant::fromValue(m);
}
QString CKeyboardKey::toStringRepresentation(int key)
{
if (key == 0) return "";
QString ks = QKeySequence(key).toString();
ks.append('(').append(QString::number(key)).append(')');
return ks;
}
void CKeyboardKey::setPropertyByIndex(const QVariant &variant, int index)
{
switch (index)
{
case IndexFunction:
{
uint f = variant.value<uint>();
this->setFunction(static_cast<HotkeyFunction>(f));
break;
}
case IndexKey:
case IndexKeyAsString:
case IndexKeyAsStringRepresentation:
{
// static_cast see docu of variant.type()
if (static_cast<QMetaType::Type>(variant.type()) == QMetaType::QChar)
this->setKey(variant.value<QChar>());
else
this->setKey(variant.value<QString>());
break;
}
case IndexIsPressed:
this->setPressed(variant.value<bool>());
break;
case IndexModifier1AsString:
this->setModifier1(variant.value<QString>());
break;
case IndexModifier2AsString:
this->setModifier2(variant.value<QString>());
break;
default:
Q_ASSERT_X(false, "CKeyboardKey", "index unknown (setter)");
break;
}
}
} // namespace Hardware
} // BlackMisc