File indexing completed on 2024-04-28 15:27:43

0001 /*
0002  *  SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 #pragma once
0007 
0008 #include <QObject>
0009 #include <QPointer>
0010 #include <QQuickItem>
0011 
0012 /**
0013  * @brief A Pool of Page objects, pages will be unique per url and the items
0014  * will be kept around unless explicitly deleted.
0015  *
0016  * Instances are C++ owned and can be deleted only manually using deletePage()
0017  * Instance are unique per url: if you need 2 different instances for a page
0018  * url, you should instantiate them in the traditional way
0019  * or use a different PagePool instance.
0020  *
0021  * @see PagePoolAction
0022  */
0023 class PagePool : public QObject
0024 {
0025     Q_OBJECT
0026     /**
0027      * @brief This property holds the last url that was loaded with
0028      * ::loadPage().
0029      *
0030      * This is useful when you need to have a "checked" state for buttons or
0031      * list items that load the page when clicked.
0032      */
0033     Q_PROPERTY(QUrl lastLoadedUrl READ lastLoadedUrl NOTIFY lastLoadedUrlChanged)
0034 
0035     /**
0036      * @brief This property holds the last item that was loaded with ::loadPage().
0037      */
0038     Q_PROPERTY(QQuickItem *lastLoadedItem READ lastLoadedItem NOTIFY lastLoadedItemChanged)
0039 
0040     /**
0041      * @brief This property holds a list of all items either loaded or managed
0042      * by the PagePool.
0043      *
0044      * @since KDE Frameworks 5.84
0045      */
0046     Q_PROPERTY(QList<QObject *> items READ items NOTIFY itemsChanged)
0047 
0048     /**
0049      * @brief This property holds a list of all page URLs either loaded or
0050      * managed by the PagePool.
0051      *
0052      * @since KDE Frameworks 5.84
0053      */
0054     Q_PROPERTY(QList<QUrl> urls READ urls NOTIFY urlsChanged)
0055 
0056     /**
0057      * @brief This property sets whether to cache pages.
0058      *
0059      * If @c true (default) the pages will be kept around, will have C++
0060      * ownership and only one instance per page will be created.
0061      * If @c false the pages will have Javascript ownership (thus deleted on pop
0062      * by the page stacks) and each call to ::loadPage() will create a new page
0063      * instance. When ::cachePages is false, Components get cached nevertheless.
0064      *
0065      * default: ``true``
0066      */
0067     Q_PROPERTY(bool cachePages READ cachePages WRITE setCachePages NOTIFY cachePagesChanged)
0068 
0069 public:
0070     PagePool(QObject *parent = nullptr);
0071     ~PagePool() override;
0072 
0073     QUrl lastLoadedUrl() const;
0074     QQuickItem *lastLoadedItem() const;
0075     QList<QObject *> items() const;
0076     QList<QUrl> urls() const;
0077 
0078     void setCachePages(bool cache);
0079     bool cachePages() const;
0080 
0081     /**
0082      * @brief This method loads the specified page and returns the page's instance
0083      * defined in the QML file.
0084      *
0085      * @note If ::cachePages is set to true, only one instance will be made per url.
0086      * @note If the url is remote (i.e. http), do not rely on the return value but
0087      * use the async callback instead.
0088      *
0089      * @param url full url of the item: it can be a well formed Url, an
0090      * absolute path or a relative one to the path of the qml file the
0091      * PagePool is instantiated from.
0092      * @param callback If we are loading a remote url, we can't have the
0093      * item immediately but will be passed as a parameter to the provided
0094      * callback. Normally, don't set a callback, use it only in case of
0095      * remote urls.
0096      * @returns the page instance that will have been created if necessary.
0097      * If the url is remote it will return null, as well will return null
0098      * if the callback has been provided.
0099      */
0100     Q_INVOKABLE QQuickItem *loadPage(const QString &url, QJSValue callback = QJSValue());
0101 
0102     /**
0103      * @brief This method loads the specified page and returns the page's instance
0104      * defined in the QML file with specified properties.
0105      *
0106      * @note If ::cachePages is set to true, only one instance will be made per url.
0107      * @note If the url is remote (i.e. https), do not rely on the return value but
0108      * use the async callback instead.
0109      *
0110      * @param url The full url of the item: it can be a well formed Url, an
0111      * absolute path or a relative path to the QML file the
0112      * PagePool is instantiated from.
0113      * @param callback If we are loading a remote url, we can't have the
0114      * item immediately but it will be passed as a parameter to the provided
0115      * callback. Normally, don't set a callback, use it only in case of
0116      * remote urls.
0117      * @param properties This is a QVariant::QVariantMap object that sets the properties of the page.
0118      * @param callback A method that is called after the page instance is created.
0119      * @returns The page instance that will be created if necessary.
0120      * If the url is remote or if the callback was provided, it will return null.
0121      */
0122     Q_INVOKABLE QQuickItem *loadPageWithProperties(const QString &url, const QVariantMap &properties, QJSValue callback = QJSValue());
0123 
0124     /**
0125      * @brief This method returns the url of the page for the given instance.
0126      * 
0127      * The returned value will be empty if there is no match.
0128      * @param item Page representing the QUrl you want.
0129      */
0130     Q_INVOKABLE QUrl urlForPage(QQuickItem *item) const;
0131 
0132     /**
0133      * @brief This method return the the page associated with a given URL, @c nullptr if there is no correspondence
0134      * @param url Url representing the Kirigami.Page you want.
0135      */
0136     Q_INVOKABLE QQuickItem *pageForUrl(const QUrl &url) const;
0137 
0138     /**
0139      * @brief This method returns whether the specified page is managed by the PagePool.
0140      * @param the page can be either a QQuickItem or an url
0141      */
0142     Q_INVOKABLE bool contains(const QVariant &page) const;
0143 
0144     /**
0145      * @brief This method deletes the specified page if it is managed by the PagePool.
0146      * @param page either the url or the instance of the page
0147      */
0148     Q_INVOKABLE void deletePage(const QVariant &page);
0149 
0150     /**
0151      * @brief This method returns the full url from an absolute or relative path.
0152      * @param file File path you want to convert to absolute path.
0153      */
0154     Q_INVOKABLE QUrl resolvedUrl(const QString &file) const;
0155 
0156     /**
0157      * @brief This method returns whether the URL is a local resource.
0158      *
0159      * The given URL is a local resource when it links to a local file, does
0160      * not have a set URL scheme, or when the scheme is set to  "qrc".
0161      * 
0162      * @see QUrl::scheme
0163      *
0164      * @param url The url you want to check.
0165      */
0166     Q_INVOKABLE bool isLocalUrl(const QUrl &url);
0167 
0168     /**
0169      * @brief This method deletes all pages managed by the PagePool.
0170      */
0171     Q_INVOKABLE void clear();
0172 
0173 Q_SIGNALS:
0174     void lastLoadedUrlChanged();
0175     void lastLoadedItemChanged();
0176     void itemsChanged();
0177     void urlsChanged();
0178     void cachePagesChanged();
0179 
0180 private:
0181     QQuickItem *createFromComponent(QQmlComponent *component, const QVariantMap &properties);
0182 
0183     QUrl m_lastLoadedUrl;
0184     QPointer<QQuickItem> m_lastLoadedItem;
0185     QHash<QUrl, QQuickItem *> m_itemForUrl;
0186     QHash<QUrl, QQmlComponent *> m_componentForUrl;
0187     QHash<QQuickItem *, QUrl> m_urlForItem;
0188 
0189     bool m_cachePages = true;
0190 };