1 /*
2 Copyright (C) 2008 - 2018 by Mark de Wever <koraq@xs4all.nl>
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13 */
14
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16
17 #include "gui/dialogs/message.hpp"
18
19 #include "gettext.hpp"
20 #include "gui/auxiliary/find_widget.hpp"
21 #include "gui/widgets/button.hpp"
22 #include "gui/widgets/image.hpp"
23 #include "gui/widgets/label.hpp"
24 #include "gui/widgets/settings.hpp"
25 #include "gui/widgets/window.hpp"
26 #include "log.hpp"
27
28 namespace gui2
29 {
30 namespace dialogs
31 {
32
33 REGISTER_DIALOG(message)
34
35 /**
36 * Helper to implement private functions without modifying the header.
37 *
38 * The class is a helper to avoid recompilation and only has static
39 * functions.
40 */
41 struct message_implementation
42 {
43 /**
44 * Initialiazes a button.
45 *
46 * @param window The window that contains the button.
47 * @param button_status The button status to modify.
48 * @param id The id of the button.
49 */
init_buttongui2::dialogs::message_implementation50 static void init_button(window& window,
51 message::button_status& button_status,
52 const std::string& id)
53 {
54 button_status.ptr = find_widget<button>(&window, id, false, true);
55 button_status.ptr->set_visible(button_status.visible);
56
57 if(!button_status.caption.empty()) {
58 button_status.ptr->set_label(button_status.caption);
59 }
60
61 if(button_status.retval != retval::NONE) {
62 button_status.ptr->set_retval(button_status.retval);
63 }
64 }
65 };
66
pre_show(window & window)67 void message::pre_show(window& window)
68 {
69 set_restore(true);
70
71 // ***** Validate the required buttons ***** ***** ***** *****
72 message_implementation::init_button(window, buttons_[left_1], "left_side");
73 message_implementation::init_button(window, buttons_[cancel], "cancel");
74 message_implementation::init_button(window, buttons_[ok], "ok");
75 message_implementation::init_button(
76 window, buttons_[right_1], "right_side");
77
78 // ***** ***** ***** ***** Set up the widgets ***** ***** ***** *****
79 styled_widget& title_widget = find_widget<label>(&window, "title", false);
80 if(!title_.empty()) {
81 title_widget.set_label(title_);
82 title_widget.set_use_markup(title_use_markup_);
83 } else {
84 title_widget.set_visible(widget::visibility::invisible);
85 }
86
87 styled_widget& img_widget = find_widget<image>(&window, "image", false);
88 if(!image_.empty()) {
89 img_widget.set_label(image_);
90 } else {
91 img_widget.set_visible(widget::visibility::invisible);
92 }
93
94 styled_widget& label = find_widget<styled_widget>(&window, "label", false);
95 label.set_label(message_);
96 label.set_use_markup(message_use_markup_);
97
98 // The label might not always be a scroll_label but the capturing
99 // shouldn't hurt.
100 window.keyboard_capture(&label);
101
102 // Override the user value, to make sure it's set properly.
103 window.set_click_dismiss(auto_close_);
104 }
105
post_show(window &)106 void message::post_show(window& /*window*/)
107 {
108 for(auto & button_status : buttons_)
109 {
110 button_status.ptr = nullptr;
111 }
112 }
113
set_button_caption(const button_id button,const std::string & caption)114 void message::set_button_caption(const button_id button,
115 const std::string& caption)
116 {
117 buttons_[button].caption = caption;
118 if(buttons_[button].ptr) {
119 buttons_[button].ptr->set_label(caption);
120 }
121 }
122
set_button_visible(const button_id button,const widget::visibility visible)123 void message::set_button_visible(const button_id button,
124 const widget::visibility visible)
125 {
126 buttons_[button].visible = visible;
127 if(buttons_[button].ptr) {
128 buttons_[button].ptr->set_visible(visible);
129 }
130 }
131
set_button_retval(const button_id button,const int retval)132 void message::set_button_retval(const button_id button, const int retval)
133 {
134 buttons_[button].retval = retval;
135 if(buttons_[button].ptr) {
136 buttons_[button].ptr->set_retval(retval);
137 }
138 }
139
button_status()140 message::button_status::button_status()
141 : ptr(nullptr)
142 , caption()
143 , visible(widget::visibility::invisible)
144 , retval(gui2::retval::NONE) // Needs explicit namespace qualifier to avoid name clashes.
145 {
146 }
147
148 } // namespace dialogs
149
150 using namespace dialogs;
151
show_message(const std::string & title,const std::string & msg,const std::string & button_caption,const bool auto_close,const bool message_use_markup,const bool title_use_markup)152 void show_message(const std::string& title,
153 const std::string& msg,
154 const std::string& button_caption,
155 const bool auto_close,
156 const bool message_use_markup,
157 const bool title_use_markup)
158 {
159 message dlg(title, msg, auto_close, message_use_markup, title_use_markup);
160 dlg.set_button_caption(message::ok, button_caption);
161 dlg.show();
162 }
163
show_message(const std::string & title,const std::string & msg,const message::button_style button_style,bool message_use_markup,bool title_use_markup)164 int show_message(const std::string& title,
165 const std::string& msg,
166 const message::button_style button_style,
167 bool message_use_markup,
168 bool title_use_markup)
169 {
170 message dlg(title,
171 msg,
172 button_style == message::auto_close,
173 message_use_markup,
174 title_use_markup);
175
176 switch(button_style) {
177 case message::auto_close:
178 break;
179 case message::ok_button:
180 dlg.set_button_visible(message::ok, widget::visibility::visible);
181 dlg.set_button_caption(message::ok, _("OK"));
182 break;
183 case message::close_button:
184 dlg.set_button_visible(message::ok, widget::visibility::visible);
185 break;
186 case message::ok_cancel_buttons:
187 dlg.set_button_visible(message::ok, widget::visibility::visible);
188 dlg.set_button_caption(message::ok, _("OK"));
189 FALLTHROUGH;
190 case message::cancel_button:
191 dlg.set_button_visible(message::cancel, widget::visibility::visible);
192 break;
193 case message::yes_no_buttons:
194 dlg.set_button_visible(message::ok, widget::visibility::visible);
195 dlg.set_button_caption(message::ok, _("Yes"));
196 dlg.set_button_visible(message::cancel, widget::visibility::visible);
197 dlg.set_button_caption(message::cancel, _("No"));
198 break;
199 }
200
201 dlg.show();
202 return dlg.get_retval();
203 }
204
show_error_message(const std::string & msg,bool message_use_markup)205 void show_error_message(const std::string& msg,
206 bool message_use_markup)
207 {
208 LOG_STREAM(err, lg::general()) << msg << '\n';
209 (void) show_message(
210 _("Error"),
211 msg,
212 message::ok_button,
213 message_use_markup);
214 }
215 } // namespace gui2
216