Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qph.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "translator.h"
5
6#include <QtCore/QByteArray>
7#include <QtCore/QDebug>
8#include <QtCore/QTextStream>
9
10#include <QtCore/QXmlStreamReader>
11
13
15{
16public:
17 QPHReader(QIODevice &dev)
19 {}
20
21 // the "real thing"
22 bool read(Translator &translator);
23
24private:
25 bool isWhiteSpace() const
26 {
27 return isCharacters() && text().toString().trimmed().isEmpty();
28 }
29
30 enum DataField { NoField, SourceField, TargetField, DefinitionField };
31 DataField m_currentField;
32 QString m_currentSource;
33 QString m_currentTarget;
34 QString m_currentDefinition;
35};
36
37bool QPHReader::read(Translator &translator)
38{
39 m_currentField = NoField;
40 while (!atEnd()) {
41 readNext();
42 if (isStartElement()) {
43 if (name() == QLatin1String("source")) {
44 m_currentField = SourceField;
45 } else if (name() == QLatin1String("target")) {
46 m_currentField = TargetField;
47 } else if (name() == QLatin1String("definition")) {
48 m_currentField = DefinitionField;
49 } else {
50 m_currentField = NoField;
51 if (name() == QLatin1String("QPH")) {
52 QXmlStreamAttributes atts = attributes();
53 translator.setLanguageCode(atts.value(QLatin1String("language")).toString());
54 translator.setSourceLanguageCode(atts.value(QLatin1String("sourcelanguage")).toString());
55 }
56 }
57 } else if (isWhiteSpace()) {
58 // ignore these
59 } else if (isCharacters()) {
60 if (m_currentField == SourceField)
61 m_currentSource += text();
62 else if (m_currentField == TargetField)
63 m_currentTarget += text();
64 else if (m_currentField == DefinitionField)
65 m_currentDefinition += text();
66 } else if (isEndElement() && name() == QLatin1String("phrase")) {
67 m_currentTarget.replace(QChar(Translator::TextVariantSeparator),
68 QChar(Translator::BinaryVariantSeparator));
70 msg.setSourceText(m_currentSource);
71 msg.setTranslation(m_currentTarget);
72 msg.setComment(m_currentDefinition);
73 translator.append(msg);
74 m_currentSource.clear();
75 m_currentTarget.clear();
76 m_currentDefinition.clear();
77 }
78 }
79 return true;
80}
81
82static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &)
83{
85 QPHReader reader(dev);
86 return reader.read(translator);
87}
88
89static QString qphProtect(const QString &str)
90{
91 QString result;
92 result.reserve(str.size() * 12 / 10);
93 for (int i = 0; i != str.size(); ++i) {
94 uint c = str.at(i).unicode();
95 switch (c) {
96 case '\"':
97 result += QLatin1String("&quot;");
98 break;
99 case '&':
100 result += QLatin1String("&amp;");
101 break;
102 case '>':
103 result += QLatin1String("&gt;");
104 break;
105 case '<':
106 result += QLatin1String("&lt;");
107 break;
108 case '\'':
109 result += QLatin1String("&apos;");
110 break;
111 default:
112 if (c < 0x20 && c != '\r' && c != '\n' && c != '\t')
113 result += QString(QLatin1String("&#%1;")).arg(c);
114 else // this also covers surrogates
115 result += QChar(c);
116 }
117 }
118 return result;
119}
120
121static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &)
122{
123 QTextStream t(&dev);
124 t << "<!DOCTYPE QPH>\n<QPH";
125 QString languageCode = translator.languageCode();
126 if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
127 t << " language=\"" << languageCode << "\"";
128 languageCode = translator.sourceLanguageCode();
129 if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
130 t << " sourcelanguage=\"" << languageCode << "\"";
131 t << ">\n";
132 for (const TranslatorMessage &msg : translator.messages()) {
133 t << "<phrase>\n";
134 t << " <source>" << qphProtect(msg.sourceText()) << "</source>\n";
135 QString str = msg.translations().join(QLatin1Char('@'));
136 str.replace(QChar(Translator::BinaryVariantSeparator),
137 QChar(Translator::TextVariantSeparator));
138 t << " <target>" << qphProtect(str)
139 << "</target>\n";
140 if (!msg.comment().isEmpty())
141 t << " <definition>" << qphProtect(msg.comment()) << "</definition>\n";
142 t << "</phrase>\n";
143 }
144 t << "</QPH>\n";
145 return true;
146}
147
149{
150 Translator::FileFormat format;
151
152 format.extension = QLatin1String("qph");
153 format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "Qt Linguist 'Phrase Book'");
155 format.priority = 0;
156 format.loader = &loadQPH;
157 format.saver = &saveQPH;
159
160 return 1;
161}
162
163Q_CONSTRUCTOR_FUNCTION(initQPH)
164
165QT_END_NAMESPACE
bool read(Translator &translator)
Definition qph.cpp:37
QPHReader(QIODevice &dev)
Definition qph.cpp:17
static void registerFileFormat(const FileFormat &format)
void append(const TranslatorMessage &msg)
void setLocationsType(LocationsType lt)
Definition translator.h:132
Combined button and popup list for selecting options.
static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &)
Definition qph.cpp:121
static QString qphProtect(const QString &str)
Definition qph.cpp:89
static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &)
Definition qph.cpp:82
int initQPH()
Definition qph.cpp:148
const char * untranslatedDescription
Definition translator.h:171