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
ui.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#include "xmlparser.h"
6
7#include <QtCore/QCoreApplication>
8#include <QtCore/QDebug>
9#include <QtCore/QFile>
10#include <QtCore/QString>
11#include <QtCore/QXmlStreamReader>
12
14
15using namespace Qt::StringLiterals;
16
17class UiReader : public XmlParser
18{
19public:
20 UiReader(Translator &translator, ConversionData &cd, QXmlStreamReader &reader)
21 : XmlParser(reader),
22 m_translator(translator),
23 m_cd(cd),
24 m_lineNumber(-1),
25 m_isTrString(false),
26 m_insideStringList(false)
27 {
28 }
29 ~UiReader() override = default;
30
31private:
32 bool startElement(QStringView namespaceURI, QStringView localName,
33 QStringView qName, const QXmlStreamAttributes &atts) override;
34 bool endElement(QStringView namespaceURI, QStringView localName,
35 QStringView qName) override;
36 bool characters(QStringView ch) override;
37 bool fatalError(qint64 line, qint64 column, const QString &message) override;
38
39 void flush();
40 void readTranslationAttributes(const QXmlStreamAttributes &atts);
41
42 Translator &m_translator;
43 ConversionData &m_cd;
44 QString m_context;
45 QString m_source;
46 QString m_comment;
47 QString m_extracomment;
48 QString m_id;
49 QString m_label;
50
51 QString m_accum;
52 int m_lineNumber;
53 bool m_isTrString;
54 bool m_insideStringList;
55};
56
57bool UiReader::startElement(QStringView namespaceURI, QStringView localName,
58 QStringView qName, const QXmlStreamAttributes &atts)
59{
60 Q_UNUSED(namespaceURI);
61 Q_UNUSED(localName);
62
63 if (qName == "string"_L1) {
64 flush();
65 if (!m_insideStringList)
66 readTranslationAttributes(atts);
67 } else if (qName == "stringlist"_L1) {
68 flush();
69 m_insideStringList = true;
70 readTranslationAttributes(atts);
71 } else if (qName == "ui"_L1) {
72 m_label = QString(atts.value("label"));
73 }
74 m_accum.clear();
75 return true;
76}
77
78bool UiReader::endElement(QStringView namespaceURI, QStringView localName,
79 QStringView qName)
80{
81 Q_UNUSED(namespaceURI);
82 Q_UNUSED(localName);
83
84 m_accum.replace("\r\n"_L1, "\n"_L1);
85
86 if (qName == "class"_L1) { // UI "header"
87 if (m_context.isEmpty())
88 m_context = m_accum;
89 } else if (qName == "string"_L1 && m_isTrString) {
90 m_source = m_accum;
91 } else if (qName == "comment"_L1) { // FIXME: what's that?
92 m_comment = m_accum;
93 flush();
94 } else if (qName == "stringlist"_L1) {
95 m_insideStringList = false;
96 } else {
97 flush();
98 }
99 return true;
100}
101
102bool UiReader::characters(QStringView ch)
103{
104 m_accum += ch.toString();
105 return true;
106}
107
108bool UiReader::fatalError(qint64 line, qint64 column, const QString &message)
109{
110 QString msg = QStringLiteral("XML error: Parse error at line %1, column %2 (%3).")
111 .arg(line)
112 .arg(column)
113 .arg(message);
114 m_cd.appendError(msg);
115 return false;
116}
117
118void UiReader::flush()
119{
120 if ((!m_context.isEmpty() || !m_id.isEmpty()) && !m_source.isEmpty()) {
121 TranslatorMessage msg(m_context, m_source,
122 m_comment, QString(), m_cd.m_sourceFileName,
123 m_lineNumber, QStringList());
124 msg.setExtraComment(m_extracomment);
125 msg.setLabel(m_label);
126 msg.setId(m_id);
127 if (!m_id.isEmpty())
128 msg.setContext({});
129 m_translator.extend(msg, m_cd);
130 }
131 m_source.clear();
132 if (!m_insideStringList) {
133 m_comment.clear();
134 m_extracomment.clear();
135 m_id.clear();
136 }
137}
138
139void UiReader::readTranslationAttributes(const QXmlStreamAttributes &atts)
140{
141 const auto notr = atts.value(QStringLiteral("notr"));
142 if (notr.isEmpty() || notr != QStringLiteral("true")) {
143 m_isTrString = true;
144 m_comment = atts.value(QStringLiteral("comment")).toString();
145 m_extracomment = atts.value(QStringLiteral("extracomment")).toString();
146 m_id = atts.value(QStringLiteral("id")).toString();
147 if (m_id.isEmpty())
148 m_label.clear();
149 if (!m_cd.m_noUiLines)
150 m_lineNumber = static_cast<int>(reader.lineNumber());
151 } else {
152 m_isTrString = false;
153 }
154}
155
156bool loadUI(Translator &translator, const QString &filename, ConversionData &cd)
157{
158 cd.m_sourceFileName = filename;
159 QFile file(filename);
160 if (!file.open(QIODevice::ReadOnly)) {
161 cd.appendError("Cannot open %1: %2"_L1.arg(filename, file.errorString()));
162 return false;
163 }
164
165 QXmlStreamReader reader(&file);
166 reader.setNamespaceProcessing(false);
167
168 UiReader uiReader(translator, cd, reader);
169 bool result = uiReader.parse();
170 if (!result)
171 cd.appendError(u"Parse error in UI file"_s);
172 return result;
173}
174
175QT_END_NAMESPACE
void extend(const TranslatorMessage &msg, ConversionData &cd)
UiReader(Translator &translator, ConversionData &cd, QXmlStreamReader &reader)
Definition ui.cpp:20
bool fatalError(qint64 line, qint64 column, const QString &message) override
Definition ui.cpp:108
bool startElement(QStringView namespaceURI, QStringView localName, QStringView qName, const QXmlStreamAttributes &atts) override
Definition ui.cpp:57
bool endElement(QStringView namespaceURI, QStringView localName, QStringView qName) override
Definition ui.cpp:78
bool characters(QStringView ch) override
Definition ui.cpp:102
~UiReader() override=default
bool parse()
Definition xmlparser.cpp:8
Combined button and popup list for selecting options.
bool loadUI(Translator &translator, const QString &filename, ConversionData &cd)
Definition ui.cpp:156