renamed all .h to .hpp
[supertux.git] / src / tinygettext / tinygettext.hpp
1 //  $Id$
2 // 
3 //  TinyGetText - A small flexible gettext() replacement
4 //  Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 // 
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 #ifndef HEADER_TINYGETTEXT_H
20 #define HEADER_TINYGETTEXT_H
21
22 #include <map>
23 #include <vector>
24 #include <set>
25 #include <string>
26
27 namespace TinyGetText {
28
29 typedef int (*PluralFunc)(int n);
30
31 struct LanguageDef {
32   const char* code;
33   const char* name;
34   int         nplural;
35   PluralFunc  plural;
36
37   LanguageDef(const char* code_, const char* name_,  int nplural_, PluralFunc plural_)
38     : code(code_), name(name_), nplural(nplural_), plural(plural_)
39   {}
40 };
41
42 /** A simple dictionary class that mimics gettext() behaviour. Each
43     Dictionary only works for a single language, for managing multiple
44     languages and .po files at once use the DictionaryManager. */
45 class Dictionary
46 {
47 private:
48   typedef std::map<std::string, std::string> Entries;
49   Entries entries;
50
51   typedef std::map<std::string, std::map<int, std::string> > PluralEntries;
52   PluralEntries plural_entries;
53
54   LanguageDef language;
55   std::string charset;
56 public:
57   /** */
58   Dictionary(const LanguageDef& language_, const std::string& charset = "");
59
60   Dictionary();
61
62   /** Return the charset used for this dictionary */
63   std::string get_charset() const;
64
65   /** Set a charset for this dictionary, this will NOT convert stuff,
66       it is for information only, you have to convert stuff yourself
67       when you add it with \a add_translation() */
68   void set_charset(const std::string& charset);
69
70   /** Set the language that is used for this dictionary, this is
71       mainly needed to evaluate plural forms */
72   void set_language(const LanguageDef& lang);
73
74   /** Translate the string \a msgid to its correct plural form, based
75       on the number of items given by \a num. \a msgid2 is \a msgid in
76       plural form. */
77   std::string translate(const std::string& msgid, const std::string& msgid2, int num);
78
79   /** Translate the string \a msgid. */
80   std::string translate(const std::string& msgid);
81   /** Translate the string \a msgid. */
82   const char* translate(const char* msgid);
83     
84   /** Add a translation from \a msgid to \a msgstr to the dictionary,
85       where \a msgid is the singular form of the message, msgid2 the
86       plural form and msgstrs a table of translations. The right
87       translation will be calculated based on the \a num argument to
88       translate(). */
89   void add_translation(const std::string& msgid, const std::string& msgid2,
90                        const std::map<int, std::string>& msgstrs);
91
92   /** Add a translation from \a msgid to \a msgstr to the
93       dictionary */
94   void add_translation(const std::string& msgid, const std::string& msgstr);
95 };
96
97 /** Manager class for dictionaries, you give it a bunch of directories
98     with .po files and it will then automatically load the right file
99     on demand depending on which language was set. */
100 class DictionaryManager
101 {
102 private:
103   typedef std::map<std::string, Dictionary> Dictionaries;
104   Dictionaries dictionaries;
105   typedef std::vector<std::string> SearchPath;
106   SearchPath search_path;
107   typedef std::map<std::string, std::string> Aliases;
108   Aliases language_aliases;
109   std::string charset;
110   std::string language;
111   Dictionary* current_dict;
112   Dictionary empty_dict;
113
114 public:
115   DictionaryManager();
116
117   /** Return the currently active dictionary, if none is set, an empty
118       dictionary is returned. */
119   Dictionary& get_dictionary()
120   { return *current_dict; }
121
122   /** Get dictionary for lang */
123   Dictionary& get_dictionary(const std::string& langspec);
124
125   /** Set a language based on a four? letter country code */
126   void set_language(const std::string& langspec);
127
128   /** returns the (normalized) country code of the currently used language */
129   const std::string& get_language() const;
130
131   /** Set a charset that will be set on the returned dictionaries */
132   void set_charset(const std::string& charset);
133
134   /** Define an alias for a language */
135   void set_language_alias(const std::string& alias, const std::string& lang);
136
137   /** Add a directory to the search path for dictionaries */
138   void add_directory(const std::string& pathname);
139   
140   /** Return a set of the available languages in their country code */
141   std::set<std::string> get_languages();
142
143 private:
144   void parseLocaleAliases();
145   /// returns the language part in a language spec (like de_DE.UTF-8 -> de)
146   std::string get_language_from_spec(const std::string& spec);
147 };
148
149 /** Read the content of the .po file given as \a in into the
150     dictionary given as \a dict */
151 void read_po_file(Dictionary& dict, std::istream& in);
152 LanguageDef& get_language_def(const std::string& name);
153
154 } // namespace TinyGetText
155
156 #endif
157
158 /* EOF */