| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. |
| 4 | ** Contact: https://www.qt.io/licensing/ |
| 5 | ** |
| 6 | ** This file is part of the tools applications of the Qt Toolkit. |
| 7 | ** |
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| 9 | ** Commercial License Usage |
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in |
| 11 | ** accordance with the commercial license agreement provided with the |
| 12 | ** Software or, alternatively, in accordance with the terms contained in |
| 13 | ** a written agreement between you and The Qt Company. For licensing terms |
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
| 15 | ** information use the contact form at https://www.qt.io/contact-us. |
| 16 | ** |
| 17 | ** GNU General Public License Usage |
| 18 | ** Alternatively, this file may be used under the terms of the GNU |
| 19 | ** General Public License version 3 as published by the Free Software |
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| 21 | ** included in the packaging of this file. Please review the following |
| 22 | ** information to ensure the GNU General Public License requirements will |
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| 24 | ** |
| 25 | ** $QT_END_LICENSE$ |
| 26 | ** |
| 27 | ****************************************************************************/ |
| 28 | |
| 29 | #include "uic.h" |
| 30 | #include "option.h" |
| 31 | #include "driver.h" |
| 32 | #include <language.h> |
| 33 | |
| 34 | #include <qfile.h> |
| 35 | #include <qdir.h> |
| 36 | #include <qhashfunctions.h> |
| 37 | #include <qtextstream.h> |
| 38 | #include <qcoreapplication.h> |
| 39 | #include <qcommandlineoption.h> |
| 40 | #include <qcommandlineparser.h> |
| 41 | |
| 42 | QT_BEGIN_NAMESPACE |
| 43 | |
| 44 | int runUic(int argc, char *argv[]) |
| 45 | { |
| 46 | qSetGlobalQHashSeed(0); // set the hash seed to 0 |
| 47 | |
| 48 | QCoreApplication app(argc, argv); |
| 49 | QCoreApplication::setApplicationVersion(QString::fromLatin1(QT_VERSION_STR)); |
| 50 | |
| 51 | Driver driver; |
| 52 | |
| 53 | // Note that uic isn't translated. |
| 54 | // If you use this code as an example for a translated app, make sure to translate the strings. |
| 55 | QCommandLineParser parser; |
| 56 | parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); |
| 57 | parser.setApplicationDescription(QStringLiteral("Qt User Interface Compiler version %1" ).arg(QString::fromLatin1(QT_VERSION_STR))); |
| 58 | parser.addHelpOption(); |
| 59 | parser.addVersionOption(); |
| 60 | |
| 61 | QCommandLineOption dependenciesOption(QStringList() << QStringLiteral("d" ) << QStringLiteral("dependencies" )); |
| 62 | dependenciesOption.setDescription(QStringLiteral("Display the dependencies." )); |
| 63 | parser.addOption(dependenciesOption); |
| 64 | |
| 65 | QCommandLineOption outputOption(QStringList() << QStringLiteral("o" ) << QStringLiteral("output" )); |
| 66 | outputOption.setDescription(QStringLiteral("Place the output into <file>" )); |
| 67 | outputOption.setValueName(QStringLiteral("file" )); |
| 68 | parser.addOption(outputOption); |
| 69 | |
| 70 | QCommandLineOption noAutoConnectionOption(QStringList() << QStringLiteral("a" ) << QStringLiteral("no-autoconnection" )); |
| 71 | noAutoConnectionOption.setDescription(QStringLiteral("Do not generate a call to QObject::connectSlotsByName()." )); |
| 72 | parser.addOption(noAutoConnectionOption); |
| 73 | |
| 74 | QCommandLineOption noProtOption(QStringList() << QStringLiteral("p" ) << QStringLiteral("no-protection" )); |
| 75 | noProtOption.setDescription(QStringLiteral("Disable header protection." )); |
| 76 | parser.addOption(noProtOption); |
| 77 | |
| 78 | QCommandLineOption noImplicitIncludesOption(QStringList() << QStringLiteral("n" ) << QStringLiteral("no-implicit-includes" )); |
| 79 | noImplicitIncludesOption.setDescription(QStringLiteral("Disable generation of #include-directives." )); |
| 80 | parser.addOption(noImplicitIncludesOption); |
| 81 | |
| 82 | QCommandLineOption postfixOption(QStringLiteral("postfix" )); |
| 83 | postfixOption.setDescription(QStringLiteral("Postfix to add to all generated classnames." )); |
| 84 | postfixOption.setValueName(QStringLiteral("postfix" )); |
| 85 | parser.addOption(postfixOption); |
| 86 | |
| 87 | QCommandLineOption translateOption(QStringList() << QStringLiteral("tr" ) << QStringLiteral("translate" )); |
| 88 | translateOption.setDescription(QStringLiteral("Use <function> for i18n." )); |
| 89 | translateOption.setValueName(QStringLiteral("function" )); |
| 90 | parser.addOption(translateOption); |
| 91 | |
| 92 | QCommandLineOption includeOption(QStringList() << QStringLiteral("include" )); |
| 93 | includeOption.setDescription(QStringLiteral("Add #include <include-file> to <file>." )); |
| 94 | includeOption.setValueName(QStringLiteral("include-file" )); |
| 95 | parser.addOption(includeOption); |
| 96 | |
| 97 | QCommandLineOption generatorOption(QStringList() << QStringLiteral("g" ) << QStringLiteral("generator" )); |
| 98 | generatorOption.setDescription(QStringLiteral("Select generator." )); |
| 99 | generatorOption.setValueName(QStringLiteral("python|cpp" )); |
| 100 | parser.addOption(generatorOption); |
| 101 | |
| 102 | QCommandLineOption connectionsOption(QStringList{QStringLiteral("c" ), QStringLiteral("connections" )}); |
| 103 | connectionsOption.setDescription(QStringLiteral("Connection syntax." )); |
| 104 | connectionsOption.setValueName(QStringLiteral("pmf|string" )); |
| 105 | parser.addOption(connectionsOption); |
| 106 | |
| 107 | QCommandLineOption idBasedOption(QStringLiteral("idbased" )); |
| 108 | idBasedOption.setDescription(QStringLiteral("Use id based function for i18n" )); |
| 109 | parser.addOption(idBasedOption); |
| 110 | |
| 111 | QCommandLineOption fromImportsOption(QStringLiteral("from-imports" )); |
| 112 | fromImportsOption.setDescription(QStringLiteral("Python: generate imports relative to '.'" )); |
| 113 | parser.addOption(fromImportsOption); |
| 114 | |
| 115 | parser.addPositionalArgument(QStringLiteral("[uifile]" ), QStringLiteral("Input file (*.ui), otherwise stdin." )); |
| 116 | |
| 117 | parser.process(app); |
| 118 | |
| 119 | driver.option().dependencies = parser.isSet(dependenciesOption); |
| 120 | driver.option().outputFile = parser.value(outputOption); |
| 121 | driver.option().autoConnection = !parser.isSet(noAutoConnectionOption); |
| 122 | driver.option().headerProtection = !parser.isSet(noProtOption); |
| 123 | driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption); |
| 124 | driver.option().idBased = parser.isSet(idBasedOption); |
| 125 | driver.option().fromImports = parser.isSet(fromImportsOption); |
| 126 | driver.option().postfix = parser.value(postfixOption); |
| 127 | driver.option().translateFunction = parser.value(translateOption); |
| 128 | driver.option().includeFile = parser.value(includeOption); |
| 129 | if (parser.isSet(connectionsOption)) { |
| 130 | const auto value = parser.value(connectionsOption); |
| 131 | if (value == QLatin1String("pmf" )) |
| 132 | driver.option().forceMemberFnPtrConnectionSyntax = 1; |
| 133 | else if (value == QLatin1String("string" )) |
| 134 | driver.option().forceStringConnectionSyntax = 1; |
| 135 | } |
| 136 | |
| 137 | Language language = Language::Cpp; |
| 138 | if (parser.isSet(generatorOption)) { |
| 139 | if (parser.value(generatorOption).compare(QLatin1String("python" )) == 0) |
| 140 | language = Language::Python; |
| 141 | } |
| 142 | language::setLanguage(language); |
| 143 | |
| 144 | QString inputFile; |
| 145 | if (!parser.positionalArguments().isEmpty()) |
| 146 | inputFile = parser.positionalArguments().at(0); |
| 147 | else // reading from stdin |
| 148 | driver.option().headerProtection = false; |
| 149 | |
| 150 | if (driver.option().dependencies) { |
| 151 | return !driver.printDependencies(inputFile); |
| 152 | } |
| 153 | |
| 154 | QTextStream *out = nullptr; |
| 155 | QFile f; |
| 156 | if (!driver.option().outputFile.isEmpty()) { |
| 157 | f.setFileName(driver.option().outputFile); |
| 158 | if (!f.open(QIODevice::WriteOnly | QFile::Text)) { |
| 159 | fprintf(stderr, "Could not create output file\n" ); |
| 160 | return 1; |
| 161 | } |
| 162 | out = new QTextStream(&f); |
| 163 | out->setEncoding(QStringConverter::Utf8); |
| 164 | } |
| 165 | |
| 166 | bool rtn = driver.uic(inputFile, out); |
| 167 | delete out; |
| 168 | |
| 169 | if (!rtn) { |
| 170 | if (driver.option().outputFile.size()) { |
| 171 | f.close(); |
| 172 | f.remove(); |
| 173 | } |
| 174 | fprintf(stderr, "File '%s' is not valid\n" , inputFile.isEmpty() ? "<stdin>" : inputFile.toLocal8Bit().constData()); |
| 175 | } |
| 176 | |
| 177 | return !rtn; |
| 178 | } |
| 179 | |
| 180 | QT_END_NAMESPACE |
| 181 | |
| 182 | int main(int argc, char *argv[]) |
| 183 | { |
| 184 | return QT_PREPEND_NAMESPACE(runUic)(argc, argv); |
| 185 | } |
| 186 | |