File indexing completed on 2024-05-05 16:07:09

0001 /*
0002     SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef QMLOBJECT_H
0008 #define QMLOBJECT_H
0009 
0010 #include <QObject>
0011 
0012 #include <QQmlComponent>
0013 
0014 #include <kdeclarative/kdeclarative_export.h>
0015 
0016 #if KDECLARATIVE_ENABLE_DEPRECATED_SINCE(5, 98)
0017 #include <KPackage/Package>
0018 #endif
0019 
0020 class QQmlEngine;
0021 class QQmlComponent;
0022 class QQmlContext;
0023 
0024 namespace KDeclarative
0025 {
0026 class QmlObjectPrivate;
0027 
0028 /**
0029  * @class KDeclarative::QmlObject qmlobject.h KDeclarative/QmlObject
0030  *
0031  * @author Marco Martin <mart@kde.org>
0032  *
0033  * @short An object that instantiates an entire QML context, with its own declarative engine
0034  *
0035  * KDeclarative::QmlObject provides a class to conveniently use QML based
0036  * declarative user interfaces inside Plasma widgets.
0037  * A QmlObject corresponds to one QML file (which can include others).
0038  * It will have its own QQmlEngine with a single root object,
0039  * described in the QML file.
0040  */
0041 class KDECLARATIVE_EXPORT QmlObject : public QObject
0042 {
0043     Q_OBJECT
0044 
0045     Q_PROPERTY(QUrl source READ source WRITE setSource)
0046     Q_PROPERTY(QString translationDomain READ translationDomain WRITE setTranslationDomain)
0047     Q_PROPERTY(bool initializationDelayed READ isInitializationDelayed WRITE setInitializationDelayed)
0048     Q_PROPERTY(QObject *rootObject READ rootObject)
0049     Q_PROPERTY(QQmlComponent::Status status READ status NOTIFY statusChanged)
0050 
0051 public:
0052     /**
0053      * Constructs a new QmlObject
0054      *
0055      * @param parent the parent of this object
0056      */
0057     explicit QmlObject(QObject *parent = nullptr);
0058 
0059     /**
0060      * Constructs a new QmlObject
0061      *
0062      * @param engine a QQmlEngine we want to use
0063      * @param parent the parent of this object
0064      *
0065      * @deprecated Since 5.95, Use QmlObject(std::shared_ptr<QmlEngine>, QObject*)
0066      * instead.
0067      */
0068 #if KDECLARATIVE_ENABLE_DEPRECATED_SINCE(5, 95)
0069     KDECLARATIVE_DEPRECATED_VERSION(5, 95, "Use QmlObject(std::shared_ptr<QQmlEngine>, QmlContext*, QObject*) instead")
0070     explicit QmlObject(QQmlEngine *engine, QObject *parent = nullptr);
0071 #endif
0072 
0073     /**
0074      * Constructs a new QmlObject
0075      *
0076      * @param engine the QQmlEngine to use
0077      * @param rootContext the root context to use for object creation
0078      * @param parent the parent of this object
0079      *
0080      * @deprecated Since 5.95, Use QmlObject(std::shared_ptr<QmlEngine>, QmlContext*, QObject*)
0081      * instead.
0082      */
0083 #if KDECLARATIVE_ENABLE_DEPRECATED_SINCE(5, 95)
0084     KDECLARATIVE_DEPRECATED_VERSION(5, 95, "Use QmlObject(std::shared_ptr<QQmlEngine>, QQmlContext*, QObject*) instead")
0085     explicit QmlObject(QQmlEngine *engine, QQmlContext *rootContext, QObject *parent = nullptr);
0086 #endif
0087 
0088     /**
0089      * Construct a new QmlObject
0090      *
0091      * @param engine The QQmlEngine to use. If this object is the first user of
0092      * the engine (e.g. use_count() is 1), KDeclarative::setupEngine() will be
0093      * called. If this is nullptr, a new engine will be created for this object
0094      * to use.
0095      * @param rootContext The QML context to use for object creation. If this is
0096      * nullptr, the engine's root context will be used.
0097      * @param parent The QObject parent for this object.
0098      */
0099     explicit QmlObject(std::shared_ptr<QQmlEngine> engine, QQmlContext *rootContext = nullptr, QObject *parent = nullptr);
0100 
0101     ~QmlObject() override;
0102 
0103     /**
0104      * Call this method before calling setupBindings to install a translation domain for all
0105      * i18n global functions. If a translation domain is set all i18n calls delegate to the
0106      * matching i18nd calls with the provided translation domain.
0107      *
0108      * The translationDomain affects all i18n calls including those from imports. Because of
0109      * that modules intended to be used as imports should prefer the i18nd variants and set
0110      * the translation domain explicitly in each call.
0111      *
0112      * This method is only required if your declarative usage is inside a library. If it's
0113      * in an application there is no need to set the translation domain as the application's
0114      * domain can be used.
0115      *
0116      * @param translationDomain The translation domain to be used for i18n calls.
0117      * @since 5.0
0118      */
0119     void setTranslationDomain(const QString &translationDomain);
0120 
0121     /**
0122      * @return the translation domain for the i18n calls done in this QML engine
0123      * @since 5.0
0124      */
0125     QString translationDomain() const;
0126 
0127     /**
0128      * Sets the path of the QML file to parse and execute
0129      *
0130      * @param path the absolute path of a QML file
0131      */
0132     void setSource(const QUrl &source);
0133 
0134     /**
0135      * @return the absolute path of the current QML file
0136      */
0137     QUrl source() const;
0138 
0139 #if KDECLARATIVE_ENABLE_DEPRECATED_SINCE(5, 98)
0140     /**
0141      * Load the package called packageName, then loads the
0142      * mainscript file for that package
0143      *
0144      * @param packageName the plugin name of the package
0145      * @seprecated Since 5.98, use KPackage manually and set the source URL to the "mainscript" file path
0146      */
0147     KDECLARATIVE_DEPRECATED_VERSION(5, 98, "use KPackage manually and set the source URL to the \"mainscript\" file path")
0148     void loadPackage(const QString &packageName);
0149 
0150     /**
0151      * Sets a package, then loads the
0152      * mainscript file for that package
0153      *
0154      * @param package the package we want to use to provide QML
0155      *         files to this QML object
0156      * @seprecated Since 5.98, use KPackage manually and set the source URL to the "mainscript" file path
0157      */
0158     KDECLARATIVE_DEPRECATED_VERSION(5, 98, "use KPackage manually and set the source URL to the \"mainscript\" file path")
0159     void setPackage(const KPackage::Package &package);
0160 
0161     /**
0162      * @return the optional package, if any
0163      * @seprecated Since 5.98, use KPackage manually and set the source URL to the "mainscript" file path
0164      */
0165     KDECLARATIVE_DEPRECATED_VERSION(5, 98, "use KPackage manually and set the source URL to the \"mainscript\" file path")
0166     KPackage::Package package() const;
0167 #endif
0168 
0169     /**
0170      * Sets whether the execution of the QML file has to be delayed later in the event loop. It has to be called before setQmlPath().
0171      * In this case it will be possible to assign new objects in the main engine context
0172      * before the main component gets initialized.
0173      * In that case it will be possible to access it immediately from the QML code.
0174      * The initialization will either be completed automatically asynchronously
0175      * or explicitly by calling completeInitialization()
0176      *
0177      * @param delay if true the initialization of the QML file will be delayed
0178      *              at the end of the event loop
0179      */
0180     void setInitializationDelayed(const bool delay);
0181 
0182     /**
0183      * @return true if the initialization of the QML file will be delayed
0184      *              at the end of the event loop
0185      */
0186     bool isInitializationDelayed() const;
0187 
0188     /**
0189      * @return the declarative engine that runs the qml file assigned to this widget.
0190      */
0191     QQmlEngine *engine();
0192 
0193     /**
0194      * @return the root object of the declarative object tree
0195      */
0196     QObject *rootObject() const;
0197 
0198     /**
0199      * @return the main QQmlComponent of the engine
0200      */
0201     QQmlComponent *mainComponent() const;
0202 
0203     /**
0204      * The components's creation context.
0205      * @since 5.11
0206      */
0207     QQmlContext *rootContext() const;
0208 
0209     /**
0210      * The component's current status.
0211      * @since 5.11
0212      */
0213     QQmlComponent::Status status() const;
0214 
0215     /**
0216      * Creates and returns an object based on the provided url to a Qml file
0217      * with the same QQmlEngine and the same root context as the main object,
0218      * that will be the parent of the newly created object
0219      * @param source url where the QML file is located
0220      * @param context The QQmlContext in which we will create the object,
0221      *             if 0 it will use the engine's root context
0222      * @param initialProperties optional properties that will be set on
0223      *             the object when created (and before Component.onCompleted
0224      *             gets emitted
0225      */
0226     QObject *createObjectFromSource(const QUrl &source, QQmlContext *context = nullptr, const QVariantHash &initialProperties = QVariantHash());
0227 
0228     /**
0229      * Creates and returns an object based on the provided QQmlComponent
0230      * with the same QQmlEngine and the same root context as the admin object,
0231      * that will be the parent of the newly created object
0232      * @param component the component we want to instantiate
0233      * @param context The QQmlContext in which we will create the object,
0234      *             if 0 it will use the engine's root context
0235      * @param initialProperties optional properties that will be set on
0236      *             the object when created (and before Component.onCompleted
0237      *             gets emitted
0238      */
0239     QObject *createObjectFromComponent(QQmlComponent *component, QQmlContext *context = nullptr, const QVariantHash &initialProperties = QVariantHash());
0240 
0241 public Q_SLOTS:
0242     /**
0243      * Finishes the process of initialization.
0244      * If isInitializationDelayed() is false, calling this will have no effect.
0245      * @param initialProperties optional properties that will be set on
0246      *             the object when created (and before Component.onCompleted
0247      *             gets emitted
0248      */
0249     void completeInitialization(const QVariantHash &initialProperties = QVariantHash());
0250 
0251 Q_SIGNALS:
0252     /**
0253      * Emitted when the parsing and execution of the QML file is terminated
0254      */
0255     void finished();
0256 
0257     void statusChanged(QQmlComponent::Status);
0258 
0259 protected:
0260     /**
0261      * Constructs a new QmlObject
0262      *
0263      * @param engine a QQmlEngine we want to use
0264      * @param rootContext the root context we want to use for objects creation
0265      * @param obj setupEngine is called when this is set to nullptr. This way the creator can
0266      * influence if the engine should be initialized or not in case it is shared between
0267      * multiple objects (such as QmlObjectSharedEngine)
0268      * @param parent the parent of this object
0269      * @since 5.45
0270      *
0271      * @deprecated Since 5.95, Use QmlObject(std::shared_ptr<QmlEngine>, QmlContext*, QObject*)
0272      * instead. The "obj" parameter has been dropped, instead setupEngine will be
0273      * called if this QmlObject is the first user of the engine.
0274      */
0275 #if KDECLARATIVE_ENABLE_DEPRECATED_SINCE(5, 95)
0276     KDECLARATIVE_DEPRECATED_VERSION(5, 95, "Use QmlObject(std::shared_ptr<QQmlEngine>, QQmlContext*, QObject*) instead")
0277     explicit QmlObject(QQmlEngine *engine, QQmlContext *rootContext, QmlObject *obj, QObject *parent = nullptr);
0278 #endif
0279 
0280 private:
0281     friend class QmlObjectPrivate;
0282     QmlObjectPrivate *const d;
0283 
0284     Q_PRIVATE_SLOT(d, void scheduleExecutionEnd())
0285     Q_PRIVATE_SLOT(d, void checkInitializationCompleted())
0286 };
0287 
0288 }
0289 
0290 #endif // multiple inclusion guard