11 #include <QDomDocument>
26 #define LOC QString("MythUIVirtualKeyboard: ")
28 static const std::array<std::array<QString,3>,95>
comps {{
29 {
"!",
"!", (QChar)0xa1}, {
"c",
"/", (QChar)0xa2},
30 {
"l",
"-", (QChar)0xa3}, {
"o",
"x", (QChar)0xa4},
31 {
"y",
"-", (QChar)0xa5}, {
"|",
"|", (QChar)0xa6},
32 {
"s",
"o", (QChar)0xa7}, {
"\"",
"\"", (QChar)0xa8},
33 {
"c",
"o", (QChar)0xa9}, {
"-",
"a", (QChar)0xaa},
34 {
"<",
"<", (QChar)0xab}, {
"-",
"|", (QChar)0xac},
35 {
"-",
"-", (QChar)0xad}, {
"r",
"o", (QChar)0xae},
36 {
"^",
"-", (QChar)0xaf}, {
"^",
"0", (QChar)0xb0},
37 {
"+",
"-", (QChar)0xb1}, {
"^",
"2", (QChar)0xb2},
38 {
"^",
"3", (QChar)0xb3}, {
"/",
"/", (QChar)0xb4},
39 {
"/",
"u", (QChar)0xb5}, {
"P",
"!", (QChar)0xb6},
40 {
"^",
".", (QChar)0xb7}, {
",",
",", (QChar)0xb8},
41 {
"^",
"1", (QChar)0xb9}, {
"_",
"o", (QChar)0xba},
42 {
">",
">", (QChar)0xbb}, {
"1",
"4", (QChar)0xbc},
43 {
"1",
"2", (QChar)0xbd}, {
"3",
"4", (QChar)0xbe},
44 {
"?",
"?", (QChar)0xbf}, {
"A",
"`", (QChar)0xc0},
45 {
"A",
"'", (QChar)0xc1}, {
"A",
"^", (QChar)0xc2},
46 {
"A",
"~", (QChar)0xc3}, {
"A",
"\"", (QChar)0xc4},
47 {
"A",
"*", (QChar)0xc5}, {
"A",
"E", (QChar)0xc6},
48 {
"C",
",", (QChar)0xc7}, {
"E",
"`", (QChar)0xc8},
49 {
"E",
"'", (QChar)0xc9}, {
"E",
"^", (QChar)0xca},
50 {
"E",
"\"", (QChar)0xcb}, {
"I",
"`", (QChar)0xcc},
51 {
"I",
"'", (QChar)0xcd}, {
"I",
"^", (QChar)0xce},
52 {
"I",
"\"", (QChar)0xcf}, {
"D",
"-", (QChar)0xd0},
53 {
"N",
"~", (QChar)0xd1}, {
"O",
"`", (QChar)0xd2},
54 {
"O",
"'", (QChar)0xd3}, {
"O",
"^", (QChar)0xd4},
55 {
"O",
"~", (QChar)0xd5}, {
"O",
"\"", (QChar)0xd6},
56 {
"x",
"x", (QChar)0xd7}, {
"O",
"/", (QChar)0xd8},
57 {
"U",
"`", (QChar)0xd9}, {
"U",
"'", (QChar)0xda},
58 {
"U",
"^", (QChar)0xdb}, {
"U",
"\"", (QChar)0xdc},
59 {
"Y",
"'", (QChar)0xdd}, {
"T",
"H", (QChar)0xde},
60 {
"s",
"s", (QChar)0xdf}, {
"a",
"`", (QChar)0xe0},
61 {
"a",
"'", (QChar)0xe1}, {
"a",
"^", (QChar)0xe2},
62 {
"a",
"~", (QChar)0xe3}, {
"a",
"\"", (QChar)0xe4},
63 {
"a",
"*", (QChar)0xe5}, {
"a",
"e", (QChar)0xe6},
64 {
"c",
",", (QChar)0xe7}, {
"e",
"`", (QChar)0xe8},
65 {
"e",
"'", (QChar)0xe9}, {
"e",
"^", (QChar)0xea},
66 {
"e",
"\"", (QChar)0xeb}, {
"i",
"`", (QChar)0xec},
67 {
"i",
"'", (QChar)0xed}, {
"i",
"^", (QChar)0xee},
68 {
"i",
"\"", (QChar)0xef}, {
"d",
"-", (QChar)0xf0},
69 {
"n",
"~", (QChar)0xf1}, {
"o",
"`", (QChar)0xf2},
70 {
"o",
"'", (QChar)0xf3}, {
"o",
"^", (QChar)0xf4},
71 {
"o",
"~", (QChar)0xf5}, {
"o",
"\"", (QChar)0xf6},
72 {
"-",
":", (QChar)0xf7}, {
"o",
"/", (QChar)0xf8},
73 {
"u",
"`", (QChar)0xf9}, {
"u",
"'", (QChar)0xfa},
74 {
"u",
"^", (QChar)0xfb}, {
"u",
"\"", (QChar)0xfc},
75 {
"y",
"'", (QChar)0xfd}, {
"t",
"h", (QChar)0xfe},
76 {
"y",
"\"", (QChar)0xff}
81 m_parentEdit(parentEdit)
112 parentScreen = qobject_cast<MythUIType *>(
m_parentEdit->parent());
116 editArea.y() + parentScreen->
GetArea().y()));
122 if (editArea.y() - area.height() - 5 > 0)
124 newPos = QPoint(editArea.x() + (editArea.width() / 2) - (area.width() / 2),
125 editArea.y() - area.height() - 5);
129 newPos = QPoint(editArea.x() + (editArea.width() / 2) - (area.width() / 2),
130 editArea.y() + editArea.height() + 5);
135 newPos = QPoint((screensize.width() / 2) - (area.width() / 2), 5);
139 newPos = QPoint((screensize.width() / 2) - (area.width() / 2), screensize.height() - 5 - area.height());
143 newPos = QPoint((screensize.width() / 2) - (area.width() / 2), (screensize.height() / 2) - (area.height() / 2));
148 if (editArea.y() + editArea.height() + area.height() + 5 < screensize.height())
150 newPos = QPoint(editArea.x() + (editArea.width() / 2) - (area.width() / 2),
151 editArea.y() + editArea.height() + 5);
155 newPos = QPoint(editArea.x() + (editArea.width() / 2) - (area.width() / 2),
156 editArea.y() - area.height() - 5);
164 if (newPos.x() + area.width() + 5 > screensize.width())
165 newPos.
setX(screensize.width() - area.width() - 5);
168 if (newPos.y() + area.height() + 5 > screensize.width())
169 newPos.
setY(screensize.width() - area.height() - 5);
178 QString language = lang.toLower();
180 QString defFile = QString(
"keyboard/%1.xml").arg(language);
182 if (!
GetMythUI()->FindThemeFile(defFile))
184 LOG(VB_GENERAL, LOG_ERR,
185 "No keyboard definition file found for: " + language);
188 defFile =
"keyboard/en_us.xml";
189 if (!
GetMythUI()->FindThemeFile(defFile))
191 LOG(VB_GENERAL, LOG_ERR,
192 "Cannot find definitions file: " + defFile);
197 LOG(VB_GENERAL, LOG_NOTICE,
"Loading definitions from: " + defFile);
199 QDomDocument doc(
"keydefinitions");
201 if (!
file.open(QIODevice::ReadOnly))
203 LOG(VB_GENERAL, LOG_ERR,
"Failed to open definitions file: " + defFile);
206 if (!doc.setContent(&
file))
208 LOG(VB_GENERAL, LOG_ERR,
209 "Failed to parse definitions file: " + defFile);
215 QDomElement docElem = doc.documentElement();
216 QDomNode n = docElem.firstChild();
219 QDomElement e = n.toElement();
222 if (e.tagName() ==
"key")
240 QString name = element.attribute(
"name");
241 QString
type = element.attribute(
"type");
243 QDomNode n = element.firstChild();
246 QDomElement e = n.toElement();
249 if (e.tagName() ==
"move")
251 left = e.attribute(
"left");
252 right = e.attribute(
"right");
253 up = e.attribute(
"up");
254 down = e.attribute(
"down");
256 else if (e.tagName() ==
"char")
258 normal = e.attribute(
"normal");
259 shift = e.attribute(
"shift");
260 alt = e.attribute(
"alt");
261 altshift = e.attribute(
"altshift");
265 LOG(VB_GENERAL, LOG_ERR,
"Unknown element in key definition");
289 for (
auto *child : std::as_const(*children))
294 if (
m_keyMap.contains(button->objectName()))
301 if (key.
type ==
"shift")
311 else if (key.
type ==
"char")
315 else if (key.
type ==
"done")
319 else if (key.
type ==
"del")
323 else if (key.
type ==
"lock")
329 else if (key.
type ==
"alt")
335 else if (key.
type ==
"comp")
341 else if (key.
type ==
"moveleft")
345 else if (key.
type ==
"moveright")
349 else if (key.
type ==
"back")
357 LOG(VB_GENERAL, LOG_WARNING,
358 QString(
"WARNING - Key '%1' not found in map")
359 .arg(button->objectName()));
367 bool handled =
false;
374 bool keyFound =
false;
385 for (
int i = 0; i < actions.size() && !handled; i++)
387 const QString&
action = actions[i];
395 else if (
action ==
"DOWN")
400 else if (
action ==
"LEFT")
405 else if (
action ==
"RIGHT")
437 for (
const auto & comp :
comps)
447 auto *
event =
new QKeyEvent(QEvent::KeyPress, 0, Qt::NoModifier, c);
467 auto *
event =
new QKeyEvent(QEvent::KeyPress, 0, Qt::NoModifier, c);
508 auto *
event =
new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier,
"");
519 auto *
event =
new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier,
"");
555 auto *
event =
new QKeyEvent(QEvent::KeyPress,
m_newlineKey.key(),
572 auto *
event =
new QKeyEvent(QEvent::KeyPress,
m_upKey.key(),
573 m_upKey.keyboardModifiers(),
"");
579 auto *
event =
new QKeyEvent(QEvent::KeyPress,
m_leftKey.key(),
593 auto *
event =
new QKeyEvent(QEvent::KeyPress,
m_downKey.key(),
600 auto *
event =
new QKeyEvent(QEvent::KeyPress,
m_rightKey.key(),
611 while (c.length() > 0)
613 if (c.startsWith(
"0x"))
615 QString sCode = c.left(6);
617 short nCode = sCode.toShort(&bOK, 16);
628 LOG(VB_GENERAL, LOG_ERR, QString(
"bad char code (%1)")
659 #
if QT_VERSION < QT_VERSION_CHECK(6,0,0)
660 KeyEventDefinition *keyDef,
662 QKeyCombination *keyDef,
667 QStringList keys = keylist.split(
',', Qt::SkipEmptyParts);
671 QKeySequence a(keys[0]);
674 LOG(VB_GENERAL, LOG_ERR,
675 QString(
"loadEventKeyDefinitions bad key (%1)").arg(keys[0]));
679 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
680 keyDef->keyCode = a[0];
682 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
683 QStringList parts = keys[0].split(
'+');
684 for (
int j = 0; j < parts.count(); j++)
686 if (parts[j].toUpper() ==
"CTRL")
687 modifiers |= Qt::ControlModifier;
688 if (parts[j].toUpper() ==
"SHIFT")
689 modifiers |= Qt::ShiftModifier;
690 if (parts[j].toUpper() ==
"ALT")
691 modifiers |= Qt::AltModifier;
692 if (parts[j].toUpper() ==
"META")
693 modifiers |= Qt::MetaModifier;
696 keyDef->modifiers = modifiers;