Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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