Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/core/Language.cc @ 704

Last change on this file since 704 was 704, checked in by landauf, 16 years ago

added a new class: Language
it's a manager for different language files to store translations of ingame text (it uses the default text, defined in the code, if no translation in the configured language is available)

File size: 8.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28#include <fstream>
29
30#include "Language.h"
31#include "CoreIncludes.h"
32
33namespace orxonox
34{
35    // ###############################
36    // ###      LanguageEntry      ###
37    // ###############################
38    LanguageEntry::LanguageEntry(const std::string& fallbackEntry)
39    {
40        RegisterRootObject(LanguageEntry);
41
42        this->fallbackEntry_ = fallbackEntry;
43        this->translatedEntry_ = fallbackEntry;
44    }
45
46    void LanguageEntry::setTranslation(const std::string& translation)
47    {
48        if (translation.compare("") != 0)
49            this->translatedEntry_ = translation;
50        else
51            this->translatedEntry_ = this->fallbackEntry_;
52    }
53
54    void LanguageEntry::setDefault(const std::string& fallbackEntry)
55    {
56        if (this->translatedEntry_.compare(this->fallbackEntry_) == 0)
57            this->translatedEntry_ = fallbackEntry;
58
59        this->fallbackEntry_ = fallbackEntry;
60    }
61
62    // ###############################
63    // ###        Language         ###
64    // ###############################
65    Language::Language()
66    {
67        RegisterRootObject(Language);
68        this->defaultLanguage_ = "default";
69        this->defaultTranslation_ = "ERROR: LANGUAGE ENTRY DOESN'T EXIST!";
70        this->readDefaultLanguageFile();
71
72        this->setConfigValues();
73    }
74
75    void Language::setConfigValues()
76    {
77        SetConfigValue(language_, this->defaultLanguage_);
78        this->readTranslatedLanguageFile();
79    }
80
81    Language& Language::getLanguage()
82    {
83        static Language theOnlyLanguageObject = Language();
84        return theOnlyLanguageObject;
85    }
86
87    void Language::createEntry(const LanguageEntryName& name, const std::string& entry)
88    {
89        if (!this->languageEntries_[name])
90        {
91            LanguageEntry* newEntry = new LanguageEntry(entry);
92            newEntry->setName(name);
93            this->languageEntries_[name] = newEntry;
94        }
95        else
96        {
97            COUT(2) << "Warning: Language entry " << name << " is duplicate in " << getFileName(this->defaultLanguage_) << "!" << std::endl;
98        }
99    }
100
101    void Language::addEntry(const LanguageEntryName& name, const std::string& entry)
102    {
103        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(name);
104        if (!it->second)
105            this->createEntry(name, entry);
106        else if (it->second->getDefault().compare(entry) == 0)
107            return;
108        else
109            it->second->setDefault(entry);
110
111        this->writeDefaultLanguageFile();
112    }
113
114    const std::string& Language::getTranslation(const LanguageEntryName& name) const
115    {
116        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(name);
117        if (it->second)
118            return it->second->getTranslation();
119        else
120        {
121            COUT(2) << "Error: Language entry \"" << name << "\" not found!" << std::endl;
122            return this->defaultTranslation_;
123        }
124    }
125
126    const std::string Language::getFileName(const std::string& language)
127    {
128        return std::string("translation_" + language + ".lang");
129    }
130
131    void Language::readDefaultLanguageFile()
132    {
133        COUT(4) << "Read default language file." << std::endl;
134
135        // This creates the file if it's not existing
136        std::ofstream createFile;
137        createFile.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::app);
138        createFile.close();
139
140        // Open the file
141        std::ifstream file;
142        file.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::in);
143
144        if (!file.is_open())
145        {
146            COUT(1) << "Error: Couldn't open file " << getFileName(this->defaultLanguage_) << " to read the default language entries!" << std::endl;
147            return;
148        }
149
150        char line[1024];
151
152        // Iterate through the file and create the LanguageEntries
153        while (file.good() && !file.eof())
154        {
155            file.getline(line, 1024);
156            std::string lineString = std::string(line);
157            if (lineString.compare("") != 0)
158            {
159                unsigned int pos = lineString.find('=');
160                if (pos < lineString.size() && lineString.size() >= 3)
161                    this->createEntry(lineString.substr(0, pos), lineString.substr(pos + 1));
162                else
163                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(this->defaultLanguage_) << std::endl;
164            }
165        }
166
167        file.close();
168    }
169
170    void Language::readTranslatedLanguageFile()
171    {
172        COUT(4) << "Read translated language file (" << this->language_ << ")." << std::endl;
173
174        // Open the file
175        std::ifstream file;
176        file.open(getFileName(this->language_).c_str(), std::fstream::in);
177
178        if (!file.is_open())
179        {
180            COUT(1) << "Error: Couldn't open file " << getFileName(this->language_) << " to read the translated language entries!" << std::endl;
181            ResetConfigValue(language_);
182            COUT(3) << "Info: Reset language to " << this->defaultLanguage_ << "." << std::endl;
183            return;
184        }
185
186        char line[1024];
187
188        // Iterate through the file and create the LanguageEntries
189        while (file.good() && !file.eof())
190        {
191            file.getline(line, 1024);
192            std::string lineString = std::string(line);
193            if (lineString.compare("") != 0)
194            {
195                unsigned int pos = lineString.find('=');
196                if (pos < lineString.size() && lineString.size() >= 3)
197                {
198                    std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(lineString.substr(0, pos));
199                    if (it->second)
200                        it->second->setTranslation(lineString.substr(pos + 1));
201                    else
202                        COUT(2) << "Warning: Unknown language entry \"" << lineString.substr(0, pos) << "\" in " << getFileName(this->language_) << std::endl;
203                }
204                else
205                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(this->language_) << std::endl;
206            }
207        }
208
209        file.close();
210    }
211
212    void Language::writeDefaultLanguageFile() const
213    {
214        COUT(4) << "Write default language file." << std::endl;
215
216        // Open the file
217        std::ofstream file;
218        file.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::out);
219
220        if (!file.is_open())
221        {
222            COUT(1) << "Error: Couldn't open file " << getFileName(this->defaultLanguage_) << " to write the default language entries!" << std::endl;
223            return;
224        }
225
226        // Iterate through the list an write the lines into the file
227        for (Iterator<LanguageEntry> it = ObjectList<LanguageEntry>::start(); it; ++it)
228        {
229            file << it->getName() << "=" << it->getDefault() << std::endl;
230        }
231
232        file.close();
233    }
234}
Note: See TracBrowser for help on using the repository browser.