2012-12-21 23:42:47 +00:00
/****************************************************************************
* *
2016-01-19 11:23:05 +00:00
* * Copyright ( C ) 2016 Research In Motion .
2019-01-14 08:42:29 +00:00
* * Copyright ( C ) 2019 The Qt Company Ltd .
2016-01-19 11:23:05 +00:00
* * Contact : https : //www.qt.io/licensing/
2012-12-21 23:42:47 +00:00
* *
* * This file is part of the tools applications of the Qt Toolkit .
* *
2016-01-19 11:23:05 +00:00
* * $ QT_BEGIN_LICENSE : GPL - EXCEPT $
2012-12-21 23:42:47 +00:00
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
2015-01-28 11:55:39 +00:00
* * a written agreement between you and The Qt Company . For licensing terms
2016-01-19 11:23:05 +00:00
* * and conditions see https : //www.qt.io/terms-conditions. For further
* * information use the contact form at https : //www.qt.io/contact-us.
2012-12-21 23:42:47 +00:00
* *
2016-01-19 11:23:05 +00:00
* * GNU General Public License Usage
* * Alternatively , this file may be used under the terms of the GNU
* * General Public License version 3 as published by the Free Software
* * Foundation with exceptions as appearing in the file LICENSE . GPL3 - EXCEPT
* * included in the packaging of this file . Please review the following
* * information to ensure the GNU General Public License requirements will
* * be met : https : //www.gnu.org/licenses/gpl-3.0.html.
2012-12-21 23:42:47 +00:00
* *
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "conf.h"
# include <QCoreApplication>
2013-10-12 02:59:09 +00:00
# ifdef QT_GUI_LIB
2012-12-21 23:42:47 +00:00
# include <QGuiApplication>
2013-10-12 02:59:09 +00:00
# include <QWindow>
# include <QFileOpenEvent>
2015-06-03 09:05:12 +00:00
# include <QOpenGLContext>
# include <QOpenGLFunctions>
2012-12-21 23:42:47 +00:00
# ifdef QT_WIDGETS_LIB
# include <QApplication>
2013-10-12 02:59:09 +00:00
# endif // QT_WIDGETS_LIB
# endif // QT_GUI_LIB
2012-12-21 23:42:47 +00:00
# include <QQmlApplicationEngine>
2014-03-09 21:27:34 +00:00
# include <QQmlComponent>
2019-04-16 15:25:36 +00:00
# include <QCommandLineOption>
# include <QCommandLineParser>
2014-03-09 21:27:34 +00:00
# include <QDir>
2012-12-21 23:42:47 +00:00
# include <QFile>
# include <QFileInfo>
2019-04-23 13:20:15 +00:00
# include <QLoggingCategory>
2012-12-21 23:42:47 +00:00
# include <QStringList>
2015-03-11 05:25:14 +00:00
# include <QScopedPointer>
2012-12-21 23:42:47 +00:00
# include <QDebug>
# include <QStandardPaths>
2014-03-09 21:27:34 +00:00
# include <QTranslator>
2012-12-21 23:42:47 +00:00
# include <QtGlobal>
2015-06-03 09:05:12 +00:00
# include <QLibraryInfo>
2012-12-21 23:42:47 +00:00
# include <qqml.h>
# include <qqmldebug.h>
2017-12-19 15:37:24 +00:00
# include <private/qtqmlglobal_p.h>
# if QT_CONFIG(qml_animation)
2012-12-21 23:42:47 +00:00
# include <private/qabstractanimation_p.h>
2017-03-30 08:41:52 +00:00
# endif
2012-12-21 23:42:47 +00:00
# include <cstdio>
# include <cstring>
# include <cstdlib>
2013-11-18 14:57:08 +00:00
# define FILE_OPEN_EVENT_WAIT_TIME 3000 // ms
2019-04-23 13:31:15 +00:00
enum QmlApplicationType {
QmlApplicationTypeUnknown
, QmlApplicationTypeCore
# ifdef QT_GUI_LIB
, QmlApplicationTypeGui
# ifdef QT_WIDGETS_LIB
, QmlApplicationTypeWidget
# endif // QT_WIDGETS_LIB
# endif // QT_GUI_LIB
} ;
static QmlApplicationType applicationType =
# ifndef QT_GUI_LIB
QmlApplicationTypeCore ;
# else
QmlApplicationTypeGui ;
# endif // QT_GUI_LIB
2018-02-21 09:41:54 +00:00
static Config * conf = nullptr ;
static QQmlApplicationEngine * qae = nullptr ;
2017-04-12 13:45:18 +00:00
# if defined(Q_OS_DARWIN) || defined(QT_GUI_LIB)
2013-11-18 14:57:08 +00:00
static int exitTimerId = - 1 ;
2017-04-12 13:45:18 +00:00
# endif
2019-04-15 13:59:03 +00:00
static const QString iconResourcePath ( QStringLiteral ( " :/qt-project.org/QmlRuntime/resources/qml-64.png " ) ) ;
2019-04-24 19:05:32 +00:00
static const QString confResourcePath ( QStringLiteral ( " :/qt-project.org/QmlRuntime/conf/ " ) ) ;
2019-04-23 13:31:15 +00:00
static bool verboseMode = false ;
static bool quietMode = false ;
2012-12-21 23:42:47 +00:00
static void loadConf ( const QString & override , bool quiet ) // Terminates app on failure
{
2019-04-24 19:05:32 +00:00
const QString defaultFileName = QLatin1String ( " default.qml " ) ;
2012-12-21 23:42:47 +00:00
QUrl settingsUrl ;
bool builtIn = false ; //just for keeping track of the warning
if ( override . isEmpty ( ) ) {
QFileInfo fi ;
fi . setFile ( QStandardPaths : : locate ( QStandardPaths : : DataLocation , defaultFileName ) ) ;
if ( fi . exists ( ) ) {
settingsUrl = QUrl : : fromLocalFile ( fi . absoluteFilePath ( ) ) ;
} else {
// ### If different built-in configs are needed per-platform, just apply QFileSelector to the qrc conf.qml path
2019-04-24 19:05:32 +00:00
fi . setFile ( confResourcePath + defaultFileName ) ;
settingsUrl = QUrl : : fromLocalFile ( fi . absoluteFilePath ( ) ) ;
2012-12-21 23:42:47 +00:00
builtIn = true ;
}
} else {
QFileInfo fi ;
2019-04-24 19:05:32 +00:00
fi . setFile ( confResourcePath + override + QLatin1String ( " .qml " ) ) ;
if ( fi . exists ( ) ) {
settingsUrl = QUrl : : fromLocalFile ( fi . absoluteFilePath ( ) ) ;
builtIn = true ;
} else {
fi . setFile ( override ) ;
if ( ! fi . exists ( ) ) {
printf ( " qml: Couldn't find required configuration file: %s \n " ,
qPrintable ( QDir : : toNativeSeparators ( fi . absoluteFilePath ( ) ) ) ) ;
exit ( 1 ) ;
}
settingsUrl = QUrl : : fromLocalFile ( fi . absoluteFilePath ( ) ) ;
2012-12-21 23:42:47 +00:00
}
}
if ( ! quiet ) {
2015-06-03 09:05:12 +00:00
printf ( " qml: %s \n " , QLibraryInfo : : build ( ) ) ;
2019-04-24 19:05:32 +00:00
if ( builtIn ) {
printf ( " qml: Using built-in configuration: %s \n " ,
qPrintable ( override . isEmpty ( ) ? defaultFileName : override ) ) ;
} else {
printf ( " qml: Using configuration: %s \n " ,
2013-10-23 22:37:16 +00:00
qPrintable ( settingsUrl . isLocalFile ( )
? QDir : : toNativeSeparators ( settingsUrl . toLocalFile ( ) )
: settingsUrl . toString ( ) ) ) ;
2019-04-24 19:05:32 +00:00
}
2012-12-21 23:42:47 +00:00
}
// TODO: When we have better engine control, ban QtQuick* imports on this engine
QQmlEngine e2 ;
QQmlComponent c2 ( & e2 , settingsUrl ) ;
conf = qobject_cast < Config * > ( c2 . create ( ) ) ;
if ( ! conf ) {
2013-10-23 22:37:16 +00:00
printf ( " qml: Error loading configuration file: %s \n " , qPrintable ( c2 . errorString ( ) ) ) ;
2012-12-21 23:42:47 +00:00
exit ( 1 ) ;
}
}
2019-04-23 13:31:15 +00:00
void noFilesGiven ( )
{
if ( ! quietMode )
printf ( " qml: No files specified. Terminating. \n " ) ;
exit ( 1 ) ;
}
2013-10-12 02:59:09 +00:00
2019-04-24 19:05:32 +00:00
static void listConfFiles ( )
{
QDir confResourceDir ( confResourcePath ) ;
printf ( " %s \n " , qPrintable ( QCoreApplication : : translate ( " main " , " Built-in configurations: " ) ) ) ;
for ( const QFileInfo & fi : confResourceDir . entryInfoList ( QDir : : Files ) )
printf ( " %s \n " , qPrintable ( fi . baseName ( ) ) ) ;
exit ( 0 ) ;
}
2019-04-23 13:31:15 +00:00
# ifdef QT_GUI_LIB
2013-11-18 14:57:08 +00:00
2012-12-21 23:42:47 +00:00
// Loads qml after receiving a QFileOpenEvent
class LoaderApplication : public QGuiApplication
{
public :
2019-04-15 13:59:03 +00:00
LoaderApplication ( int & argc , char * * argv ) : QGuiApplication ( argc , argv )
{
setWindowIcon ( QIcon ( iconResourcePath ) ) ;
}
2012-12-21 23:42:47 +00:00
2016-12-07 22:53:14 +00:00
bool event ( QEvent * ev ) override
2012-12-21 23:42:47 +00:00
{
2013-11-18 14:57:08 +00:00
if ( ev - > type ( ) = = QEvent : : FileOpen ) {
if ( exitTimerId > = 0 ) {
killTimer ( exitTimerId ) ;
exitTimerId = - 1 ;
}
2012-12-21 23:42:47 +00:00
qae - > load ( static_cast < QFileOpenEvent * > ( ev ) - > url ( ) ) ;
2013-11-18 14:57:08 +00:00
}
2012-12-21 23:42:47 +00:00
else
return QGuiApplication : : event ( ev ) ;
return true ;
}
2013-11-18 14:57:08 +00:00
2016-12-07 22:53:14 +00:00
void timerEvent ( QTimerEvent * ) override {
2013-11-18 14:57:08 +00:00
noFilesGiven ( ) ;
}
2012-12-21 23:42:47 +00:00
} ;
2013-10-12 02:59:09 +00:00
# endif // QT_GUI_LIB
2012-12-21 23:42:47 +00:00
// Listens to the appEngine signals to determine if all files failed to load
class LoadWatcher : public QObject
{
Q_OBJECT
public :
LoadWatcher ( QQmlApplicationEngine * e , int expected )
: QObject ( e )
2019-01-14 08:42:29 +00:00
, expectedFileCount ( expected )
2012-12-21 23:42:47 +00:00
{
2019-01-14 08:42:29 +00:00
connect ( e , & QQmlApplicationEngine : : objectCreated , this , & LoadWatcher : : checkFinished ) ;
2015-03-11 05:25:14 +00:00
// QQmlApplicationEngine also connects quit() to QCoreApplication::quit
2016-08-03 14:54:26 +00:00
// and exit() to QCoreApplication::exit but if called before exec()
// then QCoreApplication::quit or QCoreApplication::exit does nothing
2019-01-14 08:42:29 +00:00
connect ( e , & QQmlEngine : : quit , this , & LoadWatcher : : quit ) ;
connect ( e , & QQmlEngine : : exit , this , & LoadWatcher : : exit ) ;
2012-12-21 23:42:47 +00:00
}
2019-01-14 08:42:29 +00:00
int returnCode = 0 ;
2019-04-23 13:31:15 +00:00
bool earlyExit = false ;
2012-12-21 23:42:47 +00:00
public Q_SLOTS :
2019-01-14 08:42:29 +00:00
void checkFinished ( QObject * o , const QUrl & url )
2012-12-21 23:42:47 +00:00
{
2019-01-14 08:42:29 +00:00
Q_UNUSED ( url )
2012-12-21 23:42:47 +00:00
if ( o ) {
2015-06-03 09:05:12 +00:00
checkForWindow ( o ) ;
2012-12-21 23:42:47 +00:00
if ( conf & & qae )
2016-08-11 10:08:00 +00:00
for ( PartialScene * ps : qAsConst ( conf - > completers ) )
2012-12-21 23:42:47 +00:00
if ( o - > inherits ( ps - > itemType ( ) . toUtf8 ( ) . constData ( ) ) )
contain ( o , ps - > container ( ) ) ;
}
2019-01-14 08:42:29 +00:00
if ( haveWindow )
2012-12-21 23:42:47 +00:00
return ;
2019-01-14 08:42:29 +00:00
if ( ! - - expectedFileCount ) {
2013-10-23 22:37:16 +00:00
printf ( " qml: Did not load any objects, exiting. \n " ) ;
2019-01-14 08:42:29 +00:00
std : : exit ( 2 ) ; // Different return code from qFatal
2012-12-21 23:42:47 +00:00
}
}
2015-03-11 05:25:14 +00:00
void quit ( ) {
2019-01-14 08:42:29 +00:00
// Will be checked before calling exec()
2015-03-11 05:25:14 +00:00
earlyExit = true ;
2016-08-03 14:54:26 +00:00
returnCode = 0 ;
2015-03-11 05:25:14 +00:00
}
2016-08-03 14:54:26 +00:00
void exit ( int retCode ) {
earlyExit = true ;
returnCode = retCode ;
}
2016-11-16 13:22:36 +00:00
# if defined(QT_GUI_LIB) && QT_CONFIG(opengl)
2015-06-03 09:05:12 +00:00
void onOpenGlContextCreated ( QOpenGLContext * context ) ;
# endif
2019-01-14 08:42:29 +00:00
private :
void contain ( QObject * o , const QUrl & containPath ) ;
void checkForWindow ( QObject * o ) ;
private :
bool haveWindow = false ;
2019-04-23 13:31:15 +00:00
int expectedFileCount ;
2012-12-21 23:42:47 +00:00
} ;
2015-06-03 09:05:12 +00:00
void LoadWatcher : : contain ( QObject * o , const QUrl & containPath )
{
QQmlComponent c ( qae , containPath ) ;
QObject * o2 = c . create ( ) ;
if ( ! o2 )
return ;
checkForWindow ( o2 ) ;
bool success = false ;
int idx ;
if ( ( idx = o2 - > metaObject ( ) - > indexOfProperty ( " containedObject " ) ) ! = - 1 )
success = o2 - > metaObject ( ) - > property ( idx ) . write ( o2 , QVariant : : fromValue < QObject * > ( o ) ) ;
if ( ! success )
2019-01-14 08:42:29 +00:00
o - > setParent ( o2 ) ; // Set QObject parent, and assume container will react as needed
2015-06-03 09:05:12 +00:00
}
void LoadWatcher : : checkForWindow ( QObject * o )
{
2016-11-16 13:22:36 +00:00
# if defined(QT_GUI_LIB) && QT_CONFIG(opengl)
2019-01-14 14:51:24 +00:00
if ( o - > isWindowType ( ) & & o - > inherits ( " QQuickWindow " ) ) {
haveWindow = true ;
if ( verboseMode )
connect ( o , SIGNAL ( openglContextCreated ( QOpenGLContext * ) ) ,
this , SLOT ( onOpenGlContextCreated ( QOpenGLContext * ) ) ) ;
2015-06-03 09:05:12 +00:00
}
# else
Q_UNUSED ( o )
2015-08-18 13:54:41 +00:00
# endif // QT_GUI_LIB && !QT_NO_OPENGL
2015-06-03 09:05:12 +00:00
}
2016-11-16 13:22:36 +00:00
# if defined(QT_GUI_LIB) && QT_CONFIG(opengl)
2015-06-03 09:05:12 +00:00
void LoadWatcher : : onOpenGlContextCreated ( QOpenGLContext * context )
{
context - > makeCurrent ( qobject_cast < QWindow * > ( sender ( ) ) ) ;
QOpenGLFunctions functions ( context ) ;
QByteArray output = " Vendor : " ;
output + = reinterpret_cast < const char * > ( functions . glGetString ( GL_VENDOR ) ) ;
output + = " \n Renderer: " ;
output + = reinterpret_cast < const char * > ( functions . glGetString ( GL_RENDERER ) ) ;
output + = " \n Version : " ;
output + = reinterpret_cast < const char * > ( functions . glGetString ( GL_VERSION ) ) ;
output + = " \n Language: " ;
output + = reinterpret_cast < const char * > ( functions . glGetString ( GL_SHADING_LANGUAGE_VERSION ) ) ;
puts ( output . constData ( ) ) ;
context - > doneCurrent ( ) ;
}
2015-08-18 13:54:41 +00:00
# endif // QT_GUI_LIB && !QT_NO_OPENGL
2015-06-03 09:05:12 +00:00
2012-12-21 23:42:47 +00:00
void quietMessageHandler ( QtMsgType type , const QMessageLogContext & ctxt , const QString & msg )
{
Q_UNUSED ( ctxt ) ;
Q_UNUSED ( msg ) ;
2019-01-14 08:42:29 +00:00
// Doesn't print anything
2012-12-21 23:42:47 +00:00
switch ( type ) {
case QtFatalMsg :
2013-09-25 16:11:34 +00:00
exit ( - 1 ) ;
2012-12-21 23:42:47 +00:00
case QtCriticalMsg :
case QtDebugMsg :
2019-04-23 13:20:15 +00:00
case QtInfoMsg :
2012-12-21 23:42:47 +00:00
case QtWarningMsg :
;
}
}
2019-01-14 08:42:29 +00:00
// Called before application initialization, removes arguments it uses
2012-12-21 23:42:47 +00:00
void getAppFlags ( int & argc , char * * argv )
{
2013-10-12 02:59:09 +00:00
# ifdef QT_GUI_LIB
2013-11-14 11:38:25 +00:00
for ( int i = 0 ; i < argc ; i + + ) {
2019-04-16 15:25:36 +00:00
if ( ! strcmp ( argv [ i ] , " --apptype " ) | | ! strcmp ( argv [ i ] , " -a " ) | | ! strcmp ( argv [ i ] , " -apptype " ) ) {
2013-10-12 02:59:09 +00:00
applicationType = QmlApplicationTypeUnknown ;
2012-12-21 23:42:47 +00:00
if ( i + 1 < argc ) {
if ( ! strcmp ( argv [ i + 1 ] , " core " ) )
2013-10-12 02:59:09 +00:00
applicationType = QmlApplicationTypeCore ;
2012-12-21 23:42:47 +00:00
else if ( ! strcmp ( argv [ i + 1 ] , " gui " ) )
2013-10-12 02:59:09 +00:00
applicationType = QmlApplicationTypeGui ;
2012-12-21 23:42:47 +00:00
# ifdef QT_WIDGETS_LIB
else if ( ! strcmp ( argv [ i + 1 ] , " widget " ) )
2013-10-12 02:59:09 +00:00
applicationType = QmlApplicationTypeWidget ;
# endif // QT_WIDGETS_LIB
2012-12-21 23:42:47 +00:00
}
for ( int j = i ; j < argc - 2 ; j + + )
argv [ j ] = argv [ j + 2 ] ;
argc - = 2 ;
}
}
2017-04-12 13:45:18 +00:00
# else
Q_UNUSED ( argc )
Q_UNUSED ( argv )
2013-11-14 11:38:25 +00:00
# endif // QT_GUI_LIB
2012-12-21 23:42:47 +00:00
}
2013-10-23 22:31:10 +00:00
bool getFileSansBangLine ( const QString & path , QByteArray & output )
2012-12-21 23:42:47 +00:00
{
QFile f ( path ) ;
if ( ! f . open ( QFile : : ReadOnly | QFile : : Text ) )
2013-10-23 22:31:10 +00:00
return false ;
2012-12-21 23:42:47 +00:00
output = f . readAll ( ) ;
2013-10-23 22:31:10 +00:00
if ( output . startsWith ( " #! " ) ) { //Remove first line in this case (except \n, to avoid disturbing line count)
2012-12-21 23:42:47 +00:00
output . remove ( 0 , output . indexOf ( ' \n ' ) ) ;
2013-10-23 22:31:10 +00:00
return true ;
}
return false ;
2012-12-21 23:42:47 +00:00
}
static void loadDummyDataFiles ( QQmlEngine & engine , const QString & directory )
{
QDir dir ( directory + " /dummydata " , " *.qml " ) ;
QStringList list = dir . entryList ( ) ;
for ( int i = 0 ; i < list . size ( ) ; + + i ) {
QString qml = list . at ( i ) ;
2014-03-01 06:28:29 +00:00
QQmlComponent comp ( & engine , dir . filePath ( qml ) ) ;
2012-12-21 23:42:47 +00:00
QObject * dummyData = comp . create ( ) ;
if ( comp . isError ( ) ) {
2016-08-11 10:08:00 +00:00
const QList < QQmlError > errors = comp . errors ( ) ;
for ( const QQmlError & error : errors )
2012-12-21 23:42:47 +00:00
qWarning ( ) < < error ;
}
if ( dummyData & & ! quietMode ) {
2013-10-23 22:37:16 +00:00
printf ( " qml: Loaded dummy data: %s \n " , qPrintable ( dir . filePath ( qml ) ) ) ;
2012-12-21 23:42:47 +00:00
qml . truncate ( qml . length ( ) - 4 ) ;
engine . rootContext ( ) - > setContextProperty ( qml , dummyData ) ;
dummyData - > setParent ( & engine ) ;
}
}
}
int main ( int argc , char * argv [ ] )
{
getAppFlags ( argc , argv ) ;
2018-02-21 09:41:54 +00:00
QCoreApplication * app = nullptr ;
2013-10-12 02:59:09 +00:00
switch ( applicationType ) {
# ifdef QT_GUI_LIB
case QmlApplicationTypeGui :
app = new LoaderApplication ( argc , argv ) ;
break ;
2012-12-21 23:42:47 +00:00
# ifdef QT_WIDGETS_LIB
2013-10-12 02:59:09 +00:00
case QmlApplicationTypeWidget :
2012-12-21 23:42:47 +00:00
app = new QApplication ( argc , argv ) ;
2019-04-15 13:59:03 +00:00
static_cast < QApplication * > ( app ) - > setWindowIcon ( QIcon ( iconResourcePath ) ) ;
2013-10-12 02:59:09 +00:00
break ;
# endif // QT_WIDGETS_LIB
# endif // QT_GUI_LIB
2019-04-16 15:25:36 +00:00
case QmlApplicationTypeCore :
Q_FALLTHROUGH ( ) ;
default : // QmlApplicationTypeUnknown: not allowed, but we'll exit after checking apptypeOption below
app = new QCoreApplication ( argc , argv ) ;
2013-10-12 02:59:09 +00:00
break ;
}
2012-12-21 23:42:47 +00:00
app - > setApplicationName ( " Qml Runtime " ) ;
2014-06-27 10:59:14 +00:00
app - > setOrganizationName ( " QtProject " ) ;
2012-12-21 23:42:47 +00:00
app - > setOrganizationDomain ( " qt-project.org " ) ;
2016-11-08 12:09:54 +00:00
QCoreApplication : : setApplicationVersion ( QLatin1String ( QT_VERSION_STR ) ) ;
2012-12-21 23:42:47 +00:00
2015-03-17 01:49:46 +00:00
qmlRegisterType < Config > ( " QmlRuntime.Config " , 1 , 0 , " Configuration " ) ;
qmlRegisterType < PartialScene > ( " QmlRuntime.Config " , 1 , 0 , " PartialScene " ) ;
2012-12-21 23:42:47 +00:00
QQmlApplicationEngine e ;
QStringList files ;
QString confFile ;
QString translationFile ;
QString dummyDir ;
2019-01-14 08:42:29 +00:00
// Handle main arguments
2019-04-16 15:25:36 +00:00
QCommandLineParser parser ;
parser . setSingleDashWordOptionMode ( QCommandLineParser : : ParseAsLongOptions ) ;
parser . setOptionsAfterPositionalArgumentsMode ( QCommandLineParser : : ParseAsPositionalArguments ) ;
const QCommandLineOption helpOption = parser . addHelpOption ( ) ;
const QCommandLineOption versionOption = parser . addVersionOption ( ) ;
# ifdef QT_GUI_LIB
QCommandLineOption apptypeOption ( QStringList ( ) < < QStringLiteral ( " a " ) < < QStringLiteral ( " apptype " ) ,
QCoreApplication : : translate ( " main " , " Select which application class to use. Default is gui. " ) ,
# ifdef QT_WIDGETS_LIB
QStringLiteral ( " core|gui|widget " ) ) ;
# else
QStringLiteral ( " core|gui " ) ) ;
# endif // QT_WIDGETS_LIB
parser . addOption ( apptypeOption ) ; // Just for the help text... we've already handled this argument above
# endif // QT_GUI_LIB
QCommandLineOption importOption ( QStringLiteral ( " I " ) ,
QCoreApplication : : translate ( " main " , " Prepend the given path to the import paths. " ) , QStringLiteral ( " path " ) ) ;
parser . addOption ( importOption ) ;
QCommandLineOption qmlFileOption ( QStringLiteral ( " f " ) ,
QCoreApplication : : translate ( " main " , " Load the given file as a QML file. " ) , QStringLiteral ( " file " ) ) ;
parser . addOption ( qmlFileOption ) ;
QCommandLineOption configOption ( QStringList ( ) < < QStringLiteral ( " c " ) < < QStringLiteral ( " config " ) ,
2019-04-24 19:05:32 +00:00
QCoreApplication : : translate ( " main " , " Load the given built-in configuration or configuration file. " ) , QStringLiteral ( " file " ) ) ;
2019-04-16 15:25:36 +00:00
parser . addOption ( configOption ) ;
2019-04-24 19:05:32 +00:00
QCommandLineOption listConfOption ( QStringList ( ) < < QStringLiteral ( " list-conf " ) ,
QCoreApplication : : translate ( " main " , " List the built-in configurations. " ) ) ;
parser . addOption ( listConfOption ) ;
2019-04-16 15:25:36 +00:00
QCommandLineOption translationOption ( QStringLiteral ( " translation " ) ,
QCoreApplication : : translate ( " main " , " Load the given file as the translations file. " ) , QStringLiteral ( " file " ) ) ;
parser . addOption ( translationOption ) ;
QCommandLineOption dummyDataOption ( QStringLiteral ( " dummy-data " ) ,
QCoreApplication : : translate ( " main " , " Load QML files from the given directory as context properties. " ) , QStringLiteral ( " file " ) ) ;
parser . addOption ( dummyDataOption ) ;
// OpenGL options
QCommandLineOption glDesktopOption ( QStringLiteral ( " desktop " ) ,
QCoreApplication : : translate ( " main " , " Force use of desktop OpenGL (AA_UseDesktopOpenGL). " ) ) ;
parser . addOption ( glDesktopOption ) ;
QCommandLineOption glEsOption ( QStringLiteral ( " gles " ) ,
QCoreApplication : : translate ( " main " , " Force use of GLES (AA_UseOpenGLES). " ) ) ;
parser . addOption ( glEsOption ) ;
QCommandLineOption glSoftwareOption ( QStringLiteral ( " software " ) ,
QCoreApplication : : translate ( " main " , " Force use of software rendering (AA_UseSoftwareOpenGL). " ) ) ;
parser . addOption ( glSoftwareOption ) ;
QCommandLineOption scalingOption ( QStringLiteral ( " scaling " ) ,
QCoreApplication : : translate ( " main " , " Enable High DPI scaling (AA_EnableHighDpiScaling). " ) ) ;
parser . addOption ( scalingOption ) ;
QCommandLineOption noScalingOption ( QStringLiteral ( " no-scaling " ) ,
QCoreApplication : : translate ( " main " , " Disable High DPI scaling (AA_DisableHighDpiScaling). " ) ) ;
parser . addOption ( noScalingOption ) ;
// Debugging and verbosity options
QCommandLineOption quietOption ( QStringLiteral ( " quiet " ) ,
QCoreApplication : : translate ( " main " , " Suppress all output. " ) ) ;
parser . addOption ( quietOption ) ;
QCommandLineOption verboseOption ( QStringLiteral ( " verbose " ) ,
QCoreApplication : : translate ( " main " , " Print information about what qml is doing, like specific file URLs being loaded. " ) ) ;
parser . addOption ( verboseOption ) ;
QCommandLineOption slowAnimationsOption ( QStringLiteral ( " slow-animations " ) ,
QCoreApplication : : translate ( " main " , " Run all animations in slow motion. " ) ) ;
parser . addOption ( slowAnimationsOption ) ;
QCommandLineOption fixedAnimationsOption ( QStringLiteral ( " fixed-animations " ) ,
QCoreApplication : : translate ( " main " , " Run animations off animation tick rather than wall time. " ) ) ;
parser . addOption ( fixedAnimationsOption ) ;
// Positional arguments
parser . addPositionalArgument ( " files " ,
QCoreApplication : : translate ( " main " , " Any number of QML files can be loaded. They will share the same engine. " ) , " [files...] " ) ;
parser . addPositionalArgument ( " args " ,
QCoreApplication : : translate ( " main " , " Arguments after '--' are ignored, but passed through to the application.arguments variable in QML. " ) , " [-- args...] " ) ;
if ( ! parser . parse ( QCoreApplication : : arguments ( ) ) ) {
qWarning ( ) < < parser . errorText ( ) ;
exit ( 1 ) ;
}
if ( parser . isSet ( versionOption ) )
parser . showVersion ( ) ;
if ( parser . isSet ( helpOption ) )
parser . showHelp ( ) ;
2019-04-24 19:05:32 +00:00
if ( parser . isSet ( listConfOption ) )
listConfFiles ( ) ;
2019-04-16 15:25:36 +00:00
if ( applicationType = = QmlApplicationTypeUnknown ) {
# ifdef QT_WIDGETS_LIB
qWarning ( ) < < QCoreApplication : : translate ( " main " , " --apptype must be followed by one of the following: core gui widget \n " ) ;
# else
qWarning ( ) < < QCoreApplication : : translate ( " main " , " --apptype must be followed by one of the following: core gui \n " ) ;
# endif // QT_WIDGETS_LIB
parser . showHelp ( ) ;
}
if ( parser . isSet ( verboseOption ) )
verboseMode = true ;
if ( parser . isSet ( quietOption ) ) {
quietMode = true ;
verboseMode = false ;
}
2017-12-19 15:37:24 +00:00
# if QT_CONFIG(qml_animation)
2019-04-16 15:25:36 +00:00
if ( parser . isSet ( slowAnimationsOption ) )
QUnifiedTimer : : instance ( ) - > setSlowModeEnabled ( true ) ;
if ( parser . isSet ( fixedAnimationsOption ) )
QUnifiedTimer : : instance ( ) - > setConsistentTiming ( true ) ;
2017-03-30 08:41:52 +00:00
# endif
2019-04-16 15:25:36 +00:00
if ( parser . isSet ( glEsOption ) )
QCoreApplication : : setAttribute ( Qt : : AA_UseOpenGLES ) ;
if ( parser . isSet ( glSoftwareOption ) )
QCoreApplication : : setAttribute ( Qt : : AA_UseSoftwareOpenGL ) ;
if ( parser . isSet ( glDesktopOption ) )
QCoreApplication : : setAttribute ( Qt : : AA_UseDesktopOpenGL ) ;
if ( parser . isSet ( scalingOption ) )
QCoreApplication : : setAttribute ( Qt : : AA_EnableHighDpiScaling ) ;
if ( parser . isSet ( noScalingOption ) )
QCoreApplication : : setAttribute ( Qt : : AA_DisableHighDpiScaling ) ;
for ( const QString & importPath : parser . values ( importOption ) )
e . addImportPath ( importPath ) ;
files < < parser . values ( qmlFileOption ) ;
if ( parser . isSet ( configOption ) )
confFile = parser . value ( configOption ) ;
if ( parser . isSet ( translationOption ) )
translationFile = parser . value ( translationOption ) ;
if ( parser . isSet ( dummyDataOption ) )
dummyDir = parser . value ( dummyDataOption ) ;
for ( QString posArg : parser . positionalArguments ( ) ) {
if ( posArg = = QLatin1String ( " -- " ) )
break ;
else
files < < posArg ;
2012-12-21 23:42:47 +00:00
}
2016-11-16 13:22:36 +00:00
# if QT_CONFIG(translation)
2018-06-28 14:47:11 +00:00
// Need to be installed before QQmlApplicationEngine's automatic translation loading
// (qt_ translations are loaded there)
if ( ! translationFile . isEmpty ( ) ) {
2012-12-21 23:42:47 +00:00
QTranslator translator ;
if ( translator . load ( translationFile ) ) {
app - > installTranslator ( & translator ) ;
2013-10-23 22:37:16 +00:00
if ( verboseMode )
printf ( " qml: Loaded translation file %s \n " , qPrintable ( QDir : : toNativeSeparators ( translationFile ) ) ) ;
2012-12-21 23:42:47 +00:00
} else {
if ( ! quietMode )
2013-10-23 22:37:16 +00:00
printf ( " qml: Could not load the translation file %s \n " , qPrintable ( QDir : : toNativeSeparators ( translationFile ) ) ) ;
2012-12-21 23:42:47 +00:00
}
}
# else
if ( ! translationFile . isEmpty ( ) & & ! quietMode )
2013-10-23 22:37:16 +00:00
printf ( " qml: Translation file specified, but Qt built without translation support. \n " ) ;
2012-12-21 23:42:47 +00:00
# endif
2019-04-23 13:20:15 +00:00
if ( quietMode ) {
2012-12-21 23:42:47 +00:00
qInstallMessageHandler ( quietMessageHandler ) ;
2019-04-23 13:20:15 +00:00
QLoggingCategory : : setFilterRules ( QStringLiteral ( " *=false " ) ) ;
}
2012-12-21 23:42:47 +00:00
if ( files . count ( ) < = 0 ) {
2017-04-12 13:45:18 +00:00
# if defined(Q_OS_DARWIN)
2013-11-18 14:57:08 +00:00
if ( applicationType = = QmlApplicationTypeGui )
exitTimerId = static_cast < LoaderApplication * > ( app ) - > startTimer ( FILE_OPEN_EVENT_WAIT_TIME ) ;
else
# endif
noFilesGiven ( ) ;
2012-12-21 23:42:47 +00:00
}
qae = & e ;
2013-10-23 22:37:16 +00:00
loadConf ( confFile , ! verboseMode ) ;
2012-12-21 23:42:47 +00:00
2019-01-14 08:42:29 +00:00
// Load files
2015-03-11 05:25:14 +00:00
QScopedPointer < LoadWatcher > lw ( new LoadWatcher ( & e , files . count ( ) ) ) ;
2012-12-21 23:42:47 +00:00
2014-03-01 06:28:29 +00:00
// Load dummy data before loading QML-files
if ( ! dummyDir . isEmpty ( ) & & QFileInfo ( dummyDir ) . isDir ( ) )
loadDummyDataFiles ( e , dummyDir ) ;
2016-08-11 10:08:00 +00:00
for ( const QString & path : qAsConst ( files ) ) {
2017-03-15 10:16:20 +00:00
QUrl url = QUrl : : fromUserInput ( path , QDir : : currentPath ( ) , QUrl : : AssumeLocalFile ) ;
2017-01-02 13:04:48 +00:00
if ( verboseMode )
printf ( " qml: loading %s \n " , qPrintable ( url . toString ( ) ) ) ;
QByteArray strippedFile ;
if ( getFileSansBangLine ( path , strippedFile ) )
2019-01-14 08:42:29 +00:00
// QQmlComponent won't resolve it for us: it doesn't know it's a valid file if we loadData
e . loadData ( strippedFile , e . baseUrl ( ) . resolved ( url ) ) ;
else // Errors or no bang line
2012-12-21 23:42:47 +00:00
e . load ( url ) ;
}
2015-03-11 05:25:14 +00:00
if ( lw - > earlyExit )
2016-08-03 14:54:26 +00:00
return lw - > returnCode ;
2015-03-11 05:25:14 +00:00
2012-12-21 23:42:47 +00:00
return app - > exec ( ) ;
}
# include "main.moc"