Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/Language.cc @ 1136

Last change on this file since 1136 was 1062, checked in by rgrieder, 17 years ago
  • changed header file inclusion order
File size: 11.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file Language.cc
31    @brief Implementation of the Language and the LanguageEntry classes.
32*/
33
34#include "Language.h"
35
36#include <fstream>
37
38#include "CoreSettings.h"
39
40namespace orxonox
41{
42    // ###############################
43    // ###      LanguageEntry      ###
44    // ###############################
45    /**
46        @brief Constructor: Sets the default entry.
47        @param fallbackEntry The default entry
48    */
49    LanguageEntry::LanguageEntry(const std::string& fallbackEntry)
50    {
51        this->fallbackEntry_ = fallbackEntry;
52        this->localisedEntry_ = fallbackEntry; // Set the localisation to the fallback entry, for the case that no translation gets assigned
53        this->bLocalisationSet_ = false;
54    }
55
56    /**
57        @brief Sets the localisation of the entry.
58        @param localisation The localisation
59    */
60    void LanguageEntry::setLocalisation(const std::string& localisation)
61    {
62        // Check if the translation is more than just an empty string
63        if ((localisation != "") && (localisation.size() > 0))
64        {
65            this->localisedEntry_ = localisation;
66            this->bLocalisationSet_ = true;
67        }
68        else
69            this->localisedEntry_ = this->fallbackEntry_;
70    }
71
72    /**
73        @brief Sets the default entry.
74        @param fallbackEntry The default entry
75    */
76    void LanguageEntry::setDefault(const std::string& fallbackEntry)
77    {
78        // If the default entry changes and the translation wasn't set yet, use the new default entry as translation
79        if (!this->bLocalisationSet_)
80            this->localisedEntry_ = fallbackEntry;
81
82        this->fallbackEntry_ = fallbackEntry;
83    }
84
85    // ###############################
86    // ###        Language         ###
87    // ###############################
88    /**
89        @brief Constructor: Reads the default language file and sets some values.
90    */
91    Language::Language()
92    {
93        this->defaultLanguage_ = "default";
94        this->defaultLocalisation_ = "ERROR: LANGUAGE ENTRY DOESN'T EXIST!";
95
96        // Read the default language file to create all known LanguageEntry objects
97        this->readDefaultLanguageFile();
98    }
99
100    /**
101        @brief Returns a reference to the only existing instance of the Language class and calls the setConfigValues() function.
102        @return The reference to the only existing instance
103    */
104    Language& Language::getLanguage()
105    {
106        static Language instance = Language();
107        return instance;
108    }
109
110    /**
111        @brief Creates a new LanguageEntry with a given label and a given default entry.
112        @param label The label of the entry
113        @param entry The default entry
114        @return The created LanguageEntry object
115    */
116    LanguageEntry* Language::createEntry(const LanguageEntryLabel& label, const std::string& entry)
117    {
118        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
119
120        // Make sure we don't create a duplicate entry
121        if (it == this->languageEntries_.end())
122        {
123            LanguageEntry* newEntry = new LanguageEntry(entry);
124            newEntry->setLabel(label);
125            this->languageEntries_[label] = newEntry;
126            return newEntry;
127        }
128
129        COUT(2) << "Warning: Language entry " << label << " is duplicate in " << getFileName(this->defaultLanguage_) << "!" << std::endl;
130        return it->second;
131    }
132
133    /**
134        @brief Adds a new LanguageEntry, if it's not already existing.
135        @param label The label of the entry
136        @param entry The default entry
137    */
138    void Language::addEntry(const LanguageEntryLabel& label, const std::string& entry)
139    {
140        COUT(5) << "Language: Called addEntry with\n  label: " << label << "\n  entry: " <<  entry << std::endl;
141        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
142        if (it == this->languageEntries_.end())
143        {
144            // The entry isn't available yet, meaning it's new, so create it
145            this->createEntry(label, entry);
146        }
147        else if (it->second->getDefault().compare(entry) == 0)
148        {
149            // The entry is available and the default string is the same, so return because everything is fine
150            return;
151        }
152        else
153        {
154            // The defined default entry is not the same as in the default language file - change it to the new entry
155            it->second->setDefault(entry);
156        }
157
158        // Write the default language file because either a new entry was created or an existing entry has changed
159        this->writeDefaultLanguageFile();
160
161    }
162
163    /**
164        @brief Returns the localisation of a given entry.
165        @param label The label of the entry
166        @return The localisation
167    */
168    const std::string& Language::getLocalisation(const LanguageEntryLabel& label) const
169    {
170        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
171        if (it != this->languageEntries_.end())
172            return it->second->getLocalisation();
173        else
174        {
175            // Uh, oh, an undefined entry was requested: return the default string
176            COUT(2) << "Warning: Language entry \"" << label << "\" not found!" << std::endl;
177            return this->defaultLocalisation_;
178        }
179    }
180
181    /**
182        @brief Creates the name of the language file out of the languages name.
183        @param language The name of the language
184        @return The filename
185    */
186    const std::string Language::getFileName(const std::string& language)
187    {
188        return std::string("translation_" + language + ".lang");
189    }
190
191    /**
192        @brief Reads the default language file and creates a LanguageEntry objects for every entry.
193    */
194    void Language::readDefaultLanguageFile()
195    {
196        COUT(4) << "Read default language file." << std::endl;
197
198        // This creates the file if it's not existing
199        std::ofstream createFile;
200        createFile.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::app);
201        createFile.close();
202
203        // Open the file
204        std::ifstream file;
205        file.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::in);
206
207        if (!file.is_open())
208        {
209            COUT(1) << "An error occurred in Language.cc:" << std::endl;
210            COUT(1) << "Error: Couldn't open file " << getFileName(this->defaultLanguage_) << " to read the default language entries!" << std::endl;
211            return;
212        }
213
214        char line[1024];
215
216        // Iterate through the file and create the LanguageEntries
217        while (file.good() && !file.eof())
218        {
219            file.getline(line, 1024);
220            std::string lineString = std::string(line);
221
222            // Check if the line is empty
223            if ((lineString != "") && (lineString.size() > 0))
224            {
225                unsigned int pos = lineString.find('=');
226
227                // Check if the length is at least 3 and if there's an entry before and behind the =
228                if (pos > 0 && pos < (lineString.size() - 1) && lineString.size() >= 3)
229                    this->createEntry(lineString.substr(0, pos), lineString.substr(pos + 1));
230                else
231                {
232                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(this->defaultLanguage_) << std::endl;
233                }
234            }
235        }
236
237        file.close();
238    }
239
240    /**
241        @brief Reads the language file of the configured language and assigns the localisation to the corresponding LanguageEntry object.
242    */
243    void Language::readTranslatedLanguageFile()
244    {
245        COUT(4) << "Read translated language file (" << CoreSettings::getLanguage() << ")." << std::endl;
246
247        // Open the file
248        std::ifstream file;
249        file.open(getFileName(CoreSettings::getLanguage()).c_str(), std::fstream::in);
250
251        if (!file.is_open())
252        {
253            COUT(1) << "An error occurred in Language.cc:" << std::endl;
254            COUT(1) << "Error: Couldn't open file " << getFileName(CoreSettings::getLanguage()) << " to read the translated language entries!" << std::endl;
255            CoreSettings::resetLanguage();
256            COUT(3) << "Info: Reset language to " << this->defaultLanguage_ << "." << std::endl;
257            return;
258        }
259
260        char line[1024];
261
262        // Iterate through the file and create the LanguageEntries
263        while (file.good() && !file.eof())
264        {
265            file.getline(line, 1024);
266            std::string lineString = std::string(line);
267
268            // Check if the line is empty
269            if ((lineString != "") && (lineString.size() > 0))
270            {
271                unsigned int pos = lineString.find('=');
272
273                // Check if the length is at least 3 and if there's an entry before and behind the =
274                if (pos > 0 && pos < (lineString.size() - 1) && lineString.size() >= 3)
275                {
276                    std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(lineString.substr(0, pos));
277
278                    // Check if the entry exists
279                    if (it != this->languageEntries_.end())
280                        it->second->setLocalisation(lineString.substr(pos + 1));
281                    else
282                        this->createEntry(lineString.substr(0, pos), this->defaultLocalisation_)->setLocalisation(lineString.substr(pos + 1));
283                }
284                else
285                {
286                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(CoreSettings::getLanguage()) << std::endl;
287                }
288            }
289        }
290
291        file.close();
292    }
293
294    /**
295        @brief Writes all default entries to the default language file.
296    */
297    void Language::writeDefaultLanguageFile() const
298    {
299        COUT(4) << "Language: Write default language file." << std::endl;
300
301        // Open the file
302        std::ofstream file;
303        file.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::out);
304
305        if (!file.is_open())
306        {
307            COUT(1) << "An error occurred in Language.cc:" << std::endl;
308            COUT(1) << "Error: Couldn't open file " << getFileName(this->defaultLanguage_) << " to write the default language entries!" << std::endl;
309            return;
310        }
311
312        // Iterate through the list an write the lines into the file
313        for (std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.begin(); it != this->languageEntries_.end(); ++it)
314        {
315            file << (*it).second->getLabel() << "=" << (*it).second->getDefault() << std::endl;
316        }
317
318        file.close();
319    }
320}
Note: See TracBrowser for help on using the repository browser.