Warning, /plasma/discover/discover/qml/ApplicationsListPage.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.5 0008 import QtQuick.Controls 2.3 0009 import QtQuick.Layouts 1.1 0010 import QtQuick.Window 2.2 0011 import "navigation.js" as Navigation 0012 import org.kde.discover.app 1.0 0013 import org.kde.discover 2.0 0014 import org.kde.kirigami 2.14 as Kirigami 0015 0016 DiscoverPage { 0017 id: page 0018 readonly property var model: appsModel 0019 property alias category: appsModel.filteredCategory 0020 property alias sortRole: appsModel.sortRole 0021 property alias sortOrder: appsModel.sortOrder 0022 property alias originFilter: appsModel.originFilter 0023 property alias mimeTypeFilter: appsModel.mimeTypeFilter 0024 property alias stateFilter: appsModel.stateFilter 0025 property alias extending: appsModel.extending 0026 property alias search: appsModel.search 0027 property alias resourcesUrl: appsModel.resourcesUrl 0028 property alias isBusy: appsModel.isBusy 0029 property alias allBackends: appsModel.allBackends 0030 property alias count: apps.count 0031 property alias listHeader: apps.header 0032 property alias listHeaderPositioning: apps.headerPositioning 0033 property string sortProperty: "appsListPageSorting" 0034 property bool compact: page.width < Kirigami.Units.gridUnit * 28 || !applicationWindow().wideScreen 0035 property bool showRating: true 0036 property bool showSize: false 0037 property bool searchPage: false 0038 0039 property bool canNavigate: true 0040 readonly property alias subcategories: appsModel.subcategories 0041 0042 function stripHtml(input) { 0043 var regex = /(<([^>]+)>)/ig 0044 return input.replace(regex, ""); 0045 } 0046 0047 property string name: category ? category.name : "" 0048 title: { 0049 const count = appsModel.count; 0050 if (search.length > 0) { 0051 if (count.valid) { 0052 return i18np("Search: %2 - %3 item", "Search: %2 - %3 items", count.number, stripHtml(search), count.string) 0053 } else { 0054 return i18n("Search: %1", stripHtml(search)) 0055 } 0056 } else if (name.length > 0) { 0057 if (count.valid) { 0058 return i18np("%2 - %1 item", "%2 - %1 items", count.number, name) 0059 } else { 0060 return name 0061 } 0062 } else { 0063 if (count.valid) { 0064 return i18np("Search - %1 item", "Search - %1 items", count.number) 0065 } else { 0066 return i18n("Search") 0067 } 0068 } 0069 } 0070 0071 signal clearSearch() 0072 0073 supportsRefreshing: true 0074 onRefreshingChanged: if (refreshing) { 0075 appsModel.invalidateFilter() 0076 refreshing = false 0077 } 0078 0079 ActionGroup { 0080 id: sortGroup 0081 exclusive: true 0082 } 0083 0084 contextualActions: [ 0085 Kirigami.Action { 0086 visible: !appsModel.sortByRelevancy 0087 text: i18n("Sort: %1", sortGroup.checkedAction.text) 0088 Action { 0089 ActionGroup.group: sortGroup 0090 text: i18n("Name") 0091 onTriggered: { 0092 DiscoverSettings[page.sortProperty] = ResourcesProxyModel.NameRole 0093 } 0094 checkable: true 0095 checked: appsModel.sortRole === ResourcesProxyModel.NameRole 0096 } 0097 Action { 0098 ActionGroup.group: sortGroup 0099 text: i18n("Rating") 0100 onTriggered: { 0101 DiscoverSettings[page.sortProperty] = ResourcesProxyModel.SortableRatingRole 0102 } 0103 checkable: true 0104 checked: appsModel.sortRole === ResourcesProxyModel.SortableRatingRole 0105 } 0106 Action { 0107 ActionGroup.group: sortGroup 0108 text: i18n("Size") 0109 onTriggered: { 0110 DiscoverSettings[page.sortProperty] = ResourcesProxyModel.SizeRole 0111 } 0112 checkable: true 0113 checked: appsModel.sortRole === ResourcesProxyModel.SizeRole 0114 } 0115 Action { 0116 ActionGroup.group: sortGroup 0117 text: i18n("Release Date") 0118 onTriggered: { 0119 DiscoverSettings[page.sortProperty] = ResourcesProxyModel.ReleaseDateRole 0120 } 0121 checkable: true 0122 checked: appsModel.sortRole === ResourcesProxyModel.ReleaseDateRole 0123 } 0124 } 0125 ] 0126 0127 Kirigami.CardsListView { 0128 id: apps 0129 activeFocusOnTab: true 0130 currentIndex: -1 0131 onActiveFocusChanged: if (activeFocus && currentIndex === -1) { 0132 currentIndex = 0; 0133 } 0134 0135 section.delegate: Label { 0136 text: section 0137 anchors { 0138 right: parent.right 0139 } 0140 } 0141 0142 model: ResourcesProxyModel { 0143 id: appsModel 0144 sortRole: DiscoverSettings.appsListPageSorting 0145 sortOrder: sortRole === ResourcesProxyModel.NameRole ? Qt.AscendingOrder : Qt.DescendingOrder 0146 0147 onBusyChanged: if (isBusy) { 0148 apps.currentIndex = -1 0149 } 0150 } 0151 delegate: ApplicationDelegate { 0152 application: model.application 0153 compact: !applicationWindow().wideScreen 0154 showRating: page.showRating 0155 showSize: page.showSize 0156 } 0157 0158 Item { 0159 readonly property bool nothingFound: apps.count == 0 && !appsModel.isBusy && !ResourcesModel.isInitializing && (!page.searchPage || appsModel.search.length > 0) 0160 0161 anchors.fill: parent 0162 opacity: nothingFound ? 1 : 0 0163 visible: opacity > 0 0164 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad } } 0165 0166 Kirigami.PlaceholderMessage { 0167 visible: !searchedForThingNotFound.visible 0168 anchors.centerIn: visible ? parent : undefined 0169 width: parent.width - (Kirigami.Units.largeSpacing * 8) 0170 0171 icon.name: "edit-none" 0172 text: i18n("Nothing found") 0173 } 0174 0175 Kirigami.PlaceholderMessage { 0176 id: searchedForThingNotFound 0177 0178 property var searchAllCategoriesAction: Kirigami.Action { 0179 text: i18nc("@action:button", "Search in All Categories") 0180 icon.name: "search" 0181 onTriggered: { 0182 window.globalDrawer.resetMenu(); 0183 Navigation.clearStack() 0184 Navigation.openApplicationList( { search: page.search } ); 0185 } 0186 } 0187 property var searchTheWebAction: Kirigami.Action { 0188 text: i18nc("@action:button %1 is the name of an application", "Search the Web for \"%1\"", appsModel.search) 0189 icon.name: "internet-web-browser" 0190 onTriggered: { 0191 const searchTerm = encodeURIComponent("Linux " + appsModel.search); 0192 Qt.openUrlExternally(i18nc("If appropriate, localize this URL to be something more relevant to the language. %1 is the text that will be searched for.", "https://duckduckgo.com/?q=%1", searchTerm)); 0193 } 0194 } 0195 0196 anchors.centerIn: parent 0197 width: parent.width - (Kirigami.Units.largeSpacing * 8) 0198 0199 visible: appsModel.search.length > 0 && stateFilter !== AbstractResource.Installed 0200 0201 icon.name: "edit-none" 0202 text: page.category ? i18nc("@info:placeholder %1 is the name of an application; %2 is the name of a category of apps or add-ons", 0203 "\"%1\" was not found in the \"%2\" category", appsModel.search, page.category.name) 0204 : i18nc("@info:placeholder %1 is the name of an application", 0205 "\"%1\" was not found in the available sources", appsModel.search) 0206 explanation: page.category ? "" : i18nc("@info:placeholder%1 is the name of an application", "\"%1\" may be available on the web. Software acquired from the web has not been reviewed by your distributor for functionality or stability. Use with caution.", appsModel.search) 0207 0208 // If we're in a category, first direct the user to search globally, 0209 // because they might not have realized they were in a category and 0210 // therefore the results were limited to just what was in the category 0211 helpfulAction: page.category ? searchAllCategoriesAction : searchTheWebAction 0212 } 0213 } 0214 0215 Kirigami.PlaceholderMessage { 0216 anchors.centerIn: parent 0217 width: parent.width - (Kirigami.Units.largeSpacing * 4) 0218 0219 visible: opacity !== 0 0220 opacity: apps.count == 0 && page.searchPage && appsModel.search.length == 0 ? 1 : 0 0221 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.InOutQuad } } 0222 0223 icon.name: "search" 0224 text: i18n("Search") 0225 } 0226 0227 footer: ColumnLayout { 0228 anchors.horizontalCenter: parent.horizontalCenter 0229 visible: appsModel.isBusy && apps.atYEnd 0230 opacity: visible ? 0.5 : 0 0231 height: visible ? Layout.preferredHeight : 0 0232 0233 Item { 0234 Layout.preferredHeight: Kirigami.Units.gridUnit 0235 } 0236 Kirigami.Heading { 0237 level: 2 0238 Layout.alignment: Qt.AlignCenter 0239 text: i18n("Still looking…") 0240 } 0241 BusyIndicator { 0242 running: parent.visible 0243 Layout.alignment: Qt.AlignCenter 0244 Layout.preferredWidth: Kirigami.Units.gridUnit * 4 0245 Layout.preferredHeight: Kirigami.Units.gridUnit * 4 0246 } 0247 Behavior on opacity { 0248 PropertyAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad } 0249 } 0250 } 0251 } 0252 }