static QString dataType(const TranslatorMessage &m) { QByteArray fileName = m.fileName().toAscii(); unsigned int extHash = 0; int pos = fileName.count() - 1; for (int pass = 0; pass < 4 && pos >=0; ++pass, --pos) { if (fileName.at(pos) == '.') break; extHash |= ((int)fileName.at(pos) << (8*pass)); } switch (extHash) { case COMBINE4CHARS(0,'c','p','p'): case COMBINE4CHARS(0,'c','x','x'): case COMBINE4CHARS(0,'c','+','+'): case COMBINE4CHARS(0,'h','p','p'): case COMBINE4CHARS(0,'h','x','x'): case COMBINE4CHARS(0,'h','+','+'): return QLatin1String("cpp"); case COMBINE4CHARS(0, 0 , 0 ,'c'): case COMBINE4CHARS(0, 0 , 0 ,'h'): case COMBINE4CHARS(0, 0 ,'c','c'): case COMBINE4CHARS(0, 0 ,'c','h'): case COMBINE4CHARS(0, 0 ,'h','h'): return QLatin1String("c"); case COMBINE4CHARS(0, 0 ,'u','i'): return QLatin1String(dataTypeUIFile); //### form? default: return QLatin1String("plaintext"); // we give up } }
static void writeLineNumber(QTextStream &ts, const TranslatorMessage &msg, int indent) { if (msg.lineNumber() == -1) return; writeIndent(ts, indent); ts << "<context-group purpose=\"location\"><context context-type=\"linenumber\">" << msg.lineNumber() << "</context></context-group>\n"; foreach (const TranslatorMessage::Reference &ref, msg.extraReferences()) { writeIndent(ts, indent); ts << "<context-group purpose=\"location\">"; if (ref.fileName() != msg.fileName()) ts << "<context context-type=\"sourcefile\">" << ref.fileName() << "</context>"; ts << "<context context-type=\"linenumber\">" << ref.lineNumber() << "</context></context-group>\n"; } }
void Translator::appendSorted(const TranslatorMessage &msg) { int msgLine = msg.lineNumber(); if (msgLine < 0) { append(msg); return; } int bestIdx = 0; // Best insertion point found so far int bestScore = 0; // Its category: 0 = no hit, 1 = pre or post, 2 = middle int bestSize = 0; // The length of the region. Longer is better within one category. // The insertion point to use should this region turn out to be the best one so far int thisIdx = 0; int thisScore = 0; int thisSize = 0; // Working vars int prevLine = 0; int curIdx = 0; foreach (const TranslatorMessage &mit, m_messages) { bool sameFile = mit.fileName() == msg.fileName() && mit.context() == msg.context(); int curLine; if (sameFile && (curLine = mit.lineNumber()) >= prevLine) { if (msgLine >= prevLine && msgLine < curLine) { thisIdx = curIdx; thisScore = thisSize ? 2 : 1; } ++thisSize; prevLine = curLine; } else { if (thisSize) { if (!thisScore) { thisIdx = curIdx; thisScore = 1; } if (thisScore > bestScore || (thisScore == bestScore && thisSize > bestSize)) { bestIdx = thisIdx; bestScore = thisScore; bestSize = thisSize; } thisScore = 0; thisSize = sameFile ? 1 : 0; prevLine = 0; } } ++curIdx; }
void Translator::extend(const TranslatorMessage &msg, ConversionData &cd) { int index = find(msg); if (index == -1) { append(msg); } else { TranslatorMessage &emsg = m_messages[index]; if (emsg.sourceText().isEmpty()) { delIndex(index); emsg.setSourceText(msg.sourceText()); addIndex(index, msg); } else if (!msg.sourceText().isEmpty() && emsg.sourceText() != msg.sourceText()) { cd.appendError(QString::fromLatin1("Contradicting source strings for message with id '%1'.") .arg(emsg.id())); return; } if (emsg.extras().isEmpty()) { emsg.setExtras(msg.extras()); } else if (!msg.extras().isEmpty() && emsg.extras() != msg.extras()) { cd.appendError(QString::fromLatin1("Contradicting meta data for for %1.") .arg(!emsg.id().isEmpty() ? QString::fromLatin1("message with id '%1'").arg(emsg.id()) : QString::fromLatin1("message '%1'").arg(makeMsgId(msg)))); return; } emsg.addReferenceUniq(msg.fileName(), msg.lineNumber()); if (!msg.extraComment().isEmpty()) { QString cmt = emsg.extraComment(); if (!cmt.isEmpty()) { QStringList cmts = cmt.split(QLatin1String("\n----------\n")); if (!cmts.contains(msg.extraComment())) { cmts.append(msg.extraComment()); cmt = cmts.join(QLatin1String("\n----------\n")); } } else { cmt = msg.extraComment(); } emsg.setExtraComment(cmt); } } }
void Translator::extend(const TranslatorMessage &msg) { int index = find(msg); if (index == -1) { append(msg); } else { TranslatorMessage &emsg = m_messages[index]; emsg.addReferenceUniq(msg.fileName(), msg.lineNumber()); if (!msg.extraComment().isEmpty()) { QString cmt = emsg.extraComment(); if (!cmt.isEmpty()) cmt.append(QLatin1String("\n----------\n")); cmt.append(msg.extraComment()); emsg.setExtraComment(cmt); } if (msg.isUtf8() != emsg.isUtf8()) { emsg.setUtf8(true); emsg.setNonUtf8(true); } } }
bool MetaTranslator::saveXLIFF( const QString& filename) const { QFile f( filename ); if ( !f.open(QIODevice::WriteOnly | QIODevice::Text) ) return false; int indent = 2; int currentindent = 0; QTextStream t( &f ); t.setCodec( QTextCodec::codecForName("ISO-8859-1") ); QMap<QString, TranslatorMessage> mtSortByFileName; TMM::ConstIterator m = mm.begin(); while ( m != mm.end() ) { TranslatorMessage msg = m.key(); QString location = msg.fileName() + QLatin1String(msg.context()) + QString::number(msg.lineNumber()); mtSortByFileName.insertMulti(location, msg); ++m; } t.setFieldAlignment(QTextStream::AlignRight); t << "<?xml version=\"1.0\""; t << " encoding=\"utf-8\"?>\n"; t << "<xliff version=\"1.1\" xmlns=\"" << XLIFF11namespaceURI << "\">\n"; currentindent += indent; QMap<QString, TranslatorMessage>::iterator mi = mtSortByFileName.begin(); TranslatorMessage msg; QByteArray ctx; QString fn; bool ctxdiffer = false; bool filediffer = false; while (mi != mtSortByFileName.end()) { msg = mi.value(); ctxdiffer = msg.context() != ctx; filediffer = msg.fileName() != fn; if (ctxdiffer || filediffer) { if (!ctx.isEmpty()) { writeIndent(&t, currentindent); t << "</group>\n"; currentindent -= indent; } } if (filediffer) { if (!fn.isEmpty()) { writeIndent(&t, currentindent); t << "</body></file>\n"; currentindent -= indent; } fn = msg.fileName(); writeIndent(&t, currentindent); t << "<file original=\"" << fn << "\"" << " datatype=\"" << dataType(msg) << "\"" << " source-language=\"" << "en" << "\"" //### << " target-language=\"" << languageCode() << "\"" << "><body>\n"; currentindent += indent; } if (ctxdiffer || filediffer) { ctx = msg.context(); writeIndent(&t, currentindent); t << "<group restype=\"" << restypeContext << "\"" << " resname=\"" << evilBytes(ctx, msg.utf8()) << "\"" << ">\n"; currentindent += indent; } writeMessage(&t, msg, currentindent, m_language); ++mi; } currentindent-=indent; writeIndent(&t, currentindent); t << "</group>\n"; currentindent-=indent; writeIndent(&t, currentindent); t << "</body></file>\n"; t << "</xliff>\n"; f.close(); return true; }