feat(master): add cached conversion mode file
This commit is contained in:
@ -21,7 +21,11 @@
|
|||||||
// ReSharper disable CppDeprecatedEntity
|
// ReSharper disable CppDeprecatedEntity
|
||||||
// ReSharper disable CppClangTidyCertErr33C
|
// ReSharper disable CppClangTidyCertErr33C
|
||||||
|
|
||||||
std::ofstream GLogFile;
|
const std::string LogFilename = "FocusIME.log";
|
||||||
|
|
||||||
|
const std::string CachedModeFilename = "FocusIME.json";
|
||||||
|
|
||||||
|
std::ofstream GLogStream;
|
||||||
|
|
||||||
bool GShouldExit = false;
|
bool GShouldExit = false;
|
||||||
|
|
||||||
@ -48,7 +52,153 @@ void Tick()
|
|||||||
Chinese,
|
Chinese,
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::map<std::string, EIMEConversionMode> CachedIMEMode;
|
static std::map<std::string, EIMEConversionMode> CachedIMEMode = []
|
||||||
|
{
|
||||||
|
std::map<std::string, EIMEConversionMode> Result;
|
||||||
|
|
||||||
|
std::ifstream File(CachedModeFilename);
|
||||||
|
|
||||||
|
if (!File.is_open())
|
||||||
|
{
|
||||||
|
PrintLog("Cached conversion mode configuration file not found");
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
std::string Buffer;
|
||||||
|
|
||||||
|
Buffer.assign(std::istreambuf_iterator<char>(File), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
std::string_view View = Buffer;
|
||||||
|
|
||||||
|
// { "ItemA": "ValueA", "ItemB": "ValueB" }
|
||||||
|
|
||||||
|
while (!View.empty() && std::isspace(View.front())) View.remove_prefix(1);
|
||||||
|
while (!View.empty() && std::isspace(View.back ())) View.remove_suffix(1);
|
||||||
|
|
||||||
|
if (!View.starts_with('{') || !View.ends_with('}')) break;
|
||||||
|
|
||||||
|
View.remove_prefix(1);
|
||||||
|
View.remove_suffix(1);
|
||||||
|
|
||||||
|
// "ItemA": "ValueA", "ItemB": "ValueB"
|
||||||
|
|
||||||
|
const bool bSuccessful = [&Result, &View]
|
||||||
|
{
|
||||||
|
std::string_view::size_type Index = std::string_view::npos;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
while (!View.empty() && std::isspace(View.front())) View.remove_prefix(1);
|
||||||
|
|
||||||
|
if (!View.starts_with('"')) return false;
|
||||||
|
|
||||||
|
View.remove_prefix(1);
|
||||||
|
|
||||||
|
// ItemA": "ValueA", "ItemB": "ValueB"
|
||||||
|
|
||||||
|
Index = View.find('"');
|
||||||
|
|
||||||
|
if (Index == std::string_view::npos) return false;
|
||||||
|
|
||||||
|
std::string_view Process = View.substr(0, Index);
|
||||||
|
|
||||||
|
View.remove_prefix(Process.size() + 1);
|
||||||
|
|
||||||
|
// : "ValueA", "ItemB": "ValueB"
|
||||||
|
|
||||||
|
while (!View.empty() && std::isspace(View.front())) View.remove_prefix(1);
|
||||||
|
|
||||||
|
if (!View.starts_with(':')) return false;
|
||||||
|
|
||||||
|
View.remove_prefix(1);
|
||||||
|
|
||||||
|
// "ValueA", "ItemB": "ValueB"
|
||||||
|
|
||||||
|
while (!View.empty() && std::isspace(View.front())) View.remove_prefix(1);
|
||||||
|
|
||||||
|
if (!View.starts_with('"')) return false;
|
||||||
|
|
||||||
|
View.remove_prefix(1);
|
||||||
|
|
||||||
|
// ValueA", "ItemB": "ValueB"
|
||||||
|
|
||||||
|
Index = View.find('"');
|
||||||
|
|
||||||
|
if (Index == std::string_view::npos) return false;
|
||||||
|
|
||||||
|
std::string_view Mode = View.substr(0, Index);
|
||||||
|
|
||||||
|
View.remove_prefix(Mode.size() + 1);
|
||||||
|
|
||||||
|
// , "ItemB": "ValueB"
|
||||||
|
|
||||||
|
while (!View.empty() && std::isspace(View.front())) View.remove_prefix(1);
|
||||||
|
|
||||||
|
if (View.empty()) return true;
|
||||||
|
|
||||||
|
if (!View.starts_with(',')) return false;
|
||||||
|
|
||||||
|
View.remove_prefix(1);
|
||||||
|
|
||||||
|
if (Mode != "English" && Mode != "Chinese" && Mode != "Default") return false;
|
||||||
|
|
||||||
|
Result[std::string(Process)] =
|
||||||
|
Mode == "English" ? EIMEConversionMode::English :
|
||||||
|
Mode == "Chinese" ? EIMEConversionMode::Chinese : EIMEConversionMode::Default;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} ();
|
||||||
|
|
||||||
|
if (!bSuccessful) break;
|
||||||
|
|
||||||
|
PrintLog("Successfully loaded " + std::to_string(Result.size()) + " cached conversion mode items");
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
PrintLog("Invalid format detected in cached conversion mode configuration file");
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
} ();
|
||||||
|
|
||||||
|
auto SaveCachedIMEMode = []
|
||||||
|
{
|
||||||
|
std::ofstream File(CachedModeFilename);
|
||||||
|
|
||||||
|
if (!File.is_open())
|
||||||
|
{
|
||||||
|
PrintLog("Error: Failed to save cached conversion mode configuration");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File << "{";
|
||||||
|
|
||||||
|
bool bFirstItem = true;
|
||||||
|
|
||||||
|
for (const auto& [Name, Mode] : CachedIMEMode)
|
||||||
|
{
|
||||||
|
if (!bFirstItem) File << ",";
|
||||||
|
|
||||||
|
File << "\n\t\"" << Name << "\": \"" <<
|
||||||
|
(Mode == EIMEConversionMode::English ? "English" :
|
||||||
|
Mode == EIMEConversionMode::Chinese ? "Chinese" : "Default") << "\"";
|
||||||
|
|
||||||
|
bFirstItem = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File << "\n}\n";
|
||||||
|
|
||||||
|
File.close();
|
||||||
|
};
|
||||||
|
|
||||||
static HWND LastWindow = nullptr;
|
static HWND LastWindow = nullptr;
|
||||||
|
|
||||||
@ -83,9 +233,11 @@ void Tick()
|
|||||||
{
|
{
|
||||||
CachedIMEMode[CachedProcess] = CurrentMode;
|
CachedIMEMode[CachedProcess] = CurrentMode;
|
||||||
|
|
||||||
PrintLog("Update the conversion mode cached for process '" + CachedProcess + "' to " +
|
PrintLog("Updated cached conversion mode for process '" + CachedProcess + "' to " +
|
||||||
(CurrentMode == EIMEConversionMode::English ? "English" :
|
(CurrentMode == EIMEConversionMode::English ? "English" :
|
||||||
CurrentMode == EIMEConversionMode::Chinese ? "Chinese" : "Default"));
|
CurrentMode == EIMEConversionMode::Chinese ? "Chinese" : "Default"));
|
||||||
|
|
||||||
|
SaveCachedIMEMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,11 +297,11 @@ void Tick()
|
|||||||
{
|
{
|
||||||
if (SendMessage(IMEWindow, WM_IME_CONTROL, IMC_SETCONVERSIONMODE, TargetMode) == 0)
|
if (SendMessage(IMEWindow, WM_IME_CONTROL, IMC_SETCONVERSIONMODE, TargetMode) == 0)
|
||||||
{
|
{
|
||||||
PrintLog("Successfully set conversion mode for process '" + CachedProcess + "'");
|
PrintLog("Successfully applied conversion mode for process '" + CachedProcess + "'");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrintLog("Failed to set conversion mode for process '" + CachedProcess + "'");
|
PrintLog("Error: Failed to apply conversion mode for process '" + CachedProcess + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,9 +417,9 @@ int WINAPI WinMain(HINSTANCE Instance, HINSTANCE, LPSTR, int)
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
GLogFile.open("Log.txt", std::ios::out | std::ios::app);
|
GLogStream.open(LogFilename, std::ios::out | std::ios::app);
|
||||||
|
|
||||||
if (!GLogFile.is_open())
|
if (!GLogStream.is_open())
|
||||||
{
|
{
|
||||||
MessageBox(nullptr, "Failed to open log file.", "FocusIME", MB_OK | MB_ICONERROR);
|
MessageBox(nullptr, "Failed to open log file.", "FocusIME", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
@ -276,7 +428,7 @@ int WINAPI WinMain(HINSTANCE Instance, HINSTANCE, LPSTR, int)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintLog("FocusIME started successfully");
|
PrintLog("FocusIME application started successfully");
|
||||||
|
|
||||||
MSG Message = { };
|
MSG Message = { };
|
||||||
|
|
||||||
@ -318,9 +470,9 @@ int WINAPI WinMain(HINSTANCE Instance, HINSTANCE, LPSTR, int)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintLog("FocusIME is shutting down...");
|
PrintLog("FocusIME application is shutting down");
|
||||||
|
|
||||||
GLogFile.close();
|
GLogStream.close();
|
||||||
|
|
||||||
# if BUILD_DEBUG || BUILD_DEVELOPMENT
|
# if BUILD_DEBUG || BUILD_DEVELOPMENT
|
||||||
{
|
{
|
||||||
@ -407,7 +559,7 @@ LRESULT CALLBACK MainWindowProc(const HWND Window, const UINT Message, const WPA
|
|||||||
|
|
||||||
if (LOWORD(WParam) == ID_TRAY_EXIT)
|
if (LOWORD(WParam) == ID_TRAY_EXIT)
|
||||||
{
|
{
|
||||||
PrintLog("Exit command received from tray menu");
|
PrintLog("Exit command received from system tray menu");
|
||||||
|
|
||||||
GShouldExit = true;
|
GShouldExit = true;
|
||||||
|
|
||||||
@ -451,7 +603,7 @@ void PrintLog(const std::string& Text)
|
|||||||
Buffer[22] = Digits[Milliseconds / 10 % 10];
|
Buffer[22] = Digits[Milliseconds / 10 % 10];
|
||||||
Buffer[23] = Digits[Milliseconds / 1 % 10];
|
Buffer[23] = Digits[Milliseconds / 1 % 10];
|
||||||
|
|
||||||
GLogFile << Buffer << Text << std::endl;
|
GLogStream << Buffer << Text << std::endl;
|
||||||
|
|
||||||
#if BUILD_DEBUG || BUILD_DEVELOPMENT
|
#if BUILD_DEBUG || BUILD_DEVELOPMENT
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user