• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • localization
kcatalog.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (c) 2001 Hans Petter Bieker <bieker@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "kcatalog_p.h"
21#include "kstandarddirs.h"
22
23#include <config.h>
24
25#include <QtCore/QFile>
26#include <QMutexLocker>
27
28#include <kdebug.h>
29
30#include <stdlib.h>
31#include <locale.h>
32#include "gettext.h"
33
34
35static bool s_localeSet = false;
36
37// Initialize the locale very early during application startup
38// This is necessary for e.g. toLocal8Bit() to work, even before
39// a Q[Core]Application exists (David)
40int kInitializeLocale()
41{
42#ifndef _WIN32_WCE
43 setlocale(LC_ALL, "");
44#endif
45 extern Q_CORE_EXPORT bool qt_locale_initialized; // in Qt since 4.5.0
46 qt_locale_initialized = true; // as recommended by Thiago
47 s_localeSet = true;
48 return 1;
49}
50Q_CONSTRUCTOR_FUNCTION(kInitializeLocale)
51
52// not defined on win32 :(
53#ifdef _WIN32
54# ifndef LC_MESSAGES
55# define LC_MESSAGES 42
56# endif
57#endif
58
59static char *langenv = 0;
60static const int langenvMaxlen = 42;
61// = "LANGUAGE=" + 32 chars for language code + terminating zero
62
63class KCatalogStaticData
64{
65public:
66 KCatalogStaticData() {}
67
68 QMutex mutex;
69};
70
71K_GLOBAL_STATIC(KCatalogStaticData, catalogStaticData)
72
73class KCatalogPrivate
74{
75public:
76 KCatalogPrivate()
77 : bindDone(false)
78 {}
79
80 QByteArray language;
81 QByteArray name;
82 QByteArray localeDir;
83
84 QByteArray systemLanguage;
85 bool bindDone;
86
87 static QByteArray currentLanguage;
88
89 void setupGettextEnv ();
90 void resetSystemLanguage ();
91};
92
93QDebug operator<<(QDebug debug, const KCatalog &c)
94{
95 return debug << c.d->language << " " << c.d->name << " " << c.d->localeDir;
96}
97
98QByteArray KCatalogPrivate::currentLanguage;
99
100KCatalog::KCatalog(const QString & name, const QString & language )
101 : d( new KCatalogPrivate )
102{
103 // Set locales if the static initializer didn't work
104 if (!s_localeSet) {
105 kInitializeLocale();
106 }
107
108 // Find locale directory for this catalog.
109 QString localeDir = catalogLocaleDir( name, language );
110
111 d->language = QFile::encodeName( language );
112 d->name = QFile::encodeName( name );
113 d->localeDir = QFile::encodeName( localeDir );
114
115 // Always get translations in UTF-8, regardless of user's environment.
116 bind_textdomain_codeset( d->name, "UTF-8" );
117
118 // Invalidate current language, to trigger binding at next translate call.
119 KCatalogPrivate::currentLanguage.clear();
120
121 if (!langenv) {
122 // Call putenv only here, to initialize LANGUAGE variable.
123 // Later only change langenv to what is currently needed.
124 langenv = new char[langenvMaxlen];
125 QByteArray lang = qgetenv("LANGUAGE");
126 snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", lang.constData());
127 putenv(langenv);
128 }
129}
130
131KCatalog::KCatalog(const KCatalog & rhs)
132 : d( new KCatalogPrivate )
133{
134 *this = rhs;
135}
136
137KCatalog & KCatalog::operator=(const KCatalog & rhs)
138{
139 *d = *rhs.d;
140
141 return *this;
142}
143
144KCatalog::~KCatalog()
145{
146 delete d;
147}
148
149QString KCatalog::catalogLocaleDir( const QString &name,
150 const QString &language )
151{
152 QString relpath = QString::fromLatin1( "%1/LC_MESSAGES/%2.mo" )
153 .arg( language ).arg( name );
154 return KGlobal::dirs()->findResourceDir( "locale", relpath );
155}
156
157QString KCatalog::name() const
158{
159 return QFile::decodeName(d->name);
160}
161
162QString KCatalog::language() const
163{
164 return QFile::decodeName(d->language);
165}
166
167QString KCatalog::localeDir() const
168{
169 return QFile::decodeName(d->localeDir);
170}
171
172#ifdef Q_WS_WIN
173 extern "C" int __declspec(dllimport) _nl_msg_cat_cntr;
174#endif
175
176void KCatalogPrivate::setupGettextEnv ()
177{
178 // Point Gettext to current language, recording system value for recovery.
179 systemLanguage = qgetenv("LANGUAGE");
180 if (systemLanguage != language) {
181 // putenv has been called in the constructor,
182 // it is enough to change the string set there.
183 snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", language.constData());
184 }
185
186 // Rebind text domain if language actually changed from the last time,
187 // as locale directories may differ for different languages of same catalog.
188 if (language != currentLanguage || !bindDone) {
189
190 currentLanguage = language;
191 bindDone = true;
192
193 //kDebug() << "bindtextdomain" << name << localeDir;
194 bindtextdomain(name, localeDir);
195
196 // Magic to make sure Gettext doesn't use stale cached translation
197 // from previous language.
198#ifndef _MSC_VER
199 extern int _nl_msg_cat_cntr;
200#endif
201 ++_nl_msg_cat_cntr;
202 }
203}
204
205void KCatalogPrivate::resetSystemLanguage ()
206{
207 if (language != systemLanguage) {
208 snprintf(langenv, langenvMaxlen, "LANGUAGE=%s", systemLanguage.constData());
209 }
210}
211
212QString KCatalog::translate(const char * msgid) const
213{
214 QMutexLocker locker(&catalogStaticData->mutex);
215 d->setupGettextEnv();
216 const char *msgstr = dgettext(d->name, msgid);
217 d->resetSystemLanguage();
218 return QString::fromUtf8(msgstr);
219}
220
221QString KCatalog::translate(const char * msgctxt, const char * msgid) const
222{
223 QMutexLocker locker(&catalogStaticData->mutex);
224 d->setupGettextEnv();
225 const char *msgstr = dpgettext_expr(d->name, msgctxt, msgid);
226 d->resetSystemLanguage();
227 return QString::fromUtf8(msgstr);
228}
229
230QString KCatalog::translate(const char * msgid, const char * msgid_plural,
231 unsigned long n) const
232{
233 QMutexLocker locker(&catalogStaticData->mutex);
234 d->setupGettextEnv();
235 const char *msgstr = dngettext(d->name, msgid, msgid_plural, n);
236 d->resetSystemLanguage();
237 return QString::fromUtf8(msgstr);
238}
239
240QString KCatalog::translate(const char * msgctxt, const char * msgid,
241 const char * msgid_plural, unsigned long n) const
242{
243 QMutexLocker locker(&catalogStaticData->mutex);
244 d->setupGettextEnv();
245 const char *msgstr = dnpgettext_expr(d->name, msgctxt, msgid, msgid_plural, n);
246 d->resetSystemLanguage();
247 return QString::fromUtf8(msgstr);
248}
249
250QString KCatalog::translateStrict(const char * msgid) const
251{
252 QMutexLocker locker(&catalogStaticData->mutex);
253 d->setupGettextEnv();
254 const char *msgstr = dgettext(d->name, msgid);
255 d->resetSystemLanguage();
256 return msgstr != msgid ? QString::fromUtf8(msgstr) : QString();
257}
258
259QString KCatalog::translateStrict(const char * msgctxt, const char * msgid) const
260{
261 QMutexLocker locker(&catalogStaticData->mutex);
262 d->setupGettextEnv();
263 const char *msgstr = dpgettext_expr(d->name, msgctxt, msgid);
264 d->resetSystemLanguage();
265 return msgstr != msgid ? QString::fromUtf8(msgstr) : QString();
266}
267
268QString KCatalog::translateStrict(const char * msgid, const char * msgid_plural,
269 unsigned long n) const
270{
271 QMutexLocker locker(&catalogStaticData->mutex);
272 d->setupGettextEnv();
273 const char *msgstr = dngettext(d->name, msgid, msgid_plural, n);
274 d->resetSystemLanguage();
275 return msgstr != msgid && msgstr != msgid_plural ? QString::fromUtf8(msgstr) : QString();
276}
277
278QString KCatalog::translateStrict(const char * msgctxt, const char * msgid,
279 const char * msgid_plural, unsigned long n) const
280{
281 QMutexLocker locker(&catalogStaticData->mutex);
282 d->setupGettextEnv();
283 const char *msgstr = dnpgettext_expr(d->name, msgctxt, msgid, msgid_plural, n);
284 d->resetSystemLanguage();
285 return msgstr != msgid && msgstr != msgid_plural ? QString::fromUtf8(msgstr) : QString();
286}
287
KCatalog
This class abstracts a gettext message catalog.
Definition: kcatalog_p.h:36
KCatalog::name
QString name() const
Returns the name of the catalog.
Definition: kcatalog.cpp:157
KCatalog::KCatalog
KCatalog(const QString &name, const QString &language)
Constructor.
Definition: kcatalog.cpp:100
KCatalog::translateStrict
QString translateStrict(const char *msgid) const
Retrieves a translation of the specified message id, returning empty if the translation was not found...
Definition: kcatalog.cpp:250
KCatalog::language
QString language() const
Returns the language of the catalog.
Definition: kcatalog.cpp:162
KCatalog::localeDir
QString localeDir() const
Returns locale directory of the catalog.
Definition: kcatalog.cpp:167
KCatalog::~KCatalog
virtual ~KCatalog()
Destructor.
Definition: kcatalog.cpp:144
KCatalog::catalogLocaleDir
static QString catalogLocaleDir(const QString &name, const QString &language)
Finds the locale directory for the given catalog in given language.
Definition: kcatalog.cpp:149
KCatalog::translate
QString translate(const char *msgid) const
Retrieves a translation of the specified message id.
Definition: kcatalog.cpp:212
KCatalog::operator=
KCatalog & operator=(const KCatalog &rhs)
Assignment operator.
Definition: kcatalog.cpp:137
KStandardDirs::findResourceDir
QString findResourceDir(const char *type, const QString &filename) const
Tries to find the directory the file is in.
Definition: kstandarddirs.cpp:553
QString
gettext.h
dngettext
#define dngettext(Domainname, Msgid1, Msgid2, N)
Definition: gettext.h:72
dpgettext_expr
#define dpgettext_expr(Domainname, Msgctxt, Msgid)
Definition: gettext.h:176
dnpgettext_expr
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N)
Definition: gettext.h:221
dgettext
#define dgettext(Domainname, Msgid)
Definition: gettext.h:68
bind_textdomain_codeset
#define bind_textdomain_codeset(Domainname, Codeset)
Definition: gettext.h:78
bindtextdomain
#define bindtextdomain(Domainname, Dirname)
Definition: gettext.h:77
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
Definition: kglobal.h:221
langenvMaxlen
static const int langenvMaxlen
Definition: kcatalog.cpp:60
langenv
static char * langenv
Definition: kcatalog.cpp:59
__declspec
int __declspec(dllimport) _nl_msg_cat_cntr
operator<<
QDebug operator<<(QDebug debug, const KCatalog &c)
Definition: kcatalog.cpp:93
kInitializeLocale
int kInitializeLocale()
Definition: kcatalog.cpp:40
s_localeSet
static bool s_localeSet
Definition: kcatalog.cpp:35
kcatalog_p.h
kdebug.h
kstandarddirs.h
KGlobal::dirs
KStandardDirs * dirs()
Returns the application standard dirs object.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

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

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal