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
0008 import QtQml
0009 import QtQuick.Templates as T
0010 import org.kde.kirigami as Kirigami
0011 
0012 /**
0013  * An action used to load Pages coming from a common PagePool
0014  * in a PageRow or QtQuickControls2 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's lastLoaderUrl property 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      * The pageStack property accepts either a Kirigami.PageRow or a QtQuickControls2 StackView.
0038      * The component that will instantiate the pages, which has to work with a stack logic.
0039      * Kirigami.PageRow is recommended, but will work with QtQuicControls2 StackView as well.
0040      *
0041      * default: `bound to ApplicationWindow's global 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 T.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 Kirigami.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 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(): Item {
0093         return pagePool.pageForUrl(page)
0094     }
0095 
0096     /**
0097      * @returns true if the page has been loaded and placed on pageStack.layers
0098      * and useLayers is true, otherwise returns null.
0099      */
0100     function layerContainsPage(): bool {
0101         if (!useLayers || !pageStack.hasOwnProperty("layers")) {
0102             return false;
0103         }
0104 
0105         const pageItem = this.pageItem();
0106         const item = pageStack.layers.find(item => item === pageItem);
0107         return item !== null;
0108     }
0109 
0110     /**
0111      * @returns true if the page has been loaded and placed on the pageStack,
0112      * otherwise returns null.
0113      */
0114     function stackContainsPage(): bool {
0115         if (useLayers) {
0116             return false;
0117         }
0118         return pageStack.columnView.containsItem(pagePool.pageForUrl(page));
0119     }
0120 
0121     checkable: true
0122 
0123     onTriggered: {
0124         if (page.length === 0 || !pagePool || !pageStack) {
0125             return;
0126         }
0127 
0128         // User intends to "go back" to this layer.
0129         const pageItem = this.pageItem();
0130         if (layerContainsPage() && pageItem !== pageStack.layers.currentItem) {
0131             pageStack.layers.replace(pageItem, pageItem); // force pop above
0132             return;
0133         }
0134 
0135         // User intends to "go back" to this page.
0136         if (stackContainsPage()) {
0137             if (pageStack.hasOwnProperty("layers")) {
0138                 pageStack.layers.clear();
0139             }
0140         }
0141 
0142         const stack = useLayers ? pageStack.layers : pageStack
0143 
0144         if (pageItem != null && stack.currentItem == pageItem) {
0145             return;
0146         }
0147 
0148         if (initialProperties && typeof(initialProperties) !== "object") {
0149             console.warn("initialProperties must be of type object");
0150             return;
0151         }
0152 
0153         if (!stack.hasOwnProperty("pop") || typeof stack.pop !== "function" || !stack.hasOwnProperty("push") || typeof stack.push !== "function") {
0154             return;
0155         }
0156 
0157         if (pagePool.isLocalUrl(page)) {
0158             if (basePage) {
0159                 stack.pop(basePage);
0160 
0161             } else if (!useLayers) {
0162                 stack.clear();
0163             }
0164 
0165             stack.push(initialProperties
0166                 ? pagePool.loadPageWithProperties(page, initialProperties)
0167                 : pagePool.loadPage(page));
0168         } else {
0169             const callback = item => {
0170                 if (basePage) {
0171                     stack.pop(basePage);
0172 
0173                 } else if (!useLayers) {
0174                     stack.clear();
0175                 }
0176 
0177                 stack.push(item);
0178             };
0179 
0180             if (initialProperties) {
0181                 pagePool.loadPage(page, initialProperties, callback);
0182 
0183             } else {
0184                 pagePool.loadPage(page, callback);
0185             }
0186         }
0187     }
0188 
0189     // Exposing this as a property is required as Action does not have a default property
0190     property QtObject _private: QtObject {
0191         id: _private
0192 
0193         function setChecked(checked) {
0194             root.checked = checked;
0195         }
0196 
0197         function clearLayers() {
0198             root.pageStack.layers.clear();
0199         }
0200 
0201         property list<Connections> connections: [
0202             Connections {
0203                 target: root.pageStack
0204 
0205                 function onCurrentItemChanged() {
0206                     if (root.useLayers) {
0207                         if (root.layerContainsPage()) {
0208                             _private.clearLayers();
0209                         }
0210                         if (root.checkable) {
0211                             _private.setChecked(false);
0212                         }
0213 
0214                     } else {
0215                         if (root.checkable) {
0216                             _private.setChecked(root.stackContainsPage());
0217                         }
0218                     }
0219                 }
0220             },
0221             Connections {
0222                 enabled: root.pageStack.hasOwnProperty("layers")
0223                 target: root.pageStack.layers
0224 
0225                 function onCurrentItemChanged() {
0226                     if (root.useLayers && root.checkable) {
0227                         _private.setChecked(root.layerContainsPage());
0228 
0229                     } else {
0230                         if (root.pageStack.layers.depth === 1 && root.stackContainsPage()) {
0231                             _private.setChecked(true);
0232                         }
0233                     }
0234                 }
0235             }
0236         ]
0237     }
0238 }