1 /*
2  * Copyright (C) 2006-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  */
19 
20 #include "wui/mapdata.h"
21 
22 #include "io/filesystem/filesystem.h"
23 
MapData(const std::string & init_filename,const std::string & init_localized_name,const std::string & init_author,const MapData::MapType & init_maptype,const MapData::DisplayType & init_displaytype)24 MapData::MapData(const std::string& init_filename,
25                  const std::string& init_localized_name,
26                  const std::string& init_author,
27                  const MapData::MapType& init_maptype,
28                  const MapData::DisplayType& init_displaytype)
29    : filename(init_filename),
30      name(init_localized_name),
31      localized_name(init_localized_name),
32      authors(init_author),
33      nrplayers(0),
34      width(0),
35      height(0),
36      maptype(init_maptype),
37      displaytype(init_displaytype) {
38 }
39 
MapData(const Widelands::Map & map,const std::string & init_filename,const MapData::MapType & init_maptype,const MapData::DisplayType & init_displaytype)40 MapData::MapData(const Widelands::Map& map,
41                  const std::string& init_filename,
42                  const MapData::MapType& init_maptype,
43                  const MapData::DisplayType& init_displaytype)
44    : MapData(init_filename,
45              _("No Name"),
46              map.get_author().empty() ? _("No Author") : map.get_author(),
47              init_maptype,
48              init_displaytype) {
49 
50 	i18n::Textdomain td("maps");
51 	if (!map.get_name().empty()) {
52 		name = map.get_name();
53 		localized_name = _(name);
54 	}
55 	description = map.get_description().empty() ? "" : _(map.get_description());
56 	hint = map.get_hint().empty() ? "" : _(map.get_hint());
57 	nrplayers = map.get_nrplayers();
58 	width = map.get_width();
59 	height = map.get_height();
60 	suggested_teams = map.get_suggested_teams();
61 	tags = map.get_tags();
62 
63 	if (maptype == MapData::MapType::kScenario) {
64 		tags.insert("scenario");
65 	}
66 }
67 
MapData(const std::string & init_filename,const std::string & init_localized_name)68 MapData::MapData(const std::string& init_filename, const std::string& init_localized_name)
69    : MapData(init_filename,
70              init_localized_name,
71              _("No Author"),
72              MapData::MapType::kDirectory,
73              MapData::DisplayType::kMapnamesLocalized) {
74 }
75 
compare_names(const MapData & other)76 bool MapData::compare_names(const MapData& other) {
77 	// The parent directory gets special treatment.
78 	if (localized_name == parent_name() && maptype == MapData::MapType::kDirectory) {
79 		return true;
80 	} else if (other.localized_name == parent_name() &&
81 	           other.maptype == MapData::MapType::kDirectory) {
82 		return false;
83 	}
84 
85 	std::string this_name;
86 	std::string other_name;
87 	switch (displaytype) {
88 	case MapData::DisplayType::kFilenames:
89 		this_name = filename;
90 		other_name = other.filename;
91 		break;
92 
93 	case MapData::DisplayType::kMapnames:
94 		this_name = name;
95 		other_name = other.name;
96 		break;
97 
98 	case MapData::DisplayType::kMapnamesLocalized:
99 		this_name = localized_name;
100 		other_name = other.localized_name;
101 		break;
102 	}
103 
104 	// If there is no width, we have a directory - we want them first.
105 	if (!width && !other.width) {
106 		return this_name < other_name;
107 	} else if (!width && other.width) {
108 		return true;
109 	} else if (width && !other.width) {
110 		return false;
111 	}
112 	return this_name < other_name;
113 }
114 
compare_players(const MapData & other)115 bool MapData::compare_players(const MapData& other) {
116 	if (nrplayers == other.nrplayers) {
117 		return compare_names(other);
118 	}
119 	return nrplayers < other.nrplayers;
120 }
121 
compare_size(const MapData & other)122 bool MapData::compare_size(const MapData& other) {
123 	if (width == other.width && height == other.height) {
124 		return compare_names(other);
125 	}
126 	if (width != other.width) {
127 		return width < other.width;
128 	}
129 	return height < other.height;
130 }
131 
132 // static
create_parent_dir(const std::string & current_dir)133 MapData MapData::create_parent_dir(const std::string& current_dir) {
134 	std::string filename = FileSystem::fs_dirname(current_dir);
135 	if (!filename.empty()) {
136 		// fs_dirname always returns a directory with a separator at the end.
137 		filename.pop_back();
138 	}
139 	return MapData(filename, parent_name());
140 }
141 
142 // static
parent_name()143 std::string MapData::parent_name() {
144 	/** TRANSLATORS: Parent directory/folder */
145 	return (boost::format("<%s>") % _("parent")).str();
146 }
147 
148 // static
create_empty_dir(const std::string & current_dir)149 MapData MapData::create_empty_dir(const std::string& current_dir) {
150 	/** TRANSLATORS: This label is shown when a folder is empty */
151 	return MapData(current_dir, (boost::format("<%s>") % _("empty")).str());
152 }
153 
154 // static
create_directory(const std::string & directory)155 MapData MapData::create_directory(const std::string& directory) {
156 	std::string localized_name;
157 	if (boost::equals(directory, "maps/MP_Scenarios")) {
158 		/** TRANSLATORS: Directory name for MP Scenarios in map selection */
159 		localized_name = _("Multiplayer Scenarios");
160 	} else if (boost::equals(directory, "maps/My_Maps")) {
161 		/** TRANSLATORS: Directory name for user maps in map selection */
162 		localized_name = _("My Maps");
163 	} else {
164 		localized_name = FileSystem::fs_filename(directory.c_str());
165 	}
166 	return MapData(directory, localized_name);
167 }
168