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 } |