diff --git a/Languages/update-source-strings.sh b/Languages/update-source-strings.sh index 2bf3bdcd28..6f7faf44a7 100755 --- a/Languages/update-source-strings.sh +++ b/Languages/update-source-strings.sh @@ -9,9 +9,24 @@ cd "$(dirname "$0")/.." SRCDIR=Source find $SRCDIR -name '*.cpp' -o -name '*.h' -o -name '*.c' | \ xgettext -s -p ./Languages/po -o dolphin-emu.pot --package-name="Dolphin Emulator" \ - --keyword=_ --keyword=wxTRANSLATE --keyword=SuccessAlertT --keyword=PanicAlertT \ - --keyword=PanicYesNoT --keyword=AskYesNoT --keyword=CriticalAlertT --keyword=GetStringT \ - --keyword=_trans --keyword=tr:1,1t --keyword=tr:1,2c --keyword=QT_TR_NOOP --keyword=FmtFormatT \ + --keyword=_ \ + --keyword=wxTRANSLATE \ + --keyword=AskYesNoT \ + --keyword=AskYesNoFmtT \ + --keyword=CriticalAlertT \ + --keyword=CriticalAlertFmtT \ + --keyword=PanicAlertT \ + --keyword=PanicAlertFmtT \ + --keyword=PanicYesNoT \ + --keyword=PanicYesNoFmtT \ + --keyword=SuccessAlertT \ + --keyword=SuccessAlertFmtT \ + --keyword=GetStringT \ + --keyword=_trans \ + --keyword=tr:1,1t \ + --keyword=tr:1,2c \ + --keyword=QT_TR_NOOP \ + --keyword=FmtFormatT \ --add-comments=i18n --from-code=utf-8 -f - # Copy strings from qt-strings.pot to dolphin-emu.pot diff --git a/Source/Core/Common/MsgHandler.cpp b/Source/Core/Common/MsgHandler.cpp index ce745ebc0a..e548554d7e 100644 --- a/Source/Core/Common/MsgHandler.cpp +++ b/Source/Core/Common/MsgHandler.cpp @@ -52,6 +52,28 @@ std::string DefaultStringTranslator(const char* text) MsgAlertHandler s_msg_handler = DefaultMsgHandler; StringTranslator s_str_translator = DefaultStringTranslator; bool s_alert_enabled = true; + +const char* GetCaption(MsgType style) +{ + static const std::string info_caption = s_str_translator(_trans("Information")); + static const std::string warn_caption = s_str_translator(_trans("Question")); + static const std::string ques_caption = s_str_translator(_trans("Warning")); + static const std::string crit_caption = s_str_translator(_trans("Critical")); + + switch (style) + { + case MsgType::Information: + return info_caption.c_str(); + case MsgType::Question: + return ques_caption.c_str(); + case MsgType::Warning: + return warn_caption.c_str(); + case MsgType::Critical: + return crit_caption.c_str(); + default: + return "Unhandled caption"; + } +} } // Anonymous namespace // Select which of these functions that are used for message boxes. If @@ -83,30 +105,9 @@ std::string GetStringT(const char* string) bool MsgAlert(bool yes_no, MsgType style, const char* format, ...) { // Read message and write it to the log - const char* caption = ""; + const char* caption = GetCaption(style); char buffer[2048]; - static const std::string info_caption = s_str_translator(_trans("Information")); - static const std::string warn_caption = s_str_translator(_trans("Question")); - static const std::string ques_caption = s_str_translator(_trans("Warning")); - static const std::string crit_caption = s_str_translator(_trans("Critical")); - - switch (style) - { - case MsgType::Information: - caption = info_caption.c_str(); - break; - case MsgType::Question: - caption = ques_caption.c_str(); - break; - case MsgType::Warning: - caption = warn_caption.c_str(); - break; - case MsgType::Critical: - caption = crit_caption.c_str(); - break; - } - va_list args; va_start(args, format); CharArrayFromFormatV(buffer, sizeof(buffer) - 1, s_str_translator(format).c_str(), args); @@ -123,4 +124,21 @@ bool MsgAlert(bool yes_no, MsgType style, const char* format, ...) return true; } + +bool MsgAlertFmtImpl(bool yes_no, MsgType style, fmt::string_view format, + const fmt::format_args& args) +{ + const char* caption = GetCaption(style); + const auto message = fmt::vformat(format, args); + ERROR_LOG_FMT(MASTER_LOG, "{}: {}", caption, message); + + // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored + if (s_msg_handler != nullptr && + (s_alert_enabled || style == MsgType::Question || style == MsgType::Critical)) + { + return s_msg_handler(caption, message.c_str(), yes_no, style); + } + + return true; +} } // namespace Common diff --git a/Source/Core/Common/MsgHandler.h b/Source/Core/Common/MsgHandler.h index 737640361c..0cf13e0856 100644 --- a/Source/Core/Common/MsgHandler.h +++ b/Source/Core/Common/MsgHandler.h @@ -27,11 +27,22 @@ void RegisterMsgAlertHandler(MsgAlertHandler handler); void RegisterStringTranslator(StringTranslator translator); std::string GetStringT(const char* string); + bool MsgAlert(bool yes_no, MsgType style, const char* format, ...) #ifdef __GNUC__ __attribute__((format(printf, 3, 4))) #endif ; + +bool MsgAlertFmtImpl(bool yes_no, MsgType style, fmt::string_view format, + const fmt::format_args& args); + +template +bool MsgAlertFmt(bool yes_no, MsgType style, fmt::string_view format, const Args&... args) +{ + return MsgAlertFmtImpl(yes_no, style, format, fmt::make_args_checked(format, args...)); +} + void SetEnableAlert(bool enable); // Like fmt::format, except the string becomes translatable @@ -42,6 +53,8 @@ std::string FmtFormatT(const char* string, Args&&... args) } } // namespace Common +// Deprecated variants of the alert macros. See the fmt variants down below. + #define SuccessAlert(format, ...) \ Common::MsgAlert(false, Common::MsgType::Information, format, ##__VA_ARGS__) @@ -72,3 +85,36 @@ std::string FmtFormatT(const char* string, Args&&... args) #define CriticalAlertT(format, ...) \ Common::MsgAlert(false, Common::MsgType::Critical, format, ##__VA_ARGS__) + +// Fmt-capable variants of the macros + +#define SuccessAlertFmt(format, ...) \ + Common::MsgAlertFmt(false, Common::MsgType::Information, FMT_STRING(format), ##__VA_ARGS__) + +#define PanicAlertFmt(format, ...) \ + Common::MsgAlertFmt(false, Common::MsgType::Warning, FMT_STRING(format), ##__VA_ARGS__) + +#define PanicYesNoFmt(format, ...) \ + Common::MsgAlertFmt(true, Common::MsgType::Warning, FMT_STRING(format), ##__VA_ARGS__) + +#define AskYesNoFmt(format, ...) \ + Common::MsgAlertFmt(true, Common::MsgType::Question, FMT_STRING(format), ##__VA_ARGS__) + +#define CriticalAlertFmt(format, ...) \ + Common::MsgAlertFmt(false, Common::MsgType::Critical, FMT_STRING(format), ##__VA_ARGS__) + +// Use these macros (that do the same thing) if the message should be translated. +#define SuccessAlertFmtT(format, ...) \ + Common::MsgAlertFmt(false, Common::MsgType::Information, FMT_STRING(format), ##__VA_ARGS__) + +#define PanicAlertFmtT(format, ...) \ + Common::MsgAlertFmt(false, Common::MsgType::Warning, FMT_STRING(format), ##__VA_ARGS__) + +#define PanicYesNoFmtT(format, ...) \ + Common::MsgAlertFmt(true, Common::MsgType::Warning, FMT_STRING(format), ##__VA_ARGS__) + +#define AskYesNoFmtT(format, ...) \ + Common::MsgAlertFmt(true, Common::MsgType::Question, FMT_STRING(format), ##__VA_ARGS__) + +#define CriticalAlertFmtT(format, ...) \ + Common::MsgAlertFmt(false, Common::MsgType::Critical, FMT_STRING(format), ##__VA_ARGS__)