Warning, /frameworks/knewstuff/src/qtquick/qml/Action.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2021 Dan Leinir Turthra Jensen <admin@leinir.dk>
0003     SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 /**
0009  * @brief An action which when triggered will open a NewStuff.Dialog or a NewStuff.Page, depending on settings
0010  *
0011  * This component is equivalent to the old Button component, but functions in more modern applications
0012  *
0013  * The following is a simple example of how to use this Action to show wallpapers from the KDE Store, on a
0014  * system where Plasma has been installed (and consequently the wallpaper knsrc file is available). This also
0015  * shows how to make the action push a page to a pageStack rather than opening a dialog:
0016  *
0017 \code{.qml}
0018 import org.kde.newstuff as NewStuff
0019 
0020 NewStuff.Action {
0021     configFile: "wallpaper.knsrc"
0022     text: i18n("&Get New Wallpapers…")
0023     pageStack: applicationWindow().pageStack
0024     onEntryEvent: function(entry, event) {
0025         if (event === NewStuff.Entry.StatusChangedEvent) {
0026             // A entry was installed, updated or removed
0027         } else if (event === NewStuff.Entry.AdoptedEvent) {
0028             // The "AdoptionCommand" from the knsrc file was run for the given entry.
0029             // This should not require refreshing the data for the model
0030         }
0031     }
0032 }
0033 \endcode
0034  *
0035  * @see NewStuff.Button
0036  * @since 5.81
0037  */
0038 
0039 import QtQuick
0040 import org.kde.kirigami 2 as Kirigami
0041 import org.kde.newstuff as NewStuff
0042 
0043 Kirigami.Action {
0044     id: component
0045 
0046     /*
0047      * The configuration file is not aliased, because then we end up initialising the
0048      * Engine immediately the Action is instantiated, which we want to avoid (as that
0049      * is effectively a phone-home scenario, and causes internet traffic in situations
0050      * where it would not seem likely that there should be any).
0051      * If we want, in the future, to add some status display to the Action (such as "there
0052      * are updates to be had" or somesuch, then we can do this, but until that choice is
0053      * made, let's not)
0054      */
0055     /**
0056      * The configuration file to use for the Page created by this action
0057      */
0058     property string configFile
0059 
0060     /**
0061      * The default view mode of the page spawned by this action. This should be
0062      * set using the NewStuff.Page.ViewMode enum
0063      * @see NewStuff.Page.ViewMode
0064      */
0065     property int viewMode: NewStuff.Page.ViewMode.Preview
0066 
0067     /**
0068      * If this is set, the action will push a NewStuff.Page onto this page stack
0069      * (and request it is made visible if triggered again). If you do not set this
0070      * property, the action will spawn a NewStuff.Dialog instead.
0071      * @note If you are building a KCM, set this to your ```kcm``` object.
0072      */
0073     property QtObject pageStack: null
0074 
0075     /**
0076      * The engine which handles the content in this Action
0077      * This will be null until the action has been triggered the first time
0078      */
0079     readonly property QtObject engine: component._private.engine
0080 
0081     /**
0082      * This forwards the entry changed event from the QtQuick engine
0083      * @see Engine::entryEvent
0084      */
0085     signal entryEvent(var entry, int event);
0086 
0087     /**
0088      * If this is true (default is false), the action will be shown when the Kiosk settings are such
0089      * that Get Hot New Stuff is disallowed (and any other time enabled is set to false).
0090      * Usually you would want to leave this alone, but occasionally you may have a reason to
0091      * leave a action in place that the user is unable to enable.
0092      */
0093     property bool visibleWhenDisabled: false
0094 
0095     /**
0096     * Show the page/dialog (same as activating the action), if allowed by the Kiosk settings
0097     */
0098     function showHotNewStuff() {
0099         component._private.showHotNewStuff();
0100     }
0101 
0102     onTriggered: showHotNewStuff()
0103 
0104     icon.name: "get-hot-new-stuff"
0105     visible: enabled || visibleWhenDisabled
0106     enabled: NewStuff.Settings.allowedByKiosk
0107     onEnabledChanged: {
0108         // If the user resets this when kiosk has disallowed ghns, force enabled back to false
0109         if (enabled && !NewStuff.Settings.allowedByKiosk) {
0110             enabled = false;
0111         }
0112     }
0113 
0114     readonly property QtObject _private: QtObject {
0115         property QtObject engine: pageItem ? pageItem.engine : null
0116         // Probably wants to be deleted and cleared if the "mode" changes at runtime...
0117         property QtObject pageItem
0118 
0119         property string providerId
0120         property string entryId
0121 
0122         readonly property Connections showSpecificEntryConnection: Connections {
0123             target: component.engine
0124 
0125             function onInitialized() {
0126                 pageItem.showEntryDetails(providerId, component._private.entryId);
0127             }
0128         }
0129 
0130         readonly property Connections engineConnections: Connections {
0131             target: component.engine
0132 
0133             function onEntryEvent(entry, event) {
0134                 component.entryEvent(entry, event);
0135             }
0136         }
0137 
0138         function showHotNewStuff() {
0139             if (NewStuff.Settings.allowedByKiosk) {
0140                 if (component.pageStack !== null) {
0141                     if (component._private.pageItem // If we already have a page created...
0142                         && (component.pageStack.columnView !== undefined // first make sure that this pagestack is a Kirigami-style one (otherwise just assume we're ok)
0143                             && component.pageStack.columnView.contains(component._private.pageItem))) // and then check if the page is still in the stack before attempting to...
0144                     {
0145                         // ...set the already existing page as the current page
0146                         component.pageStack.currentItem = component._private.pageItem;
0147                     } else {
0148                         component._private.pageItem = newStuffPage.createObject(component);
0149                         component.pageStack.push(component._private.pageItem);
0150                     }
0151                 } else {
0152                     newStuffDialog.open();
0153                 }
0154             } else {
0155                 // make some noise, because silently doing nothing is a bit annoying
0156             }
0157         }
0158 
0159         property Component newStuffPage: Component {
0160             NewStuff.Page {
0161                 configFile: component.configFile
0162                 viewMode: component.viewMode
0163             }
0164         }
0165 
0166         property Item newStuffDialog: Loader {
0167             // Use this function to open the dialog. It seems roundabout, but this ensures
0168             // that the dialog is not constructed until we want it to be shown the first time,
0169             // since it will initialise itself on the first load (which causes it to phone
0170             // home) and we don't want that until the user explicitly asks for it.
0171             function open() {
0172                 if (item) {
0173                     item.open();
0174                 } else {
0175                     active = true;
0176                 }
0177             }
0178 
0179             onLoaded: {
0180                 component._private.pageItem = item;
0181                 item.open();
0182             }
0183 
0184             active: false
0185             asynchronous: true
0186 
0187             sourceComponent: NewStuff.Dialog {
0188                 configFile: component.configFile
0189                 viewMode: component.viewMode
0190             }
0191         }
0192     }
0193 }