Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/tools/qml/main.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||||||||
2 | ** | - | ||||||||||||||||||
3 | ** Copyright (C) 2016 Research In Motion. | - | ||||||||||||||||||
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 "conf.h" | - | ||||||||||||||||||
30 | - | |||||||||||||||||||
31 | #include <QCoreApplication> | - | ||||||||||||||||||
32 | - | |||||||||||||||||||
33 | #ifdef QT_GUI_LIB | - | ||||||||||||||||||
34 | #include <QGuiApplication> | - | ||||||||||||||||||
35 | #include <QWindow> | - | ||||||||||||||||||
36 | #include <QFileOpenEvent> | - | ||||||||||||||||||
37 | #include <QOpenGLContext> | - | ||||||||||||||||||
38 | #include <QOpenGLFunctions> | - | ||||||||||||||||||
39 | #ifdef QT_WIDGETS_LIB | - | ||||||||||||||||||
40 | #include <QApplication> | - | ||||||||||||||||||
41 | #endif // QT_WIDGETS_LIB | - | ||||||||||||||||||
42 | #endif // QT_GUI_LIB | - | ||||||||||||||||||
43 | - | |||||||||||||||||||
44 | #include <QQmlApplicationEngine> | - | ||||||||||||||||||
45 | #include <QQmlComponent> | - | ||||||||||||||||||
46 | #include <QDir> | - | ||||||||||||||||||
47 | #include <QFile> | - | ||||||||||||||||||
48 | #include <QFileInfo> | - | ||||||||||||||||||
49 | #include <QStringList> | - | ||||||||||||||||||
50 | #include <QScopedPointer> | - | ||||||||||||||||||
51 | #include <QDebug> | - | ||||||||||||||||||
52 | #include <QStandardPaths> | - | ||||||||||||||||||
53 | #include <QTranslator> | - | ||||||||||||||||||
54 | #include <QtGlobal> | - | ||||||||||||||||||
55 | #include <QLibraryInfo> | - | ||||||||||||||||||
56 | #include <qqml.h> | - | ||||||||||||||||||
57 | #include <qqmldebug.h> | - | ||||||||||||||||||
58 | - | |||||||||||||||||||
59 | #include <private/qtqmlglobal_p.h> | - | ||||||||||||||||||
60 | #if QT_CONFIG(qml_animation) | - | ||||||||||||||||||
61 | #include <private/qabstractanimation_p.h> | - | ||||||||||||||||||
62 | #endif | - | ||||||||||||||||||
63 | - | |||||||||||||||||||
64 | #include <cstdio> | - | ||||||||||||||||||
65 | #include <cstring> | - | ||||||||||||||||||
66 | #include <cstdlib> | - | ||||||||||||||||||
67 | - | |||||||||||||||||||
68 | #define VERSION_MAJ 1 | - | ||||||||||||||||||
69 | #define VERSION_MIN 1 | - | ||||||||||||||||||
70 | #define VERSION_STR "1.1" | - | ||||||||||||||||||
71 | - | |||||||||||||||||||
72 | #define FILE_OPEN_EVENT_WAIT_TIME 3000 // ms | - | ||||||||||||||||||
73 | - | |||||||||||||||||||
74 | static Config *conf = nullptr; | - | ||||||||||||||||||
75 | static QQmlApplicationEngine *qae = nullptr; | - | ||||||||||||||||||
76 | #if defined(Q_OS_DARWIN) || defined(QT_GUI_LIB) | - | ||||||||||||||||||
77 | static int exitTimerId = -1; | - | ||||||||||||||||||
78 | #endif | - | ||||||||||||||||||
79 | bool verboseMode = false; | - | ||||||||||||||||||
80 | - | |||||||||||||||||||
81 | static void loadConf(const QString &override, bool quiet) // Terminates app on failure | - | ||||||||||||||||||
82 | { | - | ||||||||||||||||||
83 | const QString defaultFileName = QLatin1String("configuration.qml"); | - | ||||||||||||||||||
84 | QUrl settingsUrl; | - | ||||||||||||||||||
85 | bool builtIn = false; //just for keeping track of the warning | - | ||||||||||||||||||
86 | if (override.isEmpty()) {
| 0 | ||||||||||||||||||
87 | QFileInfo fi; | - | ||||||||||||||||||
88 | fi.setFile(QStandardPaths::locate(QStandardPaths::DataLocation, defaultFileName)); | - | ||||||||||||||||||
89 | if (fi.exists()) {
| 0 | ||||||||||||||||||
90 | settingsUrl = QUrl::fromLocalFile(fi.absoluteFilePath()); | - | ||||||||||||||||||
91 | } else { never executed: end of block | 0 | ||||||||||||||||||
92 | // ### If different built-in configs are needed per-platform, just apply QFileSelector to the qrc conf.qml path | - | ||||||||||||||||||
93 | settingsUrl = QUrl(QLatin1String("qrc:///qt-project.org/QmlRuntime/conf/") + defaultFileName); | - | ||||||||||||||||||
94 | builtIn = true; | - | ||||||||||||||||||
95 | } never executed: end of block | 0 | ||||||||||||||||||
96 | } else { | - | ||||||||||||||||||
97 | QFileInfo fi; | - | ||||||||||||||||||
98 | fi.setFile(override); | - | ||||||||||||||||||
99 | if (!fi.exists()) {
| 0 | ||||||||||||||||||
100 | printf("qml: Couldn't find required configuration file: %s\n", | - | ||||||||||||||||||
101 | qPrintable(QDir::toNativeSeparators(fi.absoluteFilePath()))); | - | ||||||||||||||||||
102 | exit(1); never executed: exit(1); | 0 | ||||||||||||||||||
103 | } | - | ||||||||||||||||||
104 | settingsUrl = QUrl::fromLocalFile(fi.absoluteFilePath()); | - | ||||||||||||||||||
105 | } never executed: end of block | 0 | ||||||||||||||||||
106 | - | |||||||||||||||||||
107 | if (!quiet) {
| 0 | ||||||||||||||||||
108 | printf("qml: %s\n", QLibraryInfo::build()); | - | ||||||||||||||||||
109 | if (builtIn)
| 0 | ||||||||||||||||||
110 | printf("qml: Using built-in configuration.\n"); never executed: printf("qml: Using built-in configuration.\n"); | 0 | ||||||||||||||||||
111 | else | - | ||||||||||||||||||
112 | printf("qml: Using configuration file: %s\n", never executed: printf("qml: Using configuration file: %s\n", QtPrivate::asString(settingsUrl.isLocalFile() ? QDir::toNativeSeparators(settingsUrl.toLocalFile()) : settingsUrl.toString()).toLocal8Bit().constData() ); | 0 | ||||||||||||||||||
113 | qPrintable(settingsUrl.isLocalFile() never executed: printf("qml: Using configuration file: %s\n", QtPrivate::asString(settingsUrl.isLocalFile() ? QDir::toNativeSeparators(settingsUrl.toLocalFile()) : settingsUrl.toString()).toLocal8Bit().constData() ); | 0 | ||||||||||||||||||
114 | ? QDir::toNativeSeparators(settingsUrl.toLocalFile()) never executed: printf("qml: Using configuration file: %s\n", QtPrivate::asString(settingsUrl.isLocalFile() ? QDir::toNativeSeparators(settingsUrl.toLocalFile()) : settingsUrl.toString()).toLocal8Bit().constData() ); | 0 | ||||||||||||||||||
115 | : settingsUrl.toString())); never executed: printf("qml: Using configuration file: %s\n", QtPrivate::asString(settingsUrl.isLocalFile() ? QDir::toNativeSeparators(settingsUrl.toLocalFile()) : settingsUrl.toString()).toLocal8Bit().constData() ); | 0 | ||||||||||||||||||
116 | } | - | ||||||||||||||||||
117 | - | |||||||||||||||||||
118 | // TODO: When we have better engine control, ban QtQuick* imports on this engine | - | ||||||||||||||||||
119 | QQmlEngine e2; | - | ||||||||||||||||||
120 | QQmlComponent c2(&e2, settingsUrl); | - | ||||||||||||||||||
121 | conf = qobject_cast<Config*>(c2.create()); | - | ||||||||||||||||||
122 | - | |||||||||||||||||||
123 | if (!conf){
| 0 | ||||||||||||||||||
124 | printf("qml: Error loading configuration file: %s\n", qPrintable(c2.errorString())); | - | ||||||||||||||||||
125 | exit(1); never executed: exit(1); | 0 | ||||||||||||||||||
126 | } | - | ||||||||||||||||||
127 | } never executed: end of block | 0 | ||||||||||||||||||
128 | - | |||||||||||||||||||
129 | #ifdef QT_GUI_LIB | - | ||||||||||||||||||
130 | - | |||||||||||||||||||
131 | void noFilesGiven(); | - | ||||||||||||||||||
132 | - | |||||||||||||||||||
133 | // Loads qml after receiving a QFileOpenEvent | - | ||||||||||||||||||
134 | class LoaderApplication : public QGuiApplication | - | ||||||||||||||||||
135 | { | - | ||||||||||||||||||
136 | public: | - | ||||||||||||||||||
137 | LoaderApplication(int& argc, char **argv) : QGuiApplication(argc, argv) {} never executed: end of block | 0 | ||||||||||||||||||
138 | - | |||||||||||||||||||
139 | bool event(QEvent *ev) override | - | ||||||||||||||||||
140 | { | - | ||||||||||||||||||
141 | if (ev->type() == QEvent::FileOpen) {
| 0 | ||||||||||||||||||
142 | if (exitTimerId >= 0) {
| 0 | ||||||||||||||||||
143 | killTimer(exitTimerId); | - | ||||||||||||||||||
144 | exitTimerId = -1; | - | ||||||||||||||||||
145 | } never executed: end of block | 0 | ||||||||||||||||||
146 | qae->load(static_cast<QFileOpenEvent *>(ev)->url()); | - | ||||||||||||||||||
147 | } never executed: end of block | 0 | ||||||||||||||||||
148 | else | - | ||||||||||||||||||
149 | return QGuiApplication::event(ev); never executed: return QGuiApplication::event(ev); | 0 | ||||||||||||||||||
150 | return true; never executed: return true; | 0 | ||||||||||||||||||
151 | } | - | ||||||||||||||||||
152 | - | |||||||||||||||||||
153 | void timerEvent(QTimerEvent *) override { | - | ||||||||||||||||||
154 | noFilesGiven(); | - | ||||||||||||||||||
155 | } never executed: end of block | 0 | ||||||||||||||||||
156 | }; | - | ||||||||||||||||||
157 | - | |||||||||||||||||||
158 | #endif // QT_GUI_LIB | - | ||||||||||||||||||
159 | - | |||||||||||||||||||
160 | // Listens to the appEngine signals to determine if all files failed to load | - | ||||||||||||||||||
161 | class LoadWatcher : public QObject | - | ||||||||||||||||||
162 | { | - | ||||||||||||||||||
163 | Q_OBJECT | - | ||||||||||||||||||
164 | public: | - | ||||||||||||||||||
165 | LoadWatcher(QQmlApplicationEngine *e, int expected) | - | ||||||||||||||||||
166 | : QObject(e) | - | ||||||||||||||||||
167 | , earlyExit(false) | - | ||||||||||||||||||
168 | , returnCode(0) | - | ||||||||||||||||||
169 | , expect(expected) | - | ||||||||||||||||||
170 | , haveOne(false) | - | ||||||||||||||||||
171 | { | - | ||||||||||||||||||
172 | connect(e, SIGNAL(objectCreated(QObject*,QUrl)), | - | ||||||||||||||||||
173 | this, SLOT(checkFinished(QObject*))); | - | ||||||||||||||||||
174 | // QQmlApplicationEngine also connects quit() to QCoreApplication::quit | - | ||||||||||||||||||
175 | // and exit() to QCoreApplication::exit but if called before exec() | - | ||||||||||||||||||
176 | // then QCoreApplication::quit or QCoreApplication::exit does nothing | - | ||||||||||||||||||
177 | connect(e, SIGNAL(quit()), | - | ||||||||||||||||||
178 | this, SLOT(quit())); | - | ||||||||||||||||||
179 | connect(e, &QQmlEngine::exit, | - | ||||||||||||||||||
180 | this, &LoadWatcher::exit); | - | ||||||||||||||||||
181 | } never executed: end of block | 0 | ||||||||||||||||||
182 | - | |||||||||||||||||||
183 | bool earlyExit; | - | ||||||||||||||||||
184 | int returnCode; | - | ||||||||||||||||||
185 | - | |||||||||||||||||||
186 | private: | - | ||||||||||||||||||
187 | void contain(QObject *o, const QUrl &containPath); | - | ||||||||||||||||||
188 | void checkForWindow(QObject *o); | - | ||||||||||||||||||
189 | - | |||||||||||||||||||
190 | int expect; | - | ||||||||||||||||||
191 | bool haveOne; | - | ||||||||||||||||||
192 | - | |||||||||||||||||||
193 | public Q_SLOTS: | - | ||||||||||||||||||
194 | void checkFinished(QObject *o) | - | ||||||||||||||||||
195 | { | - | ||||||||||||||||||
196 | if (o) {
| 0 | ||||||||||||||||||
197 | checkForWindow(o); | - | ||||||||||||||||||
198 | haveOne = true; | - | ||||||||||||||||||
199 | if (conf && qae)
| 0 | ||||||||||||||||||
200 | for (PartialScene *ps : qAsConst(conf->completers)) | - | ||||||||||||||||||
201 | if (o->inherits(ps->itemType().toUtf8().constData()))
| 0 | ||||||||||||||||||
202 | contain(o, ps->container()); never executed: contain(o, ps->container()); | 0 | ||||||||||||||||||
203 | } never executed: end of block | 0 | ||||||||||||||||||
204 | if (haveOne)
| 0 | ||||||||||||||||||
205 | return; never executed: return; | 0 | ||||||||||||||||||
206 | - | |||||||||||||||||||
207 | if (! --expect) {
| 0 | ||||||||||||||||||
208 | printf("qml: Did not load any objects, exiting.\n"); | - | ||||||||||||||||||
209 | std::exit(2);//Different return code from qFatal | - | ||||||||||||||||||
210 | } never executed: end of block | 0 | ||||||||||||||||||
211 | } never executed: end of block | 0 | ||||||||||||||||||
212 | - | |||||||||||||||||||
213 | void quit() { | - | ||||||||||||||||||
214 | //Will be checked before calling exec() | - | ||||||||||||||||||
215 | earlyExit = true; | - | ||||||||||||||||||
216 | returnCode = 0; | - | ||||||||||||||||||
217 | } never executed: end of block | 0 | ||||||||||||||||||
218 | void exit(int retCode) { | - | ||||||||||||||||||
219 | earlyExit = true; | - | ||||||||||||||||||
220 | returnCode = retCode; | - | ||||||||||||||||||
221 | } never executed: end of block | 0 | ||||||||||||||||||
222 | - | |||||||||||||||||||
223 | #if defined(QT_GUI_LIB) && QT_CONFIG(opengl) | - | ||||||||||||||||||
224 | void onOpenGlContextCreated(QOpenGLContext *context); | - | ||||||||||||||||||
225 | #endif | - | ||||||||||||||||||
226 | }; | - | ||||||||||||||||||
227 | - | |||||||||||||||||||
228 | void LoadWatcher::contain(QObject *o, const QUrl &containPath) | - | ||||||||||||||||||
229 | { | - | ||||||||||||||||||
230 | QQmlComponent c(qae, containPath); | - | ||||||||||||||||||
231 | QObject *o2 = c.create(); | - | ||||||||||||||||||
232 | if (!o2)
| 0 | ||||||||||||||||||
233 | return; never executed: return; | 0 | ||||||||||||||||||
234 | checkForWindow(o2); | - | ||||||||||||||||||
235 | bool success = false; | - | ||||||||||||||||||
236 | int idx; | - | ||||||||||||||||||
237 | if ((idx = o2->metaObject()->indexOfProperty("containedObject")) != -1)
| 0 | ||||||||||||||||||
238 | success = o2->metaObject()->property(idx).write(o2, QVariant::fromValue<QObject*>(o)); never executed: success = o2->metaObject()->property(idx).write(o2, QVariant::fromValue<QObject*>(o)); | 0 | ||||||||||||||||||
239 | if (!success)
| 0 | ||||||||||||||||||
240 | o->setParent(o2); //Set QObject parent, and assume container will react as needed never executed: o->setParent(o2); | 0 | ||||||||||||||||||
241 | } never executed: end of block | 0 | ||||||||||||||||||
242 | - | |||||||||||||||||||
243 | void LoadWatcher::checkForWindow(QObject *o) | - | ||||||||||||||||||
244 | { | - | ||||||||||||||||||
245 | #if defined(QT_GUI_LIB) && QT_CONFIG(opengl) | - | ||||||||||||||||||
246 | if (verboseMode && o->isWindowType() && o->inherits("QQuickWindow")) {
| 0 | ||||||||||||||||||
247 | connect(o, SIGNAL(openglContextCreated(QOpenGLContext*)), | - | ||||||||||||||||||
248 | this, SLOT(onOpenGlContextCreated(QOpenGLContext*))); | - | ||||||||||||||||||
249 | } never executed: end of block | 0 | ||||||||||||||||||
250 | #else | - | ||||||||||||||||||
251 | Q_UNUSED(o) | - | ||||||||||||||||||
252 | #endif // QT_GUI_LIB && !QT_NO_OPENGL | - | ||||||||||||||||||
253 | } never executed: end of block | 0 | ||||||||||||||||||
254 | - | |||||||||||||||||||
255 | #if defined(QT_GUI_LIB) && QT_CONFIG(opengl) | - | ||||||||||||||||||
256 | void LoadWatcher::onOpenGlContextCreated(QOpenGLContext *context) | - | ||||||||||||||||||
257 | { | - | ||||||||||||||||||
258 | context->makeCurrent(qobject_cast<QWindow *>(sender())); | - | ||||||||||||||||||
259 | QOpenGLFunctions functions(context); | - | ||||||||||||||||||
260 | QByteArray output = "Vendor : "; | - | ||||||||||||||||||
261 | output += reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR)); | - | ||||||||||||||||||
262 | output += "\nRenderer: "; | - | ||||||||||||||||||
263 | output += reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER)); | - | ||||||||||||||||||
264 | output += "\nVersion : "; | - | ||||||||||||||||||
265 | output += reinterpret_cast<const char *>(functions.glGetString(GL_VERSION)); | - | ||||||||||||||||||
266 | output += "\nLanguage: "; | - | ||||||||||||||||||
267 | output += reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION)); | - | ||||||||||||||||||
268 | puts(output.constData()); | - | ||||||||||||||||||
269 | context->doneCurrent(); | - | ||||||||||||||||||
270 | } never executed: end of block | 0 | ||||||||||||||||||
271 | #endif // QT_GUI_LIB && !QT_NO_OPENGL | - | ||||||||||||||||||
272 | - | |||||||||||||||||||
273 | void quietMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &msg) | - | ||||||||||||||||||
274 | { | - | ||||||||||||||||||
275 | Q_UNUSED(ctxt); | - | ||||||||||||||||||
276 | Q_UNUSED(msg); | - | ||||||||||||||||||
277 | //Doesn't print anything | - | ||||||||||||||||||
278 | switch (type) { | - | ||||||||||||||||||
279 | case QtFatalMsg: never executed: case QtFatalMsg: | 0 | ||||||||||||||||||
280 | exit(-1); never executed: exit(-1); | 0 | ||||||||||||||||||
281 | case QtCriticalMsg: code before this statement never executed: case QtCriticalMsg: never executed: case QtCriticalMsg: | 0 | ||||||||||||||||||
282 | case QtDebugMsg: never executed: case QtDebugMsg: | 0 | ||||||||||||||||||
283 | case QtWarningMsg: never executed: case QtWarningMsg: | 0 | ||||||||||||||||||
284 | default: never executed: default: | 0 | ||||||||||||||||||
285 | ; | - | ||||||||||||||||||
286 | } never executed: end of block | 0 | ||||||||||||||||||
287 | } | - | ||||||||||||||||||
288 | - | |||||||||||||||||||
289 | - | |||||||||||||||||||
290 | // ### Should command line arguments have translations? Qt creator doesn't, so maybe it's not worth it. | - | ||||||||||||||||||
291 | enum QmlApplicationType { | - | ||||||||||||||||||
292 | QmlApplicationTypeUnknown | - | ||||||||||||||||||
293 | , QmlApplicationTypeCore | - | ||||||||||||||||||
294 | #ifdef QT_GUI_LIB | - | ||||||||||||||||||
295 | , QmlApplicationTypeGui | - | ||||||||||||||||||
296 | #ifdef QT_WIDGETS_LIB | - | ||||||||||||||||||
297 | , QmlApplicationTypeWidget | - | ||||||||||||||||||
298 | #endif // QT_WIDGETS_LIB | - | ||||||||||||||||||
299 | #endif // QT_GUI_LIB | - | ||||||||||||||||||
300 | }; | - | ||||||||||||||||||
301 | - | |||||||||||||||||||
302 | #ifndef QT_GUI_LIB | - | ||||||||||||||||||
303 | QmlApplicationType applicationType = QmlApplicationTypeCore; | - | ||||||||||||||||||
304 | #else | - | ||||||||||||||||||
305 | QmlApplicationType applicationType = QmlApplicationTypeGui; | - | ||||||||||||||||||
306 | #endif // QT_GUI_LIB | - | ||||||||||||||||||
307 | bool quietMode = false; | - | ||||||||||||||||||
308 | void printVersion() | - | ||||||||||||||||||
309 | { | - | ||||||||||||||||||
310 | printf("qml binary version "); | - | ||||||||||||||||||
311 | printf(VERSION_STR); | - | ||||||||||||||||||
312 | printf("\nbuilt with Qt version "); | - | ||||||||||||||||||
313 | printf(QT_VERSION_STR); | - | ||||||||||||||||||
314 | printf("\n"); | - | ||||||||||||||||||
315 | exit(0); never executed: exit(0); | 0 | ||||||||||||||||||
316 | } | - | ||||||||||||||||||
317 | - | |||||||||||||||||||
318 | void printUsage() | - | ||||||||||||||||||
319 | { | - | ||||||||||||||||||
320 | printf("Usage: qml [options] [files] [-- args]\n"); | - | ||||||||||||||||||
321 | printf("\n"); | - | ||||||||||||||||||
322 | printf("Any unknown argument before '--' will be treated as a QML file to be loaded.\n"); | - | ||||||||||||||||||
323 | printf("Any number of QML files can be loaded. They will share the same engine.\n"); | - | ||||||||||||||||||
324 | printf("'gui' application type is only available if the QtGui module is available.\n"); | - | ||||||||||||||||||
325 | printf("'widget' application type is only available if the QtWidgets module is available.\n"); | - | ||||||||||||||||||
326 | printf("\n"); | - | ||||||||||||||||||
327 | printf("General Options:\n"); | - | ||||||||||||||||||
328 | printf("\t-h, -help..................... Print this usage information and exit.\n"); | - | ||||||||||||||||||
329 | printf("\t-v, -version.................. Print the version information and exit.\n"); | - | ||||||||||||||||||
330 | #ifdef QT_GUI_LIB | - | ||||||||||||||||||
331 | #ifndef QT_WIDGETS_LIB | - | ||||||||||||||||||
332 | printf("\t-apptype [core|gui] .......... Select which application class to use. Default is gui.\n"); | - | ||||||||||||||||||
333 | #else | - | ||||||||||||||||||
334 | printf("\t-apptype [core|gui|widget] ... Select which application class to use. Default is gui.\n"); | - | ||||||||||||||||||
335 | #endif // QT_WIDGETS_LIB | - | ||||||||||||||||||
336 | #endif // QT_GUI_LIB | - | ||||||||||||||||||
337 | printf("\t-quiet ....................... Suppress all output.\n"); | - | ||||||||||||||||||
338 | printf("\t-I [path] .................... Prepend the given path to the import paths.\n"); | - | ||||||||||||||||||
339 | printf("\t-f [file] .................... Load the given file as a QML file.\n"); | - | ||||||||||||||||||
340 | printf("\t-config [file] ............... Load the given file as the configuration file.\n"); | - | ||||||||||||||||||
341 | printf("\t-- ........................... Arguments after this one are ignored by the launcher, but may be used within the QML application.\n"); | - | ||||||||||||||||||
342 | printf("\tGL options:\n"); | - | ||||||||||||||||||
343 | printf("\t-desktop.......................Force use of desktop GL (AA_UseDesktopOpenGL)\n"); | - | ||||||||||||||||||
344 | printf("\t-gles..........................Force use of GLES (AA_UseOpenGLES)\n"); | - | ||||||||||||||||||
345 | printf("\t-software......................Force use of software rendering (AA_UseOpenGLES)\n"); | - | ||||||||||||||||||
346 | printf("\t-scaling.......................Enable High DPI scaling (AA_EnableHighDpiScaling)\n"); | - | ||||||||||||||||||
347 | printf("\t-no-scaling....................Disable High DPI scaling (AA_DisableHighDpiScaling)\n"); | - | ||||||||||||||||||
348 | printf("\tDebugging options:\n"); | - | ||||||||||||||||||
349 | printf("\t-verbose ..................... Print information about what qml is doing, like specific file urls being loaded.\n"); | - | ||||||||||||||||||
350 | printf("\t-translation [file] .......... Load the given file as the translations file.\n"); | - | ||||||||||||||||||
351 | printf("\t-dummy-data [directory] ...... Load QML files from the given directory as context properties.\n"); | - | ||||||||||||||||||
352 | printf("\t-slow-animations ............. Run all animations in slow motion.\n"); | - | ||||||||||||||||||
353 | printf("\t-fixed-animations ............ Run animations off animation tick rather than wall time.\n"); | - | ||||||||||||||||||
354 | exit(0); never executed: exit(0); | 0 | ||||||||||||||||||
355 | } | - | ||||||||||||||||||
356 | - | |||||||||||||||||||
357 | void noFilesGiven() | - | ||||||||||||||||||
358 | { | - | ||||||||||||||||||
359 | if (!quietMode)
| 0 | ||||||||||||||||||
360 | printf("qml: No files specified. Terminating.\n"); never executed: printf("qml: No files specified. Terminating.\n"); | 0 | ||||||||||||||||||
361 | exit(1); never executed: exit(1); | 0 | ||||||||||||||||||
362 | } | - | ||||||||||||||||||
363 | - | |||||||||||||||||||
364 | //Called before application initialization, removes arguments it uses | - | ||||||||||||||||||
365 | void getAppFlags(int &argc, char **argv) | - | ||||||||||||||||||
366 | { | - | ||||||||||||||||||
367 | #ifdef QT_GUI_LIB | - | ||||||||||||||||||
368 | for (int i=0; i<argc; i++) {
| 0 | ||||||||||||||||||
369 | if (!strcmp(argv[i], "-apptype")) { // Must be done before application, as it selects application
| 0 | ||||||||||||||||||
370 | applicationType = QmlApplicationTypeUnknown; | - | ||||||||||||||||||
371 | if (i+1 < argc) {
| 0 | ||||||||||||||||||
372 | if (!strcmp(argv[i+1], "core"))
| 0 | ||||||||||||||||||
373 | applicationType = QmlApplicationTypeCore; never executed: applicationType = QmlApplicationTypeCore; | 0 | ||||||||||||||||||
374 | else if (!strcmp(argv[i+1], "gui"))
| 0 | ||||||||||||||||||
375 | applicationType = QmlApplicationTypeGui; never executed: applicationType = QmlApplicationTypeGui; | 0 | ||||||||||||||||||
376 | #ifdef QT_WIDGETS_LIB | - | ||||||||||||||||||
377 | else if (!strcmp(argv[i+1], "widget"))
| 0 | ||||||||||||||||||
378 | applicationType = QmlApplicationTypeWidget; never executed: applicationType = QmlApplicationTypeWidget; | 0 | ||||||||||||||||||
379 | #endif // QT_WIDGETS_LIB | - | ||||||||||||||||||
380 | } never executed: end of block | 0 | ||||||||||||||||||
381 | - | |||||||||||||||||||
382 | if (applicationType == QmlApplicationTypeUnknown) {
| 0 | ||||||||||||||||||
383 | #ifndef QT_WIDGETS_LIB | - | ||||||||||||||||||
384 | printf("-apptype must be followed by one of the following: core gui\n"); | - | ||||||||||||||||||
385 | #else | - | ||||||||||||||||||
386 | printf("-apptype must be followed by one of the following: core gui widget\n"); | - | ||||||||||||||||||
387 | #endif // QT_WIDGETS_LIB | - | ||||||||||||||||||
388 | printUsage(); | - | ||||||||||||||||||
389 | } never executed: end of block | 0 | ||||||||||||||||||
390 | for (int j=i; j<argc-2; j++)
| 0 | ||||||||||||||||||
391 | argv[j] = argv[j+2]; never executed: argv[j] = argv[j+2]; | 0 | ||||||||||||||||||
392 | argc -= 2; | - | ||||||||||||||||||
393 | } never executed: end of block | 0 | ||||||||||||||||||
394 | } never executed: end of block | 0 | ||||||||||||||||||
395 | #else | - | ||||||||||||||||||
396 | Q_UNUSED(argc) | - | ||||||||||||||||||
397 | Q_UNUSED(argv) | - | ||||||||||||||||||
398 | #endif // QT_GUI_LIB | - | ||||||||||||||||||
399 | } never executed: end of block | 0 | ||||||||||||||||||
400 | - | |||||||||||||||||||
401 | bool getFileSansBangLine(const QString &path, QByteArray &output) | - | ||||||||||||||||||
402 | { | - | ||||||||||||||||||
403 | QFile f(path); | - | ||||||||||||||||||
404 | if (!f.open(QFile::ReadOnly | QFile::Text))
| 0 | ||||||||||||||||||
405 | return false; never executed: return false; | 0 | ||||||||||||||||||
406 | output = f.readAll(); | - | ||||||||||||||||||
407 | if (output.startsWith("#!")) {//Remove first line in this case (except \n, to avoid disturbing line count)
| 0 | ||||||||||||||||||
408 | output.remove(0, output.indexOf('\n')); | - | ||||||||||||||||||
409 | return true; never executed: return true; | 0 | ||||||||||||||||||
410 | } | - | ||||||||||||||||||
411 | return false; never executed: return false; | 0 | ||||||||||||||||||
412 | } | - | ||||||||||||||||||
413 | - | |||||||||||||||||||
414 | static void loadDummyDataFiles(QQmlEngine &engine, const QString& directory) | - | ||||||||||||||||||
415 | { | - | ||||||||||||||||||
416 | QDir dir(directory+"/dummydata", "*.qml"); | - | ||||||||||||||||||
417 | QStringList list = dir.entryList(); | - | ||||||||||||||||||
418 | for (int i = 0; i < list.size(); ++i) {
| 0 | ||||||||||||||||||
419 | QString qml = list.at(i); | - | ||||||||||||||||||
420 | QQmlComponent comp(&engine, dir.filePath(qml)); | - | ||||||||||||||||||
421 | QObject *dummyData = comp.create(); | - | ||||||||||||||||||
422 | - | |||||||||||||||||||
423 | if (comp.isError()) {
| 0 | ||||||||||||||||||
424 | const QList<QQmlError> errors = comp.errors(); | - | ||||||||||||||||||
425 | for (const QQmlError &error : errors) | - | ||||||||||||||||||
426 | qWarning() << error; never executed: QMessageLogger(__FILE__, 426, __PRETTY_FUNCTION__).warning() << error; | 0 | ||||||||||||||||||
427 | } never executed: end of block | 0 | ||||||||||||||||||
428 | - | |||||||||||||||||||
429 | if (dummyData && !quietMode) {
| 0 | ||||||||||||||||||
430 | printf("qml: Loaded dummy data: %s\n", qPrintable(dir.filePath(qml))); | - | ||||||||||||||||||
431 | qml.truncate(qml.length()-4); | - | ||||||||||||||||||
432 | engine.rootContext()->setContextProperty(qml, dummyData); | - | ||||||||||||||||||
433 | dummyData->setParent(&engine); | - | ||||||||||||||||||
434 | } never executed: end of block | 0 | ||||||||||||||||||
435 | } never executed: end of block | 0 | ||||||||||||||||||
436 | } never executed: end of block | 0 | ||||||||||||||||||
437 | - | |||||||||||||||||||
438 | int main(int argc, char *argv[]) | - | ||||||||||||||||||
439 | { | - | ||||||||||||||||||
440 | getAppFlags(argc, argv); | - | ||||||||||||||||||
441 | QCoreApplication *app = nullptr; | - | ||||||||||||||||||
442 | switch (applicationType) { | - | ||||||||||||||||||
443 | case QmlApplicationTypeCore: never executed: case QmlApplicationTypeCore: | 0 | ||||||||||||||||||
444 | app = new QCoreApplication(argc, argv); | - | ||||||||||||||||||
445 | break; never executed: break; | 0 | ||||||||||||||||||
446 | #ifdef QT_GUI_LIB | - | ||||||||||||||||||
447 | case QmlApplicationTypeGui: never executed: case QmlApplicationTypeGui: | 0 | ||||||||||||||||||
448 | app = new LoaderApplication(argc, argv); | - | ||||||||||||||||||
449 | break; never executed: break; | 0 | ||||||||||||||||||
450 | #ifdef QT_WIDGETS_LIB | - | ||||||||||||||||||
451 | case QmlApplicationTypeWidget: never executed: case QmlApplicationTypeWidget: | 0 | ||||||||||||||||||
452 | app = new QApplication(argc, argv); | - | ||||||||||||||||||
453 | break; never executed: break; | 0 | ||||||||||||||||||
454 | #endif // QT_WIDGETS_LIB | - | ||||||||||||||||||
455 | #endif // QT_GUI_LIB | - | ||||||||||||||||||
456 | default: never executed: default: | 0 | ||||||||||||||||||
457 | Q_ASSERT_X(false, Q_FUNC_INFO, "impossible case"); | - | ||||||||||||||||||
458 | break; never executed: break; | 0 | ||||||||||||||||||
459 | } | - | ||||||||||||||||||
460 | - | |||||||||||||||||||
461 | app->setApplicationName("Qml Runtime"); | - | ||||||||||||||||||
462 | app->setOrganizationName("QtProject"); | - | ||||||||||||||||||
463 | app->setOrganizationDomain("qt-project.org"); | - | ||||||||||||||||||
464 | QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); | - | ||||||||||||||||||
465 | - | |||||||||||||||||||
466 | qmlRegisterType<Config>("QmlRuntime.Config", 1, 0, "Configuration"); | - | ||||||||||||||||||
467 | qmlRegisterType<PartialScene>("QmlRuntime.Config", 1, 0, "PartialScene"); | - | ||||||||||||||||||
468 | QQmlApplicationEngine e; | - | ||||||||||||||||||
469 | QStringList files; | - | ||||||||||||||||||
470 | QString confFile; | - | ||||||||||||||||||
471 | QString translationFile; | - | ||||||||||||||||||
472 | QString dummyDir; | - | ||||||||||||||||||
473 | - | |||||||||||||||||||
474 | //Handle main arguments | - | ||||||||||||||||||
475 | const QStringList argList = app->arguments(); | - | ||||||||||||||||||
476 | for (int i = 1; i < argList.count(); i++) {
| 0 | ||||||||||||||||||
477 | const QString &arg = argList[i]; | - | ||||||||||||||||||
478 | if (arg == QLatin1String("-quiet"))
| 0 | ||||||||||||||||||
479 | quietMode = true; never executed: quietMode = true; | 0 | ||||||||||||||||||
480 | else if (arg == QLatin1String("-v") || arg == QLatin1String("-version"))
| 0 | ||||||||||||||||||
481 | printVersion(); never executed: printVersion(); | 0 | ||||||||||||||||||
482 | else if (arg == QLatin1String("-h") || arg == QLatin1String("-help"))
| 0 | ||||||||||||||||||
483 | printUsage(); never executed: printUsage(); | 0 | ||||||||||||||||||
484 | else if (arg == QLatin1String("--"))
| 0 | ||||||||||||||||||
485 | break; never executed: break; | 0 | ||||||||||||||||||
486 | else if (arg == QLatin1String("-verbose"))
| 0 | ||||||||||||||||||
487 | verboseMode = true; never executed: verboseMode = true; | 0 | ||||||||||||||||||
488 | #if QT_CONFIG(qml_animation) | - | ||||||||||||||||||
489 | else if (arg == QLatin1String("-slow-animations"))
| 0 | ||||||||||||||||||
490 | QUnifiedTimer::instance()->setSlowModeEnabled(true); never executed: QUnifiedTimer::instance()->setSlowModeEnabled(true); | 0 | ||||||||||||||||||
491 | else if (arg == QLatin1String("-fixed-animations"))
| 0 | ||||||||||||||||||
492 | QUnifiedTimer::instance()->setConsistentTiming(true); never executed: QUnifiedTimer::instance()->setConsistentTiming(true); | 0 | ||||||||||||||||||
493 | #endif | - | ||||||||||||||||||
494 | else if (arg == QLatin1String("-I")) {
| 0 | ||||||||||||||||||
495 | if (i+1 == argList.count())
| 0 | ||||||||||||||||||
496 | continue;//Invalid usage, but just ignore it never executed: continue; | 0 | ||||||||||||||||||
497 | e.addImportPath(argList[i+1]); | - | ||||||||||||||||||
498 | i++; | - | ||||||||||||||||||
499 | } else if (arg == QLatin1String("-f")) { never executed: end of block
| 0 | ||||||||||||||||||
500 | if (i+1 == argList.count())
| 0 | ||||||||||||||||||
501 | continue;//Invalid usage, but just ignore it never executed: continue; | 0 | ||||||||||||||||||
502 | files << argList[i+1]; | - | ||||||||||||||||||
503 | i++; | - | ||||||||||||||||||
504 | } else if (arg == QLatin1String("-config")){ never executed: end of block
| 0 | ||||||||||||||||||
505 | if (i+1 == argList.count())
| 0 | ||||||||||||||||||
506 | continue;//Invalid usage, but just ignore it never executed: continue; | 0 | ||||||||||||||||||
507 | confFile = argList[i+1]; | - | ||||||||||||||||||
508 | i++; | - | ||||||||||||||||||
509 | } else if (arg == QLatin1String("-translation")){ never executed: end of block
| 0 | ||||||||||||||||||
510 | if (i+1 == argList.count())
| 0 | ||||||||||||||||||
511 | continue;//Invalid usage, but just ignore it never executed: continue; | 0 | ||||||||||||||||||
512 | translationFile = argList[i+1]; | - | ||||||||||||||||||
513 | i++; | - | ||||||||||||||||||
514 | } else if (arg == QLatin1String("-dummy-data")){ never executed: end of block
| 0 | ||||||||||||||||||
515 | if (i+1 == argList.count())
| 0 | ||||||||||||||||||
516 | continue;//Invalid usage, but just ignore it never executed: continue; | 0 | ||||||||||||||||||
517 | dummyDir = argList[i+1]; | - | ||||||||||||||||||
518 | i++; | - | ||||||||||||||||||
519 | } else if (arg == QLatin1String("-gles")) { never executed: end of block
| 0 | ||||||||||||||||||
520 | QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); | - | ||||||||||||||||||
521 | } else if (arg == QLatin1String("-software")) { never executed: end of block
| 0 | ||||||||||||||||||
522 | QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); | - | ||||||||||||||||||
523 | } else if (arg == QLatin1String("-desktop")) { never executed: end of block
| 0 | ||||||||||||||||||
524 | QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); | - | ||||||||||||||||||
525 | } else if (arg == QLatin1String("-scaling")) { never executed: end of block
| 0 | ||||||||||||||||||
526 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); | - | ||||||||||||||||||
527 | } else if (arg == QLatin1String("-no-scaling")) { never executed: end of block
| 0 | ||||||||||||||||||
528 | QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); | - | ||||||||||||||||||
529 | } else { never executed: end of block | 0 | ||||||||||||||||||
530 | files << arg; | - | ||||||||||||||||||
531 | } never executed: end of block | 0 | ||||||||||||||||||
532 | } | - | ||||||||||||||||||
533 | - | |||||||||||||||||||
534 | if (quietMode && verboseMode)
| 0 | ||||||||||||||||||
535 | verboseMode = false; never executed: verboseMode = false; | 0 | ||||||||||||||||||
536 | - | |||||||||||||||||||
537 | #if QT_CONFIG(translation) | - | ||||||||||||||||||
538 | //qt_ translations loaded by QQmlApplicationEngine | - | ||||||||||||||||||
539 | QString sysLocale = QLocale::system().name(); | - | ||||||||||||||||||
540 | - | |||||||||||||||||||
541 | if (!translationFile.isEmpty()) { //Note: installed before QQmlApplicationEngine's automatic translation loading
| 0 | ||||||||||||||||||
542 | QTranslator translator; | - | ||||||||||||||||||
543 | - | |||||||||||||||||||
544 | if (translator.load(translationFile)) {
| 0 | ||||||||||||||||||
545 | app->installTranslator(&translator); | - | ||||||||||||||||||
546 | if (verboseMode)
| 0 | ||||||||||||||||||
547 | printf("qml: Loaded translation file %s\n", qPrintable(QDir::toNativeSeparators(translationFile))); never executed: printf("qml: Loaded translation file %s\n", QtPrivate::asString(QDir::toNativeSeparators(translationFile)).toLocal8Bit().constData()); | 0 | ||||||||||||||||||
548 | } else { never executed: end of block | 0 | ||||||||||||||||||
549 | if (!quietMode)
| 0 | ||||||||||||||||||
550 | printf("qml: Could not load the translation file %s\n", qPrintable(QDir::toNativeSeparators(translationFile))); never executed: printf("qml: Could not load the translation file %s\n", QtPrivate::asString(QDir::toNativeSeparators(translationFile)).toLocal8Bit().constData()); | 0 | ||||||||||||||||||
551 | } never executed: end of block | 0 | ||||||||||||||||||
552 | } | - | ||||||||||||||||||
553 | #else | - | ||||||||||||||||||
554 | if (!translationFile.isEmpty() && !quietMode) | - | ||||||||||||||||||
555 | printf("qml: Translation file specified, but Qt built without translation support.\n"); | - | ||||||||||||||||||
556 | #endif | - | ||||||||||||||||||
557 | - | |||||||||||||||||||
558 | if (quietMode)
| 0 | ||||||||||||||||||
559 | qInstallMessageHandler(quietMessageHandler); never executed: qInstallMessageHandler(quietMessageHandler); | 0 | ||||||||||||||||||
560 | - | |||||||||||||||||||
561 | if (files.count() <= 0) {
| 0 | ||||||||||||||||||
562 | #if defined(Q_OS_DARWIN) | - | ||||||||||||||||||
563 | if (applicationType == QmlApplicationTypeGui) | - | ||||||||||||||||||
564 | exitTimerId = static_cast<LoaderApplication *>(app)->startTimer(FILE_OPEN_EVENT_WAIT_TIME); | - | ||||||||||||||||||
565 | else | - | ||||||||||||||||||
566 | #endif | - | ||||||||||||||||||
567 | noFilesGiven(); | - | ||||||||||||||||||
568 | } never executed: end of block | 0 | ||||||||||||||||||
569 | - | |||||||||||||||||||
570 | qae = &e; | - | ||||||||||||||||||
571 | loadConf(confFile, !verboseMode); | - | ||||||||||||||||||
572 | - | |||||||||||||||||||
573 | //Load files | - | ||||||||||||||||||
574 | QScopedPointer<LoadWatcher> lw(new LoadWatcher(&e, files.count())); | - | ||||||||||||||||||
575 | - | |||||||||||||||||||
576 | // Load dummy data before loading QML-files | - | ||||||||||||||||||
577 | if (!dummyDir.isEmpty() && QFileInfo (dummyDir).isDir())
| 0 | ||||||||||||||||||
578 | loadDummyDataFiles(e, dummyDir); never executed: loadDummyDataFiles(e, dummyDir); | 0 | ||||||||||||||||||
579 | - | |||||||||||||||||||
580 | for (const QString &path : qAsConst(files)) { | - | ||||||||||||||||||
581 | QUrl url = QUrl::fromUserInput(path, QDir::currentPath(), QUrl::AssumeLocalFile); | - | ||||||||||||||||||
582 | if (verboseMode)
| 0 | ||||||||||||||||||
583 | printf("qml: loading %s\n", qPrintable(url.toString())); never executed: printf("qml: loading %s\n", QtPrivate::asString(url.toString()).toLocal8Bit().constData()); | 0 | ||||||||||||||||||
584 | QByteArray strippedFile; | - | ||||||||||||||||||
585 | if (getFileSansBangLine(path, strippedFile))
| 0 | ||||||||||||||||||
586 | e.loadData(strippedFile, e.baseUrl().resolved(url)); //QQmlComponent won't resolve it for us, it doesn't know it's a valid file if we loadData never executed: e.loadData(strippedFile, e.baseUrl().resolved(url)); | 0 | ||||||||||||||||||
587 | else //Errors or no bang line | - | ||||||||||||||||||
588 | e.load(url); never executed: e.load(url); | 0 | ||||||||||||||||||
589 | } | - | ||||||||||||||||||
590 | - | |||||||||||||||||||
591 | if (lw->earlyExit)
| 0 | ||||||||||||||||||
592 | return lw->returnCode; never executed: return lw->returnCode; | 0 | ||||||||||||||||||
593 | - | |||||||||||||||||||
594 | return app->exec(); never executed: return app->exec(); | 0 | ||||||||||||||||||
595 | } | - | ||||||||||||||||||
596 | - | |||||||||||||||||||
597 | #include "main.moc" | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |