Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/console/src/core/Language.cc @ 1436

Last change on this file since 1436 was 1313, checked in by landauf, 16 years ago
  • implemented Shell, but not yet linked with the graphical console
  • added new features (cursor, OIS::KeyCode listener) to InputBuffer
  • changed some includes to avoid circular header-dependencies in OrxonoxClass and Shell
File size: 11.9 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
[1313]40#include "Debug.h"
41
[704]42namespace orxonox
43{
44    // ###############################
45    // ###      LanguageEntry      ###
46    // ###############################
[720]47    /**
48        @brief Constructor: Sets the default entry.
49        @param fallbackEntry The default entry
50    */
[715]51    LanguageEntry::LanguageEntry(const std::string& fallbackEntry)
[704]52    {
53        this->fallbackEntry_ = fallbackEntry;
[871]54        this->localisedEntry_ = fallbackEntry; // Set the localisation to the fallback entry, for the case that no translation gets assigned
55        this->bLocalisationSet_ = false;
[704]56    }
57
[720]58    /**
[871]59        @brief Sets the localisation of the entry.
60        @param localisation The localisation
[720]61    */
[871]62    void LanguageEntry::setLocalisation(const std::string& localisation)
[704]63    {
[720]64        // Check if the translation is more than just an empty string
[1052]65        if ((localisation != "") && (localisation.size() > 0))
[725]66        {
[871]67            this->localisedEntry_ = localisation;
68            this->bLocalisationSet_ = true;
[725]69        }
[704]70        else
[871]71            this->localisedEntry_ = this->fallbackEntry_;
[704]72    }
73
[720]74    /**
75        @brief Sets the default entry.
76        @param fallbackEntry The default entry
77    */
[715]78    void LanguageEntry::setDefault(const std::string& fallbackEntry)
[704]79    {
[720]80        // If the default entry changes and the translation wasn't set yet, use the new default entry as translation
[871]81        if (!this->bLocalisationSet_)
82            this->localisedEntry_ = fallbackEntry;
[704]83
84        this->fallbackEntry_ = fallbackEntry;
85    }
86
87    // ###############################
88    // ###        Language         ###
89    // ###############################
[720]90    /**
91        @brief Constructor: Reads the default language file and sets some values.
92    */
[704]93    Language::Language()
94    {
95        this->defaultLanguage_ = "default";
[871]96        this->defaultLocalisation_ = "ERROR: LANGUAGE ENTRY DOESN'T EXIST!";
[720]97
98        // Read the default language file to create all known LanguageEntry objects
[704]99        this->readDefaultLanguageFile();
100    }
101
[720]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    */
[704]106    Language& Language::getLanguage()
107    {
[1052]108        static Language instance = Language();
109        return instance;
[704]110    }
111
[720]112    /**
[871]113        @brief Creates a new LanguageEntry with a given label and a given default entry.
114        @param label The label of the entry
[720]115        @param entry The default entry
[725]116        @return The created LanguageEntry object
[720]117    */
[871]118    LanguageEntry* Language::createEntry(const LanguageEntryLabel& label, const std::string& entry)
[704]119    {
[871]120        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
[725]121
[720]122        // Make sure we don't create a duplicate entry
[728]123        if (it == this->languageEntries_.end())
[704]124        {
125            LanguageEntry* newEntry = new LanguageEntry(entry);
[871]126            newEntry->setLabel(label);
127            this->languageEntries_[label] = newEntry;
[725]128            return newEntry;
[704]129        }
[725]130
[871]131        COUT(2) << "Warning: Language entry " << label << " is duplicate in " << getFileName(this->defaultLanguage_) << "!" << std::endl;
[725]132        return it->second;
[704]133    }
134
[720]135    /**
136        @brief Adds a new LanguageEntry, if it's not already existing.
[871]137        @param label The label of the entry
[720]138        @param entry The default entry
139    */
[871]140    void Language::addEntry(const LanguageEntryLabel& label, const std::string& entry)
[704]141    {
[871]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);
[728]144        if (it == this->languageEntries_.end())
[720]145        {
146            // The entry isn't available yet, meaning it's new, so create it
[871]147            this->createEntry(label, entry);
[720]148        }
[704]149        else if (it->second->getDefault().compare(entry) == 0)
[720]150        {
151            // The entry is available and the default string is the same, so return because everything is fine
[704]152            return;
[720]153        }
[704]154        else
[720]155        {
156            // The defined default entry is not the same as in the default language file - change it to the new entry
[704]157            it->second->setDefault(entry);
[720]158        }
[704]159
[720]160        // Write the default language file because either a new entry was created or an existing entry has changed
[704]161        this->writeDefaultLanguageFile();
[728]162
[704]163    }
164
[720]165    /**
[871]166        @brief Returns the localisation of a given entry.
167        @param label The label of the entry
168        @return The localisation
[720]169    */
[871]170    const std::string& Language::getLocalisation(const LanguageEntryLabel& label) const
[704]171    {
[871]172        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
[728]173        if (it != this->languageEntries_.end())
[871]174            return it->second->getLocalisation();
[704]175        else
176        {
[720]177            // Uh, oh, an undefined entry was requested: return the default string
[871]178            COUT(2) << "Warning: Language entry \"" << label << "\" not found!" << std::endl;
179            return this->defaultLocalisation_;
[704]180        }
181    }
182
[720]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    */
[715]188    const std::string Language::getFileName(const std::string& language)
[704]189    {
[715]190        return std::string("translation_" + language + ".lang");
[704]191    }
192
[720]193    /**
194        @brief Reads the default language file and creates a LanguageEntry objects for every entry.
195    */
[704]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        {
[871]211            COUT(1) << "An error occurred in Language.cc:" << std::endl;
[704]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);
[715]222            std::string lineString = std::string(line);
[720]223
224            // Check if the line is empty
[1052]225            if ((lineString != "") && (lineString.size() > 0))
[704]226            {
[782]227                unsigned int pos = lineString.find('=');
[720]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)
[704]231                    this->createEntry(lineString.substr(0, pos), lineString.substr(pos + 1));
232                else
[1052]233                {
[704]234                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(this->defaultLanguage_) << std::endl;
[1052]235                }
[704]236            }
237        }
238
239        file.close();
240    }
241
[720]242    /**
[871]243        @brief Reads the language file of the configured language and assigns the localisation to the corresponding LanguageEntry object.
[720]244    */
[704]245    void Language::readTranslatedLanguageFile()
246    {
[1052]247        COUT(4) << "Read translated language file (" << CoreSettings::getLanguage() << ")." << std::endl;
[704]248
249        // Open the file
250        std::ifstream file;
[1052]251        file.open(getFileName(CoreSettings::getLanguage()).c_str(), std::fstream::in);
[704]252
253        if (!file.is_open())
254        {
[871]255            COUT(1) << "An error occurred in Language.cc:" << std::endl;
[1052]256            COUT(1) << "Error: Couldn't open file " << getFileName(CoreSettings::getLanguage()) << " to read the translated language entries!" << std::endl;
257            CoreSettings::resetLanguage();
[704]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);
[715]268            std::string lineString = std::string(line);
[720]269
270            // Check if the line is empty
[1052]271            if ((lineString != "") && (lineString.size() > 0))
[704]272            {
[782]273                unsigned int pos = lineString.find('=');
[720]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)
[704]277                {
[715]278                    std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(lineString.substr(0, pos));
[720]279
280                    // Check if the entry exists
[728]281                    if (it != this->languageEntries_.end())
[871]282                        it->second->setLocalisation(lineString.substr(pos + 1));
[704]283                    else
[871]284                        this->createEntry(lineString.substr(0, pos), this->defaultLocalisation_)->setLocalisation(lineString.substr(pos + 1));
[704]285                }
286                else
[1052]287                {
288                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(CoreSettings::getLanguage()) << std::endl;
289                }
[704]290            }
291        }
292
293        file.close();
294    }
295
[720]296    /**
297        @brief Writes all default entries to the default language file.
298    */
[704]299    void Language::writeDefaultLanguageFile() const
300    {
[871]301        COUT(4) << "Language: Write default language file." << std::endl;
[704]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        {
[871]309            COUT(1) << "An error occurred in Language.cc:" << std::endl;
[704]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
[1052]315        for (std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.begin(); it != this->languageEntries_.end(); ++it)
[704]316        {
[1052]317            file << (*it).second->getLabel() << "=" << (*it).second->getDefault() << std::endl;
[704]318        }
319
320        file.close();
321    }
322}
Note: See TracBrowser for help on using the repository browser.