src/hbcore/i18n/hbtranslator.cpp
changeset 3 11d3954df52a
parent 2 06ff229162e9
child 6 c3690ec91ef8
equal deleted inserted replaced
2:06ff229162e9 3:11d3954df52a
    31 
    31 
    32 #include <hbfindfile.h>
    32 #include <hbfindfile.h>
    33 #include <hbtranslator.h>
    33 #include <hbtranslator.h>
    34 #include <hbtranslator_p.h>
    34 #include <hbtranslator_p.h>
    35 
    35 
    36 
    36 #ifdef Q_OS_SYMBIAN
    37 const QString defaultpath = "/resource/qt/translations/";
    37 const char* defaultPath   = "/resource/qt/translations/";
       
    38 const char* defaultDrive  = "Z:";
       
    39 const char* defaultCommon = "common_";
       
    40 #else
       
    41 const QString defaultPath = "";
       
    42 const char* defaultDrive  = "";
       
    43 const char* defaultCommon = "common_";
       
    44 
       
    45 #endif
       
    46 
       
    47 #ifdef Q_OS_SYMBIAN
       
    48 #include <f32file.h>
       
    49 #include <eikenv.h>
       
    50 #endif
       
    51 
       
    52 #ifdef Q_OS_SYMBIAN
       
    53 static void toSymbianPath(QString &path) {    
       
    54     int len=path.length();
       
    55     for (int i=0; i<len; i++) {
       
    56         QCharRef ref=path[i];
       
    57         if (ref == '/') {
       
    58            ref= '\\';
       
    59         }
       
    60     }
       
    61 }
       
    62 #endif
       
    63 
       
    64 static uchar* loadTranslatorData(QTranslator &translator, QString &qmFile,bool doFallback=true) {
       
    65 #ifndef Q_OS_SYMBIAN
       
    66     translator.load(qmFile);
       
    67     Q_UNUSED(doFallback);
       
    68     return 0;
       
    69 #else    
       
    70     RFile fl;
       
    71     RFs& fs = CCoeEnv::Static()->FsSession();
       
    72     // TPtrC ptrFName;
       
    73     QString qmFile2;        
       
    74     QString delims="_.";
       
    75     TInt err;
       
    76     for (;;) {
       
    77         qmFile2=qmFile;
       
    78         qmFile2 += QString(".qm");        
       
    79 
       
    80         TPtrC ptrFName(reinterpret_cast<const TText*>(qmFile2.constData()));                   
       
    81         err= fl.Open(fs, ptrFName, EFileShareReadersOrWriters | EFileRead | EFileStream );
       
    82         if (err == KErrNotFound) { 
       
    83            if (!doFallback) { // no fallback, then return
       
    84                return 0;
       
    85            }        
       
    86            // else continue
       
    87         } 
       
    88         else {
       
    89             if (err != KErrNone ) { // if some other error return error, don't look anymore
       
    90                 return 0;
       
    91             }
       
    92             else {
       
    93                 break; // file was found
       
    94             }
       
    95         }
       
    96         // do fallback
       
    97         qmFile2 = qmFile;
       
    98         ptrFName.Set((ushort*)(qmFile2.constData()), qmFile2.length());
       
    99         err= fl.Open(fs, ptrFName, EFileShareReadersOrWriters | EFileRead | EFileStream );
       
   100         if (err == KErrNone) {
       
   101             break;
       
   102         }
       
   103         else {
       
   104             if (err != KErrNotFound) {
       
   105                 return 0;
       
   106             }
       
   107         }
       
   108         // check fallback names
       
   109         int rightmost = 0;
       
   110         for (int i=0; i<(int)delims.length(); i++) {
       
   111             int k=qmFile.lastIndexOf(delims[i]);
       
   112             if (k>rightmost) {
       
   113                 rightmost=k;
       
   114             }    
       
   115         }
       
   116 
       
   117         // no truncations? fail
       
   118         if (rightmost==0) {
       
   119             return 0;
       
   120         }
       
   121         qmFile.truncate(rightmost);                
       
   122     }
       
   123     
       
   124     TInt sz;
       
   125     err = fl.Size(sz);
       
   126     if (err != KErrNone) {
       
   127         fl.Close();
       
   128         return 0;
       
   129     }   
       
   130     uchar *buf = new uchar[sz];
       
   131     TPtr8 bufPtr(buf,0,sz); 
       
   132     err = fl.Read(bufPtr, sz);
       
   133     if (err != KErrNone) {
       
   134         fl.Close();
       
   135         return 0;
       
   136     }        
       
   137     fl.Close();
       
   138     if (!translator.load(bufPtr.Ptr(),sz)) {
       
   139         delete buf;
       
   140         return 0;
       
   141     }
       
   142     return buf;
       
   143 #endif    
       
   144 }
    38 
   145 
    39 /*!
   146 /*!
    40     @beta
   147     @beta
    41     @hbcore
   148     @hbcore
    42     \class HbTranslator
   149     \class HbTranslator
    44     and loads translation files into QTranslator.
   151     and loads translation files into QTranslator.
    45 */
   152 */
    46 
   153 
    47 /*!
   154 /*!
    48     Default case: searches translation file from default location (/resource/qt/translations/) with default name, which is <executablename>.qm
   155     Default case: searches translation file from default location (/resource/qt/translations/) with default name, which is <executablename>.qm
       
   156     
       
   157     \attention Cross-Platform API
    49 */
   158 */
    50 HbTranslator::HbTranslator(): d(new HbTranslatorPrivate())
   159 HbTranslator::HbTranslator(): d(new HbTranslatorPrivate())
    51 {
   160 {
    52     QFileInfo info(qApp->applicationFilePath());
   161     QFileInfo info(qApp->applicationFilePath());
    53     QString defaultname = info.baseName();  // defaultname = <executablename>
   162     QString defaultName = info.baseName();  // defaultname = <executablename>
    54     d->installTranslator(defaultpath, defaultname);
   163     d->installTranslator(defaultPath, defaultName);
    55 }
   164 }
    56 
   165 
    57 /*!
   166 /*!
    58     Searches translation file \a file from default location.
   167     Searches translation file \a file from default location.
    59 */
   168     
    60 
   169     \attention Cross-Platform API
       
   170 */
    61 HbTranslator::HbTranslator(const QString &file): d(new HbTranslatorPrivate())
   171 HbTranslator::HbTranslator(const QString &file): d(new HbTranslatorPrivate())
    62 {
   172 {
    63     d->installTranslator(defaultpath, file);
   173     d->installTranslator(defaultPath, file);
    64 }
   174 }
    65 
   175 
    66 /*!
   176 /*!
    67     Searches translation file \a file from path \a path.
   177     Searches translation file \a file from path \a path.
       
   178     
       
   179     \attention Cross-Platform API
       
   180 
    68     \code
   181     \code
    69     HbTranslator trans = new HbTranslator("/resource/qt/custom/", "customfile");
   182     HbTranslator trans("/resource/qt/custom/", "customfile");
    70     \endcode
   183     \endcode
    71 */
   184 */
    72 HbTranslator::HbTranslator(const QString &path, const QString &file): d(new HbTranslatorPrivate())
   185 HbTranslator::HbTranslator(const QString &path, const QString &file): d(new HbTranslatorPrivate())
    73 {
   186 {
    74     d->installTranslator(path, file);
   187     d->installTranslator(path, file);
    79     delete d;
   192     delete d;
    80 }
   193 }
    81 
   194 
    82 /*!
   195 /*!
    83     Loads common.ts translations from default location.
   196     Loads common.ts translations from default location.
       
   197     
       
   198     \attention Cross-Platform API
    84 */
   199 */
    85 void HbTranslator::loadCommon()
   200 void HbTranslator::loadCommon()
    86 {
   201 {    
    87     QString lang = QLocale::system().name();
   202     QString lang = QLocale::system().name();
    88     QString commonts = QString("Z:") + defaultpath + QString("common_") + lang;
   203     QString commonts = QString(defaultDrive) + QString(defaultPath) + QString(defaultCommon) + lang;
    89     d->common.load(commonts);
   204     bool loaded;
    90     qApp->installTranslator(&d->common);
   205     loaded = (d->commonData=loadTranslatorData(d->common, commonts));
       
   206     if (loaded) {
       
   207         qApp->installTranslator(&d->common);    
       
   208     }
    91 }
   209 }
    92 
   210 
    93 // internal function for common operations of HbTranslator
   211 // internal function for common operations of HbTranslator
    94 void HbTranslatorPrivate::installTranslator(const QString &path, const QString &name)
   212 void HbTranslatorPrivate::installTranslator(const QString &pth, const QString &name)
    95 {
   213 {
       
   214     QString path(pth);
       
   215 #ifdef Q_OS_SYMBIAN        
       
   216     toSymbianPath(path);
       
   217 #endif    
    96     QString filepath = qApp->applicationFilePath();
   218     QString filepath = qApp->applicationFilePath();
    97     QChar drive = filepath.at(0);
   219     QChar drive;
       
   220     if (filepath.length()>=2 && filepath.at(1) == ':') {
       
   221         drive = filepath.at(0);
       
   222     }    
       
   223             
    98     QString lang = QLocale::system().name();
   224     QString lang = QLocale::system().name();
    99     QString lang2 = lang;
   225     QString lang2 = lang;
   100     languageDowngrade(lang);
   226     languageDowngrade(lang);
   101     QString tsfile = path + name + QString("_") + lang + QString(".qm");
   227     QString tsfile = path + name + QString("_") + lang;
   102     if (!HbFindFile::hbFindFile(tsfile, drive)) {
   228     QString tsfileQM = tsfile + QString(".qm"); 
   103     	tsfile = path + name + QString("_") + lang2 + QString(".qm");
   229 
   104         HbFindFile::hbFindFile(tsfile);
   230     bool loaded = false;    
   105     }
   231     if (HbFindFile::hbFindFile(tsfileQM, drive)) {
   106     translator.load(tsfile);
   232         tsfileQM.chop(3);        
   107     qApp->installTranslator(&translator);
   233         loaded = (translatorData=loadTranslatorData(translator,tsfileQM));        
   108 }
   234     }
       
   235     else {
       
   236         tsfile = path + name + QString("_") + lang2;
       
   237         tsfileQM = tsfile + QString(".qm");
       
   238         if (HbFindFile::hbFindFile(tsfileQM, drive)) {
       
   239             tsfileQM.chop(3);
       
   240             loaded = (translatorData=loadTranslatorData(translator,tsfileQM));        
       
   241         }
       
   242         else {
       
   243             QList<QString> fallBack;
       
   244             fallBack.append("en");
       
   245             fallBack.append("en_US");
       
   246             int len = fallBack.length();
       
   247             for (int i=0; i<len; i++) {
       
   248                 QString lang;
       
   249                 tsfile = path + name + QString("_") + fallBack.at(i);
       
   250                 tsfileQM = tsfile + QString(".qm");
       
   251                 if (HbFindFile::hbFindFile(tsfileQM, drive)) {
       
   252                     tsfileQM.chop(3);
       
   253                     loaded = (translatorData=loadTranslatorData(translator,tsfileQM));        
       
   254                 }    
       
   255             }        
       
   256         }
       
   257     }
       
   258 
       
   259     if (loaded) {
       
   260         qApp->installTranslator(&translator);
       
   261     }
       
   262 }
       
   263 
       
   264 class LanguageHash : public QHash<QString,QString>
       
   265 {
       
   266 public:
       
   267     LanguageHash();    
       
   268 };
       
   269 
       
   270 LanguageHash::LanguageHash(){
       
   271     (*this)["en_GB"] = "en";
       
   272     (*this)["fr_FR"] = "fr";
       
   273     (*this)["de_DE"] = "de";
       
   274     (*this)["es_ES"] = "es";
       
   275     (*this)["it_IT"] = "it";
       
   276     (*this)["sv_SE"] = "sv";
       
   277     (*this)["da_DK"] = "da";
       
   278     (*this)["no_NO"] = "no";
       
   279     (*this)["fi_FI"] = "fi";
       
   280     (*this)["en_US"] = "en_US";
       
   281     (*this)["pt_PT"] = "pt";
       
   282     (*this)["tr_TR"] = "tr";
       
   283     (*this)["is_IS"] = "is";
       
   284     (*this)["ru_RU"] = "ru";
       
   285     (*this)["hu_HU"] = "hu";
       
   286     (*this)["nl_NL"] = "nl";
       
   287     (*this)["cs_CZ"] = "cs";
       
   288     (*this)["sk_SK"] = "sk";
       
   289     (*this)["pl_PL"] = "pl";
       
   290     (*this)["sl_SI"] = "sl";
       
   291     (*this)["zh_TW"] = "zh_TW";
       
   292     (*this)["zh_HK"] = "zh_HK";
       
   293     (*this)["zh_CN"] = "zh_CN";
       
   294     (*this)["ja_JP"] = "ja";
       
   295     (*this)["th_TH"] = "th";
       
   296     (*this)["ar_AE"] = "ar";
       
   297     (*this)["tl_PH"] = "tl";
       
   298     (*this)["bg_BG"] = "bg";
       
   299     (*this)["ca_ES"] = "ca";
       
   300     (*this)["hr_HR"] = "hr";
       
   301     (*this)["et_EE"] = "et";
       
   302     (*this)["fa_IR"] = "fa";
       
   303     (*this)["fr_CA"] = "fr_CA";
       
   304     (*this)["el_GR"] = "el";
       
   305     (*this)["he_IL"] = "he";
       
   306     (*this)["hi_IN"] = "hi";
       
   307     (*this)["id_ID"] = "id";
       
   308     (*this)["ko_KR"] = "ko";
       
   309     (*this)["lv_LV"] = "lv";
       
   310     (*this)["lt_LT"] = "lt";
       
   311     (*this)["ms_MY"] = "ms";
       
   312     (*this)["pt_BR"] = "pt_BR";
       
   313     (*this)["ro_RO"] = "ro";
       
   314     (*this)["sr_YU"] = "sr";
       
   315     (*this)["es_MX"] = "es_MX"; //!!
       
   316     (*this)["uk_UA"] = "uk";
       
   317     (*this)["ur_PK"] = "ur";
       
   318     (*this)["vi_VN"] = "vi";
       
   319     (*this)["eu_ES"] = "eu";
       
   320     (*this)["gl_ES"] = "gl";
       
   321     
       
   322 }
       
   323                          
       
   324 Q_GLOBAL_STATIC(LanguageHash, gs_LanguageHash)
   109 
   325 
   110 // internal function for solving conflict between QLocale::system().name() and actual ts file naming convention.
   326 // internal function for solving conflict between QLocale::system().name() and actual ts file naming convention.
   111 bool HbTranslatorPrivate::languageDowngrade(QString &lang)
   327 bool HbTranslatorPrivate::languageDowngrade(QString &lang)
   112 {
   328 {
   113     static QHash<QString, QString> languages;
   329     QHash<QString,QString> *languageHash = gs_LanguageHash();
   114     languages["en_GB"] = "en";
   330     if (languageHash) {
   115     languages["fr_FR"] = "fr";
   331         if (languageHash->contains(lang)) {
   116     languages["de_DE"] = "de";
   332            lang  = languageHash->value(lang);
   117     languages["es_ES"] = "es";
   333            return true;
   118     languages["it_IT"] = "it";
   334         }                
   119     languages["sv_SE"] = "sv";
       
   120     languages["da_DK"] = "da";
       
   121     languages["no_NO"] = "no";
       
   122     languages["fi_FI"] = "fi";
       
   123     languages["en_US"] = "en_US";
       
   124     languages["pt_PT"] = "pt";
       
   125     languages["tr_TR"] = "tr";
       
   126     languages["is_IS"] = "is";
       
   127     languages["ru_RU"] = "ru";
       
   128     languages["hu_HU"] = "hu";
       
   129     languages["nl_NL"] = "nl";
       
   130     languages["cs_CZ"] = "cs";
       
   131     languages["sk_SK"] = "sk";
       
   132     languages["pl_PL"] = "pl";
       
   133     languages["sl_SI"] = "sl";
       
   134     languages["zh_TW"] = "zh_TW";
       
   135     languages["zh_HK"] = "zh_HK";
       
   136     languages["zh_CN"] = "zh_CN";
       
   137     languages["ja_JP"] = "ja";
       
   138     languages["th_TH"] = "th";
       
   139     languages["ar_AE"] = "ar";
       
   140     languages["tl_PH"] = "tl";
       
   141     languages["bg_BG"] = "bg";
       
   142     languages["ca_ES"] = "ca";
       
   143     languages["hr_HR"] = "hr";
       
   144     languages["et_EE"] = "et";
       
   145     languages["fa_IR"] = "fa";
       
   146     languages["fr_CA"] = "fr_CA";
       
   147     languages["el_GR"] = "el";
       
   148     languages["he_IL"] = "he";
       
   149     languages["hi_IN"] = "hi";
       
   150     languages["id_ID"] = "id";
       
   151     languages["ko_KR"] = "ko";
       
   152     languages["lv_LV"] = "lv";
       
   153     languages["lt_LT"] = "lt";
       
   154     languages["ms_MY"] = "ms";
       
   155     languages["pt_BR"] = "pt_BR";
       
   156     languages["ro_RO"] = "ro";
       
   157     languages["sr_YU"] = "sr";
       
   158     languages["es_MX"] = "es_MX"; //!!
       
   159     languages["uk_UA"] = "uk";
       
   160     languages["ur_PK"] = "ur";
       
   161     languages["vi_VN"] = "vi";
       
   162     languages["eu_ES"] = "eu";
       
   163     languages["gl_ES"] = "gl";
       
   164     
       
   165     if (languages.contains(lang)) {
       
   166     	lang  = languages.value(lang);
       
   167     	return true;
       
   168     }
   335     }
   169     return false;
   336     return false;
   170 }
   337 }