📄 metatranslator.cpp
字号:
}bool MetaTranslator::save( const QString& filename) const{ QFile f( filename ); if ( !f.open(QIODevice::WriteOnly) ) return false; QTextStream t( &f ); t.setCodec( QTextCodec::codecForName("ISO-8859-1") ); //### The xml prolog allows processors to easily detect the correct encoding t << "<?xml version=\"1.0\""; t << " encoding=\"utf-8\""; t << "?>\n<!DOCTYPE TS><TS version=\"1.1\""; if (!languageCode().isEmpty() && languageCode() != QLatin1String("C")) t << " language=\"" << languageCode() << "\""; t << ">\n"; if ( codecName != "ISO-8859-1" ) t << "<defaultcodec>" << codecName << "</defaultcodec>\n"; TMM::ConstIterator m = mm.begin(); while ( m != mm.end() ) { TMMInv inv; TMMInv::Iterator i; bool contextIsUtf8 = m.key().utf8(); QByteArray context = m.key().context(); QByteArray comment = ""; do { if (QByteArray(m.key().sourceText()) == ContextComment) { if ( m.key().type() != MetaTranslatorMessage::Obsolete ) { contextIsUtf8 = m.key().utf8(); comment = QByteArray(m.key().comment()); } } else { inv.insert( *m, m.key() ); } } while ( ++m != mm.end() && QByteArray(m.key().context()) == context ); t << "<context"; if ( contextIsUtf8 ) t << " encoding=\"UTF-8\""; t << ">\n"; t << " <name>" << evilBytes( context, contextIsUtf8 ) << "</name>\n"; if ( !comment.isEmpty() ) t << " <comment>" << evilBytes( comment, contextIsUtf8 ) << "</comment>\n"; for ( i = inv.begin(); i != inv.end(); ++i ) { MetaTranslatorMessage msg = *i; // no need for such noise if ( msg.type() == MetaTranslatorMessage::Obsolete && msg.translation().isEmpty() ) { continue; } t << " <message"; if ( msg.utf8() ) t << " encoding=\"UTF-8\""; if ( msg.isPlural() ) t << " numerus=\"yes\""; t << ">\n"; if (!msg.fileName().isEmpty() && msg.lineNumber() >= 0) { QDir tsPath = QFileInfo(filename).absoluteDir(); QString fn = tsPath.relativeFilePath(msg.fileName()).replace('\\','/'); t << " <location filename=\"" << fn << "\" line=\"" << msg.lineNumber() << "\"/>\n"; } t << " <source>" << evilBytes( (*i).sourceText(), (*i).utf8() ) << "</source>\n"; if ( !QByteArray((*i).comment()).isEmpty() ) t << " <comment>" << evilBytes( (*i).comment(), (*i).utf8() ) << "</comment>\n"; t << " <translation"; if ( (*i).type() == MetaTranslatorMessage::Unfinished ) t << " type=\"unfinished\""; else if ( (*i).type() == MetaTranslatorMessage::Obsolete ) t << " type=\"obsolete\""; t << ">"; if (msg.isPlural()) { t << "\n"; QLocale::Language l; QLocale::Country c; languageAndCountry(m_language, &l, &c); QStringList translns = normalizedTranslations(*i, l, c); for (int j = 0; j < qMax(1, translns.count()); ++j) t << " <numerusform>" << protect( translns.value(j).toUtf8() ) << "</numerusform>\n"; t << " "; } else { t << protect( (*i).translation().toUtf8() ); } t << "</translation>\n"; t << " </message>\n"; } t << "</context>\n"; } t << "</TS>\n"; f.close(); return true;}bool MetaTranslator::release( const QString& filename, bool verbose, bool ignoreUnfinished, Translator::SaveMode mode ) const{ QFile file(filename); if (file.open(QIODevice::WriteOnly)) { bool ok = release(&file, verbose, ignoreUnfinished, mode); file.close(); return ok; } return false;}void MetaTranslator::languageAndCountry(const QString &languageCode, QLocale::Language *lang, QLocale::Country *country){ QLocale locale(languageCode); if (lang) *lang = locale.language(); if (country) { if (languageCode.indexOf(QLatin1Char('_')) != -1) { *country = locale.country(); } else { *country = QLocale::AnyCountry; } }}bool MetaTranslator::release( QIODevice *iod, bool verbose /*= false*/, bool ignoreUnfinished /*= false*/, Translator::SaveMode mode /*= Translator::Stripped */) const{ Translator tor( 0 ); QLocale::Language l; QLocale::Country c; languageAndCountry(m_language, &l, &c); QByteArray rules; if (getNumerusInfo(l, c, &rules, 0)) { tor.setNumerusRules(rules); } int finished = 0; int unfinished = 0; int untranslated = 0; TMM::ConstIterator m; for ( m = mm.begin(); m != mm.end(); ++m ) { MetaTranslatorMessage::Type typ = m.key().type(); if ( typ != MetaTranslatorMessage::Obsolete ) { if ( typ == MetaTranslatorMessage::Unfinished ) { if (m.key().translation().isEmpty()) { untranslated++; } else { unfinished++; } } else { finished++; } QByteArray context = m.key().context(); QByteArray sourceText = m.key().sourceText(); QByteArray comment = m.key().comment(); QStringList translations = m.key().translations(); if ( !ignoreUnfinished || typ != MetaTranslatorMessage::Unfinished ) { /* Drop the comment in (context, sourceText, comment), unless the context is empty, unless (context, sourceText, "") already exists or unless we already dropped the comment of (context, sourceText, comment0). */ if ( comment.isEmpty() || context.isEmpty() || contains(context, sourceText, "") || !tor.findMessage(context, sourceText, "").translation() .isNull() ) { tor.insert( m.key() ); } else { tor.insert( TranslatorMessage(context, sourceText, "", QString(), -1, translations) ); //filename and lineNumbers will be ignored from now. } } } } bool saved = tor.save( iod, mode ); if ( saved && verbose ) { int generatedCount = finished + unfinished; fprintf( stderr, " Generated %d translation%s (%d finished and %d unfinished)\n", generatedCount, generatedCount == 1 ? "" : "s", finished, unfinished); if (untranslated) fprintf( stderr, " Ignored %d untranslated source text%s\n", untranslated, untranslated == 1 ? "" : "s"); } return saved;}QString MetaTranslator::languageCode() const{ return m_language;}void MetaTranslator::setLanguageCode(const QString &languageCode){ m_language = languageCode;}bool MetaTranslator::contains( const char *context, const char *sourceText, const char *comment ) const{ return mm.contains(MetaTranslatorMessage(context, sourceText, comment, QString(), 0));}MetaTranslatorMessage MetaTranslator::find( const char *context, const char *sourceText, const char *comment ) const{ QList<MetaTranslatorMessage> all = messages(); QList<MetaTranslatorMessage>::const_iterator i1; int delta = -1; for (i1 = all.constBegin(); i1 != all.constEnd(); ++i1) { MetaTranslatorMessage m = *i1; delta = qstrcmp(m.context(), context); if (delta == 0) { delta = qstrcmp(m.comment(), comment); if (delta == 0) { delta = QString::compare(m.sourceText(), sourceText); if (delta == 0) return (*i1); } } } return MetaTranslatorMessage(); }MetaTranslatorMessage MetaTranslator::find(const char *context, const char *comment, const QString &fileName, int lineNumber) const{ QList<MetaTranslatorMessage> all = messages(); QList<MetaTranslatorMessage>::const_iterator i1; int delta = -1; if (lineNumber >= 0 && !fileName.isEmpty()) { for (i1 = all.constBegin(); i1 != all.constEnd(); ++i1) { MetaTranslatorMessage m = *i1; delta = qstrcmp(m.context(), context); if (delta == 0) { delta = qstrcmp(m.comment(), comment); if (delta == 0) { delta = QString::compare(m.fileName(), fileName); if (delta == 0) { delta = m.lineNumber() - lineNumber; if (delta == 0) return (*i1); } } } } } return MetaTranslatorMessage();}void MetaTranslator::insert( const MetaTranslatorMessage& m ){ int pos = mm.count(); if (mm.contains(m)) { pos = mm.value(m); mm.remove(m); } mm.insert(m, pos);}void MetaTranslator::stripObsoleteMessages(){ TMM newmm; TMM::Iterator m = mm.begin(); while ( m != mm.end() ) { if ( m.key().type() != MetaTranslatorMessage::Obsolete ) newmm.insert( m.key(), *m ); ++m; } mm = newmm;}void MetaTranslator::stripEmptyContexts(){ TMM newmm; TMM::Iterator m = mm.begin(); while ( m != mm.end() ) { if ( QByteArray(m.key().sourceText()) == ContextComment ) { TMM::Iterator n = m; ++n; // the context comment is followed by other messages if ( n != newmm.end() && qstrcmp(m.key().context(), n.key().context()) == 0 ) newmm.insert( m.key(), *m ); } else { newmm.insert( m.key(), *m ); } ++m; } mm = newmm;}void MetaTranslator::makeFileNamesAbsolute(const QDir &oldPath){ TMM newmm; for (TMM::iterator m = mm.begin(); m != mm.end(); ++m) { MetaTranslatorMessage msg = m.key(); QString fileName = m.key().fileName(); QFileInfo fi (fileName); if (fi.isRelative()) { fileName = oldPath.absoluteFilePath(fileName); } msg.setFileName(fileName); newmm.insert(msg, m.value()); } mm = newmm;}void MetaTranslator::setCodec( const char *name ){ const int latin1 = 4; codecName = name; codec = QTextCodec::codecForName( name ); if ( codec == 0 || codec->mibEnum() == latin1 ) codec = 0;}QString MetaTranslator::toUnicode( const char *str, bool utf8 ) const{ if ( utf8 ) return QString::fromUtf8( str ); else if ( codec == 0 ) return QString( str ); else return codec->toUnicode( str );}QList<MetaTranslatorMessage> MetaTranslator::messages() const{ int n = mm.count(); TMM::ConstIterator *t = new TMM::ConstIterator[n + 1]; TMM::ConstIterator m; for ( m = mm.begin(); m != mm.end(); ++m ) t[*m] = m; QList<MetaTranslatorMessage> val; for ( int i = 0; i < n; i++ ) val.append( t[i].key() ); delete[] t; return val;}QList<MetaTranslatorMessage> MetaTranslator::translatedMessages() const{ QList<MetaTranslatorMessage> val; TMM::ConstIterator m; for ( m = mm.begin(); m != mm.end(); ++m ) { if ( m.key().type() == MetaTranslatorMessage::Finished ) val.append( m.key() ); } return val;}// the grammatical numerus is the number of plural forms + singular forms.// i.e english has two forms: singular og plural.// and polish has three forms: // 1. singular (1), // 2. plural form 1 (numbers that ends with 2,3,4 except 12,13,14)// 3. plural form 2 (all others)// Thus, english returns 2, polish returns 3int MetaTranslator::grammaticalNumerus(QLocale::Language language, QLocale::Country country){ QStringList forms; getNumerusInfo(language, country, 0, &forms); return forms.count();}QStringList MetaTranslator::normalizedTranslations(const MetaTranslatorMessage& m, QLocale::Language language, QLocale::Country country){ QStringList translations = m.translations(); int numTranslations = 1; if (m.isPlural()) { numTranslations = grammaticalNumerus(language, country); } // make sure that the stringlist always have the size of the language's current numerus, or 1 if its not plural if (translations.count() > numTranslations) { for (int i = translations.count(); i > numTranslations; --i) translations.removeLast(); } else if (translations.count() < numTranslations) { for (int i = translations.count(); i < numTranslations; ++i) translations << QString(); } return translations; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -