• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • 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 #ifndef _WIN32_WCE
00043     setlocale(LC_ALL, "");
00044 #endif
00045     extern Q_CORE_EXPORT bool qt_locale_initialized; // in Qt since 4.5.0
00046     qt_locale_initialized = true; // as recommended by Thiago
00047     s_localeSet = true;
00048     return 1;
00049 }
00050 Q_CONSTRUCTOR_FUNCTION(kInitializeLocale)
00051 
00052 // not defined on win32 :(
00053 #ifdef _WIN32
00054 # ifndef LC_MESSAGES
00055 #  define LC_MESSAGES 42
00056 # endif
00057 #endif
00058 
00059 static char *langenv = 0;
00060 static const int langenvMaxlen = 42;
00061 // = "LANGUAGE=" + 32 chars for language code + terminating zero
00062 
00063 class KCatalogStaticData
00064 {
00065 public:
00066     KCatalogStaticData() {}
00067 
00068     QMutex mutex;
00069 };
00070 
00071 K_GLOBAL_STATIC(KCatalogStaticData, catalogStaticData)
00072 
00073 class KCatalogPrivate
00074 {
00075 public:
00076     KCatalogPrivate()
00077         : bindDone(false)
00078     {}
00079 
00080   QByteArray language;
00081   QByteArray name;
00082   QByteArray localeDir;
00083 
00084   QByteArray systemLanguage;
00085   bool bindDone;
00086 
00087   static QByteArray currentLanguage;
00088 
00089   void setupGettextEnv ();
00090   void resetSystemLanguage ();
00091 };
00092 
00093 QDebug operator<<(QDebug debug, const KCatalog &c)
00094 {
00095   return debug << c.d->language << " " << c.d->name << " " << c.d->localeDir;
00096 }
00097 
00098 QByteArray KCatalogPrivate::currentLanguage;
00099 
00100 KCatalog::KCatalog(const QString & name, const QString & language )
00101   : d( new KCatalogPrivate )
00102 {
00103     // Set locales if the static initializer didn't work
00104     if (!s_localeSet) {
00105         kInitializeLocale();
00106     }
00107 
00108   // Find locale directory for this catalog.
00109   QString localeDir = catalogLocaleDir( name, language );
00110 
00111   d->language = QFile::encodeName( language );
00112   d->name = QFile::encodeName( name );
00113   d->localeDir = QFile::encodeName( localeDir );
00114 
00115   // Always get translations in UTF-8, regardless of user's environment.
00116   bind_textdomain_codeset( d->name, "UTF-8" );
00117 
00118   // Invalidate current language, to trigger binding at next translate call.
00119   KCatalogPrivate::currentLanguage.clear();
00120 
00121   if (!langenv) {
00122     // Call putenv only here, to initialize LANGUAGE variable.
00123     // Later only change langenv to what is currently needed.
00124     langenv = new char[langenvMaxlen];
00125     QByteArray lang = qgetenv("LANGUAGE");
00126     snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", lang.constData());
00127     putenv(langenv);
00128   }
00129 }
00130 
00131 KCatalog::KCatalog(const KCatalog & rhs)
00132   : d( new KCatalogPrivate )
00133 {
00134   *this = rhs;
00135 }
00136 
00137 KCatalog & KCatalog::operator=(const KCatalog & rhs)
00138 {
00139   *d = *rhs.d;
00140 
00141   return *this;
00142 }
00143 
00144 KCatalog::~KCatalog()
00145 {
00146   delete d;
00147 }
00148 
00149 QString KCatalog::catalogLocaleDir( const QString &name,
00150                                     const QString &language )
00151 {
00152   QString relpath =  QString::fromLatin1( "%1/LC_MESSAGES/%2.mo" )
00153                     .arg( language ).arg( name );
00154   return KGlobal::dirs()->findResourceDir( "locale", relpath );
00155 }
00156 
00157 QString KCatalog::name() const
00158 {
00159   return QFile::decodeName(d->name);
00160 }
00161 
00162 QString KCatalog::language() const
00163 {
00164   return QFile::decodeName(d->language);
00165 }
00166 
00167 QString KCatalog::localeDir() const
00168 {
00169   return QFile::decodeName(d->localeDir);
00170 }
00171 
00172 #ifdef Q_WS_WIN
00173   extern "C" int __declspec(dllimport) _nl_msg_cat_cntr;
00174 #endif
00175 
00176 void KCatalogPrivate::setupGettextEnv ()
00177 {
00178   // Point Gettext to current language, recording system value for recovery.
00179   systemLanguage = qgetenv("LANGUAGE");
00180   if (systemLanguage != language) {
00181     // putenv has been called in the constructor,
00182     // it is enough to change the string set there.
00183     snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", language.constData());
00184   }
00185 
00186   // Rebind text domain if language actually changed from the last time,
00187   // as locale directories may differ for different languages of same catalog.
00188   if (language != currentLanguage || !bindDone) {
00189 
00190     currentLanguage = language;
00191     bindDone = true;
00192 
00193     //kDebug() << "bindtextdomain" << name << localeDir;
00194     bindtextdomain(name, localeDir);
00195 
00196     // Magic to make sure Gettext doesn't use stale cached translation
00197     // from previous language.
00198 #ifndef _MSC_VER
00199     extern int _nl_msg_cat_cntr;
00200 #endif
00201     ++_nl_msg_cat_cntr;
00202   }
00203 }
00204 
00205 void KCatalogPrivate::resetSystemLanguage ()
00206 {
00207   if (language != systemLanguage) {
00208     snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", systemLanguage.constData());
00209   }
00210 }
00211 
00212 QString KCatalog::translate(const char * msgid) const
00213 {
00214   QMutexLocker locker(&catalogStaticData->mutex);
00215   d->setupGettextEnv();
00216   const char *msgstr = dgettext(d->name, msgid);
00217   d->resetSystemLanguage();
00218   return QString::fromUtf8(msgstr);
00219 }
00220 
00221 QString KCatalog::translate(const char * msgctxt, const char * msgid) const
00222 {
00223   QMutexLocker locker(&catalogStaticData->mutex);
00224   d->setupGettextEnv();
00225   const char *msgstr = dpgettext_expr(d->name, msgctxt, msgid);
00226   d->resetSystemLanguage();
00227   return QString::fromUtf8(msgstr);
00228 }
00229 
00230 QString KCatalog::translate(const char * msgid, const char * msgid_plural,
00231                             unsigned long n) const
00232 {
00233   QMutexLocker locker(&catalogStaticData->mutex);
00234   d->setupGettextEnv();
00235   const char *msgstr = dngettext(d->name, msgid, msgid_plural, n);
00236   d->resetSystemLanguage();
00237   return QString::fromUtf8(msgstr);
00238 }
00239 
00240 QString KCatalog::translate(const char * msgctxt, const char * msgid,
00241                             const char * msgid_plural, unsigned long n) const
00242 {
00243   QMutexLocker locker(&catalogStaticData->mutex);
00244   d->setupGettextEnv();
00245   const char *msgstr = dnpgettext_expr(d->name, msgctxt, msgid, msgid_plural, n);
00246   d->resetSystemLanguage();
00247   return QString::fromUtf8(msgstr);
00248 }
00249 
00250 QString KCatalog::translateStrict(const char * msgid) const
00251 {
00252   QMutexLocker locker(&catalogStaticData->mutex);
00253   d->setupGettextEnv();
00254   const char *msgstr = dgettext(d->name, msgid);
00255   d->resetSystemLanguage();
00256   return msgstr != msgid ? QString::fromUtf8(msgstr) : QString();
00257 }
00258 
00259 QString KCatalog::translateStrict(const char * msgctxt, const char * msgid) const
00260 {
00261   QMutexLocker locker(&catalogStaticData->mutex);
00262   d->setupGettextEnv();
00263   const char *msgstr = dpgettext_expr(d->name, msgctxt, msgid);
00264   d->resetSystemLanguage();
00265   return msgstr != msgid ? QString::fromUtf8(msgstr) : QString();
00266 }
00267 
00268 QString KCatalog::translateStrict(const char * msgid, const char * msgid_plural,
00269                                   unsigned long n) const
00270 {
00271   QMutexLocker locker(&catalogStaticData->mutex);
00272   d->setupGettextEnv();
00273   const char *msgstr = dngettext(d->name, msgid, msgid_plural, n);
00274   d->resetSystemLanguage();
00275   return msgstr != msgid && msgstr != msgid_plural ? QString::fromUtf8(msgstr) : QString();
00276 }
00277 
00278 QString KCatalog::translateStrict(const char * msgctxt, const char * msgid,
00279                                   const char * msgid_plural, unsigned long n) const
00280 {
00281   QMutexLocker locker(&catalogStaticData->mutex);
00282   d->setupGettextEnv();
00283   const char *msgstr = dnpgettext_expr(d->name, msgctxt, msgid, msgid_plural, n);
00284   d->resetSystemLanguage();
00285   return msgstr != msgid && msgstr != msgid_plural ? QString::fromUtf8(msgstr) : QString();
00286 }
00287 

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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