diff --git a/rbutil/rbutilqt/base/rbunzip.cpp b/rbutil/rbutilqt/base/rbunzip.cpp index 49d12156ea..fb964b52db 100644 --- a/rbutil/rbutilqt/base/rbunzip.cpp +++ b/rbutil/rbutilqt/base/rbunzip.cpp @@ -21,6 +21,7 @@ #include +//! @brief extract archive to destination UnZip::ErrorCode RbUnZip::extractArchive(const QString& dest) { QStringList files = this->fileList(); @@ -41,8 +42,25 @@ UnZip::ErrorCode RbUnZip::extractArchive(const QString& dest) return error; } + +//! @brief abort an extractArchive() operation. void RbUnZip::abortUnzip(void) { m_abortunzip = true; } + +//! @brief return total size of extracted files in archive. +qulonglong RbUnZip::totalSize(void) +{ + QList l = this->entryList(); + qulonglong total = 0; + + int i = l.size(); + while(i--) + total += l.at(i).uncompressedSize; + + return total; + +} + diff --git a/rbutil/rbutilqt/base/rbunzip.h b/rbutil/rbutilqt/base/rbunzip.h index 133437a4e2..c0b7215b6a 100644 --- a/rbutil/rbutilqt/base/rbunzip.h +++ b/rbutil/rbutilqt/base/rbunzip.h @@ -28,12 +28,13 @@ class RbUnZip : public QObject, public UnZip { - Q_OBJECT - public: + Q_OBJECT + public: UnZip::ErrorCode extractArchive(const QString&); + qulonglong totalSize(void); - signals: - void unzipProgress(int, int); + signals: + void unzipProgress(int, int); public slots: void abortUnzip(void); diff --git a/rbutil/rbutilqt/base/utils.cpp b/rbutil/rbutilqt/base/utils.cpp index a6a80c6eef..64fc18e449 100644 --- a/rbutil/rbutilqt/base/utils.cpp +++ b/rbutil/rbutilqt/base/utils.cpp @@ -32,6 +32,9 @@ #include #include #endif +#if defined(Q_OS_LINUX) +#include +#endif // recursive function to delete a dir with files bool recRmdir( const QString &dirName ) @@ -78,7 +81,7 @@ QString resolvePathCase(QString path) for(int i = start; i < elems.size(); i++) { QStringList direlems - = QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System); + = QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System); if(direlems.contains(elems.at(i), Qt::CaseInsensitive)) { // need to filter using QRegExp as QStringList::filter(QString) // matches any substring @@ -99,3 +102,40 @@ QString resolvePathCase(QString path) return realpath; } + +//! @brief figure the free disk space on a filesystem +//! @param path path on the filesystem to check +//! @return size in bytes +qulonglong filesystemFree(QString path) +{ + qlonglong size = 0; +#if defined(Q_OS_LINUX) + // the usage of statfs() is deprecated by the LSB so use statvfs(). + struct statvfs fs; + int ret; + + ret = statvfs(qPrintable(path), &fs); + + if(ret == 0) + size = fs.f_bsize * fs.f_bavail; +#endif +#if defined(Q_OS_MACX) + struct statfs fs; + int ret; + + ret = statfs(qPrintable(path), &fs); + + if(ret == 0) + size = fs.f_bsize * fs.f_bavail; +#endif +#if defined(Q_OS_WIN32) + BOOL ret; + ULARGE_INTEGER freeAvailBytes; + + ret = GetDiskFreeSpaceExW((LPCTSTR)path.utf16(), &freeAvailBytes, NULL, NULL); + if(ret) + size = freeAvailBytes.QuadPart; +#endif + return size; +} + diff --git a/rbutil/rbutilqt/base/utils.h b/rbutil/rbutilqt/base/utils.h index 19cdca92c9..0a9135485a 100644 --- a/rbutil/rbutilqt/base/utils.h +++ b/rbutil/rbutilqt/base/utils.h @@ -28,6 +28,7 @@ bool recRmdir( const QString &dirName ); QString resolvePathCase(QString path); +qulonglong filesystemFree(QString path); #endif diff --git a/rbutil/rbutilqt/installzip.cpp b/rbutil/rbutilqt/installzip.cpp index 5842e00d3f..9539e3a640 100644 --- a/rbutil/rbutilqt/installzip.cpp +++ b/rbutil/rbutilqt/installzip.cpp @@ -19,7 +19,7 @@ #include "installzip.h" #include "rbunzip.h" - +#include "utils.h" ZipInstaller::ZipInstaller(QObject* parent): QObject(parent) { @@ -148,6 +148,17 @@ void ZipInstaller::downloadDone(bool error) return; } + // check for free space. Make sure after installation will still be + // some room for operating (also includes calculation mistakes due to + // cluster sizes on the player). + if(filesystemFree(m_mountpoint) < (uz.totalSize() + 1000000)) { + m_dp->addItem(tr("Not enough disk space! Aborting."), LOGERROR); + m_dp->abort(); + m_dp->setProgressMax(1); + m_dp->setProgressValue(1); + emit done(true); + return; + } ec = uz.extractArchive(m_mountpoint); // TODO: better handling of aborted unzip operation. if(ec != UnZip::Ok) { diff --git a/rbutil/rbutilqt/sysinfo.cpp b/rbutil/rbutilqt/sysinfo.cpp index 7ca4b8585c..9a4c8b75b0 100644 --- a/rbutil/rbutilqt/sysinfo.cpp +++ b/rbutil/rbutilqt/sysinfo.cpp @@ -21,6 +21,8 @@ #include "sysinfo.h" #include "ui_sysinfofrm.h" #include "detect.h" +#include "utils.h" +#include "autodetection.h" Sysinfo::Sysinfo(QWidget *parent) : QDialog(parent) @@ -37,18 +39,33 @@ void Sysinfo::updateSysinfo(void) { QString info; info += tr("OS
") + Detect::osVersionString() + "
"; - info += tr("Username:
%1
").arg(Detect::userName()); + info += tr("Username
%1
").arg(Detect::userName()); #if defined(Q_OS_WIN32) - info += tr("Permissions:
%1
").arg(Detect::userPermissionsString()); + info += tr("Permissions
%1
").arg(Detect::userPermissionsString()); #endif - info += tr("Attached USB devices:
"); + info += tr("Attached USB devices
"); QMap usbids = Detect::listUsbDevices(); QList usbkeys = usbids.keys(); - for(int i = 0; i < usbkeys.size(); i++) - info += tr("VID: %1 PID: %2, %3
") + for(int i = 0; i < usbkeys.size(); i++) { + info += tr("VID: %1 PID: %2, %3") .arg((usbkeys.at(i)&0xffff0000)>>16, 4, 16, QChar('0')) .arg(usbkeys.at(i)&0xffff, 4, 16, QChar('0')) - .arg(usbids.value(usbkeys.at(i))); + .arg(usbids.value(usbkeys.at(i))); + if(i + 1 < usbkeys.size()) + info += "
"; + } + info += "
"; + + info += "" + tr("Filesystem") + "
"; + QStringList drives = Autodetection::mountpoints(); + for(int i = 0; i < drives.size(); i++) { + info += tr("%1, %2 MiB available") + .arg(drives.at(i)) + .arg(filesystemFree(drives.at(i)) / (1024*1024)); + if(i + 1 < drives.size()) + info += "
"; + } + info += "
"; ui.textBrowser->setHtml(info); }