diff --git a/discover/qml/UpdatesPage.qml b/discover/qml/UpdatesPage.qml index d078d7c3..be03e15f 100644 --- a/discover/qml/UpdatesPage.qml +++ b/discover/qml/UpdatesPage.qml @@ -1,348 +1,348 @@ import QtQuick.Controls 2.3 import QtQuick.Layouts 1.1 import QtQuick 2.4 import org.kde.discover 2.0 import org.kde.discover.app 1.0 import "navigation.js" as Navigation import org.kde.kirigami 2.3 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 && !ResourcesModel.isFetching onTriggered: resourcesUpdatesModel.updateAll() } footer: ScrollView { id: scv width: parent.width height: visible ? Kirigami.Units.gridUnit * 10 : 0 visible: log.contents.length > 0 TextArea { readOnly: true text: log.contents cursorPosition: text.length - 1 font.family: "monospace" ReadFile { id: log filter: ".*ALPM-SCRIPTLET\\] .*" path: "/var/log/pacman.log" } } } 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 { left: refreshAction main: currentAction } header: ToolBar { Kirigami.Theme.colorSet: Kirigami.Theme.Button Kirigami.Theme.inherit: false visible: (updateModel.totalUpdatesCount > 0 && resourcesUpdatesModel.isProgressing) || updateModel.hasUpdates RowLayout { anchors.fill: parent enabled: page.currentAction.enabled CheckBox { Layout.leftMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing enabled: !resourcesUpdatesModel.isProgressing && !ResourcesModel.isFetching tristate: true checkState: updateModel.toUpdateCount === 0 ? Qt.Unchecked : updateModel.toUpdateCount === updateModel.totalUpdatesCount ? Qt.Checked : Qt.PartiallyChecked onClicked: { if (updateModel.toUpdateCount === 0) updateModel.checkAll() else updateModel.uncheckAll() } } Label { Layout.fillWidth: true text: page.unselected === 0 ? i18n("All updates selected (%1)", updateModel.updateSize) : i18np("%1/%2 update selected (%3)", "%1/%2 updates selected (%3)", updateModel.toUpdateCount, updateModel.totalUpdatesCount, updateModel.updateSize) elide: Text.ElideRight } } } supportsRefreshing: true onRefreshingChanged: { showPassiveNotification("Fetching updates...") ResourcesModel.updateAction.triggered() refreshing = false } ListView { id: updatesView currentIndex: -1 displaced: Transition { YAnimator { duration: Kirigami.Units.longDuration easing.type: Easing.InOutQuad } } 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: Kirigami.Units.gridUnit * 12 height: width } Item { visible: page.footerLabel === "" height: Kirigami.Units.gridUnit width: 1 } } model: QSortFilterProxyModel { sourceModel: updateModel sortRole: UpdateModel.SectionResourceProgressRole } section { property: "section" delegate: Kirigami.Heading { x: Kirigami.Units.gridUnit level: 2 text: section height: implicitHeight + Kirigami.Units.largeSpacing * 2 } } delegate: Kirigami.AbstractListItem { backgroundColor: Kirigami.Theme.backgroundColor 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.fetchUpdateDetails(index) } RowLayout { Layout.fillWidth: true Layout.fillHeight: true CheckBox { id: itemChecked Layout.leftMargin: Kirigami.Units.gridUnit Layout.alignment: Qt.AlignVCenter checked: model.checked === Qt.Checked onClicked: model.checked = (model.checked===Qt.Checked ? Qt.Unchecked : Qt.Checked) enabled: !resourcesUpdatesModel.isProgressing } Kirigami.Icon { width: Kirigami.Units.gridUnit * 2 Layout.preferredHeight: width source: decoration smooth: true } ColumnLayout { // App name Kirigami.Heading { Layout.fillWidth: true text: i18n("%1", display) level: 3 elide: Text.ElideRight } // Old and new version numbers; show when there's enough room Label { id: oldAndNewVersions Layout.fillWidth: true elide: Text.ElideRight text: i18n("%1 → %2", installedVersion, availableVersion) visible: !truncated } // Available version only, for when old+new would be elided. // Use squeezey text to gain more room, and if it's still so // so long that it would be elided, elide from the left so // the most important part on the right is still visible // All of this is mostly for the benefit of KDE Neon users, // since the version strings there are really really long Label { Layout.fillWidth: true elide: Text.ElideLeft text: availableVersion visible: !oldAndNewVersions.visible font.letterSpacing: -0.5 } } LabelBackground { Layout.minimumWidth: Kirigami.Units.gridUnit * 6 text: size progress: resourceProgress/100 } } Frame { Layout.fillWidth: true implicitHeight: view.contentHeight visible: layout.extended && changelog.length>0 LinkLabel { id: view anchors { right: parent.right left: parent.left } text: changelog textFormat: Text.StyledText wrapMode: Text.WordWrap onLinkActivated: Qt.openUrlExternally(link) } //This saves a binding loop on implictHeight, as the Label //height is updated twice (first time with the wrong value) Behavior on implicitHeight { PropertyAnimation { duration: Kirigami.Units.shortDuration } } } 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" : resourcesUpdatesModel.isProgressing ? "progressing" : ResourcesModel.isFetching ? "fetching" : resourcesUpdatesModel.needsReboot ? "reboot" : 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", "Checking 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: "reboot" - PropertyChanges { target: page; title: i18nc("@info", "The system requires a reboot") } - PropertyChanges { target: page; footerLabel: i18nc("@info", "Reboot") } + PropertyChanges { target: page; title: i18nc("@info", "The system requires a restart") } + PropertyChanges { target: page; footerLabel: i18nc("@info", "Restart") } }, 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") } } ] } diff --git a/libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp b/libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp index 01e6d231..9bd199cd 100644 --- a/libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp +++ b/libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp @@ -1,333 +1,333 @@ /*************************************************************************** * Copyright © 2012-2014 Aleix Pol Gonzalez * * Copyright © 2013 Lukas Appelhans * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * 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 General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "PackageKitMessages.h" #include #include #include namespace PackageKitMessages { QString errorMessage(PackageKit::Transaction::Error error) { switch(error) { case PackageKit::Transaction::ErrorOom: return i18n("Out of memory"); case PackageKit::Transaction::ErrorNoNetwork: return i18n("No network connection available"); case PackageKit::Transaction::ErrorNotSupported: return i18n("Operation not supported"); case PackageKit::Transaction::ErrorInternalError: return i18n("Internal error"); case PackageKit::Transaction::ErrorGpgFailure: return i18n("GPG failure"); case PackageKit::Transaction::ErrorPackageIdInvalid: return i18n("PackageID invalid"); case PackageKit::Transaction::ErrorPackageNotInstalled: return i18n("Package not installed"); case PackageKit::Transaction::ErrorPackageNotFound: return i18n("Package not found"); case PackageKit::Transaction::ErrorPackageAlreadyInstalled: return i18n("Package is already installed"); case PackageKit::Transaction::ErrorPackageDownloadFailed: return i18n("Package download failed"); case PackageKit::Transaction::ErrorGroupNotFound: return i18n("Package group not found"); case PackageKit::Transaction::ErrorGroupListInvalid: return i18n("Package group list invalid"); case PackageKit::Transaction::ErrorDepResolutionFailed: return i18n("Dependency resolution failed"); case PackageKit::Transaction::ErrorFilterInvalid: return i18n("Filter invalid"); case PackageKit::Transaction::ErrorCreateThreadFailed: return i18n("Failed while creating a thread"); case PackageKit::Transaction::ErrorTransactionError: return i18n("Transaction failure"); case PackageKit::Transaction::ErrorTransactionCancelled: return i18n("Transaction canceled"); case PackageKit::Transaction::ErrorNoCache: return i18n("No Cache available"); case PackageKit::Transaction::ErrorRepoNotFound: return i18n("Cannot find repository"); case PackageKit::Transaction::ErrorCannotRemoveSystemPackage: return i18n("Cannot remove system package"); case PackageKit::Transaction::ErrorProcessKill: return i18n("The PackageKit daemon has crashed"); case PackageKit::Transaction::ErrorFailedInitialization: return i18n("Initialization failure"); case PackageKit::Transaction::ErrorFailedFinalise: return i18n("Failed to finalize transaction"); case PackageKit::Transaction::ErrorFailedConfigParsing: return i18n("Config parsing failed"); case PackageKit::Transaction::ErrorCannotCancel: return i18n("Cannot cancel transaction"); case PackageKit::Transaction::ErrorCannotGetLock: return i18n("Cannot obtain lock"); case PackageKit::Transaction::ErrorNoPackagesToUpdate: return i18n("No packages to update"); case PackageKit::Transaction::ErrorCannotWriteRepoConfig: return i18n("Cannot write repo config"); case PackageKit::Transaction::ErrorLocalInstallFailed: return i18n("Local install failed"); case PackageKit::Transaction::ErrorBadGpgSignature: return i18n("Bad GPG signature found"); case PackageKit::Transaction::ErrorMissingGpgSignature: return i18n("No GPG signature found"); case PackageKit::Transaction::ErrorCannotInstallSourcePackage: return i18n("Cannot install source package"); case PackageKit::Transaction::ErrorRepoConfigurationError: return i18n("Repo configuration error"); case PackageKit::Transaction::ErrorNoLicenseAgreement: return i18n("No license agreement"); case PackageKit::Transaction::ErrorFileConflicts: return i18n("File conflicts found"); case PackageKit::Transaction::ErrorPackageConflicts: return i18n("Package conflict found"); case PackageKit::Transaction::ErrorRepoNotAvailable: return i18n("Repo not available"); case PackageKit::Transaction::ErrorInvalidPackageFile: return i18n("Invalid package file"); case PackageKit::Transaction::ErrorPackageInstallBlocked: return i18n("Package install blocked"); case PackageKit::Transaction::ErrorPackageCorrupt: return i18n("Corrupt package found"); case PackageKit::Transaction::ErrorAllPackagesAlreadyInstalled: return i18n("All packages already installed"); case PackageKit::Transaction::ErrorFileNotFound: return i18n("File not found"); case PackageKit::Transaction::ErrorNoMoreMirrorsToTry: return i18n("No more mirrors available"); case PackageKit::Transaction::ErrorNoDistroUpgradeData: return i18n("No distro upgrade data"); case PackageKit::Transaction::ErrorIncompatibleArchitecture: return i18n("Incompatible architecture"); case PackageKit::Transaction::ErrorNoSpaceOnDevice: return i18n("No space on device left"); case PackageKit::Transaction::ErrorMediaChangeRequired: return i18n("A media change is required"); case PackageKit::Transaction::ErrorNotAuthorized: return i18n("You have no authorization to execute this operation"); case PackageKit::Transaction::ErrorUpdateNotFound: return i18n("Update not found"); case PackageKit::Transaction::ErrorCannotInstallRepoUnsigned: return i18n("Cannot install from unsigned repo"); case PackageKit::Transaction::ErrorCannotUpdateRepoUnsigned: return i18n("Cannot update from unsigned repo"); case PackageKit::Transaction::ErrorCannotGetFilelist: return i18n("Cannot get file list"); case PackageKit::Transaction::ErrorCannotGetRequires: return i18n("Cannot get requires"); case PackageKit::Transaction::ErrorCannotDisableRepository: return i18n("Cannot disable repository"); case PackageKit::Transaction::ErrorRestrictedDownload: return i18n("Restricted download detected"); case PackageKit::Transaction::ErrorPackageFailedToConfigure: return i18n("Package failed to configure"); case PackageKit::Transaction::ErrorPackageFailedToBuild: return i18n("Package failed to build"); case PackageKit::Transaction::ErrorPackageFailedToInstall: return i18n("Package failed to install"); case PackageKit::Transaction::ErrorPackageFailedToRemove: return i18n("Package failed to remove"); case PackageKit::Transaction::ErrorUpdateFailedDueToRunningProcess: return i18n("Update failed due to running process"); case PackageKit::Transaction::ErrorPackageDatabaseChanged: return i18n("The package database changed"); case PackageKit::Transaction::ErrorProvideTypeNotSupported: return i18n("The provided type is not supported"); case PackageKit::Transaction::ErrorInstallRootInvalid: return i18n("Install root is invalid"); case PackageKit::Transaction::ErrorCannotFetchSources: return i18nc("Failed to sync your Linux distro repositories or other sources of packages", "Cannot fetch sources"); case PackageKit::Transaction::ErrorCancelledPriority: return i18n("Canceled priority"); case PackageKit::Transaction::ErrorUnfinishedTransaction: return i18n("Unfinished transaction"); case PackageKit::Transaction::ErrorLockRequired: return i18n("Lock required"); case PackageKit::Transaction::ErrorUnknown: default: { int idx = PackageKit::Transaction::staticMetaObject.indexOfEnumerator("Error"); QMetaEnum metaenum = PackageKit::Transaction::staticMetaObject.enumerator(idx); return i18n("Unknown error %1.", QString::fromLatin1(metaenum.valueToKey(error))); } } } QString restartMessage(PackageKit::Transaction::Restart restart, const QString& pkgid) { switch (restart) { case PackageKit::Transaction::RestartApplication: return i18n("'%1' was changed and suggests to be restarted.", PackageKit::Daemon::packageName(pkgid)); case PackageKit::Transaction::RestartSession: return i18n("A change by '%1' suggests your session to be restarted.", PackageKit::Daemon::packageName(pkgid)); case PackageKit::Transaction::RestartSecuritySession: return i18n("'%1' was updated for security reasons, a restart of the session is recommended.", PackageKit::Daemon::packageName(pkgid)); case PackageKit::Transaction::RestartSecuritySystem: return i18n("'%1' was updated for security reasons, a restart of the system is recommended.", PackageKit::Daemon::packageName(pkgid)); case PackageKit::Transaction::RestartSystem: case PackageKit::Transaction::RestartUnknown: case PackageKit::Transaction::RestartNone: default: - return i18n("A change by '%1' suggests your system to be rebooted.", PackageKit::Daemon::packageName(pkgid)); + return i18n("A change by '%1' suggests your system to be restarted.", PackageKit::Daemon::packageName(pkgid)); } } QString restartMessage(PackageKit::Transaction::Restart restart) { switch (restart) { case PackageKit::Transaction::RestartApplication: return i18n("The application will have to be restarted."); case PackageKit::Transaction::RestartSession: return i18n("The session will have to be restarted"); case PackageKit::Transaction::RestartSystem: - return i18n("The system will have to be rebooted."); + return i18n("The system will have to be restarted."); case PackageKit::Transaction::RestartSecuritySession: return i18n("For security, the session will have to be restarted."); case PackageKit::Transaction::RestartSecuritySystem: return i18n("For security, the system will have to be restarted."); case PackageKit::Transaction::RestartUnknown: case PackageKit::Transaction::RestartNone: default: return QString(); } } QString statusMessage(PackageKit::Transaction::Status status) { switch (status) { case PackageKit::Transaction::StatusWait: return i18n("Waiting..."); case PackageKit::Transaction::StatusRefreshCache: return i18n("Refreshing Cache..."); case PackageKit::Transaction::StatusSetup: return i18n("Setup..."); case PackageKit::Transaction::StatusRunning: return i18n("Processing..."); case PackageKit::Transaction::StatusRemove: return i18n("Remove..."); case PackageKit::Transaction::StatusDownload: return i18n("Downloading..."); case PackageKit::Transaction::StatusInstall: return i18n("Installing..."); case PackageKit::Transaction::StatusUpdate: return i18n("Updating..."); case PackageKit::Transaction::StatusCleanup: return i18n("Cleaning up..."); // case PackageKit::Transaction::StatusObsolete: case PackageKit::Transaction::StatusDepResolve: return i18n("Resolving dependencies..."); case PackageKit::Transaction::StatusSigCheck: return i18n("Checking signatures..."); case PackageKit::Transaction::StatusTestCommit: return i18n("Test committing..."); case PackageKit::Transaction::StatusCommit: return i18n("Committing..."); //StatusRequest, case PackageKit::Transaction::StatusFinished: return i18n("Finished"); case PackageKit::Transaction::StatusCancel: return i18n("Canceled"); case PackageKit::Transaction::StatusWaitingForLock: return i18n("Waiting for lock..."); case PackageKit::Transaction::StatusWaitingForAuth: return i18n("Waiting for authorization..."); //StatusScanProcessList, //StatusCheckExecutableFiles, //StatusCheckLibraries, case PackageKit::Transaction::StatusCopyFiles: return i18n("Copying files..."); case PackageKit::Transaction::StatusUnknown: default: return i18n("Unknown Status"); } } QString statusDetail(PackageKit::Transaction::Status status) { switch (status) { case PackageKit::Transaction::StatusWait: return i18n("We are waiting for something."); case PackageKit::Transaction::StatusSetup: return i18n("Setting up transaction..."); case PackageKit::Transaction::StatusRunning: return i18n("The transaction is currently working..."); case PackageKit::Transaction::StatusRemove: return i18n("The transaction is currently removing packages..."); case PackageKit::Transaction::StatusDownload: return i18n("The transaction is currently downloading packages..."); case PackageKit::Transaction::StatusInstall: return i18n("The transactions is currently installing packages..."); case PackageKit::Transaction::StatusUpdate: return i18n("The transaction is currently updating packages..."); case PackageKit::Transaction::StatusCleanup: return i18n("The transaction is currently cleaning up..."); //case PackageKit::Transaction::StatusObsolete, case PackageKit::Transaction::StatusDepResolve: return i18n("The transaction is currently resolving the dependencies of the packages it will install..."); case PackageKit::Transaction::StatusSigCheck: return i18n("The transaction is currently checking the signatures of the packages..."); case PackageKit::Transaction::StatusTestCommit: return i18n("The transaction is currently testing the commit of this set of packages..."); case PackageKit::Transaction::StatusCommit: return i18n("The transaction is currently committing its set of packages..."); //StatusRequest, case PackageKit::Transaction::StatusFinished: return i18n("The transaction has finished!"); case PackageKit::Transaction::StatusCancel: return i18n("The transaction was canceled"); case PackageKit::Transaction::StatusWaitingForLock: return i18n("The transaction is currently waiting for the lock..."); case PackageKit::Transaction::StatusWaitingForAuth: return i18n("Waiting for the user to authorize the transaction..."); //StatusScanProcessList, //StatusCheckExecutableFiles, //StatusCheckLibraries, case PackageKit::Transaction::StatusCopyFiles: return i18n("The transaction is currently copying files..."); case PackageKit::Transaction::StatusRefreshCache: return i18n("Currently refreshing the repository cache..."); case PackageKit::Transaction::StatusUnknown: default: { int idx = PackageKit::Transaction::staticMetaObject.indexOfEnumerator("Status"); QMetaEnum metaenum = PackageKit::Transaction::staticMetaObject.enumerator(idx); return i18n("Unknown status %1.", QString::fromLatin1(metaenum.valueToKey(status))); } } } QString updateStateMessage(PackageKit::Transaction::UpdateState state) { switch(state) { case PackageKit::Transaction::UpdateStateUnknown: return QString(); case PackageKit::Transaction::UpdateStateStable: return i18nc("update state", "Stable"); case PackageKit::Transaction::UpdateStateUnstable: return i18nc("update state", "Unstable"); case PackageKit::Transaction::UpdateStateTesting: return i18nc("update state", "Testing"); } return QString(); } }