diff --git a/MsgPopup.qml b/MsgPopup.qml new file mode 100644 index 0000000..2508ffd --- /dev/null +++ b/MsgPopup.qml @@ -0,0 +1,142 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2020 Raspberry Pi (Trading) Limited + */ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.0 +import QtQuick.Controls.Material 2.2 + +Popup { + id: msgpopup + x: 75 + y: parent.height/2-100 + width: parent.width-150 + height: msgpopupbody.implicitHeight+150 + padding: 0 + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + property alias title: msgpopupheader.text + property alias text: msgpopupbody.text + property bool continueButton: true + property bool yesButton: false + property bool noButton: false + signal yes() + signal no() + + // background of title + Rectangle { + color: "#f5f5f5" + anchors.right: parent.right + anchors.top: parent.top + height: 35 + width: parent.width + } + // line under title + Rectangle { + color: "#afafaf" + width: parent.width + y: 35 + implicitHeight: 1 + } + + Text { + id: msgx + text: "X" + anchors.right: parent.right + anchors.top: parent.top + anchors.rightMargin: 25 + anchors.topMargin: 10 + font.family: roboto.name + font.bold: true + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + msgpopup.close() + } + } + } + + ColumnLayout { + spacing: 20 + anchors.fill: parent + + Text { + id: msgpopupheader + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + Layout.fillWidth: true + Layout.topMargin: 10 + font.family: roboto.name + font.bold: true + } + + Text { + id: msgpopupbody + font.pointSize: 12 + wrapMode: Text.Wrap + textFormat: Text.StyledText + font.family: roboto.name + Layout.maximumWidth: msgpopup.width-50 + Layout.fillHeight: true + Layout.leftMargin: 25 + Layout.topMargin: 25 + Accessible.name: text.replace(/<\/?[^>]+(>|$)/g, "") + } + + RowLayout { + Layout.alignment: Qt.AlignCenter | Qt.AlignBottom + Layout.bottomMargin: 10 + spacing: 20 + + Button { + text: qsTr("NO") + onClicked: { + msgpopup.close() + msgpopup.no() + } + Material.foreground: "#ffffff" + Material.background: "#c51a4a" + font.family: roboto.name + visible: msgpopup.noButton + Accessible.onPressAction: clicked() + } + + Button { + text: qsTr("YES") + onClicked: { + msgpopup.close() + msgpopup.yes() + } + Material.foreground: "#ffffff" + Material.background: "#c51a4a" + font.family: roboto.name + visible: msgpopup.yesButton + Accessible.onPressAction: clicked() + } + + Button { + text: qsTr("CONTINUE") + onClicked: { + msgpopup.close() + } + Material.foreground: "#ffffff" + Material.background: "#c51a4a" + font.family: roboto.name + visible: msgpopup.continueButton + Accessible.onPressAction: clicked() + } + + Text { text: " " } + } + } + + function openPopup() { + open() + // trigger screen reader to speak out message + msgpopupbody.forceActiveFocus() + } +} diff --git a/debian/changelog b/debian/changelog index 01a438f..f9cf56c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +rpi-imager (1.4) unstable; urgency=medium + + * Add basic accessibility support + * Add keyboard navigation support + * Linux: do not let progress exceed 100% if + device reports incorrect write counters + * Show new SD card size if SD card is replaced + * Linux: do not use direct IO on verifying but purge cache with + posix_fadvise() + + -- Floris Bos Tue, 30 Jun 2020 00:29:37 +0200 + rpi-imager (1.3) unstable; urgency=medium * Remove zero sized drives from list diff --git a/i18n/rpi-imager_nl.ts b/i18n/rpi-imager_nl.ts index aba38fe..4cb03d4 100644 --- a/i18n/rpi-imager_nl.ts +++ b/i18n/rpi-imager_nl.ts @@ -48,7 +48,7 @@ Fout bij uitvoeren authopen: '%1' - + Cannot open storage device '%1'. Fout bij openen opslagapparaat '%1'. @@ -65,33 +65,33 @@ Card could be advertising wrong capacity (possible counterfeit) Kaart geeft mogelijk onjuiste capaciteit aan (mogelijk counterfeit) - + Error writing to storage (while flushing) Fout bij schrijven naar opslag (tijdens flushen) - + Error writing to storage (while fsync) Fout bij schrijven naar opslag (tijdens fsync) - + Download corrupt. Hash does not match Download corrupt. Hash komt niet overeen - + Error writing first block (partition table) Fout bij schrijven naar eerste deel van kaart (partitie tabel) - + Error reading from storage. SD card may be broken. Fout bij lezen van SD kaart. Kaart is mogelijk defect. - + Verifying write failed. Contents of SD card is different from what was written to it. Verificatie mislukt. De gegevens die op de SD kaart staan wijken af van wat er naar geschreven is. @@ -101,7 +101,7 @@ SD card may be broken. - + Error partitioning: %1 Fout bij partitioneren: %1 @@ -126,27 +126,27 @@ SD card may be broken. Ongeldig device: %1 - + Error formatting (through udisks2) Fout bij formatteren (via udisks2) - + Error starting sfdisk Fout bij starten sfdisk - + Error starting mkfs.fat Fout bij starten mkfs.fat - + Error running mkfs.fat: %1 Fout bij uitvoeren mkfs.fat: %1 - + Formatting not implemented for this platform Formatteren is niet geimplementeerd op dit besturingssysteem @@ -154,198 +154,270 @@ SD card may be broken. ImageWriter - + Storage capacity is not large enough. Needs to be at least %1 GB Opslagcapaciteit niet groot genoeg. Deze dient minimaal %1 GB te zijn - + Input file is not a valid disk image. File size %1 bytes is not a multiple of 512 bytes. Invoerbestand is geen disk image. Bestandsgrootte %1 bytes is geen veelvoud van 512 bytes. - + Downloading and writing image Downloaden en schrijven van image - + Select image Selecteer image + + LocalFileExtractThread + + + Error opening image file + Fout bij openen image bestand + + + + MsgPopup + + + NO + Nee + + + + YES + Ja + + + + CONTINUE + VERDER GAAN + + + + QObject + + + Internal SD card reader + Interne SD kaart lezer + + main - + Raspberry Pi Imager v%1 Raspberry Pi Imager v%1 - + Are you sure you want to quit? Weet u zeker dat u wilt afsluiten? - + Raspberry Pi Imager is still busy.<br>Are you sure you want to quit? Raspberry Pi Imager is nog niet klaar.<br>Weet u zeker dat u wilt afsluiten? - - + + Operating System Besturingssysteem - + CHOOSE OS SELECTEER OS - - + + SD Card SD kaart - - + + CHOOSE SD CARD SELECTEER SD KAART - + WRITE SCHRIJF - - + + Writing... %1% Schrijven... %1% - + CANCEL WRITE Annuleer schrijven - - + + Select this button to change the operating system + Kies deze knop om een besturingssysteem te kiezen + + + + Select this button to change the destination SD card + Kies deze knop om de SD kaart te kiezen + + + + Select this button to start writing the image + Kies deze knop om te beginnen met het schrijven van de image + + + + Cancelling... Annuleren... - + CANCEL VERIFY ANNULEER VERIFICATIE - - - + + + Finalizing... Afronden... - - + + Erase Wissen - + Format card as FAT32 Formatteer kaart als FAT32 - + Use custom Gebruik eigen bestand - + Select a custom .img from your computer Selecteer een eigen .img bestand - - + + Local file + Lokaal bestand + + + + Warning + Waarschuwing + + + + All existing data on '%1' will be erased.<br>Are you sure you want to continue? + Alle bestaande gegevens op '%1' zullen verwijderd worden.<br>Weet u zeker dat u door wilt gaan? + + + + <b>%1</b> has been erased<br><br>You can now remove the SD card from the reader + <b>%1</b> is gewist<br><br>U kunt nu de SD kaart uit de lezer halen + + + + Error parsing os_list.json Fout bij parsen os_list.json - + + Connect an USB stick containing images first.<br>The images must be located in the root folder of the USB stick. + Sluit eerst een USB stick met images aan.<br>De images moeten in de hoofdmap van de USB stick staan. + + + Back Terug - + Go back to main menu Terug naar hoofdmenu - + Released: %1 Release datum: %1 - + Cached on your computer Opgeslagen op computer - + Online - %1 GB download Online %1 GB download - + + Mounted as %1 Mounted op %1 - QUIT APP - AFSLUITEN + AFSLUITEN - CONTINUE - VERDER GAAN + VERDER GAAN - + Error downloading OS list from Internet Fout bij downloaden van lijst met besturingssystemen - + Verifying... %1% Verifiëren... %1% - + Error Fout - + Write Successful Klaar met schrijven - <b>%2</b> has been erased<br><br>You can now remove the SD card from the reader - <b>%2</b> is gewist<br><br>U kunt nu de SD kaart uit de lezer halen + <b>%2</b> is gewist<br><br>U kunt nu de SD kaart uit de lezer halen - + <b>%1</b> has been written to <b>%2</b><br><br>You can now remove the SD card from the reader <b>%1</b> is geschreven naar <b>%2</b><br><br>U kunt nu de SD kaart uit de lezer halen diff --git a/i18n/rpi-imager_zh_cn.ts b/i18n/rpi-imager_zh_cn.ts index e41f493..bc189b1 100644 --- a/i18n/rpi-imager_zh_cn.ts +++ b/i18n/rpi-imager_zh_cn.ts @@ -48,7 +48,7 @@ - + Cannot open storage device '%1'. @@ -64,33 +64,33 @@ Card could be advertising wrong capacity (possible counterfeit) - + Error writing to storage (while flushing) - + Error writing to storage (while fsync) - + Download corrupt. Hash does not match - + Error writing first block (partition table) - + Error reading from storage. SD card may be broken. - + Verifying write failed. Contents of SD card is different from what was written to it. @@ -100,7 +100,7 @@ SD card may be broken. - + Error partitioning: %1 @@ -125,27 +125,27 @@ SD card may be broken. - + Error formatting (through udisks2) - + Error starting sfdisk - + Error starting mkfs.fat - + Error running mkfs.fat: %1 - + Formatting not implemented for this platform @@ -153,196 +153,264 @@ SD card may be broken. ImageWriter - + Storage capacity is not large enough. Needs to be at least %1 GB - + Input file is not a valid disk image. File size %1 bytes is not a multiple of 512 bytes. - + Downloading and writing image - + Select image + + LocalFileExtractThread + + + Error opening image file + + + + + MsgPopup + + + NO + + + + + YES + + + + + CONTINUE + 继续 + + + + QObject + + + Internal SD card reader + + + main - + Raspberry Pi Imager v%1 树莓派镜像烧录 v%1 - + Are you sure you want to quit? - + Raspberry Pi Imager is still busy.<br>Are you sure you want to quit? - - + + Operating System 操作系统 - + CHOOSE OS 选择操作系统 - - + + SD Card SD卡 - - + + CHOOSE SD CARD 选择SD卡 - + WRITE 烧录 - - + + Writing... %1% 写入中...%1% - + CANCEL WRITE 取消写入 - - + + Select this button to change the operating system + + + + + Select this button to change the destination SD card + + + + + Select this button to start writing the image + + + + + Cancelling... 取消中... - + CANCEL VERIFY 取消验证 - - - + + + Finalizing... 完成中... - - + + Erase 擦除 - + Format card as FAT32 格式化SD卡为FAT32格式 - + Use custom 使用自定义镜像 - + Select a custom .img from your computer 使用下载的系统镜像文件烧录 - - + + Local file + + + + + Warning + + + + + All existing data on '%1' will be erased.<br>Are you sure you want to continue? + + + + + <b>%1</b> has been erased<br><br>You can now remove the SD card from the reader + + + + + Error parsing os_list.json 解析 os_list.json 错误 - + + Connect an USB stick containing images first.<br>The images must be located in the root folder of the USB stick. + + + + Back 返回 - + Go back to main menu 回到主页 - + Released: %1 解压中...%1 - + Cached on your computer 在你的电脑上缓存 - + Online - %1 GB download 已下载:%1 GB - + + Mounted as %1 挂载在:%1 上 - QUIT APP - 退出 + 退出 - CONTINUE - 继续 + 继续 - + Error downloading OS list from Internet 下载镜像列表错误 - + Verifying... %1% 验证文件中...%1% - + Error 错误 - + Write Successful 烧录成功 - - <b>%2</b> has been erased<br><br>You can now remove the SD card from the reader - - - - + <b>%1</b> has been written to <b>%2</b><br><br>You can now remove the SD card from the reader <b>%1</b> 已经成功烧录到 <b>%2</b><br><br>上了,你可以卸载SD卡了 diff --git a/main.qml b/main.qml index d49db15..ca44e32 100644 --- a/main.qml +++ b/main.qml @@ -30,10 +30,7 @@ ApplicationWindow { onClosing: { if (progressBar.visible) { close.accepted = false - msgpopupheader.text = qsTr("Are you sure you want to quit?") - msgpopupbody.text = qsTr("Raspberry Pi Imager is still busy.
Are you sure you want to quit?") - quitbutton.visible = true - msgpopup.open() + quitpopup.openPopup() } } @@ -111,9 +108,18 @@ ApplicationWindow { topPadding: 0 Layout.minimumHeight: 40 Layout.fillWidth: true - onClicked: ospopup.open() + onClicked: { + ospopup.open() + if (osswipeview.currentIndex == 0) + oslist.forceActiveFocus() + else + suboslist.forceActiveFocus() + } Material.background: "#ffffff" Material.foreground: "#c51a4a" + Accessible.ignored: ospopup.visible || dstpopup.visible + Accessible.description: qsTr("Select this button to change the operating system") + Accessible.onPressAction: clicked() } } @@ -146,9 +152,13 @@ ApplicationWindow { imageWriter.refreshDriveList() drivePollTimer.start() dstpopup.open() + dstlist.forceActiveFocus() } Material.background: "#ffffff" Material.foreground: "#c51a4a" + Accessible.ignored: ospopup.visible || dstpopup.visible + Accessible.description: qsTr("Select this button to change the destination SD card") + Accessible.onPressAction: clicked() } } @@ -168,6 +178,8 @@ ApplicationWindow { font.family: roboto.name Layout.minimumHeight: 40 Layout.fillWidth: true + Accessible.ignored: ospopup.visible || dstpopup.visible + Accessible.description: qsTr("Select this button to start writing the image") enabled: false Material.background: "#ffffff" @@ -175,20 +187,10 @@ ApplicationWindow { onClicked: { if (!imageWriter.readyToWrite()) return; - enabled = false - cancelwritebutton.enabled = true - cancelwritebutton.visible = true - cancelverifybutton.enabled = true - progressText.text = qsTr("Writing... %1%").arg("0") - progressText.visible = true - progressBar.visible = true - progressBar.indeterminate = true - progressBar.Material.accent = "#ffffff" - osbutton.enabled = false - dstbutton.enabled = false - imageWriter.setVerifyEnabled(true) - imageWriter.startWrite() + + confirmwritepopup.askForConfirmation() } + Accessible.onPressAction: clicked() } } @@ -228,6 +230,7 @@ ApplicationWindow { Layout.alignment: Qt.AlignRight visible: false font.family: roboto.name + Accessible.onPressAction: clicked() } Button { id: cancelverifybutton @@ -242,6 +245,7 @@ ApplicationWindow { Layout.alignment: Qt.AlignRight visible: false font.family: roboto.name + Accessible.onPressAction: clicked() } } } @@ -258,7 +262,6 @@ ApplicationWindow { width: parent.width-100 height: parent.height-50 padding: 0 - focus: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside // background of title @@ -320,28 +323,47 @@ ApplicationWindow { ListView { id: oslist model: osmodel + currentIndex: -1 delegate: osdelegate width: window.width-100 height: window.height-100 - focus: true boundsBehavior: Flickable.StopAtBounds + highlight: Rectangle { color: "lightsteelblue"; radius: 5 } ScrollBar.vertical: ScrollBar { width: 10 policy: oslist.contentHeight > oslist.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded } + Keys.onSpacePressed: { + if (currentIndex != -1) + selectOSitem(model.get(currentIndex), true) + } + Accessible.onPressAction: { + if (currentIndex != -1) + selectOSitem(model.get(currentIndex), true) + } } ListView { id: suboslist model: subosmodel + currentIndex: -1 delegate: osdelegate width: window.width-100 height: window.height-100 boundsBehavior: Flickable.StopAtBounds + highlight: Rectangle { color: "lightsteelblue"; radius: 5 } ScrollBar.vertical: ScrollBar { width: 10 policy: suboslist.contentHeight > suboslist.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded } + Keys.onSpacePressed: { + if (currentIndex != -1) + selectOSitem(model.get(currentIndex)) + } + Accessible.onPressAction: { + if (currentIndex != -1) + selectOSitem(model.get(currentIndex)) + } } } } @@ -405,12 +427,14 @@ ApplicationWindow { Item { width: window.width-100 height: image_download_size ? 100 : 60 + Accessible.name: name+".\n"+description Rectangle { id: bgrect anchors.fill: parent color: "#f5f5f5" - visible: false + visible: mouseOver && parent.ListView.view.currentIndex !== index + property bool mouseOver: false } Rectangle { id: borderrect @@ -464,6 +488,13 @@ ApplicationWindow { return txt; } + /* + Accessible.role: Accessible.ListItem + Accessible.name: name+".\n"+description + Accessible.focusable: true + Accessible.focused: parent.parent.parent.ListView.view.currentIndex === index + */ + ToolTip { visible: osMouseArea.containsMouse && typeof(tooltip) == "string" && tooltip != "" delay: 1000 @@ -490,80 +521,15 @@ ApplicationWindow { hoverEnabled: true onEntered: { - bgrect.visible = true + bgrect.mouseOver = true } onExited: { - bgrect.visible = false + bgrect.mouseOver = false } onClicked: { - if (typeof(subitems) == "object" && subitems.count) { - if (subosmodel.count>1) - { - subosmodel.remove(1, subosmodel.count-1) - } - for (var i=0; i1) - { - subosmodel.remove(1, subosmodel.count-1) - } - - httpRequest(subitems_url, function (x) { - var o = JSON.parse(x.responseText) - if (!"os_list" in o) { - onError(qsTr("Error parsing os_list.json")) - return; - } - var oslist = o["os_list"] - for (var i in oslist) { - subosmodel.append(oslist[i]) - } - }) - osswipeview.setCurrentIndex(1) - } - } else if (url == "") { - if (!imageWriter.isEmbeddedMode()) { - imageWriter.openFileDialog() - } - else { - if (imageWriter.mountUsbSourceMedia()) { - if (subosmodel.count>1) - { - subosmodel.remove(1, subosmodel.count-1) - } - - var oslist = JSON.parse(imageWriter.getUsbSourceOSlist()) - for (var i in oslist) { - subosmodel.append(oslist[i]) - } - osswipeview.setCurrentIndex(1) - } - else - { - onError(qsTr("Connect an USB stick containing images first.
The images must be located in the root folder of the USB stick.")) - } - } - } else { - imageWriter.setSrc(url, image_download_size, extract_size, typeof(extract_sha256) != "undefined" ? extract_sha256 : "", typeof(contains_multiple_files) != "undefined" ? contains_multiple_files : false) - osbutton.text = name - ospopup.close() - if (imageWriter.readyToWrite()) { - writebutton.enabled = true - } - } + selectOSitem(model) } } } @@ -579,7 +545,6 @@ ApplicationWindow { width: parent.width-100 height: parent.height-50 padding: 0 - focus: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside // background of title @@ -640,12 +605,37 @@ ApplicationWindow { delegate: dstdelegate width: window.width-100 height: window.height-100 - focus: true boundsBehavior: Flickable.StopAtBounds + highlight: Rectangle { color: "lightsteelblue"; radius: 5 } ScrollBar.vertical: ScrollBar { width: 10 policy: dstlist.contentHeight > dstlist.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded } + + Keys.onSpacePressed: { + if (currentIndex == -1) + return + + drivePollTimer.stop() + dstpopup.close() + imageWriter.setDst(currentItem.device, currentItem.size) + dstbutton.text = currentItem.description + if (imageWriter.readyToWrite()) { + writebutton.enabled = true + } + } + Accessible.onPressAction: { + if (currentIndex == -1) + return + + drivePollTimer.stop() + dstpopup.close() + imageWriter.setDst(currentItem.device, currentItem.size) + dstbutton.text = currentItem.description + if (imageWriter.readyToWrite()) { + writebutton.enabled = true + } + } } } } @@ -657,12 +647,24 @@ ApplicationWindow { Item { width: window.width-100 height: 60 + Accessible.name: { + var txt = description+" - "+(size/1000000000).toFixed(1)+" gigabytes" + if (mountpoints.length > 0) { + txt += qsTr("Mounted as %1").arg(mountpoints.join(", ")) + } + return txt; + } + property string description: model.description + property string device: model.device + property string size: model.size Rectangle { id: dstbgrect anchors.fill: parent color: "#f5f5f5" - visible: false + visible: mouseOver && parent.ListView.view.currentIndex !== index + property bool mouseOver: false + } Rectangle { id: dstborderrect @@ -710,11 +712,11 @@ ApplicationWindow { hoverEnabled: true onEntered: { - dstbgrect.visible = true + dstbgrect.mouseOver = true } onExited: { - dstbgrect.visible = false + dstbgrect.mouseOver = false } onClicked: { @@ -730,109 +732,48 @@ ApplicationWindow { } } - Popup { + MsgPopup { id: msgpopup - x: 75 - y: parent.height/2-100 - width: parent.width-150 - height: msgpopupbody.implicitHeight+150 //200 - padding: 0 - focus: true - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + } - // background of title - Rectangle { - color: "#f5f5f5" - anchors.right: parent.right - anchors.top: parent.top - height: 35 - width: parent.width + MsgPopup { + id: quitpopup + continueButton: false + yesButton: true + noButton: true + title: qsTr("Are you sure you want to quit?") + text: qsTr("Raspberry Pi Imager is still busy.
Are you sure you want to quit?") + onYes: { + Qt.quit() } - // line under title - Rectangle { - color: "#afafaf" - width: parent.width - y: 35 - implicitHeight: 1 + } + + MsgPopup { + id: confirmwritepopup + continueButton: false + yesButton: true + noButton: true + title: qsTr("Warning") + onYes: { + writebutton.enabled = false + cancelwritebutton.enabled = true + cancelwritebutton.visible = true + cancelverifybutton.enabled = true + progressText.text = qsTr("Writing... %1%").arg("0") + progressText.visible = true + progressBar.visible = true + progressBar.indeterminate = true + progressBar.Material.accent = "#ffffff" + osbutton.enabled = false + dstbutton.enabled = false + imageWriter.setVerifyEnabled(true) + imageWriter.startWrite() } - Text { - id: msgx - text: "X" - anchors.right: parent.right - anchors.top: parent.top - anchors.rightMargin: 25 - anchors.topMargin: 10 - font.family: roboto.name - font.bold: true - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - if (continuebutton.visible) - msgpopup.close() - else - Qt.quit() - } - } - } - - ColumnLayout { - spacing: 20 - anchors.fill: parent - - Text { - id: msgpopupheader - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.topMargin: 10 - font.family: roboto.name - font.bold: true - } - - Text { - id: msgpopupbody - font.pointSize: 12 - wrapMode: Text.Wrap - textFormat: Text.StyledText - font.family: roboto.name - Layout.maximumWidth: msgpopup.width-50 - Layout.fillHeight: true - Layout.leftMargin: 25 - Layout.topMargin: 25 - } - - RowLayout { - Layout.alignment: Qt.AlignCenter | Qt.AlignBottom - Layout.bottomMargin: 10 - spacing: 20 - - Button { - id: quitbutton - text: qsTr("QUIT APP") - onClicked: Qt.quit() - Material.foreground: "#ffffff" - Material.background: "#c51a4a" - font.family: roboto.name - visible: imageWriter.isEmbeddedMode() - } - - Button { - id: continuebutton - text: qsTr("CONTINUE") - onClicked: { - msgpopup.close() - quitbutton.visible = imageWriter.isEmbeddedMode() - } - Material.foreground: "#ffffff" - Material.background: "#c51a4a" - font.family: roboto.name - } - - Text { text: " " } - } + function askForConfirmation() + { + text = qsTr("All existing data on '%1' will be erased.
Are you sure you want to continue?").arg(dstbutton.text) + openPopup() } } @@ -926,19 +867,19 @@ ApplicationWindow { } function onError(msg) { - msgpopupheader.text = qsTr("Error") - msgpopupbody.text = msg - msgpopup.open() + msgpopup.title = qsTr("Error") + msgpopup.text = msg + msgpopup.openPopup() resetWriteButton() } function onSuccess() { - msgpopupheader.text = qsTr("Write Successful") + msgpopup.title = qsTr("Write Successful") if (osbutton.text === qsTr("Erase")) - msgpopupbody.text = qsTr("%2 has been erased

You can now remove the SD card from the reader").arg(dstbutton.text) + msgpopup.text = qsTr("%1 has been erased

You can now remove the SD card from the reader").arg(dstbutton.text) else - msgpopupbody.text = qsTr("%1 has been written to %2

You can now remove the SD card from the reader").arg(osbutton.text).arg(dstbutton.text) - msgpopup.open() + msgpopup.text = qsTr("%1 has been written to %2

You can now remove the SD card from the reader").arg(osbutton.text).arg(dstbutton.text) + msgpopup.openPopup() imageWriter.setDst("") dstbutton.text = qsTr("CHOOSE SD CARD") resetWriteButton() @@ -974,4 +915,87 @@ ApplicationWindow { } }) } + + function selectOSitem(d, selectFirstSubitem) + { + if (typeof(d.subitems) == "object" && d.subitems.count) { + if (subosmodel.count>1) + { + subosmodel.remove(1, subosmodel.count-1) + } + for (var i=0; i1) + { + subosmodel.remove(1, subosmodel.count-1) + } + + httpRequest(d.subitems_url, function (x) { + var o = JSON.parse(x.responseText) + if (!"os_list" in o) { + onError(qsTr("Error parsing os_list.json")) + return; + } + var oslist = o["os_list"] + for (var i in oslist) { + subosmodel.append(oslist[i]) + } + }) + + if (selectFirstSubitem === true) + suboslist.currentIndex = 0 + else + suboslist.currentIndex = -1 + osswipeview.setCurrentIndex(1) + } + } else if (d.url === "") { + if (!imageWriter.isEmbeddedMode()) { + imageWriter.openFileDialog() + } + else { + if (imageWriter.mountUsbSourceMedia()) { + if (subosmodel.count>1) + { + subosmodel.remove(1, subosmodel.count-1) + } + + var oslist = JSON.parse(imageWriter.getUsbSourceOSlist()) + for (var i in oslist) { + subosmodel.append(oslist[i]) + } + if (selectFirstSubitem === true) + suboslist.currentIndex = 0 + else + suboslist.currentIndex = -1 + osswipeview.setCurrentIndex(1) + } + else + { + onError(qsTr("Connect an USB stick containing images first.
The images must be located in the root folder of the USB stick.")) + } + } + } else { + imageWriter.setSrc(d.url, d.image_download_size, d.extract_size, typeof(d.extract_sha256) != "undefined" ? d.extract_sha256 : "", typeof(d.contains_multiple_files) != "undefined" ? d.contains_multiple_files : false) + osbutton.text = d.name + ospopup.close() + if (imageWriter.readyToWrite()) { + writebutton.enabled = true + } + } + } } diff --git a/qml.qrc b/qml.qrc index 0648227..bf966b5 100644 --- a/qml.qrc +++ b/qml.qrc @@ -16,5 +16,6 @@ icons/ic_sd_storage_40px.svg icons/ic_storage_40px.svg icons/ic_usb_40px.svg + MsgPopup.qml