Add core application functionality to Qt.application in QML
authorAlan Alpert <aalpert@rim.com>
Tue, 19 Feb 2013 05:07:15 +0000 (21:07 -0800)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 5 Mar 2013 21:37:25 +0000 (22:37 +0100)
This exposes some information to QML which is available on
the QCoreApplication instance.

A future change should make it possible to restrict this for use in scripting
environments (which should not have access to the QCoreApplication). That has
been left out of this change because proper support for such restrictions is
not yet in place.

Change-Id: Ica144fcfb0b42fa6df8d0cb1c7c03eb97282b489
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
src/qml/qml/qqmlengine.cpp
src/qml/qml/qqmlglobal.cpp
src/qml/qml/qqmlglobal_p.h
src/quick/util/qquickapplication.cpp
src/quick/util/qquickapplication_p.h
tests/auto/qml/qqmlglobal/tst_qqmlglobal.cpp

index b0b6f45..ddc6f0e 100644 (file)
@@ -437,13 +437,31 @@ The following functions are also on the Qt object.
     \li Qt.RightToLeft - Text and graphics elements should be positioned
                         from right to left.
     \endlist
-
+    \row
+    \li \c application.arguments
+    \li This is a string list of the arguments the executable was invoked with.
+    \row
+    \li \c application.name
+    \li This is the application name set on the QCoreApplication instance. This property can be written
+    to in order to set the application name.
+    \row
+    \li \c application.version
+    \li This is the application version set on the QCoreApplication instance. This property can be written
+    to in order to set the application name.
     \endtable
 
+    The object also has one signal, aboutToQuit(), which is the same as \l QCoreApplication::aboutToQuit().
+
     The following example uses the \c application object to indicate
     whether the application is currently active:
 
     \snippet qml/application.qml document
+
+    Note that when using QML without a QGuiApplication, the following properties will be undefined:
+    \list
+    \li application.active
+    \li application.layoutDirection
+    \endlist
 */
 
 /*!
index 379a168..607ee4d 100644 (file)
@@ -44,6 +44,7 @@
 #include <QtCore/qvariant.h>
 #include <QtCore/qstringlist.h>
 #include <QtCore/qdebug.h>
+#include <QtCore/QCoreApplication>
 
 QT_BEGIN_NAMESPACE
 
@@ -357,7 +358,7 @@ Q_AUTOTEST_EXPORT QQmlColorProvider *QQml_colorProvider(void)
 
 
 QQmlGuiProvider::~QQmlGuiProvider() {}
-QObject *QQmlGuiProvider::application(QObject *) { return 0; }
+QObject *QQmlGuiProvider::application(QObject *) { return new QQmlApplication(); }
 QStringList QQmlGuiProvider::fontFamilies() { return QStringList(); }
 bool QQmlGuiProvider::openUrlExternally(QUrl &) { return false; }
 
@@ -383,8 +384,7 @@ Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *newPr
 static QQmlGuiProvider **getGuiProvider(void)
 {
     if (guiProvider == 0) {
-        qWarning() << "Warning: QQml_guiProvider: no GUI provider has been set!";
-        static QQmlGuiProvider nullGuiProvider;
+        static QQmlGuiProvider nullGuiProvider; //Still provides an application with no GUI support
         guiProvider = &nullGuiProvider;
     }
 
@@ -397,4 +397,51 @@ Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider(void)
     return *providerPtr;
 }
 
+//Docs in qqmlengine.cpp
+QQmlApplication::QQmlApplication(QObject *parent)
+    : QObject(*(new QQmlApplicationPrivate),parent)
+{
+    connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
+            this, SIGNAL(aboutToQuit()));
+}
+
+QQmlApplication::QQmlApplication(QQmlApplicationPrivate &dd, QObject *parent)
+    : QObject(dd, parent)
+{
+    connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
+            this, SIGNAL(aboutToQuit()));
+}
+
+QStringList QQmlApplication::args()
+{
+    Q_D(QQmlApplication);
+    if (!d->argsInit) {
+        d->argsInit = true;
+        d->args = QCoreApplication::arguments();
+    }
+    return d->args;
+}
+
+QString QQmlApplication::name() const
+{
+    return QCoreApplication::instance()->applicationName();
+}
+
+QString QQmlApplication::version() const
+{
+    return QCoreApplication::instance()->applicationVersion();
+}
+
+void QQmlApplication::setName(const QString &arg)
+{
+    QCoreApplication::instance()->setApplicationName(arg);
+    emit nameChanged(); //Note that we don't get notified if it's changed from C++
+}
+
+void QQmlApplication::setVersion(const QString &arg)
+{
+    QCoreApplication::instance()->setApplicationVersion(arg);
+    emit versionChanged(); //Note that we don't get notified if it's changed from C++
+}
+
 QT_END_NAMESPACE
index f6b2c81..6ca54f6 100644 (file)
@@ -313,6 +313,53 @@ public:
 Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *);
 Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider();
 
+class QQmlApplicationPrivate;
+
+class Q_QML_PRIVATE_EXPORT QQmlApplication : public QObject
+{
+    //Application level logic, subclassed by QtQuick if available via QQmlGuiProvider
+    Q_OBJECT
+    Q_PROPERTY(QStringList arguments READ args CONSTANT)
+    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+    Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged)
+public:
+    QQmlApplication(QObject* parent=0);
+
+    QStringList args();
+
+    QString name() const;
+    QString version() const;
+
+public Q_SLOTS:
+    void setName(const QString &arg);
+    void setVersion(const QString &arg);
+
+Q_SIGNALS:
+    void aboutToQuit();
+
+    void nameChanged();
+    void versionChanged();
+
+protected:
+    QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=0);
+
+private:
+    Q_DISABLE_COPY(QQmlApplication);
+    Q_DECLARE_PRIVATE(QQmlApplication);
+};
+
+class QQmlApplicationPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QQmlApplication)
+public:
+    QQmlApplicationPrivate() {
+        argsInit = false;
+    }
+
+    bool argsInit;
+    QStringList args;
+};
+
 QT_END_NAMESPACE
 
 #endif // QQMLGLOBAL_H
index 1e2a421..bc8b724 100644 (file)
 #include <qpa/qplatformintegration.h>
 #include <QtGui/QGuiApplication>
 #include <QtCore/QDebug>
+#include <QtQml/private/qqmlglobal_p.h>
 
 QT_BEGIN_NAMESPACE
 
-class QQuickApplicationPrivate : public QObjectPrivate
+class QQuickApplicationPrivate : public QQmlApplicationPrivate
 {
     Q_DECLARE_PUBLIC(QQuickApplication)
 public:
@@ -70,7 +71,7 @@ private:
 */
 
 QQuickApplication::QQuickApplication(QObject *parent)
-    : QObject(*new QQuickApplicationPrivate(), parent)
+    : QQmlApplication(*new QQuickApplicationPrivate(), parent)
 {
     if (qApp) {
         qApp->installEventFilter(this);
index 2eef59b..cccc024 100644 (file)
 
 #include <QtCore/QObject>
 #include <qqml.h>
+#include <QtQml/private/qqmlglobal_p.h>
 #include <private/qtquickglobal_p.h>
 
 QT_BEGIN_NAMESPACE
 
 
 class QQuickApplicationPrivate;
-class Q_AUTOTEST_EXPORT QQuickApplication : public QObject
+class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication
 {
     Q_OBJECT
     Q_PROPERTY(bool active READ active NOTIFY activeChanged)
index 293eccb..793da64 100644 (file)
@@ -54,7 +54,7 @@ private slots:
     void initTestCase();
 
     void colorProviderWarning();
-    void guiProviderWarning();
+    void noGuiProviderWarning();
 };
 
 void tst_qqmlglobal::initTestCase()
@@ -68,11 +68,9 @@ void tst_qqmlglobal::colorProviderWarning()
     QQml_colorProvider();
 }
 
-void tst_qqmlglobal::guiProviderWarning()
+void tst_qqmlglobal::noGuiProviderWarning()
 {
-    const QLatin1String expected("Warning: QQml_guiProvider: no GUI provider has been set! ");
-    QTest::ignoreMessage(QtWarningMsg, expected.data());
-    QQml_guiProvider();
+    QVERIFY(QQml_guiProvider()); //No GUI provider, so a default non-zero application instance is returned.
 }
 
 QTEST_MAIN(tst_qqmlglobal)