mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
feat: 添加解析错误消息
This commit is contained in:
parent
7682132dce
commit
a7c3f766f7
20 changed files with 165 additions and 108 deletions
|
|
@ -57,16 +57,13 @@ void LocalizationService::EarlyInitialize() {
|
|||
}
|
||||
}
|
||||
|
||||
_Language(bestLanguage);
|
||||
_SetLanguage(bestLanguage);
|
||||
}
|
||||
|
||||
void LocalizationService::Initialize(int language) {
|
||||
if (language >= 0) {
|
||||
_Language(SUPPORTED_LANGUAGES[language]);
|
||||
_SetLanguage(SUPPORTED_LANGUAGES[language]);
|
||||
}
|
||||
|
||||
_resourceLoader = winrt::ResourceLoader::GetForViewIndependentUse(
|
||||
CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
}
|
||||
|
||||
std::span<const wchar_t*> LocalizationService::GetSupportedLanguages() noexcept {
|
||||
|
|
@ -74,10 +71,14 @@ std::span<const wchar_t*> LocalizationService::GetSupportedLanguages() noexcept
|
|||
}
|
||||
|
||||
winrt::hstring LocalizationService::GetLocalizedString(std::wstring_view resName) const noexcept {
|
||||
return _resourceLoader.GetString(resName);
|
||||
assert(_language);
|
||||
// 不确定 ResourceLoader 是否线程安全,为每个线程创建独立的实例
|
||||
thread_local static winrt::ResourceLoader resourceLoader =
|
||||
winrt::ResourceLoader::GetForViewIndependentUse(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
return resourceLoader.GetString(resName);
|
||||
}
|
||||
|
||||
void LocalizationService::_Language(const wchar_t* tag) {
|
||||
void LocalizationService::_SetLanguage(const wchar_t* tag) {
|
||||
_language = tag;
|
||||
winrt::ResourceContext::SetGlobalQualifierValue(L"Language", tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
#include "StrHelper.h"
|
||||
#include "Logger.h"
|
||||
#include "ShaderEffectDesc.h"
|
||||
#include "LocalizationService.h"
|
||||
#include <bitset>
|
||||
|
||||
namespace Magpie {
|
||||
|
||||
// 当前 MagpieFX 版本
|
||||
static constexpr uint32_t MAGPIE_FX_VERSION = 5;
|
||||
// 向后兼容的最低版本
|
||||
static constexpr uint32_t MAGPIE_FX_MIN_SUPPORTED_VERSION = 4;
|
||||
|
||||
// 必须出现在一行的开头才视为指令
|
||||
static const char* META_INDICATOR = "//!";
|
||||
|
|
@ -20,6 +23,37 @@ struct ParserState {
|
|||
bool isNewLine;
|
||||
};
|
||||
|
||||
static std::string DebugFormat(std::string_view str) noexcept {
|
||||
return fmt::format("{:?s}", std::span<const char>(str.begin(), str.end()));
|
||||
}
|
||||
|
||||
static void SetGeneralParseError(
|
||||
ParserState& state,
|
||||
std::string_view source,
|
||||
std::string_view expected = {}
|
||||
) noexcept {
|
||||
// 限制打印的源代码字符数量
|
||||
std::string sourceStart;
|
||||
constexpr uint32_t SOURCE_PRINT_COUNT = 12;
|
||||
if (source.size() <= SOURCE_PRINT_COUNT) {
|
||||
sourceStart = DebugFormat(source);
|
||||
} else {
|
||||
sourceStart = StrHelper::Concat(source.substr(0, SOURCE_PRINT_COUNT), "...");
|
||||
sourceStart = DebugFormat(sourceStart);
|
||||
}
|
||||
|
||||
if (expected.empty()) {
|
||||
std::string msgFmt = StrHelper::UTF16ToUTF8(LocalizationService::Get()
|
||||
.GetLocalizedString(L"ShaderEffectParser_GeneralError"));
|
||||
state.errorMsg = fmt::format(fmt::runtime(msgFmt), state.lineNumber, sourceStart);
|
||||
} else {
|
||||
std::string msgFmt = StrHelper::UTF16ToUTF8(LocalizationService::Get()
|
||||
.GetLocalizedString(L"ShaderEffectParser_GeneralErrorWithExpected"));
|
||||
state.errorMsg = fmt::format(fmt::runtime(msgFmt),
|
||||
state.lineNumber, sourceStart, DebugFormat(expected));
|
||||
}
|
||||
}
|
||||
|
||||
static bool RemoveLeadingComment(
|
||||
std::string_view& source,
|
||||
ParserState& state,
|
||||
|
|
@ -72,7 +106,8 @@ static bool RemoveLeadingComment(
|
|||
|
||||
// 提取换行符的后一个字符需检查文件结尾
|
||||
if (i + 1 == source.size()) {
|
||||
state.errorMsg = "块注释未闭合";
|
||||
state.errorMsg = StrHelper::UTF16ToUTF8(LocalizationService::Get()
|
||||
.GetLocalizedString(L"ShaderEffectParser_UnclosedBlockComment"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -144,6 +179,7 @@ static bool GetNextToken(std::string_view& source, ParserState& state, std::stri
|
|||
result = source;
|
||||
return true;
|
||||
} else {
|
||||
SetGeneralParseError(state, source);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -152,7 +188,7 @@ static bool GetNextToken(std::string_view& source, ParserState& state, std::stri
|
|||
|
||||
// 必须以字母或下划线开头
|
||||
if (!StrHelper::isalpha(c) && c != '_') {
|
||||
state.errorMsg = fmt::format("Unexpected character \"{}\" in line {}.", c, state.lineNumber);
|
||||
SetGeneralParseError(state, source);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +223,7 @@ static bool CheckNextToken(std::string_view& source, ParserState& state, std::st
|
|||
if (token == expectedToken) {
|
||||
return true;
|
||||
} else {
|
||||
state.errorMsg = fmt::format("Unexpected token \"{}\" in line {}.", token, state.lineNumber);
|
||||
SetGeneralParseError(state, source, expectedToken);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -206,32 +242,25 @@ static bool CheckMetaIndicator(std::string_view& source, ParserState& state, boo
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool RequireMetaIndicator(std::string_view& source, ParserState& state) noexcept {
|
||||
bool result = false;
|
||||
if (!CheckMetaIndicator(source, state, result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
state.errorMsg = fmt::format("Unexpected character \"{}\" in line {}.", source[0], state.lineNumber);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool RequireLineEnd(std::string_view& source, ParserState& state) noexcept {
|
||||
RemoveLeadingSpaces(source, state);
|
||||
|
||||
if (source.empty() || source[0] == '\n') {
|
||||
return true;
|
||||
} else {
|
||||
state.errorMsg = fmt::format("Unexpected character \"{}\" in line {}.", source[0], state.lineNumber);
|
||||
SetGeneralParseError(state, source, "\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool CheckMagic(std::string_view& source, ParserState& state) noexcept {
|
||||
if (!RequireMetaIndicator(source, state)) {
|
||||
bool isMetaIndicator = false;
|
||||
if (!CheckMetaIndicator(source, state, isMetaIndicator)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isMetaIndicator) {
|
||||
SetGeneralParseError(state, source, META_INDICATOR);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -268,6 +297,7 @@ static bool GetNextStringUntilLineEnd(
|
|||
|
||||
if constexpr (!AllowEmpty) {
|
||||
if (value.empty()) {
|
||||
SetGeneralParseError(state, source);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -288,6 +318,7 @@ static bool GetNextNumber(std::string_view& source, ParserState& state, T& value
|
|||
|
||||
const auto& result = std::from_chars(source.data(), source.data() + source.size(), value);
|
||||
if ((int)result.ec) {
|
||||
SetGeneralParseError(state, source);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -371,8 +402,9 @@ static bool ResolveHeaderVersion(
|
|||
return false;
|
||||
}
|
||||
|
||||
// 向后兼容到 5
|
||||
if (version < 5 || version > MAGPIE_FX_VERSION) {
|
||||
if (version < MAGPIE_FX_MIN_SUPPORTED_VERSION || version > MAGPIE_FX_VERSION) {
|
||||
state.errorMsg = StrHelper::UTF16ToUTF8(LocalizationService::Get()
|
||||
.GetLocalizedString(L"ShaderEffectParser_UnsupportedFXVersion"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -467,7 +499,7 @@ static bool ResolveHeaderScaleFactor(
|
|||
|
||||
static bool ResolveHeader(
|
||||
std::string_view source,
|
||||
uint32_t startLineNumer,
|
||||
ParserState& state,
|
||||
EffectInfo& effectInfo
|
||||
) noexcept {
|
||||
static constexpr std::array COMMAND_INFOS = {
|
||||
|
|
@ -478,11 +510,6 @@ static bool ResolveHeader(
|
|||
CommandInfo{ "SCALE_FACTOR", ResolveHeaderScaleFactor, false },
|
||||
};
|
||||
|
||||
ParserState state = {
|
||||
.lineNumber = startLineNumer,
|
||||
.isNewLine = false
|
||||
};
|
||||
|
||||
if (!ResolveBlockCommon(COMMAND_INFOS, source, state, &effectInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -497,6 +524,7 @@ static bool ResolveHeader(
|
|||
|
||||
// HEADER 只能有 #include
|
||||
if (!source.starts_with("#include")) {
|
||||
SetGeneralParseError(state, source, "\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -511,7 +539,12 @@ static bool ResolveHeader(
|
|||
return false;
|
||||
}
|
||||
|
||||
return source.empty();
|
||||
if (!source.empty()) {
|
||||
SetGeneralParseError(state, source, "\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ResolveParameterDefault(
|
||||
|
|
@ -594,7 +627,7 @@ static bool ResolveParameterLabel(
|
|||
|
||||
static bool ResolveParameter(
|
||||
std::string_view source,
|
||||
uint32_t startLineNumer,
|
||||
ParserState& state,
|
||||
EffectInfoParameter& effectInfoParameter
|
||||
) noexcept {
|
||||
static constexpr std::array COMMAND_INFOS = {
|
||||
|
|
@ -605,11 +638,6 @@ static bool ResolveParameter(
|
|||
CommandInfo{ "LABEL", ResolveParameterLabel, false }
|
||||
};
|
||||
|
||||
ParserState state = {
|
||||
.lineNumber = startLineNumer,
|
||||
.isNewLine = false
|
||||
};
|
||||
|
||||
if (!ResolveBlockCommon(COMMAND_INFOS, source, state, &effectInfoParameter)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -626,6 +654,7 @@ static bool ResolveParameter(
|
|||
}
|
||||
|
||||
if (token != "float" && token != "int") {
|
||||
SetGeneralParseError(state, source, "float|int");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -635,7 +664,12 @@ static bool ResolveParameter(
|
|||
|
||||
effectInfoParameter.name = token;
|
||||
|
||||
if (!RemoveLeadingBlanks(source, state) || !source.starts_with(';')) {
|
||||
if (!RemoveLeadingBlanks(source, state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!source.starts_with(';')) {
|
||||
SetGeneralParseError(state, source, ";");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -774,14 +808,20 @@ std::string ShaderEffectParser::ParseForInfo(
|
|||
// 结束最后一个区块。source 以换行符结尾,因此最后一个区块也以换行符结尾。
|
||||
completeCurrentBlock(BlockType::Header, sourceView.size(), std::numeric_limits<size_t>::max());
|
||||
|
||||
if (!ResolveHeader(headerBlock.source, headerBlock.startLineNumer, effectInfo)) {
|
||||
state.lineNumber = headerBlock.startLineNumer;
|
||||
state.isNewLine = false;
|
||||
|
||||
if (!ResolveHeader(headerBlock.source, state, effectInfo)) {
|
||||
Logger::Get().Error(StrHelper::Concat("ResolveHeader 失败\n\t错误消息: ", state.errorMsg));
|
||||
return std::move(state.errorMsg);
|
||||
}
|
||||
|
||||
effectInfo.params.resize(paramBlocks.size());
|
||||
for (size_t i = 0; i < paramBlocks.size(); ++i) {
|
||||
if (!ResolveParameter(paramBlocks[i].source, paramBlocks[i].startLineNumer, effectInfo.params[i])) {
|
||||
state.lineNumber = paramBlocks[i].startLineNumer;
|
||||
state.isNewLine = false;
|
||||
|
||||
if (!ResolveParameter(paramBlocks[i].source, state, effectInfo.params[i])) {
|
||||
Logger::Get().Error(fmt::format("ResolveParameter#{} 失败\n\t错误消息: ", state.errorMsg));
|
||||
return std::move(state.errorMsg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@ public:
|
|||
private:
|
||||
LocalizationService() = default;
|
||||
|
||||
void _Language(const wchar_t* tag);
|
||||
void _SetLanguage(const wchar_t* tag);
|
||||
|
||||
const wchar_t* _language = nullptr;
|
||||
winrt::ResourceLoader _resourceLoader{ nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,10 +178,9 @@ static HRESULT CALLBACK TaskDialogCallback(
|
|||
}
|
||||
|
||||
static void ShowErrorMessage(const wchar_t* mainInstruction, const wchar_t* content) noexcept {
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
const hstring errorStr = resourceLoader.GetString(L"AppSettings_Dialog_Error");
|
||||
const hstring exitStr = resourceLoader.GetString(L"AppSettings_Dialog_Exit");
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
const hstring errorStr = ls.GetLocalizedString(L"AppSettings_Dialog_Error");
|
||||
const hstring exitStr = ls.GetLocalizedString(L"AppSettings_Dialog_Exit");
|
||||
|
||||
TASKDIALOG_BUTTON button{ IDCANCEL, exitStr.c_str() };
|
||||
TASKDIALOGCONFIG tdc{
|
||||
|
|
@ -223,17 +222,18 @@ bool AppSettings::Initialize() noexcept {
|
|||
return true;
|
||||
}
|
||||
|
||||
// 此时 ResourceLoader 使用“首选语言”
|
||||
// 此时 LocalizationService 使用“首选语言”
|
||||
|
||||
std::string configText;
|
||||
if (!Win32Helper::ReadTextFile(existingConfigPath.c_str(), configText)) {
|
||||
logger.Error("读取配置文件失败");
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
hstring title = resourceLoader.GetString(L"AppSettings_ErrorDialog_ReadFailed");
|
||||
hstring content = resourceLoader.GetString(L"AppSettings_ErrorDialog_ConfigLocation");
|
||||
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
hstring title = ls.GetLocalizedString(L"AppSettings_ErrorDialog_ReadFailed");
|
||||
hstring content = ls.GetLocalizedString(L"AppSettings_ErrorDialog_ConfigLocation");
|
||||
ShowErrorMessage(title.c_str(),
|
||||
fmt::format(fmt::runtime(std::wstring_view(content)), existingConfigPath.native()).c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -249,23 +249,25 @@ bool AppSettings::Initialize() noexcept {
|
|||
doc.ParseInsitu(configText.data());
|
||||
if (doc.HasParseError()) {
|
||||
Logger::Get().Error(fmt::format("解析配置失败\n\t错误码: {}", (int)doc.GetParseError()));
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
hstring title = resourceLoader.GetString(L"AppSettings_ErrorDialog_NotValidJson");
|
||||
hstring content = resourceLoader.GetString(L"AppSettings_ErrorDialog_ConfigLocation");
|
||||
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
hstring title = ls.GetLocalizedString(L"AppSettings_ErrorDialog_NotValidJson");
|
||||
hstring content = ls.GetLocalizedString(L"AppSettings_ErrorDialog_ConfigLocation");
|
||||
ShowErrorMessage(title.c_str(),
|
||||
fmt::format(fmt::runtime(std::wstring_view(content)), existingConfigPath.native()).c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doc.IsObject()) {
|
||||
Logger::Get().Error("配置文件根元素不是 Object");
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
hstring title = resourceLoader.GetString(L"AppSettings_ErrorDialog_ParseFailed");
|
||||
hstring content = resourceLoader.GetString(L"AppSettings_ErrorDialog_ConfigLocation");
|
||||
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
hstring title = ls.GetLocalizedString(L"AppSettings_ErrorDialog_ParseFailed");
|
||||
hstring content = ls.GetLocalizedString(L"AppSettings_ErrorDialog_ConfigLocation");
|
||||
ShowErrorMessage(title.c_str(),
|
||||
fmt::format(fmt::runtime(std::wstring_view(content)), existingConfigPath.native()).c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,9 +43,8 @@ HomeViewModel::HomeViewModel() {
|
|||
}
|
||||
|
||||
hstring HomeViewModel::TimerDescription() const noexcept {
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
hstring fmtStr = resourceLoader.GetString(L"Home_Activation_Timer_Description");
|
||||
hstring fmtStr = LocalizationService::Get()
|
||||
.GetLocalizedString(L"Home_Activation_Timer_Description");
|
||||
return hstring(fmt::format(
|
||||
fmt::runtime(std::wstring_view(fmtStr)),
|
||||
AppSettings::Get().CountdownSeconds()
|
||||
|
|
@ -71,12 +70,11 @@ bool HomeViewModel::IsNotRunning() const noexcept {
|
|||
}
|
||||
|
||||
hstring HomeViewModel::TimerButtonText(bool windowedMode) const noexcept {
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
if (ScalingService::Get().IsTimerOn(windowedMode)) {
|
||||
return resourceLoader.GetString(L"Home_Activation_Timer_Cancel");
|
||||
return ls.GetLocalizedString(L"Home_Activation_Timer_Cancel");
|
||||
} else {
|
||||
return resourceLoader.GetString(L"Home_Activation_Timer_Start");
|
||||
return ls.GetLocalizedString(L"Home_Activation_Timer_Start");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,9 +117,8 @@ hstring HomeViewModel::UpdateCardTitle() const noexcept {
|
|||
return {};
|
||||
}
|
||||
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
hstring titleFmt = resourceLoader.GetString(L"About_Version_UpdateCard_Title");
|
||||
hstring titleFmt = LocalizationService::Get()
|
||||
.GetLocalizedString(L"About_Version_UpdateCard_Title");
|
||||
return hstring(fmt::format(fmt::runtime(std::wstring_view(titleFmt)), updateService.Tag()));
|
||||
}
|
||||
|
||||
|
|
@ -162,15 +159,14 @@ hstring HomeViewModel::InitialToolbarStateDescription() const noexcept {
|
|||
const ToolbarState windowedInitialState =
|
||||
AppSettings::Get().WindowedInitialToolbarState();
|
||||
|
||||
const ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
if (fullscreenInitialState == windowedInitialState) {
|
||||
return resourceLoader.GetString(STATE_STRING_IDS[(uint32_t)fullscreenInitialState]);
|
||||
return ls.GetLocalizedString(STATE_STRING_IDS[(uint32_t)fullscreenInitialState]);
|
||||
} else {
|
||||
return hstring(StrHelper::Concat(
|
||||
resourceLoader.GetString(STATE_STRING_IDS[(uint32_t)fullscreenInitialState]),
|
||||
ls.GetLocalizedString(STATE_STRING_IDS[(uint32_t)fullscreenInitialState]),
|
||||
L" | ",
|
||||
resourceLoader.GetString(STATE_STRING_IDS[(uint32_t)windowedInitialState]))
|
||||
ls.GetLocalizedString(STATE_STRING_IDS[(uint32_t)windowedInitialState]))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -229,9 +225,8 @@ void HomeViewModel::OpenScreenshotSaveDirectory() const noexcept {
|
|||
}
|
||||
|
||||
fire_and_forget HomeViewModel::ChangeScreenshotSaveDirectory() noexcept {
|
||||
const ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
const hstring titleStr = resourceLoader.GetString(L"Dialog_SetlectScreenshotSaveDirectory_Title");
|
||||
const hstring titleStr = LocalizationService::Get()
|
||||
.GetLocalizedString(L"Dialog_SelectScreenshotSaveDirectory_Title");
|
||||
|
||||
const std::filesystem::path oldValue = AppSettings::Get().ScreenshotsDir();
|
||||
|
||||
|
|
|
|||
|
|
@ -916,7 +916,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>Change</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>Select a directory to save screenshots</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
@ -1060,4 +1060,16 @@
|
|||
<data name="Home_Advanced_DeveloperOptions_HighestShaderModel_NotLimited.Content" xml:space="preserve">
|
||||
<value>Not limited</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_UnclosedBlockComment" xml:space="preserve">
|
||||
<value>Unclosed block comment.</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_GeneralError" xml:space="preserve">
|
||||
<value>Line {}: unable to parse {}.</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_UnsupportedFXVersion" xml:space="preserve">
|
||||
<value>Unsupported FX version.</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_GeneralErrorWithExpected" xml:space="preserve">
|
||||
<value>Line {}: unable to parse {}, expected: {}.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -895,7 +895,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>Cambiar</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>Selecciona una ruta para guardar capturas de pantalla</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -910,7 +910,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>Changer</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>Choisissez un répertoire pour sauvegarder vos captures</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -913,7 +913,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>Ubah</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>Pilih direktori untuk menyimpan tangkapan layar</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -910,7 +910,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>変更</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>スクリーンショットの保存先を選択する</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -949,7 +949,7 @@
|
|||
<data name="Message_Windowed3DGameMode" xml:space="preserve">
|
||||
<value>3D 게임 모드에서는 창 모드 스케일링이 지원되지 않습니다.</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>스크린샷을 저장할 경로를 선택하세요</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -854,7 +854,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>Zmień</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>Wybierz katalog, w którym chcesz zapisać zrzuty ekranu</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -910,7 +910,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>Изменить</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>Выбрать директорию сохранения скриншотов</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -913,7 +913,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>மாற்றம்</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>திரை சாட்களைச் சேமிக்க ஒரு கோப்பகத்தைத் தேர்ந்தெடுக்கவும்</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -835,7 +835,7 @@
|
|||
<data name="Home_Advanced_DeveloperOptions_DisableTopmost.Content" xml:space="preserve">
|
||||
<value>Tắt chế độ luôn ở trên cùng</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>Chọn thư mục để lưu ảnh chụp màn hình</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -916,7 +916,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>更改</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>选择截图保存目录</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
@ -1060,4 +1060,16 @@
|
|||
<data name="Home_Advanced_DeveloperOptions_HighestShaderModel_NotLimited.Content" xml:space="preserve">
|
||||
<value>不限制</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_UnclosedBlockComment" xml:space="preserve">
|
||||
<value>块注释未闭合。</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_GeneralErrorWithExpected" xml:space="preserve">
|
||||
<value>第 {} 行: 无法解析 {},期望为:{}。</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_UnsupportedFXVersion" xml:space="preserve">
|
||||
<value>不支持的 FX 版本。</value>
|
||||
</data>
|
||||
<data name="ShaderEffectParser_GeneralError" xml:space="preserve">
|
||||
<value>第 {} 行: 无法解析 {}。</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -913,7 +913,7 @@
|
|||
<data name="Home_Toolbar_ScreenshotSaveDirectory_Change.Content" xml:space="preserve">
|
||||
<value>更改</value>
|
||||
</data>
|
||||
<data name="Dialog_SetlectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<data name="Dialog_SelectScreenshotSaveDirectory_Title" xml:space="preserve">
|
||||
<value>選擇截圖儲存目錄</value>
|
||||
</data>
|
||||
<data name="Message_ScreenshotSaved" xml:space="preserve">
|
||||
|
|
|
|||
|
|
@ -283,15 +283,13 @@ void RootPage::NewProfileNameContextFlyout_Opening(IInspectable const&, IInspect
|
|||
return;
|
||||
}
|
||||
|
||||
// 惰性初始化
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
|
||||
// 填入进程名
|
||||
MenuFlyoutItem item1;
|
||||
FontIcon icon1;
|
||||
icon1.Glyph(L"\xE9F5");
|
||||
item1.Text(resourceLoader.GetString(L"Root_NewProfileFlyout_NameContextFlyout_ProcessName"));
|
||||
item1.Text(ls.GetLocalizedString(L"Root_NewProfileFlyout_NameContextFlyout_ProcessName"));
|
||||
item1.Icon(icon1);
|
||||
RoutedEventHandler clickHandler([this](IInspectable const&, IInspectable const&) {
|
||||
_UpdateNewProfileNameTextBox(false);
|
||||
|
|
@ -304,7 +302,7 @@ void RootPage::NewProfileNameContextFlyout_Opening(IInspectable const&, IInspect
|
|||
MenuFlyoutItem item2;
|
||||
FontIcon icon2;
|
||||
icon2.Glyph(L"\xECAA");
|
||||
item2.Text(resourceLoader.GetString(L"Root_NewProfileFlyout_NameContextFlyout_AppName"));
|
||||
item2.Text(ls.GetLocalizedString(L"Root_NewProfileFlyout_NameContextFlyout_AppName"));
|
||||
item2.Icon(icon2);
|
||||
item2.Click(clickHandler);
|
||||
item2.Tag(box_value(2));
|
||||
|
|
@ -321,7 +319,7 @@ void RootPage::NewProfileNameContextFlyout_Opening(IInspectable const&, IInspect
|
|||
FontIcon icon3;
|
||||
icon3.Glyph(L"\xE737");
|
||||
item3.Icon(icon3);
|
||||
item3.Text(resourceLoader.GetString(L"Root_NewProfileFlyout_NameContextFlyout_WindowTitle"));
|
||||
item3.Text(ls.GetLocalizedString(L"Root_NewProfileFlyout_NameContextFlyout_WindowTitle"));
|
||||
item3.Click([this](IInspectable const&, IInspectable const&) {
|
||||
_UpdateNewProfileNameTextBox(true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "ScalingModeEffectItem.h"
|
||||
#include "Win32Helper.h"
|
||||
#include "RootPage.h"
|
||||
#include "LocalizationService.h"
|
||||
|
||||
using namespace ::Magpie;
|
||||
|
||||
|
|
@ -30,9 +31,8 @@ ScalingModeItem::ScalingModeItem(uint32_t index, bool isInitialExpanded)
|
|||
std::vector<IInspectable> linkedProfiles;
|
||||
const Profile& defaultProfile = AppSettings::Get().DefaultProfile();
|
||||
if (defaultProfile.scalingMode == (int)index) {
|
||||
hstring defaults = ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID)
|
||||
.GetString(L"Root_Defaults/Content");
|
||||
linkedProfiles.push_back(box_value(defaults));
|
||||
linkedProfiles.push_back(box_value(LocalizationService::Get()
|
||||
.GetLocalizedString(L"Root_Defaults/Content")));
|
||||
}
|
||||
for (const Profile& profile : AppSettings::Get().Profiles()) {
|
||||
if (profile.scalingMode == (int)index) {
|
||||
|
|
@ -267,10 +267,9 @@ hstring ScalingModeItem::Description() const noexcept {
|
|||
if (EffectsService::Get().GetEffect(effect.name) != nullptr) {
|
||||
result += EffectHelper::GetDisplayName(effect.name);
|
||||
} else {
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
result += L'(';
|
||||
result += resourceLoader.GetString(L"ScalingModes_Description_UnknownEffect");
|
||||
result += LocalizationService::Get()
|
||||
.GetLocalizedString(L"ScalingModes_Description_UnknownEffect");
|
||||
result += L')';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,13 @@ using namespace Magpie;
|
|||
namespace winrt::Magpie::implementation {
|
||||
|
||||
IVector<IInspectable> SettingsViewModel::Languages() const {
|
||||
std::span<const wchar_t*> tags = LocalizationService::Get().GetSupportedLanguages();
|
||||
LocalizationService& ls = LocalizationService::Get();
|
||||
std::span<const wchar_t*> tags = ls.GetSupportedLanguages();
|
||||
|
||||
std::vector<IInspectable> languages;
|
||||
languages.reserve(tags.size() + 1);
|
||||
|
||||
ResourceLoader resourceLoader =
|
||||
ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID);
|
||||
languages.push_back(box_value(resourceLoader.GetString(L"Settings_General_Language_System")));
|
||||
languages.push_back(box_value(ls.GetLocalizedString(L"Settings_General_Language_System")));
|
||||
for (const wchar_t* tag : tags) {
|
||||
Windows::Globalization::Language language(tag);
|
||||
languages.push_back(box_value(language.NativeName()));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue