1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4
5 #include "Common/MsgHandler.h"
6
7 #include <cstdarg>
8 #include <string>
9
10 #ifdef _WIN32
11 #include <windows.h>
12 #else
13 #include <cstdio>
14 #include <fmt/format.h>
15 #endif
16
17 #include "Common/Common.h"
18 #include "Common/CommonTypes.h"
19 #include "Common/Logging/Log.h"
20 #include "Common/StringUtil.h"
21
22 namespace Common
23 {
24 namespace
25 {
26 // Default non library dependent panic alert
DefaultMsgHandler(const char * caption,const char * text,bool yes_no,MsgType style)27 bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, MsgType style)
28 {
29 #ifdef _WIN32
30 int window_style = MB_ICONINFORMATION;
31 if (style == MsgType::Question)
32 window_style = MB_ICONQUESTION;
33 if (style == MsgType::Warning)
34 window_style = MB_ICONWARNING;
35
36 return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(),
37 window_style | (yes_no ? MB_YESNO : MB_OK));
38 #else
39 fmt::print(stderr, "{}\n", text);
40
41 // Return no to any question (which will in general crash the emulator)
42 return false;
43 #endif
44 }
45
46 // Default (non) translator
DefaultStringTranslator(const char * text)47 std::string DefaultStringTranslator(const char* text)
48 {
49 return text;
50 }
51
52 MsgAlertHandler s_msg_handler = DefaultMsgHandler;
53 StringTranslator s_str_translator = DefaultStringTranslator;
54 bool s_alert_enabled = true;
55 } // Anonymous namespace
56
57 // Select which of these functions that are used for message boxes. If
58 // Qt is enabled we will use QtMsgAlertHandler() that is defined in Main.cpp
RegisterMsgAlertHandler(MsgAlertHandler handler)59 void RegisterMsgAlertHandler(MsgAlertHandler handler)
60 {
61 s_msg_handler = handler;
62 }
63
64 // Select translation function.
RegisterStringTranslator(StringTranslator translator)65 void RegisterStringTranslator(StringTranslator translator)
66 {
67 s_str_translator = translator;
68 }
69
70 // enable/disable the alert handler
SetEnableAlert(bool enable)71 void SetEnableAlert(bool enable)
72 {
73 s_alert_enabled = enable;
74 }
75
GetStringT(const char * string)76 std::string GetStringT(const char* string)
77 {
78 return s_str_translator(string);
79 }
80
81 // This is the first stop for gui alerts where the log is updated and the
82 // correct window is shown
MsgAlert(bool yes_no,MsgType style,const char * format,...)83 bool MsgAlert(bool yes_no, MsgType style, const char* format, ...)
84 {
85 // Read message and write it to the log
86 const char* caption = "";
87 char buffer[2048];
88
89 static const std::string info_caption = s_str_translator(_trans("Information"));
90 static const std::string warn_caption = s_str_translator(_trans("Question"));
91 static const std::string ques_caption = s_str_translator(_trans("Warning"));
92 static const std::string crit_caption = s_str_translator(_trans("Critical"));
93
94 switch (style)
95 {
96 case MsgType::Information:
97 caption = info_caption.c_str();
98 break;
99 case MsgType::Question:
100 caption = ques_caption.c_str();
101 break;
102 case MsgType::Warning:
103 caption = warn_caption.c_str();
104 break;
105 case MsgType::Critical:
106 caption = crit_caption.c_str();
107 break;
108 }
109
110 va_list args;
111 va_start(args, format);
112 CharArrayFromFormatV(buffer, sizeof(buffer) - 1, s_str_translator(format).c_str(), args);
113 va_end(args);
114
115 ERROR_LOG(MASTER_LOG, "%s: %s", caption, buffer);
116
117 // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
118 if (s_msg_handler != nullptr &&
119 (s_alert_enabled || style == MsgType::Question || style == MsgType::Critical))
120 {
121 return s_msg_handler(caption, buffer, yes_no, style);
122 }
123
124 return true;
125 }
126 } // namespace Common
127