The Battle for Wesnoth  1.19.25+dev
language_selection.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2025
3  by Mark de Wever <koraq@xs4all.nl>
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 "gui/widgets/listbox.hpp"
22 #include "gui/widgets/window.hpp"
23 #include "game_config.hpp"
24 #include "gettext.hpp"
25 #include "language.hpp"
27 #include "serialization/markup.hpp"
28 
29 namespace gui2::dialogs
30 {
31 
32 namespace
33 {
34 
35 const std::string translations_wiki_url = "https://wiki.wesnoth.org/WesnothTranslations";
36 
37 const std::string translations_stats_url = "https://gettext.wesnoth.org/";
38 
39 }
40 
41 REGISTER_DIALOG(language_selection)
42 
44  : modal_dialog(window_id())
45  , langs_(get_languages(true))
46  , complete_langs_(langs_.size())
47 {
48  bool show_all = get_min_translation_percent() == 0;
49 
50  const language_def& current_language = get_language();
51 
52  // Build language list and completion filter
53  for(std::size_t i = 0; i < langs_.size(); ++i) {
54  if(langs_[i] == current_language) {
55  // Always show the initial language regardless of completion. If it's under
56  // threshold then it probably means we should start by showing all languages
57  // too, regardless of what the initial threshold setting is.
58  complete_langs_[i] = true;
59  if(langs_[i].percent < get_min_translation_percent()) {
60  show_all = true;
61  }
62  } else {
63  complete_langs_[i] = langs_[i].percent >= get_min_translation_percent();
64  }
65  }
66 
67  register_bool("show_all", true, show_all);
68  // Markup needs to be enabled for the link to be highlighted
69  register_label("contrib_url", true, translations_wiki_url, true);
70  register_label("stats_url", true, translations_stats_url, true);
71 }
72 
74 {
75  toggle_button& show_all_toggle = find_widget<toggle_button>("show_all");
76  listbox& list = find_widget<listbox>("language_list");
77 
78  if(show_all_toggle.get_value_bool()) {
79  boost::dynamic_bitset<> mask;
80  mask.resize(langs_.size(), true);
81  list.set_row_shown(mask);
82  } else {
84  }
85 }
86 
88 {
89  listbox& list = find_widget<listbox>("language_list");
90  keyboard_capture(&list);
91 
92  toggle_button& show_all_toggle = find_widget<toggle_button>("show_all");
93  connect_signal_mouse_left_click(show_all_toggle, std::bind(
95 
96  // Disable show all languages toggle when --all-translations or --translations-over 0
97  // command line options are used, since in these cases there is no difference in the
98  // languages shown between toggles, making it redundant.
99  if(get_min_translation_percent() <= 0) {
100  show_all_toggle.set_active(false);
101  }
102 
103  const language_def& current_language = get_language();
104 
105  for(const auto& lang : langs_) {
106  std::string lang_label = game_config::debug && !lang.localename.empty()
107  ? lang.language + "\n" + markup::tag("small", markup::tag("tt", lang.localename))
108  : lang.language;
109 
110  list.add_row(widget_data{
111  { "language", {
112  { "label", std::move(lang_label) },
113  { "use_markup", "true" }
114  }},
115  { "translated_total", {
116  { "label", markup::span_color(game_config::red_to_green(lang.percent), lang.percent, "%") },
117  { "use_markup", "true" }
118  }},
119  });
120 
121  if(lang == current_language) {
122  list.select_last_row();
123  }
124  }
125 
126  // The view filter needs to be set after building the list to take the Show
127  // All toggle value + language completion stats into account as needed.
129 }
130 
132 {
133  if(get_retval() == retval::OK) {
134  const int res = find_widget<listbox>("language_list")
135  .get_selected_row();
136 
137  assert(res != -1);
138 
139  ::set_language(langs_[res]);
140  prefs::get().set_locale(langs_[res].localename);
141  }
142 }
143 
144 } // namespace dialogs
virtual void post_show() override
Actions to be taken after the window has been shown.
virtual void pre_show() override
Actions to be taken before showing the window.
const std::vector< language_def > langs_
Abstract base class for all modal dialogs.
The listbox class.
Definition: listbox.hpp:41
bool select_last_row(const bool select=true)
Does exactly as advertised: selects the list's last row.
Definition: listbox.hpp:186
void set_row_shown(const unsigned row, const bool shown)
Makes a row visible or invisible.
Definition: listbox.cpp:163
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:92
virtual void set_active(const bool active) override
See styled_widget::set_active.
void keyboard_capture(widget *widget)
Definition: window.cpp:1197
int get_retval()
Definition: window.hpp:394
static prefs & get()
std::size_t i
Definition: function.cpp:1031
This file contains the window object, this object is a top level container which has the event manage...
std::vector< language_def > get_languages(bool all)
Return a list of available translations.
Definition: language.cpp:162
int get_min_translation_percent()
Definition: language.cpp:187
const language_def & get_language()
Definition: language.cpp:311
const bool & debug
Definition: game_config.cpp:96
color_t red_to_green(double val, bool for_text)
Return a color corresponding to the value val red for val=0.0 to green for val=100....
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:163
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:36
@ OK
Dialog was closed with the OK button.
Definition: retval.hpp:35
std::string span_color(const color_t &color, Args &&... data)
Applies Pango markup to the input specifying its display color.
Definition: markup.hpp:110
std::string tag(std::string_view tag, Args &&... data)
Wraps the given data in the specified tag.
Definition: markup.hpp:45
void set_language(const std::string &language, const std::vector< std::string > *)
Definition: gettext.cpp:494
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:81