Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
driver.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 "driver.h"
5#include "uic.h"
6#include "ui4.h"
7
8#include <language.h>
9
10#include <qfileinfo.h>
11#include <qdebug.h>
12
13#include <algorithm>
14
16
17using namespace Qt::StringLiterals;
18
20 : m_stdout(stdout, QFile::WriteOnly | QFile::Text)
21{
22 m_output = &m_stdout;
23}
24
25Driver::~Driver() = default;
26
27static inline QString spacerItemClass() { return QStringLiteral("QSpacerItem"); }
28static inline QString actionGroupClass() { return QStringLiteral("QActionGroup"); }
29static inline QString actionClass() { return QStringLiteral("QAction"); }
30static inline QString buttonGroupClass() { return QStringLiteral("QButtonGroup"); }
31
32template <class DomClass>
33Driver::DomObjectHashConstIt<DomClass>
34 Driver::findByAttributeNameIt(const DomObjectHash<DomClass> &domHash,
35 const QString &name) const
36{
37 const auto end = domHash.cend();
38 for (auto it = domHash.cbegin(); it != end; ++it) {
39 if (it.key()->attributeName() == name)
40 return it;
41 }
42 return end;
43}
44
45template <class DomClass>
46const DomClass *Driver::findByAttributeName(const DomObjectHash<DomClass> &domHash,
47 const QString &name) const
48{
49 auto it = findByAttributeNameIt(domHash, name);
50 return it != domHash.cend() ? it.key() : nullptr;
51}
52
53template <class DomClass>
54QString Driver::findOrInsert(DomObjectHash<DomClass> *domHash, const DomClass *dom,
55 const QString &className, bool isMember)
56{
57 auto it = domHash->find(dom);
58 if (it == domHash->end()) {
59 const QString name = this->unique(dom->attributeName(), className);
60 it = domHash->insert(dom, isMember ? language::self + name : name);
61 }
62 return it.value();
63}
64
66{
67 // Top level is passed into setupUI(), everything else is a member variable
68 const bool isMember = !m_widgets.isEmpty();
69 return findOrInsert(&m_widgets, ui_widget, ui_widget->attributeClass(), isMember);
70}
71
73{
74 return findOrInsert(&m_spacers, ui_spacer, spacerItemClass());
75}
76
78{
79 return findOrInsert(&m_layouts, ui_layout, ui_layout->attributeClass());
80}
81
83{
84 switch (ui_layoutItem->kind()) {
86 return findOrInsertWidget(ui_layoutItem->elementWidget());
88 return findOrInsertSpacer(ui_layoutItem->elementSpacer());
90 return findOrInsertLayout(ui_layoutItem->elementLayout());
92 break;
93 }
94
95 Q_ASSERT( 0 );
96
97 return QString();
98}
99
101{
102 return findOrInsert(&m_actionGroups, ui_group, actionGroupClass());
103}
104
106{
107 return findOrInsert(&m_actions, ui_action, actionClass());
108}
109
111{
112 return findOrInsert(&m_buttonGroups, ui_group, buttonGroupClass());
113}
114
115// Find a group by its non-uniqified name
116const DomButtonGroup *Driver::findButtonGroup(const QString &attributeName) const
117{
118 return findByAttributeName(m_buttonGroups, attributeName);
119}
120
121
126
128{
130 std::replace_if(result.begin(), result.end(),
131 [] (QChar c) { return !c.isLetterOrNumber(); },
132 u'_');
133 return result;
134}
135
136QString Driver::unique(const QString &instanceName, const QString &className)
137{
139 bool alreadyUsed = false;
140
141 if (!instanceName.isEmpty()) {
142 name = normalizedName(instanceName);
143 QString base = name;
144
145 for (int id = 1; m_nameRepository.contains(name); ++id) {
146 alreadyUsed = true;
147 name = base + QString::number(id);
148 }
149 } else if (!className.isEmpty()) {
151 } else {
152 name = unique("var"_L1);
153 }
154
155 if (alreadyUsed && !className.isEmpty()) {
156 fprintf(stderr, "%s: Warning: The name '%s' (%s) is already in use, defaulting to '%s'.\n",
157 qPrintable(m_option.messagePrefix()),
158 qPrintable(instanceName), qPrintable(className),
160 }
161
162 m_nameRepository.insert(name, true);
163 return name;
164}
165
167{
168 QString qname = name;
169
170 if (qname.at(0) == u'Q' || qname.at(0) == u'K')
171 qname.remove(0, 1);
172
173 for (int i = 0, size = qname.size(); i < size && qname.at(i).isUpper(); ++i)
174 qname[i] = qname.at(i).toLower();
175
176 return qname;
177}
178
180{
181 return (c.toUpper() >= u'A' && c.toUpper() <= u'Z') || c.isDigit() || c == u'_';
182}
183
185{
186 QString name = m_option.outputFile;
187
188 if (name.isEmpty()) {
189 name = "ui_"_L1; // ### use ui_ as prefix.
190 name.append(m_option.inputFile);
191 }
192
193 return headerFileName(name);
194}
195
197{
198 if (fileName.isEmpty())
199 return headerFileName(u"noname"_s);
200
202 QString baseName = info.baseName();
203 // Transform into a valid C++ identifier
204 if (!baseName.isEmpty() && baseName.at(0).isDigit())
205 baseName.prepend(u'_');
206 for (int i = 0; i < baseName.size(); ++i) {
207 QChar c = baseName.at(i);
208 if (!isAnsiCCharacter(c)) {
209 // Replace character by its unicode value
210 QString hex = QString::number(c.unicode(), 16);
211 baseName.replace(i, 1, u'_' + hex + u'_');
212 i += hex.size() + 1;
213 }
214 }
215 return baseName.toUpper() + "_H"_L1;
216}
217
219{
220 Q_ASSERT(m_option.dependencies == true);
221
222 m_option.inputFile = fileName;
223
224 Uic tool(this);
225 return tool.printDependencies();
226}
227
229{
230 m_option.inputFile = fileName;
231 setUseIdBasedTranslations(ui->attributeIdbasedtr());
232
233 QTextStream *oldOutput = m_output;
234
235 m_output = out != nullptr ? out : &m_stdout;
236
237 Uic tool(this);
238 const bool result = tool.write(ui);
239
240 m_output = oldOutput;
241
242 return result;
243}
244
246{
247 QFile f;
248 if (fileName.isEmpty()) {
249 if (!f.open(stdin, QIODevice::ReadOnly))
250 return false;
251 } else {
253 if (!f.open(QIODevice::ReadOnly))
254 return false;
255 }
256
257 m_option.inputFile = fileName;
258
259 QTextStream *oldOutput = m_output;
260 bool deleteOutput = false;
261
262 if (out) {
263 m_output = out;
264 } else {
265#ifdef Q_OS_WIN
266 // As one might also redirect the output to a file on win,
267 // we should not create the textstream with QFile::Text flag.
268 // The redirected file is opened in TextMode and this will
269 // result in broken line endings as writing will replace \n again.
270 m_output = new QTextStream(stdout, QIODevice::WriteOnly);
271#else
272 m_output = new QTextStream(stdout, QIODevice::WriteOnly | QFile::Text);
273#endif
274 deleteOutput = true;
275 }
276
277 Uic tool(this);
278 bool rtn = tool.write(&f);
279 f.close();
280
281 if (deleteOutput)
282 delete m_output;
283
284 m_output = oldOutput;
285
286 return rtn;
287}
288
289const DomWidget *Driver::widgetByName(const QString &attributeName) const
290{
291 return findByAttributeName(m_widgets, attributeName);
292}
293
294QString Driver::widgetVariableName(const QString &attributeName) const
295{
296 auto it = findByAttributeNameIt(m_widgets, attributeName);
297 return it != m_widgets.cend() ? it.value() : QString();
298}
299
300const DomActionGroup *Driver::actionGroupByName(const QString &attributeName) const
301{
302 return findByAttributeName(m_actionGroups, attributeName);
303}
304
305const DomAction *Driver::actionByName(const QString &attributeName) const
306{
307 return findByAttributeName(m_actions, attributeName);
308}
309
Definition ui4.h:116
bool uic(const QString &fileName, QTextStream *output=nullptr)
Definition driver.cpp:245
void setUseIdBasedTranslations(bool u)
Definition driver.h:68
const DomAction * actionByName(const QString &attributeName) const
Definition driver.cpp:305
QString widgetVariableName(const QString &attributeName) const
Definition driver.cpp:294
static QString qtify(const QString &name)
Definition driver.cpp:166
const DomActionGroup * actionGroupByName(const QString &attributeName) const
Definition driver.cpp:300
QString unique(const QString &instanceName=QString(), const QString &className=QString())
Definition driver.cpp:136
QString findOrInsertButtonGroup(const DomButtonGroup *ui_group)
Definition driver.cpp:110
static QString normalizedName(const QString &name)
Definition driver.cpp:127
QString findOrInsertWidget(const DomWidget *ui_widget)
Definition driver.cpp:65
const DomWidget * widgetByName(const QString &attributeName) const
Definition driver.cpp:289
QString findOrInsertActionGroup(const DomActionGroup *ui_group)
Definition driver.cpp:100
QString findOrInsertLayoutItem(const DomLayoutItem *ui_layoutItem)
Definition driver.cpp:82
virtual ~Driver()
const DomButtonGroup * findButtonGroup(const QString &attributeName) const
Definition driver.cpp:116
QString headerFileName() const
Definition driver.cpp:184
QString findOrInsertAction(const DomAction *ui_action)
Definition driver.cpp:105
QString findOrInsertLayout(const DomLayout *ui_layout)
Definition driver.cpp:77
QString findOrInsertSpacer(const DomSpacer *ui_spacer)
Definition driver.cpp:72
Driver()
Definition driver.cpp:19
QString findOrInsertName(const QString &name)
Definition driver.cpp:122
bool printDependencies(const QString &fileName)
Definition driver.cpp:218
\inmodule QtCore
\inmodule QtCore
Definition qfile.h:93
void setFileName(const QString &name)
Sets the name of the file.
Definition qfile.cpp:302
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
Definition qhash.h:1007
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
iterator end()
Definition qset.h:140
const_iterator cend() const noexcept
Definition qset.h:142
iterator find(const T &value)
Definition qset.h:159
const_iterator cbegin() const noexcept
Definition qset.h:138
iterator insert(const T &value)
Definition qset.h:155
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3824
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
QString & append(QChar c)
Definition qstring.cpp:3252
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition qstring.cpp:3466
QString & prepend(QChar c)
Definition qstring.h:478
QString toUpper() const &
Definition qstring.h:439
\inmodule QtCore
Definition uic.h:30
bool printDependencies()
Definition uic.cpp:36
bool write(QIODevice *in)
Definition uic.cpp:191
QSet< QString >::iterator it
static QString buttonGroupClass()
Definition driver.cpp:30
static bool isAnsiCCharacter(QChar c)
Definition driver.cpp:179
static QString spacerItemClass()
Definition driver.cpp:27
static QString actionGroupClass()
Definition driver.cpp:28
static QString actionClass()
Definition driver.cpp:29
Combined button and popup list for selecting options.
QString self
Definition language.cpp:58
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint end
GLenum GLuint id
[7]
GLfloat GLfloat f
GLuint name
const GLubyte * c
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
static const uint base
Definition qurlidna.cpp:20
const char className[16]
[1]
Definition qwizard.cpp:100
QTextStream out(stdout)
[7]
QHostInfo info
[0]
QString outputFile
Definition option.h:36
QString messagePrefix() const
Definition option.h:65
unsigned int dependencies
Definition option.h:25
QString inputFile
Definition option.h:35