# HG changeset patch # User Wuzzy # Date 1556565830 -7200 # Node ID bb412d8e435fd7f78fde01bee4c63a5e2b581e59 # Parent eef1f76150fe5555984c47f6e86745984094afc8 Frontend: Fix wrong keyboard key names being displayed with regard to keyboard layout diff -r eef1f76150fe -r bb412d8e435f ChangeLog.txt --- a/ChangeLog.txt Sun Apr 28 00:09:56 2019 +0300 +++ b/ChangeLog.txt Mon Apr 29 21:23:50 2019 +0200 @@ -92,6 +92,7 @@ + Add button in main menu at top left corner to open credits page + Restructure credits page + More intelligent automatic mission selection in campaign screen + * Fix controls list failing to display correct key names with regards to keyboard layout * Fix force-locked schemes getting unlocked when changing map types * Fix possible to select background-only or hidden themes indirectly by changing map type * Disallow slash, backslash and colon characters in team and scheme names diff -r eef1f76150fe -r bb412d8e435f QTfrontend/hedgewars.qrc --- a/QTfrontend/hedgewars.qrc Sun Apr 28 00:09:56 2019 +0300 +++ b/QTfrontend/hedgewars.qrc Mon Apr 29 21:23:50 2019 +0200 @@ -1,6 +1,7 @@ ../share/hedgewars/Data/Graphics/AmmoMenu/Ammos_base.png + ../share/hedgewars/Data/misc/keys.csv res/css/qt.css res/css/chat.css res/css/christmas.css diff -r eef1f76150fe -r bb412d8e435f QTfrontend/util/DataManager.cpp --- a/QTfrontend/util/DataManager.cpp Sun Apr 28 00:09:56 2019 +0300 +++ b/QTfrontend/util/DataManager.cpp Mon Apr 29 21:23:50 2019 +0200 @@ -28,9 +28,12 @@ #include #include +#include + #include "hwconsts.h" #include "HWApplication.h" #include "sdlkeys.h" +#include "KeyMap.h" #include "physfs.h" #include "DataManager.h" @@ -147,6 +150,7 @@ QStandardItemModel * DataManager::bindsModel() { + KeyMap km = KeyMap::instance(); if(m_bindsModel == NULL) { m_bindsModel = new QStandardItemModel(); @@ -160,8 +164,27 @@ { QStandardItem * item = new QStandardItem(); QString keyId = QString(sdlkeys[j][0]); - QString keyTr = HWApplication::translate("binds (keys)", sdlkeys[j][1]); - item->setData((keyId == "none" || keyTr.contains(": ")) ? keyTr : HWApplication::translate("binds (keys)", "Keyboard") + QString(": ") + keyTr, Qt::DisplayRole); + QString keyDisplay; + bool isKeyboard = !QString(sdlkeys[j][1]).contains(": "); + if (keyId == "none" || (!isKeyboard)) + keyDisplay = HWApplication::translate("binds (keys)", sdlkeys[j][1]); + else + // Get key name with respect to keyboard layout + keyDisplay = QString(SDL_GetKeyName(SDL_GetKeyFromScancode(km.getScancodeFromKeyname(sdlkeys[j][0])))); + + bool kbFallback = keyDisplay.trimmed().isEmpty(); + if (kbFallback) + { + // If SDL doesn't know a name, show fallback enclosed in brackets + keyDisplay = QString(sdlkeys[j][1]) + QString(" ") + HWApplication::translate("binds (keys)", "(unsupported)"); + } + if (isKeyboard) + { + if (!kbFallback) + keyDisplay = HWApplication::translate("binds (keys)", keyDisplay.toUtf8().constData()); + keyDisplay = HWApplication::translate("binds (keys)", "Keyboard") + QString(": ") + keyDisplay; + } + item->setData(keyDisplay, Qt::DisplayRole); item->setData(sdlkeys[j][0], Qt::UserRole + 1); m_bindsModel->appendRow(item); } diff -r eef1f76150fe -r bb412d8e435f QTfrontend/util/KeyMap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/util/KeyMap.cpp Mon Apr 29 21:23:50 2019 +0200 @@ -0,0 +1,103 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2019 Andrey Korotaev + * + * 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; version 2 of the License + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "KeyMap.h" +#include "SDL.h" + +KeyMap & KeyMap::instance() +{ + static KeyMap instance; + instance.getKeyMap(); + return instance; +} + +bool KeyMap::getKeyMap() +{ + if (keyMapGenerated) + return true; + QFile keyFile(":keys.csv"); + if (!keyFile.open(QIODevice::ReadOnly)) + { + qWarning("ERROR: keys.csv could not be opened!"); + return false; + } + QString keyString = keyFile.readAll(); + QStringList cells = QStringList() << QString("") << QString(""); + QChar currChar; + bool isInQuote = false; + int cell = 0; + int charInCell = 0; + QString scancode = ""; + QString keyname = ""; + for(long long int i = 0; i < keyString.length(); i++) + { + currChar = keyString.at(i); + if (currChar == '\"') { + isInQuote = !isInQuote; + } + if (currChar == ',' && !isInQuote) { + cell++; + continue; + } + if (currChar == '\n') { + mapOfKeynames[(SDL_Scancode) scancode.toInt()] = keyname; + mapOfScancodes[keyname] = (SDL_Scancode) scancode.toInt(); + if ((SDL_Scancode) scancode.toInt() == SDL_SCANCODE_UNKNOWN) + continue; + cell = 0; + scancode = ""; + keyname = ""; + continue; + } + if (cell == 0 && currChar != "\"") { + scancode += currChar; + } else if (cell == 1 && currChar != "\"") { + keyname += currChar; + } + charInCell++; + } + keyMapGenerated = true; + keyFile.close(); + return true; +} + +SDL_Scancode KeyMap::getScancodeFromKeyname(QString keyname) +{ + if (mapOfScancodes.contains(keyname)) + return mapOfScancodes[keyname]; + else + return SDL_SCANCODE_UNKNOWN; +} + +QString KeyMap::getKeynameFromScancode(int scancode) +{ + if (mapOfKeynames.contains((SDL_Scancode) scancode)) + if (mapOfKeynames[(SDL_Scancode) scancode] == SDL_SCANCODE_UNKNOWN) + return QString("none"); + else + return mapOfKeynames[(SDL_Scancode) scancode]; + else + return QString(""); +} + +QString KeyMap::getKeynameFromScancodeConverted(int scancode) +{ + SDL_Keycode keycode = SDL_GetKeyFromScancode((SDL_Scancode) scancode); + return SDL_GetKeyName(keycode); +} + diff -r eef1f76150fe -r bb412d8e435f QTfrontend/util/KeyMap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/util/KeyMap.h Mon Apr 29 21:23:50 2019 +0200 @@ -0,0 +1,56 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2019 Andrey Korotaev + * + * 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; version 2 of the License + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief KeyMap class definition + */ + +#ifndef HEDGEWARS_KEYMAP_H +#define HEDGEWARS_KEYMAP_H + +#include +#include +#include "SDL.h" + +class KeyMap +{ + public: + /** + * @brief Returns reference to the singleton instance of this class. + * + * @see singleton pattern + * + * @return reference to the instance. + */ + static KeyMap & instance(); + SDL_Scancode getScancodeFromKeyname(QString keyname); + QString getKeynameFromScancode(int scancode); + QString getKeynameFromScancodeConverted(int scancode); + QString getKeynameFromKeycode(int keycode); + + private: + // TODO: Optimize data structures + QHash mapOfKeynames; + QHash mapOfScancodes; + bool getKeyMap(); + bool keyMapGenerated = false; + +}; + +#endif // HEDGEWARS_KEYMAP_H