Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1057 was 1056, checked in by landauf, 17 years ago

don't panic, no codechanges!
added a link to www.orxonox.net

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