Refactor language codes out of Language class

So that the C++ API won't need to include the whole Language class
amongst its headers.
This commit is contained in:
Oliver Hamlet
2016-08-24 07:48:38 +01:00
parent 6911c7edc2
commit c29b5b7d50
27 changed files with 213 additions and 179 deletions
+1
View File
@@ -208,6 +208,7 @@ set (LOOT_HEADERS "${CMAKE_SOURCE_DIR}/src/backend/app/loot_paths.h"
"${CMAKE_SOURCE_DIR}/src/backend/helpers/yaml_set_helpers.h"
"${CMAKE_SOURCE_DIR}/src/backend/error.h"
"${CMAKE_SOURCE_DIR}/include/loot/game_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/language_code.h"
"${CMAKE_SOURCE_DIR}/include/loot/message_type.h")
set (LOOT_GUI_SRC "${CMAKE_SOURCE_DIR}/src/gui/main.cpp"
+44
View File
@@ -0,0 +1,44 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_LANGUAGE_CODE
#define LOOT_LANGUAGE_CODE
namespace loot {
enum struct LanguageCode : unsigned int {
english = 1,
spanish = 2,
russian = 3,
french = 4,
chinese = 5,
polish = 6,
brazilian_portuguese = 7,
finnish = 8,
german = 9,
danish = 10,
korean = 11
};
}
#endif
+2 -1
View File
@@ -29,6 +29,7 @@
#include <boost/filesystem/fstream.hpp>
#include "backend/app/loot_version.h"
#include "loot/loot_version.h"
using std::lock_guard;
using std::recursive_mutex;
@@ -58,7 +59,7 @@ LootSettings::LootSettings() :
enableDebugLogging_(false),
updateMasterlist_(true),
game_("auto"),
language_(Language(Language::Code::english)),
language_(Language(LanguageCode::english)),
lastGame_("auto") {}
void LootSettings::load(YAML::Node& settings) {
+2 -2
View File
@@ -112,7 +112,7 @@ void LootState::init(const std::string& cmdLineGame) {
gen.add_messages_domain("loot");
//Boost.Locale initialisation: Generate and imbue locales.
locale::global(gen(Language(Language::Code::english).GetLocale() + ".UTF-8"));
locale::global(gen(Language(LanguageCode::english).GetLocale() + ".UTF-8"));
boost::filesystem::path::imbue(locale());
// Check if the LOOT local app data folder exists, and create it if not.
@@ -162,7 +162,7 @@ void LootState::init(const std::string& cmdLineGame) {
fs::remove(LootPaths::getLootDataPath() / "CEFDebugLog.txt");
// Now that settings have been loaded, set the locale again to handle translations.
if (getLanguage().GetCode() != Language::Code::english) {
if (getLanguage().GetCode() != LanguageCode::english) {
BOOST_LOG_TRIVIAL(debug) << "Initialising language settings.";
Language lang(getLanguage());
BOOST_LOG_TRIVIAL(debug) << "Selected language: " << lang.GetName();
+28 -28
View File
@@ -25,75 +25,75 @@
#include "backend/helpers/language.h"
namespace loot {
const std::vector<Language::Code> Language::codes({
Code::english,
Code::spanish,
Code::russian,
Code::french,
Code::chinese,
Code::polish,
Code::brazilian_portuguese,
Code::finnish,
Code::german,
Code::danish,
Code::korean
const std::vector<LanguageCode> Language::codes({
LanguageCode::english,
LanguageCode::spanish,
LanguageCode::russian,
LanguageCode::french,
LanguageCode::chinese,
LanguageCode::polish,
LanguageCode::brazilian_portuguese,
LanguageCode::finnish,
LanguageCode::german,
LanguageCode::danish,
LanguageCode::korean
});
Language::Language(Code code) {
Language::Language(LanguageCode code) {
Construct(code);
}
Language::Language(const std::string& locale) {
for (Code code : codes) {
for (LanguageCode code : codes) {
if (locale == Language(code).GetLocale()) {
Construct(code);
return;
}
}
Construct(Code::english);
Construct(LanguageCode::english);
}
void Language::Construct(const Code code) {
void Language::Construct(const LanguageCode code) {
code_ = code;
if (code_ == Code::spanish) {
if (code_ == LanguageCode::spanish) {
name_ = "Español";
locale_ = "es";
} else if (code_ == Code::russian) {
} else if (code_ == LanguageCode::russian) {
name_ = "Русский";
locale_ = "ru";
} else if (code_ == Code::french) {
} else if (code_ == LanguageCode::french) {
name_ = "Français";
locale_ = "fr";
} else if (code_ == Code::chinese) {
} else if (code_ == LanguageCode::chinese) {
name_ = "简体中文";
locale_ = "zh_CN";
} else if (code_ == Code::polish) {
} else if (code_ == LanguageCode::polish) {
name_ = "Polski";
locale_ = "pl";
} else if (code_ == Code::brazilian_portuguese) {
} else if (code_ == LanguageCode::brazilian_portuguese) {
name_ = "Português do Brasil";
locale_ = "pt_BR";
} else if (code_ == Code::finnish) {
} else if (code_ == LanguageCode::finnish) {
name_ = "suomi";
locale_ = "fi";
} else if (code_ == Code::german) {
} else if (code_ == LanguageCode::german) {
name_ = "Deutsch";
locale_ = "de";
} else if (code_ == Code::danish) {
} else if (code_ == LanguageCode::danish) {
name_ = "Dansk";
locale_ = "da";
} else if (code_ == Code::korean) {
} else if (code_ == LanguageCode::korean) {
name_ = "한국어";
locale_ = "ko";
} else {
code_ = Code::english;
code_ = LanguageCode::english;
name_ = "English";
locale_ = "en";
}
}
Language::Code Language::GetCode() const {
LanguageCode Language::GetCode() const {
return code_;
}
+7 -18
View File
@@ -28,36 +28,25 @@
#include <string>
#include <vector>
#include "loot/language_code.h"
namespace loot {
//Language class for simpler language support.
class Language {
public:
enum struct Code : unsigned int {
english = 1,
spanish = 2,
russian = 3,
french = 4,
chinese = 5,
polish = 6,
brazilian_portuguese = 7,
finnish = 8,
german = 9,
danish = 10,
korean = 11
};
static const std::vector<Code> codes;
static const std::vector<LanguageCode> codes;
Language(const Code code);
Language(const LanguageCode code);
Language(const std::string& locale);
Code GetCode() const;
LanguageCode GetCode() const;
std::string GetName() const;
std::string GetLocale() const;
private:
void Construct(const Code code);
void Construct(const LanguageCode code);
Code code_;
LanguageCode code_;
std::string name_;
std::string locale_;
};
+6 -6
View File
@@ -35,7 +35,7 @@ Message::Message() : type_(MessageType::say) {}
Message::Message(const MessageType type, const std::string& content,
const std::string& condition) : type_(type), ConditionalMetadata(condition) {
content_.push_back(MessageContent(content, Language::Code::english));
content_.push_back(MessageContent(content, LanguageCode::english));
}
Message::Message(const MessageType type, const std::vector<MessageContent>& content,
@@ -43,7 +43,7 @@ Message::Message(const MessageType type, const std::vector<MessageContent>& cont
if (content.size() > 1) {
bool englishStringExists = false;
for (const auto &mc : content) {
if (mc.GetLanguage() == Language::Code::english)
if (mc.GetLanguage() == LanguageCode::english)
englishStringExists = true;
}
if (!englishStringExists)
@@ -53,7 +53,7 @@ Message::Message(const MessageType type, const std::vector<MessageContent>& cont
bool Message::operator < (const Message& rhs) const {
if (!content_.empty() && !rhs.GetContent().empty())
return boost::ilexicographical_compare(ChooseContent(Language::Code::english).GetText(), rhs.ChooseContent(Language::Code::english).GetText());
return boost::ilexicographical_compare(ChooseContent(LanguageCode::english).GetText(), rhs.ChooseContent(LanguageCode::english).GetText());
else if (content_.empty() && !rhs.GetContent().empty())
return true;
else
@@ -64,14 +64,14 @@ bool Message::operator == (const Message& rhs) const {
return (content_ == rhs.GetContent());
}
bool Message::EvalCondition(loot::Game& game, const Language::Code language) {
bool Message::EvalCondition(loot::Game& game, const LanguageCode language) {
BOOST_LOG_TRIVIAL(trace) << "Choosing message content for language: " << Language(language).GetName();
content_.assign({ChooseContent(language)});
return ConditionalMetadata::EvalCondition(game);
}
MessageContent Message::ChooseContent(const Language::Code language) const {
MessageContent Message::ChooseContent(const LanguageCode language) const {
BOOST_LOG_TRIVIAL(trace) << "Choosing message content.";
return MessageContent::Choose(content_, language);
}
@@ -81,7 +81,7 @@ MessageType Message::GetType() const {
}
std::string Message::GetText() const {
return ChooseContent(Language::Code::english).GetText();
return ChooseContent(LanguageCode::english).GetText();
}
std::vector<MessageContent> Message::GetContent() const {
+4 -4
View File
@@ -50,13 +50,13 @@ public:
bool operator < (const Message& rhs) const;
bool operator == (const Message& rhs) const;
bool EvalCondition(Game& game, const Language::Code language);
bool EvalCondition(Game& game, const LanguageCode language);
MessageType GetType() const;
std::string GetText() const;
std::vector<MessageContent> GetContent() const;
private:
MessageContent ChooseContent(const Language::Code language) const;
MessageContent ChooseContent(const LanguageCode language) const;
MessageType type_;
std::vector<MessageContent> content_;
@@ -104,14 +104,14 @@ struct convert<loot::Message> {
if (node["content"].IsSequence())
content = node["content"].as< std::vector<loot::MessageContent> >();
else {
content.push_back(loot::MessageContent(node["content"].as<std::string>(), loot::Language::Code::english));
content.push_back(loot::MessageContent(node["content"].as<std::string>(), loot::LanguageCode::english));
}
//Check now that at least one item in content is English if there are multiple items.
if (content.size() > 1) {
bool found = false;
for (const auto &mc : content) {
if (mc.GetLanguage() == loot::Language::Code::english)
if (mc.GetLanguage() == loot::LanguageCode::english)
found = true;
}
if (!found)
+5 -5
View File
@@ -29,15 +29,15 @@
#include "backend/helpers/language.h"
namespace loot {
MessageContent::MessageContent() : language_(Language::Code::english) {}
MessageContent::MessageContent() : language_(LanguageCode::english) {}
MessageContent::MessageContent(const std::string& text, const Language::Code language) : text_(text), language_(language) {}
MessageContent::MessageContent(const std::string& text, const LanguageCode language) : text_(text), language_(language) {}
std::string MessageContent::GetText() const {
return text_;
}
Language::Code MessageContent::GetLanguage() const {
LanguageCode MessageContent::GetLanguage() const {
return language_;
}
@@ -49,7 +49,7 @@ bool MessageContent::operator == (const MessageContent& rhs) const {
return (boost::iequals(text_, rhs.GetText()));
}
MessageContent MessageContent::Choose(const std::vector<MessageContent> content,
const Language::Code language) {
const LanguageCode language) {
if (content.empty())
return MessageContent();
else if (content.size() == 1)
@@ -59,7 +59,7 @@ MessageContent MessageContent::Choose(const std::vector<MessageContent> content,
for (const auto &mc : content) {
if (mc.GetLanguage() == language) {
return mc;
} else if (mc.GetLanguage() == Language::Code::english)
} else if (mc.GetLanguage() == LanguageCode::english)
english = mc;
}
return english;
+5 -5
View File
@@ -34,19 +34,19 @@ namespace loot {
class MessageContent {
public:
MessageContent();
MessageContent(const std::string& text, const Language::Code language);
MessageContent(const std::string& text, const LanguageCode language);
std::string GetText() const;
Language::Code GetLanguage() const;
LanguageCode GetLanguage() const;
bool operator < (const MessageContent& rhs) const;
bool operator == (const MessageContent& rhs) const;
static MessageContent Choose(const std::vector<MessageContent> content,
const Language::Code language);
const LanguageCode language);
private:
std::string text_;
Language::Code language_;
LanguageCode language_;
};
}
@@ -70,7 +70,7 @@ struct convert<loot::MessageContent> {
throw RepresentationException(node.Mark(), "bad conversion: 'lang' key missing from 'message content' object");
std::string text = node["text"].as<std::string>();
loot::Language::Code lang = loot::Language(node["lang"].as<std::string>()).GetCode();
loot::LanguageCode lang = loot::Language(node["lang"].as<std::string>()).GetCode();
rhs = loot::MessageContent(text, lang);
@@ -77,7 +77,7 @@ std::vector<MessageContent> PluginCleaningData::Info() const {
return info_;
}
MessageContent PluginCleaningData::ChooseInfo(const Language::Code language) const {
MessageContent PluginCleaningData::ChooseInfo(const LanguageCode language) const {
BOOST_LOG_TRIVIAL(trace) << "Choosing dirty info content.";
return MessageContent::Choose(info_, language);
}
+3 -3
View File
@@ -56,7 +56,7 @@ public:
std::string CleaningUtility() const;
std::vector<MessageContent> Info() const;
MessageContent ChooseInfo(const Language::Code language) const;
MessageContent ChooseInfo(const LanguageCode language) const;
Message AsMessage() const;
bool EvalCondition(Game& game, const std::string& pluginName) const;
@@ -114,7 +114,7 @@ struct convert<loot::PluginCleaningData> {
if (node["info"].IsSequence())
info = node["info"].as<std::vector<loot::MessageContent>>();
else {
info.push_back(loot::MessageContent(node["info"].as<std::string>(), loot::Language::Code::english));
info.push_back(loot::MessageContent(node["info"].as<std::string>(), loot::LanguageCode::english));
}
}
@@ -122,7 +122,7 @@ struct convert<loot::PluginCleaningData> {
if (info.size() > 1) {
bool found = false;
for (const auto &mc : info) {
if (mc.GetLanguage() == loot::Language::Code::english)
if (mc.GetLanguage() == loot::LanguageCode::english)
found = true;
}
if (!found)
+1 -1
View File
@@ -345,7 +345,7 @@ void PluginMetadata::Locations(const std::set<Location>& locations) {
locations_ = locations;
}
PluginMetadata& PluginMetadata::EvalAllConditions(Game& game, const Language::Code language) {
PluginMetadata& PluginMetadata::EvalAllConditions(Game& game, const LanguageCode language) {
for (auto it = loadAfter_.begin(); it != loadAfter_.end();) {
if (!it->EvalCondition(game))
loadAfter_.erase(it++);
+1 -1
View File
@@ -89,7 +89,7 @@ public:
void CleanInfo(const std::set<PluginCleaningData>& info);
void Locations(const std::set<Location>& locations);
PluginMetadata& EvalAllConditions(Game& game, const Language::Code language);
PluginMetadata& EvalAllConditions(Game& game, const LanguageCode language);
bool HasNameOnly() const;
bool IsRegexPlugin() const;
+1 -1
View File
@@ -148,7 +148,7 @@ void MetadataList::AppendMessage(const Message& message) {
messages_.push_back(message);
}
void MetadataList::EvalAllConditions(Game& game, const Language::Code language) {
void MetadataList::EvalAllConditions(Game& game, const LanguageCode language) {
std::unordered_set<PluginMetadata> replacementSet;
for (auto &plugin : plugins_) {
PluginMetadata p(plugin);
+1 -1
View File
@@ -57,7 +57,7 @@ public:
void AppendMessage(const Message& message);
// Eval plugin conditions.
void EvalAllConditions(Game& game, const Language::Code language);
void EvalAllConditions(Game& game, const LanguageCode language);
protected:
std::set<std::string> bashTags_;
+2 -2
View File
@@ -98,7 +98,7 @@ private:
vertex_t target;
};
std::vector<Plugin> PluginSorter::Sort(Game& game, const Language::Code language) {
std::vector<Plugin> PluginSorter::Sort(Game& game, const LanguageCode language) {
using std::vector;
// Clear existing data.
graph_.clear();
@@ -167,7 +167,7 @@ std::vector<Plugin> PluginSorter::Sort(Game& game, const Language::Code language
return plugins;
}
void PluginSorter::AddPluginVertices(Game& game, const Language::Code language) {
void PluginSorter::AddPluginVertices(Game& game, const LanguageCode language) {
BOOST_LOG_TRIVIAL(info) << "Merging masterlist, userlist into plugin list, evaluating conditions and checking for install validity.";
// The resolution of tie-breaks in the plugin graph may be dependent
+2 -2
View File
@@ -40,7 +40,7 @@ typedef boost::associative_property_map<std::map<vertex_t, size_t>> vertex_map_t
class PluginSorter {
public:
std::vector<Plugin> Sort(Game& game, const Language::Code language);
std::vector<Plugin> Sort(Game& game, const LanguageCode language);
private:
bool GetVertexByName(const std::string& name, vertex_t& vertex) const;
void CheckForCycles() const;
@@ -50,7 +50,7 @@ private:
void PropagatePriorities();
void AddPluginVertices(Game& game, const Language::Code language);
void AddPluginVertices(Game& game, const LanguageCode language);
void AddSpecificEdges();
void AddPriorityEdges();
void AddOverlapEdges();
+1 -1
View File
@@ -91,7 +91,7 @@ void LootApp::OnContextInitialized() {
// Need to set the global locale for this process so that messages will
// be translated.
BOOST_LOG_TRIVIAL(debug) << "Initialising language settings in UI thread.";
if (lootState_.getLanguage().GetCode() != Language::Code::english) {
if (lootState_.getLanguage().GetCode() != LanguageCode::english) {
boost::locale::generator gen;
gen.add_messages_path(LootPaths::getL10nPath().string());
gen.add_messages_domain("loot");
+21 -21
View File
@@ -32,56 +32,56 @@ along with LOOT. If not, see
namespace loot {
namespace test {
TEST(Language, codeConstructorShouldSetTheCorrectData) {
Language lang(Language::Code::english);
EXPECT_EQ(Language::Code::english, lang.GetCode());
Language lang(LanguageCode::english);
EXPECT_EQ(LanguageCode::english, lang.GetCode());
EXPECT_EQ("English", lang.GetName());
EXPECT_EQ("en", lang.GetLocale());
lang = Language(Language::Code::polish);
EXPECT_EQ(Language::Code::polish, lang.GetCode());
lang = Language(LanguageCode::polish);
EXPECT_EQ(LanguageCode::polish, lang.GetCode());
EXPECT_EQ("Polski", lang.GetName());
EXPECT_EQ("pl", lang.GetLocale());
}
TEST(Language, localeConstructorShouldSetTheCorrectData) {
Language lang("en");
EXPECT_EQ(Language::Code::english, lang.GetCode());
EXPECT_EQ(LanguageCode::english, lang.GetCode());
EXPECT_EQ("English", lang.GetName());
EXPECT_EQ("en", lang.GetLocale());
lang = Language("de");
EXPECT_EQ(Language::Code::german, lang.GetCode());
EXPECT_EQ(LanguageCode::german, lang.GetCode());
EXPECT_EQ("Deutsch", lang.GetName());
EXPECT_EQ("de", lang.GetLocale());
}
TEST(Language, codeConstructorShouldTreatAnInvalidCodeAsEnglish) {
Language lang(Language::Code(1000));
EXPECT_EQ(Language::Code::english, lang.GetCode());
Language lang(LanguageCode(1000));
EXPECT_EQ(LanguageCode::english, lang.GetCode());
EXPECT_EQ("English", lang.GetName());
EXPECT_EQ("en", lang.GetLocale());
}
TEST(Language, localeConstructorShouldTreatAnInvalidLocaleAsEnglish) {
Language lang("foo");
EXPECT_EQ(Language::Code::english, lang.GetCode());
EXPECT_EQ(LanguageCode::english, lang.GetCode());
EXPECT_EQ("English", lang.GetName());
EXPECT_EQ("en", lang.GetLocale());
}
TEST(Language, codesShouldContainAllExpectedLanguageCodes) {
std::vector<Language::Code> codes = {
Language::Code::english,
Language::Code::spanish,
Language::Code::russian,
Language::Code::french,
Language::Code::chinese,
Language::Code::polish,
Language::Code::brazilian_portuguese,
Language::Code::finnish,
Language::Code::german,
Language::Code::danish,
Language::Code::korean
std::vector<LanguageCode> codes = {
LanguageCode::english,
LanguageCode::spanish,
LanguageCode::russian,
LanguageCode::french,
LanguageCode::chinese,
LanguageCode::polish,
LanguageCode::brazilian_portuguese,
LanguageCode::finnish,
LanguageCode::german,
LanguageCode::danish,
LanguageCode::korean
};
EXPECT_EQ(codes, Language::codes);

Some files were not shown because too many files have changed in this diff Show More