Warning, /frameworks/kirigami/src/controls/PagePoolAction.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 import QtQuick 2.7
0008 import QtQml 2.7
0009 import QtQuick.Controls 2.5 as QQC2
0010 import org.kde.kirigami 2.11 as Kirigami
0011 
0012 /**
0013  * An action used to load Pages coming from a common PagePool
0014  * in a PageRow or QtQuick.Controls.StackView.
0015  *
0016  * @see PagePool
0017  */
0018 Kirigami.Action {
0019     id: root
0020 
0021 //BEGIN properties
0022     /**
0023      * @brief This property holds the url or filename of the page that this action will load.
0024      */
0025     property string page
0026 
0027     /**
0028      * @brief This property holds the PagePool object used by this PagePoolAction.
0029      *
0030      * PagePool will make sure only one instance of the page identified by the page url will be created and reused.
0031      * PagePool::lastLoadedUrl will be used to control the mutual exclusivity of the checked
0032      * state of the PagePoolAction instances sharing the same PagePool.
0033      */
0034     property Kirigami.PagePool pagePool
0035 
0036     /**
0037      * This property accepts either a PageRow or a StackView.
0038      * The component that will instantiate the pages, which has to work with a stack logic.
0039      * PageRow is recommended, but will work with StackView as well.
0040      *
0041      * default: `bound to the global ApplicationWindow::pageStack, which is a PageRow by default`
0042      */
0043     property Item pageStack: typeof applicationWindow !== 'undefined' ? applicationWindow().pageStack : null
0044 
0045     /**
0046      * @brief This property sets the page in the ::pageStack after which
0047      * new pages will be pushed.
0048      *
0049      * All pages present after the given basePage will be removed from the ::pageStack
0050      */
0051     property QQC2.Page basePage
0052 
0053     /**
0054      * This property holds a function that generate the property values for the created page
0055      * when it is pushed onto the PagePool.
0056      *
0057      * Example usage:
0058      * @code{.qml}
0059      * Kirigami.PagePoolAction {
0060      *     text: i18n("Security")
0061      *     icon.name: "security-low"
0062      *     page: Qt.resolvedUrl("Security.qml")
0063      *     initialProperties: {
0064      *         return {
0065      *             room: root.room
0066      *         }
0067      *     }
0068      * }
0069      * @endcode
0070      * @property QVariantMap initialProperties
0071      */
0072     property var initialProperties
0073 
0074     /**
0075       * @brief This property sets whether PagePoolAction will use the layers property
0076       * implemented by the ::pageStack.
0077       *
0078       * This is intended for use with PageRow layers to allow PagePoolActions to
0079       * push context-specific pages onto the layers stack.
0080       *
0081       * default: ``false``
0082       *
0083       * @since KDE Frameworks 5.70
0084       * @since org.kde.kirigami 2.12
0085       */
0086     property bool useLayers: false
0087 //END properties
0088 
0089     /**
0090       * @returns the page item held in the PagePool or null if it has not been loaded yet.
0091       */
0092     function pageItem() {
0093         return pagePool.pageForUrl(page)
0094     }
0095 
0096     /**
0097       * @returns @c true if the page has been loaded and placed on pageStack.layers
0098       * and useLayers is true, otherwise returns null.
0099       */
0100     function layerContainsPage() {
0101         if (!useLayers || !pageStack.hasOwnProperty("layers")) return false
0102 
0103         const item = pageStack.layers.find((item, index) => {
0104             return item === pagePool.pageForUrl(page)
0105         })
0106         return !!item
0107     }
0108 
0109     /**
0110       * @returns @c true if the page has been loaded and placed on the ::pageStack,
0111       * otherwise returns null.
0112       */
0113     function stackContainsPage() {
0114         if (useLayers) return false
0115         return pageStack.columnView.containsItem(pagePool.pageForUrl(page))
0116     }
0117 
0118     checkable: true
0119 
0120     onTriggered: {
0121         if (page.length === 0 || !pagePool || !pageStack) {
0122             return;
0123         }
0124 
0125         // User intends to "go back" to this layer.
0126         if (layerContainsPage() && pageItem() !== pageStack.layers.currentItem) {
0127             pageStack.layers.replace(pageItem(), pageItem()) // force pop above
0128             return
0129         }
0130 
0131         // User intends to "go back" to this page.
0132         if (stackContainsPage()) {
0133             if (pageStack.hasOwnProperty("layers")) {
0134                 pageStack.layers.clear()
0135             }
0136         }
0137 
0138         const pageStack_ = useLayers ? pageStack.layers : pageStack
0139 
0140         if (initialProperties && typeof(initialProperties) !== "object") {
0141             console.warn("initialProperties must be of type object");
0142             return;
0143         }
0144 
0145         if (!pageStack_.hasOwnProperty("pop") || typeof pageStack_.pop !== "function" || !pageStack_.hasOwnProperty("push") || typeof pageStack_.push !== "function") {
0146             return;
0147         }
0148 
0149         if (pagePool.isLocalUrl(page)) {
0150             if (basePage) {
0151                 pageStack_.pop(basePage);
0152 
0153             } else if (!useLayers) {
0154                 pageStack_.clear();
0155             }
0156 
0157             pageStack_.push(initialProperties ?
0158                                pagePool.loadPageWithProperties(page, initialProperties) :
0159                                pagePool.loadPage(page));
0160         } else {
0161             const callback = function(item) {
0162                 if (basePage) {
0163                     pageStack_.pop(basePage);
0164 
0165                 } else if (!useLayers) {
0166                     pageStack_.clear();
0167                 }
0168                 pageStack_.push(item);
0169             };
0170 
0171             if (initialProperties) {
0172                 pagePool.loadPage(page, initialProperties, callback);
0173 
0174             } else {
0175                 pagePool.loadPage(page, callback);
0176             }
0177         }
0178     }
0179 
0180     // Exposing this as a property is required as Action does not have a default property
0181     /** @internal */
0182     property QtObject _private: QtObject {
0183         id: _private
0184 
0185         function setChecked(checked) {
0186             root.checked = checked
0187         }
0188 
0189         function clearLayers() {
0190             pageStack.layers.clear()
0191         }
0192 
0193         property list<Connections> connections: [
0194             Connections {
0195                 target: pageStack
0196 
0197                 function onCurrentItemChanged() {
0198                     if (root.useLayers) {
0199                         if (root.layerContainsPage()) {
0200                             _private.clearLayers()
0201                         }
0202                         if (root.checkable)
0203                             _private.setChecked(false);
0204 
0205                     } else {
0206                         if (root.checkable)
0207                             _private.setChecked(root.stackContainsPage());
0208                     }
0209                 }
0210             },
0211             Connections {
0212                 enabled: pageStack.hasOwnProperty("layers")
0213                 target: pageStack.layers
0214 
0215                 function onCurrentItemChanged() {
0216                     if (root.useLayers && root.checkable) {
0217                         _private.setChecked(root.layerContainsPage());
0218 
0219                     } else {
0220                         if (pageStack.layers.depth === 1 && root.stackContainsPage()) {
0221                             _private.setChecked(true)
0222                         }
0223                     }
0224                 }
0225             }
0226         ]
0227     }
0228 }