• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

kcatalog.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (c) 2001 Hans Petter Bieker <bieker@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
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 // Initialize the locale very early during application startup
00038 // This is necessary for e.g. toLocal8Bit() to work, even before
00039 // a Q[Core]Application exists (David)
00040 int kInitializeLocale()
00041 {
00042     setlocale(LC_ALL, "");
00043     extern Q_CORE_EXPORT bool qt_locale_initialized; // in Qt since 4.5.0
00044     qt_locale_initialized = true; // as recommended by Thiago
00045     s_localeSet = true;
00046     return 1;
00047 }
00048 Q_CONSTRUCTOR_FUNCTION(kInitializeLocale)
00049 
00050 // not defined on win32 :(
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 // = "LANGUAGE=" + 32 chars for language code + terminating zero
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     // Set locales if the static initializer didn't work
00102     if (!s_localeSet) {
00103         kInitializeLocale();
00104     }
00105 
00106   // Find locale directory for this catalog.
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   // Always get translations in UTF-8, regardless of user's environment.
00114   bind_textdomain_codeset( d->name, "UTF-8" );
00115 
00116   // Invalidate current language, to trigger binding at next translate call.
00117   KCatalogPrivate::currentLanguage.clear();
00118 
00119   if (!langenv) {
00120     // Call putenv only here, to initialize LANGUAGE variable.
00121     // Later only change langenv to what is currently needed.
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   // Point Gettext to current language, recording system value for recovery.
00173   systemLanguage = qgetenv("LANGUAGE");
00174   if (systemLanguage != language) {
00175     // putenv has been called in the constructor,
00176     // it is enough to change the string set there.
00177     snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", language.constData());
00178   }
00179 
00180   // Rebind text domain if language actually changed from the last time,
00181   // as locale directories may differ for different languages of same catalog.
00182   if (language != currentLanguage || !bindDone) {
00183 
00184     currentLanguage = language;
00185     bindDone = true;
00186 
00187     //kDebug() << "bindtextdomain" << name << localeDir;
00188     bindtextdomain(name, localeDir);
00189 
00190     // // Magic to make sure Gettext doesn't use stale cached translation
00191     // // from previous language.
00192     // extern int _nl_msg_cat_cntr;
00193     // ++_nl_msg_cat_cntr;
00194     //
00195     // Note: Not needed, caching of translations is not an issue because
00196     // language is switched only if translation is not found.
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 

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal