diff --git a/src/core/key.cpp b/src/core/key.cpp index 6a9bf9d..190fd35 100644 --- a/src/core/key.cpp +++ b/src/core/key.cpp @@ -1,127 +1,132 @@ /* * Copyright 2012 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "key.h" #include "keychar.h" Key::Key(QObject* parent) : AbstractKey(parent), m_fingerIndex(0), m_hasHapticMarker(false) { } QString Key::keyType() const { return "key"; } int Key::fingerIndex() const { return m_fingerIndex; } void Key::setFingerIndex(int finger) { Q_ASSERT(finger >= 0 && finger <= 8); if(finger != m_fingerIndex) { m_fingerIndex = finger; emit fingerIndexChanged(); } } bool Key::hasHapticMarker() const { return m_hasHapticMarker; } void Key::setHasHapticMarker(bool hasHapticMarker) { if(hasHapticMarker != m_hasHapticMarker) { m_hasHapticMarker = hasHapticMarker; emit hasHapticMarkerChanged(); } } +const QList& Key::keyChars() const +{ + return m_keyChars; +} + int Key::keyCharCount() const { return m_keyChars.count(); } KeyChar* Key::keyChar(int index) const { Q_ASSERT(index >= 0 && index < m_keyChars.length()); return m_keyChars.at(index); } void Key::addKeyChar(KeyChar* keyChar) { emit keyCharAboutToBeAdded(keyChar, m_keyChars.length()); m_keyChars.append(keyChar); keyChar->setParent(this); emit keyCharCountChanged(); emit keyCharAdded(); } void Key::insertKeyChar(int index, KeyChar* keyChar) { Q_ASSERT(index >= 0 && index < m_keyChars.length()); emit keyCharAboutToBeAdded(keyChar, index); m_keyChars.insert(index, keyChar); keyChar->setParent(this); emit keyCharCountChanged(); emit keyCharAdded(); } void Key::removeKeyChar(int index) { Q_ASSERT(index >= 0 && index < m_keyChars.length()); emit keyCharsAboutToBeRemoved(index, index); delete m_keyChars.at(index); m_keyChars.removeAt(index); emit keyCharCountChanged(); emit keyCharsRemoved(); } void Key::clearKeyChars() { if (m_keyChars.count() == 0) return; emit keyCharsAboutToBeRemoved(0, m_keyChars.length() - 1); qDeleteAll(m_keyChars); m_keyChars.clear(); emit keyCharCountChanged(); emit keyCharsRemoved(); } void Key::copyFrom(Key* source) { AbstractKey::copyFrom(source); setFingerIndex(source->fingerIndex()); setHasHapticMarker(source->hasHapticMarker()); clearKeyChars(); for (int j = 0; j < source->keyCharCount(); j++) { KeyChar* keyChar = new KeyChar(this); keyChar->copyFrom(source->keyChar(j)); addKeyChar(keyChar); } } diff --git a/src/core/key.h b/src/core/key.h index 30f7cf4..a307346 100644 --- a/src/core/key.h +++ b/src/core/key.h @@ -1,64 +1,65 @@ /* * Copyright 2012 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KEY_H #define KEY_H #include "abstractkey.h" #include class KeyChar; class Key : public AbstractKey { Q_OBJECT Q_PROPERTY(int fingerIndex READ fingerIndex WRITE setFingerIndex NOTIFY fingerIndexChanged) Q_PROPERTY(bool hasHapticMarker READ hasHapticMarker WRITE setHasHapticMarker NOTIFY hasHapticMarkerChanged) Q_PROPERTY(int keyCharCount READ keyCharCount NOTIFY keyCharCountChanged) public: explicit Key(QObject* parent = 0); Q_INVOKABLE QString keyType() const; int fingerIndex() const; void setFingerIndex(int finger); bool hasHapticMarker() const; void setHasHapticMarker(bool hasHapticMarker); + const QList& keyChars() const; int keyCharCount() const; Q_INVOKABLE KeyChar* keyChar(int index) const; Q_INVOKABLE void addKeyChar(KeyChar* keyChar); Q_INVOKABLE void insertKeyChar(int index, KeyChar* keyChar); Q_INVOKABLE void removeKeyChar(int index); Q_INVOKABLE void clearKeyChars(); Q_INVOKABLE void copyFrom(Key* source); signals: void fingerIndexChanged(); void hasHapticMarkerChanged(); void keyCharCountChanged(); void keyCharAboutToBeAdded(KeyChar* keyChar, int index); void keyCharAdded(); void keyCharsAboutToBeRemoved(int first, int last); void keyCharsRemoved(); private: int m_fingerIndex; bool m_hasHapticMarker; QList m_keyChars; }; #endif // KEY_H diff --git a/src/core/keyboardlayout.cpp b/src/core/keyboardlayout.cpp index f16937a..2b378c3 100644 --- a/src/core/keyboardlayout.cpp +++ b/src/core/keyboardlayout.cpp @@ -1,274 +1,292 @@ /* * Copyright 2012 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "keyboardlayout.h" #include #include #include #include #include #include #include #include #include "abstractkey.h" #include "key.h" +#include "keychar.h" #include "specialkey.h" #include "dataindex.h" KeyboardLayout::KeyboardLayout(QObject *parent) : KeyboardLayoutBase(parent), m_associatedDataIndexKeyboardLayout(0), m_title(""), m_name(""), m_width(0), m_height(0), m_keys(QList()), m_referenceKey(0), m_signalMapper(new QSignalMapper(this)) { connect(m_signalMapper, SIGNAL(mapped(int)), SLOT(onKeyGeometryChanged(int))); } DataIndexKeyboardLayout* KeyboardLayout::associatedDataIndexKeyboardLayout() const { return m_associatedDataIndexKeyboardLayout; } void KeyboardLayout::setAssociatedDataIndexKeyboardLayout(DataIndexKeyboardLayout* dataIndexKeyboardLayout) { if (dataIndexKeyboardLayout != m_associatedDataIndexKeyboardLayout) { m_associatedDataIndexKeyboardLayout = dataIndexKeyboardLayout; emit associatedDataIndexKeyboardLayoutChanged(); } } void KeyboardLayout::setId(const QString& id) { KeyboardLayoutBase::setId(id); if (m_associatedDataIndexKeyboardLayout) { m_associatedDataIndexKeyboardLayout->setId(id); } } void KeyboardLayout::setTitle(const QString& title) { KeyboardLayoutBase::setTitle(title); if (m_associatedDataIndexKeyboardLayout) { m_associatedDataIndexKeyboardLayout->setTitle(title); } } void KeyboardLayout::setName(const QString& name) { KeyboardLayoutBase::setName(name); if (m_associatedDataIndexKeyboardLayout) { m_associatedDataIndexKeyboardLayout->setName(name); } } int KeyboardLayout::width() const { return m_width; } void KeyboardLayout::setWidth(int width) { if(width != m_width) { m_width = width; emit widthChanged(); } } int KeyboardLayout::height() const { return m_height; } void KeyboardLayout::setHeight(int height) { if(height != m_height) { m_height = height; emit heightChanged(); } } int KeyboardLayout::keyCount() const { return m_keys.count(); } AbstractKey* KeyboardLayout::referenceKey() { return m_referenceKey; } void KeyboardLayout::copyFrom(KeyboardLayout* source) { setIsValid(false); setTitle(source->title()); setName(source->name()); setWidth(source->width()); setHeight(source->height()); clearKeys(); for(int i = 0; i < source->keyCount(); i++) { AbstractKey* const abstractSourceKey = source->key(i); AbstractKey* abstractKey = 0; Key* const sourceKey = qobject_cast(abstractSourceKey); if (sourceKey) { Key* key = new Key(this); key->copyFrom(sourceKey); abstractKey = key; } SpecialKey* const sourceSpecialKey = qobject_cast(abstractSourceKey); if (sourceSpecialKey) { SpecialKey* specialKey = new SpecialKey(this); specialKey->copyFrom(sourceSpecialKey); abstractKey = specialKey; } addKey(abstractKey); } setIsValid(true); } +QString KeyboardLayout::allCharacters() const +{ + QString result; + for (const auto abstractKey: m_keys) + { + Key* const key = qobject_cast(abstractKey); + if (key) + { + for (const auto keyChar : key->keyChars()) + { + result.append(keyChar->value()); + } + } + } + return result; +} + AbstractKey* KeyboardLayout::key(int index) const { Q_ASSERT(index >= 0 && index < m_keys.count()); return m_keys.at(index); } int KeyboardLayout::keyIndex(AbstractKey* key) const { return m_keys.indexOf(key); } void KeyboardLayout::addKey(AbstractKey* key) { m_keys.append(key); key->setParent(this); connect(key, SIGNAL(widthChanged()), m_signalMapper, SLOT(map())); connect(key, SIGNAL(heightChanged()), m_signalMapper, SLOT(map())); m_signalMapper->setMapping(key, m_keys.count() - 1); emit keyCountChanged(); updateReferenceKey(key); } void KeyboardLayout::insertKey(int index, AbstractKey* key) { m_keys.insert(index, key); key->setParent(this); connect(key, SIGNAL(widthChanged()), m_signalMapper, SLOT(map())); connect(key, SIGNAL(heightChanged()), m_signalMapper, SLOT(map())); m_signalMapper->setMapping(key, m_keys.count() - 1); emit keyCountChanged(); updateReferenceKey(key); } void KeyboardLayout::removeKey(int index) { Q_ASSERT(index >= 0 && index < m_keys.count()); AbstractKey* key = m_keys.at(index); m_keys.removeAt(index); emit keyCountChanged(); updateReferenceKey(0); key->deleteLater(); } void KeyboardLayout::clearKeys() { if (m_keys.count() == 0) return; qDeleteAll(m_keys); m_keys.clear(); emit keyCountChanged(); updateReferenceKey(0); } QSize KeyboardLayout::size() const { return QSize(m_width, m_height); } void KeyboardLayout::setSize(const QSize& size) { setWidth(size.width()); setHeight(size.height()); } void KeyboardLayout::onKeyGeometryChanged(int keyIndex) { updateReferenceKey(key(keyIndex)); } void KeyboardLayout::updateReferenceKey(AbstractKey *testKey) { if (testKey) { if (!m_referenceKey) { m_referenceKey = testKey; emit referenceKeyChanged(); return; } if (compareKeysForReference(testKey, m_referenceKey)) { m_referenceKey = testKey; emit referenceKeyChanged(); return; } } AbstractKey* canditate = 0; foreach(AbstractKey* key, m_keys) { if (canditate == 0) { canditate = key; } else { if (compareKeysForReference(key, canditate)) { canditate = key; } } } m_referenceKey = canditate; emit referenceKeyChanged(); } bool KeyboardLayout::compareKeysForReference(const AbstractKey *testKey, const AbstractKey *compareKey) const { return testKey->width() * testKey->height() < compareKey->width() * compareKey->height(); } diff --git a/src/core/keyboardlayout.h b/src/core/keyboardlayout.h index b076e59..6989425 100644 --- a/src/core/keyboardlayout.h +++ b/src/core/keyboardlayout.h @@ -1,87 +1,88 @@ /* * Copyright 2012 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KEYBOARD_H #define KEYBOARD_H #include "keyboardlayoutbase.h" #include #include class QSignalMapper; class AbstractKey; class DataIndexKeyboardLayout; class KeyboardLayout : public KeyboardLayoutBase { Q_OBJECT Q_PROPERTY(DataIndexKeyboardLayout* associatedDataIndexKeyboardLayout READ associatedDataIndexKeyboardLayout WRITE setAssociatedDataIndexKeyboardLayout NOTIFY associatedDataIndexKeyboardLayoutChanged) Q_PROPERTY(AbstractKey* referenceKey READ referenceKey NOTIFY referenceKeyChanged) Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) Q_PROPERTY(int keyCount READ keyCount NOTIFY keyCountChanged) public: explicit KeyboardLayout(QObject* parent = 0); DataIndexKeyboardLayout* associatedDataIndexKeyboardLayout() const; void setAssociatedDataIndexKeyboardLayout(DataIndexKeyboardLayout* dataIndexKeyboardLayout); void setId(const QString& id); void setTitle(const QString& title); void setName(const QString& name); int width() const ; void setWidth(int width); int height() const; void setHeight(int height); int keyCount() const; Q_INVOKABLE AbstractKey* key(int index) const; Q_INVOKABLE int keyIndex(AbstractKey* key) const; Q_INVOKABLE void addKey(AbstractKey* key); Q_INVOKABLE void insertKey(int index, AbstractKey* key); Q_INVOKABLE void removeKey(int index); Q_INVOKABLE void clearKeys(); AbstractKey* referenceKey(); Q_INVOKABLE void copyFrom(KeyboardLayout* source); + Q_INVOKABLE QString allCharacters() const; QSize size() const; void setSize(const QSize& size); signals: void associatedDataIndexKeyboardLayoutChanged(); void widthChanged(); void heightChanged(); void referenceKeyChanged(); void keyCountChanged(); private slots: void onKeyGeometryChanged(int keyIndex); private: void updateReferenceKey(AbstractKey* newKey=0); bool compareKeysForReference(const AbstractKey* testKey, const AbstractKey* compareKey) const; DataIndexKeyboardLayout* m_associatedDataIndexKeyboardLayout; QString m_title; QString m_name; int m_width; int m_height; QList m_keys; AbstractKey* m_referenceKey; QSignalMapper* m_signalMapper; }; #endif // KEYBOARD_H