Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/core/Language.cc @ 1036

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

added CoreSettings, a class containing all settings of core classes (at the moment it's only debuglevel and language)

removed DebugLevel
removed OrxonoxClass inheritance of Language and LanguageEntry

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