Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core3/src/core/Language.cc @ 1610

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

moved Debug.h, OutputHandler and OutputBuffer to util, to make COUT(x) available everywhere

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