@@ -0,0 +1,389 @@
2+ * This file is part of system-settings
4+ * Copyright (C) 2016 Canonical Ltd.
6+ * Contact: Jonas G. Drange <jonas.drange@canonical.com>
8+ * This program is free software: you can redistribute it and/or modify it
9+ * under the terms of the GNU General Public License version 3, as published
10+ * by the Free Software Foundation.
12+ * This program is distributed in the hope that it will be useful, but
13+ * WITHOUT ANY WARRANTY; without even the implied warranties of
14+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15+ * PURPOSE. See the GNU General Public License for more details.
17+ * You should have received a copy of the GNU General Public License along
18+ * with this program. If not, see <http://www.gnu.org/licenses/>.
23+import QtQuick.Layouts 1.1
24+import Ubuntu.Components 1.3
25+import Ubuntu.Components.ListItems 1.3 as ListItems
26+import Ubuntu.Components.Themes 1.3
27+import Ubuntu.SystemSettings.Update 1.0
32+ property int updateState // This is an Update::State
33+ property int kind // This is an Update::Kind
35+ property string version
36+ property string downloadId
37+ property date updatedAt
38+ property bool launchable: false
40+ property alias name: nameLabel.text
41+ property alias error: errorElementDetail.text
42+ property alias iconUrl: icon.source
43+ property alias progress: progressBar.value
52+ height: layout.height + (divider.visible ? divider.height : 0)
54+ animation: UbuntuNumberAnimation {}
59+ mainSlot: ColumnLayout {
61+ // Width the parent, minus the icon and some padding
62+ width: parent.width - (icon.width + (layout.padding.top * 3))
69+ verticalAlignment: Text.AlignVCenter
70+ elide: Text.ElideMiddle
71+ Layout.fillWidth: true
72+ Layout.fillHeight: true
77+ objectName: "updateButton"
78+ Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
80+ switch (updateState) {
81+ case Update.StateInstalled:
88+ switch(updateState) {
89+ case Update.StateAvailable:
90+ case Update.StateDownloading:
91+ case Update.StateDownloadingAutomatically:
92+ case Update.StateDownloadPaused:
93+ case Update.StateAutomaticDownloadPaused:
94+ case Update.StateInstallPaused:
95+ case Update.StateDownloaded:
96+ case Update.StateFailed:
99+ // Enabled if installed and a click app (can launch).
100+ case Update.StateInstalled:
101+ return kind === Update.KindClick;
103+ case Update.StateInstalling:
104+ case Update.StateInstallingAutomatically:
105+ case Update.StateUnavailable:
106+ case Update.StateInstallFinished:
107+ case Update.StateQueuedForDownload:
108+ case Update.StateUnknown:
114+ switch(updateState) {
115+ case Update.StateUnknown:
116+ case Update.StateUnavailable:
117+ case Update.StateFailed:
118+ return i18n.tr("Retry");
120+ case Update.StateAvailable:
121+ case Update.StateQueuedForDownload:
122+ if (update.kind === Update.KindClick) {
123+ return i18n.tr("Update");
125+ return i18n.tr("Download");
128+ case Update.StateDownloadPaused:
129+ case Update.StateAutomaticDownloadPaused:
130+ case Update.StateInstallPaused:
131+ return i18n.tr("Resume");
133+ case Update.StateDownloading:
134+ case Update.StateDownloadingAutomatically:
135+ case Update.StateInstalling:
136+ case Update.StateInstallingAutomatically:
137+ case Update.StateInstallFinished:
138+ return i18n.tr("Pause");
140+ case Update.StateDownloaded:
141+ if (kind === Update.KindImage) {
142+ return i18n.tr("Install…");
144+ return i18n.tr("Install");
147+ case Update.StateInstalled:
148+ return i18n.tr("Open");
151+ console.error("Unknown update state", updateState);
156+ switch (updateState) {
159+ case Update.StateUnknown:
160+ case Update.StateUnavailable:
161+ case Update.StateFailed:
165+ case Update.StateDownloadPaused:
166+ case Update.StateAutomaticDownloadPaused:
167+ case Update.StateInstallPaused:
171+ case Update.StateAvailable:
172+ if (kind === Update.KindClick) {
179+ case Update.StateDownloaded:
183+ case Update.StateDownloading:
184+ case Update.StateDownloadingAutomatically:
185+ case Update.StateInstalling:
186+ case Update.StateInstallingAutomatically:
190+ case Update.StateInstalled:
196+ } // Name/button RowLayout
199+ spacing: units.gu(2)
203+ objectName: "updateDownloadLabel"
205+ Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
207+ visible: text !== ""
211+ switch (updateState) {
213+ case Update.StateInstalling:
214+ case Update.StateInstallingAutomatically:
215+ case Update.StateInstallPaused:
216+ return i18n.tr("Installing");
218+ case Update.StateInstallPaused:
219+ case Update.StateDownloadPaused:
220+ return i18n.tr("Paused");
222+ case Update.StateQueuedForDownload:
223+ return i18n.tr("Waiting to download");
225+ case Update.StateDownloading:
226+ return i18n.tr("Downloading");
236+ objectName: "updateStatusLabel"
238+ visible: text !== ""
239+ Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
240+ Layout.fillWidth: true
242+ horizontalAlignment: Text.AlignRight
247+ function humanFileSize(bytes, si) {
248+ var thresh = si ? 1000 : 1024;
249+ if(Math.abs(bytes) < thresh) {
250+ return bytes + ' B';
253+ ? ['kB','MB','GB','TB','PB','EB','ZB','YB']
254+ : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
259+ } while(Math.abs(bytes) >= thresh && u < units.length - 1);
260+ return bytes.toFixed(1)+' '+units[u];
263+ switch (updateState) {
264+ case Update.StateAvailable:
265+ return humanFileSize(size, 1000);
267+ case Update.StateDownloading:
268+ case Update.StateDownloadingAutomatically:
269+ case Update.StateDownloadPaused:
270+ case Update.StateAutomaticDownloadPaused:
271+ var down = humanFileSize((size / 100) * progress, 1000);
272+ var left = humanFileSize(size, 1000);
273+ if (progress > 100) {
276+ /* TRANSLATORS: %1 is the human readable amount
277+ of bytes downloaded, and %2 is the total to be
279+ return i18n.tr("%1 of %2").arg(down).arg(left);
282+ case Update.StateDownloaded:
283+ return i18n.tr("Downloaded");
285+ case Update.StateInstallFinished:
286+ return i18n.tr("Installed");
288+ case Update.StateInstalled:
289+ /* TRANSLATORS: %1 is the date at which this
290+ update was applied. */
291+ return i18n.tr("Updated %1").arg(
292+ updatedAt.toLocaleDateString(Qt.locale(), "d MMMM")
299+ /* Seems AlignRight causes a rendering issue that can be
300+ fixed by doing an explicit doLayout. */
301+ Component.onCompleted: doLayout()
307+ objectName: "updateError"
308+ spacing: units.gu(1)
309+ height: childrenRect.height
310+ Layout.fillWidth: true
311+ visible: errorElementDetail.text
314+ id: errorElementTitle
315+ text: i18n.tr("Update failed")
316+ color: UbuntuColors.red
320+ id: errorElementDetail
321+ anchors { left: parent.left; right: parent.right }
323+ wrapMode: Text.WrapAnywhere
329+ objectName: "updateProgressbar"
332+ switch (updateState) {
333+ case Update.StateQueuedForDownload:
334+ case Update.StateDownloading:
335+ case Update.StateDownloadPaused:
336+ case Update.StateInstalling:
337+ case Update.StateInstallPaused:
344+ Layout.maximumHeight: units.gu(0.5)
345+ Layout.fillWidth: true
346+ indeterminate: update.progress < 0 || update.progress > 100
349+ showProgressPercentage: false
352+ animation: UbuntuNumberAnimation {}
355+ } // Layout for the rest of the stuff
358+ SlotsLayout.position: SlotsLayout.Leading;
364+ visible: kind === Update.KindImage && !fallback.visible
365+ anchors.fill: parent
373+ visible: kind !== Update.KindImage && !fallback.visible
374+ anchors.fill: parent
380+ visible: icon.status === Image.Error
381+ source : Qt.resolvedUrl("/usr/share/icons/suru/apps/scalable/ubuntu-logo-symbolic.svg")
382+ anchors.fill: parent