source: trunk/tools/linguist/shared/qph.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the Qt Linguist of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "translator.h"
43
44#include <QtCore/QByteArray>
45#include <QtCore/QDebug>
46#include <QtCore/QTextCodec>
47#include <QtCore/QTextStream>
48
49#include <QtXml/QXmlStreamReader>
50#include <QtXml/QXmlStreamAttribute>
51
52QT_BEGIN_NAMESPACE
53
54class QPHReader : public QXmlStreamReader
55{
56public:
57 QPHReader(QIODevice &dev)
58 : QXmlStreamReader(&dev)
59 {}
60
61 // the "real thing"
62 bool read(Translator &translator);
63
64private:
65 bool isWhiteSpace() const
66 {
67 return isCharacters() && text().toString().trimmed().isEmpty();
68 }
69
70 enum DataField { NoField, SourceField, TargetField, DefinitionField };
71 DataField m_currentField;
72 QString m_currentSource;
73 QString m_currentTarget;
74 QString m_currentDefinition;
75};
76
77bool QPHReader::read(Translator &translator)
78{
79 m_currentField = NoField;
80 QString result;
81 while (!atEnd()) {
82 readNext();
83 if (isStartElement()) {
84 if (name() == QLatin1String("source")) {
85 m_currentField = SourceField;
86 } else if (name() == QLatin1String("target")) {
87 m_currentField = TargetField;
88 } else if (name() == QLatin1String("definition")) {
89 m_currentField = DefinitionField;
90 } else {
91 m_currentField = NoField;
92 if (name() == QLatin1String("QPH")) {
93 QXmlStreamAttributes atts = attributes();
94 translator.setLanguageCode(atts.value(QLatin1String("language")).toString());
95 translator.setSourceLanguageCode(atts.value(QLatin1String("sourcelanguage")).toString());
96 }
97 }
98 } else if (isWhiteSpace()) {
99 // ignore these
100 } else if (isCharacters()) {
101 if (m_currentField == SourceField)
102 m_currentSource += text();
103 else if (m_currentField == TargetField)
104 m_currentTarget += text();
105 else if (m_currentField == DefinitionField)
106 m_currentDefinition += text();
107 } else if (isEndElement() && name() == QLatin1String("phrase")) {
108 m_currentTarget.replace(QChar(Translator::TextVariantSeparator),
109 QChar(Translator::BinaryVariantSeparator));
110 TranslatorMessage msg;
111 msg.setSourceText(m_currentSource);
112 msg.setTranslation(m_currentTarget);
113 msg.setComment(m_currentDefinition);
114 translator.append(msg);
115 m_currentSource.clear();
116 m_currentTarget.clear();
117 m_currentDefinition.clear();
118 }
119 }
120 return true;
121}
122
123static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &)
124{
125 translator.setLocationsType(Translator::NoLocations);
126 QPHReader reader(dev);
127 return reader.read(translator);
128}
129
130static QString protect(const QString &str)
131{
132 QString result;
133 result.reserve(str.length() * 12 / 10);
134 for (int i = 0; i != str.size(); ++i) {
135 uint c = str.at(i).unicode();
136 switch (c) {
137 case '\"':
138 result += QLatin1String("&quot;");
139 break;
140 case '&':
141 result += QLatin1String("&amp;");
142 break;
143 case '>':
144 result += QLatin1String("&gt;");
145 break;
146 case '<':
147 result += QLatin1String("&lt;");
148 break;
149 case '\'':
150 result += QLatin1String("&apos;");
151 break;
152 default:
153 if (c < 0x20 && c != '\r' && c != '\n' && c != '\t')
154 result += QString(QLatin1String("&#%1;")).arg(c);
155 else // this also covers surrogates
156 result += QChar(c);
157 }
158 }
159 return result;
160}
161
162static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &)
163{
164 QTextStream t(&dev);
165 t.setCodec(QTextCodec::codecForName("UTF-8"));
166 t << "<!DOCTYPE QPH>\n<QPH";
167 QString languageCode = translator.languageCode();
168 if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
169 t << " language=\"" << languageCode << "\"";
170 languageCode = translator.sourceLanguageCode();
171 if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
172 t << " sourcelanguage=\"" << languageCode << "\"";
173 t << ">\n";
174 foreach (const TranslatorMessage &msg, translator.messages()) {
175 t << "<phrase>\n";
176 t << " <source>" << protect(msg.sourceText()) << "</source>\n";
177 QString str = msg.translations().join(QLatin1String("@"));
178 str.replace(QChar(Translator::BinaryVariantSeparator),
179 QChar(Translator::TextVariantSeparator));
180 t << " <target>" << protect(str)
181 << "</target>\n";
182 if (!msg.comment().isEmpty())
183 t << " <definition>" << protect(msg.comment()) << "</definition>\n";
184 t << "</phrase>\n";
185 }
186 t << "</QPH>\n";
187 return true;
188}
189
190int initQPH()
191{
192 Translator::FileFormat format;
193
194 format.extension = QLatin1String("qph");
195 format.description = QObject::tr("Qt Linguist 'Phrase Book'");
196 format.fileType = Translator::FileFormat::TranslationSource;
197 format.priority = 0;
198 format.loader = &loadQPH;
199 format.saver = &saveQPH;
200 Translator::registerFileFormat(format);
201
202 return 1;
203}
204
205Q_CONSTRUCTOR_FUNCTION(initQPH)
206
207QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.