Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1055 was 1052, checked in by landauf, 17 years ago

merged core2 back to trunk
there might be some errors, wasn't able to test it yet due to some strange g++ and linker behaviour.

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.