mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-19 06:47:41 +00:00
- ldml::vkeys class updated to keep a set<> of keys - fix the test case to not leak! Fixes: #12298
112 lines
2.7 KiB
C++
112 lines
2.7 KiB
C++
/*
|
|
Copyright: © SIL International.
|
|
Description: Implementation for LDML Vkeys
|
|
Create Date: 6 Oct 2022
|
|
Authors: Steven R. Loomis
|
|
*/
|
|
|
|
#include "ldml_vkeys.hpp"
|
|
#include "kmx_file.h"
|
|
#include <ldml/keyman_core_ldml.h>
|
|
|
|
namespace km {
|
|
namespace core {
|
|
namespace ldml {
|
|
|
|
vkeys::vkeys() : vkey_to_string() {
|
|
}
|
|
|
|
void
|
|
vkeys::add(km_core_virtual_key vk, km_core_ldml_modifier_state modifier_state, std::u16string output) {
|
|
// construct key
|
|
const vkey_id id(vk, modifier_state);
|
|
// assign the string
|
|
vkey_to_string[id] = output;
|
|
if (!output.empty()) {
|
|
// empty string = gap key, etc.
|
|
all_vkeys.insert(id);
|
|
}
|
|
}
|
|
|
|
km_core_keyboard_key *
|
|
vkeys::get_key_list() const {
|
|
km_core_keyboard_key *list = new km_core_keyboard_key[all_vkeys.size() + 1];
|
|
std::size_t n = 0;
|
|
for (const auto &k : all_vkeys) {
|
|
list[n ].key = k.first;
|
|
list[n++].modifier_flag = k.second;
|
|
}
|
|
list[n++] = KM_CORE_KEYBOARD_KEY_LIST_END;
|
|
return list;
|
|
}
|
|
|
|
static const uint16_t BOTH_ALT = LALTFLAG | RALTFLAG;
|
|
static const uint16_t BOTH_CTRL = LCTRLFLAG | RCTRLFLAG;
|
|
|
|
std::u16string
|
|
vkeys::lookup(km_core_virtual_key vk, uint16_t modifier_state, bool &found) const {
|
|
const vkey_id id(vk, modifier_state);
|
|
|
|
// try exact match first
|
|
std::u16string ret = lookup(id, found);
|
|
if (found) {
|
|
return ret;
|
|
}
|
|
|
|
const bool have_ctrl = modifier_state & BOTH_CTRL;
|
|
const bool have_alt = modifier_state & BOTH_ALT;
|
|
|
|
// look for a layer with "alt" (either)
|
|
if (have_alt) {
|
|
const vkey_id id_alt(vk, (modifier_state & ~(BOTH_ALT)) | K_ALTFLAG);
|
|
ret = lookup(id_alt, found);
|
|
if (found) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
// look for a layer with "ctrl" (either)
|
|
if (have_ctrl) {
|
|
const vkey_id id_ctrl(vk, (modifier_state & ~(BOTH_CTRL)) | K_CTRLFLAG);
|
|
ret = lookup(id_ctrl, found);
|
|
if (found) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
// look for a layer with "alt ctrl" (either)
|
|
if (have_ctrl && have_alt) {
|
|
const vkey_id id_ctrl_alt(vk, (modifier_state & ~(BOTH_ALT | BOTH_CTRL)) | K_CTRLFLAG | K_ALTFLAG);
|
|
ret = lookup(id_ctrl_alt, found);
|
|
if (found) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
// look for a layer with "other"
|
|
{
|
|
const vkey_id id_default(vk, (LDML_KEYS_MOD_OTHER));
|
|
ret = lookup(id_default, found);
|
|
if (found) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
// default: return failure. found=false.
|
|
return ret;
|
|
}
|
|
|
|
std::u16string
|
|
vkeys::lookup(const vkey_id& id, bool &found) const {
|
|
const auto key = vkey_to_string.find(id);
|
|
if (key == vkey_to_string.end()) {
|
|
found = false;
|
|
return std::u16string(); // TODO-LDML: optimize object construction?
|
|
}
|
|
found = true;
|
|
return key->second;
|
|
}
|
|
|
|
} // namespace ldml
|
|
} // namespace core
|
|
} // namespace km
|