/* Copyright (C) 2013 * 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 "hwkeyboardkey.h" #include "blackmiscfreefunctions.h" #include namespace BlackMisc { namespace Hardware { CKeyboardKey::CKeyboardKey() : m_qtKey(Qt::Key_unknown), m_modifier1(ModifierNone), m_modifier2(ModifierNone) {} CKeyboardKey::CKeyboardKey(Qt::Key keyCode, Modifier modifier1, Modifier modifier2) : m_qtKey(keyCode), m_modifier1(modifier1), m_modifier2(modifier2) {} void CKeyboardKey::registerMetadata() { qRegisterMetaType(); qDBusRegisterMetaType(); } /* * To JSON */ QJsonObject CKeyboardKey::toJson() const { return BlackMisc::serializeJson(TupleConverter::toMetaTuple(*this)); } /* * From Json */ void CKeyboardKey::fromJson(const QJsonObject &json) { BlackMisc::deserializeJson(json, TupleConverter::toMetaTuple(*this)); } QString CKeyboardKey::convertToQString(bool /* i18n */) const { QString s = this->getModifier1AsString(); s.append(" ").append(this->getModifier2AsString()).append(" "); if (this->m_qtKey != 0) s.append(" ").append(this->getKeyAsStringRepresentation()); return s.trimmed(); } int CKeyboardKey::getMetaTypeId() const { return qMetaTypeId(); } bool CKeyboardKey::isA(int metaTypeId) const { return (metaTypeId == qMetaTypeId()); } 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; } /* * Compare */ int CKeyboardKey::compareImpl(const CValueObject &otherBase) const { const auto &other = static_cast(otherBase); return compare(TupleConverter::toMetaTuple(*this), TupleConverter::toMetaTuple(other)); } /* * Marshall to DBus */ void CKeyboardKey::marshallToDbus(QDBusArgument &argument) const { argument << TupleConverter::toMetaTuple(*this); } /* * Unmarshall from DBus */ void CKeyboardKey::unmarshallFromDbus(const QDBusArgument &argument) { argument >> TupleConverter::toMetaTuple(*this); } /* * Hash */ uint CKeyboardKey::getValueHash() const { return qHash(TupleConverter::toMetaTuple(*this)); } /* * Equal? */ bool CKeyboardKey::operator ==(const CKeyboardKey &other) const { if (this == &other) return true; return TupleConverter::toMetaTuple(*this) == TupleConverter::toMetaTuple(other); } /* * Unequal? */ bool CKeyboardKey::operator !=(const CKeyboardKey &other) const { return !((*this) == other); } 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(this->m_modifier1) < static_cast(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_qtKey = Qt::Key_unknown; QKeySequence sequence(key); m_qtKey = static_cast(sequence[0]); } void CKeyboardKey::setKey(const QChar &key) { if (key.isNull()) this->m_qtKey = Qt::Key_unknown; else { QKeySequence sequence(key); m_qtKey = static_cast(sequence[0]); } } bool CKeyboardKey::addModifier(const Modifier &modifier) { bool added = false; // Don't add the same modifier twice if (hasModifier(modifier)) return false; if (m_modifier1 == ModifierNone) { m_modifier1 = modifier; added = true; } else if (m_modifier2 == ModifierNone) { m_modifier2 = modifier; added = true; } if (added) this->cleanup(); return added; } bool CKeyboardKey::addModifier(const QString &modifier) { return addModifier(modifierFromString(modifier)); } bool CKeyboardKey::removeModifier(const Modifier &modifier) { bool removed = false; if (m_modifier1 == modifier) { m_modifier1 = ModifierNone; removed = true; } if (m_modifier2 == modifier) { m_modifier2 = ModifierNone; removed = true; } cleanup(); return removed; } bool CKeyboardKey::removeModifier(const QString &modifier) { return removeModifier(modifierFromString(modifier)); } bool CKeyboardKey::equalsModifierReleaxed(CKeyboardKey::Modifier m1, CKeyboardKey::Modifier m2) { if (m1 == m2) return true; if (m1 == ModifierAltAny && (m2 == ModifierAltLeft || m2 == ModifierAltRight)) return true; if (m1 == ModifierCtrlAny && (m2 == ModifierCtrlLeft || m2 == ModifierCtrlRight)) return true; if (m1 == ModifierShiftAny && (m2 == ModifierShiftLeft || m2 == ModifierShiftRight)) return true; if (m2 == ModifierAltAny && (m1 == ModifierAltLeft || m1 == ModifierAltRight)) return true; if (m2 == ModifierCtrlAny && (m1 == ModifierCtrlLeft || m1 == ModifierCtrlRight)) return true; if (m2 == ModifierShiftAny && (m1 == ModifierShiftLeft || m1 == ModifierShiftRight)) return true; return false; } void CKeyboardKey::setKeyObject(const CKeyboardKey &key) { this->m_modifier1 = key.m_modifier1; this->m_modifier2 = key.m_modifier2; this->m_qtKey = key.m_qtKey; } bool CKeyboardKey::equalsWithRelaxedModifiers(const CKeyboardKey &key) const { if (key == (*this)) return true; // fully equal, not need to bother // this can never be true if (key.m_qtKey != this->m_qtKey) return false; if (this->numberOfModifiers() != key.numberOfModifiers()) return false; // special modifiers if (this->getModifier1() != key.getModifier1()) { if (!CKeyboardKey::equalsModifierReleaxed(this->getModifier1(), key.getModifier1())) return false; } return CKeyboardKey::equalsModifierReleaxed(this->getModifier1(), key.getModifier1()); } QVariant CKeyboardKey::propertyByIndex(int index) const { switch (index) { case IndexModifier1: return QVariant(static_cast(this->m_modifier1)); case IndexModifier2: return QVariant(static_cast(this->m_modifier2)); case IndexModifier1AsString: return QVariant(this->getModifier1AsString()); case IndexModifier2AsString: return QVariant(this->getModifier2AsString()); case IndexKey: return QVariant(this->m_qtKey); case IndexKeyAsString: return QVariant(QString(QChar(this->m_qtKey))); case IndexKeyAsStringRepresentation: return QVariant(this->getKeyAsStringRepresentation()); 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 IndexKey: case IndexKeyAsString: case IndexKeyAsStringRepresentation: { // static_cast see docu of variant.type() if (static_cast(variant.type()) == QMetaType::QChar) this->setKey(variant.value()); else this->setKey(variant.value()); break; } case IndexModifier1AsString: this->setModifier1(variant.value()); break; case IndexModifier2AsString: this->setModifier2(variant.value()); break; case IndexKeyObject: this->setKeyObject(variant.value()); break; default: Q_ASSERT_X(false, "CKeyboardKey", "index unknown (setter)"); break; } } } // namespace Hardware } // BlackMisc