File indexing completed on 2024-04-21 03:56:01

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  * A Pool of Page items, pages will be unique per url and the items
0014  * will be kept around unless explicitly deleted.
0015  * Instances are C++ owned and can be deleted only manually using deletePage()
0016  * Instance are unique per url: if you need 2 different instance for a page
0017  * url, you should instantiate them in the traditional way
0018  * or use a different PagePool instance.
0019  *
0020  * @see org::kde::kirigami::PagePoolAction
0021  */
0022 class PagePool : public QObject
0023 {
0024     Q_OBJECT
0025     QML_ELEMENT
0026     /**
0027      * The last url that was loaded with @loadPage. Useful if you need
0028      * to have a "checked" state to buttons or list items that
0029      * load the page when clicked.
0030      */
0031     Q_PROPERTY(QUrl lastLoadedUrl READ lastLoadedUrl NOTIFY lastLoadedUrlChanged FINAL)
0032 
0033     /**
0034      * The last item that was loaded with @loadPage.
0035      */
0036     Q_PROPERTY(QQuickItem *lastLoadedItem READ lastLoadedItem NOTIFY lastLoadedItemChanged FINAL)
0037 
0038     /**
0039      * All items loaded/managed by the PagePool.
0040      * @since 5.84
0041      */
0042     Q_PROPERTY(QList<QQuickItem *> items READ items NOTIFY itemsChanged FINAL)
0043 
0044     /**
0045      * All page URLs loaded/managed by the PagePool.
0046      * @since 5.84
0047      */
0048     Q_PROPERTY(QList<QUrl> urls READ urls NOTIFY urlsChanged FINAL)
0049 
0050     /**
0051      * If true (default) the pages will be kept around, will have C++ ownership and
0052      * only one instance per page will be created.
0053      * If false the pages will have Javascript ownership (thus deleted on pop by the
0054      * page stacks) and each call to loadPage will create a new page instance. When
0055      * cachePages is false, Components get cached nevertheless.
0056      */
0057     Q_PROPERTY(bool cachePages READ cachePages WRITE setCachePages NOTIFY cachePagesChanged FINAL)
0058 
0059 public:
0060     PagePool(QObject *parent = nullptr);
0061     ~PagePool() override;
0062 
0063     QUrl lastLoadedUrl() const;
0064     QQuickItem *lastLoadedItem() const;
0065     QList<QQuickItem *> items() const;
0066     QList<QUrl> urls() const;
0067 
0068     void setCachePages(bool cache);
0069     bool cachePages() const;
0070 
0071     /**
0072      * Returns the instance of the item defined in the QML file identified
0073      * by url, only one instance will be made per url if cachePAges is true.
0074      * If the url is remote (i.e. http) don't rely on the return value but
0075      * us the async callback instead.
0076      *
0077      * @param url full url of the item: it can be a well formed Url, an
0078      * absolute path or a relative one to the path of the qml file the
0079      * PagePool is instantiated from
0080      * @param callback If we are loading a remote url, we can't have the
0081      * item immediately but will be passed as a parameter to the provided
0082      * callback. Normally, don't set a callback, use it only in case of
0083      * remote urls
0084      * @returns the page instance that will have been created if necessary.
0085      * If the url is remote it will return null, as well will return null
0086      * if the callback has been provided
0087      */
0088     Q_INVOKABLE QQuickItem *loadPage(const QString &url, QJSValue callback = QJSValue());
0089 
0090     Q_INVOKABLE QQuickItem *loadPageWithProperties(const QString &url, const QVariantMap &properties, QJSValue callback = QJSValue());
0091 
0092     /**
0093      * @returns The url of the page for the given instance, empty if there is no correspondence
0094      */
0095     Q_INVOKABLE QUrl urlForPage(QQuickItem *item) const;
0096 
0097     /**
0098      * @returns The page associated with a given URL, nullptr if there is no correspondence
0099      */
0100     Q_INVOKABLE QQuickItem *pageForUrl(const QUrl &url) const;
0101 
0102     /**
0103      * @returns true if the is managed by the PagePool
0104      * @param the page can be either a QQuickItem or an url
0105      */
0106     Q_INVOKABLE bool contains(const QVariant &page) const;
0107 
0108     /**
0109      * Deletes the page (only if is managed by the pool.
0110      * @param page either the url or the instance of the page
0111      */
0112     Q_INVOKABLE void deletePage(const QVariant &page);
0113 
0114     /**
0115      * @returns full url from an absolute or relative path
0116      */
0117     Q_INVOKABLE QUrl resolvedUrl(const QString &file) const;
0118 
0119     /**
0120      * @returns true if the url identifies a local resource (local file or a file inside Qt's resource system).
0121      * False if the url points to a network location
0122      */
0123     Q_INVOKABLE bool isLocalUrl(const QUrl &url);
0124 
0125     /**
0126      * Deletes all pages managed by the pool.
0127      */
0128     Q_INVOKABLE void clear();
0129 
0130 Q_SIGNALS:
0131     void lastLoadedUrlChanged();
0132     void lastLoadedItemChanged();
0133     void itemsChanged();
0134     void urlsChanged();
0135     void cachePagesChanged();
0136 
0137 private:
0138     QQuickItem *createFromComponent(QQmlComponent *component, const QVariantMap &properties);
0139 
0140     QUrl m_lastLoadedUrl;
0141     QPointer<QQuickItem> m_lastLoadedItem;
0142     QHash<QUrl, QQuickItem *> m_itemForUrl;
0143     QHash<QUrl, QQmlComponent *> m_componentForUrl;
0144     QHash<QQuickItem *, QUrl> m_urlForItem;
0145 
0146     bool m_cachePages = true;
0147 };