1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
// Copyright 2009 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <cstdint>
#include <string>
#include <utility>
#include <fmt/format.h>
#include "Common/FormatUtil.h"
namespace Common
{
// Message alerts
enum class MsgType
{
Information,
Question,
Warning,
Critical
};
using MsgAlertHandler = bool (*)(const char* caption, const char* text, bool yes_no, MsgType style);
using StringTranslator = std::string (*)(const char* text);
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 <std::size_t NumFields, typename S, typename... Args>
bool MsgAlertFmt(bool yes_no, MsgType style, const S& format, const Args&... args)
{
static_assert(NumFields == sizeof...(args),
"Unexpected number of replacement fields in format string; did you pass too few or "
"too many arguments?");
return MsgAlertFmtImpl(yes_no, style, format, fmt::make_args_checked<Args...>(format, args...));
}
void SetEnableAlert(bool enable);
// Like fmt::format, except the string becomes translatable
template <typename... Args>
std::string FmtFormatT(const char* string, Args&&... args)
{
return fmt::format(Common::GetStringT(string), std::forward<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__)
#define PanicAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define PanicYesNo(format, ...) \
Common::MsgAlert(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define AskYesNo(format, ...) \
Common::MsgAlert(true, Common::MsgType::Question, format, ##__VA_ARGS__)
#define CriticalAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
// Use these macros (that do the same thing) if the message should be translated.
#define SuccessAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Information, format, ##__VA_ARGS__)
#define PanicAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define PanicYesNoT(format, ...) \
Common::MsgAlert(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define AskYesNoT(format, ...) \
Common::MsgAlert(true, Common::MsgType::Question, format, ##__VA_ARGS__)
#define CriticalAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
// Fmt-capable variants of the macros
#define GenericAlertFmt(yes_no, style, format, ...) \
[&] { \
/* Use a macro-like name to avoid shadowing warnings */ \
constexpr auto GENERIC_ALERT_FMT_N = Common::CountFmtReplacementFields(format); \
return Common::MsgAlertFmt<GENERIC_ALERT_FMT_N>(yes_no, style, FMT_STRING(format), \
##__VA_ARGS__); \
}()
#define GenericAlertFmtT(yes_no, style, format, ...) \
[&] { \
static_assert(!Common::ContainsNonPositionalArguments(format), \
"Translatable strings must use positional arguments (e.g. {0} instead of {})"); \
/* Use a macro-like name to avoid shadowing warnings */ \
constexpr auto GENERIC_ALERT_FMT_N = Common::CountFmtReplacementFields(format); \
return Common::MsgAlertFmt<GENERIC_ALERT_FMT_N>(yes_no, style, FMT_STRING(format), \
##__VA_ARGS__); \
}()
#define SuccessAlertFmt(format, ...) \
GenericAlertFmt(false, Common::MsgType::Information, format, ##__VA_ARGS__)
#define PanicAlertFmt(format, ...) \
GenericAlertFmt(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define PanicYesNoFmt(format, ...) \
GenericAlertFmt(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define AskYesNoFmt(format, ...) \
GenericAlertFmt(true, Common::MsgType::Question, format, ##__VA_ARGS__)
#define CriticalAlertFmt(format, ...) \
GenericAlertFmt(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
// Use these macros (that do the same thing) if the message should be translated.
#define SuccessAlertFmtT(format, ...) \
GenericAlertFmtT(false, Common::MsgType::Information, format, ##__VA_ARGS__)
#define PanicAlertFmtT(format, ...) \
GenericAlertFmtT(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define PanicYesNoFmtT(format, ...) \
GenericAlertFmtT(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
#define AskYesNoFmtT(format, ...) \
GenericAlertFmtT(true, Common::MsgType::Question, format, ##__VA_ARGS__)
#define CriticalAlertFmtT(format, ...) \
GenericAlertFmtT(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
|