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("&quot;") );            break;        case '&':            result += QString( QLatin1String("&amp;") );            break;        case '>':            result += QString( QLatin1String("&gt;") );            break;        case '<':            result += QString( QLatin1String("&lt;") );            break;        case '\'':            result += QString( QLatin1String("&apos;") );            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 + -
显示快捷键?