diff --git a/discover/qml/ApplicationsListPage.qml b/discover/qml/ApplicationsListPage.qml index 7fb6aa46..15e787f8 100644 --- a/discover/qml/ApplicationsListPage.qml +++ b/discover/qml/ApplicationsListPage.qml @@ -1,159 +1,164 @@ /* * Copyright (C) 2012 Aleix Pol Gonzalez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library/Lesser General Public License * version 2, or (at your option) any later version, as published by the * Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library/Lesser General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.5 import QtQuick.Controls 1.1 import QtQuick.Controls 2.1 as QQC2 import QtQuick.Layouts 1.1 import QtQuick.Window 2.2 import "navigation.js" as Navigation import org.kde.discover.app 1.0 import org.kde.discover 2.0 import org.kde.kirigami 2.0 as Kirigami DiscoverPage { id: page readonly property var model: appsModel property alias category: appsModel.filteredCategory property alias sortRole: appsModel.sortRole property alias sortOrder: appsModel.sortOrder property alias originFilter: appsModel.originFilter property alias mimeTypeFilter: appsModel.mimeTypeFilter property alias stateFilter: appsModel.stateFilter property alias extending: appsModel.extending property alias search: appsModel.search property alias resourcesUrl: appsModel.resourcesUrl property alias isBusy: appsModel.isBusy property alias allBackends: appsModel.allBackends property alias count: apps.count property alias listHeader: apps.header property Component listHeaderExtra property bool compact: page.width < 500 || !applicationWindow().wideScreen property bool canNavigate: true readonly property alias subcategories: appsModel.subcategories title: category ? category.name : "" onSearchChanged: { appsModel.sortOrder = Qt.AscendingOrder } signal clearSearch() + supportsRefreshing: true + onRefreshingChanged: if (refreshing) { + appsModel.invalidateFilter() + refreshing = false + } ListView { id: apps section.delegate: QQC2.Label { text: section anchors { right: parent.right } } headerPositioning: ListView.OverlayHeader header: CategoryDisplay { id: header category: appsModel.filteredCategory search: appsModel.search extra: page.listHeaderExtra } model: ResourcesProxyModel { id: appsModel sortRole: ResourcesProxyModel.RatingCountRole sortOrder: Qt.DescendingOrder } spacing: Kirigami.Units.gridUnit currentIndex: -1 delegate: ApplicationDelegate { x: Kirigami.Units.gridUnit width: ListView.view.width - Kirigami.Units.gridUnit*2 application: model.application compact: page.compact } QQC2.Label { anchors.centerIn: parent opacity: apps.count == 0 && !appsModel.isBusy ? 0.3 : 0 Behavior on opacity { PropertyAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad; } } text: i18n("Sorry, nothing found...") } BusyIndicator { id: busyIndicator anchors { top: parent.bottom horizontalCenter: parent.horizontalCenter margins: Kirigami.Units.largeSpacing } running: false opacity: 0 states: [ State { name: "running"; when: appsModel.isBusy PropertyChanges { target: busyIndicator; opacity: 1; running: true; } AnchorChanges { target: busyIndicator; anchors.bottom: parent.bottom; anchors.top: undefined; } } ] transitions: [ Transition { from: "" to: "running" SequentialAnimation { PauseAnimation { duration: Kirigami.Units.longDuration * 5; } ParallelAnimation { AnchorAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad; } PropertyAnimation { property: "opacity"; duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad; } } } }, Transition { from: "running" to: "" ParallelAnimation { AnchorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.InOutQuad; } PropertyAnimation { property: "opacity"; duration: Kirigami.Units.shortDuration; easing.type: Easing.InOutQuad; } } } ] QQC2.Label { id: busyLabel anchors { horizontalCenter: parent.horizontalCenter bottom: parent.top } text: i18n("Still looking...") opacity: 0 states: [ State { name: "running"; when: busyIndicator.opacity === 1; PropertyChanges { target: busyLabel; opacity: 1; } } ] transitions: Transition { from: "" to: "running" SequentialAnimation { PauseAnimation { duration: Kirigami.Units.longDuration * 5; } PropertyAnimation { property: "opacity"; duration: Kirigami.Units.longDuration * 10; easing.type: Easing.InOutCubic; } } } } } } } diff --git a/discover/qml/UpdatesPage.qml b/discover/qml/UpdatesPage.qml index 65b6854e..0cab35e6 100644 --- a/discover/qml/UpdatesPage.qml +++ b/discover/qml/UpdatesPage.qml @@ -1,280 +1,281 @@ import QtQuick.Controls 1.2 import QtQuick.Controls 2.1 as QQC2 import QtQuick.Layouts 1.1 import QtQuick 2.4 import org.kde.discover 2.0 import org.kde.discover.app 1.0 import org.kde.kquickcontrolsaddons 2.0 import org.kde.kcoreaddons 1.0 import "navigation.js" as Navigation import org.kde.kirigami 2.1 as Kirigami DiscoverPage { id: page title: i18n("Updates") property string footerLabel: "" ResourcesUpdatesModel { id: resourcesUpdatesModel onPassiveMessage: window.showPassiveNotification(message) onIsProgressingChanged: { if (!isProgressing) { resourcesUpdatesModel.prepare() } } Component.onCompleted: { if (!isProgressing) { resourcesUpdatesModel.prepare() } } } UpdateModel { id: updateModel backend: resourcesUpdatesModel } Kirigami.Action { id: updateAction text: page.unselected>0 ? i18n("Update Selected") : i18n("Update All") visible: updateModel.toUpdateCount iconName: "update-none" enabled: !resourcesUpdatesModel.isProgressing onTriggered: resourcesUpdatesModel.updateAll() } Kirigami.Action { id: cancelUpdateAction iconName: "dialog-cancel" text: i18n("Cancel") enabled: resourcesUpdatesModel.transaction && resourcesUpdatesModel.transaction.isCancellable onTriggered: resourcesUpdatesModel.transaction.cancel() } readonly property int unselected: (updateModel.totalUpdatesCount - updateModel.toUpdateCount) readonly property QtObject currentAction: resourcesUpdatesModel.isProgressing ? cancelUpdateAction : updateAction actions.main: applicationWindow().wideScreen ? null : currentAction header: QQC2.ToolBar { visible: (updateModel.totalUpdatesCount > 0 && resourcesUpdatesModel.isProgressing) || updateModel.hasUpdates RowLayout { anchors.fill: parent LabelBackground { Layout.leftMargin: Kirigami.Units.gridUnit text: updateModel.toUpdateCount + " (" + updateModel.updateSize+")" } QQC2.Label { text: i18n("updates selected") } LabelBackground { id: unselectedItem text: page.unselected visible: page.unselected>0 } QQC2.Label { text: i18n("updates not selected") visible: unselectedItem.visible } Item { Layout.fillWidth: true } Button { Layout.minimumWidth: Kirigami.Units.gridUnit * 6 Layout.rightMargin: Kirigami.Units.gridUnit text: page.currentAction.text visible: !page.actions.main onClicked: page.currentAction.trigger() } } } supportsRefreshing: true onRefreshingChanged: { showPassiveNotification("Fetching updates...") ResourcesModel.updateAction.triggered() + refreshing = false } ListView { id: updatesView currentIndex: -1 footer: ColumnLayout { anchors.right: parent.right anchors.left: parent.left Kirigami.Heading { Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter horizontalAlignment: Text.AlignHCenter visible: page.footerLabel !== "" text: page.footerLabel } Kirigami.Icon { Layout.alignment: Qt.AlignHCenter visible: page.footerLabel !== "" source: "update-none" opacity: 0.3 width: 200 height: 200 } Item { visible: page.footerLabel === "" height: Kirigami.Units.gridUnit width: 1 } } model: updateModel section { property: "section" delegate: Kirigami.Heading { x: Kirigami.Units.gridUnit level: 2 text: section } } spacing: Kirigami.Units.smallSpacing delegate: Kirigami.AbstractListItem { backgroundColor: Kirigami.Theme.viewBackgroundColor x: Kirigami.Units.gridUnit width: ListView.view.width - Kirigami.Units.gridUnit * 2 highlighted: ListView.isCurrentItem onEnabledChanged: if (!enabled) { layout.extended = false; } Keys.onReturnPressed: { itemChecked.clicked() } Keys.onPressed: if (event.key===Qt.Key_Alt) layout.extended = true Keys.onReleased: if (event.key===Qt.Key_Alt) layout.extended = false ColumnLayout { id: layout property bool extended: false onExtendedChanged: if (extended) { updateModel.fetchChangelog(index) } RowLayout { Layout.fillWidth: true Layout.fillHeight: true CheckBox { id: itemChecked anchors.verticalCenter: parent.verticalCenter checked: model.checked == Qt.Checked onClicked: model.checked = (model.checked==Qt.Checked ? Qt.Unchecked : Qt.Checked) } Kirigami.Icon { Layout.fillHeight: true Layout.preferredWidth: height source: decoration } QQC2.Label { Layout.fillWidth: true text: i18n("%1 (%2)", display, version) elide: Text.ElideRight } LabelBackground { Layout.minimumWidth: Kirigami.Units.gridUnit * 6 text: size progress: resourceProgress/100 } } QQC2.Frame { Layout.fillWidth: true Layout.minimumHeight: view.contentHeight visible: layout.extended && changelog.length>0 QQC2.Label { id: view anchors { right: parent.right left: parent.left } text: changelog textFormat: Text.StyledText wrapMode: Text.WordWrap onLinkActivated: Qt.openUrlExternally(link) } } Button { Layout.alignment: Qt.AlignRight text: i18n("More Information...") visible: layout.extended enabled: !resourcesUpdatesModel.isProgressing onClicked: Navigation.openApplication(resource) } } onClicked: { layout.extended = !layout.extended } } } readonly property alias secSinceUpdate: resourcesUpdatesModel.secsToLastUpdate state: ( updateModel.hasUpdates ? "has-updates" : ResourcesModel.isFetching ? "fetching" : resourcesUpdatesModel.isProgressing ? "progressing" : secSinceUpdate < 0 ? "unknown" : secSinceUpdate === 0 ? "now-uptodate" : secSinceUpdate < 1000 * 60 * 60 * 24 ? "uptodate" : secSinceUpdate < 1000 * 60 * 60 * 24 * 7 ? "medium" : "low" ) states: [ State { name: "fetching" PropertyChanges { target: page; title: i18nc("@info", "Fetching...") } PropertyChanges { target: page; footerLabel: i18nc("@info", "Looking for updates") } }, State { name: "progressing" PropertyChanges { target: page; title: i18nc("@info", "Updating...") } PropertyChanges { target: page; footerLabel: resourcesUpdatesModel.progress<=0 ? i18nc("@info", "Fetching updates") : "" } }, State { name: "has-updates" PropertyChanges { target: page; title: i18nc("@info", "Updates") } }, State { name: "now-uptodate" PropertyChanges { target: page; title: i18nc("@info", "The system is up to date") } PropertyChanges { target: page; footerLabel: i18nc("@info", "No updates") } }, State { name: "uptodate" PropertyChanges { target: page; title: i18nc("@info", "The system is up to date") } PropertyChanges { target: page; footerLabel: i18nc("@info", "No updates") } }, State { name: "medium" PropertyChanges { target: page; title: i18nc("@info", "No updates are available") } }, State { name: "low" PropertyChanges { target: page; title: i18nc("@info", "Should check for updates") } }, State { name: "unknown" PropertyChanges { target: page; title: i18nc("@info", "It is unknown when the last check for updates was") } } ] }