Merge pull request #645 from tdewey-rpi/dev/shared/device-filtering

Device-first OS list filtering
This commit is contained in:
Tom Dewey 2023-10-16 13:56:39 +01:00 committed by GitHub
commit e8d7de934f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 6317 additions and 6559 deletions

View file

@ -197,8 +197,8 @@ On macOS, disable it by editing the property list for the application:
defaults write org.raspberrypi.Imager.plist telemetry -bool NO
```
### Advanced options
### OS Customization
When using the app, press <kbd>CTRL</kbd> + <kbd>SHIFT</kbd> + <kbd>X</kbd> to reveal the **Advanced options** dialog.
When using the app, press <kbd>CTRL</kbd> + <kbd>SHIFT</kbd> + <kbd>X</kbd> to reveal the **OS Customization** dialog.
In here, you can specify several things you would otherwise set in the boot configuration files. For example, you can enable SSH, set the Wi-Fi login, and specify your locale settings for the system image.

View file

@ -194,7 +194,8 @@
"extract_sha256": "ceb7d7489847ed811e7746fa779837f78fc06d43663148a696280e6a1cfe00e3",
"image_download_size": 1306588543,
"release_date": "2022-01-28",
"init_format": "systemd"
"init_format": "systemd",
"devices": ["pi1a"]
}
],
"required": [
@ -205,7 +206,8 @@
"extract_size",
"extract_sha256",
"image_download_size",
"release_date"
"release_date",
"devices"
],
"properties": {
"name": {
@ -298,6 +300,31 @@
"systemd"
]
},
"devices": {
"$id": "#/properties/os_list/items/anyOf/0/properties/devices",
"type": "array",
"title": "The devices schema",
"description": "Provides a JSON-format list of strings representing Raspberry Pi devices that are supported with this image",
"default": "",
"examples": [
"[\"pi1a\", \"pi1b\"]",
"[\"pi4\", \"pi5\"]",
"[\"cm3\", \"cm4\"]"
]
},
"matching_type": {
"$id": "#/properties/os_list/items/anyOf/0/properties/matching_type",
"type": "array",
"title": "The matching_type schema",
"description": "Allows specification of the matching algorithm to use for device tags. If you set this to 'exclusive', any image that does not explicitly tag your target device will not be displayed. Set to 'prefix' to allow for family matching (eg, match all Pi1 devices), but no untagged images. Set to 'inclusive', and get your exact device name and all untagged images. Finally, if you set to 'inclusive_prefix', you can match all images tagged with your family prefix (eg, Pi1), and any untagged image.",
"default": "exclusive",
"examples": [
"exclusive",
"exclusive_prefix",
"inclusive",
"inclusive_prefix"
]
},
"website": {
"$id": "#/properties/os_list/items/anyOf/1/properties/website",
"type": "string",

View file

@ -17,7 +17,7 @@ Window {
maximumWidth: width
minimumHeight: 125
height: Math.min(750, cl.implicitHeight)
title: qsTr("Advanced options")
title: qsTr("OS Customization")
property bool initialized: false
property bool hasSavedSettings: false
@ -49,7 +49,7 @@ Window {
RowLayout {
Label {
text: qsTr("Image customization options")
text: qsTr("OS customization options")
}
ComboBox {
id: comboSaveSettings
@ -539,7 +539,7 @@ Window {
/* Lacking an easy cross-platform to fetch keyboard layout
from host system, just default to "gb" for people in
UK time zone for now, and "us" for everyone else */
if (tz == "Europe/London") {
if (tz === "Europe/London") {
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("gb")
} else {
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("us")

View file

@ -70,7 +70,7 @@ Popup {
Layout.topMargin: 10
font.family: roboto.name
font.bold: true
text: qsTr("Warning: advanced settings set")
text: qsTr("Use OS customization?")
}
Text {
@ -83,8 +83,9 @@ Popup {
Layout.fillHeight: true
Layout.leftMargin: 25
Layout.topMargin: 25
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Accessible.name: text.replace(/<\/?[^>]+(>|$)/g, "")
text: qsTr("Would you like to apply the image customization settings saved earlier?")
text: qsTr("Would you like to apply OS customization settings?")
}
RowLayout {
@ -94,10 +95,10 @@ Popup {
id: buttons
ImButton {
text: qsTr("NO")
text: qsTr("EDIT SETTINGS")
onClicked: {
msgpopup.close()
msgpopup.no()
msgpopup.editSettings()
}
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
Material.background: "#c51a4a"
@ -111,6 +112,7 @@ Popup {
}
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
Material.background: "#c51a4a"
enabled: imageWriter.hasSavedCustomizationSettings() ? true : false
}
ImButton {
@ -121,13 +123,14 @@ Popup {
}
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
Material.background: "#c51a4a"
enabled: imageWriter.hasSavedCustomizationSettings() ? true : false
}
ImButton {
text: qsTr("EDIT SETTINGS")
text: qsTr("NO")
onClicked: {
msgpopup.close()
msgpopup.editSettings()
msgpopup.no()
}
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
Material.background: "#c51a4a"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,16 @@
</context>
<context>
<name>DownloadThread</name>
<message>
<location filename="../downloadthread.cpp" line="118"/>
<source>unmounting drive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="138"/>
<source>opening drive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="166"/>
<source>Error running diskpart: %1</source>
@ -73,13 +83,18 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="826"/>
<source>Error reading from storage.&lt;br&gt;SD card may be broken.</source>
<location filename="../downloadthread.cpp" line="319"/>
<source>Write error while trying to zero out last part of card.&lt;br&gt;Card could be advertising wrong capacity (possible counterfeit).</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="898"/>
<source>Customizing image</source>
<location filename="../downloadthread.cpp" line="408"/>
<source>starting download</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="466"/>
<source>Error downloading: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@ -98,8 +113,8 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="466"/>
<source>Error downloading: %1</source>
<location filename="../downloadthread.cpp" line="697"/>
<source>Download corrupt. Hash does not match</source>
<translation type="unfinished"></translation>
</message>
<message>
@ -114,41 +129,26 @@
<source>Error writing to storage (while fsync)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="697"/>
<source>Download corrupt. Hash does not match</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="118"/>
<source>unmounting drive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="138"/>
<source>opening drive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="319"/>
<source>Write error while trying to zero out last part of card.&lt;br&gt;Card could be advertising wrong capacity (possible counterfeit).</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="408"/>
<source>starting download</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="751"/>
<source>Error writing first block (partition table)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="826"/>
<source>Error reading from storage.&lt;br&gt;SD card may be broken.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="845"/>
<source>Verifying write failed. Contents of SD card is different from what was written to it.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../downloadthread.cpp" line="898"/>
<source>Customizing image</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DriveFormatThread</name>
@ -213,27 +213,27 @@
<context>
<name>ImageWriter</name>
<message>
<location filename="../imagewriter.cpp" line="248"/>
<location filename="../imagewriter.cpp" line="252"/>
<source>Storage capacity is not large enough.&lt;br&gt;Needs to be at least %1 GB.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../imagewriter.cpp" line="254"/>
<location filename="../imagewriter.cpp" line="258"/>
<source>Input file is not a valid disk image.&lt;br&gt;File size %1 bytes is not a multiple of 512 bytes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../imagewriter.cpp" line="442"/>
<location filename="../imagewriter.cpp" line="446"/>
<source>Downloading and writing image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../imagewriter.cpp" line="575"/>
<location filename="../imagewriter.cpp" line="579"/>
<source>Select image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../imagewriter.cpp" line="896"/>
<location filename="../imagewriter.cpp" line="971"/>
<source>Would you like to prefill the wifi password from the system keychain?</source>
<translation type="unfinished"></translation>
</message>
@ -316,6 +316,62 @@
<source>Set hostname:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="120"/>
<source>Set username and password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="142"/>
<source>Username:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="158"/>
<location filename="../OptionsPopup.qml" line="219"/>
<source>Password:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="186"/>
<source>Configure wireless LAN</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="205"/>
<source>SSID:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="238"/>
<source>Show password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="244"/>
<source>Hidden SSID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="250"/>
<source>Wireless LAN country:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="261"/>
<source>Set locale settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="271"/>
<source>Time zone:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="281"/>
<source>Keyboard layout:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="298"/>
<source>Enable SSH</source>
@ -341,62 +397,6 @@
<source>RUN SSH-KEYGEN</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="186"/>
<source>Configure wireless LAN</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="205"/>
<source>SSID:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="158"/>
<location filename="../OptionsPopup.qml" line="219"/>
<source>Password:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="120"/>
<source>Set username and password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="142"/>
<source>Username:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="244"/>
<source>Hidden SSID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="238"/>
<source>Show password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="250"/>
<source>Wireless LAN country:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="261"/>
<source>Set locale settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="271"/>
<source>Time zone:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="281"/>
<source>Keyboard layout:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../OptionsPopup.qml" line="375"/>
<source>Play sound when finished</source>
@ -430,32 +430,32 @@
<name>UseSavedSettingsPopup</name>
<message>
<location filename="../UseSavedSettingsPopup.qml" line="73"/>
<source>Warning: advanced settings set</source>
<source>Use image customisation?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UseSavedSettingsPopup.qml" line="87"/>
<source>Would you like to apply the image customization settings saved earlier?</source>
<location filename="../UseSavedSettingsPopup.qml" line="88"/>
<source>Would you like to apply image customization settings?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UseSavedSettingsPopup.qml" line="97"/>
<source>NO</source>
<translation></translation>
<location filename="../UseSavedSettingsPopup.qml" line="98"/>
<source>EDIT SETTINGS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UseSavedSettingsPopup.qml" line="107"/>
<location filename="../UseSavedSettingsPopup.qml" line="108"/>
<source>NO, CLEAR SETTINGS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UseSavedSettingsPopup.qml" line="117"/>
<location filename="../UseSavedSettingsPopup.qml" line="119"/>
<source>YES</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UseSavedSettingsPopup.qml" line="127"/>
<source>EDIT SETTINGS</source>
<location filename="../UseSavedSettingsPopup.qml" line="130"/>
<source>NO</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -467,256 +467,262 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="97"/>
<location filename="../main.qml" line="413"/>
<location filename="../main.qml" line="114"/>
<location filename="../main.qml" line="467"/>
<source>Raspberry Pi Device</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="126"/>
<source>CHOOSE DEVICE</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="138"/>
<source>Select this button to choose your target Raspberry Pi</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="152"/>
<location filename="../main.qml" line="576"/>
<source>Operating System</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="109"/>
<location filename="../main.qml" line="163"/>
<source>CHOOSE OS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="121"/>
<location filename="../main.qml" line="175"/>
<source>Select this button to change the operating system</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="133"/>
<location filename="../main.qml" line="780"/>
<location filename="../main.qml" line="189"/>
<location filename="../main.qml" line="957"/>
<source>Storage</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="145"/>
<location filename="../main.qml" line="1108"/>
<location filename="../main.qml" line="200"/>
<location filename="../main.qml" line="1286"/>
<source>CHOOSE STORAGE</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="171"/>
<source>WRITE</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="175"/>
<source>Select this button to start writing the image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="216"/>
<source>CANCEL WRITE</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="219"/>
<location filename="../main.qml" line="1035"/>
<source>Cancelling...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="227"/>
<source>CANCEL VERIFY</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="230"/>
<location filename="../main.qml" line="1058"/>
<location filename="../main.qml" line="1127"/>
<source>Finalizing...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="245"/>
<source>Select this button to access advanced settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="259"/>
<source>Using custom repository: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="268"/>
<source>Keyboard navigation: &lt;tab&gt; navigate to next button &lt;space&gt; press button/select item &lt;arrow up/down&gt; go up/down in lists</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="289"/>
<source>Language: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="312"/>
<source>Keyboard: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="437"/>
<source>Pi model:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="448"/>
<source>[ All ]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="572"/>
<location filename="../main.qml" line="1092"/>
<source>Erase</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="573"/>
<source>Format card as FAT32</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="582"/>
<source>Use custom</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="583"/>
<source>Select a custom .img from your computer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="528"/>
<source>Back</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="155"/>
<location filename="../main.qml" line="214"/>
<source>Select this button to change the destination storage device</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="529"/>
<location filename="../main.qml" line="261"/>
<source>CANCEL WRITE</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="264"/>
<location filename="../main.qml" line="1213"/>
<source>Cancelling...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="276"/>
<source>CANCEL VERIFY</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="279"/>
<location filename="../main.qml" line="1236"/>
<location filename="../main.qml" line="1305"/>
<source>Finalizing...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="288"/>
<source>Next</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="294"/>
<source>Select this button to start writing the image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="316"/>
<source>Using custom repository: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="325"/>
<source>Keyboard navigation: &lt;tab&gt; navigate to next button &lt;space&gt; press button/select item &lt;arrow up/down&gt; go up/down in lists</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="346"/>
<source>Language: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="369"/>
<source>Keyboard: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="490"/>
<source>[ All ]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="638"/>
<source>Back</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="639"/>
<source>Go back to main menu</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="695"/>
<location filename="../main.qml" line="872"/>
<source>Released: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="705"/>
<location filename="../main.qml" line="882"/>
<source>Cached on your computer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="707"/>
<location filename="../main.qml" line="884"/>
<source>Local file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="708"/>
<location filename="../main.qml" line="885"/>
<source>Online - %1 GB download</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="833"/>
<location filename="../main.qml" line="885"/>
<location filename="../main.qml" line="891"/>
<location filename="../main.qml" line="1010"/>
<location filename="../main.qml" line="1062"/>
<location filename="../main.qml" line="1068"/>
<source>Mounted as %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="887"/>
<location filename="../main.qml" line="1064"/>
<source>[WRITE PROTECTED]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="929"/>
<location filename="../main.qml" line="1106"/>
<source>Are you sure you want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="930"/>
<location filename="../main.qml" line="1107"/>
<source>Raspberry Pi Imager is still busy.&lt;br&gt;Are you sure you want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="941"/>
<location filename="../main.qml" line="1118"/>
<source>Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="949"/>
<location filename="../main.qml" line="1126"/>
<source>Preparing to write...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="973"/>
<source>Update available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="974"/>
<source>There is a newer version of Imager available.&lt;br&gt;Would you like to visit the website to download it?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1038"/>
<source>Writing... %1%</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="962"/>
<location filename="../main.qml" line="1140"/>
<source>All existing data on &apos;%1&apos; will be erased.&lt;br&gt;Are you sure you want to continue?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1017"/>
<location filename="../main.qml" line="1151"/>
<source>Update available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1152"/>
<source>There is a newer version of Imager available.&lt;br&gt;Would you like to visit the website to download it?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1195"/>
<source>Error downloading OS list from Internet</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1061"/>
<location filename="../main.qml" line="1216"/>
<source>Writing... %1%</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1239"/>
<source>Verifying... %1%</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1068"/>
<location filename="../main.qml" line="1246"/>
<source>Preparing to write... (%1)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1084"/>
<location filename="../main.qml" line="1262"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1091"/>
<location filename="../main.qml" line="1269"/>
<source>Write Successful</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1093"/>
<location filename="../main.qml" line="1270"/>
<location filename="../main.qml" line="1523"/>
<source>Erase</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1271"/>
<source>&lt;b&gt;%1&lt;/b&gt; has been erased&lt;br&gt;&lt;br&gt;You can now remove the SD card from the reader</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1100"/>
<location filename="../main.qml" line="1278"/>
<source>&lt;b&gt;%1&lt;/b&gt; has been written to &lt;b&gt;%2&lt;/b&gt;&lt;br&gt;&lt;br&gt;You can now remove the SD card from the reader</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1202"/>
<location filename="../main.qml" line="1423"/>
<source>Error parsing os_list.json</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1391"/>
<location filename="../main.qml" line="1524"/>
<source>Format card as FAT32</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1533"/>
<source>Use custom</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1534"/>
<source>Select a custom .img from your computer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1681"/>
<source>Connect an USB stick containing images first.&lt;br&gt;The images must be located in the root folder of the USB stick.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.qml" line="1407"/>
<location filename="../main.qml" line="1697"/>
<source>SD card is write protected.&lt;br&gt;Push the lock switch on the left side of the card upwards, and try again.</source>
<translation type="unfinished"></translation>
</message>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -25,6 +25,20 @@ ApplicationWindow {
FontLoader {id: robotoLight; source: "fonts/Roboto-Light.ttf"}
FontLoader {id: robotoBold; source: "fonts/Roboto-Bold.ttf"}
/** hw device list storage
*
* To allow us to filter the OS list, we maintain an application-wide record of the selected device
* tags.
*/
property string hwTags
/** 0: Exclusive, must match explicit device names only, no untagged
1: Exclusive by prefix, must match the device name as a prefix, no untagged
2: Inclusive, match explicit device names and untagged
3: Inclusive by prefix, match explicit device names and untagged
*/
property int hwTagMatchingType
onClosing: {
if (progressBar.visible) {
close.accepted = false
@ -55,40 +69,81 @@ ApplicationWindow {
spacing: 0
Rectangle {
implicitHeight: window.height/2
implicitHeight: window.height/3
Image {
id: image
Layout.fillWidth: true
//Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
fillMode: Image.PreserveAspectFit
source: "icons/logo_stacked_imager.png"
source: "icons/logo_sxs_imager.png"
width: window.width
height: window.height/2
height: window.height/3
}
}
Rectangle {
color: "#c31c4a"
implicitWidth: window.width
implicitHeight: window.height/2
implicitHeight: (window.height/3) * 2
GridLayout {
id: gridLayout
rowSpacing: 25
rowSpacing: 15
anchors.fill: parent
anchors.topMargin: 25
anchors.rightMargin: 50
anchors.leftMargin: 50
rows: 6
rows: 5
columns: 3
columnSpacing: 25
columnSpacing: 15
ColumnLayout {
id: columnLayout
id: columnLayout0
spacing: 0
Layout.row: 0
Layout.column: 0
Layout.fillWidth: true
Text {
id: text0
color: "#ffffff"
text: qsTr("Raspberry Pi Device")
Layout.fillWidth: true
Layout.preferredHeight: 17
Layout.preferredWidth: 100
font.pixelSize: 12
font.family: robotoBold.name
font.bold: true
horizontalAlignment: Text.AlignHCenter
}
ImButton {
id: hwbutton
text: qsTr("CHOOSE DEVICE")
spacing: 0
padding: 0
bottomPadding: 0
topPadding: 0
Layout.minimumHeight: 40
Layout.fillWidth: true
onClicked: {
hwpopup.open()
hwlistview.currentItem.forceActiveFocus()
}
Accessible.ignored: ospopup.visible || dstpopup.visible || hwpopup.visible
Accessible.description: qsTr("Select this button to choose your target Raspberry Pi")
}
}
ColumnLayout {
id: columnLayout1
spacing: 0
Layout.row: 0
Layout.column: 1
Layout.fillWidth: true
Text {
@ -97,7 +152,6 @@ ApplicationWindow {
text: qsTr("Operating System")
Layout.fillWidth: true
Layout.preferredHeight: 17
Layout.preferredWidth: 100
font.pixelSize: 12
font.family: robotoBold.name
font.bold: true
@ -117,7 +171,7 @@ ApplicationWindow {
ospopup.open()
osswipeview.currentItem.forceActiveFocus()
}
Accessible.ignored: ospopup.visible || dstpopup.visible
Accessible.ignored: ospopup.visible || dstpopup.visible || hwpopup.visible
Accessible.description: qsTr("Select this button to change the operating system")
}
}
@ -125,6 +179,8 @@ ApplicationWindow {
ColumnLayout {
id: columnLayout2
spacing: 0
Layout.row: 0
Layout.column: 2
Layout.fillWidth: true
Text {
@ -133,7 +189,6 @@ ApplicationWindow {
text: qsTr("Storage")
Layout.fillWidth: true
Layout.preferredHeight: 17
Layout.preferredWidth: 100
font.pixelSize: 12
font.family: robotoBold.name
font.bold: true
@ -143,55 +198,29 @@ ApplicationWindow {
ImButton {
id: dstbutton
text: qsTr("CHOOSE STORAGE")
spacing: 0
padding: 0
bottomPadding: 0
topPadding: 0
Layout.minimumHeight: 40
Layout.preferredWidth: 100
Layout.preferredWidth: 200
Layout.fillWidth: true
onClicked: {
imageWriter.startDriveListPolling()
dstpopup.open()
dstlist.forceActiveFocus()
}
Accessible.ignored: ospopup.visible || dstpopup.visible
Accessible.ignored: ospopup.visible || dstpopup.visible || hwpopup.visible
Accessible.description: qsTr("Select this button to change the destination storage device")
}
}
ColumnLayout {
id: columnLayoutProgress
spacing: 0
Layout.fillWidth: true
Text {
text: " "
Layout.preferredHeight: 17
Layout.preferredWidth: 100
}
ImButton {
id: writebutton
text: qsTr("WRITE")
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
onClicked: {
if (!imageWriter.readyToWrite()) {
return
}
if (!optionspopup.initialized && imageWriter.imageSupportsCustomization() && imageWriter.hasSavedCustomizationSettings()) {
usesavedsettingspopup.openPopup()
} else {
confirmwritepopup.askForConfirmation()
}
}
}
}
ColumnLayout {
id: columnLayout3
Layout.columnSpan: 3
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.row: 1
Layout.column: 0
Layout.columnSpan: 2
Text {
id: progressText
@ -202,16 +231,32 @@ ApplicationWindow {
visible: false
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
Layout.bottomMargin: 25
padding: 5
}
ProgressBar {
Layout.bottomMargin: 25
padding: 5
id: progressBar
Layout.fillWidth: true
visible: false
Material.background: "#d15d7d"
}
}
ColumnLayout {
id: columnLayout3
Layout.row: 1
Layout.column: 2
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
spacing: 0
ImButton {
Layout.bottomMargin: 25
Layout.minimumHeight: 40
Layout.preferredWidth: 200
padding: 5
id: cancelwritebutton
text: qsTr("CANCEL WRITE")
onClicked: {
@ -223,6 +268,10 @@ ApplicationWindow {
visible: false
}
ImButton {
Layout.bottomMargin: 25
Layout.minimumHeight: 40
Layout.preferredWidth: 200
padding: 5
id: cancelverifybutton
text: qsTr("CANCEL VERIFY")
onClicked: {
@ -235,17 +284,25 @@ ApplicationWindow {
}
ImButton {
id: writebutton
text: qsTr("Next")
Layout.bottomMargin: 25
padding: 5
id: customizebutton
Layout.minimumHeight: 40
Layout.preferredWidth: 200
Layout.alignment: Qt.AlignRight
Accessible.ignored: ospopup.visible || dstpopup.visible || hwpopup.visible
Accessible.description: qsTr("Select this button to start writing the image")
enabled: false
onClicked: {
optionspopup.openPopup()
}
visible: imageWriter.imageSupportsCustomization()
Accessible.description: qsTr("Select this button to access advanced settings")
contentItem: Image {
source: "icons/ic_cog_red.svg"
fillMode: Image.PreserveAspectFit
if (!imageWriter.readyToWrite()) {
return
}
if (!optionspopup.visible && imageWriter.imageSupportsCustomization()) {
usesavedsettingspopup.openPopup()
} else {
confirmwritepopup.askForConfirmation()
}
}
}
}
@ -359,6 +416,110 @@ ApplicationWindow {
}
}
Popup {
id: hwpopup
x: 50
y: 25
width: parent.width-100
height: parent.height-50
padding: 0
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
property string hwselected: ""
// 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 {
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: {
hwpopup.close()
}
}
}
ColumnLayout {
spacing: 10
Text {
text: qsTr("Raspberry Pi Device")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
Layout.fillWidth: true
Layout.topMargin: 10
font.family: roboto.name
font.bold: true
}
Item {
clip: true
Layout.preferredWidth: hwlist.width
Layout.preferredHeight: hwlist.height
ListView {
id: hwlistview
interactive: false
ListView {
id: hwlist
model: ListModel {
id: deviceModel
ListElement {
name: qsTr("[ All ]")
tags: "[]"
icon: ""
description: ""
matching_type: "exclusive"
}
}
currentIndex: -1
delegate: hwdelegate
width: window.width-100
height: window.height-100
boundsBehavior: Flickable.StopAtBounds
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
ScrollBar.vertical: ScrollBar {
width: 10
policy: hwlist.contentHeight > hwlist.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded
}
Keys.onSpacePressed: {
if (currentIndex != -1)
selectHWitem(model.get(currentIndex))
}
Accessible.onPressAction: {
if (currentIndex != -1)
selectHWitem(model.get(currentIndex))
}
Keys.onEnterPressed: Keys.onSpacePressed(event)
Keys.onReturnPressed: Keys.onSpacePressed(event)
}
}
}
}
}
/*
Popup for OS selection
*/
@ -402,6 +563,7 @@ ApplicationWindow {
cursorShape: Qt.PointingHandCursor
onClicked: {
ospopup.close()
osswipeview.decrementCurrentIndex()
}
}
}
@ -419,59 +581,6 @@ ApplicationWindow {
font.bold: true
}
Rectangle {
id: modelRowRect
color: "#ffffe3"
Layout.fillWidth: true
implicitHeight: modelRow.implicitHeight
visible: osswipeview.currentIndex == 0
Layout.bottomMargin: -10
Row {
id: modelRow
spacing: 15
leftPadding: 15
Text {
id: modelText
text: qsTr("Pi model:")
font.family: roboto.name
verticalAlignment: Qt.AlignVCenter
height: parent.height
}
ComboBox {
id: deviceModelCombo
model: ListModel {
id: deviceModel
ListElement {
name: qsTr("[ All ]")
tags: "[]"
}
}
width: 300
textRole: "name"
font.family: roboto.name
font.pixelSize: 12
currentIndex: 0
onCurrentIndexChanged: {
/* Reload list */
httpRequest(imageWriter.constantOsListUrl(), function (x) {
var o = JSON.parse(x.responseText)
var oslist = oslistFromJson(o)
if (oslist === false)
return
osmodel.remove(0, osmodel.count-2)
for (var i in oslist) {
osmodel.insert(osmodel.count-2, oslist[i])
}
})
}
}
}
}
Item {
clip: true
Layout.preferredWidth: oslist.width
@ -487,7 +596,7 @@ ApplicationWindow {
currentIndex: -1
delegate: osdelegate
width: window.width-100
height: modelRowRect.visible ? window.height-100-modelRowRect.height : window.height-100
height: window.height-100
boundsBehavior: Flickable.StopAtBounds
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
ScrollBar.vertical: ScrollBar {
@ -559,30 +668,6 @@ ApplicationWindow {
ListModel {
id: osmodel
ListElement {
url: "internal://format"
icon: "icons/erase.png"
extract_size: 0
image_download_size: 0
extract_sha256: ""
contains_multiple_files: false
release_date: ""
subitems_url: ""
subitems_json: ""
name: qsTr("Erase")
description: qsTr("Format card as FAT32")
tooltip: ""
website: ""
init_format: ""
}
ListElement {
url: ""
icon: "icons/use_custom.png"
name: qsTr("Use custom")
description: qsTr("Select a custom .img from your computer")
}
Component.onCompleted: {
if (imageWriter.isOnline()) {
fetchOSlist();
@ -590,6 +675,97 @@ ApplicationWindow {
}
}
Component {
id: hwdelegate
Item {
width: window.width-100
height: contentLayout.implicitHeight + 24
Accessible.name: name+".\n"+description
MouseArea {
id: hwMouseArea
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: {
bgrect.mouseOver = true
}
onExited: {
bgrect.mouseOver = false
}
onClicked: {
selectHWitem(model)
}
}
Rectangle {
id: bgrect
anchors.fill: parent
color: "#f5f5f5"
visible: mouseOver && parent.ListView.view.currentIndex !== index
property bool mouseOver: false
}
Rectangle {
id: borderrect
implicitHeight: 1
implicitWidth: parent.width
color: "#dcdcdc"
y: parent.height
}
RowLayout {
id: contentLayout
anchors {
left: parent.left
top: parent.top
right: parent.right
margins: 12
}
spacing: 12
Image {
source: icon == "icons/ic_build_48px.svg" ? "icons/cat_misc_utility_images.png": icon
Layout.preferredHeight: 64
Layout.preferredWidth: 64
sourceSize.width: 64
sourceSize.height: 64
fillMode: Image.PreserveAspectFit
verticalAlignment: Image.AlignVCenter
Layout.alignment: Qt.AlignVCenter
}
ColumnLayout {
Layout.fillWidth: true
Text {
text: name
elide: Text.ElideRight
font.family: roboto.name
font.bold: true
}
Text {
Layout.fillWidth: true
font.family: roboto.name
text: description
wrapMode: Text.WordWrap
color: "#1a1a1a"
}
ToolTip {
visible: hwMouseArea.containsMouse && typeof(tooltip) == "string" && tooltip != ""
delay: 1000
text: typeof(tooltip) == "string" ? tooltip : ""
clip: false
}
}
}
}
}
Component {
id: osdelegate
@ -941,8 +1117,8 @@ ApplicationWindow {
title: qsTr("Warning")
onYes: {
langbarRect.visible = false
writebutton.visible = false
writebutton.enabled = false
customizebutton.visible = false
cancelwritebutton.enabled = true
cancelwritebutton.visible = true
cancelverifybutton.enabled = true
@ -953,6 +1129,7 @@ ApplicationWindow {
progressBar.Material.accent = "#ffffff"
osbutton.enabled = false
dstbutton.enabled = false
hwbutton.enabled = false
imageWriter.setVerifyEnabled(true)
imageWriter.startWrite()
}
@ -1071,9 +1248,9 @@ ApplicationWindow {
function resetWriteButton() {
progressText.visible = false
progressBar.visible = false
customizebutton.visible = imageWriter.imageSupportsCustomization()
osbutton.enabled = true
dstbutton.enabled = true
hwbutton.enabled = true
writebutton.visible = true
writebutton.enabled = imageWriter.readyToWrite()
cancelwritebutton.visible = false
@ -1113,10 +1290,10 @@ ApplicationWindow {
imageWriter.setSrc(file)
osbutton.text = imageWriter.srcFileName()
ospopup.close()
osswipeview.decrementCurrentIndex()
if (imageWriter.readyToWrite()) {
writebutton.enabled = true
}
customizebutton.visible = imageWriter.imageSupportsCustomization()
}
function onCancelled() {
@ -1150,7 +1327,7 @@ ApplicationWindow {
}
}
function filterItems(list, tags)
function filterItems(list, tags, matchingType)
{
if (!tags || !tags.length)
return
@ -1162,24 +1339,67 @@ ApplicationWindow {
if ("devices" in entry && entry["devices"].length) {
var foundTag = false
for (var j in tags)
{
if (entry["devices"].includes(tags[j]))
{
foundTag = true
switch(matchingType) {
case 0: /* exact matching */
case 2: /* exact matching */
for (var j in tags)
{
if (entry["devices"].includes(tags[j]))
{
foundTag = true
break
}
}
/* If there's no match, remove this item from the list. */
if (!foundTag)
{
list.splice(i, 1)
continue
}
break
case 1: /* Exlusive by prefix matching */
case 3: /* Inclusive by prefix matching */
for (var deviceTypePrefix in tags) {
for (var deviceSpec in entry["devices"]) {
if (deviceSpec.startsWith(deviceTypePrefix)) {
foundTag = true
break
}
}
/* Terminate outer loop early if we've already
* decided it's a match
*/
if (foundTag) {
break
}
}
/* If there's no match, remove this item from the list. */
if (!foundTag)
{
list.splice(i, 1)
continue
}
break
}
}
if (!foundTag)
{
list.splice(i, 1)
continue
} else {
/* No device list attached? If we're in an exclusive mode that's bad news indeed. */
switch (matchingType) {
case 0:
case 1:
if (!("subitems" in entry)) {
/* If you're not carrying subitems, you're not going in. */
list.splice(i, 1)
}
break
case 2:
case 3:
/* Inclusive filtering. We're keeping this one. */
break;
}
}
if ("subitems" in entry) {
filterItems(entry["subitems"], tags)
filterItems(entry["subitems"], tags, hwTagMatchingType)
}
}
}
@ -1206,7 +1426,9 @@ ApplicationWindow {
oslist = o["os_list"]
}
filterItems(oslist, JSON.parse(deviceModel.get(deviceModelCombo.currentIndex).tags))
if (hwTags != "") {
filterItems(oslist, JSON.parse(hwTags), hwTagMatchingType)
}
checkForRandom(oslist)
/* Flatten subitems to subitems_json */
@ -1242,8 +1464,9 @@ ApplicationWindow {
var oslist = oslistFromJson(o)
if (oslist === false)
return
osmodel.clear()
for (var i in oslist) {
osmodel.insert(osmodel.count-2, oslist[i])
osmodel.append(oslist[i])
}
if ("imager" in o) {
@ -1251,6 +1474,7 @@ ApplicationWindow {
if ("devices" in imager)
{
deviceModel.clear()
var devices = imager["devices"]
for (var j in devices)
{
@ -1258,7 +1482,7 @@ ApplicationWindow {
deviceModel.append(devices[j])
if ("default" in devices[j] && devices[j]["default"])
{
deviceModelCombo.currentIndex = deviceModel.count-1
hwlist.currentIndex = deviceModel.count-1
}
}
}
@ -1283,6 +1507,31 @@ ApplicationWindow {
}
}
}
/* Add in our 'special' items. */
osmodel.append({
url: "internal://format",
icon: "icons/erase.png",
extract_size: 0,
image_download_size: 0,
extract_sha256: "",
contains_multiple_files: false,
release_date: "",
subitems_url: "",
subitems_json: "",
name: qsTr("Erase"),
description: qsTr("Format card as FAT32"),
tooltip: "",
website: "",
init_format: ""
})
osmodel.append({
url: "",
icon: "icons/use_custom.png",
name: qsTr("Use custom"),
description: qsTr("Select a custom .img from your computer")
})
})
}
@ -1326,6 +1575,46 @@ ApplicationWindow {
return m
}
function selectHWitem(hwmodel) {
hwTags = hwmodel.tags
if (hwmodel.matching_type) {
switch (hwmodel.matching_type) {
case "exclusive":
hwTagMatchingType = 0
break;
case "exclusive_prefix":
hwTagMatchingType = 1
break;
case "inclusive":
hwTagMatchingType = 2
break;
case "inclusive_prefix":
hwTagMatchingType = 3
break;
}
} else {
/* Default is exclusive exact matching */
hwTagMatchingType = 0
}
/* Reload list */
httpRequest(imageWriter.constantOsListUrl(), function (x) {
var o = JSON.parse(x.responseText)
var oslist = oslistFromJson(o)
if (oslist === false)
return
osmodel.remove(0, osmodel.count-2)
for (var i in oslist) {
osmodel.insert(osmodel.count-2, oslist[i])
}
})
hwbutton.text = hwmodel.name
hwpopup.close()
}
function selectOSitem(d, selectFirstSubitem)
{
if (typeof(d.subitems_json) == "string" && d.subitems_json !== "") {
@ -1395,10 +1684,10 @@ ApplicationWindow {
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, ospopup.categorySelected, d.name, typeof(d.init_format) != "undefined" ? d.init_format : "")
osbutton.text = d.name
ospopup.close()
osswipeview.decrementCurrentIndex()
if (imageWriter.readyToWrite()) {
writebutton.enabled = true
}
customizebutton.visible = imageWriter.imageSupportsCustomization()
}
}

View file

@ -32,6 +32,7 @@
<file>icons/cat_language_specific_operating_systems.png</file>
<file>icons/cat_3d_printing.png</file>
<file>icons/logo_stacked_imager.png</file>
<file>icons/logo_sxs_imager.png</file>
<file>qmlcomponents/ImButton.qml</file>
<file>qmlcomponents/ImCheckBox.qml</file>
<file>qmlcomponents/ImRadioButton.qml</file>