summaryrefslogtreecommitdiffstats
path: root/src/kvilib/system/kvi_locale.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kvilib/system/kvi_locale.cpp')
-rw-r--r--src/kvilib/system/kvi_locale.cpp1191
1 files changed, 1191 insertions, 0 deletions
diff --git a/src/kvilib/system/kvi_locale.cpp b/src/kvilib/system/kvi_locale.cpp
new file mode 100644
index 00000000..f49eabe4
--- /dev/null
+++ b/src/kvilib/system/kvi_locale.cpp
@@ -0,0 +1,1191 @@
+//=============================================================================
+//
+// File : kvi_locale.cpp
+// Creation date : Fri Mar 19 1999 19:08:41 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVILIB__
+
+
+//#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+#include "kvi_malloc.h"
+#include "kvi_bswap.h"
+
+#define _KVI_LOCALE_CPP_
+#include "kvi_locale.h"
+
+#include <qglobal.h> //for debug()
+#include <qtextcodec.h>
+#include <qdir.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qlocale.h>
+#endif
+
+#include "kvi_string.h"
+#include "kvi_qcstring.h"
+#include "kvi_env.h"
+#include "kvi_fileutils.h"
+#include "kvi_file.h"
+
+
+KVILIB_API KviMessageCatalogue * g_pMainCatalogue = 0;
+
+static KviStr g_szLang;
+static KviTranslator * g_pTranslator = 0;
+static KviPointerHashTable<const char *,KviMessageCatalogue> * g_pCatalogueDict = 0;
+static QTextCodec * g_pUtf8TextCodec = 0;
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The following code was extracted and adapted from gutf8.c
+// from the GNU GLIB2 package.
+//
+// gutf8.c - Operations on UTF-8 strings.
+//
+// Copyright (C) 1999 Tom Tromey
+// Copyright (C) 2000 Red Hat, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+//
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef char gchar;
+typedef unsigned char guchar;
+typedef signed int gssize;
+typedef unsigned int gunichar;
+
+
+
+#define UNICODE_VALID(Char) \
+ ((Char) < 0x110000 && \
+ (((Char) & 0xFFFFF800) != 0xD800) && \
+ ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
+ ((Char) & 0xFFFE) != 0xFFFE)
+
+#define CONTINUATION_CHAR \
+ if ((*(guchar *)p & 0xc0) != 0x80) /* 10xxxxxx */ \
+ goto error; \
+ val <<= 6; \
+ val |= (*(guchar *)p) & 0x3f;
+
+
+static const char *
+fast_validate (const char *str)
+
+{
+ gunichar val = 0;
+ gunichar min = 0;
+ const gchar *p;
+
+ for (p = str; *p; p++)
+ {
+ if (*(guchar *)p < 128)
+ /* done */;
+ else
+ {
+ const gchar *last;
+
+ last = p;
+ if ((*(guchar *)p & 0xe0) == 0xc0) /* 110xxxxx */
+ {
+ if ((*(guchar *)p & 0x1e) == 0)
+ goto error;
+ p++;
+ if ((*(guchar *)p & 0xc0) != 0x80) /* 10xxxxxx */
+ goto error;
+ }
+ else
+ {
+ if ((*(guchar *)p & 0xf0) == 0xe0) /* 1110xxxx */
+ {
+ min = (1 << 11);
+ val = *(guchar *)p & 0x0f;
+ goto TWO_REMAINING;
+ }
+ else if ((*(guchar *)p & 0xf8) == 0xf0) /* 11110xxx */
+ {
+ min = (1 << 16);
+ val = *(guchar *)p & 0x07;
+ }
+ else
+ goto error;
+
+ p++;
+ CONTINUATION_CHAR;
+ TWO_REMAINING:
+ p++;
+ CONTINUATION_CHAR;
+ p++;
+ CONTINUATION_CHAR;
+
+ if (val < min)
+ goto error;
+
+ if (!UNICODE_VALID(val))
+ goto error;
+ }
+
+ continue;
+
+ error:
+ return last;
+ }
+ }
+
+ return p;
+}
+
+static const gchar *
+fast_validate_len (const char *str,
+ gssize max_len)
+
+{
+ gunichar val = 0;
+ gunichar min = 0;
+ const gchar *p;
+
+ for (p = str; (max_len < 0 || (p - str) < max_len) && *p; p++)
+ {
+ if (*(guchar *)p < 128)
+ /* done */;
+ else
+ {
+ const gchar *last;
+
+ last = p;
+ if ((*(guchar *)p & 0xe0) == 0xc0) /* 110xxxxx */
+ {
+ if (max_len >= 0 && max_len - (p - str) < 2)
+ goto error;
+
+ if ((*(guchar *)p & 0x1e) == 0)
+ goto error;
+ p++;
+ if ((*(guchar *)p & 0xc0) != 0x80) /* 10xxxxxx */
+ goto error;
+ }
+ else
+ {
+ if ((*(guchar *)p & 0xf0) == 0xe0) /* 1110xxxx */
+ {
+ if (max_len >= 0 && max_len - (p - str) < 3)
+ goto error;
+
+ min = (1 << 11);
+ val = *(guchar *)p & 0x0f;
+ goto TWO_REMAINING;
+ }
+ else if ((*(guchar *)p & 0xf8) == 0xf0) /* 11110xxx */
+ {
+ if (max_len >= 0 && max_len - (p - str) < 4)
+ goto error;
+
+ min = (1 << 16);
+ val = *(guchar *)p & 0x07;
+ }
+ else
+ goto error;
+
+ p++;
+ CONTINUATION_CHAR;
+ TWO_REMAINING:
+ p++;
+ CONTINUATION_CHAR;
+ p++;
+ CONTINUATION_CHAR;
+
+ if (val < min)
+ goto error;
+ if (!UNICODE_VALID(val))
+ goto error;
+ }
+
+ continue;
+
+ error:
+ return last;
+ }
+ }
+
+ return p;
+}
+
+static bool g_utf8_validate (const char *str,
+ gssize max_len,
+ const gchar **end)
+
+{
+ const gchar *p;
+
+ if (max_len < 0)
+ p = fast_validate (str);
+ else
+ p = fast_validate_len (str, max_len);
+
+ if (end)
+ *end = p;
+
+ if ((max_len >= 0 && p != str + max_len) ||
+ (max_len < 0 && *p != '\0'))
+ return false;
+ else
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+// End of gutf8.c
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+
+class KviSmartTextCodec : public QTextCodec
+{
+protected:
+ KviQCString m_szName;
+ QTextCodec * m_pRecvCodec;
+ QTextCodec * m_pSendCodec;
+public:
+ KviSmartTextCodec(const char * szName,const char * szChildCodecName,bool bSendInUtf8)
+ : QTextCodec()
+ {
+ m_szName = szName;
+ if(!g_pUtf8TextCodec)
+ {
+ g_pUtf8TextCodec = QTextCodec::codecForName("UTF-8");
+ if(!g_pUtf8TextCodec)
+ {
+ debug("Can't find the global utf8 text codec!");
+ g_pUtf8TextCodec = QTextCodec::codecForLocale(); // try anything else...
+ }
+ }
+ m_pRecvCodec = QTextCodec::codecForName(szChildCodecName);
+ if(!m_pRecvCodec)
+ {
+ debug("Can't find the codec for name %s (composite codec creation)",szName);
+ m_pRecvCodec = g_pUtf8TextCodec;
+ }
+ if(bSendInUtf8)
+ m_pSendCodec = g_pUtf8TextCodec;
+ else
+ m_pSendCodec = m_pRecvCodec;
+ }
+public:
+ bool ok(){ return m_pRecvCodec && g_pUtf8TextCodec; };
+
+ virtual int mibEnum () const { return 0; };
+
+#ifdef COMPILE_USE_QT4
+ virtual QByteArray name() const { return m_szName; };
+protected:
+ virtual QByteArray convertFromUnicode(const QChar * input,int number,ConverterState * state) const
+ {
+ return m_pSendCodec->fromUnicode(input,number,state);
+ }
+ virtual QString convertToUnicode(const char * chars,int len,ConverterState * state) const
+ {
+ if(g_utf8_validate(chars,len,NULL))return g_pUtf8TextCodec->toUnicode(chars,len,state);
+ return m_pRecvCodec->toUnicode(chars,len,state);
+ }
+#else
+public:
+ virtual const char * mimeName () const { return m_pRecvCodec->mimeName(); };
+ virtual const char * name () const { return m_szName.data(); };
+ virtual QTextDecoder * makeDecoder () const { return m_pRecvCodec->makeDecoder(); };
+ virtual QTextEncoder * makeEncoder () const { return m_pSendCodec->makeEncoder(); };
+ QCString fromUnicode (const QString & uc) const { return m_pSendCodec->fromUnicode(uc); };
+ virtual QCString fromUnicode (const QString & uc,int & lenInOut) const { return m_pSendCodec->fromUnicode(uc,lenInOut); };
+ QString toUnicode(const char * chars) const
+ {
+ if(g_utf8_validate(chars,-1,NULL))return g_pUtf8TextCodec->toUnicode(chars);
+ return m_pRecvCodec->toUnicode(chars);
+ };
+ virtual QString toUnicode(const char * chars,int len) const
+ {
+ if(g_utf8_validate(chars,len,NULL))return g_pUtf8TextCodec->toUnicode(chars,len);
+ return m_pRecvCodec->toUnicode(chars,len);
+ };
+ QString toUnicode(const QByteArray & a,int len) const
+ {
+ if(g_utf8_validate(a.data(),len,NULL))return g_pUtf8TextCodec->toUnicode(a,len);
+ return m_pRecvCodec->toUnicode(a,len);
+ };
+ QString toUnicode(const QByteArray & a) const
+ {
+ if(g_utf8_validate(a.data(),a.size(),NULL))return g_pUtf8TextCodec->toUnicode(a);
+ return m_pRecvCodec->toUnicode(a);
+ };
+ QString toUnicode(const QCString & a,int len) const
+ {
+ if(g_utf8_validate(a.data(),len,NULL))return g_pUtf8TextCodec->toUnicode(a,len);
+ return m_pRecvCodec->toUnicode(a,len);
+ };
+ QString toUnicode(const QCString & a) const
+ {
+ if(g_utf8_validate(a.data(),-1,NULL))return g_pUtf8TextCodec->toUnicode(a);
+ return m_pRecvCodec->toUnicode(a);
+ };
+
+ virtual bool canEncode(QChar ch) const { return m_pSendCodec->canEncode(ch); };
+ virtual bool canEncode(const QString &s) const { return m_pSendCodec->canEncode(s); };
+ virtual int heuristicContentMatch(const char * chars,int len) const
+ {
+ int iii = g_pUtf8TextCodec->heuristicContentMatch(chars,len);
+ if(iii < 0)return m_pRecvCodec->heuristicContentMatch(chars,len);
+ return iii;
+ }
+ virtual int heuristicNameMatch(const char * hint) const { return 0; };
+#endif
+};
+
+static KviPointerHashTable<const char *,KviSmartTextCodec> * g_pSmartCodecDict = 0;
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The following code was extracted and adapted from gettext.h and gettextP.h
+// from the GNU gettext package.
+//
+// Internal header for GNU gettext internationalization functions.
+// Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with the GNU C Library; see the file COPYING.LIB. If not,
+// write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+//
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+
+#if HAVE_LIMITS_H || _LIBC
+ #include <limits.h>
+#endif
+
+// The magic number of the GNU message catalog format.
+#define KVI_LOCALE_MAGIC 0x950412de
+#define KVI_LOCALE_MAGIC_SWAPPED 0xde120495
+
+// Revision number of the currently used .mo (binary) file format.
+#define MO_REVISION_NUMBER 0
+
+
+// Header for binary .mo file format.
+struct GnuMoFileHeader
+{
+ // The magic number.
+ kvi_u32_t magic;
+ // The revision number of the file format.
+ kvi_u32_t revision;
+ // The number of strings pairs.
+ kvi_u32_t nstrings;
+ // Offset of table with start offsets of original strings.
+ kvi_u32_t orig_tab_offset;
+ // Offset of table with start offsets of translation strings.
+ kvi_u32_t trans_tab_offset;
+ // Size of hashing table.
+ kvi_u32_t hash_tab_size;
+ // Offset of first hashing entry.
+ kvi_u32_t hash_tab_offset;
+};
+
+struct GnuMoStringDescriptor
+{
+ // Length of addressed string.
+ kvi_u32_t length;
+ // Offset of string in file.
+ kvi_u32_t offset;
+};
+
+#define KVI_SWAP_IF_NEEDED(flag,value) (flag ? kvi_swap32(value) : (value))
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+// End of gettext.h & gettextP.h
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// HELPERS
+
+static int somePrimeNumbers[90]=
+{
+ 257 , 521 , 769 , 1031, 1087, 1091, 1103, 1117, 1123, 1151, // Incomplete *.mo files
+ 1163, 1171, 1181, 1193, 1201, 1213, 1217, 1223, 1229, 1231, // Complete *.mo files
+ 1237, 1249, 1259, 1277, 1283, 1289, 1291, 1297, 1307, 1319,
+ 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1433,
+ 1447, 1459, 1471, 1481, 1493, 1511, 1523, 1531, 1543, 1553,
+ 1567, 1571, 1583, 1597, 1609, 1619, 1627, 1637, 1657, 1667, // Too big for KVIrc *.mo files
+ 1693, 1709, 1721, 1733, 1741, 1753, 1777, 1789, 1811, 1831,
+ 1907, 2069, 2111, 2221, 2309, 2441, 2531, 2617, 2731, 2837,
+ 2903, 3121, 3329, 3331, 3767, 4127, 5051, 6089, 7039, 9973
+};
+
+int kvi_getFirstBiggerPrime(int number)
+{
+ for(int i=0;i<90;i++){
+ if(somePrimeNumbers[i] >= number)return somePrimeNumbers[i];
+ }
+ return 9973; //error!
+}
+
+
+KviMessageCatalogue::KviMessageCatalogue()
+{
+ //m_uEncoding = 0;
+ m_pTextCodec = QTextCodec::codecForLocale();
+
+ //m_pMessages = new KviPointerHashTable<const char *,KviTranslationEntry>(1123,true,false); // dictSize, case sensitive , don't copy keys
+ m_pMessages = new KviPointerHashTable<const char *,KviTranslationEntry>(32,true,false); // dictSize, case sensitive , don't copy keys
+ m_pMessages->setAutoDelete(true);
+}
+
+KviMessageCatalogue::~KviMessageCatalogue()
+{
+ if(m_pMessages)
+ delete m_pMessages;
+}
+
+bool KviMessageCatalogue::load(const QString& name)
+{
+ QString szCatalogueFile(name);
+
+ // Try to load the header
+ KviFile f(szCatalogueFile);
+ if(!f.openForReading())
+ {
+ debug("[KviLocale]: Failed to open the messages file %s: probably doesn't exist",KviQString::toUtf8(szCatalogueFile).data());
+ return false;
+ }
+
+ GnuMoFileHeader hdr;
+
+ if(f.readBlock((char *)&hdr,sizeof(GnuMoFileHeader)) < (int)sizeof(GnuMoFileHeader))
+ {
+ debug("KviLocale: Failed to read header of %s",KviQString::toUtf8(szCatalogueFile).data());
+ f.close();
+ return false;
+ }
+
+ bool bMustSwap = false;
+
+ if(hdr.magic != KVI_LOCALE_MAGIC)
+ {
+ if(hdr.magic == KVI_LOCALE_MAGIC_SWAPPED)
+ {
+ debug("KviLocale: Swapped magic for file %s: swapping data too",KviQString::toUtf8(szCatalogueFile).data());
+ bMustSwap = true;
+ } else {
+ debug("KviLocale: Bad locale magic for file %s: not a *.mo file ?",KviQString::toUtf8(szCatalogueFile).data());
+ f.close();
+ return false;
+ }
+ }
+
+ if(KVI_SWAP_IF_NEEDED(bMustSwap,hdr.revision) != MO_REVISION_NUMBER)
+ {
+ debug("KviLocale: Invalid *.mo file revision number for file %s",KviQString::toUtf8(szCatalogueFile).data());
+ f.close();
+ return false;
+ }
+
+ int numberOfStrings = KVI_SWAP_IF_NEEDED(bMustSwap,hdr.nstrings);
+
+ if(numberOfStrings <= 0)
+ {
+ debug("KviLocale: No translated messages found in file %s",KviQString::toUtf8(szCatalogueFile).data());
+ f.close();
+ return false;
+ }
+
+ if(numberOfStrings >= 9972)
+ {
+ debug("Number of strings too big...sure that it is a KVIrc catalog file ?");
+ numberOfStrings = 9972;
+ }
+
+ // return back
+ f.seek(0);
+
+ unsigned int fSize = f.size();
+ char * buffer = (char *)kvi_malloc(fSize);
+
+ // FIXME: maybe read it in blocks eh ?
+ if(f.readBlock(buffer,fSize) < (int)fSize)
+ {
+ debug("KviLocale: Error while reading the translation file %s",KviQString::toUtf8(szCatalogueFile).data());
+ kvi_free(buffer);
+ f.close();
+ return false;
+ }
+
+ // Check for broken *.mo files
+ if(fSize < (24 + (sizeof(GnuMoStringDescriptor) * numberOfStrings)))
+ {
+ debug("KviLocale: Broken translation file %s (too small for all descriptors)",KviQString::toUtf8(szCatalogueFile).data());
+ kvi_free(buffer);
+ f.close();
+ return false;
+ }
+
+ GnuMoStringDescriptor * origDescriptor = (GnuMoStringDescriptor *)(buffer + KVI_SWAP_IF_NEEDED(bMustSwap,hdr.orig_tab_offset));
+ GnuMoStringDescriptor * transDescriptor = (GnuMoStringDescriptor *)(buffer + KVI_SWAP_IF_NEEDED(bMustSwap,hdr.trans_tab_offset));
+
+ // Check again for broken *.mo files
+ int expectedFileSize = KVI_SWAP_IF_NEEDED(bMustSwap,transDescriptor[numberOfStrings - 1].offset) +
+ KVI_SWAP_IF_NEEDED(bMustSwap,transDescriptor[numberOfStrings - 1].length);
+
+ if(fSize < (unsigned int)expectedFileSize)
+ {
+ debug("KviLocale: Broken translation file %s (too small for all the message strings)",KviQString::toUtf8(szCatalogueFile).data());
+ kvi_free(buffer);
+ f.close();
+ return false;
+ }
+
+ // Ok...we can run now
+
+ int dictSize = kvi_getFirstBiggerPrime(numberOfStrings);
+ if(m_pMessages)
+ delete m_pMessages;
+ m_pMessages = new KviPointerHashTable<const char *,KviTranslationEntry>(dictSize,true,false); // dictSize, case sensitive , don't copy keys
+ m_pMessages->setAutoDelete(true);
+
+ KviStr szHeader;
+
+ for(int i=0;i < numberOfStrings;i++)
+ {
+ // FIXME: "Check for NULL inside strings here ?"
+ //debug("original seems to be at %u and %u byttes long",KVI_SWAP_IF_NEEDED(bMustSwap,origDescriptor[i].offset),
+ // KVI_SWAP_IF_NEEDED(bMustSwap,origDescriptor[i].length));
+ //debug("translated seems to be at %u and %u byttes long",KVI_SWAP_IF_NEEDED(bMustSwap,transDescriptor[i].offset),
+ // KVI_SWAP_IF_NEEDED(bMustSwap,transDescriptor[i].length));
+
+ KviTranslationEntry * e = new KviTranslationEntry(
+ (char *)(buffer + KVI_SWAP_IF_NEEDED(bMustSwap,origDescriptor[i].offset)),
+ KVI_SWAP_IF_NEEDED(bMustSwap,origDescriptor[i].length),
+ (char *)(buffer + KVI_SWAP_IF_NEEDED(bMustSwap,transDescriptor[i].offset)),
+ KVI_SWAP_IF_NEEDED(bMustSwap,transDescriptor[i].length));
+
+ // In some (or all?) *.mo files the first string
+ // is zero bytes long and the translated one contains
+ // informations about the translation
+ if(e->m_szKey.len() == 0)
+ {
+ szHeader = e->m_szEncodedTranslation;
+ delete e;
+ continue;
+ }
+
+ m_pMessages->insert(e->m_szKey.ptr(),e);
+ }
+
+ kvi_free(buffer);
+ f.close();
+
+ m_pTextCodec = 0;
+
+ // find out the text encoding , if possible
+ if(szHeader.hasData())
+ {
+ // find "charset=*\n"
+ int idx = szHeader.findFirstIdx("charset=");
+ if(idx != -1)
+ {
+ szHeader.cutLeft(idx + 8);
+ szHeader.cutFromFirst('\n');
+ szHeader.stripWhiteSpace();
+ m_pTextCodec = KviLocale::codecForName(szHeader.ptr());
+ if(!m_pTextCodec)
+ {
+ debug("Can't find the codec for charset=%s",szHeader.ptr());
+ debug("Falling back to codecForLocale()");
+ m_pTextCodec = QTextCodec::codecForLocale();
+ }
+ }
+ }
+
+ if(!m_pTextCodec)
+ {
+ debug("The message catalogue does not have a \"charset\" header");
+ debug("Assuming utf8"); // FIXME: or codecForLocale() ?
+ m_pTextCodec = QTextCodec::codecForName("UTF-8");
+ }
+
+ return true;
+}
+
+const char * KviMessageCatalogue::translate(const char *text)
+{
+ KviTranslationEntry * aux = m_pMessages->find(text);
+ if(aux)return aux->m_szEncodedTranslation.ptr();
+ return text;
+}
+
+const QString & KviMessageCatalogue::translateToQString(const char *text)
+{
+ KviTranslationEntry * aux = m_pMessages->find(text);
+ if(aux)
+ {
+ if(aux->m_pQTranslation)return *(aux->m_pQTranslation);
+ aux->m_pQTranslation = new QString(m_pTextCodec->toUnicode(aux->m_szEncodedTranslation.ptr()));
+ return *(aux->m_pQTranslation);
+ }
+ // no translation is available: let's avoid continous string decoding
+ aux = new KviTranslationEntry(text);
+ m_pMessages->insert(aux->m_szKey.ptr(),aux);
+ aux->m_pQTranslation = new QString(m_pTextCodec->toUnicode(aux->m_szEncodedTranslation.ptr()));
+ return *(aux->m_pQTranslation);
+}
+
+
+
+
+namespace KviLocale
+{
+#ifndef QT_NO_BIG_CODECS
+ #define NUM_ENCODINGS 109
+#else
+ #define NUM_ENCODINGS 85
+#endif
+
+
+
+ static EncodingDescription supported_encodings[]=
+ {
+ { "UTF-8" , 0 , 0 , "8-bit Unicode" },
+ { "ISO-8859-1" , 0 , 0 , "Western, Latin-1" },
+ { "ISO-8859-2" , 0 , 0 , "Central European 1" },
+ { "ISO-8859-3" , 0 , 0 , "Central European 2" },
+ { "ISO-8859-4" , 0 , 0 , "Baltic, Standard" },
+ { "ISO-8859-5" , 0 , 0 , "Cyrillic, ISO" },
+ { "ISO-8859-6" , 0 , 0 , "Arabic, Standard" },
+ { "ISO-8859-7" , 0 , 0 , "Greek" },
+ { "ISO-8859-8" , 0 , 0 , "Hebrew, visually ordered" },
+ { "ISO-8859-8-i" , 0 , 0 , "Hebrew, logically ordered" },
+ { "ISO-8859-9" , 0 , 0 , "Turkish, Latin-5" },
+ { "ISO-8859-15" , 0 , 0 , "Western, Latin-1 + Euro" },
+ { "KOI8-R" , 0 , 0 , "Cyrillic, KOI" },
+ { "KOI8-U" , 0 , 0 , "Ukrainian" },
+ { "CP-1250" , 0 , 0 , "Central European 3" },
+ { "CP-1251" , 0 , 0 , "Cyrillic, Windows" },
+ { "CP-1252" , 0 , 0 , "Western, CP" },
+ { "CP-1253" , 0 , 0 , "Greek, CP" },
+ { "CP-1256" , 0 , 0 , "Arabic, CP" },
+ { "CP-1257" , 0 , 0 , "Baltic, CP" },
+ { "CP-1255" , 0 , 0 , "Hebrew, CP" },
+ { "CP-1254" , 0 , 0 , "Turkish, CP" },
+ { "TIS-620" , 0 , 0 , "Thai" },
+#ifndef QT_NO_BIG_CODECS
+ { "Big5" , 0 , 0 , "Chinese Traditional" },
+ { "Big5-HKSCS" , 0 , 0 , "Chinese Traditional, Hong Kong" },
+ { "GB18030" , 0 , 0 , "Chinese Simplified" },
+ { "JIS7" , 0 , 0 , "Japanese (JIS7)" },
+ { "Shift-JIS" , 0 , 0 , "Japanese (Shift-JIS)" },
+ { "EUC-JP" , 0 , 0 , "Japanese (EUC-JP)" },
+ { "EUC-KR" , 0 , 0 , "Korean" },
+ { "TSCII" , 0 , 0 , "Tamil" },
+#endif
+ { "ISO-8859-10" , 0 , 0 , "ISO-8859-10" },
+ { "ISO-8859-13" , 0 , 0 , "ISO-8859-13" },
+ { "ISO-8859-14" , 0 , 0 , "ISO-8859-14" },
+ { "IBM-850" , 0 , 0 , "IBM-850" },
+ { "IBM-866" , 0 , 0 , "IBM-866" },
+ { "CP874" , 0 , 0 , "CP874" },
+
+ // smart codecs that send in the local charset
+ { "ISO-8859-1 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Western Latin-1, O: Western Latin-1" },
+ { "ISO-8859-2 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Central European 1, O: Central European 1" },
+ { "ISO-8859-3 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Central European 2, O: Central European 2" },
+ { "ISO-8859-4 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Baltic, Standard, O: Baltic, Standard" },
+ { "ISO-8859-5 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Cyrillic, ISO, O: Cyrillic, ISO" },
+ { "ISO-8859-6 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Arabic, Standard, O: Arabic, Standard" },
+ { "ISO-8859-7 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Greek, O: Greek" },
+ { "ISO-8859-8 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Hebrew, visually ordered, O: Hebrew, visually ordered" },
+ { "ISO-8859-8-i [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Hebrew, logically ordered, O: Hebrew, logically ordered" },
+ { "ISO-8859-9 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Turkish, Latin-5, O: Turkish, Latin-5" },
+ { "ISO-8859-15 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Western, Latin-1 + Euro, O: Western, Latin-1 + Euro" },
+ { "KOI8-R [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Cyrillic, KOI, O: Cyrillic, KOI" },
+ { "KOI8-U [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Ukrainian, O: Ukrainian" },
+ { "CP-1250 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Central European 3, O: Central European 3" },
+ { "CP-1251 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Cyrillic, Windows, O: Cyrillic, Windows" },
+ { "CP-1252 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Western, CP, O: Western, CP" },
+ { "CP-1253 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Greek, CP, O: Greek, CP" },
+ { "CP-1256 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Arabic, CP, O: Arabic, CP" },
+ { "CP-1257 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Baltic, CP, O: Baltic, CP" },
+ { "CP-1255 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Hebrew, CP, O: Hebrew, CP" },
+ { "CP-1254 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Turkish, CP, O: Turkish, CP" },
+ { "TIS-620 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Thai, O: Thai" },
+#ifndef QT_NO_BIG_CODECS
+ { "Big5 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Chinese Traditional, O: Chinese Traditional" },
+ { "Big5-HKSCS [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Chinese Traditional, Hong Kong, O: Chinese Traditional, Hong Kong" },
+ { "GB18030 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Chinese Simplified, O: Chinese Simplified" },
+ { "JIS7 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Japanese (JIS7), O: Japanese " },
+ { "Shift-JIS [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Japanese (Shift-JIS), O: Japanese (Shift-JIS)" },
+ { "EUC-JP [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Japanese (EUC-JP), O: Japanese (EUC-JP)" },
+ { "EUC-KR [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Korean, O: Korean" },
+ { "TSCII [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / Tamil, O: Tamil" },
+#endif
+ { "ISO-8859-10 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / ISO-8859-10, O: ISO-8859-10" },
+ { "ISO-8859-13 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / ISO-8859-13, O: ISO-8859-13" },
+ { "ISO-8859-14 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / ISO-8859-14, O: ISO-8859-14" },
+ { "IBM-850 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / IBM-850, O: IBM-850" },
+ { "IBM-866 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / IBM-866, O: IBM-866" },
+ { "CP874 [UTF-8]" , 1 , 0 , "I: 8-bit Unicode / CP874, O: CP874" },
+
+ // smart codecs that send in utf8
+ { "UTF-8 [ISO-8859-1]" , 1 , 1 , "I: 8-bit Unicode / Western Latin-1, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-2]" , 1 , 1 , "I: 8-bit Unicode / Central European 1, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-3]" , 1 , 1 , "I: 8-bit Unicode / Central European 2, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-4]" , 1 , 1 , "I: 8-bit Unicode / Baltic, Standard, O: 8-bit Unicode" },
+
+ { "UTF-8 [ISO-8859-5]" , 1 , 1 , "I: 8-bit Unicode / Cyrillic, ISO, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-6]" , 1 , 1 , "I: 8-bit Unicode / Arabic, Standard, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-7]" , 1 , 1 , "I: 8-bit Unicode / Greek, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-8]" , 1 , 1 , "I: 8-bit Unicode / Hebrew, visually ordered, O: 8-bit Unicode" },
+
+ { "UTF-8 [ISO-8859-8-i]" , 1 , 1 , "I: 8-bit Unicode / Hebrew, logically ordered, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-9]" , 1 , 1 , "I: 8-bit Unicode / Turkish, Latin-5, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-15]" , 1 , 1 , "I: 8-bit Unicode / Western, Latin-1 + Euro, O: 8-bit Unicode" },
+ { "UTF-8 [KOI8-R]" , 1 , 1 , "I: 8-bit Unicode / Cyrillic, KOI, O: 8-bit Unicode" },
+
+ { "UTF-8 [KOI8-U]" , 1 , 1 , "I: 8-bit Unicode / Ukrainian, O: 8-bit Unicode" },
+ { "UTF-8 [CP-1250]" , 1 , 1 , "I: 8-bit Unicode / Central European 3, O: 8-bit Unicode" },
+ { "UTF-8 [CP-1251]" , 1 , 1 , "I: 8-bit Unicode / Cyrillic, Windows, O: 8-bit Unicode" },
+ { "UTF-8 [CP-1252]" , 1 , 1 , "I: 8-bit Unicode / Western, CP, O: 8-bit Unicode" },
+
+ { "UTF-8 [CP-1253]" , 1 , 1 , "I: 8-bit Unicode / Greek, CP, O: 8-bit Unicode" },
+ { "UTF-8 [CP-1256]" , 1 , 1 , "I: 8-bit Unicode / Arabic, CP, O: 8-bit Unicode" },
+ { "UTF-8 [CP-1257]" , 1 , 1 , "I: 8-bit Unicode / Baltic, CP, O: 8-bit Unicode" },
+ { "UTF-8 [CP-1255]" , 1 , 1 , "I: 8-bit Unicode / Hebrew, CP, O: 8-bit Unicode" },
+
+ { "UTF-8 [CP-1254]" , 1 , 1 , "I: 8-bit Unicode / Turkish, CP, O: 8-bit Unicode" },
+ { "UTF-8 [TIS-620]" , 1 , 1 , "I: 8-bit Unicode / Thai, O: 8-bit Unicode" },
+#ifndef QT_NO_BIG_CODECS
+ { "UTF-8 [Big5]" , 1 , 1 , "I: 8-bit Unicode / Chinese Traditional, O: 8-bit Unicode" },
+ { "UTF-8 [Big5-HKSCS]" , 1 , 1 , "I: 8-bit Unicode / Chinese Traditional, Hong Kong, O: 8-bit Unicode" },
+
+ { "UTF-8 [GB18030]" , 1 , 1 , "I: 8-bit Unicode / Chinese Simplified, O: 8-bit Unicode" },
+ { "UTF-8 [JIS7]" , 1 , 1 , "I: 8-bit Unicode / Japanese (JIS7), O: 8-bit Unicode" },
+ { "UTF-8 [Shift-JIS]" , 1 , 1 , "I: 8-bit Unicode / Japanese (Shift-JIS), O: Japanese (Shift-JIS)" },
+ { "UTF-8 [EUC-JP]" , 1 , 1 , "I: 8-bit Unicode / Japanese (EUC-JP), O: Japanese (EUC-JP)" },
+
+ { "UTF-8 [EUC-KR]" , 1 , 1 , "I: 8-bit Unicode / Korean, O: 8-bit Unicode" },
+ { "UTF-8 [TSCII]" , 1 , 1 , "I: 8-bit Unicode / Tamil, O: 8-bit Unicode" },
+#endif
+ { "UTF-8 [ISO-8859-10]" , 1 , 1 , "I: 8-bit Unicode / ISO-8859-10, O: 8-bit Unicode" },
+ { "UTF-8 [ISO-8859-13]" , 1 , 1 , "I: 8-bit Unicode / ISO-8859-13, O: 8-bit Unicode" },
+
+ { "UTF-8 [ISO-8859-14]" , 1 , 1 , "I: 8-bit Unicode / ISO-8859-14, O: 8-bit Unicode" },
+ { "UTF-8 [IBM-850]" , 1 , 1 , "I: 8-bit Unicode / IBM-850, O: 8-bit Unicode" },
+ { "UTF-8 [IBM-866]" , 1 , 1 , "I: 8-bit Unicode / IBM-866, O: 8-bit Unicode" },
+ { "UTF-8 [CP874]" , 1 , 1 , "I: 8-bit Unicode / CP874, O: 8-bit Unicode" },
+
+ { 0 , 0 , 0 , 0 }
+ };
+
+ EncodingDescription * encodingDescription(int iIdx)
+ {
+ if(iIdx > NUM_ENCODINGS)return &(supported_encodings[NUM_ENCODINGS]);
+ return &(supported_encodings[iIdx]);
+ }
+
+ QTextCodec * codecForName(const char * szName)
+ {
+ KviStr szTmp = szName;
+ int idx = szTmp.findFirstIdx('[');
+ if(idx != -1)
+ {
+ // composite codec: either UTF-8 [child codec] or child codec [UTF-8]
+ KviSmartTextCodec * c = g_pSmartCodecDict->find(szName);
+ if(c)return c;
+
+
+ if(kvi_strEqualCIN("UTF-8 [",szName,7))
+ {
+ szTmp.replaceAll("UTF-8 [","");
+ szTmp.replaceAll("]","");
+ // smart codec that sends UTF-8
+ c = new KviSmartTextCodec(szName,szTmp.ptr(),true);
+ } else {
+ szTmp.cutFromFirst(' ');
+ // smart codec that sends child encoding
+ c = new KviSmartTextCodec(szName,szTmp.ptr(),false);
+ }
+ if(c->ok())
+ {
+ g_pSmartCodecDict->replace(szName,c);
+ return c;
+ } else {
+ delete c;
+ }
+ }
+ return QTextCodec::codecForName(szName);
+ }
+
+ const KviStr & localeName()
+ {
+ return g_szLang;
+ }
+
+ bool loadCatalogue(const QString &name,const QString &szLocaleDir)
+ {
+ //debug("Looking up catalogue %s",name);
+ if(g_pCatalogueDict->find(KviQString::toUtf8(name).data()))return true; // already loaded
+
+ QString szBuffer;
+
+ if(findCatalogue(szBuffer,name,szLocaleDir))
+ {
+ KviMessageCatalogue * c = new KviMessageCatalogue();
+ if(c->load(szBuffer))
+ {
+ //debug("KviLocale: loaded catalogue %s",name);
+ g_pCatalogueDict->insert(KviQString::toUtf8(name).data(),c);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool unloadCatalogue(const QString &name)
+ {
+ //debug("Unloading catalogue : %s",name);
+ return g_pCatalogueDict->remove(KviQString::toUtf8(name).data());
+ }
+
+ bool findCatalogue(QString &szBuffer,const QString& name,const QString& szLocaleDir)
+ {
+ KviStr szLocale = g_szLang;
+
+ QString szLocDir = szLocaleDir;
+ KviQString::ensureLastCharIs(szLocDir,KVI_PATH_SEPARATOR_CHAR);
+
+ KviQString::sprintf(szBuffer,"%Q%Q_%s.mo",&szLocDir,&name,szLocale.ptr());
+
+ if(KviFileUtils::fileExists(szBuffer))return true;
+
+ if(szLocale.findFirstIdx('.') != -1)
+ {
+ // things like en_GB.utf8
+ // kill them
+ szLocale.cutFromFirst('.');
+
+ KviQString::sprintf(szBuffer,"%Q%Q_%s.mo",&szLocDir,&name,szLocale.ptr());
+ if(KviFileUtils::fileExists(szBuffer))return true;
+ }
+
+ if(szLocale.findFirstIdx('@') != -1)
+ {
+ // things like @euro ?
+ // kill them
+ szLocale.cutFromFirst('@');
+ KviQString::sprintf(szBuffer,"%Q%Q_%s.mo",&szLocDir,&name,szLocale.ptr());
+ if(KviFileUtils::fileExists(szBuffer))return true;
+ }
+
+ if(szLocale.findFirstIdx('_') != -1)
+ {
+ // things like en_GB
+ // kill them
+ szLocale.cutFromFirst('_');
+ KviQString::sprintf(szBuffer,"%Q%Q_%s.mo",&szLocDir,&name,szLocale.ptr());
+ if(KviFileUtils::fileExists(szBuffer))return true;
+ }
+
+ // try the lower case version too
+ szLocale.toLower();
+ KviQString::sprintf(szBuffer,"%Q%Q_%s.mo",&szLocDir,&name,szLocale.ptr());
+ if(KviFileUtils::fileExists(szBuffer))return true;
+
+ return false;
+ }
+
+ //
+ // This function attempts to determine the current locale
+ // and then load the corresponding translation file
+ // from the KVIrc locale directory
+ // Returns true if the locale was correctly set
+ // i.e. the locale is C or POSIX (no translation needed)
+ // or the locale is correctly defined and the
+ // translation map was sucesfully loaded
+ //
+
+ void init(QApplication * app,const QString &localeDir)
+ {
+ // first of all try to find out the current locale
+ g_szLang="";
+#ifdef COMPILE_USE_QT4
+ QString szLangFile=QString("%1/.kvirc_force_locale").arg(QDir::homePath());
+#else
+ QString szLangFile=QString("%1/.kvirc_force_locale").arg(QDir::homeDirPath());
+#endif
+ if(KviFileUtils::fileExists(szLangFile))
+ {
+ QString szTmp;
+ KviFileUtils::readFile(szLangFile,szTmp);
+ g_szLang=szTmp;
+ }
+ if(g_szLang.isEmpty())g_szLang = kvi_getenv("KVIRC_LANG");
+#ifdef COMPILE_USE_QT4
+ if(g_szLang.isEmpty())g_szLang = QLocale::system().name();
+#else
+ if(g_szLang.isEmpty())g_szLang = QTextCodec::locale();
+#endif
+ if(g_szLang.isEmpty())g_szLang = kvi_getenv("LC_MESSAGES");
+ if(g_szLang.isEmpty())g_szLang = kvi_getenv("LANG");
+ if(g_szLang.isEmpty())g_szLang = "en";
+ g_szLang.stripWhiteSpace();
+
+ // the main catalogue is supposed to be kvirc_<language>.mo
+ g_pMainCatalogue = new KviMessageCatalogue();
+ // the catalogue dict
+ g_pCatalogueDict = new KviPointerHashTable<const char *,KviMessageCatalogue>;
+ g_pCatalogueDict->setAutoDelete(true);
+
+ // the smart codec dict
+ g_pSmartCodecDict = new KviPointerHashTable<const char *,KviSmartTextCodec>;
+ // the Qt docs explicitly state that we shouldn't delete
+ // the codecs by ourselves...
+ g_pSmartCodecDict->setAutoDelete(false);
+
+ if(g_szLang.hasData())
+ {
+ QString szBuffer;
+ if(findCatalogue(szBuffer,"kvirc",localeDir))
+ {
+ g_pMainCatalogue->load(szBuffer);
+ g_pTranslator = new KviTranslator(app,"kvirc_translator");
+ app->installTranslator(g_pTranslator);
+ } else {
+ KviStr szTmp = g_szLang;
+ szTmp.cutFromFirst('.');
+ szTmp.cutFromFirst('_');
+ szTmp.cutFromFirst('@');
+ szTmp.toLower();
+ if(!(kvi_strEqualCI(szTmp.ptr(),"en") ||
+ kvi_strEqualCI(szTmp.ptr(),"c") ||
+ kvi_strEqualCI(szTmp.ptr(),"us") ||
+ kvi_strEqualCI(szTmp.ptr(),"gb") ||
+ kvi_strEqualCI(szTmp.ptr(),"posix")))
+ {
+ // FIXME: THIS IS NO LONGER VALID!!!
+ debug("Can't find the catalogue for locale \"%s\" (%s)",g_szLang.ptr(),szTmp.ptr());
+ debug("There is no such translation or the $LANG variable was incorrectly set");
+ debug("You can use $KVIRC_LANG to override the catalogue name");
+ debug("For example you can set KVIRC_LANG to it_IT to force usage of the it.mo catalogue");
+ }
+ }
+ }
+
+ //g_pTextCodec = QTextCodec::codecForLocale();
+ //if(!g_pTextCodec)g_pTextCodec = QTextCodec::codecForLocale();
+ }
+
+ void done(QApplication * app)
+ {
+ delete g_pMainCatalogue;
+ delete g_pCatalogueDict;
+ delete g_pSmartCodecDict;
+ g_pMainCatalogue = 0;
+ g_pCatalogueDict = 0;
+ g_pSmartCodecDict = 0;
+ if(g_pTranslator)
+ {
+ app->removeTranslator(g_pTranslator);
+ delete g_pTranslator;
+ g_pTranslator = 0;
+ }
+ }
+
+ KviMessageCatalogue * getLoadedCatalogue(const QString& name)
+ {
+ return g_pCatalogueDict->find(KviQString::toUtf8(name).data());
+ }
+
+
+ const char * translate(const char * text,const char * context)
+ {
+ if(context)
+ {
+ KviMessageCatalogue * c = g_pCatalogueDict->find(context);
+ if(!c)
+ {
+ // FIXME: Should really try to load the catalogue here!
+ c = new KviMessageCatalogue();
+ g_pCatalogueDict->insert(context,c);
+ }
+ return c->translate(text);
+ }
+ return g_pMainCatalogue->translate(text);
+ }
+
+ const QString & translateToQString(const char * text,const char * context)
+ {
+ if(context)
+ {
+ KviMessageCatalogue * c = g_pCatalogueDict->find(context);
+ if(!c)
+ {
+ // FIXME: Should really try to load the catalogue here!
+ c = new KviMessageCatalogue();
+ g_pCatalogueDict->insert(context,c);
+ }
+ return c->translateToQString(text);
+ }
+ return g_pMainCatalogue->translateToQString(text);
+ }
+};
+
+KviTranslator::KviTranslator(QObject * par,const char * nam)
+#ifdef COMPILE_USE_QT4
+: QTranslator(par)
+#else
+: QTranslator(par,nam)
+#endif
+{
+}
+
+KviTranslator::~KviTranslator()
+{
+}
+
+#ifdef COMPILE_USE_QT4
+QString KviTranslator::translate(const char *context,const char * message,const char * comment) const
+{
+ // we ignore contexts and comments for qt translations
+ return g_pMainCatalogue->translateToQString(message);
+}
+#endif
+
+QString KviTranslator::find(const char *context,const char * message) const
+{
+ // we ignore contexts for qt translations
+ return g_pMainCatalogue->translateToQString(message);
+}
+
+#ifndef COMPILE_USE_QT4
+QTranslatorMessage KviTranslator::findMessage(const char * context,const char * sourceText,const char * comment) const
+{
+ // we ignore contexts for qt translations
+ return QTranslatorMessage(context,sourceText,comment,g_pMainCatalogue->translateToQString(sourceText));
+}
+#endif
+
+#if 0
+
+// a fake table that will force these translations
+// to be included in the *.pot file
+
+static QString fake_translations_table[]=
+{
+ // global
+ __tr2qs("OK"),
+ __tr2qs("Cancel"),
+ // color dialog
+ __tr2qs("Select color"),
+ __tr2qs("&Basic colors"),
+ __tr2qs("&Custom colors"),
+ __tr2qs("&Red"),
+ __tr2qs("&Green"),
+ __tr2qs("Bl&ue"),
+ __tr2qs("&Define Custom Colors >>"),
+ __tr2qs("&Add to Custom Colors"),
+ // font dialog
+ __tr2qs("Select Font"),
+ __tr2qs("&Font"),
+ __tr2qs("Font st&yle"),
+ __tr2qs("&Size"),
+ __tr2qs("Sample"),
+ __tr2qs("Effects"),
+ __tr2qs("Stri&keout"),
+ __tr2qs("&Underline"),
+ __tr2qs("Scr&ipt"),
+ //File selector
+ __tr2qs("Parent Directory"),
+ __tr2qs("Back"),
+ __tr2qs("Forward"),
+ __tr2qs("Reload"),
+ __tr2qs("New Directory"),
+ __tr2qs("Bookmarks"),
+ __tr2qs("Add Bookmark"),
+ __tr2qs("&Edit Bookmarks"),
+ __tr2qs("New Bookmark Folder..."),
+ __tr2qs("Configure"),
+ __tr2qs("Sorting"),
+ __tr2qs("By Name"),
+ __tr2qs("By Date"),
+ __tr2qs("By Size"),
+ __tr2qs("Reverse"),
+ __tr2qs("Directories First"),
+ __tr2qs("Case Insensitive"),
+ __tr2qs("Short View"),
+ __tr2qs("Detailed View"),
+ __tr2qs("Show Hidden Files"),
+ __tr2qs("Show Quick Access Navigation Panel"),
+ __tr2qs("Show Preview"),
+ __tr2qs("Separate Directories"),
+ __tr2qs("Often used directories"),
+ __tr2qs("Desktop"),
+ __tr2qs("Home Directory"),
+ __tr2qs("Floppy"),
+ __tr2qs("Temporary Files"),
+ __tr2qs("Network"),
+ __tr2qs("New Directory..."),
+ __tr2qs("Delete"),
+ __tr2qs("Thumbnail Previews"),
+ __tr2qs("Large Icons"),
+ __tr2qs("Small Icons"),
+ __tr2qs("Properties..."),
+ __tr2qs("&Automatic Preview"),
+ __tr2qs("&Preview"),
+ __tr2qs("&Location:"),
+ __tr2qs("&Filter:"),
+ __tr2qs("All Files"),
+ __tr2qs("&OK"),
+ __tr2qs("&Cancel")
+
+}
+
+#endif