Linux embedded: misc improvements
- Allow static build - Use .svg icons - Linux Embedded lacks normal "open file dialog". So simply scan files in root folder of USB stick and return list. - Change QProcess::execute(command) calls to QProcess::execute(command, args) calls to silence Qt 5.15.0 depreciation warning.
|
@ -240,5 +240,12 @@ else()
|
|||
install(FILES linux/rpi-imager.desktop DESTINATION share/applications)
|
||||
endif()
|
||||
|
||||
get_target_property(QT_TARGET_TYPE Qt5::Core TYPE)
|
||||
if(${QT_TARGET_TYPE} STREQUAL "STATIC_LIBRARY")
|
||||
find_package(Qt5QmlImportScanner REQUIRED)
|
||||
qt5_import_qml_plugins(${PROJECT_NAME})
|
||||
qt5_import_plugins(${PROJECT_NAME} INCLUDE Qt5::QSvgPlugin)
|
||||
endif()
|
||||
|
||||
include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick Qt5::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS})
|
||||
|
|
|
@ -186,7 +186,7 @@ void DriveFormatThread::run()
|
|||
return;
|
||||
}
|
||||
|
||||
proc.execute("partprobe");
|
||||
proc.execute("partprobe", QStringList() );
|
||||
|
||||
args.clear();
|
||||
args << fatpartition;
|
||||
|
|
Before Width: | Height: | Size: 493 B |
6
icons/ic_build_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 37.832031 31.582031 L 22.582031 16.332031 C 24.082031 12.5 23.25 7.917969 20.167969 4.832031 C 16.832031 1.5 11.832031 0.832031 7.832031 2.75 L 15.082031 10 L 10 15.082031 L 2.75 7.832031 C 0.832031 11.832031 1.5 16.832031 4.832031 20.167969 C 7.917969 23.25 12.5 24.082031 16.332031 22.582031 L 31.582031 37.832031 C 32.25 38.5 33.332031 38.5 33.917969 37.832031 L 37.832031 33.917969 C 38.5 33.332031 38.5 32.25 37.832031 31.582031 Z M 37.832031 31.582031 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 761 B |
Before Width: | Height: | Size: 224 B |
6
icons/ic_chevron_left_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 25.691406 12.359375 L 23.332031 10 L 13.332031 20 L 23.332031 30 L 25.691406 27.640625 L 18.050781 20 Z M 25.691406 12.359375 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 429 B |
Before Width: | Height: | Size: 225 B |
6
icons/ic_chevron_right_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 16.667969 10 L 14.308594 12.359375 L 21.949219 20 L 14.308594 27.640625 L 16.667969 30 L 26.667969 20 Z M 16.667969 10 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 422 B |
Before Width: | Height: | Size: 202 B |
Before Width: | Height: | Size: 321 B |
6
icons/ic_computer_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 33.332031 30 C 35.175781 30 36.648438 28.507812 36.648438 26.667969 L 36.667969 10 C 36.667969 8.160156 35.175781 6.667969 33.332031 6.667969 L 6.667969 6.667969 C 4.824219 6.667969 3.332031 8.160156 3.332031 10 L 3.332031 26.667969 C 3.332031 28.507812 4.824219 30 6.667969 30 L 0 30 L 0 33.332031 L 40 33.332031 L 40 30 Z M 6.667969 10 L 33.332031 10 L 33.332031 26.667969 L 6.667969 26.667969 Z M 6.667969 10 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 715 B |
Before Width: | Height: | Size: 278 B |
6
icons/ic_delete_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 10 31.667969 C 10 33.507812 11.492188 35 13.332031 35 L 26.667969 35 C 28.507812 35 30 33.507812 30 31.667969 L 30 11.667969 L 10 11.667969 Z M 31.667969 6.667969 L 25.832031 6.667969 L 24.167969 5 L 15.832031 5 L 14.167969 6.667969 L 8.332031 6.667969 L 8.332031 10 L 31.667969 10 Z M 31.667969 6.667969 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 608 B |
Before Width: | Height: | Size: 372 B |
6
icons/ic_sd_storage_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 30 3.332031 L 16.667969 3.332031 L 6.699219 13.332031 L 6.667969 33.332031 C 6.667969 35.167969 8.167969 36.667969 10 36.667969 L 30 36.667969 C 31.832031 36.667969 33.332031 35.167969 33.332031 33.332031 L 33.332031 6.667969 C 33.332031 4.832031 31.832031 3.332031 30 3.332031 Z M 20 13.332031 L 16.667969 13.332031 L 16.667969 6.667969 L 20 6.667969 Z M 25 13.332031 L 21.667969 13.332031 L 21.667969 6.667969 L 25 6.667969 Z M 30 13.332031 L 26.667969 13.332031 L 26.667969 6.667969 L 30 6.667969 Z M 30 13.332031 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 820 B |
Before Width: | Height: | Size: 235 B |
6
icons/ic_storage_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 3.332031 33.332031 L 36.667969 33.332031 L 36.667969 26.667969 L 3.332031 26.667969 Z M 6.667969 28.332031 L 10 28.332031 L 10 31.667969 L 6.667969 31.667969 Z M 3.332031 6.667969 L 3.332031 13.332031 L 36.667969 13.332031 L 36.667969 6.667969 Z M 10 11.667969 L 6.667969 11.667969 L 6.667969 8.332031 L 10 8.332031 Z M 3.332031 23.332031 L 36.667969 23.332031 L 36.667969 16.667969 L 3.332031 16.667969 Z M 6.667969 18.332031 L 10 18.332031 L 10 21.667969 L 6.667969 21.667969 Z M 6.667969 18.332031 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 804 B |
Before Width: | Height: | Size: 513 B |
6
icons/ic_usb_40px.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40pt" height="40pt" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 25 11.667969 L 25 18.332031 L 26.667969 18.332031 L 26.667969 21.667969 L 21.667969 21.667969 L 21.667969 8.332031 L 25 8.332031 L 20 1.667969 L 15 8.332031 L 18.332031 8.332031 L 18.332031 21.667969 L 13.332031 21.667969 L 13.332031 18.214844 C 14.507812 17.609375 15.332031 16.417969 15.332031 15 C 15.332031 12.976562 13.691406 11.332031 11.667969 11.332031 C 9.640625 11.332031 8 12.976562 8 15 C 8 16.417969 8.824219 17.609375 10 18.214844 L 10 21.667969 C 10 23.507812 11.492188 25 13.332031 25 L 18.332031 25 L 18.332031 30.082031 C 17.148438 30.691406 16.332031 31.910156 16.332031 33.332031 C 16.332031 35.359375 17.976562 37 20 37 C 22.023438 37 23.667969 35.359375 23.667969 33.332031 C 23.667969 31.910156 22.851562 30.691406 21.667969 30.082031 L 21.667969 25 L 26.667969 25 C 28.507812 25 30 23.507812 30 21.667969 L 30 18.332031 L 31.667969 18.332031 L 31.667969 11.667969 Z M 25 11.667969 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
BIN
icons/rpi2-hires.png
Normal file
After Width: | Height: | Size: 68 KiB |
|
@ -476,6 +476,7 @@ void ImageWriter::pollNetwork()
|
|||
if (!a.isLoopback() && a.scopeId().isEmpty())
|
||||
{
|
||||
/* Not a loopback or IPv6 link-local address, so online */
|
||||
qDebug() << "IP:" << a;
|
||||
_online = true;
|
||||
break;
|
||||
}
|
||||
|
@ -484,14 +485,23 @@ void ImageWriter::pollNetwork()
|
|||
if (_online)
|
||||
{
|
||||
_networkchecktimer.stop();
|
||||
qDebug() << "Network online. Synchronizing time.";
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
||||
connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(onTimeSyncReply(QNetworkReply*)));
|
||||
manager->head(QNetworkRequest(QUrl(TIME_URL)));
|
||||
|
||||
// Wait another 0.1 sec, as dhcpcd may not have set up nameservers yet
|
||||
QTimer::singleShot(100, this, SLOT(syncTime()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImageWriter::syncTime()
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
qDebug() << "Network online. Synchronizing time.";
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
||||
connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(onTimeSyncReply(QNetworkReply*)));
|
||||
manager->head(QNetworkRequest(QUrl(TIME_URL)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImageWriter::onTimeSyncReply(QNetworkReply *reply)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
|
@ -508,7 +518,8 @@ void ImageWriter::onTimeSyncReply(QNetworkReply *reply)
|
|||
}
|
||||
else
|
||||
{
|
||||
// TODO: try again later?
|
||||
qDebug() << "Error synchronizing time. Trying again in 3 seconds";
|
||||
QTimer::singleShot(3000, this, SLOT(syncTime()));
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
@ -520,6 +531,76 @@ bool ImageWriter::isEmbeddedMode()
|
|||
return _embeddedMode;
|
||||
}
|
||||
|
||||
/* Mount any USB sticks that can contain source images under /media */
|
||||
bool ImageWriter::mountUsbSourceMedia()
|
||||
{
|
||||
int devices = 0;
|
||||
#ifdef Q_OS_LINUX
|
||||
QDir dir("/sys/class/block");
|
||||
QStringList list = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
||||
if (!dir.exists("/media"))
|
||||
dir.mkdir("/media");
|
||||
|
||||
for (auto devname : list)
|
||||
{
|
||||
if (!devname.startsWith("mmcblk0") && !QFile::symLinkTarget("/sys/class/block/"+devname).contains("/devices/virtual/"))
|
||||
{
|
||||
QString mntdir = "/media/"+devname;
|
||||
|
||||
if (dir.exists(mntdir))
|
||||
{
|
||||
devices++;
|
||||
continue;
|
||||
}
|
||||
|
||||
dir.mkdir(mntdir);
|
||||
QStringList args = { "-o", "ro", QString("/dev/")+devname, mntdir };
|
||||
|
||||
if ( QProcess::execute("mount", args) == 0 )
|
||||
devices++;
|
||||
else
|
||||
dir.rmdir(mntdir);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return devices > 0;
|
||||
}
|
||||
|
||||
QByteArray ImageWriter::getUsbSourceOSlist()
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
QJsonArray oslist;
|
||||
QDir dir("/media");
|
||||
QStringList medialist = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
QStringList namefilters = {"*.img", "*.zip", "*.gz", "*.xz"};
|
||||
|
||||
for (auto devname : medialist)
|
||||
{
|
||||
QDir subdir("/media/"+devname);
|
||||
QStringList files = subdir.entryList(namefilters, QDir::Files, QDir::Name);
|
||||
for (auto file : files)
|
||||
{
|
||||
QString path = "/media/"+devname+"/"+file;
|
||||
QFileInfo fi(path);
|
||||
|
||||
QJsonObject f = {
|
||||
{"name", file},
|
||||
{"description", devname+"/"+file},
|
||||
{"url", QUrl::fromLocalFile(path).toString() },
|
||||
{"release_date", ""},
|
||||
{"image_download_size", fi.size()}
|
||||
};
|
||||
oslist.append(f);
|
||||
}
|
||||
}
|
||||
|
||||
return QJsonDocument(oslist).toJson();
|
||||
#else
|
||||
return QByteArray();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MountUtilsLog(std::string msg) {
|
||||
qDebug() << "mountutils:" << msg.c_str();
|
||||
}
|
||||
|
|
|
@ -75,8 +75,16 @@ public:
|
|||
/* Returns true if online */
|
||||
Q_INVOKABLE bool isOnline();
|
||||
|
||||
/* Returns true if run on embedded Linux platform */
|
||||
Q_INVOKABLE bool isEmbeddedMode();
|
||||
|
||||
/* Mount any USB sticks that can contain source images under /media
|
||||
Returns true if at least one device was mounted */
|
||||
Q_INVOKABLE bool mountUsbSourceMedia();
|
||||
|
||||
/* Returns a json formatted list of the OS images found on USB stick */
|
||||
Q_INVOKABLE QByteArray getUsbSourceOSlist();
|
||||
|
||||
signals:
|
||||
/* We are emiting signals with QVariant as parameters because QML likes it that way */
|
||||
|
||||
|
@ -93,6 +101,7 @@ protected slots:
|
|||
|
||||
void pollProgress();
|
||||
void pollNetwork();
|
||||
void syncTime();
|
||||
void onSuccess();
|
||||
void onError(QString msg);
|
||||
void onFileSelected(QString filename);
|
||||
|
|
|
@ -48,7 +48,8 @@ namespace Drivelist
|
|||
std::vector<DeviceDescriptor> deviceList;
|
||||
|
||||
QProcess p;
|
||||
p.start("lsblk --bytes --json --paths --output-all");
|
||||
QStringList args = { "--bytes", "--json", "--paths", "--output-all" };
|
||||
p.start("lsblk", args);
|
||||
p.waitForFinished(2000);
|
||||
QByteArray output = p.readAll();
|
||||
|
||||
|
|
10
main.cpp
|
@ -17,6 +17,7 @@
|
|||
#include <QQuickWindow>
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QScreen>
|
||||
#ifndef QT_NO_WIDGETS
|
||||
#include <QtWidgets/QApplication>
|
||||
#endif
|
||||
|
@ -37,6 +38,15 @@ int main(int argc, char *argv[])
|
|||
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
#ifdef QT_NO_WIDGETS
|
||||
{
|
||||
QGuiApplication tmp(argc, argv);
|
||||
int h = QGuiApplication::primaryScreen()->geometry().height();
|
||||
if (h > 720)
|
||||
{
|
||||
qputenv("QT_SCALE_FACTOR", QByteArray::number(h / 720.0, 'f', 2));
|
||||
}
|
||||
}
|
||||
|
||||
QGuiApplication app(argc, argv);
|
||||
#else
|
||||
QApplication app(argc, argv);
|
||||
|
|
65
main.qml
|
@ -13,12 +13,13 @@ import Qt.labs.settings 1.0
|
|||
ApplicationWindow {
|
||||
id: window
|
||||
visible: true
|
||||
width: 680
|
||||
height: 420
|
||||
minimumWidth: 680
|
||||
maximumWidth: 680
|
||||
minimumHeight: 420
|
||||
maximumHeight: 420
|
||||
|
||||
width: imageWriter.isEmbeddedMode() ? -1 : 680
|
||||
height: imageWriter.isEmbeddedMode() ? -1 : 420
|
||||
minimumWidth: imageWriter.isEmbeddedMode() ? -1 : 680
|
||||
maximumWidth: imageWriter.isEmbeddedMode() ? -1 : 680
|
||||
minimumHeight: imageWriter.isEmbeddedMode() ? -1 : 420
|
||||
maximumHeight: imageWriter.isEmbeddedMode() ? -1 : 420
|
||||
|
||||
title: qsTr("Raspberry Pi Imager v%1").arg(imageWriter.constantVersion())
|
||||
|
||||
|
@ -50,13 +51,18 @@ ApplicationWindow {
|
|||
id: bg
|
||||
spacing: 0
|
||||
|
||||
Image {
|
||||
id: image
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.preferredWidth: window.width
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "icons/rpi2.png"
|
||||
Rectangle {
|
||||
implicitHeight: window.height/2
|
||||
|
||||
Image {
|
||||
id: image
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: imageWriter.isEmbeddedMode() ? "icons/rpi2-hires.png" : "icons/rpi2.png"
|
||||
width: window.width
|
||||
height: window.height/2
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
@ -347,7 +353,7 @@ ApplicationWindow {
|
|||
|
||||
ListElement {
|
||||
url: "internal://format"
|
||||
icon: "icons/ic_delete_40px.png"
|
||||
icon: "icons/ic_delete_40px.svg"
|
||||
extract_size: 0
|
||||
image_download_size: 0
|
||||
extract_sha256: ""
|
||||
|
@ -362,7 +368,7 @@ ApplicationWindow {
|
|||
|
||||
ListElement {
|
||||
url: ""
|
||||
icon: "icons/ic_computer_40px.png"
|
||||
icon: "icons/ic_computer_40px.svg"
|
||||
name: qsTr("Use custom")
|
||||
description: qsTr("Select a custom .img from your computer")
|
||||
}
|
||||
|
@ -379,7 +385,7 @@ ApplicationWindow {
|
|||
|
||||
ListElement {
|
||||
url: ""
|
||||
icon: "icons/ic_chevron_left_40px.png"
|
||||
icon: "icons/ic_chevron_left_40px.svg"
|
||||
extract_size: 0
|
||||
image_download_size: 0
|
||||
extract_sha256: ""
|
||||
|
@ -421,7 +427,7 @@ ApplicationWindow {
|
|||
width: 64
|
||||
|
||||
Image {
|
||||
source: icon == "icons/ic_build_48px.svg" ? "icons/ic_build_40px.png": icon
|
||||
source: icon == "icons/ic_build_48px.svg" ? "icons/ic_build_40px.svg": icon
|
||||
verticalAlignment: Image.AlignVCenter
|
||||
height: parent.parent.parent.height
|
||||
fillMode: Image.Pad
|
||||
|
@ -447,6 +453,8 @@ ApplicationWindow {
|
|||
if (typeof(url) == "string" && url != "" && url != "internal://format") {
|
||||
if (typeof(extract_sha256) != "undefined" && imageWriter.isCached(url,extract_sha256)) {
|
||||
txt += "<br>"+qsTr("Cached on your computer")
|
||||
} else if (url.startsWith("file://")) {
|
||||
txt += "<br>"+qsTr("Local file")
|
||||
} else {
|
||||
txt += "<br>"+qsTr("Online - %1 GB download").arg((image_download_size/1073741824).toFixed(1));
|
||||
}
|
||||
|
@ -467,7 +475,7 @@ ApplicationWindow {
|
|||
}
|
||||
Column {
|
||||
Image {
|
||||
source: "icons/ic_chevron_right_40px.png"
|
||||
source: "icons/ic_chevron_right_40px.svg"
|
||||
visible: (typeof(subitems) == "object" && subitems.count) || (typeof(subitems_url) == "string" && subitems_url != "" && subitems_url != "internal://back")
|
||||
height: parent.parent.parent.height
|
||||
fillMode: Image.Pad
|
||||
|
@ -531,8 +539,22 @@ ApplicationWindow {
|
|||
imageWriter.openFileDialog()
|
||||
}
|
||||
else {
|
||||
// FIXME: provide QML file dialog
|
||||
onError("Using custom images is not implemented on this platform yet.")
|
||||
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.<br>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)
|
||||
|
@ -547,7 +569,6 @@ ApplicationWindow {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Popup for SD card device selection
|
||||
*/
|
||||
|
@ -658,7 +679,7 @@ ApplicationWindow {
|
|||
width: 64
|
||||
|
||||
Image {
|
||||
source: isUsb ? "icons/ic_usb_40px.png" : isScsi ? "icons/ic_storage_40px.png" : "icons/ic_sd_storage_40px.png"
|
||||
source: isUsb ? "icons/ic_usb_40px.svg" : isScsi ? "icons/ic_storage_40px.svg" : "icons/ic_sd_storage_40px.svg"
|
||||
verticalAlignment: Image.AlignVCenter
|
||||
height: parent.parent.parent.height
|
||||
fillMode: Image.Pad
|
||||
|
|
18
qml.qrc
|
@ -7,14 +7,14 @@
|
|||
<file>fonts/Roboto-Bold.ttf</file>
|
||||
<file>fonts/Roboto-Light.ttf</file>
|
||||
<file>fonts/Roboto-Regular.ttf</file>
|
||||
<file>icons/ic_chevron_right_40px.png</file>
|
||||
<file>icons/ic_chevron_left_40px.png</file>
|
||||
<file>icons/ic_computer_40px.png</file>
|
||||
<file>icons/ic_delete_40px.png</file>
|
||||
<file>icons/ic_usb_40px.png</file>
|
||||
<file>icons/ic_storage_40px.png</file>
|
||||
<file>icons/ic_sd_storage_40px.png</file>
|
||||
<file>icons/ic_build_40px.png</file>
|
||||
<file>icons/ic_close_18px.png</file>
|
||||
<file>icons/rpi2-hires.png</file>
|
||||
<file>icons/ic_build_40px.svg</file>
|
||||
<file>icons/ic_chevron_left_40px.svg</file>
|
||||
<file>icons/ic_chevron_right_40px.svg</file>
|
||||
<file>icons/ic_computer_40px.svg</file>
|
||||
<file>icons/ic_delete_40px.svg</file>
|
||||
<file>icons/ic_sd_storage_40px.svg</file>
|
||||
<file>icons/ic_storage_40px.svg</file>
|
||||
<file>icons/ic_usb_40px.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|