The Battle for Wesnoth  1.19.0+dev
game_version_dialog.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2024
3  by Iris Morelle <shadowm2006@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
19 
20 #include "build_info.hpp"
21 #include "desktop/clipboard.hpp"
22 #include "desktop/open.hpp"
23 #include "desktop/version.hpp"
24 #include "filesystem.hpp"
25 #include "formula/string_utils.hpp"
28 #include "gui/widgets/button.hpp"
30 #include "gui/widgets/listbox.hpp"
33 #include "gui/widgets/window.hpp"
34 #include "gui/dialogs/message.hpp"
36 #include "gettext.hpp"
37 #include "help/help.hpp"
38 
39 #include <functional>
40 
41 namespace
42 {
43 
44 const std::string text_feature_on = "<span color='#0f0'>&#9679;</span>";
45 const std::string text_feature_off = "<span color='#f00'>&#9679;</span>";
46 
47 } // end anonymous namespace
48 
49 namespace gui2::dialogs
50 {
51 
52 REGISTER_DIALOG(game_version)
53 
54 game_version::game_version(unsigned start_page)
55  : modal_dialog(window_id())
56  , path_wid_stem_("path_")
57  , copy_wid_stem_("copy_")
58  , browse_wid_stem_("browse_")
59  , path_map_()
60  , log_path_(lg::get_log_file_path())
61  , deps_()
63  , report_()
64  , start_page_(start_page)
65 {
66  // NOTE: these path_map_ entries are referenced by the GUI2 WML
67  // definition of this dialog using preprocessor macros.
68  path_map_["datadir"] = game_config::path;
69  path_map_["config"] = filesystem::get_user_config_dir();
70  path_map_["userdata"] = filesystem::get_user_data_dir();
71  path_map_["saves"] = filesystem::get_saves_dir();
72  path_map_["addons"] = filesystem::get_addons_dir();
73  path_map_["cache"] = filesystem::get_cache_dir();
74  // path to logs directory
75  path_map_["logs"] = filesystem::get_logs_dir();
76  path_map_["screenshots"] = filesystem::get_screenshot_dir();
77 
78  for(unsigned k = 0; k < game_config::LIB_COUNT; ++k) {
80 
82  e[0] = game_config::library_name(lib);
83  if(e[0].empty()) {
84  continue;
85  }
88  deps_.push_back(e);
89  }
90 
91  generate_plain_text_report();
92 }
93 
95 {
96  utils::string_map i18n_syms;
97 
98  tab_container& tabs = find_widget<tab_container>(&window, "tabs", false);
99 
100  //
101  // General information.
102  //
103  tabs.select_tab(0);
104 
105  styled_widget& version_label = find_widget<styled_widget>(&window, "version", false);
106  styled_widget& os_label = find_widget<styled_widget>(&window, "os", false);
107  styled_widget& arch_label = find_widget<styled_widget>(&window, "arch", false);
108 
109  version_label.set_label(game_config::revision);
110  os_label.set_label("<i>"+desktop::os_version()+"</i>");
111  arch_label.set_label(game_config::build_arch());
112 
113  button& copy_all = find_widget<button>(&window, "copy_all", false);
115 
116  // Bottom row buttons
117  button& credits_button = find_widget<button>(&window, "credits", false);
118  connect_signal_mouse_left_click(credits_button, std::bind(&game_version::show_credits_dialog, this));
119 
120  button& license_button = find_widget<button>(&window, "license", false);
121  connect_signal_mouse_left_click(license_button, std::bind(&game_version::show_license, this));
122 
123  button& issue_button = find_widget<button>(&window, "issue", false);
124  connect_signal_mouse_left_click(issue_button, std::bind(&game_version::report_issue, this));
125 
126  connect_signal_mouse_left_click(find_widget<button>(&window, "run_migrator", false), std::bind(&game_version::run_migrator, this));
127 
128  //
129  // Game paths tab.
130  //
131  tabs.select_tab(1);
132 
133  for(const auto & path_ent : path_map_)
134  {
135  const std::string& path_id = path_ent.first;
136  const std::string& path_path = filesystem::normalize_path(path_ent.second, true);
137 
138  text_box_base& path_w = find_widget<text_box_base>(&window, path_wid_stem_ + path_id, false);
139  button& copy_w = find_widget<button>(&window, copy_wid_stem_ + path_id, false);
140  button& browse_w = find_widget<button>(&window, browse_wid_stem_ + path_id, false);
141 
142  path_w.set_value(path_path);
143 
145  copy_w,
146  std::bind(&game_version::copy_to_clipboard_callback, this, path_path, copy_wid_stem_ + path_id));
148  browse_w,
149  std::bind(&game_version::browse_directory_callback, this, path_path));
150 
152  // No point in displaying these on platforms that can't do
153  // open_object().
155  }
156 
158  copy_w.set_active(false);
159  copy_w.set_tooltip(_("Clipboard support not found, contact your packager"));
160  }
161  }
162 
163  button& stderr_button = find_widget<button>(&window, "open_stderr", false);
165  stderr_button.set_active(!log_path_.empty() && filesystem::file_exists(log_path_));
166 
167  //
168  // Build info tab.
169  //
170  tabs.select_tab(2);
171 
172  widget_data list_data;
173 
174  listbox& deps_listbox
175  = find_widget<listbox>(&window, "deps_listbox", false);
176 
177  for(const auto & dep : deps_)
178  {
179  list_data["dep_name"]["label"] = dep[0];
180 
181  list_data["dep_build_version"]["label"] = dep[1];
182 
183  // The build version is always known, but runtime version isn't, esp.
184  // for header-only libraries like Boost for which the concept does not
185  // apply.
186  if(!dep[2].empty()) {
187  list_data["dep_rt_version"]["label"] = dep[2];
188  } else {
189  list_data["dep_rt_version"]["label"] = font::unicode_em_dash;
190  }
191 
192  deps_listbox.add_row(list_data);
193  }
194 
195  deps_listbox.select_row(0);
196  list_data.clear();
197 
198  //
199  // Features tab.
200  //
201  tabs.select_tab(3);
202 
203  listbox& opts_listbox
204  = find_widget<listbox>(&window, "opts_listbox", false);
205 
206  for(const auto & opt : opts_)
207  {
208  list_data["opt_name"]["label"] = opt.name;
209 
210  if(opt.enabled) {
211  list_data["opt_status"]["label"] = text_feature_on;
212  } else {
213  list_data["opt_status"]["label"] = text_feature_off;
214  }
215  list_data["opt_status"]["use_markup"] = "true";
216 
217  opts_listbox.add_row(list_data);
218  }
219 
220  opts_listbox.select_row(0);
221  list_data.clear();
222 
223  //
224  // Community tab
225  //
226  tabs.select_tab(4);
227 
228  connect_signal_mouse_left_click(find_widget<button>(&window, "forums", false), std::bind(&desktop::open_object, "https://forums.wesnoth.org/"));
229  connect_signal_mouse_left_click(find_widget<button>(&window, "discord", false), std::bind(&desktop::open_object, "https://discord.gg/battleforwesnoth"));
230  connect_signal_mouse_left_click(find_widget<button>(&window, "irc", false), std::bind(&desktop::open_object, "https://web.libera.chat/#wesnoth"));
231  connect_signal_mouse_left_click(find_widget<button>(&window, "steam", false), std::bind(&desktop::open_object, "https://steamcommunity.com/app/599390/discussions/"));
232  connect_signal_mouse_left_click(find_widget<button>(&window, "reddit", false), std::bind(&desktop::open_object, "https://www.reddit.com/r/wesnoth/"));
233  connect_signal_mouse_left_click(find_widget<button>(&window, "donate", false), std::bind(&desktop::open_object, "https://www.spi-inc.org/projects/wesnoth/"));
234 
235  //
236  // Set-up page stack and auxiliary controls last.
237  //
238 
239  tabs.select_tab(start_page_);
240 }
241 
243 {
245 }
246 
248 {
250 }
251 
252 void game_version::copy_to_clipboard_callback(const std::string& path, const std::string btn_id)
253 {
255 
256  button& copy_w = find_widget<button>(get_window(), btn_id, false);
257  copy_w.set_success(true);
258 }
259 
261 {
263 
264  button& copy_all = find_widget<button>(get_window(), "copy_all", false);
265  copy_all.set_success(true);
266 }
267 
269 {
271 }
272 
274  gui2::dialogs::end_credits::display();
275 }
276 
278  help::show_help("license");
279 }
280 
283  show_message("", _("Opening links is not supported, contact your packager"), dialogs::message::auto_close);
284  return;
285  } else {
286  desktop::open_object("https://bugs.wesnoth.org");
287  }
288 }
289 
290 } // namespace dialogs
Simple push button.
Definition: button.hpp:36
virtual void set_active(const bool active) override
See styled_widget::set_active.
Definition: button.cpp:64
void set_success(bool success)
Definition: button.cpp:89
const std::string path_wid_stem_
The display function.
void report_issue()
Open browser to report issue.
std::array< std::string, 4 > deplist_entry
void report_copy_callback()
Callback function for the dialog-wide copy-to-clipboard button.
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
void copy_to_clipboard_callback(const std::string &path, const std::string btn_id)
Callback function for copy-to-clipboard action buttons.
std::map< std::string, std::string > path_map_
const std::string log_path_
path to current log file
void run_migrator()
Callback function to re-run the version migration dialog.
void show_credits_dialog()
Show credits dialogs.
std::vector< deplist_entry > deps_
void browse_directory_callback(const std::string &path)
Callback function for browse-directory action buttons.
std::vector< game_config::optional_feature > opts_
@ auto_close
Enables auto close.
Definition: message.hpp:71
Abstract base class for all modal dialogs.
window * get_window()
Returns a pointer to the dialog's window.
The listbox class.
Definition: listbox.hpp:43
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
Definition: listbox.cpp:59
bool select_row(const unsigned row, const bool select=true)
Selects a row.
Definition: listbox.cpp:243
void set_tooltip(const t_string &tooltip)
virtual void set_label(const t_string &text)
A container widget that shows one of its pages of widgets depending on which tab the user clicked.
void select_tab(unsigned index)
Abstract base class for text items.
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
void set_visible(const visibility visible)
Definition: widget.cpp:469
@ invisible
The user set the widget invisible, that means:
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:61
Platform identification and version information functions.
Declarations for File-IO.
static std::string _(const char *str)
Definition: gettext.hpp:93
This file contains the window object, this object is a top level container which has the event manage...
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:32
bool available()
Whether wesnoth was compiled with support for a clipboard.
Definition: clipboard.cpp:53
bool open_object([[maybe_unused]] const std::string &path_or_url)
Definition: open.cpp:46
constexpr bool open_object_is_supported()
Returns whether open_object() is supported/implemented for the current platform.
Definition: open.hpp:54
std::string os_version()
Returns a string with the running OS name and version information.
Definition: version.cpp:216
std::string get_cache_dir()
Definition: filesystem.cpp:931
std::string get_user_config_dir()
Definition: filesystem.cpp:912
std::string get_user_data_dir()
Definition: filesystem.cpp:921
static bool file_exists(const bfs::path &fpath)
Definition: filesystem.cpp:319
std::string get_saves_dir()
std::string get_screenshot_dir()
std::string get_logs_dir()
Definition: filesystem.cpp:926
std::string get_addons_dir()
std::string normalize_path(const std::string &fpath, bool normalize_separators, bool resolve_dot_entries)
Returns the absolute path of a file.
const std::string unicode_em_dash
Definition: constants.cpp:44
Game configuration data as global variables.
Definition: build_info.cpp:61
const std::string & library_name(LIBRARY_ID lib)
Retrieve the user-visible name for the given library.
Definition: build_info.cpp:387
std::string path
Definition: filesystem.cpp:84
std::string full_build_report()
Produce a bug report-style info dump.
Definition: build_info.cpp:665
std::vector< optional_feature > optional_features_table(bool localize)
Retrieve the features table.
Definition: build_info.cpp:350
const std::string & library_runtime_version(LIBRARY_ID lib)
Retrieve the runtime version number of the given library.
Definition: build_info.cpp:378
const std::string & library_build_version(LIBRARY_ID lib)
Retrieve the build-time version number of the given library.
Definition: build_info.cpp:369
std::string build_arch()
Obtain the processor architecture for this build.
Definition: build_info.cpp:316
const std::string revision
REGISTER_DIALOG(editor_edit_unit)
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:177
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:34
void 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)
Shows a message to the user.
Definition: message.cpp:150
void show_help(const std::string &show_topic, int xloc, int yloc)
Open the help browser, show topic with id show_topic.
Definition: help.cpp:140
Definition: pump.hpp:41
std::string get_log_file_path()
Definition: log.cpp:280
std::map< std::string, t_string > string_map
Desktop environment interaction functions.
#define e