diff --git a/src/MPDeviceBleImpl.cpp b/src/MPDeviceBleImpl.cpp index 3f91bcf2..c2fcb052 100644 --- a/src/MPDeviceBleImpl.cpp +++ b/src/MPDeviceBleImpl.cpp @@ -557,6 +557,79 @@ QList MPDeviceBleImpl::getFavorites(const QByteArray &data) return res; } +void MPDeviceBleImpl::readLanguages() +{ + m_deviceLanguages = QJsonObject{}; + m_keyboardLayouts = QJsonObject{}; + AsyncJobs *jobs = new AsyncJobs( + "Read languages", + this); + jobs->append(new MPCommandJob(mpDev, + MPCmd::GET_LANG_NUM, + [this, jobs] (const QByteArray &data, bool &) + { + const auto payload = bleProt->getFullPayload(data); + const int langNum = bleProt->toIntFromLittleEndian(payload[0], payload[1]); + qDebug() << "Language number: " << langNum; + for (int i = 0; i < langNum; ++i) + { + jobs->append(new MPCommandJob(mpDev, + MPCmd::GET_LANG_DESC, + QByteArray(1, static_cast(i)), + [this, i, langNum] (const QByteArray &data, bool &) + { + const QString lang = bleProt->toQString(bleProt->getFullPayload(data)); + if (AppDaemon::isDebugDev()) + { + qDebug() << i << " lang desc: " << lang; + } + m_deviceLanguages[lang] = i; + if (i == (langNum - 1)) + { + emit bleDeviceLanguage(m_deviceLanguages); + } + return true; + } + )); + } + return true; + } + )); + jobs->append(new MPCommandJob(mpDev, + MPCmd::GET_KEYB_LAYOUT_NUM, + [this, jobs] (const QByteArray &data, bool &) + { + const auto payload = bleProt->getFullPayload(data); + const auto layoutNum = bleProt->toIntFromLittleEndian(payload[0], payload[1]); + qDebug() << "Keyboard layout number: " << layoutNum; + for (int i = 0; i < layoutNum; ++i) + { + jobs->append(new MPCommandJob(mpDev, + MPCmd::GET_LAYOUT_DESC, + QByteArray(1, static_cast(i)), + [this, i, layoutNum] (const QByteArray &data, bool &) + { + const QString layout = bleProt->toQString(bleProt->getFullPayload(data)); + if (AppDaemon::isDebugDev()) + { + qDebug() << i << " layout desc: " << layout; + } + m_keyboardLayouts[layout] = i; + if (i == (layoutNum - 1)) + { + emit bleKeyboardLayout(m_keyboardLayouts); + } + return true; + } + )); + } + return true; + } + )); + + mpDev->enqueueAndRunJob(jobs); +} + QByteArray MPDeviceBleImpl::createStoreCredMessage(const BleCredential &cred) { return createCredentialMessage(cred.getAttributes()); diff --git a/src/MPDeviceBleImpl.h b/src/MPDeviceBleImpl.h index d4279b0a..98a46930 100644 --- a/src/MPDeviceBleImpl.h +++ b/src/MPDeviceBleImpl.h @@ -89,8 +89,12 @@ class MPDeviceBleImpl: public QObject QList getFavorites(const QByteArray& data); + void readLanguages(); + signals: void userSettingsChanged(QJsonObject settings); + void bleDeviceLanguage(const QJsonObject& langs); + void bleKeyboardLayout(const QJsonObject& layouts); private: void checkDataFlash(const QByteArray &data, QElapsedTimer *timer, AsyncJobs *jobs, QString filePath, const MPDeviceProgressCb &cbProgress); @@ -115,6 +119,8 @@ class MPDeviceBleImpl: public QObject MPBLEFreeAddressProvider freeAddressProv; QJsonObject m_categories; + QJsonObject m_deviceLanguages; + QJsonObject m_keyboardLayouts; static constexpr quint8 MESSAGE_FLIP_BIT = 0x80; static constexpr quint8 MESSAGE_ACK_AND_PAYLOAD_LENGTH = 0x7F; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 1c727c41..581a0603 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -31,6 +31,11 @@ #include "qtcsv/stringdata.h" #include "qtcsv/reader.h" +const QString MainWindow::NONE_STRING = tr("None"); +const QString MainWindow::TAB_STRING = tr("Tab"); +const QString MainWindow::ENTER_STRING = tr("Enter"); +const QString MainWindow::SPACE_STRING = tr("Space"); + void MainWindow::initHelpLabels() { auto getFontAwesomeIconPixmap = [=](int character, QSize size = QSize(20, 20)) @@ -254,12 +259,6 @@ MainWindow::MainWindow(WSClient *client, DbMasterController *mc, QWidget *parent ui->comboBoxKnock->addItem(tr("Low"), 1); ui->comboBoxKnock->addItem(tr("Medium"), 2); ui->comboBoxKnock->addItem(tr("High"), 3); - ui->comboBoxLoginOutput->addItem(tr("Tab"), 43); - ui->comboBoxLoginOutput->addItem(tr("Enter"), 40); - ui->comboBoxLoginOutput->addItem(tr("Space"), 44); - ui->comboBoxPasswordOutput->addItem(tr("Tab"), 43); - ui->comboBoxPasswordOutput->addItem(tr("Enter"), 40); - ui->comboBoxPasswordOutput->addItem(tr("Space"), 44); // Close behavior #ifdef Q_OS_MAC @@ -348,6 +347,23 @@ MainWindow::MainWindow(WSClient *client, DbMasterController *mc, QWidget *parent ui->cbCredentialPrompt->setChecked(settings["storage_prompt"].toBool()); }); + connect(wsClient, &WSClient::updateBLEDeviceLanguage, + [this](const QJsonObject& langs) + { + updateBLEComboboxItems(ui->comboBoxDeviceLang, langs); + updateBLEComboboxItems(ui->comboBoxUserLanguage, langs); + } + ); + connect(wsClient, &WSClient::updateBLEKeyboardLayout, + [this](const QJsonObject& layouts) + { + updateBLEComboboxItems(ui->comboBoxUsbLayout, layouts); + updateBLEComboboxItems(ui->comboBoxBtLayout, layouts); + wsClient->settingsHelper()->resetSettings(); + } + ); + + //When device has new parameters, update the GUI connect(wsClient, &WSClient::mpHwVersionChanged, [=]() { @@ -1378,6 +1394,20 @@ void MainWindow::displayMCUVersion(bool visible) ui->labelAboutMainMCUValue->setText(wsClient->get_mainMCUVersion()); } +void MainWindow::updateBLEComboboxItems(QComboBox *cb, const QJsonObject& items) +{ + cb->clear(); + for (auto it = items.begin(); it != items.end(); ++it) + { + cb->addItem(it.key(), it.value().toInt()); + } + QSortFilterProxyModel* proxy = new QSortFilterProxyModel(cb); + proxy->setSourceModel( cb->model()); + cb->model()->setParent(proxy); + cb->setModel(proxy); + cb->model()->sort(0); +} + void MainWindow::on_toolButton_clearBackupFilePath_released() { ui->lineEdit_dbBackupFilePath->clear(); diff --git a/src/MainWindow.h b/src/MainWindow.h index 380c1632..ea9af9c3 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -60,6 +60,12 @@ class MainWindow : public QMainWindow void updateBackupControlsVisibility(bool visible); + + const static QString NONE_STRING; + const static QString TAB_STRING; + const static QString ENTER_STRING; + const static QString SPACE_STRING; + friend class SettingsGuiHelper; friend class SettingsGuiMini; friend class SettingsGuiBLE; @@ -174,6 +180,8 @@ private slots: void displayMCUVersion(bool visible = true); + void updateBLEComboboxItems(QComboBox *cb, const QJsonObject& items); + Ui::MainWindow *ui = nullptr; QtAwesome* awesome; @@ -203,7 +211,6 @@ private slots: SystemEventHandler eventHandler; const QString HIBP_URL = "https://haveibeenpwned.com/Passwords"; - const QString NONE_STRING = tr("None"); }; #endif // MAINWINDOW_H diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 9eaa9073..ced8c823 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -576,6 +576,170 @@ Hint: keep your mouse positioned over an option to get more details. + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + USB Layout + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Bluetooth Layout + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Device Language + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + User Language + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -596,6 +760,13 @@ Hint: keep your mouse positioned over an option to get more details. + + + + + + + For slow computers: wait @@ -660,6 +831,13 @@ Hint: keep your mouse positioned over an option to get more details. + + + + + + + Send @@ -718,6 +896,13 @@ Hint: keep your mouse positioned over an option to get more details. + + + + + + + Send @@ -1176,6 +1361,13 @@ Hint: keep your mouse positioned over an option to get more details. + + + + Boot Animation + + + diff --git a/src/MessageProtocol/MessageProtocolBLE.cpp b/src/MessageProtocol/MessageProtocolBLE.cpp index 6e49ea76..113a956b 100644 --- a/src/MessageProtocol/MessageProtocolBLE.cpp +++ b/src/MessageProtocol/MessageProtocolBLE.cpp @@ -342,6 +342,16 @@ void MessageProtocolBLE::fillCommandMapping() {MPCmd::GET_USER_SETTINGS , 0x0013}, {MPCmd::GET_USER_CATEGORIES , 0x0014}, {MPCmd::SET_USER_CATEGORIES , 0x0015}, + {MPCmd::GET_USER_LANG , 0x0016}, + {MPCmd::GET_DEVICE_LANG , 0x0017}, + {MPCmd::GET_KEYB_LAYOUT_ID , 0x0018}, + {MPCmd::GET_LANG_NUM , 0x0019}, + {MPCmd::GET_KEYB_LAYOUT_NUM , 0x001A}, + {MPCmd::GET_LANG_DESC , 0x001B}, + {MPCmd::GET_LAYOUT_DESC , 0x001C}, + {MPCmd::SET_KEYB_LAYOUT_ID , 0x001D}, + {MPCmd::SET_USER_LANG , 0x001E}, + {MPCmd::SET_DEVICE_LANG , 0x001F}, {MPCmd::CMD_DBG_OPEN_DISP_BUFFER , 0x8001}, {MPCmd::CMD_DBG_SEND_TO_DISP_BUFFER , 0x8002}, {MPCmd::CMD_DBG_CLOSE_DISP_BUFFER , 0x8003}, diff --git a/src/Mooltipass/MPSettingsBLE.cpp b/src/Mooltipass/MPSettingsBLE.cpp index c979beb2..735f3dd4 100644 --- a/src/Mooltipass/MPSettingsBLE.cpp +++ b/src/Mooltipass/MPSettingsBLE.cpp @@ -18,21 +18,66 @@ void MPSettingsBLE::loadParameters() "Loading device parameters", this); - //TODO: Implement loading correct settings, when implemented on fw side jobs->append(new MPCommandJob(mpDevice, MPCmd::GET_DEVICE_SETTINGS, [this] (const QByteArray &data, bool &) { m_lastDeviceSettings = pMesProt->getFullPayload(data); qDebug() << "Full device settings payload: " << m_lastDeviceSettings.toHex(); - qWarning() << "Load Parameters processing haven't been implemented for BLE yet."; set_reserved_ble(m_lastDeviceSettings.at(DeviceSettingsBLE::RESERVED_BYTE) != 0); set_user_interaction_timeout(m_lastDeviceSettings.at(DeviceSettingsBLE::USER_INTERACTION_TIMEOUT_BYTE)); set_random_starting_pin(m_lastDeviceSettings.at(DeviceSettingsBLE::RANDOM_PIN_BYTE) != 0); set_prompt_animation(m_lastDeviceSettings.at(DeviceSettingsBLE::ANIMATION_DURING_PROMPT_BYTE) != 0); + set_key_after_login(m_lastDeviceSettings.at(DeviceSettingsBLE::DEFAULT_CHAR_AFTER_LOGIN)); + set_key_after_pass(m_lastDeviceSettings.at(DeviceSettingsBLE::DEFAULT_CHAR_AFTER_PASS)); + set_delay_after_key(m_lastDeviceSettings.at(DeviceSettingsBLE::DELAY_BETWEEN_KEY_PRESS)); + set_bool_animation(m_lastDeviceSettings.at(DeviceSettingsBLE::BOOT_ANIMATION_BYTE) != 0); return true; } )); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::GET_USER_LANG, + [this] (const QByteArray &data, bool &) + { + const auto langId = pMesProt->getFirstPayloadByte(data); + qDebug() << "User language: " << langId; + set_user_language(langId); + return true; + } + )); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::GET_DEVICE_LANG, + [this] (const QByteArray &data, bool &) + { + const auto langId = pMesProt->getFirstPayloadByte(data); + qDebug() << "Device language: " << langId; + set_device_language(langId); + return true; + } + )); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::GET_KEYB_LAYOUT_ID, + QByteArray(1, USB_LAYOUT_ID), + [this] (const QByteArray &data, bool &) + { + const auto layoutId = pMesProt->getFirstPayloadByte(data); + qDebug() << "Keyboard USB layout: " << layoutId; + set_keyboard_usb_layout(layoutId); + return true; + } + )); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::GET_KEYB_LAYOUT_ID, + QByteArray(1, BT_LAYOUT_ID), + [this] (const QByteArray &data, bool &) + { + const auto layoutId = pMesProt->getFirstPayloadByte(data); + qDebug() << "Keyboard Bluetooth layout: " << layoutId; + set_keyboard_bt_layout(layoutId); + return true; + } + )); + mpDevice->enqueueAndRunJob(jobs); return; } @@ -43,6 +88,10 @@ void MPSettingsBLE::updateParam(MPParams::Param param, int val) { m_lastDeviceSettings[m_bleByteMapping[param]] = static_cast(val); } + else + { + setProperty(m_paramMap[param], val); + } } void MPSettingsBLE::connectSendParams(QObject *slotObject) @@ -73,6 +122,33 @@ void MPSettingsBLE::setSettings() return true; } )); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::SET_USER_LANG, + QByteArray(1, get_user_language()), + pMesProt->getDefaultFuncDone() + )); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::SET_DEVICE_LANG, + QByteArray(1, get_device_language()), + pMesProt->getDefaultFuncDone() + )); + QByteArray layoutUsbData; + layoutUsbData.append(USB_LAYOUT_ID); + layoutUsbData.append(get_keyboard_usb_layout()); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::SET_KEYB_LAYOUT_ID, + layoutUsbData, + pMesProt->getDefaultFuncDone() + )); + QByteArray layoutBtData; + layoutBtData.append(BT_LAYOUT_ID); + layoutBtData.append(get_keyboard_bt_layout()); + jobs->append(new MPCommandJob(mpDevice, + MPCmd::SET_KEYB_LAYOUT_ID, + layoutBtData, + pMesProt->getDefaultFuncDone() + )); + mpDevice->enqueueAndRunJob(jobs); } diff --git a/src/MooltipassCmds.h b/src/MooltipassCmds.h index 7b7edfef..6aa2425f 100644 --- a/src/MooltipassCmds.h +++ b/src/MooltipassCmds.h @@ -138,6 +138,16 @@ class MPCmd: public QObject GET_USER_SETTINGS , GET_USER_CATEGORIES , SET_USER_CATEGORIES , + GET_USER_LANG , + GET_DEVICE_LANG , + GET_KEYB_LAYOUT_ID , + GET_LANG_NUM , + GET_KEYB_LAYOUT_NUM , + GET_LANG_DESC , + GET_LAYOUT_DESC , + SET_KEYB_LAYOUT_ID , + SET_USER_LANG , + SET_DEVICE_LANG , CMD_DBG_MESSAGE , CMD_DBG_OPEN_DISP_BUFFER , CMD_DBG_SEND_TO_DISP_BUFFER , @@ -202,7 +212,12 @@ class MPParams: public QObject HASH_DISPLAY_FEATURE_PARAM, RANDOM_INIT_PIN_PARAM, RESERVED_BLE, - PROMPT_ANIMATION_PARAM + PROMPT_ANIMATION_PARAM, + BOOT_ANIMATION_PARAM, + DEVICE_LANGUAGE, + USER_LANGUAGE, + KEYBOARD_USB_LAYOUT, + KEYBOARD_BT_LAYOUT }; Q_ENUM(Param) }; diff --git a/src/Settings/DeviceSettings.cpp b/src/Settings/DeviceSettings.cpp index 1bd01be9..e0435bf1 100644 --- a/src/Settings/DeviceSettings.cpp +++ b/src/Settings/DeviceSettings.cpp @@ -112,6 +112,9 @@ void DeviceSettings::updateParam(MPParams::Param param, bool en) void DeviceSettings::fillParameterMapping() { m_paramMap = { + {MPParams::KEY_AFTER_LOGIN_SEND_PARAM, "key_after_login"}, + {MPParams::KEY_AFTER_PASS_SEND_PARAM, "key_after_pass"}, + {MPParams::DELAY_AFTER_KEY_ENTRY_PARAM, "delay_after_key"}, {MPParams::USER_INTER_TIMEOUT_PARAM, "user_interaction_timeout"}, {MPParams::RANDOM_INIT_PIN_PARAM, "random_starting_pin"} }; diff --git a/src/Settings/DeviceSettings.h b/src/Settings/DeviceSettings.h index ba82ea48..27fe64dc 100644 --- a/src/Settings/DeviceSettings.h +++ b/src/Settings/DeviceSettings.h @@ -10,6 +10,10 @@ class DeviceSettings : public QObject { Q_OBJECT + QT_SETTINGS_PROPERTY(int, key_after_login, 0, MPParams::KEY_AFTER_LOGIN_SEND_PARAM) + QT_SETTINGS_PROPERTY(int, key_after_pass, 0, MPParams::KEY_AFTER_PASS_SEND_PARAM) + QT_SETTINGS_PROPERTY(int, delay_after_key, 0, MPParams::DELAY_AFTER_KEY_ENTRY_PARAM) + QT_SETTINGS_PROPERTY(int, user_interaction_timeout, 0, MPParams::USER_INTER_TIMEOUT_PARAM) QT_SETTINGS_PROPERTY(bool, random_starting_pin, false, MPParams::RANDOM_INIT_PIN_PARAM) @@ -35,6 +39,7 @@ class DeviceSettings : public QObject virtual void loadParameters() = 0; virtual void updateParam(MPParams::Param param, int val) = 0; void updateParam(MPParams::Param param, bool en); + virtual void setupKeyboardLayout() {} const QMetaObject* getMetaObject() const {return metaObject();} diff --git a/src/Settings/DeviceSettingsBLE.cpp b/src/Settings/DeviceSettingsBLE.cpp index 51ab961b..179e04d6 100644 --- a/src/Settings/DeviceSettingsBLE.cpp +++ b/src/Settings/DeviceSettingsBLE.cpp @@ -8,11 +8,20 @@ DeviceSettingsBLE::DeviceSettingsBLE(QObject *parent) void DeviceSettingsBLE::fillParameterMapping() { + m_paramMap.insert(MPParams::KEYBOARD_USB_LAYOUT, "keyboard_usb_layout"); + m_paramMap.insert(MPParams::KEYBOARD_BT_LAYOUT, "keyboard_bt_layout"); + m_paramMap.insert(MPParams::DEVICE_LANGUAGE, "device_language"); + m_paramMap.insert(MPParams::USER_LANGUAGE, "user_language"); m_bleByteMapping[MPParams::RANDOM_INIT_PIN_PARAM] = RANDOM_PIN_BYTE; m_bleByteMapping[MPParams::USER_INTER_TIMEOUT_PARAM] = USER_INTERACTION_TIMEOUT_BYTE; + m_bleByteMapping[MPParams::KEY_AFTER_LOGIN_SEND_PARAM] = DEFAULT_CHAR_AFTER_LOGIN; + m_bleByteMapping[MPParams::KEY_AFTER_PASS_SEND_PARAM] = DEFAULT_CHAR_AFTER_PASS; + m_bleByteMapping[MPParams::DELAY_AFTER_KEY_ENTRY_PARAM] = DELAY_BETWEEN_KEY_PRESS; m_paramMap.insert(MPParams::RESERVED_BLE, "reserved_ble"); m_bleByteMapping[MPParams::RESERVED_BLE] = RESERVED_BYTE; m_paramMap.insert(MPParams::PROMPT_ANIMATION_PARAM, "prompt_animation"); m_bleByteMapping[MPParams::PROMPT_ANIMATION_PARAM] = ANIMATION_DURING_PROMPT_BYTE; + m_paramMap.insert(MPParams::BOOT_ANIMATION_PARAM, "bool_animation"); + m_bleByteMapping[MPParams::BOOT_ANIMATION_PARAM] = BOOT_ANIMATION_BYTE; } diff --git a/src/Settings/DeviceSettingsBLE.h b/src/Settings/DeviceSettingsBLE.h index 58276311..7e1ed04e 100644 --- a/src/Settings/DeviceSettingsBLE.h +++ b/src/Settings/DeviceSettingsBLE.h @@ -8,8 +8,13 @@ class DeviceSettingsBLE : public DeviceSettings Q_OBJECT //MP BLE only + QT_SETTINGS_PROPERTY(int, keyboard_usb_layout, 0, MPParams::KEYBOARD_USB_LAYOUT) + QT_SETTINGS_PROPERTY(int, keyboard_bt_layout, 0, MPParams::KEYBOARD_BT_LAYOUT) + QT_SETTINGS_PROPERTY(int, device_language, 0, MPParams::DEVICE_LANGUAGE) + QT_SETTINGS_PROPERTY(int, user_language, 0, MPParams::USER_LANGUAGE) QT_SETTINGS_PROPERTY(bool, reserved_ble, false, MPParams::RESERVED_BLE) QT_SETTINGS_PROPERTY(bool, prompt_animation, false, MPParams::PROMPT_ANIMATION_PARAM) + QT_SETTINGS_PROPERTY(bool, bool_animation, false, MPParams::BOOT_ANIMATION_PARAM) public: DeviceSettingsBLE(QObject *parent); @@ -20,9 +25,17 @@ class DeviceSettingsBLE : public DeviceSettings RESERVED_BYTE = 0, RANDOM_PIN_BYTE = 1, USER_INTERACTION_TIMEOUT_BYTE = 2, - ANIMATION_DURING_PROMPT_BYTE = 3 + ANIMATION_DURING_PROMPT_BYTE = 3, + DEVICE_DEFAULT_LANG = 4, + DEFAULT_CHAR_AFTER_LOGIN = 5, + DEFAULT_CHAR_AFTER_PASS = 6, + DELAY_BETWEEN_KEY_PRESS = 7, + BOOT_ANIMATION_BYTE = 8 }; + static constexpr char USB_LAYOUT_ID = 0x01; + static constexpr char BT_LAYOUT_ID = 0x00; + protected: void fillParameterMapping(); QMap m_bleByteMapping; diff --git a/src/Settings/DeviceSettingsMini.cpp b/src/Settings/DeviceSettingsMini.cpp index e3891f7d..875e9ac1 100644 --- a/src/Settings/DeviceSettingsMini.cpp +++ b/src/Settings/DeviceSettingsMini.cpp @@ -36,11 +36,8 @@ void DeviceSettingsMini::fillParameterMapping() m_paramMap.insert(MPParams::OFFLINE_MODE_PARAM, "offline_mode"); m_paramMap.insert(MPParams::TUTORIAL_BOOL_PARAM, "tutorial_enabled"); m_paramMap.insert(MPParams::KEY_AFTER_LOGIN_SEND_BOOL_PARAM, "key_after_login_enabled"); - m_paramMap.insert(MPParams::KEY_AFTER_LOGIN_SEND_PARAM, "key_after_login"); m_paramMap.insert(MPParams::KEY_AFTER_PASS_SEND_BOOL_PARAM, "key_after_pass_enabled"); - m_paramMap.insert(MPParams::KEY_AFTER_PASS_SEND_PARAM, "key_after_pass"); m_paramMap.insert(MPParams::DELAY_AFTER_KEY_ENTRY_BOOL_PARAM, "delay_after_key_enabled"); - m_paramMap.insert(MPParams::DELAY_AFTER_KEY_ENTRY_PARAM, "delay_after_key"); m_paramMap.insert(MPParams::MINI_OLED_CONTRAST_CURRENT_PARAM, "screen_brightness"); m_paramMap.insert(MPParams::MINI_KNOCK_DETECT_ENABLE_PARAM, "knock_enabled"); m_paramMap.insert(MPParams::MINI_KNOCK_THRES_PARAM, "knock_sensitivity"); diff --git a/src/Settings/DeviceSettingsMini.h b/src/Settings/DeviceSettingsMini.h index 97d67a7c..9b250223 100644 --- a/src/Settings/DeviceSettingsMini.h +++ b/src/Settings/DeviceSettingsMini.h @@ -18,11 +18,8 @@ class DeviceSettingsMini : public DeviceSettings QT_SETTINGS_PROPERTY(bool, tutorial_enabled, false, MPParams::TUTORIAL_BOOL_PARAM) QT_SETTINGS_PROPERTY(bool, key_after_login_enabled, false, MPParams::KEY_AFTER_LOGIN_SEND_BOOL_PARAM) - QT_SETTINGS_PROPERTY(int, key_after_login, 0, MPParams::KEY_AFTER_LOGIN_SEND_PARAM) QT_SETTINGS_PROPERTY(bool, key_after_pass_enabled, false, MPParams::KEY_AFTER_PASS_SEND_BOOL_PARAM) - QT_SETTINGS_PROPERTY(int, key_after_pass, 0, MPParams::KEY_AFTER_PASS_SEND_PARAM) QT_SETTINGS_PROPERTY(bool, delay_after_key_enabled, false, MPParams::DELAY_AFTER_KEY_ENTRY_BOOL_PARAM) - QT_SETTINGS_PROPERTY(int, delay_after_key, 0, MPParams::DELAY_AFTER_KEY_ENTRY_PARAM) //MP Mini only QT_SETTINGS_PROPERTY(int, screen_brightness, 0, MPParams::MINI_OLED_CONTRAST_CURRENT_PARAM) //51-20%, 89-35%, 128-50%, 166-65%, 204-80%, 255-100% diff --git a/src/Settings/SettingsGuiBLE.cpp b/src/Settings/SettingsGuiBLE.cpp index b74d2aad..c1f30031 100644 --- a/src/Settings/SettingsGuiBLE.cpp +++ b/src/Settings/SettingsGuiBLE.cpp @@ -21,13 +21,45 @@ void SettingsGuiBLE::updateParam(MPParams::Param param, int val) void SettingsGuiBLE::updateUI() { - ui->groupBox_keyboard->hide(); + // Keyboard groupbox + ui->comboBoxLoginOutput->clear(); + ui->comboBoxLoginOutput->addItem(MainWindow::NONE_STRING, NONE_INDEX); + ui->comboBoxLoginOutput->addItem(MainWindow::TAB_STRING, TAB_INDEX); + ui->comboBoxLoginOutput->addItem(MainWindow::ENTER_STRING, ENTER_INDEX); + ui->comboBoxLoginOutput->addItem(MainWindow::SPACE_STRING, SPACE_INDEX); + ui->comboBoxPasswordOutput->clear(); + ui->comboBoxPasswordOutput->addItem(MainWindow::NONE_STRING, NONE_INDEX); + ui->comboBoxPasswordOutput->addItem(MainWindow::TAB_STRING, TAB_INDEX); + ui->comboBoxPasswordOutput->addItem(MainWindow::ENTER_STRING, ENTER_INDEX); + ui->comboBoxPasswordOutput->addItem(MainWindow::SPACE_STRING, SPACE_INDEX); + ui->checkBoxSlowHost->hide(); + ui->checkBoxSendAfterLogin->hide(); + ui->checkBoxSendAfterPassword->hide(); + ui->settings_keyboard_layout->hide(); + ui->settings_usb_layout->show(); + ui->settings_bt_layout->show(); + ui->settings_user_language->show(); + ui->settings_device_language->show(); + + // Miscellaneous groupbox ui->groupBox_miscellaneous->hide(); + ui->groupBox_BLESettings->show(); ui->checkBoxBLEReserved->hide(); + // Inactivity groupbox ui->settings_inactivity_lock->hide(); ui->checkBoxScreensaver->hide(); ui->hashDisplayFeatureCheckBox->hide(); ui->settings_advanced_lockunlock->hide(); } + +void SettingsGuiBLE::setupKeyboardLayout() +{ + if (ui->comboBoxUsbLayout->count() > 0) + { + //Combobox for BLE layouts is filled + return; + } + m_mw->wsClient->requestBleKeyboardLayout(); +} diff --git a/src/Settings/SettingsGuiBLE.h b/src/Settings/SettingsGuiBLE.h index 150f1b01..90e3ffc2 100644 --- a/src/Settings/SettingsGuiBLE.h +++ b/src/Settings/SettingsGuiBLE.h @@ -15,6 +15,12 @@ class SettingsGuiBLE : public DeviceSettingsBLE, public ISettingsGui void loadParameters() override; void updateParam(MPParams::Param param, int val) override; void updateUI() override; + void setupKeyboardLayout() override; + + static const int NONE_INDEX = 0; + static const int TAB_INDEX = 9; + static const int ENTER_INDEX = 10; + static const int SPACE_INDEX = 32; }; #endif // SETTINGSGUIBLE_H diff --git a/src/Settings/SettingsGuiHelper.cpp b/src/Settings/SettingsGuiHelper.cpp index 77b3fd07..17f92159 100644 --- a/src/Settings/SettingsGuiHelper.cpp +++ b/src/Settings/SettingsGuiHelper.cpp @@ -44,9 +44,13 @@ void SettingsGuiHelper::setMainWindow(MainWindow *mw) {MPParams::HASH_DISPLAY_FEATURE_PARAM, ui->hashDisplayFeatureCheckBox}, {MPParams::LOCK_UNLOCK_FEATURE_PARAM, ui->lockUnlockModeComboBox}, {MPParams::RESERVED_BLE, ui->checkBoxBLEReserved}, - {MPParams::PROMPT_ANIMATION_PARAM, ui->checkBoxPromptAnim} + {MPParams::PROMPT_ANIMATION_PARAM, ui->checkBoxPromptAnim}, + {MPParams::DEVICE_LANGUAGE, ui->comboBoxDeviceLang}, + {MPParams::USER_LANGUAGE, ui->comboBoxUserLanguage}, + {MPParams::KEYBOARD_USB_LAYOUT, ui->comboBoxUsbLayout}, + {MPParams::KEYBOARD_BT_LAYOUT, ui->comboBoxBtLayout}, + {MPParams::BOOT_ANIMATION_PARAM, ui->checkBoxBootAnim} }; - setupKeyboardLayout(); //When something changed in GUI, show save/reset buttons for (const auto& widget : m_widgetMapping) { @@ -86,6 +90,7 @@ void SettingsGuiHelper::createSettingUIMapping() return; } + m_settings->setupKeyboardLayout(); m_settings->connectSendParams(this); dynamic_cast(m_settings)->updateUI(); } @@ -236,6 +241,10 @@ void SettingsGuiHelper::sendParams(int value, int param) void SettingsGuiHelper::checkKeyboardLayout() { + if (m_wsClient->isMPBLE()) + { + return; + } const auto containsFw13LangLayouts = ui->comboBoxLang->findText(m_fw13LangMap.firstKey()) != -1; const bool isFw13 = m_wsClient->isFw13(); if (!containsFw13LangLayouts && isFw13) @@ -254,44 +263,3 @@ void SettingsGuiHelper::checkKeyboardLayout() } } } - -void SettingsGuiHelper::setupKeyboardLayout() -{ - //Add languages to combobox - auto* langCb = ui->comboBoxLang; - langCb->addItem("en_US", ID_KEYB_EN_US_LUT); - langCb->addItem("fr_FR", ID_KEYB_FR_FR_LUT); - langCb->addItem("es_ES", ID_KEYB_ES_ES_LUT); - langCb->addItem("de_DE", ID_KEYB_DE_DE_LUT); - langCb->addItem("es_AR", ID_KEYB_ES_AR_LUT); - langCb->addItem("en_AU", ID_KEYB_EN_AU_LUT); - langCb->addItem("fr_BE", ID_KEYB_FR_BE_LUT); - langCb->addItem("po_BR", ID_KEYB_PO_BR_LUT); - langCb->addItem("en_CA", ID_KEYB_EN_CA_LUT); - langCb->addItem("cz_CZ", ID_KEYB_CZ_CZ_LUT); - langCb->addItem("da_DK", ID_KEYB_DA_DK_LUT); - langCb->addItem("fi_FI", ID_KEYB_FI_FI_LUT); - langCb->addItem("hu_HU", ID_KEYB_HU_HU_LUT); - langCb->addItem("is_IS", ID_KEYB_IS_IS_LUT); - langCb->addItem("it_IT", ID_KEYB_IT_IT_LUT); - langCb->addItem("nl_NL", ID_KEYB_NL_NL_LUT); - langCb->addItem("no_NO", ID_KEYB_NO_NO_LUT); - langCb->addItem("po_PO", ID_KEYB_PO_PO_LUT); - langCb->addItem("ro_RO", ID_KEYB_RO_RO_LUT); - langCb->addItem("sl_SL", ID_KEYB_SL_SL_LUT); - langCb->addItem("frde_CH", ID_KEYB_FRDE_CH_LUT); - langCb->addItem("en_UK", ID_KEYB_EN_UK_LUT); - langCb->addItem("cs_QWERTY", ID_KEYB_CZ_QWERTY_LUT); - langCb->addItem("en_DV", ID_KEYB_EN_DV_LUT); - langCb->addItem("fr_MAC", ID_KEYB_FR_MAC_LUT); - langCb->addItem("fr_CH_MAC", ID_KEYB_FR_CH_MAC_LUT); - langCb->addItem("de_CH_MAC", ID_KEYB_DE_CH_MAC_LUT); - langCb->addItem("de_MAC", ID_KEYB_DE_MAC_LUT); - langCb->addItem("us_MAC", ID_KEYB_US_MAC_LUT); - - QSortFilterProxyModel* proxy = new QSortFilterProxyModel(langCb); - proxy->setSourceModel( langCb->model()); - langCb->model()->setParent(proxy); - langCb->setModel(proxy); - langCb->model()->sort(0); -} diff --git a/src/Settings/SettingsGuiHelper.h b/src/Settings/SettingsGuiHelper.h index 17570e34..18033aac 100644 --- a/src/Settings/SettingsGuiHelper.h +++ b/src/Settings/SettingsGuiHelper.h @@ -31,8 +31,6 @@ private slots: void sendParams(int value, int param); private: - void setupKeyboardLayout(); - WSClient* m_wsClient = nullptr; DeviceSettings* m_settings = nullptr; MainWindow* m_mw = nullptr; diff --git a/src/Settings/SettingsGuiMini.cpp b/src/Settings/SettingsGuiMini.cpp index edeac2e3..c049b69d 100644 --- a/src/Settings/SettingsGuiMini.cpp +++ b/src/Settings/SettingsGuiMini.cpp @@ -21,12 +21,77 @@ void SettingsGuiMini::updateParam(MPParams::Param param, int val) void SettingsGuiMini::updateUI() { - ui->groupBox_keyboard->show(); + // Keyboard groupbox + ui->comboBoxLoginOutput->clear(); + ui->comboBoxLoginOutput->addItem(MainWindow::TAB_STRING, TAB_INDEX); + ui->comboBoxLoginOutput->addItem(MainWindow::ENTER_STRING, ENTER_INDEX); + ui->comboBoxLoginOutput->addItem(MainWindow::SPACE_STRING, SPACE_INDEX); + ui->comboBoxPasswordOutput->clear(); + ui->comboBoxPasswordOutput->addItem(MainWindow::TAB_STRING, TAB_INDEX); + ui->comboBoxPasswordOutput->addItem(MainWindow::ENTER_STRING, ENTER_INDEX); + ui->comboBoxPasswordOutput->addItem(MainWindow::SPACE_STRING, SPACE_INDEX); + ui->checkBoxSlowHost->show(); + ui->checkBoxSendAfterLogin->show(); + ui->checkBoxSendAfterPassword->show(); + ui->settings_keyboard_layout->show(); + ui->settings_usb_layout->hide(); + ui->settings_bt_layout->hide(); + ui->settings_user_language->hide(); + ui->settings_device_language->hide(); + + // Miscellaneous groupbox ui->groupBox_miscellaneous->show(); + ui->groupBox_BLESettings->hide(); + // Inactivity groupbox ui->settings_inactivity_lock->show(); ui->checkBoxScreensaver->show(); ui->hashDisplayFeatureCheckBox->show(); ui->settings_advanced_lockunlock->show(); } + +void SettingsGuiMini::setupKeyboardLayout() +{ + auto* langCb = ui->comboBoxLang; + if (langCb->count() > 0) + { + //Combobox for Mini layouts is filled + return; + } + langCb->addItem("en_US", ID_KEYB_EN_US_LUT); + langCb->addItem("fr_FR", ID_KEYB_FR_FR_LUT); + langCb->addItem("es_ES", ID_KEYB_ES_ES_LUT); + langCb->addItem("de_DE", ID_KEYB_DE_DE_LUT); + langCb->addItem("es_AR", ID_KEYB_ES_AR_LUT); + langCb->addItem("en_AU", ID_KEYB_EN_AU_LUT); + langCb->addItem("fr_BE", ID_KEYB_FR_BE_LUT); + langCb->addItem("po_BR", ID_KEYB_PO_BR_LUT); + langCb->addItem("en_CA", ID_KEYB_EN_CA_LUT); + langCb->addItem("cz_CZ", ID_KEYB_CZ_CZ_LUT); + langCb->addItem("da_DK", ID_KEYB_DA_DK_LUT); + langCb->addItem("fi_FI", ID_KEYB_FI_FI_LUT); + langCb->addItem("hu_HU", ID_KEYB_HU_HU_LUT); + langCb->addItem("is_IS", ID_KEYB_IS_IS_LUT); + langCb->addItem("it_IT", ID_KEYB_IT_IT_LUT); + langCb->addItem("nl_NL", ID_KEYB_NL_NL_LUT); + langCb->addItem("no_NO", ID_KEYB_NO_NO_LUT); + langCb->addItem("po_PO", ID_KEYB_PO_PO_LUT); + langCb->addItem("ro_RO", ID_KEYB_RO_RO_LUT); + langCb->addItem("sl_SL", ID_KEYB_SL_SL_LUT); + langCb->addItem("frde_CH", ID_KEYB_FRDE_CH_LUT); + langCb->addItem("en_UK", ID_KEYB_EN_UK_LUT); + langCb->addItem("cs_QWERTY", ID_KEYB_CZ_QWERTY_LUT); + langCb->addItem("en_DV", ID_KEYB_EN_DV_LUT); + langCb->addItem("fr_MAC", ID_KEYB_FR_MAC_LUT); + langCb->addItem("fr_CH_MAC", ID_KEYB_FR_CH_MAC_LUT); + langCb->addItem("de_CH_MAC", ID_KEYB_DE_CH_MAC_LUT); + langCb->addItem("de_MAC", ID_KEYB_DE_MAC_LUT); + langCb->addItem("us_MAC", ID_KEYB_US_MAC_LUT); + + QSortFilterProxyModel* proxy = new QSortFilterProxyModel(langCb); + proxy->setSourceModel( langCb->model()); + langCb->model()->setParent(proxy); + langCb->setModel(proxy); + langCb->model()->sort(0); +} diff --git a/src/Settings/SettingsGuiMini.h b/src/Settings/SettingsGuiMini.h index 37251a2b..dc155eb1 100644 --- a/src/Settings/SettingsGuiMini.h +++ b/src/Settings/SettingsGuiMini.h @@ -16,6 +16,12 @@ class SettingsGuiMini : public DeviceSettingsMini, public ISettingsGui void loadParameters() override; void updateParam(MPParams::Param param, int val) override; void updateUI() override; + void setupKeyboardLayout() override; + + + static const int TAB_INDEX = 43; + static const int ENTER_INDEX = 40; + static const int SPACE_INDEX = 44; }; #endif // SETTINGSGUIMINI_H diff --git a/src/WSClient.cpp b/src/WSClient.cpp index 99d08396..5cd8b561 100644 --- a/src/WSClient.cpp +++ b/src/WSClient.cpp @@ -478,6 +478,14 @@ void WSClient::onTextMessageReceived(const QString &message) QJsonObject o = rootobj["data"].toObject(); emit updateUserSettingsOnUI(o); } + else if (rootobj["msg"] == "device_languages") + { + emit updateBLEDeviceLanguage(rootobj["data"].toObject()); + } + else if (rootobj["msg"] == "keyboard_layouts") + { + emit updateBLEKeyboardLayout(rootobj["data"].toObject()); + } } bool WSClient::isFwVersion(int version) const @@ -703,6 +711,11 @@ void WSClient::sendUserSettingsRequest() sendJsonData({{ "msg", "get_user_settings" }}); } +void WSClient::requestBleKeyboardLayout() +{ + sendJsonData({{ "msg", "request_keyboard_layout" }}); +} + void WSClient::sendLockDevice() { sendJsonData({{ "msg", "lock_device" }}); diff --git a/src/WSClient.h b/src/WSClient.h index 7889d937..4a1f119f 100644 --- a/src/WSClient.h +++ b/src/WSClient.h @@ -108,6 +108,8 @@ class WSClient: public QObject inline bool isFw12() const { return isFwVersion(12); } inline bool isFw13() const { return isFwVersion(13); } + void requestBleKeyboardLayout(); + void sendLockDevice(); SettingsGuiHelper* settingsHelper(); @@ -140,6 +142,8 @@ class WSClient: public QObject void deviceConnacted(); void deviceDisconnected(); void deleteDataNodesFinished(); + void updateBLEDeviceLanguage(const QJsonObject& langs); + void updateBLEKeyboardLayout(const QJsonObject& layouts); public slots: void sendJsonData(const QJsonObject &data); diff --git a/src/WSServerCon.cpp b/src/WSServerCon.cpp index 55872deb..35a1650f 100644 --- a/src/WSServerCon.cpp +++ b/src/WSServerCon.cpp @@ -410,7 +410,10 @@ void WSServerCon::resetDevice(MPDevice *dev) if (nullptr != mpdevice->ble()) { - connect(mpdevice->ble(), &MPDeviceBleImpl::userSettingsChanged, this, &WSServerCon::sendUserSettings); + const auto* mpBle = mpdevice->ble(); + connect(mpBle, &MPDeviceBleImpl::userSettingsChanged, this, &WSServerCon::sendUserSettings); + connect(mpBle, &MPDeviceBleImpl::bleDeviceLanguage, this, &WSServerCon::sendDeviceLanguage); + connect(mpBle, &MPDeviceBleImpl::bleKeyboardLayout, this, &WSServerCon::sendKeyboardLayout); } } @@ -544,6 +547,28 @@ void WSServerCon::sendFilesCache() sendJsonMessage(oroot); } +void WSServerCon::sendDeviceLanguage(const QJsonObject &langs) +{ + if (!mpdevice || !mpdevice->ble()) + { + return; + } + sendJsonMessage({{ "msg", "device_languages" }, + { "data", langs } + }); +} + +void WSServerCon::sendKeyboardLayout(const QJsonObject &layouts) +{ + if (!mpdevice || !mpdevice->ble()) + { + return; + } + sendJsonMessage({{ "msg", "keyboard_layouts" }, + { "data", layouts } + }); +} + void WSServerCon::sendCardDbMetadata() { qDebug() << "Send card db metadata"; @@ -1191,7 +1216,11 @@ void WSServerCon::processMessageBLE(QJsonObject root, const MPDeviceProgressCb & } else if (root["msg"] == "get_user_settings") { - bleImpl->sendUserSettings(); + bleImpl->sendUserSettings(); + } + else if (root["msg"] == "request_keyboard_layout") + { + bleImpl->readLanguages(); } else { diff --git a/src/WSServerCon.h b/src/WSServerCon.h index 3fd98ea7..b598b7f4 100644 --- a/src/WSServerCon.h +++ b/src/WSServerCon.h @@ -59,6 +59,9 @@ private slots: void sendDeviceUID(); void sendFilesCache(); + void sendDeviceLanguage(const QJsonObject& langs); + void sendKeyboardLayout(const QJsonObject& layouts); + void sendCardDbMetadata(); void sendHibpNotification(QString credInfo, QString pwnedNum);