00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kcatalog_p.h"
00021 #include "kstandarddirs.h"
00022
00023 #include <config.h>
00024
00025 #include <QtCore/QFile>
00026 #include <QMutexLocker>
00027
00028 #include <kdebug.h>
00029
00030 #include <stdlib.h>
00031 #include <locale.h>
00032 #include "gettext.h"
00033
00034
00035 static bool s_localeSet = false;
00036
00037
00038
00039
00040 int kInitializeLocale()
00041 {
00042 setlocale(LC_ALL, "");
00043 extern Q_CORE_EXPORT bool qt_locale_initialized;
00044 qt_locale_initialized = true;
00045 s_localeSet = true;
00046 return 1;
00047 }
00048 Q_CONSTRUCTOR_FUNCTION(kInitializeLocale)
00049
00050
00051 #ifdef _WIN32
00052 # ifndef LC_MESSAGES
00053 # define LC_MESSAGES 42
00054 # endif
00055 #endif
00056
00057 static char *langenv = 0;
00058 static const int langenvMaxlen = 42;
00059
00060
00061 class KCatalogStaticData
00062 {
00063 public:
00064 KCatalogStaticData() {}
00065
00066 QMutex mutex;
00067 };
00068
00069 K_GLOBAL_STATIC(KCatalogStaticData, catalogStaticData)
00070
00071 class KCatalogPrivate
00072 {
00073 public:
00074 KCatalogPrivate()
00075 : bindDone(false)
00076 {}
00077
00078 QByteArray language;
00079 QByteArray name;
00080 QByteArray localeDir;
00081
00082 QByteArray systemLanguage;
00083 bool bindDone;
00084
00085 static QByteArray currentLanguage;
00086
00087 void setupGettextEnv ();
00088 void resetSystemLanguage ();
00089 };
00090
00091 QDebug operator<<(QDebug debug, const KCatalog &c)
00092 {
00093 return debug << c.d->language << " " << c.d->name << " " << c.d->localeDir;
00094 }
00095
00096 QByteArray KCatalogPrivate::currentLanguage;
00097
00098 KCatalog::KCatalog(const QString & name, const QString & language )
00099 : d( new KCatalogPrivate )
00100 {
00101
00102 if (!s_localeSet) {
00103 kInitializeLocale();
00104 }
00105
00106
00107 QString localeDir = catalogLocaleDir( name, language );
00108
00109 d->language = QFile::encodeName( language );
00110 d->name = QFile::encodeName( name );
00111 d->localeDir = QFile::encodeName( localeDir );
00112
00113
00114 bind_textdomain_codeset( d->name, "UTF-8" );
00115
00116
00117 KCatalogPrivate::currentLanguage.clear();
00118
00119 if (!langenv) {
00120
00121
00122 langenv = new char[langenvMaxlen];
00123 QByteArray lang = qgetenv("LANGUAGE");
00124 snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", lang.constData());
00125 putenv(langenv);
00126 }
00127 }
00128
00129 KCatalog::KCatalog(const KCatalog & rhs)
00130 : d( new KCatalogPrivate )
00131 {
00132 *this = rhs;
00133 }
00134
00135 KCatalog & KCatalog::operator=(const KCatalog & rhs)
00136 {
00137 *d = *rhs.d;
00138
00139 return *this;
00140 }
00141
00142 KCatalog::~KCatalog()
00143 {
00144 delete d;
00145 }
00146
00147 QString KCatalog::catalogLocaleDir( const QString &name,
00148 const QString &language )
00149 {
00150 QString relpath = QString::fromLatin1( "%1/LC_MESSAGES/%2.mo" )
00151 .arg( language ).arg( name );
00152 return KGlobal::dirs()->findResourceDir( "locale", relpath );
00153 }
00154
00155 QString KCatalog::name() const
00156 {
00157 return d->name;
00158 }
00159
00160 QString KCatalog::language() const
00161 {
00162 return d->language;
00163 }
00164
00165 QString KCatalog::localeDir() const
00166 {
00167 return d->localeDir;
00168 }
00169
00170 void KCatalogPrivate::setupGettextEnv ()
00171 {
00172
00173 systemLanguage = qgetenv("LANGUAGE");
00174 if (systemLanguage != language) {
00175
00176
00177 snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", language.constData());
00178 }
00179
00180
00181
00182 if (language != currentLanguage || !bindDone) {
00183
00184 currentLanguage = language;
00185 bindDone = true;
00186
00187
00188 bindtextdomain(name, localeDir);
00189
00190
00191
00192
00193
00194
00195
00196
00197 }
00198 }
00199
00200 void KCatalogPrivate::resetSystemLanguage ()
00201 {
00202 if (language != systemLanguage) {
00203 snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", systemLanguage.constData());
00204 }
00205 }
00206
00207 QString KCatalog::translate(const char * msgid) const
00208 {
00209 QMutexLocker locker(&catalogStaticData->mutex);
00210 d->setupGettextEnv();
00211 const char *msgstr = dgettext(d->name, msgid);
00212 d->resetSystemLanguage();
00213 return QString::fromUtf8(msgstr);
00214 }
00215
00216 QString KCatalog::translate(const char * msgctxt, const char * msgid) const
00217 {
00218 QMutexLocker locker(&catalogStaticData->mutex);
00219 d->setupGettextEnv();
00220 const char *msgstr = dpgettext_expr(d->name, msgctxt, msgid);
00221 d->resetSystemLanguage();
00222 return QString::fromUtf8(msgstr);
00223 }
00224
00225 QString KCatalog::translate(const char * msgid, const char * msgid_plural,
00226 unsigned long n) const
00227 {
00228 QMutexLocker locker(&catalogStaticData->mutex);
00229 d->setupGettextEnv();
00230 const char *msgstr = dngettext(d->name, msgid, msgid_plural, n);
00231 d->resetSystemLanguage();
00232 return QString::fromUtf8(msgstr);
00233 }
00234
00235 QString KCatalog::translate(const char * msgctxt, const char * msgid,
00236 const char * msgid_plural, unsigned long n) const
00237 {
00238 QMutexLocker locker(&catalogStaticData->mutex);
00239 d->setupGettextEnv();
00240 const char *msgstr = dnpgettext_expr(d->name, msgctxt, msgid, msgid_plural, n);
00241 d->resetSystemLanguage();
00242 return QString::fromUtf8(msgstr);
00243 }
00244
00245 QString KCatalog::translateStrict(const char * msgid) const
00246 {
00247 QMutexLocker locker(&catalogStaticData->mutex);
00248 d->setupGettextEnv();
00249 const char *msgstr = dgettext(d->name, msgid);
00250 d->resetSystemLanguage();
00251 return msgstr != msgid ? QString::fromUtf8(msgstr) : QString();
00252 }
00253
00254 QString KCatalog::translateStrict(const char * msgctxt, const char * msgid) const
00255 {
00256 QMutexLocker locker(&catalogStaticData->mutex);
00257 d->setupGettextEnv();
00258 const char *msgstr = dpgettext_expr(d->name, msgctxt, msgid);
00259 d->resetSystemLanguage();
00260 return msgstr != msgid ? QString::fromUtf8(msgstr) : QString();
00261 }
00262
00263 QString KCatalog::translateStrict(const char * msgid, const char * msgid_plural,
00264 unsigned long n) const
00265 {
00266 QMutexLocker locker(&catalogStaticData->mutex);
00267 d->setupGettextEnv();
00268 const char *msgstr = dngettext(d->name, msgid, msgid_plural, n);
00269 d->resetSystemLanguage();
00270 return msgstr != msgid && msgstr != msgid_plural ? QString::fromUtf8(msgstr) : QString();
00271 }
00272
00273 QString KCatalog::translateStrict(const char * msgctxt, const char * msgid,
00274 const char * msgid_plural, unsigned long n) const
00275 {
00276 QMutexLocker locker(&catalogStaticData->mutex);
00277 d->setupGettextEnv();
00278 const char *msgstr = dnpgettext_expr(d->name, msgctxt, msgid, msgid_plural, n);
00279 d->resetSystemLanguage();
00280 return msgstr != msgid && msgstr != msgid_plural ? QString::fromUtf8(msgstr) : QString();
00281 }
00282