xliff.cpp
来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 581 行 · 第 1/2 页
CPP
581 行
/******************************************************************************** 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 "xliff.h"#include <QtCore/QTextStream>#include <QtCore/QString>#include <QtCore/QFile>#include <QtCore/QTextCodec>#include <QtXml>#include <QtGui/QApplication>#include <QtGui/QMessageBox>/** * Implementation of XLIFF file format for Linguist */#define XLIFF11_PROFILE_PO_DRAFT#ifdef XLIFF11_PROFILE_PO_DRAFTstatic const char *restypeContext = "x-gettext-domain";static const char *restypePlurals = "x-gettext-plurals";static const char *dataTypeUIFile = "x-trolltech-designer-ui";static const char *contextNameLocation = "po-reference"; //###//static const char *contextTypeComment = "x-po-transcomment";#elsestatic const char *restypeContext = "x-trolltech-linguist-context";static const char *restypePlurals = "x-trolltech-linguist-plurals";static const char *dataTypeUIFile = "x-trolltech-designer-ui";static const char *contextNameLocation = "lineNo";#endifstatic const char *XLIFF11namespaceURI = "urn:oasis:names:tc:xliff:document:1.1";// try our best at XLIFF12 alsostatic const char *XLIFF12namespaceURI = "urn:oasis:names:tc:xliff:document:1.2";#define COMBINE4CHARS(c1, c2, c3, c4) \ (int(c1) << 24 | int(c2) << 16 | int(c3) << 8 | int(c4) )static QString dataType(const MetaTranslatorMessage &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 writeIndent(QTextStream *t, int indent){ // ### slow (?) for (int i = 0 ; i < indent; ++i) { (*t) << " "; }}struct CharMnemonic{ char ch; char escape; char *mnemonic;};static const CharMnemonic charCodeMnemonics[] = { {0x07, 'a', "bel"}, {0x08, 'b', "bs"}, {0x09, 't', "tab"}, {0x0a, 'n', "lf"}, {0x0b, 'v', "vt"}, {0x0c, 'f', "ff"}, {0x0d, 'r', "cr"}};static char charFromEscape(char escape){ for (uint i = 0; i < sizeof(charCodeMnemonics)/sizeof(CharMnemonic); ++i) { CharMnemonic cm = charCodeMnemonics[i]; if (cm.escape == escape) return cm.ch; } Q_ASSERT(0); return escape;}static QString numericEntity( int ch ){ QString name; char escapechar; // ### This needs to be reviewed, to reflect the updated XLIFF-PO spec. if (ch >= 7 && ch <= 0x0d) { CharMnemonic cm = charCodeMnemonics[int(ch) - 7]; name = QLatin1String(cm.mnemonic); escapechar = cm.escape; static int id = 0; return QString::fromAscii("<ph id=\"ph%1\" ctype=\"x-ch-%2\">\\%3</ph>") .arg(++id) .arg(name) .arg(escapechar); } else { return QString::fromAscii("&#x%1;").arg(QString::number(ch, 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 += QLatin1String( """ ); break; case '&': result += QLatin1String( "&" ); break; case '>': result += QLatin1String( ">" ); break; case '<': result += QLatin1String( "<" ); break; case '\'': result += QLatin1String( "'" ); break; default: if ( (uchar) str[k] < 0x20 ) 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; }}static void writeLineNumber(QTextStream *t, const MetaTranslatorMessage &msg, int indent){ if (msg.lineNumber() != -1) { writeIndent(t, indent); (*t) << "<context-group name=\"" << contextNameLocation << "\" purpose=\"location\"><context context-type=\"linenumber\">" << msg.lineNumber() << "</context></context-group>\n"; }}static void writeComment(QTextStream *t, const MetaTranslatorMessage &msg, int indent){ if (msg.comment() && qstrlen(msg.comment())) { writeIndent(t, indent); (*t) << "<note>" << msg.comment() << "</note>\n"; }}static void writeTransUnit(QTextStream *t, const MetaTranslatorMessage &msg, int msgid, int indent, const QString &translation = QString()){ static int plural = 0; static int prevMsgId = -1; writeIndent(t, indent); (*t) << "<trans-unit id=\"msg"; QString strid; QByteArray transl; if (msg.isPlural()) { if (prevMsgId != msgid) plural = 0; strid = QString::fromAscii("%1[%2]").arg(msgid).arg(plural); ++plural; transl = translation.toUtf8(); } else { strid = QString::fromAscii("%1").arg(msgid); plural = 0; transl = msg.translation().toUtf8(); } prevMsgId = msgid; (*t) << strid << "\""; QString state; indent+=2; if (msg.type() == MetaTranslatorMessage::Obsolete) { (*t) << " translate=\"no\""; } else { state = msg.type() == MetaTranslatorMessage::Finished ? QLatin1String("final") : QLatin1String("new"); state = QString::fromAscii(" state=\"%1\"").arg(state); } (*t) << ">\n"; writeIndent(t, indent); (*t) << "<source xml:space=\"preserve\">" << evilBytes(msg.sourceText(), msg.utf8()) << "</source>\n"; writeIndent(t, indent); (*t) << "<target xml:space=\"preserve\"" << state << ">" << evilBytes(transl, msg.utf8()) << "</target>\n"; // ### In XLIFF 1.1, name is marked as required, and it must be unique // This is questionable behaviour, and was brought up at the xliff-comments mailinglist. if (!msg.isPlural()) { writeLineNumber(t, msg, indent); writeComment(t, msg, indent); } indent-=2; writeIndent(t, indent); (*t) << "</trans-unit>\n";}static void writeMessage(QTextStream *t, const MetaTranslatorMessage &msg, int indent, const QString &languageCode){ static int msgid = 1; if (msg.isPlural()) { writeIndent(t, indent); (*t) << "<group restype=\"" << restypePlurals << "\">\n"; indent+=2; writeLineNumber(t, msg, indent); writeComment(t, msg, indent); QLocale::Language l; QLocale::Country c; MetaTranslator::languageAndCountry(languageCode, &l, &c); QStringList translns = MetaTranslator::normalizedTranslations(msg, l, c); for (int j = 0; j < qMax(1, translns.count()); ++j) { writeTransUnit(t, msg, msgid, indent, translns.at(j));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?