Changeset 846 for trunk/tools/linguist/shared
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/tools/linguist/shared/abstractproitemvisitor.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/numerus.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 65 65 { Q_EQ, 1, Q_NEWRULE, 66 66 Q_EQ, 2 }; 67 static const uchar slovak Rules[] =67 static const uchar slovakStyleRules[] = 68 68 { Q_EQ, 1, Q_NEWRULE, 69 69 Q_BETWEEN, 2, 4 }; … … 101 101 Q_EQ, 2, Q_NEWRULE, 102 102 Q_MOD_100 | Q_BETWEEN, 3, 10, Q_NEWRULE, 103 Q_MOD_100 | Q_ NOT | Q_BETWEEN, 0, 2};103 Q_MOD_100 | Q_GEQ, 11 }; 104 104 static const uchar tagalogRules[] = 105 105 { Q_LEQ, 1, Q_NEWRULE, … … 115 115 static const char * const latvianForms[] = { "Singular", "Plural", "Nullar", 0 }; 116 116 static const char * const irishStyleForms[] = { "Singular", "Dual", "Plural", 0 }; 117 static const char * const slovak Forms[] = { "Singular", "Paucal", "Plural", 0 };117 static const char * const slovakStyleForms[] = { "Singular", "Paucal", "Plural", 0 }; 118 118 static const char * const macedonianForms[] = { "Singular", "Dual", "Plural", 0 }; 119 119 static const char * const lithuanianForms[] = { "Singular", "Paucal", "Plural", 0 }; … … 280 280 EOL 281 281 }; 282 static const QLocale::Language slovak Languages[] = { QLocale::Slovak, QLocale::Czech, EOL };282 static const QLocale::Language slovakStyleLanguages[] = { QLocale::Slovak, QLocale::Czech, EOL }; 283 283 static const QLocale::Language macedonianLanguage[] = { QLocale::Macedonian, EOL }; 284 284 static const QLocale::Language lithuanianLanguage[] = { QLocale::Lithuanian, EOL }; … … 319 319 const QLocale::Language *languages; 320 320 const QLocale::Country *countries; 321 const char * const gettextRules; 321 322 }; 322 323 323 324 static const NumerusTableEntry numerusTable[] = { 324 { 0, 0, japaneseStyleForms, japaneseStyleLanguages, 0 }, 325 { englishStyleRules, sizeof(englishStyleRules), englishStyleForms, englishStyleLanguages, 0 }, 325 { 0, 0, japaneseStyleForms, japaneseStyleLanguages, 0, "nplurals=1; plural=0;" }, 326 { englishStyleRules, sizeof(englishStyleRules), englishStyleForms, englishStyleLanguages, 0, 327 "nplurals=2; plural=(n != 1);" }, 326 328 { frenchStyleRules, sizeof(frenchStyleRules), frenchStyleForms, frenchStyleLanguages, 327 frenchStyleCountries }, 328 { latvianRules, sizeof(latvianRules), latvianForms, latvianLanguage, 0 }, 329 { icelandicRules, sizeof(icelandicRules), icelandicForms, icelandicLanguage, 0 }, 330 { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0 }, 331 { slovakRules, sizeof(slovakRules), slovakForms, slovakLanguages, 0 }, 332 { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0 }, 333 { lithuanianRules, sizeof(lithuanianRules), lithuanianForms, lithuanianLanguage, 0 }, 334 { russianStyleRules, sizeof(russianStyleRules), russianStyleForms, russianStyleLanguages, 0 }, 335 { polishRules, sizeof(polishRules), polishForms, polishLanguage, 0 }, 336 { romanianRules, sizeof(romanianRules), romanianForms, romanianLanguages, 0 }, 337 { slovenianRules, sizeof(slovenianRules), slovenianForms, slovenianLanguage, 0 }, 338 { malteseRules, sizeof(malteseRules), malteseForms, malteseLanguage, 0 }, 339 { welshRules, sizeof(welshRules), welshForms, welshLanguage, 0 }, 340 { arabicRules, sizeof(arabicRules), arabicForms, arabicLanguage, 0 }, 341 { tagalogRules, sizeof(tagalogRules), tagalogForms, tagalogLanguage, 0 }, 342 { catalanRules, sizeof(catalanRules), catalanForms, catalanLanguage, 0 } 329 frenchStyleCountries, "nplurals=2; plural=(n > 1);" }, 330 { latvianRules, sizeof(latvianRules), latvianForms, latvianLanguage, 0, 331 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" }, 332 { icelandicRules, sizeof(icelandicRules), icelandicForms, icelandicLanguage, 0, 333 "nplurals=2; plural=(n%10==1 && n%100!=11 ? 0 : 1);" }, 334 { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0, 335 "nplurals=3; plural=(n==1 ? 0 : n==2 ? 1 : 2);" }, 336 { slovakStyleRules, sizeof(slovakStyleRules), slovakStyleForms, slovakStyleLanguages, 0, 337 "nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);" }, 338 { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0, 339 "nplurals=3; plural=(n%100==1 ? 0 : n%100==2 ? 1 : 2);" }, 340 { lithuanianRules, sizeof(lithuanianRules), lithuanianForms, lithuanianLanguage, 0, 341 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" }, 342 { russianStyleRules, sizeof(russianStyleRules), russianStyleForms, russianStyleLanguages, 0, 343 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }, 344 { polishRules, sizeof(polishRules), polishForms, polishLanguage, 0, 345 "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }, 346 { romanianRules, sizeof(romanianRules), romanianForms, romanianLanguages, 0, 347 "nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);" }, 348 { slovenianRules, sizeof(slovenianRules), slovenianForms, slovenianLanguage, 0, 349 "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" }, 350 { malteseRules, sizeof(malteseRules), malteseForms, malteseLanguage, 0, 351 "nplurals=4; plural=(n==1 ? 0 : (n==0 || (n%100>=1 && n%100<=10)) ? 1 : (n%100>=11 && n%100<=19) ? 2 : 3);" }, 352 { welshRules, sizeof(welshRules), welshForms, welshLanguage, 0, 353 "nplurals=5; plural=(n==0 ? 0 : n==1 ? 1 : (n>=2 && n<=5) ? 2 : n==6 ? 3 : 4);" }, 354 { arabicRules, sizeof(arabicRules), arabicForms, arabicLanguage, 0, 355 "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : (n%100>=3 && n%100<=10) ? 3 : n%100>=11 ? 4 : 5);" }, 356 { tagalogRules, sizeof(tagalogRules), tagalogForms, tagalogLanguage, 0, 357 "nplurals=3; plural=(n==1 ? 0 : (n%10==4 || n%10==6 || n%10== 9) ? 1 : 2);" }, 358 { catalanRules, sizeof(catalanRules), catalanForms, catalanLanguage, 0, 359 "nplurals=3; plural=(n==1 ? 0 : (n==11 || n/1000==11 || n/1000000==11 || n/1000000000==11) ? 1 : 2);" }, 343 360 }; 344 361 … … 353 370 354 371 bool getNumerusInfo(QLocale::Language language, QLocale::Country country, 355 QByteArray *rules, QStringList *forms)372 QByteArray *rules, QStringList *forms, const char **gettextRules) 356 373 { 357 374 while (true) { … … 366 383 entry.rulesSize); 367 384 } 385 if (gettextRules) 386 *gettextRules = entry.gettextRules; 368 387 if (forms) { 369 388 forms->clear(); -
trunk/tools/linguist/shared/po.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 46 46 #include <QtCore/QHash> 47 47 #include <QtCore/QString> 48 #include <QtCore/QTextCodec> 48 49 #include <QtCore/QTextStream> 49 50 50 51 #include <ctype.h> 51 52 #define MAGIC_OBSOLETE_REFERENCE "Obsolete_PO_entries"53 52 54 53 // Uncomment if you wish to hard wrap long lines in .po files. Note that this … … 202 201 203 202 public: 204 Q Stringid;205 Q Stringcontext;206 Q Stringtscomment;207 Q StringoldTscomment;208 Q StringlineNumber;209 Q StringfileName;210 Q Stringreferences;211 Q StringtranslatorComments;212 Q StringautomaticComments;213 Q StringmsgId;214 Q StringoldMsgId;215 Q StringListmsgStr;203 QByteArray id; 204 QByteArray context; 205 QByteArray tscomment; 206 QByteArray oldTscomment; 207 QByteArray lineNumber; 208 QByteArray fileName; 209 QByteArray references; 210 QByteArray translatorComments; 211 QByteArray automaticComments; 212 QByteArray msgId; 213 QByteArray oldMsgId; 214 QList<QByteArray> msgStr; 216 215 bool isPlural; 217 216 bool isFuzzy; … … 220 219 221 220 222 static bool isTranslationLine(const QString &line) 223 { 224 return line.startsWith(QLatin1String("#~ msgstr")) 225 || line.startsWith(QLatin1String("msgstr")); 226 } 227 228 static QString slurpEscapedString(const QStringList &lines, int & l, 229 int offset, const QString &prefix, ConversionData &cd) 230 { 231 QString msg; 221 static bool isTranslationLine(const QByteArray &line) 222 { 223 return line.startsWith("#~ msgstr") || line.startsWith("msgstr"); 224 } 225 226 static QByteArray slurpEscapedString(const QList<QByteArray> &lines, int &l, 227 int offset, const QByteArray &prefix, ConversionData &cd) 228 { 229 QByteArray msg; 232 230 int stoff; 233 231 234 232 for (; l < lines.size(); ++l) { 235 const Q String&line = lines.at(l);233 const QByteArray &line = lines.at(l); 236 234 if (line.isEmpty() || !line.startsWith(prefix)) 237 235 break; 238 while ( line[offset].isSpace()) // No length check, as string has no trailing spaces.236 while (isspace(line[offset])) // No length check, as string has no trailing spaces. 239 237 offset++; 240 if (line[offset] .unicode()!= '"')238 if (line[offset] != '"') 241 239 break; 242 240 offset++; … … 244 242 if (offset == line.length()) 245 243 goto premature_eol; 246 u short c = line[offset++].unicode();244 uchar c = line[offset++]; 247 245 if (c == '"') { 248 246 if (offset == line.length()) 249 247 break; 250 while ( line[offset].isSpace())248 while (isspace(line[offset])) 251 249 offset++; 252 if (line[offset++] .unicode()!= '"') {250 if (line[offset++] != '"') { 253 251 cd.appendError(QString::fromLatin1( 254 252 "PO parsing error: extra characters on line %1.") … … 261 259 if (offset == line.length()) 262 260 goto premature_eol; 263 c = line[offset++] .unicode();261 c = line[offset++]; 264 262 switch (c) { 265 263 case 'r': 266 msg += QLatin1Char('\r'); // Maybe just throw it away?264 msg += '\r'; // Maybe just throw it away? 267 265 break; 268 266 case 'n': 269 msg += QLatin1Char('\n');267 msg += '\n'; 270 268 break; 271 269 case 't': 272 msg += QLatin1Char('\t');270 msg += '\t'; 273 271 break; 274 272 case 'v': 275 msg += QLatin1Char('\v');273 msg += '\v'; 276 274 break; 277 275 case 'a': 278 msg += QLatin1Char('\a');276 msg += '\a'; 279 277 break; 280 278 case 'b': 281 msg += QLatin1Char('\b');279 msg += '\b'; 282 280 break; 283 281 case 'f': 284 msg += QLatin1Char('\f');282 msg += '\f'; 285 283 break; 286 284 case '"': 287 msg += QLatin1Char('"');285 msg += '"'; 288 286 break; 289 287 case '\\': 290 msg += QLatin1Char('\\');288 msg += '\\'; 291 289 break; 292 290 case '0': … … 299 297 case '7': 300 298 stoff = offset - 1; 301 while ((c = line[offset] .unicode()) >= '0' && c <= '7')299 while ((c = line[offset]) >= '0' && c <= '7') 302 300 if (++offset == line.length()) 303 301 goto premature_eol; 304 msg += QChar(line.mid(stoff, offset - stoff).toUInt(0, 8));302 msg += line.mid(stoff, offset - stoff).toUInt(0, 8); 305 303 break; 306 304 case 'x': 307 305 stoff = offset; 308 while (isxdigit(line[offset] .unicode()))306 while (isxdigit(line[offset])) 309 307 if (++offset == line.length()) 310 308 goto premature_eol; 311 msg += QChar(line.mid(stoff, offset - stoff).toUInt(0, 16));309 msg += line.mid(stoff, offset - stoff).toUInt(0, 16); 312 310 break; 313 311 default: 314 312 cd.appendError(QString::fromLatin1( 315 313 "PO parsing error: invalid escape '\\%1' (line %2).") 316 .arg(QChar( c)).arg(l + 1));317 msg += QLatin1Char('\\');318 msg += QChar(c);314 .arg(QChar((uint)c)).arg(l + 1)); 315 msg += '\\'; 316 msg += c; 319 317 break; 320 318 } 321 319 } else { 322 msg += QChar(c);320 msg += c; 323 321 } 324 322 } … … 331 329 cd.appendError(QString::fromLatin1( 332 330 "PO parsing error: premature end of line %1.").arg(l + 1)); 333 return QString(); 334 } 335 336 static void slurpComment(QString &msg, const QStringList &lines, int & l) 337 { 338 const QChar newline = QLatin1Char('\n'); 339 QString prefix = lines.at(l); 331 return QByteArray(); 332 } 333 334 static void slurpComment(QByteArray &msg, const QList<QByteArray> &lines, int & l) 335 { 336 QByteArray prefix = lines.at(l); 340 337 for (int i = 1; ; i++) { 341 if (prefix.at(i) .unicode()!= ' ') {338 if (prefix.at(i) != ' ') { 342 339 prefix.truncate(i); 343 340 break; … … 345 342 } 346 343 for (; l < lines.size(); ++l) { 347 const Q String&line = lines.at(l);344 const QByteArray &line = lines.at(l); 348 345 if (line.startsWith(prefix)) 349 346 msg += line.mid(prefix.size()); 350 else if (line != QLatin1String("#"))351 break; 352 msg += newline;347 else if (line != "#") 348 break; 349 msg += '\n'; 353 350 } 354 351 --l; 355 352 } 356 353 354 static void splitContext(QByteArray *comment, QByteArray *context) 355 { 356 char *data = comment->data(); 357 int len = comment->size(); 358 int sep = -1, j = 0; 359 360 for (int i = 0; i < len; i++, j++) { 361 if (data[i] == '~' && i + 1 < len) 362 i++; 363 else if (data[i] == '|') 364 sep = j; 365 data[j] = data[i]; 366 } 367 if (sep >= 0) { 368 QByteArray tmp = comment->mid(sep + 1, j - sep - 1); 369 comment->truncate(sep); 370 *context = *comment; 371 *comment = tmp; 372 } else { 373 comment->truncate(j); 374 } 375 } 376 377 static QString makePoHeader(const QString &str) 378 { 379 return QLatin1String("po-header-") + str.toLower().replace(QLatin1Char('-'), QLatin1Char('_')); 380 } 381 382 static QByteArray QByteArrayList_join(const QList<QByteArray> &that, char sep) 383 { 384 int totalLength = 0; 385 const int size = that.size(); 386 387 for (int i = 0; i < size; ++i) 388 totalLength += that.at(i).size(); 389 390 if (size > 0) 391 totalLength += size - 1; 392 393 QByteArray res; 394 if (totalLength == 0) 395 return res; 396 res.reserve(totalLength); 397 for (int i = 0; i < that.size(); ++i) { 398 if (i) 399 res += sep; 400 res += that.at(i); 401 } 402 return res; 403 } 404 357 405 bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) 358 406 { 359 const QChar quote = QLatin1Char('"'); 360 const QChar newline = QLatin1Char('\n'); 361 QTextStream in(&dev); 362 in.setCodec(cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); 407 QTextCodec *codec = QTextCodec::codecForName( 408 cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); 363 409 bool error = false; 364 410 … … 381 427 382 428 // we need line based lookahead below. 383 QStringList lines; 384 while (!in.atEnd()) 385 lines.append(in.readLine().trimmed()); 386 lines.append(QString()); 387 388 int l = 0; 429 QList<QByteArray> lines; 430 while (!dev.atEnd()) 431 lines.append(dev.readLine().trimmed()); 432 lines.append(QByteArray()); 433 434 int l = 0, lastCmtLine = -1; 435 bool qtContexts = false; 389 436 PoItem item; 390 437 for (; l != lines.size(); ++l) { 391 Q Stringline = lines.at(l);438 QByteArray line = lines.at(l); 392 439 if (line.isEmpty()) 393 440 continue; 394 441 if (isTranslationLine(line)) { 395 bool isObsolete = line.startsWith( QLatin1String("#~ msgstr"));396 const Q String prefix = QLatin1String(isObsolete ? "#~ " : "");442 bool isObsolete = line.startsWith("#~ msgstr"); 443 const QByteArray prefix = isObsolete ? "#~ " : ""; 397 444 while (true) { 398 int idx = line.indexOf(QLatin1Char(' '), prefix.length()); 399 QString str = slurpEscapedString(lines, l, idx, prefix, cd); 445 int idx = line.indexOf(' ', prefix.length()); 446 QByteArray str = slurpEscapedString(lines, l, idx, prefix, cd); 447 item.msgStr.append(str); 448 if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1))) 449 break; 450 ++l; 451 line = lines.at(l); 452 } 453 if (item.msgId.isEmpty()) { 454 QHash<QString, QByteArray> extras; 455 QList<QByteArray> hdrOrder; 456 QByteArray pluralForms; 457 foreach (const QByteArray &hdr, item.msgStr.first().split('\n')) { 458 if (hdr.isEmpty()) 459 continue; 460 int idx = hdr.indexOf(':'); 461 if (idx < 0) { 462 cd.appendError(QString::fromLatin1("Unexpected PO header format '%1'") 463 .arg(QString::fromLatin1(hdr))); 464 error = true; 465 break; 466 } 467 QByteArray hdrName = hdr.left(idx).trimmed(); 468 QByteArray hdrValue = hdr.mid(idx + 1).trimmed(); 469 hdrOrder << hdrName; 470 if (hdrName == "X-Language") { 471 translator.setLanguageCode(QString::fromLatin1(hdrValue)); 472 } else if (hdrName == "X-Source-Language") { 473 translator.setSourceLanguageCode(QString::fromLatin1(hdrValue)); 474 } else if (hdrName == "X-Qt-Contexts") { 475 qtContexts = (hdrValue == "true"); 476 } else if (hdrName == "Plural-Forms") { 477 pluralForms = hdrValue; 478 } else if (hdrName == "MIME-Version") { 479 // just assume it is 1.0 480 } else if (hdrName == "Content-Type") { 481 if (cd.m_codecForSource.isEmpty()) { 482 if (!hdrValue.startsWith("text/plain; charset=")) { 483 cd.appendError(QString::fromLatin1("Unexpected Content-Type header '%1'") 484 .arg(QString::fromLatin1(hdrValue))); 485 error = true; 486 // This will avoid a flood of conversion errors. 487 codec = QTextCodec::codecForName("latin1"); 488 } else { 489 QByteArray cod = hdrValue.mid(20); 490 QTextCodec *cdc = QTextCodec::codecForName(cod); 491 if (!cdc) { 492 cd.appendError(QString::fromLatin1("Unsupported codec '%1'") 493 .arg(QString::fromLatin1(cod))); 494 error = true; 495 // This will avoid a flood of conversion errors. 496 codec = QTextCodec::codecForName("latin1"); 497 } else { 498 codec = cdc; 499 } 500 } 501 } 502 } else if (hdrName == "Content-Transfer-Encoding") { 503 if (hdrValue != "8bit") { 504 cd.appendError(QString::fromLatin1("Unexpected Content-Transfer-Encoding '%1'") 505 .arg(QString::fromLatin1(hdrValue))); 506 return false; 507 } 508 } else if (hdrName == "X-Virgin-Header") { 509 // legacy 510 } else { 511 extras[makePoHeader(QString::fromLatin1(hdrName))] = hdrValue; 512 } 513 } 514 if (!pluralForms.isEmpty()) { 515 if (translator.languageCode().isEmpty()) { 516 extras[makePoHeader(QLatin1String("Plural-Forms"))] = pluralForms; 517 } else { 518 // FIXME: have fun with making a consistency check ... 519 } 520 } 521 // Eliminate the field if only headers we added are present in standard order. 522 // Keep in sync with savePO 523 static const char * const dfltHdrs[] = { 524 "MIME-Version", "Content-Type", "Content-Transfer-Encoding", 525 "Plural-Forms", "X-Language", "X-Source-Language", "X-Qt-Contexts" 526 }; 527 uint cdh = 0; 528 for (int cho = 0; cho < hdrOrder.length(); cho++) { 529 for (;; cdh++) { 530 if (cdh == sizeof(dfltHdrs)/sizeof(dfltHdrs[0])) { 531 extras[QLatin1String("po-headers")] = 532 QByteArrayList_join(hdrOrder, ','); 533 goto doneho; 534 } 535 if (hdrOrder.at(cho) == dfltHdrs[cdh]) { 536 cdh++; 537 break; 538 } 539 } 540 } 541 doneho: 542 if (lastCmtLine != -1) 543 extras[QLatin1String("po-header_comment")] = 544 QByteArrayList_join(lines.mid(0, lastCmtLine + 1), '\n'); 545 for (QHash<QString, QByteArray>::ConstIterator it = extras.constBegin(), 546 end = extras.constEnd(); 547 it != end; ++it) 548 translator.setExtra(it.key(), codec->toUnicode(it.value())); 549 item = PoItem(); 550 continue; 551 } 552 // build translator message 553 TranslatorMessage msg; 554 msg.setContext(codec->toUnicode(item.context)); 555 if (!item.references.isEmpty()) { 556 QString xrefs; 557 foreach (const QString &ref, 558 codec->toUnicode(item.references).split( 559 QRegExp(QLatin1String("\\s")), QString::SkipEmptyParts)) { 560 int pos = ref.indexOf(QLatin1Char(':')); 561 int lpos = ref.lastIndexOf(QLatin1Char(':')); 562 if (pos != -1 && pos == lpos) { 563 bool ok; 564 int lno = ref.mid(pos + 1).toInt(&ok); 565 if (ok) { 566 msg.addReference(ref.left(pos), lno); 567 continue; 568 } 569 } 570 if (!xrefs.isEmpty()) 571 xrefs += QLatin1Char(' '); 572 xrefs += ref; 573 } 574 if (!xrefs.isEmpty()) 575 item.extra[QLatin1String("po-references")] = xrefs; 576 } 577 msg.setId(codec->toUnicode(item.id)); 578 msg.setSourceText(codec->toUnicode(item.msgId)); 579 msg.setOldSourceText(codec->toUnicode(item.oldMsgId)); 580 msg.setComment(codec->toUnicode(item.tscomment)); 581 msg.setOldComment(codec->toUnicode(item.oldTscomment)); 582 msg.setExtraComment(codec->toUnicode(item.automaticComments)); 583 msg.setTranslatorComment(codec->toUnicode(item.translatorComments)); 584 msg.setPlural(item.isPlural || item.msgStr.size() > 1); 585 QStringList translations; 586 foreach (const QByteArray &bstr, item.msgStr) { 587 QString str = codec->toUnicode(bstr); 400 588 str.replace(QChar(Translator::TextVariantSeparator), 401 589 QChar(Translator::BinaryVariantSeparator)); 402 item.msgStr.append(str); 403 if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1))) 404 break; 405 ++l; 406 line = lines.at(l); 407 } 408 if (item.msgId.isEmpty()) { 409 QRegExp rx(QLatin1String("\\bX-Language: ([^\n]*)\n")); 410 int idx = rx.indexIn(item.msgStr.first()); 411 if (idx >= 0) { 412 translator.setLanguageCode(rx.cap(1)); 413 item.msgStr.first().remove(idx, rx.matchedLength()); 414 } 415 QRegExp rx2(QLatin1String("\\bX-Source-Language: ([^\n]*)\n")); 416 int idx2 = rx2.indexIn(item.msgStr.first()); 417 if (idx2 >= 0) { 418 translator.setSourceLanguageCode(rx2.cap(1)); 419 item.msgStr.first().remove(idx2, rx2.matchedLength()); 420 } 421 if (item.msgStr.first().indexOf( 422 QRegExp(QLatin1String("\\bX-Virgin-Header:[^\n]*\n"))) >= 0) { 423 item = PoItem(); 424 continue; 425 } 426 } 427 // build translator message 428 TranslatorMessage msg; 429 msg.setContext(item.context); 430 if (!item.references.isEmpty()) { 431 foreach (const QString &ref, 432 item.references.split(QRegExp(QLatin1String("\\s")), 433 QString::SkipEmptyParts)) { 434 int pos = ref.lastIndexOf(QLatin1Char(':')); 435 if (pos != -1) 436 msg.addReference(ref.left(pos), ref.mid(pos + 1).toInt()); 437 } 438 } else if (isObsolete) { 439 msg.setFileName(QLatin1String(MAGIC_OBSOLETE_REFERENCE)); 440 } 441 msg.setId(item.id); 442 msg.setSourceText(item.msgId); 443 msg.setOldSourceText(item.oldMsgId); 444 msg.setComment(item.tscomment); 445 msg.setOldComment(item.oldTscomment); 446 msg.setExtraComment(item.automaticComments); 447 msg.setTranslatorComment(item.translatorComments); 448 msg.setPlural(item.isPlural || item.msgStr.size() > 1); 449 msg.setTranslations(item.msgStr); 590 translations << str; 591 } 592 msg.setTranslations(translations); 450 593 if (isObsolete) 451 594 msg.setType(TranslatorMessage::Obsolete); 452 else if (item.isFuzzy )595 else if (item.isFuzzy || (!msg.sourceText().isEmpty() && !msg.isTranslated())) 453 596 msg.setType(TranslatorMessage::Unfinished); 454 597 else … … 461 604 translator.append(msg); 462 605 item = PoItem(); 463 } else if (line.startsWith( QLatin1Char('#'))) {464 switch (line.size() < 2 ? 0 : line.at(1).unicode()) {606 } else if (line.startsWith('#')) { 607 switch (line.size() < 2 ? 0 : line.at(1)) { 465 608 case ':': 466 609 item.references += line.mid(3); 467 item.references += newline;610 item.references += '\n'; 468 611 break; 469 612 case ',': { 470 613 QStringList flags = 471 line.mid(2).split(QRegExp(QLatin1String("[, ]")),472 614 QString::fromLatin1(line.mid(2)).split( 615 QRegExp(QLatin1String("[, ]")), QString::SkipEmptyParts); 473 616 if (flags.removeOne(QLatin1String("fuzzy"))) 474 617 item.isFuzzy = true; 618 flags.removeOne(QLatin1String("qt-format")); 475 619 TranslatorMessage::ExtraData::const_iterator it = 476 620 item.extra.find(QLatin1String("po-flags")); … … 482 626 } 483 627 case 0: 484 item.translatorComments += newline;628 item.translatorComments += '\n'; 485 629 break; 486 630 case ' ': … … 488 632 break; 489 633 case '.': 490 if (line.startsWith( QLatin1String("#. ts-context "))) {634 if (line.startsWith("#. ts-context ")) { // legacy 491 635 item.context = line.mid(14); 492 } else if (line.startsWith( QLatin1String("#. ts-id "))) {636 } else if (line.startsWith("#. ts-id ")) { 493 637 item.id = line.mid(9); 494 638 } else { 495 639 item.automaticComments += line.mid(3); 496 item.automaticComments += newline;640 item.automaticComments += '\n'; 497 641 } 498 642 break; 499 643 case '|': 500 if (line.startsWith( QLatin1String("#| msgid "))) {501 item.oldMsgId = slurpEscapedString(lines, l, 9, QLatin1String("#| "), cd);502 } else if (line.startsWith( QLatin1String("#| msgid_plural "))) {503 Q String extra = slurpEscapedString(lines, l, 16, QLatin1String("#| "), cd);644 if (line.startsWith("#| msgid ")) { 645 item.oldMsgId = slurpEscapedString(lines, l, 9, "#| ", cd); 646 } else if (line.startsWith("#| msgid_plural ")) { 647 QByteArray extra = slurpEscapedString(lines, l, 16, "#| ", cd); 504 648 if (extra != item.oldMsgId) 505 item.extra[QLatin1String("po-old_msgid_plural")] = extra; 506 } else if (line.startsWith(QLatin1String("#| msgctxt "))) { 507 item.oldTscomment = slurpEscapedString(lines, l, 11, QLatin1String("#| "), cd); 649 item.extra[QLatin1String("po-old_msgid_plural")] = 650 codec->toUnicode(extra); 651 } else if (line.startsWith("#| msgctxt ")) { 652 item.oldTscomment = slurpEscapedString(lines, l, 11, "#| ", cd); 653 if (qtContexts) 654 splitContext(&item.oldTscomment, &item.context); 508 655 } else { 509 cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2' \n"))510 .arg(l + 1).arg( lines[l]));656 cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'")) 657 .arg(l + 1).arg(codec->toUnicode(lines[l]))); 511 658 error = true; 512 659 } 513 660 break; 514 661 case '~': 515 if (line.startsWith( QLatin1String("#~ msgid "))) {516 item.msgId = slurpEscapedString(lines, l, 9, QLatin1String("#~ "), cd);517 } else if (line.startsWith( QLatin1String("#~ msgid_plural "))) {518 Q String extra = slurpEscapedString(lines, l, 16, QLatin1String("#~ "), cd);662 if (line.startsWith("#~ msgid ")) { 663 item.msgId = slurpEscapedString(lines, l, 9, "#~ ", cd); 664 } else if (line.startsWith("#~ msgid_plural ")) { 665 QByteArray extra = slurpEscapedString(lines, l, 16, "#~ ", cd); 519 666 if (extra != item.msgId) 520 item.extra[QLatin1String("po-msgid_plural")] = extra; 667 item.extra[QLatin1String("po-msgid_plural")] = 668 codec->toUnicode(extra); 521 669 item.isPlural = true; 522 } else if (line.startsWith(QLatin1String("#~ msgctxt "))) { 523 item.tscomment = slurpEscapedString(lines, l, 11, QLatin1String("#~ "), cd); 670 } else if (line.startsWith("#~ msgctxt ")) { 671 item.tscomment = slurpEscapedString(lines, l, 11, "#~ ", cd); 672 if (qtContexts) 673 splitContext(&item.tscomment, &item.context); 524 674 } else { 525 cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2' \n"))526 .arg(l + 1).arg( lines[l]));675 cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'")) 676 .arg(l + 1).arg(codec->toUnicode(lines[l]))); 527 677 error = true; 528 678 } 529 679 break; 530 680 default: 531 cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2' \n"))532 .arg(l + 1).arg( lines[l]));681 cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'")) 682 .arg(l + 1).arg(codec->toUnicode(lines[l]))); 533 683 error = true; 534 684 break; 535 685 } 536 } else if (line.startsWith(QLatin1String("msgctxt "))) { 537 item.tscomment = slurpEscapedString(lines, l, 8, QString(), cd); 538 } else if (line.startsWith(QLatin1String("msgid "))) { 539 item.msgId = slurpEscapedString(lines, l, 6, QString(), cd); 540 } else if (line.startsWith(QLatin1String("msgid_plural "))) { 541 QString extra = slurpEscapedString(lines, l, 13, QString(), cd); 686 lastCmtLine = l; 687 } else if (line.startsWith("msgctxt ")) { 688 item.tscomment = slurpEscapedString(lines, l, 8, QByteArray(), cd); 689 if (qtContexts) 690 splitContext(&item.tscomment, &item.context); 691 } else if (line.startsWith("msgid ")) { 692 item.msgId = slurpEscapedString(lines, l, 6, QByteArray(), cd); 693 } else if (line.startsWith("msgid_plural ")) { 694 QByteArray extra = slurpEscapedString(lines, l, 13, QByteArray(), cd); 542 695 if (extra != item.msgId) 543 item.extra[QLatin1String("po-msgid_plural")] = extra;696 item.extra[QLatin1String("po-msgid_plural")] = codec->toUnicode(extra); 544 697 item.isPlural = true; 545 698 } else { 546 cd.appendError(QString(QLatin1String("PO-format error in line %1: '%2' \n"))547 .arg(l + 1).arg( lines[l]));699 cd.appendError(QString(QLatin1String("PO-format error in line %1: '%2'")) 700 .arg(l + 1).arg(codec->toUnicode(lines[l]))); 548 701 error = true; 549 702 } … … 552 705 } 553 706 707 static void addPoHeader(Translator::ExtraData &headers, QStringList &hdrOrder, 708 const char *name, const QString &value) 709 { 710 QString qName = QLatin1String(name); 711 if (!hdrOrder.contains(qName)) 712 hdrOrder << qName; 713 headers[makePoHeader(qName)] = value; 714 } 715 716 static QString escapeComment(const QString &in, bool escape) 717 { 718 QString out = in; 719 if (escape) { 720 out.replace(QLatin1Char('~'), QLatin1String("~~")); 721 out.replace(QLatin1Char('|'), QLatin1String("~|")); 722 } 723 return out; 724 } 725 554 726 bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) 555 727 { 728 QString str_format = QLatin1String("-format"); 729 556 730 bool ok = true; 557 731 QTextStream out(&dev); 558 732 out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec); 559 733 560 bool first = true; 561 if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) { 562 out << 563 "# SOME DESCRIPTIVE TITLE.\n" 564 "# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n" 565 "# This file is distributed under the same license as the PACKAGE package.\n" 566 "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n" 567 "#\n" 568 "#, fuzzy\n" 569 "msgid \"\"\n" 570 "msgstr \"\"\n" 571 "\"X-Virgin-Header: remove this line if you change anything in the header.\\n\"\n"; 572 if (!translator.languageCode().isEmpty()) 573 out << "\"X-Language: " << translator.languageCode() << "\\n\"\n"; 574 if (!translator.sourceLanguageCode().isEmpty()) 575 out << "\"X-Source-Language: " << translator.sourceLanguageCode() << "\\n\"\n"; 576 first = false; 577 } 734 bool qtContexts = false; 735 foreach (const TranslatorMessage &msg, translator.messages()) 736 if (!msg.context().isEmpty()) { 737 qtContexts = true; 738 break; 739 } 740 741 QString cmt = translator.extra(QLatin1String("po-header_comment")); 742 if (!cmt.isEmpty()) 743 out << cmt << '\n'; 744 out << "msgid \"\"\n"; 745 Translator::ExtraData headers = translator.extras(); 746 QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split( 747 QLatin1Char(','), QString::SkipEmptyParts); 748 // Keep in sync with loadPO 749 addPoHeader(headers, hdrOrder, "MIME-Version", QLatin1String("1.0")); 750 addPoHeader(headers, hdrOrder, "Content-Type", 751 QLatin1String("text/plain; charset=" + out.codec()->name())); 752 addPoHeader(headers, hdrOrder, "Content-Transfer-Encoding", QLatin1String("8bit")); 753 if (!translator.languageCode().isEmpty()) { 754 QLocale::Language l; 755 QLocale::Country c; 756 Translator::languageAndCountry(translator.languageCode(), &l, &c); 757 const char *gettextRules; 758 if (getNumerusInfo(l, c, 0, 0, &gettextRules)) 759 addPoHeader(headers, hdrOrder, "Plural-Forms", QLatin1String(gettextRules)); 760 addPoHeader(headers, hdrOrder, "X-Language", translator.languageCode()); 761 } 762 if (!translator.sourceLanguageCode().isEmpty()) 763 addPoHeader(headers, hdrOrder, "X-Source-Language", translator.sourceLanguageCode()); 764 if (qtContexts) 765 addPoHeader(headers, hdrOrder, "X-Qt-Contexts", QLatin1String("true")); 766 QString hdrStr; 767 foreach (const QString &hdr, hdrOrder) { 768 hdrStr += hdr; 769 hdrStr += QLatin1String(": "); 770 hdrStr += headers.value(makePoHeader(hdr)); 771 hdrStr += QLatin1Char('\n'); 772 } 773 out << poEscapedString(QString(), QString::fromLatin1("msgstr"), true, hdrStr); 774 578 775 foreach (const TranslatorMessage &msg, translator.messages()) { 579 if (!first) 580 out << endl; 776 out << endl; 581 777 582 778 if (!msg.translatorComment().isEmpty()) … … 586 782 out << poEscapedLines(QLatin1String("#."), true, msg.extraComment()); 587 783 588 if (!msg.context().isEmpty())589 out << QLatin1String("#. ts-context ") << msg.context() << '\n';590 784 if (!msg.id().isEmpty()) 591 785 out << QLatin1String("#. ts-id ") << msg.id() << '\n'; 592 786 593 if (!msg.fileName().isEmpty() && msg.fileName() != QLatin1String(MAGIC_OBSOLETE_REFERENCE)) { 787 QString xrefs = msg.extra(QLatin1String("po-references")); 788 if (!msg.fileName().isEmpty() || !xrefs.isEmpty()) { 594 789 QStringList refs; 595 790 foreach (const TranslatorMessage::Reference &ref, msg.allReferences()) 596 791 refs.append(QString(QLatin1String("%2:%1")) 597 792 .arg(ref.lineNumber()).arg(ref.fileName())); 793 if (!xrefs.isEmpty()) 794 refs << xrefs; 598 795 out << poWrappedEscapedLines(QLatin1String("#:"), true, refs.join(QLatin1String(" "))); 599 796 } 600 797 601 798 bool noWrap = false; 799 bool skipFormat = false; 602 800 QStringList flags; 603 if (msg.type() == TranslatorMessage::Unfinished )801 if (msg.type() == TranslatorMessage::Unfinished && msg.isTranslated()) 604 802 flags.append(QLatin1String("fuzzy")); 605 803 TranslatorMessage::ExtraData::const_iterator itr = 606 804 msg.extras().find(QLatin1String("po-flags")); 607 805 if (itr != msg.extras().end()) { 608 if (itr->split(QLatin1String(", ")).contains(QLatin1String("no-wrap"))) 806 QStringList atoms = itr->split(QLatin1String(", ")); 807 foreach (const QString &atom, atoms) 808 if (atom.endsWith(str_format)) { 809 skipFormat = true; 810 break; 811 } 812 if (atoms.contains(QLatin1String("no-wrap"))) 609 813 noWrap = true; 610 814 flags.append(*itr); 611 815 } 816 if (!skipFormat) { 817 QString source = msg.sourceText(); 818 // This is fuzzy logic, as we don't know whether the string is 819 // actually used with QString::arg(). 820 for (int off = 0; (off = source.indexOf(QLatin1Char('%'), off)) >= 0; ) { 821 if (++off >= source.length()) 822 break; 823 if (source.at(off) == QLatin1Char('n') || source.at(off).isDigit()) { 824 flags.append(QLatin1String("qt-format")); 825 break; 826 } 827 } 828 } 612 829 if (!flags.isEmpty()) 613 830 out << "#, " << flags.join(QLatin1String(", ")) << '\n'; … … 615 832 QString prefix = QLatin1String("#| "); 616 833 if (!msg.oldComment().isEmpty()) 617 out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap, msg.oldComment()); 834 out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap, 835 escapeComment(msg.oldComment(), qtContexts)); 618 836 if (!msg.oldSourceText().isEmpty()) 619 837 out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.oldSourceText()); … … 622 840 out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural); 623 841 prefix = QLatin1String((msg.type() == TranslatorMessage::Obsolete) ? "#~ " : ""); 624 if (!msg.comment().isEmpty()) 625 out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap, msg.comment()); 842 if (!msg.context().isEmpty()) 843 out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap, 844 escapeComment(msg.context(), true) + QLatin1Char('|') 845 + escapeComment(msg.comment(), true)); 846 else if (!msg.comment().isEmpty()) 847 out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap, 848 escapeComment(msg.comment(), qtContexts)); 626 849 out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.sourceText()); 627 850 if (!msg.isPlural()) { 628 851 QString transl = msg.translation(); 629 if (first) { 630 transl.remove(QRegExp(QLatin1String("\\bX-Language:[^\n]*\n"))); 631 if (!translator.languageCode().isEmpty()) 632 transl += QLatin1String("X-Language: ") + translator.languageCode() + QLatin1Char('\n'); 633 } 852 transl.replace(QChar(Translator::BinaryVariantSeparator), 853 QChar(Translator::TextVariantSeparator)); 634 854 out << poEscapedString(prefix, QLatin1String("msgstr"), noWrap, transl); 635 855 } else { … … 647 867 } 648 868 } 649 first = false;650 869 } 651 870 return ok; 871 } 872 873 static bool savePOT(const Translator &translator, QIODevice &dev, ConversionData &cd) 874 { 875 Translator ttor = translator; 876 ttor.dropTranslations(); 877 return savePO(ttor, dev, cd); 652 878 } 653 879 … … 662 888 format.priority = 1; 663 889 Translator::registerFileFormat(format); 890 format.extension = QLatin1String("pot"); 891 format.description = QObject::tr("GNU Gettext localization template files"); 892 format.loader = &loadPO; 893 format.saver = &savePOT; 894 format.fileType = Translator::FileFormat::TranslationSource; 895 format.priority = -1; 896 Translator::registerFileFormat(format); 664 897 return 1; 665 898 } -
trunk/tools/linguist/shared/profileevaluator.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 2608 2608 { 2609 2609 if (d->m_verbose && !d->m_skipLevel) 2610 qWarning("%s", qPrintable(message));2610 fprintf(stderr, "%s\n", qPrintable(message)); 2611 2611 } 2612 2612 … … 2614 2614 { 2615 2615 if (!d->m_skipLevel) 2616 qWarning("%s", qPrintable(message));2616 fprintf(stderr, "%s\n", qPrintable(message)); 2617 2617 } 2618 2618 … … 2620 2620 { 2621 2621 if (!d->m_skipLevel) 2622 qWarning("%s", qPrintable(message));2622 fprintf(stderr, "%s\n", qPrintable(message)); 2623 2623 } 2624 2624 -
trunk/tools/linguist/shared/profileevaluator.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/proitems.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/proitems.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/proparserutils.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/qm.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 565 565 QStringList numerusForms; 566 566 bool guessPlurals = true; 567 if (getNumerusInfo(l, c, 0, &numerusForms ))567 if (getNumerusInfo(l, c, 0, &numerusForms, 0)) 568 568 guessPlurals = (numerusForms.count() == 1); 569 569 … … 705 705 Translator::languageAndCountry(translator.languageCode(), &l, &c); 706 706 QByteArray rules; 707 if (getNumerusInfo(l, c, &rules, 0 ))707 if (getNumerusInfo(l, c, &rules, 0, 0)) 708 708 releaser.setNumerusRules(rules); 709 709 releaser.setCodecName(translator.codecName()); … … 774 774 int generatedCount = finished + unfinished; 775 775 cd.appendError(QCoreApplication::translate("LRelease", 776 " Generated %n translation(s) (%1 finished and %2 unfinished) \n", 0,776 " Generated %n translation(s) (%1 finished and %2 unfinished)", 0, 777 777 QCoreApplication::CodecForTr, generatedCount).arg(finished).arg(unfinished)); 778 778 if (untranslated) 779 779 cd.appendError(QCoreApplication::translate("LRelease", 780 " Ignored %n untranslated source text(s) \n", 0,780 " Ignored %n untranslated source text(s)", 0, 781 781 QCoreApplication::CodecForTr, untranslated)); 782 782 } -
trunk/tools/linguist/shared/qph.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/simtexth.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/simtexth.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/translator.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include "simtexth.h" 45 45 46 #include <iostream> 47 46 48 #include <stdio.h> 47 49 #ifdef Q_OS_WIN 48 #include <io.h> // required for _setmode, to avoid _O_TEXT streams... 49 #include <fcntl.h> // for _O_BINARY 50 // required for _setmode, to avoid _O_TEXT streams... 51 # ifdef Q_OS_WINCE 52 # include <stdlib.h> 53 # else 54 # include <io.h> // for _setmode 55 # include <fcntl.h> // for _O_BINARY 56 # endif 50 57 #endif 51 58 … … 214 221 #ifdef Q_OS_WIN 215 222 // QFile is broken for text files 223 # ifdef Q_OS_WINCE 224 ::_setmode(stdin, _O_BINARY); 225 # else 216 226 ::_setmode(0, _O_BINARY); 227 # endif 217 228 #endif 218 229 if (!file.open(stdin, QIODevice::ReadOnly)) { … … 254 265 #ifdef Q_OS_WIN 255 266 // QFile is broken for text files 267 # ifdef Q_OS_WINCE 268 ::_setmode(stdout, _O_BINARY); 269 # else 256 270 ::_setmode(1, _O_BINARY); 271 # endif 257 272 #endif 258 273 if (!file.open(stdout, QIODevice::WriteOnly)) { … … 574 589 { 575 590 if (!dupes.byId.isEmpty() || !dupes.byContents.isEmpty()) { 591 std::cerr << "Warning: dropping duplicate messages in '" << qPrintable(fileName); 576 592 if (!verbose) { 577 qWarning("Warning: dropping duplicate messages in '%s'\n(try -verbose for more info).", 578 qPrintable(fileName)); 593 std::cerr << "'\n(try -verbose for more info).\n"; 579 594 } else { 580 qWarning("Warning: dropping duplicate messages in '%s':", qPrintable(fileName));595 std::cerr << "':\n"; 581 596 foreach (int i, dupes.byId) 582 qWarning("\n* ID: %s", qPrintable(message(i).id()));597 std::cerr << "\n* ID: " << qPrintable(message(i).id()) << std::endl; 583 598 foreach (int j, dupes.byContents) { 584 599 const TranslatorMessage &msg = message(j); 585 qWarning("\n* Context: %s\n* Source: %s", 586 qPrintable(msg.context()), 587 qPrintable(msg.sourceText())); 600 std::cerr << "\n* Context: " << qPrintable(msg.context()) 601 << "\n* Source: " << qPrintable(msg.sourceText()) << std::endl; 588 602 if (!msg.comment().isEmpty()) 589 qWarning("* Comment: %s", qPrintable(msg.comment()));603 std::cerr << "* Comment: " << qPrintable(msg.comment()) << std::endl; 590 604 } 591 qWarning();605 std::cerr << std::endl; 592 606 } 593 607 } … … 653 667 if (l != QLocale::C) { 654 668 QStringList forms; 655 if (getNumerusInfo(l, c, 0, &forms ))669 if (getNumerusInfo(l, c, 0, &forms, 0)) 656 670 numPlurals = forms.count(); // includes singular 657 671 } … … 676 690 "Removed plural forms as the target language has less " 677 691 "forms.\nIf this sounds wrong, possibly the target language is " 678 "not set or recognized. \n"));692 "not set or recognized.")); 679 693 } 680 694 … … 725 739 if (!codec) { 726 740 if (!name.isEmpty()) 727 qWarning("No QTextCodec for %s available. Using Latin1\n", name.constData());741 std::cerr << "No QTextCodec for " << name.constData() << " available. Using Latin1.\n"; 728 742 m_codec = QTextCodec::codecForName("ISO-8859-1"); 729 743 } else { -
trunk/tools/linguist/shared/translator.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 93 93 94 94 void appendError(const QString &error) { m_errors.append(error); } 95 QString error() const { return m_errors.join(QLatin1String("\n")); }95 QString error() const { return m_errors.isEmpty() ? QString() : m_errors.join(QLatin1String("\n")) + QLatin1Char('\n'); } 96 96 QStringList errors() const { return m_errors; } 97 97 void clearErrors() { m_errors.clear(); } … … 124 124 Translator(); 125 125 126 bool load(const QString &filename, ConversionData &err, const QString &format /* = "auto"*/);127 bool save(const QString &filename, ConversionData &err, const QString &format /* = "auto"*/) const;126 bool load(const QString &filename, ConversionData &err, const QString &format /* = "auto" */); 127 bool save(const QString &filename, ConversionData &err, const QString &format /* = "auto" */) const; 128 128 bool release(QFile *iod, ConversionData &cd) const; 129 129 … … 234 234 235 235 bool getNumerusInfo(QLocale::Language language, QLocale::Country country, 236 QByteArray *rules, QStringList *forms);236 QByteArray *rules, QStringList *forms, const char **gettextRules); 237 237 238 238 /* -
trunk/tools/linguist/shared/translatormessage.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/translatormessage.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/ts.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/tools/linguist/shared/ts.dtd
r561 r846 5 5 ! The location element is set as optional since it was introduced first in Qt 4.2. 6 6 ! The userdata element is set as optional since it was introduced first in Qt 4.4. 7 ! The source and translation elements are optional starting with version 3.08 ! (Qt 4.6) to support S60 blank messages.9 7 ! 10 8 --> … … 37 35 <!-- The encoding to use in the QM file by default. Default is ISO-8859-1. --> 38 36 <!ELEMENT defaultcodec (#PCDATA) > 39 <!ELEMENT context (name ?, comment?, (context|message)+) >37 <!ELEMENT context (name, comment?, (context|message)+) > 40 38 <!ATTLIST context 41 39 encoding CDATA #IMPLIED> 42 40 <!ELEMENT name %evilstring; > 43 <!-- If "no", then the context nesting is for informational puposes only -->44 <!ATTLIST name45 nest (yes|no) "yes">46 41 <!-- This is "disambiguation" in the (new) API, or "msgctxt" in gettext speak --> 47 42 <!ELEMENT comment %evilstring; > … … 54 49 <!ELEMENT message (location*, source?, oldsource?, comment?, oldcomment?, extracomment?, translatorcomment?, translation?, userdata?, extra-**) > 55 50 <!-- 56 ! If utf8 is true, the defaultcodec is overridden and the message is encoded 57 ! in UTF-8 in the QM file. 51 ! If utf8 is "true", the defaultcodec is overridden and the message is encoded 52 ! in UTF-8 in the QM file. If it is "both", both source encodings are stored 53 ! in the QM file. 58 54 --> 59 55 <!ATTLIST message 60 56 id CDATA #IMPLIED 61 utf8 (true|false ) "false"57 utf8 (true|false|both) "false" 62 58 numerus (yes|no) "no"> 63 59 <!ELEMENT location EMPTY> … … 101 97 <!ELEMENT numerusform (#PCDATA|byte|lengthvariant)* > 102 98 <!ATTLIST numerusform 103 plurality (nullar|singular|dual|trial|paucal|greaterpaucal|plural|greaterplural) #IMPLIED>104 99 variants (yes|no) "no"> 105 100 <!ELEMENT lengthvariant %evilstring; > 106 <!--107 ! The translation variants have a priority between 1 ("highest") and 9 ("lowest")108 ! Typically longer translations get a higher priority.109 ! If omitted, the order of appearance of the variants in the TS files is used.110 -->111 <!ATTLIST lengthvariant112 priority (1|2|3|4|5|6|7|8|9) #IMPLIED>113 -
trunk/tools/linguist/shared/xliff.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 54 54 55 55 56 // The string value is historical and reflects the main purpose: Keeping 57 // obsolete entries separate from the magic file message (which both have 58 // no location information, but typically reside at opposite ends of the file). 59 #define MAGIC_OBSOLETE_REFERENCE "Obsolete_PO_entries" 60 56 61 QT_BEGIN_NAMESPACE 57 62 … … 504 509 m_sourceLanguage = atts.value(QLatin1String("source-language")); 505 510 m_sourceLanguage.replace(QLatin1Char('-'), QLatin1Char('_')); 511 if (m_sourceLanguage == QLatin1String("en")) 512 m_sourceLanguage.clear(); 506 513 } else if (localName == QLatin1String("group")) { 507 514 if (atts.value(QLatin1String("restype")) == QLatin1String(restypeContext)) { … … 691 698 return false; 692 699 } 700 if (m_type == TranslatorMessage::Obsolete && m_refs.size() == 1 701 && m_refs.at(0).fileName() == QLatin1String(MAGIC_OBSOLETE_REFERENCE)) 702 m_refs.clear(); 693 703 TranslatorMessage msg(m_context, m_sources[0], 694 704 m_comment, QString(), QString(), -1, … … 760 770 QList<QString> fileOrder; 761 771 foreach (const TranslatorMessage &msg, translator.messages()) { 762 QHash<QString, QList<TranslatorMessage> > &file = messageOrder[msg.fileName()]; 772 QString fn = msg.fileName(); 773 if (fn.isEmpty() && msg.type() == TranslatorMessage::Obsolete) 774 fn = QLatin1String(MAGIC_OBSOLETE_REFERENCE); 775 QHash<QString, QList<TranslatorMessage> > &file = messageOrder[fn]; 763 776 if (file.isEmpty()) 764 fileOrder.append( msg.fileName());777 fileOrder.append(fn); 765 778 QList<TranslatorMessage> &context = file[msg.context()]; 766 779 if (context.isEmpty()) 767 contextOrder[ msg.fileName()].append(msg.context());780 contextOrder[fn].append(msg.context()); 768 781 context.append(msg); 769 782 }
Note:
See TracChangeset
for help on using the changeset viewer.