The Battle for Wesnoth  1.17.4+dev
about.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2022
3  by David White <dave@whitevine.net>
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 #include "about.hpp"
17 
18 #include "config.hpp"
19 #include "font/pango/escape.hpp"
20 #include "game_config_view.hpp"
21 #include "gettext.hpp"
23 
24 #include <map>
25 
26 /**
27  * @namespace about
28  * Display credits %about all contributors.
29  */
30 namespace about
31 {
32 namespace
33 {
34 
35 credits_data parsed_credits_data;
36 std::map<std::string, std::vector<std::string>> images_campaigns;
37 std::vector<std::string> images_general;
38 
39 void gather_images(const config& from, std::vector<std::string>& to)
40 {
41  const auto& im = utils::parenthetical_split(from["images"], ',');
42  to.insert(to.end(), im.begin(), im.end());
43 }
44 
45 } // namespace
46 
47 credits_group::credits_group(const config& cfg, bool is_campaign_credits)
48  : sections()
49  , id()
50  , header()
51 {
52  if(is_campaign_credits) {
53  id = cfg["id"].str();
54  header = cfg["name"].t_str();
55  }
56 
57  sections.reserve(cfg.child_count("about"));
58 
59  for(const config& about : cfg.child_range("about")) {
60  if(!about.has_child("entry")) {
61  continue;
62  }
63 
64  sections.emplace_back(about);
65 
66  if(is_campaign_credits) {
67  gather_images(about, images_campaigns[id]);
68  } else {
69  gather_images(about, images_general);
70  }
71  }
72 
73  if(cfg["sort"].to_bool(false)) {
74  std::sort(sections.begin(), sections.end());
75  }
76 }
77 
79  : names()
80  , title(cfg["title"].t_str())
81 {
82  names.reserve(cfg.child_count("entry"));
83 
84  for(const config& entry : cfg.child_range("entry")) {
85  names.emplace_back(font::escape_text(entry["name"].str()), font::escape_text(entry["comment"].str()));
86  }
87 }
88 
90 {
91  return translation::compare(title.str(), o.title.str()) < 0;
92 }
93 
95 {
96  return parsed_credits_data;
97 }
98 
99 std::optional<credits_data::const_iterator> get_campaign_credits(const std::string& campaign)
100 {
101  const auto res = std::find_if(parsed_credits_data.begin(), parsed_credits_data.end(),
102  [&campaign](const credits_group& group) { return group.id == campaign; });
103  return res != parsed_credits_data.end() ? std::make_optional(res) : std::nullopt;
104 }
105 
106 std::vector<std::string> get_background_images(const std::string& campaign)
107 {
108  if(campaign.empty()) {
109  return images_general;
110  }
111 
112  if(const auto it = images_campaigns.find(campaign); it != images_campaigns.cend()) {
113  return it->second;
114  }
115 
116  return images_general;
117 }
118 
119 void set_about(const game_config_view& cfg)
120 {
121  parsed_credits_data.clear();
122 
123  // TODO: should we reserve space in parsed_credits_data here?
124 
125  images_campaigns.clear();
126  images_general.clear();
127 
128  //
129  // Parse all [credits_group] tags
130  //
131  for(const config& group : cfg.child_range("credits_group")) {
132  if(group.has_child("about")) {
133  parsed_credits_data.emplace_back(group, false);
134 
135  // Not in the credits_group since we don't want to inadvertently
136  // pick up images from campaigns.
137  gather_images(group, images_general);
138  }
139  }
140 
141  //
142  // Parse all toplevel [about] tags.
143  //
144  config misc;
145  for(const config& about : cfg.child_range("about")) {
146  misc.add_child("about", about);
147  }
148 
149  if(!misc.empty()) {
150  parsed_credits_data.emplace_back(misc, false);
151  }
152 
153  //
154  // Parse all campaign [about] tags.
155  //
156  for(const config& campaign : cfg.child_range("campaign")) {
157  if(campaign.has_child("about")) {
158  parsed_credits_data.emplace_back(campaign, true);
159  }
160  }
161 }
162 
163 } // end namespace about
t_string title
The section title.
Definition: about.hpp:40
config_array_view child_range(config_key_type key) const
int compare(const std::string &s1, const std::string &s2)
Case-sensitive lexicographical comparison.
Definition: gettext.cpp:498
unsigned child_count(config_key_type key) const
Definition: config.cpp:372
const credits_data & get_credits_data()
Gets all credits data.
Definition: about.cpp:94
child_itors child_range(config_key_type key)
Definition: config.cpp:344
Definitions for the interface to Wesnoth Markup Language (WML).
std::vector< about_group > sections
The group&#39;s sub-groups.
Definition: about.hpp:48
std::vector< std::string > get_background_images(const std::string &campaign)
Gets credit background images for a given campaign.
Definition: about.cpp:106
Display credits about all contributors.
std::vector< credits_group > credits_data
Definition: about.hpp:57
std::vector< std::pair< std::string, std::string > > names
Contributor names.
Definition: about.hpp:37
void set_about(const game_config_view &cfg)
Regenerates the credits data.
Definition: about.cpp:119
credits_group(const config &cfg, bool is_campaign_credits)
Definition: about.cpp:47
about_group(const config &cfg)
Definition: about.cpp:78
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:215
std::string escape_text(const std::string &text)
Escapes the pango markup characters in a text.
Definition: escape.hpp:33
bool operator<(const about_group &o) const
Definition: about.cpp:89
std::vector< std::string > names
Definition: build_info.cpp:67
config & add_child(config_key_type key)
Definition: config.cpp:514
std::optional< credits_data::const_iterator > get_campaign_credits(const std::string &campaign)
Gets credits for a given campaign.
Definition: about.cpp:99
t_string header
Optional group title.
Definition: about.hpp:54
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:60
const std::string & str() const
Definition: tstring.hpp:191
bool empty() const
Definition: config.cpp:941
std::vector< std::string > parenthetical_split(const std::string &val, const char separator, const std::string &left, const std::string &right, const int flags)
Splits a string based either on a separator, except then the text appears within specified parenthesi...