xliff.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 581 行 · 第 1/2 页

CPP
581
字号
        }        indent-=2;        writeIndent(t, indent);        (*t) << "</group>\n";    } else {        writeTransUnit(t, msg, msgid, indent);    }    ++msgid;}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, MetaTranslatorMessage> mtSortByFileName;    TMM::ConstIterator m = mm.begin();    while ( m != mm.end() ) {        MetaTranslatorMessage 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, MetaTranslatorMessage>::iterator mi = mtSortByFileName.begin();    MetaTranslatorMessage 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;}XLIFFHandler::XLIFFHandler( MetaTranslator *translator )    : tor( translator ),       m_type( MetaTranslatorMessage::Finished ),      m_lineNumber(-1),       ferrorCount( 1 ),       contextIsUtf8( false ),      messageIsUtf8( false ),       m_URI(QLatin1String(XLIFF11namespaceURI)),      m_URI12(QLatin1String(XLIFF12namespaceURI)){     }void XLIFFHandler::pushContext(XliffContext ctx){    m_contextStack.push_back(ctx);}// Only pops it off if the top of the stack contains ctxbool XLIFFHandler::popContext(XliffContext ctx){    if (!m_contextStack.isEmpty() && m_contextStack.top() == ctx) {        m_contextStack.pop();        return true;    }    return false;}XLIFFHandler::XliffContext XLIFFHandler::currentContext() const{    if (!m_contextStack.isEmpty())        return (XliffContext)m_contextStack.top();    return XC_xliff;}// traverses to the top to check all of the parent contexes.bool XLIFFHandler::hasContext(XliffContext ctx) const{    for (int i = m_contextStack.count() - 1; i >= 0; --i) {        if (m_contextStack.at(i) == ctx)            return true;    }    return false;}bool XLIFFHandler::startElement( const QString& namespaceURI,                           const QString& localName, const QString& /*qName*/,                           const QXmlAttributes& atts ){    if (namespaceURI == m_URI || namespaceURI == m_URI12) {        if (localName == QLatin1String("xliff")) {            // make sure that the stack is not empty during parsing            pushContext(XC_xliff);        } else if (localName == QLatin1String("file")) {            m_fileName = atts.value(QLatin1String("original"));            m_language = atts.value(QLatin1String("target-language"));        } else if (localName == QLatin1String("group")) {            pushContext(XC_group);            if (atts.value(QLatin1String("restype")) == QLatin1String(restypeContext)) {                m_context = atts.value(QLatin1String("resname"));            } else {                if (atts.value(QLatin1String("restype")) == QLatin1String(restypePlurals)) {                    pushContext(XC_restype_plurals);                }                m_comment.clear();            }        } else if (localName == QLatin1String("trans-unit")) {            if (atts.value(QLatin1String("translate")) == QLatin1String("no")) {                m_type = MetaTranslatorMessage::Obsolete;            }            m_comment.clear();        } else if (localName == QLatin1String("target")) {            QString state = atts.value(QLatin1String("state"));            if (state == QLatin1String("new")) {                m_type = MetaTranslatorMessage::Unfinished;            } else if (state == QLatin1String("final")) {                m_type = MetaTranslatorMessage::Finished;            }        } else if (localName == QLatin1String("context-group")) {            QString purpose = atts.value(QLatin1String("purpose"));            if (purpose == QLatin1String("location")) {                pushContext(XC_context_group);            }        } else if (currentContext() == XC_context_group && localName == QLatin1String("context")) {            if ( atts.value(QLatin1String("context-type")) == QLatin1String("linenumber"))                pushContext(XC_context_linenumber);        } else if (localName == QLatin1String("ph")) {            QString ctype = atts.value(QLatin1String("ctype"));            if (ctype.startsWith(QLatin1String("x-ch-"))) {                m_ctype = ctype.mid(5);            }            pushContext(XC_ph);        }        if (currentContext() != XC_ph)            accum.clear();        return true;    }    return false;}bool XLIFFHandler::endElement(const QString& namespaceURI,                              const QString& localName, const QString& /*qName*/ ){    if (namespaceURI == m_URI || namespaceURI == m_URI12) {        if (localName == QLatin1String("xliff")) {            popContext(XC_xliff);        } else if (localName == QLatin1String("source")) {            m_source = accum;        } else if (localName == QLatin1String("target")) {            translations.append(accum);        } else if (localName == QLatin1String("context-group")) {            popContext(XC_context_group);        } else if (currentContext() == XC_context_linenumber && localName == QLatin1String("context")) {            bool ok;            m_lineNumber = accum.trimmed().toInt(&ok);            if (!ok)                m_lineNumber = -1;            popContext(XC_context_linenumber);        } else if (localName == QLatin1String("note")) {            m_comment = accum;        } else if (localName == QLatin1String("ph")) {            m_ctype.clear();            popContext(XC_ph);        } else if (localName == QLatin1String("trans-unit")) {            if (!hasContext(XC_restype_plurals)) {                tor->insert( MetaTranslatorMessage(m_context.toAscii(), m_source.toAscii(),                                                m_comment.toAscii(), m_fileName, m_lineNumber,                                                 translations, false, m_type, false) );                translations.clear();                m_lineNumber = -1;            }        } else if (localName == QLatin1String("group")) {            if (hasContext(XC_restype_plurals)) {                tor->insert( MetaTranslatorMessage(m_context.toAscii(), m_source.toAscii(),                                                m_comment.toAscii(), m_fileName, m_lineNumber,                                                 translations, false, m_type, true) );                popContext(XC_restype_plurals);                translations.clear();                m_lineNumber = -1;            }            popContext(XC_group);        }        return true;    }    return false;}bool XLIFFHandler::characters( const QString& ch ){    if (currentContext() == XC_ph) {        // handle the content of <ph> elements        for (int i = 0; i < ch.count(); ++i) {            QChar chr  = ch.at(i);            if (accum.endsWith(QLatin1Char('\\'))) {                accum[accum.size() - 1] = QLatin1Char(charFromEscape(chr.toAscii()));            } else {                accum.append(chr);            }        }    } else {        QString t = ch;        // a hack to avoid that QString::simplified does not remove the space at the beginning or at the end.        t.prepend(QLatin1Char('|'));        t.append(QLatin1Char('|'));        t = t.simplified().mid(1, t.length() - 2);        accum += t;    }    return true;}bool XLIFFHandler::endDocument(){    tor->setLanguageCode(m_language);    return true;}bool XLIFFHandler::fatalError( const QXmlParseException& exception ){    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;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?