1
//=============================================================================
3
// File : KviLocale.cpp
4
// Creation date : Fri Mar 19 1999 19:08:41 by Szymon Stefanek
6
// This file is part of the KVIrc irc client distribution
7
// Copyright (C) 1999-2010 Szymon Stefanek (pragma at kvirc dot net)
8
// Copyright (C) 2011 Elvio Basello (hellvis69 at gmail dot com)
10
// This program is FREE software. You can redistribute it and/or
11
// modify it under the terms of the GNU General Public License
12
// as published by the Free Software Foundation; either version 2
13
// of the License, or (at your opinion) any later version.
15
// This program is distributed in the HOPE that it will be USEFUL,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
// See the GNU General Public License for more details.
20
// You should have received a copy of the GNU General Public License
21
// along with this program. If not, write to the Free Software Foundation,
22
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
//=============================================================================
26
#include "kvi_debug.h"
27
#include "kvi_defaults.h"
28
#include "KviMemory.h"
29
#include "KviByteOrder.h"
31
#define _KVI_LOCALE_CPP_
32
#include "KviLocale.h"
33
#include "KviCString.h"
34
#include "KviQString.h"
35
#include "KviEnvironment.h"
36
#include "KviFileUtils.h"
38
#include "KviPointerHashTable.h"
39
#include "KviTranslator.h"
42
#include <QApplication>
49
KVILIB_API KviMessageCatalogue * g_pMainCatalogue = NULL;
51
static KviTranslator * g_pTranslator = NULL;
52
static KviPointerHashTable<const char *,KviMessageCatalogue> * g_pCatalogueDict = NULL;
53
static QTextCodec * g_pUtf8TextCodec = NULL;
54
static QString g_szDefaultLocalePath; // FIXME: Convert this to a search path list
56
/////////////////////////////////////////////////////////////////////////////////////
58
// The following code was extracted and adapted from gutf8.c
59
// from the GNU GLIB2 package.
61
// gutf8.c - Operations on UTF-8 strings.
63
// Copyright (C) 1999 Tom Tromey
64
// Copyright (C) 2000 Red Hat, Inc.
66
// This library is free software; you can redistribute it and/or
67
// modify it under the terms of the GNU Lesser General Public
68
// License as published by the Free Software Foundation; either
69
// version 2 of the License, or (at your option) any later version.
71
// This library is distributed in the hope that it will be useful,
72
// but WITHOUT ANY WARRANTY; without even the implied warranty of
73
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74
// Lesser General Public License for more details.
76
// You should have received a copy of the GNU Lesser General Public
77
// License along with this library; if not, write to the
78
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
79
// Boston, MA 02111-1307, USA.
81
/////////////////////////////////////////////////////////////////////////////////////
84
#define UNICODE_VALID(Char) \
85
((Char) < 0x110000 && \
86
(((Char) & 0xFFFFF800) != 0xD800) && \
87
((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
88
((Char) & 0xFFFE) != 0xFFFE)
90
#define CONTINUATION_CHAR \
91
if ((*(unsigned char *)p & 0xc0) != 0x80) /* 10xxxxxx */ \
94
val |= (*(unsigned char *)p) & 0x3f;
97
static const char * fast_validate (const char *str)
100
unsigned int min = 0;
103
for (p = str; *p; p++)
105
if (*(unsigned char *)p < 128)
112
if ((*(unsigned char *)p & 0xe0) == 0xc0) /* 110xxxxx */
114
if ((*(unsigned char *)p & 0x1e) == 0)
117
if ((*(unsigned char *)p & 0xc0) != 0x80) /* 10xxxxxx */
122
if ((*(unsigned char *)p & 0xf0) == 0xe0) /* 1110xxxx */
125
val = *(unsigned char *)p & 0x0f;
128
else if ((*(unsigned char *)p & 0xf8) == 0xf0) /* 11110xxx */
131
val = *(unsigned char *)p & 0x07;
143
if (val < min) goto error;
145
if (!UNICODE_VALID(val)) goto error;
158
static const char * fast_validate_len (const char *str, int max_len)
160
unsigned int val = 0;
161
unsigned int min = 0;
164
for (p = str; (max_len < 0 || (p - str) < max_len) && *p; p++)
166
if (*(unsigned char *)p < 128)
173
if ((*(unsigned char *)p & 0xe0) == 0xc0) /* 110xxxxx */
175
if (max_len >= 0 && max_len - (p - str) < 2)
178
if ((*(unsigned char *)p & 0x1e) == 0)
181
if ((*(unsigned char *)p & 0xc0) != 0x80) /* 10xxxxxx */
186
if ((*(unsigned char *)p & 0xf0) == 0xe0) /* 1110xxxx */
188
if (max_len >= 0 && max_len - (p - str) < 3)
192
val = *(unsigned char *)p & 0x0f;
195
else if ((*(unsigned char *)p & 0xf8) == 0xf0) /* 11110xxx */
197
if (max_len >= 0 && max_len - (p - str) < 4)
201
val = *(unsigned char *)p & 0x07;
214
if (val < min) goto error;
215
if (!UNICODE_VALID(val)) goto error;
228
static bool g_utf8_validate(const char *str,int max_len,const char **end)
233
p = fast_validate (str);
235
p = fast_validate_len (str, max_len);
239
if ((max_len >= 0 && p != str + max_len) ||
240
(max_len < 0 && *p != '\0'))
246
/////////////////////////////////////////////////////////////////////////////////////
248
/////////////////////////////////////////////////////////////////////////////////////
250
class KviSmartTextCodec : public QTextCodec
254
QTextCodec * m_pRecvCodec;
255
QTextCodec * m_pSendCodec;
257
KviSmartTextCodec(const char * szName,QTextCodec * pChildCodec,bool bSendInUtf8)
260
Q_ASSERT(pChildCodec);
262
m_pRecvCodec = pChildCodec;
265
if(!g_pUtf8TextCodec)
267
g_pUtf8TextCodec = QTextCodec::codecForName("UTF-8");
268
if(!g_pUtf8TextCodec)
270
qDebug("Can't find the global utf8 text codec!");
271
g_pUtf8TextCodec = QTextCodec::codecForLocale(); // try anything else...
272
if(!g_pUtf8TextCodec)
273
qDebug("Aargh.. got no UTF-8 text codec: we're in trouble.");
277
m_pSendCodec = bSendInUtf8 ? g_pUtf8TextCodec : pChildCodec;
280
bool ok(){ return m_pRecvCodec && g_pUtf8TextCodec; };
282
virtual int mibEnum () const { return 0; };
284
virtual QByteArray name() const { return m_szName; };
286
virtual QByteArray convertFromUnicode(const QChar * input,int number,ConverterState * state) const
288
return m_pSendCodec->fromUnicode(input,number,state);
290
virtual QString convertToUnicode(const char * chars,int len,ConverterState * state) const
292
if(g_utf8_validate(chars,len,NULL))
293
return g_pUtf8TextCodec->toUnicode(chars,len,state);
295
return m_pRecvCodec->toUnicode(chars,len,state);
299
static KviPointerHashTable<const char *,KviSmartTextCodec> * g_pSmartCodecDict = 0;
301
static const char * encoding_groups[] =
308
#ifndef QT_NO_BIG_CODECS
316
static KviLocale::EncodingDescription supported_encodings[] =
319
{ "UTF-8" , 0 , 0 , 0, "8-bit Unicode" },
321
{ "ISO-8859-1" , 0 , 0 , 1, "Western, Latin-1" },
322
{ "ISO-8859-15" , 0 , 0 , 1, "Western, Latin-1 + Euro" },
323
{ "IBM-850" , 0 , 0 , 1, "IBM-850" },
324
{ "CP-1252" , 0 , 0 , 1, "Western Codepage" },
325
{ "ISO-8859-14" , 0 , 0 , 1, "Celtic" },
326
{ "ISO-8859-7" , 0 , 0 , 1, "Greek" },
327
{ "CP-1253" , 0 , 0 , 1, "Greek Codepage" },
328
{ "ISO-8859-10" , 0 , 0 , 1, "Nordic" },
329
{ "ISO-8859-3" , 0 , 0 , 1, "South European" },
331
{ "ISO-8859-4" , 0 , 0 , 2, "Baltic, Standard" },
332
{ "ISO-8859-13" , 0 , 0 , 2, "Baltic" },
333
{ "CP-1257" , 0 , 0 , 2, "Baltic Codepage" },
334
{ "ISO-8859-2" , 0 , 0 , 2, "Central European" },
335
{ "CP-1250" , 0 , 0 , 2, "Central European Codepage" },
336
{ "ISO-8859-9" , 0 , 0 , 2, "Turkish, Latin-5" },
337
{ "CP-1254" , 0 , 0 , 2, "Turkish Codepage" },
339
{ "ISO-8859-5" , 0 , 0 , 3, "Cyrillic, ISO" },
340
{ "CP-1251" , 0 , 0 , 3, "Cyrillic Codepage" },
341
{ "KOI8-R" , 0 , 0 , 3, "Cyrillic, KOI" },
342
{ "KOI8-U" , 0 , 0 , 3, "Cyrillic/Ukrainian" },
343
{ "IBM-866" , 0 , 0 , 3, "IBM-866" },
345
{ "ISO-8859-6" , 0 , 0 , 4, "Arabic, Standard" },
346
{ "CP-1256" , 0 , 0 , 4, "Arabic Codepage" },
347
{ "ISO-8859-8" , 0 , 0 , 4, "Hebrew, visually ordered" },
348
{ "ISO-8859-8-i" , 0 , 0 , 4, "Hebrew, logically ordered" },
349
{ "CP-1255" , 0 , 0 , 4, "Hebrew Codepage" },
351
{ "TIS-620" , 0 , 0 , 7, "Thai" },
352
{ "CP874" , 0 , 0 , 7, "Thai Codepage" },
353
#ifndef QT_NO_BIG_CODECS
355
{ "Big5" , 0 , 0 , 5, "Chinese Traditional" },
356
{ "Big5-HKSCS" , 0 , 0 , 5, "Chinese Traditional, Hong Kong" },
357
{ "GB18030" , 0 , 0 , 5, "Chinese Simplified" },
359
{ "JIS7" , 0 , 0 , 6, "Japanese (JIS7)" },
360
{ "Shift-JIS" , 0 , 0 , 6, "Japanese (Shift-JIS)" },
361
{ "EUC-JP" , 0 , 0 , 6, "Japanese (EUC-JP)" },
363
{ "EUC-KR" , 0 , 0 , 7, "Korean" },
364
{ "TSCII" , 0 , 0 , 7, "Tamil" },
367
// smart codecs that send in the local charset
369
{ "ISO-8859-1 [UTF-8]" , 1 , 0 , 1, "Western, Latin-1 - Unicode" },
370
{ "ISO-8859-15 [UTF-8]" , 1 , 0 , 1, "Western, Latin-1 + Euro - Unicode" },
371
{ "IBM-850 [UTF-8]" , 1 , 0 , 1, "IBM-850 - Unicode" },
372
{ "CP-1252 [UTF-8]" , 1 , 0 , 1, "Western Codepage - Unicode" },
373
{ "ISO-8859-14 [UTF-8]" , 1 , 0 , 1, "Celtic - Unicode" },
374
{ "ISO-8859-7 [UTF-8]" , 1 , 0 , 1, "Greek - Unicode" },
375
{ "CP-1253 [UTF-8]" , 1 , 0 , 1, "Greek Codepage - Unicode" },
376
{ "ISO-8859-10 [UTF-8]" , 1 , 0 , 1, "Nordic - Unicode" },
377
{ "ISO-8859-3 [UTF-8]" , 1 , 0 , 1, "South European - Unicode" },
379
{ "ISO-8859-4 [UTF-8]" , 1 , 0 , 2, "Baltic, Standard - Unicode" },
380
{ "ISO-8859-13 [UTF-8]" , 1 , 0 , 2, "Baltic - Unicode" },
381
{ "CP-1257 [UTF-8]" , 1 , 0 , 2, "Baltic Codepage - Unicode" },
382
{ "ISO-8859-2 [UTF-8]" , 1 , 0 , 2, "Central European - Unicode" },
383
{ "CP-1250 [UTF-8]" , 1 , 0 , 2, "Central European Codepage - Unicode" },
384
{ "ISO-8859-9 [UTF-8]" , 1 , 0 , 2, "Turkish, Latin-5 - Unicode" },
385
{ "CP-1254 [UTF-8]" , 1 , 0 , 2, "Turkish Codepage - Unicode" },
387
{ "ISO-8859-5 [UTF-8]" , 1 , 0 , 3, "Cyrillic, ISO - Unicode" },
388
{ "CP-1251 [UTF-8]" , 1 , 0 , 3, "Cyrillic Codepage - Unicode" },
389
{ "KOI8-R [UTF-8]" , 1 , 0 , 3, "Cyrillic, KOI - Unicode" },
390
{ "KOI8-U [UTF-8]" , 1 , 0 , 3, "Cyrillic/Ukrainian - Unicode" },
391
{ "IBM-866 [UTF-8]" , 1 , 0 , 3, "IBM-866 - Unicode" },
393
{ "ISO-8859-6 [UTF-8]" , 1 , 0 , 4, "Arabic, Standard - Unicode" },
394
{ "CP-1256 [UTF-8]" , 1 , 0 , 4, "Arabic Codepage - Unicode" },
395
{ "ISO-8859-8 [UTF-8]" , 1 , 0 , 4, "Hebrew, visually ordered - Unicode" },
396
{ "ISO-8859-8-i [UTF-8]" , 1 , 0 , 4, "Hebrew, logically ordered - Unicode" },
397
{ "CP-1255 [UTF-8]" , 1 , 0 , 4, "Hebrew Codepage - Unicode" },
399
{ "TIS-620 [UTF-8]" , 1 , 0 , 7, "Thai - Unicode" },
400
{ "CP874 [UTF-8]" , 1 , 0 , 7, "Thai Codepage - Unicode" },
401
#ifndef QT_NO_BIG_CODECS
403
{ "Big5 [UTF-8]" , 1 , 0 , 5, "Chinese Traditional - Unicode" },
404
{ "Big5-HKSCS [UTF-8]" , 1 , 0 , 5, "Chinese Traditional, Hong Kong - Unicode" },
405
{ "GB18030 [UTF-8]" , 1 , 0 , 5, "Chinese Simplified - Unicode" },
407
{ "JIS7 [UTF-8]" , 1 , 0 , 6, "Japanese (JIS7) - Unicode" },
408
{ "Shift-JIS [UTF-8]" , 1 , 0 , 6, "Japanese (Shift-JIS) - Unicode" },
409
{ "EUC-JP [UTF-8]" , 1 , 0 , 6, "Japanese (EUC-JP) - Unicode" },
411
{ "EUC-KR [UTF-8]" , 1 , 0 , 7, "Korean - Unicode" },
412
{ "TSCII [UTF-8]" , 1 , 0 , 7, "Tamil - Unicode" },
415
// smart codecs that send in utf8
417
{ "UTF-8 [ISO-8859-1]" , 1 , 1 , 1, "Unicode - Western, Latin-1" },
418
{ "UTF-8 [ISO-8859-15]" , 1 , 1 , 1, "Unicode - Western, Latin-1 + Euro" },
419
{ "UTF-8 [IBM-850]" , 1 , 1 , 1, "Unicode - IBM-850" },
420
{ "UTF-8 [CP-1252]" , 1 , 1 , 1, "Unicode - Western Codepage" },
421
{ "UTF-8 [ISO-8859-14]" , 1 , 1 , 1, "Unicode - Celtic" },
422
{ "UTF-8 [ISO-8859-7]" , 1 , 1 , 1, "Unicode - Greek" },
423
{ "UTF-8 [CP-1253]" , 1 , 1 , 1, "Unicode - Greek Codepage" },
424
{ "UTF-8 [ISO-8859-10]" , 1 , 1 , 1, "Unicode - Nordic" },
425
{ "UTF-8 [ISO-8859-3]" , 1 , 1 , 1, "Unicode - South European" },
427
{ "UTF-8 [ISO-8859-4]" , 1 , 1 , 2, "Unicode - Baltic, Standard" },
428
{ "UTF-8 [ISO-8859-13]" , 1 , 1 , 2, "Unicode - Baltic" },
429
{ "UTF-8 [CP-1257]" , 1 , 1 , 2, "Unicode - Baltic Codepage" },
430
{ "UTF-8 [ISO-8859-2]" , 1 , 1 , 2, "Unicode - Central European" },
431
{ "UTF-8 [CP-1250]" , 1 , 1 , 2, "Unicode - Central European Codepage" },
432
{ "UTF-8 [ISO-8859-9]" , 1 , 1 , 2, "Unicode - Turkish, Latin-5" },
433
{ "UTF-8 [CP-1254]" , 1 , 1 , 2, "Unicode - Turkish Codepage" },
435
{ "UTF-8 [ISO-8859-5]" , 1 , 1 , 3, "Unicode - Cyrillic, ISO" },
436
{ "UTF-8 [CP-1251]" , 1 , 1 , 3, "Unicode - Cyrillic Codepage" },
437
{ "UTF-8 [KOI8-R]" , 1 , 1 , 3, "Unicode - Cyrillic, KOI" },
438
{ "UTF-8 [KOI8-U]" , 1 , 1 , 3, "Unicode - Cyrillic/Ukrainian" },
439
{ "UTF-8 [IBM-866]" , 1 , 1 , 3, "Unicode - IBM-866" },
441
{ "UTF-8 [ISO-8859-6]" , 1 , 1 , 4, "Unicode - Arabic, Standard" },
442
{ "UTF-8 [CP-1256]" , 1 , 1 , 4, "Unicode - Arabic Codepage" },
443
{ "UTF-8 [ISO-8859-8]" , 1 , 1 , 4, "Unicode - Hebrew, visually ordered" },
444
{ "UTF-8 [ISO-8859-8-i]" , 1 , 1 , 4, "Unicode - Hebrew, logically ordered" },
445
{ "UTF-8 [CP-1255]" , 1 , 1 , 4, "Unicode - Hebrew Codepage" },
447
{ "UTF-8 [TIS-620]" , 1 , 1 , 7, "Unicode - Thai" },
448
{ "UTF-8 [CP874]" , 1 , 1 , 7, "Unicode - Thai Codepage" },
449
#ifndef QT_NO_BIG_CODECS
451
{ "UTF-8 [Big5]" , 1 , 1 , 5, "Unicode - Chinese Traditional" },
452
{ "UTF-8 [Big5-HKSCS]" , 1 , 1 , 5, "Unicode - Chinese Traditional, Hong Kong" },
453
{ "UTF-8 [GB18030]" , 1 , 1 , 5, "Unicode - Chinese Simplified" },
455
{ "UTF-8 [JIS7]" , 1 , 1 , 6, "Unicode - Japanese (JIS7)" },
456
{ "UTF-8 [Shift-JIS]" , 1 , 1 , 6, "Unicode - Japanese (Shift-JIS)" },
457
{ "UTF-8 [EUC-JP]" , 1 , 1 , 6, "Unicode - Japanese (EUC-JP)" },
459
{ "UTF-8 [EUC-KR]" , 1 , 1 , 7, "Unicode - Korean" },
460
{ "UTF-8 [TSCII]" , 1 , 1 , 7, "Unicode - Tamil" },
462
{ 0 , 0 , 0 , 0 , 0 }
465
KviLocale * KviLocale::m_pSelf = NULL;
466
unsigned int KviLocale::m_uCount = 0;
467
KviCString KviLocale::g_szLang = "";
469
KviLocale::KviLocale(QApplication * pApp, const QString & szLocaleDir, const QString & szForceLocaleDir)
473
// first of all try to find out the current locale
474
QString szLangFile = QString("%1/%2").arg(szForceLocaleDir, KVI_FORCE_LOCALE_FILE_NAME);
476
if(KviFileUtils::fileExists(szLangFile))
479
KviFileUtils::readFile(szLangFile,szTmp);
482
if(g_szLang.isEmpty())
483
g_szLang = KviEnvironment::getVariable("KVIRC_LANG");
484
#ifdef COMPILE_KDE_SUPPORT
485
if(g_szLang.isEmpty())
486
g_szLang = KviEnvironment::getVariable("KDE_LANG");
487
#endif //COMPILE_KDE_SUPPORT
488
if(g_szLang.isEmpty())
489
g_szLang = KviEnvironment::getVariable("LC_MESSAGES");
490
if(g_szLang.isEmpty())
491
g_szLang = KviEnvironment::getVariable("LANG");
492
if(g_szLang.isEmpty())
493
g_szLang = QLocale::system().name();
494
if(g_szLang.isEmpty())
498
g_szDefaultLocalePath = szLocaleDir;
500
// the main catalogue is supposed to be kvirc_<language>.mo
501
g_pMainCatalogue = new KviMessageCatalogue();
502
// the catalogue dict
503
g_pCatalogueDict = new KviPointerHashTable<const char *,KviMessageCatalogue>;
504
g_pCatalogueDict->setAutoDelete(true);
506
// the smart codec dict
507
g_pSmartCodecDict = new KviPointerHashTable<const char *,KviSmartTextCodec>;
508
// the Qt docs explicitly state that we shouldn't delete
509
// the codecs by ourselves...
510
g_pSmartCodecDict->setAutoDelete(false);
512
if(g_szLang.hasData())
515
if(findCatalogue(szBuffer,"kvirc",szLocaleDir))
517
g_pMainCatalogue->load(szBuffer);
518
g_pTranslator = new KviTranslator(m_pApp);
519
m_pApp->installTranslator(g_pTranslator);
521
KviCString szTmp = g_szLang;
522
szTmp.cutFromFirst('.');
523
szTmp.cutFromFirst('_');
524
szTmp.cutFromFirst('@');
526
if(!(kvi_strEqualCI(szTmp.ptr(),"en") ||
527
kvi_strEqualCI(szTmp.ptr(),"c") ||
528
kvi_strEqualCI(szTmp.ptr(),"us") ||
529
kvi_strEqualCI(szTmp.ptr(),"gb") ||
530
kvi_strEqualCI(szTmp.ptr(),"posix")))
532
// FIXME: THIS IS NO LONGER VALID!!!
533
qDebug("Can't find the catalogue for locale \"%s\" (%s)",g_szLang.ptr(),szTmp.ptr());
534
qDebug("There is no such translation or the $LANG variable was incorrectly set");
535
qDebug("You can use $KVIRC_LANG to override the catalogue name");
536
qDebug("For example you can set KVIRC_LANG to it_IT to force usage of the it.mo catalogue");
541
//g_pTextCodec = QTextCodec::codecForLocale();
543
// g_pTextCodec = QTextCodec::codecForLocale();
546
KviLocale::~KviLocale()
548
delete g_pMainCatalogue;
549
delete g_pCatalogueDict;
550
delete g_pSmartCodecDict;
551
g_pMainCatalogue = 0;
552
g_pCatalogueDict = 0;
553
g_pSmartCodecDict = 0;
556
m_pApp->removeTranslator(g_pTranslator);
557
delete g_pTranslator;
562
void KviLocale::init(QApplication * pApp, const QString & szLocaleDir, const QString & szForceLocaleDir)
564
if((!m_pSelf) && (m_pSelf->count() == 0))
566
m_pSelf = new KviLocale(pApp,szLocaleDir,szForceLocaleDir);
571
void KviLocale::done()
574
if(m_pSelf->count() == 0)
578
QTextCodec * KviLocale::codecForName(const char * pcName)
580
KviCString szTmp = pcName;
583
int iIdx = szTmp.findFirstIdx('[');
586
// Might be a composite codec: either UTF-8 [child codec] or child codec [UTF-8]
587
KviSmartTextCodec * pCodec = g_pSmartCodecDict->find(pcName);
589
return pCodec; // got cached copy
591
if(kvi_strEqualCIN("UTF-8 [",pcName,7))
593
// Likely a smart codec that sends UTF-8
594
szTmp.replaceAll("UTF-8 [","");
595
szTmp.replaceAll("]","");
598
// Likely a smart codec that sends child encoding ?
599
szTmp.cutFromFirst(' ');
603
QTextCodec * pChildCodec = QTextCodec::codecForName(szTmp.ptr());
606
pCodec = new KviSmartTextCodec(pcName,pChildCodec,bSendUtf8);
610
g_pSmartCodecDict->replace(pcName,pCodec);
616
// The name of the child codec was invalid: can't create such a smart codec.
617
// We probably screwed up the guess above related to the [ char.
618
// This code path is also triggered by the yircfuzzer by specifying completly invalid codec names.
622
return QTextCodec::codecForName(pcName);
625
bool KviLocale::findCatalogue(QString & szBuffer, const QString & szName,const QString & szLocaleDir)
627
KviCString szLocale = g_szLang;
629
QString szLocDir = szLocaleDir;
630
KviQString::ensureLastCharIs(szLocDir,KVI_PATH_SEPARATOR_CHAR);
632
szBuffer = QString("%1%2_%3.mo").arg(szLocDir,szName).arg(szLocale.ptr());
634
if(KviFileUtils::fileExists(szBuffer))
637
if(szLocale.findFirstIdx('.') != -1)
639
// things like en_GB.utf8
641
szLocale.cutFromFirst('.');
643
szBuffer = QString("%1%2_%3.mo").arg(szLocDir,szName).arg(szLocale.ptr());
644
if(KviFileUtils::fileExists(szBuffer))
648
if(szLocale.findFirstIdx('@') != -1)
650
// things like @euro ?
652
szLocale.cutFromFirst('@');
653
szBuffer = QString("%1%2_%3.mo").arg(szLocDir,szName).arg(szLocale.ptr());
654
if(KviFileUtils::fileExists(szBuffer))
658
if(szLocale.findFirstIdx('_') != -1)
662
szLocale.cutFromFirst('_');
663
szBuffer = QString("%1%2_%3.mo").arg(szLocDir,szName).arg(szLocale.ptr());
664
if(KviFileUtils::fileExists(szBuffer))
668
// try the lower case version too
670
szBuffer = QString("%1%2_%3.mo").arg(szLocDir,szName).arg(szLocale.ptr());
671
if(KviFileUtils::fileExists(szBuffer))
677
KviMessageCatalogue * KviLocale::loadCatalogue(const QString & szName, const QString & szLocaleDir)
679
//qDebug("Looking up catalogue %s",szName.toUtf8().data());
682
KviMessageCatalogue * pCatalogue = g_pCatalogueDict->find(szName.toUtf8().data());
684
return pCatalogue; // already loaded
686
if(!findCatalogue(szBuffer,szName,szLocaleDir))
689
pCatalogue = new KviMessageCatalogue();
690
if(pCatalogue->load(szBuffer))
692
g_pCatalogueDict->insert(szName.toUtf8().data(),pCatalogue);
699
bool KviLocale::unloadCatalogue(const QString & szName)
701
//qDebug("Unloading catalogue: %s",szName.toUtf8().data());
702
return g_pCatalogueDict->remove(szName.toUtf8().data());
705
KviMessageCatalogue * KviLocale::getLoadedCatalogue(const QString & szName)
707
return g_pCatalogueDict->find(szName.toUtf8().data());
710
const char * KviLocale::encodingGroup(int iIdx)
712
if(iIdx > KVI_NUM_ENCODING_GROUPS)
713
return encoding_groups[KVI_NUM_ENCODING_GROUPS];
714
return encoding_groups[iIdx];
717
KviLocale::EncodingDescription * KviLocale::encodingDescription(int iIdx)
719
if(iIdx > KVI_NUM_ENCODINGS)
720
return &(supported_encodings[KVI_NUM_ENCODINGS]);
721
return &(supported_encodings[iIdx]);
724
const char * KviLocale::translate(const char * pcText, const char * pcContext)
727
return g_pMainCatalogue->translate(pcText);
729
KviMessageCatalogue * pCatalogue = g_pCatalogueDict->find(pcContext);
732
pCatalogue = loadCatalogue(QString::fromUtf8(pcContext),g_szDefaultLocalePath);
736
pCatalogue = new KviMessageCatalogue();
737
g_pCatalogueDict->insert(pcContext,pCatalogue);
740
return pCatalogue->translate(pcText);
743
const QString & KviLocale::translateToQString(const char * pcText, const char * pcContext)
746
return g_pMainCatalogue->translateToQString(pcText);
748
KviMessageCatalogue * pCatalogue = g_pCatalogueDict->find(pcContext);
751
pCatalogue = loadCatalogue(QString::fromUtf8(pcContext),g_szDefaultLocalePath);
755
pCatalogue = new KviMessageCatalogue();
756
g_pCatalogueDict->insert(pcContext,pCatalogue);
759
return pCatalogue->translateToQString(pcText);