metatranslator.cpp
来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 837 行 · 第 1/2 页
CPP
837 行
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt Linguist of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "metatranslator.h"#include "translator.h"#include "xliff.h"#include <QApplication>#include <QByteArray>#include <QFile>#include <QMessageBox>#include <QTextCodec>#include <QTextStream>#include <QtXml>#include <QtCore/QDir>#include <QtCore/QFileInfo>static bool encodingIsUtf8( const QXmlAttributes& atts ){ for ( int i = 0; i < atts.length(); i++ ) { // utf8="true" is a pre-3.0 syntax if ( atts.qName(i) == QString(QLatin1String("utf8")) ) { return ( atts.value(i) == QString(QLatin1String("true")) ); } else if ( atts.qName(i) == QString(QLatin1String("encoding")) ) { return ( atts.value(i) == QString(QLatin1String("UTF-8")) ); } } return false;}class TsHandler : public QXmlDefaultHandler{public: TsHandler( MetaTranslator *translator ) : tor( translator ), type( MetaTranslatorMessage::Finished ), inMessage( false ), ferrorCount( 0 ), contextIsUtf8( false ), messageIsUtf8( false ), m_isPlural(false) { } virtual bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ); virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ); virtual bool characters( const QString& ch ); virtual bool fatalError( const QXmlParseException& exception ); virtual bool endDocument();private: MetaTranslator *tor; MetaTranslatorMessage::Type type; bool inMessage; QString m_language; QString context; QString source; QString comment; QStringList translations; QString m_fileName; int m_lineNumber; QString accum; int ferrorCount; bool contextIsUtf8; bool messageIsUtf8; bool m_isPlural;};bool TsHandler::startElement( const QString& /* namespaceURI */, const QString& /* localName */, const QString& qName, const QXmlAttributes& atts ){ if ( qName == QString(QLatin1String("byte")) ) { for ( int i = 0; i < atts.length(); i++ ) { if ( atts.qName(i) == QString(QLatin1String("value")) ) { QString value = atts.value( i ); int base = 10; if ( value.startsWith(QLatin1String("x")) ) { base = 16; value = value.mid( 1 ); } int n = value.toUInt( 0, base ); if ( n != 0 ) accum += QChar( n ); } } } else { if ( qName == QString(QLatin1String("TS")) ) { m_language = atts.value(QLatin1String("language")); } else if ( qName == QString(QLatin1String("context")) ) { context.clear(); source.clear(); comment.clear(); translations.clear(); contextIsUtf8 = encodingIsUtf8( atts ); } else if ( qName == QString(QLatin1String("message")) ) { inMessage = true; type = MetaTranslatorMessage::Finished; source.clear(); comment.clear(); translations.clear(); messageIsUtf8 = encodingIsUtf8( atts ); m_isPlural = atts.value(QLatin1String("numerus")).compare(QLatin1String("yes")) == 0; } else if (qName == QString(QLatin1String("location")) && inMessage) { bool bOK; int lineNo = atts.value(QString(QLatin1String("line"))).toInt(&bOK); if (!bOK) lineNo = -1; m_fileName = atts.value(QString(QLatin1String("filename"))); m_lineNumber = lineNo; } else if ( qName == QString(QLatin1String("translation")) ) { for ( int i = 0; i < atts.length(); i++ ) { if ( atts.qName(i) == QString(QLatin1String("type")) ) { if ( atts.value(i) == QString(QLatin1String("unfinished")) ) type = MetaTranslatorMessage::Unfinished; else if ( atts.value(i) == QString(QLatin1String("obsolete")) ) type = MetaTranslatorMessage::Obsolete; else type = MetaTranslatorMessage::Finished; } } } accum.clear(); } return true;}bool TsHandler::endElement( const QString& /* namespaceURI */, const QString& /* localName */, const QString& qName ){ if ( qName == QString(QLatin1String("codec")) || qName == QString(QLatin1String("defaultcodec")) ) { // QLatin1String("codec") is a pre-3.0 syntax tor->setCodec( accum.toLatin1() ); } else if ( qName == QString(QLatin1String("name")) ) { context = accum; } else if ( qName == QString(QLatin1String("source")) ) { source = accum; } else if ( qName == QString(QLatin1String("comment")) ) { if ( inMessage ) { comment = accum; } else { if ( contextIsUtf8 ) tor->insert( MetaTranslatorMessage(context.toUtf8(), ContextComment, accum.toUtf8(), QString(), 0, QStringList(), true, MetaTranslatorMessage::Unfinished) ); else tor->insert( MetaTranslatorMessage(context.toAscii(), ContextComment, accum.toAscii(), QString(), 0, QStringList(), false, MetaTranslatorMessage::Unfinished) ); } } else if ( qName == QString(QLatin1String("numerusform")) ) { translations.append(accum); m_isPlural = true; } else if ( qName == QString(QLatin1String("translation")) ) { if (translations.isEmpty()) translations.append(accum); } else if ( qName == QString(QLatin1String("message")) ) { if ( messageIsUtf8 ) tor->insert( MetaTranslatorMessage(context.toUtf8(), source.toUtf8(), comment.toUtf8(), m_fileName, m_lineNumber, translations, true, type, m_isPlural) ); else tor->insert( MetaTranslatorMessage(context.toAscii(), source.toAscii(), comment.toAscii(), m_fileName, m_lineNumber, translations, false, type, m_isPlural) ); inMessage = false; } return true;}bool TsHandler::characters( const QString& ch ){ QString t = ch; t.replace( QLatin1String("\r"), QLatin1String("") ); accum += t; return true;}bool TsHandler::endDocument(){ tor->setLanguageCode(m_language); return true;}bool TsHandler::fatalError( const QXmlParseException& exception ){ if ( ferrorCount++ == 0 ) { QString msg; msg.sprintf( "Parse error at line %d, column %d (%s).", exception.lineNumber(), exception.columnNumber(), exception.message().toLatin1().data() ); if ( qobject_cast<QApplication*>(QCoreApplication::instance()) == 0 ) fprintf( stderr, "XML error: %s\n", msg.toLatin1().data() ); else QMessageBox::information(0, QObject::tr("Qt Linguist"), msg ); } return false;}static QString numericEntity( int ch ){ return QString( ch <= 0x20 ? QLatin1String("<byte value=\"x%1\"/>") : QLatin1String("&#x%1;") ) .arg( ch, 0, 16 );}static QString protect( const QByteArray& str ){ QString result; int len = (int) str.length(); for ( int k = 0; k < len; k++ ) { switch( str[k] ) { case '\"': result += QString( QLatin1String(""") ); break; case '&': result += QString( QLatin1String("&") ); break; case '>': result += QString( QLatin1String(">") ); break; case '<': result += QString( QLatin1String("<") ); break; case '\'': result += QString( QLatin1String("'") ); break; default: if ( (uchar) str[k] < 0x20 && str[k] != '\n' ) result += numericEntity( (uchar) str[k] ); else result += QLatin1Char(str[k]); } } return result;}static QString evilBytes( const QByteArray& str, bool utf8 ){ if ( utf8 ) { return protect( str ); } else { QString result; QByteArray t = protect( str ).toLatin1(); int len = (int) t.length(); for ( int k = 0; k < len; k++ ) { if ( (uchar) t[k] >= 0x7f ) result += numericEntity( (uchar) t[k] ); else result += QLatin1Char( t[k] ); } return result; }}MetaTranslatorMessage::MetaTranslatorMessage() : utfeight( false ), ty( Unfinished ), m_plural(false){}MetaTranslatorMessage::MetaTranslatorMessage( const char *context, const char *sourceText, const char *comment, const QString &fileName, int lineNumber, const QStringList& translations, bool utf8, Type type, bool plural ) : TranslatorMessage( context, sourceText, comment, fileName, lineNumber, translations ), utfeight( false ), ty( type ), m_plural(plural){ /* Don't use UTF-8 if it makes no difference. UTF-8 should be reserved for the real problematic case: non-ASCII (possibly non-Latin1) characters in .ui files. */ if ( utf8 ) { if ( sourceText != 0 ) { int i = 0; while ( sourceText[i] != '\0' ) { if ( (uchar) sourceText[i] >= 0x80 ) { utfeight = true; break; } i++; } } if ( !utfeight && comment != 0 ) { int i = 0; while ( comment[i] != '\0' ) { if ( (uchar) comment[i] >= 0x80 ) { utfeight = true; break; } i++; } } if ( !utfeight && context != 0 ) { int i = 0; while ( context[i] != '\0' ) { if ( (uchar) context[i] >= 0x80 ) { utfeight = true; break; } i++; } } }}MetaTranslatorMessage::MetaTranslatorMessage( const MetaTranslatorMessage& m ) : TranslatorMessage( m ), utfeight( m.utfeight ), ty( m.ty ), m_plural(m.m_plural){}MetaTranslatorMessage& MetaTranslatorMessage::operator=( const MetaTranslatorMessage& m ){ TranslatorMessage::operator=( m ); utfeight = m.utfeight; ty = m.ty; m_plural = m.m_plural; return *this;}bool MetaTranslatorMessage::operator==( const MetaTranslatorMessage& m ) const{ return qstrcmp( context(), m.context() ) == 0 && qstrcmp( sourceText(), m.sourceText() ) == 0 && qstrcmp( comment(), m.comment() ) == 0;}bool MetaTranslatorMessage::operator<( const MetaTranslatorMessage& m ) const{ int delta = qstrcmp( context(), m.context() ); if ( delta == 0 ) { delta = qstrcmp( sourceText(), m.sourceText() ); if (delta == 0) delta = qstrcmp( comment(), m.comment() ); } return delta < 0;}MetaTranslator::MetaTranslator(){ clear();}MetaTranslator::MetaTranslator( const MetaTranslator& tor ) : mm( tor.mm ), codecName( tor.codecName ), codec( tor.codec ){}MetaTranslator& MetaTranslator::operator=( const MetaTranslator& tor ){ mm = tor.mm; codecName = tor.codecName; codec = tor.codec; return *this;}void MetaTranslator::clear(){ mm.clear(); codecName = "ISO-8859-1"; codec = 0;}bool MetaTranslator::load( const QString& filename ){ QFile f( filename ); if ( !f.open(QIODevice::ReadOnly) ) return false; QXmlInputSource in( &f ); QXmlSimpleReader reader; QXmlDefaultHandler *hand = 0; if (filename.endsWith(QLatin1String(".xlf"))) { hand = static_cast<QXmlDefaultHandler *>(new XLIFFHandler( this )); } else { reader.setFeature( QLatin1String("http://xml.org/sax/features/namespaces"), false ); reader.setFeature( QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true ); hand = static_cast<QXmlDefaultHandler *>(new TsHandler( this ));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?