diff --git a/CMakeLists.txt b/CMakeLists.txt
index 27d6eeb..7a661e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,8 +75,8 @@ if (Qt5Widgets_FOUND)
set(EXTRALIBS ${EXTRALIBS} Qt5::Widgets)
endif()
-#qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} i18n/rpi-imager_en.ts i18n/rpi-imager_nl.ts i18n/rpi-imager_zh_cn.ts i18n/rpi-imager_tr.ts i18n/rpi-imager_fr.ts i18n/rpi-imager_de.ts i18n/rpi-imager_it.ts)
-qt5_add_translation(QM_FILES i18n/rpi-imager_en.ts i18n/rpi-imager_nl.ts i18n/rpi-imager_zh_cn.ts i18n/rpi-imager_tr.ts i18n/rpi-imager_fr.ts i18n/rpi-imager_de.ts i18n/rpi-imager_it.ts)
+#qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} i18n/rpi-imager_en.ts i18n/rpi-imager_nl.ts i18n/rpi-imager_zh_cn.ts i18n/rpi-imager_tr.ts i18n/rpi-imager_fr.ts i18n/rpi-imager_de.ts i18n/rpi-imager_sk.ts i18n/rpi-imager_it.ts)
+qt5_add_translation(QM_FILES i18n/rpi-imager_en.ts i18n/rpi-imager_nl.ts i18n/rpi-imager_zh_cn.ts i18n/rpi-imager_tr.ts i18n/rpi-imager_fr.ts i18n/rpi-imager_de.ts i18n/rpi-imager_sk.ts i18n/rpi-imager_it.ts)
configure_file(i18n/translations.qrc "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
set(SOURCES ${SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc ${QM_FILES})
diff --git a/downloadthread.cpp b/downloadthread.cpp
index aee6a94..10b427b 100644
--- a/downloadthread.cpp
+++ b/downloadthread.cpp
@@ -91,8 +91,24 @@ size_t DownloadThread::_curl_header_callback( void *ptr, size_t size, size_t nme
return len;
}
+QByteArray DownloadThread::_fileGetContentsTrimmed(const QString &filename)
+{
+ QByteArray result;
+ QFile f(filename);
+
+ if (f.exists() && f.open(f.ReadOnly))
+ {
+ result = f.readAll().trimmed();
+ f.close();
+ }
+
+ return result;
+}
+
bool DownloadThread::_openAndPrepareDevice()
{
+ emit preparationStatusUpdate(tr("opening drive"));
+
if (_filename.startsWith("/dev/"))
{
unmount_disk(_filename.constData());
@@ -203,11 +219,65 @@ bool DownloadThread::_openAndPrepareDevice()
}
#endif
+#ifdef Q_OS_LINUX
+ /* Optional optimizations for Linux */
+
+ if (_filename.startsWith("/dev/"))
+ {
+ QString devname = _filename.mid(5);
+
+ /* On some internal SD card readers CID/CSD is available, print it for debugging purposes */
+ QByteArray cid = _fileGetContentsTrimmed("/sys/block/"+devname+"/device/cid");
+ QByteArray csd = _fileGetContentsTrimmed("/sys/block/"+devname+"/device/csd");
+ if (!cid.isEmpty())
+ qDebug() << "SD card CID:" << cid;
+ if (!csd.isEmpty())
+ qDebug() << "SD card CSD:" << csd;
+
+ QByteArray discardmax = _fileGetContentsTrimmed("/sys/block/"+devname+"/queue/discard_max_bytes");
+
+ if (discardmax.isEmpty() || discardmax == "0")
+ {
+ qDebug() << "BLKDISCARD not supported";
+ }
+ else
+ {
+ /* DISCARD/TRIM the SD card */
+ uint64_t devsize, range[2];
+ int fd = _file.handle();
+
+ if (::ioctl(fd, BLKGETSIZE64, &devsize) == -1) {
+ qDebug() << "Error getting device/sector size with BLKGETSIZE64 ioctl():" << strerror(errno);
+ }
+ else
+ {
+ qDebug() << "Try to perform TRIM/DISCARD on device";
+ range[0] = 0;
+ range[1] = devsize;
+ emit preparationStatusUpdate(tr("discarding existing data on drive"));
+ _timer.start();
+ if (::ioctl(fd, BLKDISCARD, &range) == -1)
+ {
+ qDebug() << "BLKDISCARD failed.";
+ }
+ else
+ {
+ qDebug() << "BLKDISCARD successful. Discarding took" << _timer.elapsed() / 1000 << "seconds";
+ }
+ }
+ }
+ }
+#endif
+
#ifndef Q_OS_WIN
// Zero out MBR
qint64 knownsize = _file.size();
QByteArray emptyMB(1024*1024, 0);
+ emit preparationStatusUpdate(tr("zeroing out first and last MB of drive"));
+ qDebug() << "Zeroing out first and last MB of drive";
+ _timer.start();
+
if (!_file.write(emptyMB.data(), emptyMB.size()) || !_file.flush())
{
emit error(tr("Write error while zero'ing out MBR"));
@@ -229,36 +299,10 @@ bool DownloadThread::_openAndPrepareDevice()
}
emptyMB.clear();
_file.seek(0);
+ qDebug() << "Done zeroing out start and end of drive. Took" << _timer.elapsed() / 1000 << "seconds";
#endif
#ifdef Q_OS_LINUX
- /* Optional optimizations for Linux */
-
- /* See if we can DISCARD/TRIM the SD card */
- uint64_t devsize, range[2];
- int fd = _file.handle();
-
- if (::ioctl(fd, BLKGETSIZE64, &devsize) == -1) {
- qDebug() << "Error getting device/sector size with BLKGETSIZE64 ioctl():" << strerror(errno);
- }
- else
- {
- int secsize;
- ::ioctl(fd, BLKSSZGET, &secsize);
- qDebug() << "Sector size:" << secsize << "Device size:" << devsize;
-
- qDebug() << "Try to perform TRIM/DISCARD on device";
- range[0] = 0;
- range[1] = devsize;
- if (::ioctl(fd, BLKDISCARD, &range) == -1)
- {
- qDebug() << "BLKDISCARD not supported";
- }
- else
- {
- qDebug() << "BLKDISCARD successful";
- }
- }
_sectorsStart = _sectorsWritten();
#endif
@@ -303,6 +347,7 @@ void DownloadThread::run()
if (!_proxy.isEmpty())
curl_easy_setopt(_c, CURLOPT_PROXY, _proxy.constData());
+ emit preparationStatusUpdate(tr("starting download"));
_timer.start();
CURLcode ret = curl_easy_perform(_c);
diff --git a/downloadthread.h b/downloadthread.h
index 2f46b95..37f52a8 100644
--- a/downloadthread.h
+++ b/downloadthread.h
@@ -126,6 +126,7 @@ signals:
void error(QString msg);
void cacheFileUpdated(QByteArray sha256);
void finalizing();
+ void preparationStatusUpdate(QString msg);
protected:
virtual void run();
@@ -140,6 +141,7 @@ protected:
void _writeCache(const char *buf, size_t len);
qint64 _sectorsWritten();
void _closeFiles();
+ QByteArray _fileGetContentsTrimmed(const QString &filename);
/*
* libcurl callbacks
diff --git a/i18n/rpi-imager_sk.ts b/i18n/rpi-imager_sk.ts
new file mode 100644
index 0000000..cbf096f
--- /dev/null
+++ b/i18n/rpi-imager_sk.ts
@@ -0,0 +1,450 @@
+
+
+
+
+ DownloadExtractThread
+
+
+ Error writing to storage
+ Chyba pri zápise na úložisko
+
+
+
+
+ Error extracting archive: %1
+ Chyba pri rozbaľovaní archívu: %1
+
+
+
+ Error mounting FAT32 partition
+ Chyba pri pripájaní partície FAT32
+
+
+
+ Operating system did not mount FAT32 partition
+ Operačný systém nepripojil partíciu FAT32
+
+
+
+ Error changing to directory '%1'
+ Chyba pri vstupe do adresára '%1'
+
+
+
+ DownloadThread
+
+
+ Error running diskpart: %1
+ Chyba počas behu diskpart: %1
+
+
+
+ Error removing existing partitions
+ Chyba pri odstraňovaní existujúcich partiícií
+
+
+
+ Authentication cancelled
+ Zrušená autentifikácia
+
+
+
+ Error running authopen to gain access to disk device '%1'
+ Chyba pri spúšťaní authopen v snahe o získanie prístupu na diskové zariadenie '%1'
+
+
+
+ Please verify if 'Raspberry Pi Imager' is allowed access to 'removable volumes' in privacy settings (under 'files and folders' or alternatively give it 'full disk access').
+ Preverte, prosím, či má 'Raspberry Pi Imager' prístup k 'vymeniteľným nosičom' v nastaveniach súkromia (pod 'súbormi a priečinkami', prípadne mu udeľte 'plný prístup k diskom').
+
+
+
+ Cannot open storage device '%1'.
+ Nepodarilo sa otvoriť zariadenie úložiska '%1'.
+
+
+
+ Write error while zero'ing out MBR
+ Chyba zápisu pri prepisovaní MBR nulami
+
+
+
+ Write error while trying to zero out last part of card.
+Card could be advertising wrong capacity (possible counterfeit)
+ Chyba zápisu pri prepisovaní poslednej časti karty nulami.
+Karta pravdepodobne udáva nesprávnu kapacitu (a môže byť falošná)
+
+
+
+ Access denied error while writing file to disk.
+ Odopretý prístup pri zápise súboru na disk.
+
+
+
+ Controlled Folder Access seems to be enabled. Please add both rpi-imager.exe and fat32format.exe to the list of allowed apps and try again.
+ Vyzerá, že máte zapnutý Controlled Folder Access. Pridajte, prosím, rpi-imager.exe a fat32format.exe do zoznamu povolených aplikácií a skúste to znovu.
+
+
+
+ Error writing file to disk
+ Chyba pri zápise na disk
+
+
+
+ Error writing to storage (while flushing)
+ Chyba pri zápise na úložisko (počas volania flush)
+
+
+
+ Error writing to storage (while fsync)
+ Chyba pri zápise na úložisko (počas volania fsync)
+
+
+
+ Download corrupt. Hash does not match
+ Stiahnutý súbor je poškodený. Kontrolný súčet nesedí
+
+
+
+ Error writing first block (partition table)
+ Chyba pri zápise prvého bloku (tabuľky partícií)
+
+
+
+ Error reading from storage.
+SD card may be broken.
+ Chyba pri čítaní z úložiska.
+Karta SD môže byť poškodená.
+
+
+
+ Verifying write failed. Contents of SD card is different from what was written to it.
+ Overovanie zápisu skončilo s chybou. Obsah karty SD sa nezhoduje s tým, čo na ňu bolo zapísané.
+
+
+
+ DriveFormatThread
+
+
+
+
+ Error partitioning: %1
+ Chyba pri zápise partícií: %1
+
+
+
+ Error starting fat32format
+ Chyba pri spustení fat32format
+
+
+
+ Error running fat32format: %1
+ Chyba pri spustení fat32format: %1
+
+
+
+ Error determining new drive letter
+ Chyba pri zisťovaní písmena nového disku
+
+
+
+ Invalid device: %1
+ Neplatné zariadenie: %1
+
+
+
+ Error formatting (through udisks2)
+ Chyba pri formátovaní (pomocou udisks2)
+
+
+
+ Error starting sfdisk
+ Chyba pri spustení sfdisk
+
+
+
+ Error starting mkfs.fat
+ Chyba pri spustení mkfs.fat
+
+
+
+ Error running mkfs.fat: %1
+ Chyba pri spustení mkfs.fat: %1
+
+
+
+ Formatting not implemented for this platform
+ Formátovanie nie je na tejto platforme implementované
+
+
+
+ ImageWriter
+
+
+ Storage capacity is not large enough.
+Needs to be at least %1 GB
+ Kapacita úložiska je nedostatočná
+Musí byť aspoň %1 GB
+
+
+
+ Input file is not a valid disk image.
+File size %1 bytes is not a multiple of 512 bytes.
+ Vstupný súbor nie je platným obrazom disku.
+Veľkosť súboru %1 bajtov nie je násobkom 512 bajtov.
+
+
+
+ Downloading and writing image
+ Sťahujem a zapisujem obraz
+
+
+
+ Select image
+ Vyberte obraz
+
+
+
+ LocalFileExtractThread
+
+
+ Error opening image file
+ Chyba pri otváraní súboru s obrazom
+
+
+
+ MsgPopup
+
+
+ NO
+ NIE
+
+
+
+ YES
+ ÁNO
+
+
+
+ CONTINUE
+ POKRAČOVAŤ
+
+
+
+ QObject
+
+
+ Internal SD card reader
+ Interná čítačka SD kariet
+
+
+
+ main
+
+
+ Raspberry Pi Imager v%1
+ Raspberry Pi Imager v%1
+
+
+
+ Are you sure you want to quit?
+ Skutočne chcete skončiť?
+
+
+
+ Raspberry Pi Imager is still busy.<br>Are you sure you want to quit?
+ Raspberry Pi Imager ešte neskončil.<br>Ste si istý, že chcete skončiť?
+
+
+
+
+ Operating System
+ Operačný systém
+
+
+
+ CHOOSE OS
+ VÝBER OS
+
+
+
+
+ SD Card
+ SD karta
+
+
+
+
+ CHOOSE SD CARD
+ VYBERTE SD KARTU
+
+
+
+ WRITE
+ ZÁPIS
+
+
+
+
+ Writing... %1%
+ Zapisujem... %1%
+
+
+
+ CANCEL WRITE
+ ZRUŠIŤ ZÁPIS
+
+
+
+ Select this button to change the operating system
+ Pre zmenu operačného systému kliknite na toto tlačidlo
+
+
+
+ Select this button to change the destination SD card
+ Pre zmenu cieľovej SD karty kliknite na toto tlačidlo
+
+
+
+ Select this button to start writing the image
+ Kliknutím na toto tlačidlo spustíte zápis
+
+
+
+
+ Cancelling...
+ Ruším operáciu...
+
+
+
+ CANCEL VERIFY
+ ZRUŠIŤ OVEROVANIE
+
+
+
+
+
+ Finalizing...
+ Ukončujem...
+
+
+
+
+ Erase
+ Vymazať
+
+
+
+ Format card as FAT32
+ Formátovať kartu ako FAT32
+
+
+
+ Use custom
+ Použiť vlastný
+
+
+
+ Select a custom .img from your computer
+ Použiť vlastný súbor img. na Vašom počítači
+
+
+
+ Local file
+ Miestny súbor
+
+
+
+ [WRITE PROTECTED]
+ [OCHRANA PROTI ZÁPISU]
+
+
+
+ Warning
+ Varovanie
+
+
+
+ All existing data on '%1' will be erased.<br>Are you sure you want to continue?
+ Všetky existujúce dáta na '%1' budú odstránené.<br>Naozaj chcete pokračovať?
+
+
+
+ <b>%1</b> has been erased<br><br>You can now remove the SD card from the reader
+ <b>%1</b> bola vymazaná<br><br>Teraz môžete odstrániť SD kartu z čítačky
+
+
+
+
+ Error parsing os_list.json
+ Chyba pri spracovaní os_list.json
+
+
+
+ Connect an USB stick containing images first.<br>The images must be located in the root folder of the USB stick.
+ Najprv pripojte USB kľúč, ktorý obsahuje diskové obrazy.<br>Obrazy sa musia nachádzať v koreňovom priečinku USB kľúča.
+
+
+
+ SD card is write protected.<br>Push the lock switch on the left side of the card upwards, and try again.
+ SD karta je chránená proti zápisu.<br>Presuňte prepínač zámku na ľavej strane karty smerom hore a skúste to znova.
+
+
+
+ Back
+ Späť
+
+
+
+ Go back to main menu
+ Prejsť do hlavnej ponuky
+
+
+
+ Released: %1
+ Vydané: %1
+
+
+
+ Cached on your computer
+ Uložené na počítači
+
+
+
+ Online - %1 GB download
+ Online %1 GB na stiahnutie
+
+
+
+
+
+ Mounted as %1
+ Pripojená ako %1
+
+
+
+ Error downloading OS list from Internet
+ Chyba pri sťahovaní zoznamu OS z Internetu
+
+
+
+ Verifying... %1%
+ Overujem... %1%
+
+
+
+ Error
+ Chyba
+
+
+
+ Write Successful
+ Zápis úspešne skončil
+
+
+
+ <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> bol zapísaný na <b>%2</b><br><br>Teraz môžete odstrániť SD kartu z čítačky
+
+
+
diff --git a/i18n/translations.qrc b/i18n/translations.qrc
index 9ffb5bc..c0a603f 100644
--- a/i18n/translations.qrc
+++ b/i18n/translations.qrc
@@ -5,7 +5,8 @@
rpi-imager_fr.qm
rpi-imager_it.qm
rpi-imager_nl.qm
- rpi-imager_tr.qm
- rpi-imager_zh_cn.qm
+ rpi-imager_sk.qm
+ rpi-imager_tr.qm
+ rpi-imager_zh_cn.qm
diff --git a/imagewriter.cpp b/imagewriter.cpp
index 6c2aef6..57b8adf 100644
--- a/imagewriter.cpp
+++ b/imagewriter.cpp
@@ -201,6 +201,8 @@ void ImageWriter::startWrite()
connect(_thread, SIGNAL(success()), SLOT(onSuccess()));
connect(_thread, SIGNAL(error(QString)), SLOT(onError(QString)));
+ connect(_thread, SIGNAL(finalizing()), SLOT(onFinalizing()));
+ connect(_thread, SIGNAL(preparationStatusUpdate(QString)), SLOT(onPreparationStatusUpdate(QString)));
_thread->setVerifyEnabled(_verifyEnabled);
_thread->setUserAgent(QString("Mozilla/5.0 rpi-imager/%1").arg(constantVersion()).toUtf8());
@@ -252,6 +254,7 @@ void ImageWriter::startWrite()
_thread->start();
}
+ _dlnow = 0; _verifynow = 0;
_polltimer.start(PROGRESS_UPDATE_INTERVAL);
}
@@ -403,6 +406,11 @@ void ImageWriter::onFinalizing()
emit finalizing();
}
+void ImageWriter::onPreparationStatusUpdate(QString msg)
+{
+ emit preparationStatusUpdate(msg);
+}
+
void ImageWriter::openFileDialog()
{
#ifndef QT_NO_WIDGETS
diff --git a/imagewriter.h b/imagewriter.h
index f0c6131..10fb143 100644
--- a/imagewriter.h
+++ b/imagewriter.h
@@ -99,6 +99,7 @@ signals:
void cancelled();
void finalizing();
void networkOnline();
+ void preparationStatusUpdate(QVariant msg);
protected slots:
@@ -112,6 +113,7 @@ protected slots:
void onCacheFileUpdated(QByteArray sha256);
void onFinalizing();
void onTimeSyncReply(QNetworkReply *reply);
+ void onPreparationStatusUpdate(QString msg);
protected:
QUrl _src, _repo;
diff --git a/localfileextractthread.cpp b/localfileextractthread.cpp
index cc5081e..0ac86a3 100644
--- a/localfileextractthread.cpp
+++ b/localfileextractthread.cpp
@@ -31,6 +31,7 @@ void LocalFileExtractThread::run()
if (isImage() && !_openAndPrepareDevice())
return;
+ emit preparationStatusUpdate(tr("opening image file"));
_timer.start();
_inputfile.setFileName( QUrl(_url).toLocalFile() );
if (!_inputfile.open(_inputfile.ReadOnly))
diff --git a/main.cpp b/main.cpp
index 3c4f690..5587e4e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -158,6 +158,7 @@ int main(int argc, char *argv[])
QObject *qmlwindow = engine.rootObjects().value(0);
qmlwindow->connect(&imageWriter, SIGNAL(downloadProgress(QVariant,QVariant)), qmlwindow, SLOT(onDownloadProgress(QVariant,QVariant)));
qmlwindow->connect(&imageWriter, SIGNAL(verifyProgress(QVariant,QVariant)), qmlwindow, SLOT(onVerifyProgress(QVariant,QVariant)));
+ qmlwindow->connect(&imageWriter, SIGNAL(preparationStatusUpdate(QVariant)), qmlwindow, SLOT(onPreparationStatusUpdate(QVariant)));
qmlwindow->connect(&imageWriter, SIGNAL(error(QVariant)), qmlwindow, SLOT(onError(QVariant)));
qmlwindow->connect(&imageWriter, SIGNAL(success()), qmlwindow, SLOT(onSuccess()));
qmlwindow->connect(&imageWriter, SIGNAL(fileSelected(QVariant)), qmlwindow, SLOT(onFileSelected(QVariant)));
diff --git a/main.qml b/main.qml
index 816b39f..ea87424 100644
--- a/main.qml
+++ b/main.qml
@@ -749,7 +749,7 @@ ApplicationWindow {
cancelwritebutton.enabled = true
cancelwritebutton.visible = true
cancelverifybutton.enabled = true
- progressText.text = qsTr("Writing... %1%").arg("0")
+ progressText.text = qsTr("Preparing to write...");
progressText.visible = true
progressBar.visible = true
progressBar.indeterminate = true
@@ -831,6 +831,10 @@ ApplicationWindow {
}
}
+ function onPreparationStatusUpdate(msg) {
+ progressText.text = qsTr("Preparing to write... (%1)").arg(msg)
+ }
+
function resetWriteButton() {
progressText.visible = false
progressBar.visible = false