Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/core/Language.cc @ 1490

Last change on this file since 1490 was 1446, checked in by landauf, 17 years ago

merged console branch into network branch

after several heavy troubles it compiles, but there is still a bug I couldn't fix: orxonox crashes as soon as one presses a key after opening the console… maybe someone else sees the problem?

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