first push

This commit is contained in:
2026-04-03 09:26:10 +08:00
parent 2937a44e07
commit 025b88e366
41 changed files with 6842 additions and 0 deletions

View File

@@ -0,0 +1,573 @@
#include "LOGIC/Lgc_Func_Button_Private.h"
#include <QtCore/QRegularExpression>
#include <QtCore/QStringList>
namespace
{
bool Lgc_FunctionButton_IsSequenceSeparator(QChar Character)
{
return Character.isSpace() ||
(Character == QLatin1Char(',')) ||
(Character == QLatin1Char(';')) ||
(Character == QLatin1Char('|')) ||
(Character == QChar(0xFF0C)) ||
(Character == QChar(0xFF1B)) ||
(Character == QChar(0x3001));
}
quint16 Lgc_FunctionButton_GetUsageFromDigit(QChar Character)
{
switch (Character.unicode())
{
case '0': return 0x0062;
case '1': return 0x0059;
case '2': return 0x005A;
case '3': return 0x005B;
case '4': return 0x005C;
case '5': return 0x005D;
case '6': return 0x005E;
case '7': return 0x005F;
case '8': return 0x0060;
case '9': return 0x0061;
default:
return 0;
}
}
quint16 Lgc_FunctionButton_GetUsageFromSymbol(QChar Character)
{
switch (Character.unicode())
{
case '+': return 0x0057;
case '/': return 0x0054;
case '*': return 0x0055;
case '-': return 0x0056;
case '.': return 0x0063;
default:
return 0;
}
}
} // namespace
bool Lgc_FunctionButton_ParseLegacySequenceText(
const QString& Text,
quint16 SourceUsage,
QVector<quint16>* p_UsageList,
QString* p_ErrorText)
{
p_UsageList->clear();
if (p_ErrorText != nullptr) p_ErrorText->clear();
const QString UpperText = Text.toUpper();
int Index = 0;
const QVector<QPair<QString, quint16>> TokenList = {
{ QStringLiteral("NUMLOCK"), 0x0053 },
{ QStringLiteral("ENTER"), 0x0058 },
{ QStringLiteral("DIVIDE"), 0x0054 },
{ QStringLiteral("SLASH"), 0x0054 },
{ QStringLiteral("MULTIPLY"), 0x0055 },
{ QStringLiteral("ASTERISK"), 0x0055 },
{ QStringLiteral("DECIMAL"), 0x0063 },
{ QStringLiteral("MINUS"), 0x0056 },
{ QStringLiteral("SOURCE"), SourceUsage },
{ QStringLiteral("PLUS"), 0x0057 },
{ QStringLiteral("STAR"), 0x0055 },
{ QStringLiteral("SELF"), SourceUsage },
{ QStringLiteral("DOT"), 0x0063 },
{ QStringLiteral("NUM"), 0x0053 }
};
while (Index < Text.size())
{
const QChar Character = Text.at(Index);
if (Lgc_FunctionButton_IsSequenceSeparator(Character))
{
++Index;
continue;
}
if ((Index + 1) < Text.size())
{
const QString Token = Text.mid(Index, 2);
if ((Token == QStringLiteral("本键")) || (Token == QStringLiteral("自身")))
{
p_UsageList->append(SourceUsage);
Index += 2;
continue;
}
}
const quint16 DigitUsage = Lgc_FunctionButton_GetUsageFromDigit(Character);
if (DigitUsage != 0)
{
p_UsageList->append(DigitUsage);
++Index;
continue;
}
const quint16 SymbolUsage = Lgc_FunctionButton_GetUsageFromSymbol(Character);
if (SymbolUsage != 0)
{
p_UsageList->append(SymbolUsage);
++Index;
continue;
}
bool IsMatched = false;
for (const auto& Token : TokenList)
{
if (!UpperText.mid(Index, Token.first.size()).compare(Token.first, Qt::CaseInsensitive))
{
p_UsageList->append(Token.second);
Index += Token.first.size();
IsMatched = true;
break;
}
}
if (IsMatched)
{
continue;
}
if (p_ErrorText != nullptr)
{
*p_ErrorText = QStringLiteral("无法识别的按键序列片段:%1").arg(Text.mid(Index, 8));
}
p_UsageList->clear();
return false;
}
return true;
}
bool Lgc_FunctionButton_TryParseSequenceToken(
const QString& Token,
quint16 SourceUsage,
Lgc_FunctionButton_Struct_SequenceKey* p_KeyItem)
{
const QString TrimmedToken = Token.trimmed();
const QString UpperToken = TrimmedToken.toUpper();
if (UpperToken.isEmpty())
{
return false;
}
const auto SetKey = [p_KeyItem](WORD VirtualKey, DWORD ExtraFlags, bool IsModifier, const QString& Text)
{
p_KeyItem->Key = { VirtualKey, ExtraFlags, IsModifier };
p_KeyItem->Text = Text;
};
if ((UpperToken == QStringLiteral("SOURCE")) ||
(UpperToken == QStringLiteral("SELF")) ||
(TrimmedToken == QStringLiteral("本键")) ||
(TrimmedToken == QStringLiteral("自身")))
{
const auto SourceKey = Lgc_FunctionButton_GetWindowsKey(SourceUsage);
if (SourceKey.VirtualKey == 0)
{
return false;
}
p_KeyItem->Key = SourceKey;
p_KeyItem->Text = Lgc_FunctionButton_GetUsageShortText(SourceUsage);
return true;
}
if ((UpperToken.size() == 1) && UpperToken.at(0).isLetterOrNumber())
{
SetKey(static_cast<WORD>(UpperToken.at(0).unicode()), 0, false, UpperToken);
return true;
}
if (UpperToken == QStringLiteral("CTRL") || UpperToken == QStringLiteral("CONTROL"))
{
SetKey(VK_CONTROL, 0, true, QStringLiteral("Ctrl"));
return true;
}
if (UpperToken == QStringLiteral("SHIFT"))
{
SetKey(VK_SHIFT, 0, true, QStringLiteral("Shift"));
return true;
}
if (UpperToken == QStringLiteral("ALT"))
{
SetKey(VK_MENU, 0, true, QStringLiteral("Alt"));
return true;
}
if (UpperToken == QStringLiteral("WIN") || UpperToken == QStringLiteral("META"))
{
SetKey(VK_LWIN, 0, true, QStringLiteral("Win"));
return true;
}
if (UpperToken == QStringLiteral("ENTER"))
{
SetKey(VK_RETURN, 0, false, QStringLiteral("Enter"));
return true;
}
if (UpperToken == QStringLiteral("NUMENTER"))
{
SetKey(VK_RETURN, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("NumEnter"));
return true;
}
if (UpperToken == QStringLiteral("SPACE"))
{
SetKey(VK_SPACE, 0, false, QStringLiteral("Space"));
return true;
}
if (UpperToken == QStringLiteral("TAB"))
{
SetKey(VK_TAB, 0, false, QStringLiteral("Tab"));
return true;
}
if (UpperToken == QStringLiteral("ESC") || UpperToken == QStringLiteral("ESCAPE"))
{
SetKey(VK_ESCAPE, 0, false, QStringLiteral("Esc"));
return true;
}
if (UpperToken == QStringLiteral("BACKSPACE"))
{
SetKey(VK_BACK, 0, false, QStringLiteral("Backspace"));
return true;
}
if (UpperToken == QStringLiteral("DELETE"))
{
SetKey(VK_DELETE, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Delete"));
return true;
}
if (UpperToken == QStringLiteral("INSERT"))
{
SetKey(VK_INSERT, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Insert"));
return true;
}
if (UpperToken == QStringLiteral("HOME"))
{
SetKey(VK_HOME, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Home"));
return true;
}
if (UpperToken == QStringLiteral("END"))
{
SetKey(VK_END, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("End"));
return true;
}
if (UpperToken == QStringLiteral("PAGEUP"))
{
SetKey(VK_PRIOR, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("PageUp"));
return true;
}
if (UpperToken == QStringLiteral("PAGEDOWN"))
{
SetKey(VK_NEXT, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("PageDown"));
return true;
}
if (UpperToken == QStringLiteral("LEFT"))
{
SetKey(VK_LEFT, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Left"));
return true;
}
if (UpperToken == QStringLiteral("RIGHT"))
{
SetKey(VK_RIGHT, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Right"));
return true;
}
if (UpperToken == QStringLiteral("UP"))
{
SetKey(VK_UP, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Up"));
return true;
}
if (UpperToken == QStringLiteral("DOWN"))
{
SetKey(VK_DOWN, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Down"));
return true;
}
if (UpperToken == QStringLiteral("CAPSLOCK"))
{
SetKey(VK_CAPITAL, 0, false, QStringLiteral("CapsLock"));
return true;
}
if (UpperToken == QStringLiteral("PRINTSCREEN"))
{
SetKey(VK_SNAPSHOT, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("PrintScreen"));
return true;
}
if (UpperToken == QStringLiteral("SCROLLLOCK"))
{
SetKey(VK_SCROLL, 0, false, QStringLiteral("ScrollLock"));
return true;
}
if (UpperToken == QStringLiteral("PAUSE"))
{
SetKey(VK_PAUSE, 0, false, QStringLiteral("Pause"));
return true;
}
if (UpperToken == QStringLiteral("NUM0")) { SetKey(VK_NUMPAD0, 0, false, QStringLiteral("Num0")); return true; }
if (UpperToken == QStringLiteral("NUM1")) { SetKey(VK_NUMPAD1, 0, false, QStringLiteral("Num1")); return true; }
if (UpperToken == QStringLiteral("NUM2")) { SetKey(VK_NUMPAD2, 0, false, QStringLiteral("Num2")); return true; }
if (UpperToken == QStringLiteral("NUM3")) { SetKey(VK_NUMPAD3, 0, false, QStringLiteral("Num3")); return true; }
if (UpperToken == QStringLiteral("NUM4")) { SetKey(VK_NUMPAD4, 0, false, QStringLiteral("Num4")); return true; }
if (UpperToken == QStringLiteral("NUM5")) { SetKey(VK_NUMPAD5, 0, false, QStringLiteral("Num5")); return true; }
if (UpperToken == QStringLiteral("NUM6")) { SetKey(VK_NUMPAD6, 0, false, QStringLiteral("Num6")); return true; }
if (UpperToken == QStringLiteral("NUM7")) { SetKey(VK_NUMPAD7, 0, false, QStringLiteral("Num7")); return true; }
if (UpperToken == QStringLiteral("NUM8")) { SetKey(VK_NUMPAD8, 0, false, QStringLiteral("Num8")); return true; }
if (UpperToken == QStringLiteral("NUM9")) { SetKey(VK_NUMPAD9, 0, false, QStringLiteral("Num9")); return true; }
if (UpperToken == QStringLiteral("NUM/")) { SetKey(VK_DIVIDE, KEYEVENTF_EXTENDEDKEY, false, QStringLiteral("Num/")); return true; }
if (UpperToken == QStringLiteral("NUM*")) { SetKey(VK_MULTIPLY, 0, false, QStringLiteral("Num*")); return true; }
if (UpperToken == QStringLiteral("NUM-")) { SetKey(VK_SUBTRACT, 0, false, QStringLiteral("Num-")); return true; }
if (UpperToken == QStringLiteral("NUM+")) { SetKey(VK_ADD, 0, false, QStringLiteral("Num+")); return true; }
if (UpperToken == QStringLiteral("NUM.")) { SetKey(VK_DECIMAL, 0, false, QStringLiteral("Num.")); return true; }
if (UpperToken == QStringLiteral("COMMA")) { SetKey(VK_OEM_COMMA, 0, false, QStringLiteral("Comma")); return true; }
if (UpperToken == QStringLiteral("PERIOD")) { SetKey(VK_OEM_PERIOD, 0, false, QStringLiteral("Period")); return true; }
if (UpperToken == QStringLiteral("SEMICOLON")) { SetKey(VK_OEM_1, 0, false, QStringLiteral("Semicolon")); return true; }
if (UpperToken == QStringLiteral("SLASH")) { SetKey(VK_OEM_2, 0, false, QStringLiteral("Slash")); return true; }
if (UpperToken == QStringLiteral("GRAVE")) { SetKey(VK_OEM_3, 0, false, QStringLiteral("Grave")); return true; }
if (UpperToken == QStringLiteral("LEFTBRACKET")) { SetKey(VK_OEM_4, 0, false, QStringLiteral("LeftBracket")); return true; }
if (UpperToken == QStringLiteral("BACKSLASH")) { SetKey(VK_OEM_5, 0, false, QStringLiteral("Backslash")); return true; }
if (UpperToken == QStringLiteral("RIGHTBRACKET")) { SetKey(VK_OEM_6, 0, false, QStringLiteral("RightBracket")); return true; }
if (UpperToken == QStringLiteral("QUOTE")) { SetKey(VK_OEM_7, 0, false, QStringLiteral("Quote")); return true; }
if (UpperToken == QStringLiteral("MINUS")) { SetKey(VK_OEM_MINUS, 0, false, QStringLiteral("Minus")); return true; }
if (UpperToken == QStringLiteral("EQUAL")) { SetKey(VK_OEM_PLUS, 0, false, QStringLiteral("Equal")); return true; }
const QRegularExpression FunctionKeyPattern(QStringLiteral("^F(\\d{1,2})$"));
const QRegularExpressionMatch Match = FunctionKeyPattern.match(UpperToken);
if (Match.hasMatch())
{
const int FunctionIndex = Match.captured(1).toInt();
if ((FunctionIndex >= 1) && (FunctionIndex <= 24))
{
SetKey(
static_cast<WORD>(VK_F1 + FunctionIndex - 1),
0,
false,
QStringLiteral("F%1").arg(FunctionIndex));
return true;
}
}
return false;
}
bool Lgc_FunctionButton_ParseRecordedSequenceText(
const QString& Text,
quint16 SourceUsage,
QVector<Lgc_FunctionButton_Struct_SequenceKey>* p_KeyList,
QString* p_ErrorText)
{
p_KeyList->clear();
if (p_ErrorText != nullptr) p_ErrorText->clear();
const QStringList TokenList = Text.split(
QRegularExpression(QStringLiteral("[\\s,;|,;、]+")),
QString::SkipEmptyParts);
if (TokenList.isEmpty())
{
return false;
}
for (const QString& Token : TokenList)
{
Lgc_FunctionButton_Struct_SequenceKey KeyItem;
if (!Lgc_FunctionButton_TryParseSequenceToken(Token, SourceUsage, &KeyItem))
{
if (p_ErrorText != nullptr)
{
*p_ErrorText = QStringLiteral("无法识别的按键序列片段:%1").arg(Token);
}
p_KeyList->clear();
return false;
}
p_KeyList->append(KeyItem);
}
return true;
}
bool Lgc_FunctionButton_IsSameWindowsKey(
const Lgc_FunctionButton_Struct_WindowsKey& Left,
const Lgc_FunctionButton_Struct_WindowsKey& Right)
{
return (Left.VirtualKey == Right.VirtualKey) &&
(Left.ExtraFlags == Right.ExtraFlags);
}
bool Lgc_FunctionButton_ParseKeyCombinationText(
const QString& Text,
quint16 SourceUsage,
QVector<Lgc_FunctionButton_Struct_SequenceKey>* p_KeyList,
QString* p_ErrorText)
{
p_KeyList->clear();
if (p_ErrorText != nullptr) p_ErrorText->clear();
QStringList TokenList;
if (Text.contains(QLatin1Char('+')))
{
TokenList = Text.split(
QRegularExpression(QStringLiteral("\\s*\\+\\s*")),
QString::SkipEmptyParts);
}
else
{
TokenList = Text.split(
QRegularExpression(QStringLiteral("[\\s,;|,;、]+")),
QString::SkipEmptyParts);
}
for (const QString& Token : TokenList)
{
Lgc_FunctionButton_Struct_SequenceKey KeyItem;
if (!Lgc_FunctionButton_TryParseSequenceToken(Token, SourceUsage, &KeyItem))
{
if (p_ErrorText != nullptr)
{
*p_ErrorText = QStringLiteral("无法识别的按键片段:%1").arg(Token);
}
p_KeyList->clear();
return false;
}
p_KeyList->append(KeyItem);
}
return !p_KeyList->isEmpty();
}
QString Lgc_FunctionButton_FormatKeyCombination(
const QVector<Lgc_FunctionButton_Struct_SequenceKey>& KeyList)
{
QStringList TextList;
for (const auto& KeyItem : KeyList)
{
TextList.append(KeyItem.Text);
}
return TextList.join(QStringLiteral("+"));
}
QVector<QVector<Lgc_FunctionButton_Struct_SequenceKey>>
Lgc_FunctionButton_GroupSequenceKeysIntoCombinations(
const QVector<Lgc_FunctionButton_Struct_SequenceKey>& KeyList)
{
QVector<QVector<Lgc_FunctionButton_Struct_SequenceKey>> CombinationList;
QVector<Lgc_FunctionButton_Struct_SequenceKey> ModifierList;
for (const auto& KeyItem : KeyList)
{
if (KeyItem.Key.IsModifier)
{
bool IsDuplicate = false;
for (const auto& OldModifier : ModifierList)
{
if (Lgc_FunctionButton_IsSameWindowsKey(OldModifier.Key, KeyItem.Key))
{
IsDuplicate = true;
break;
}
}
if (!IsDuplicate)
{
ModifierList.append(KeyItem);
}
continue;
}
QVector<Lgc_FunctionButton_Struct_SequenceKey> Combination = ModifierList;
Combination.append(KeyItem);
CombinationList.append(Combination);
}
if (CombinationList.isEmpty() && !ModifierList.isEmpty())
{
CombinationList.append(ModifierList);
}
return CombinationList;
}
bool Lgc_FunctionButton_ParseShortcutSequenceText(
const QString& Text,
quint16 SourceUsage,
QVector<QVector<Lgc_FunctionButton_Struct_SequenceKey>>* p_CombinationList,
QString* p_ErrorText)
{
p_CombinationList->clear();
if (p_ErrorText != nullptr) p_ErrorText->clear();
const QStringList SegmentList = Text.split(
QRegularExpression(QStringLiteral("\\s*(?:->|=>|→)\\s*")),
QString::SkipEmptyParts);
if (SegmentList.size() > 1)
{
for (const QString& SegmentText : SegmentList)
{
QVector<Lgc_FunctionButton_Struct_SequenceKey> Combination;
if (!Lgc_FunctionButton_ParseKeyCombinationText(
SegmentText,
SourceUsage,
&Combination,
p_ErrorText))
{
p_CombinationList->clear();
return false;
}
p_CombinationList->append(Combination);
}
return !p_CombinationList->isEmpty();
}
QVector<Lgc_FunctionButton_Struct_SequenceKey> FlatKeyList;
if (!Lgc_FunctionButton_ParseRecordedSequenceText(
Text,
SourceUsage,
&FlatKeyList,
p_ErrorText))
{
QVector<Lgc_FunctionButton_Struct_SequenceKey> SingleCombination;
if (!Lgc_FunctionButton_ParseKeyCombinationText(
Text,
SourceUsage,
&SingleCombination,
p_ErrorText))
{
return false;
}
p_CombinationList->append(SingleCombination);
return true;
}
*p_CombinationList = Lgc_FunctionButton_GroupSequenceKeysIntoCombinations(FlatKeyList);
return !p_CombinationList->isEmpty();
}
QString Lgc_FunctionButton_FormatShortcutSequence(
const QVector<QVector<Lgc_FunctionButton_Struct_SequenceKey>>& CombinationList)
{
QStringList TextList;
for (const auto& Combination : CombinationList)
{
TextList.append(Lgc_FunctionButton_FormatKeyCombination(Combination));
}
return TextList.join(QStringLiteral(" -> "));
}
QVector<Lgc_FunctionButton_Struct_SequenceKey> Lgc_FunctionButton_ConvertUsageListToSequenceKeys(
const QVector<quint16>& UsageList)
{
QVector<Lgc_FunctionButton_Struct_SequenceKey> KeyList;
for (quint16 Usage : UsageList)
{
const auto Key = Lgc_FunctionButton_GetWindowsKey(Usage);
if (Key.VirtualKey == 0)
{
KeyList.clear();
return KeyList;
}
Lgc_FunctionButton_Struct_SequenceKey KeyItem;
KeyItem.Key = Key;
KeyItem.Text = Lgc_FunctionButton_GetUsageShortText(Usage);
KeyList.append(KeyItem);
}
return KeyList;
}