From 7c6ee7f1a24faeafc793414e877bf014743d9cfe Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Thu, 12 Mar 2015 04:01:41 +1100 Subject: Added QML bindings for packages --- heimdall-frontend/source/FirmwareInfo.cpp | 43 ++++- heimdall-frontend/source/FirmwareInfo.h | 78 +++++++-- heimdall-frontend/source/GZipFile.cpp | 24 ++- heimdall-frontend/source/PackageData.cpp | 8 + heimdall-frontend/source/PackageData.h | 20 ++- heimdall-frontend/source/Packaging.cpp | 96 +++++------ heimdall-frontend/source/Packaging.h | 10 +- heimdall-frontend/source/main.cpp | 16 +- heimdall-frontend/source/mainwindow.cpp | 189 ++++++++++----------- heimdall-frontend/source/qml/ArrayExtensions.js | 3 + heimdall-frontend/source/qml/DropFiles.qml | 17 +- heimdall-frontend/source/qml/FileUtils.js | 46 ++--- heimdall-frontend/source/qml/bindings/Firmware.cpp | 49 ++++++ heimdall-frontend/source/qml/bindings/Firmware.h | 53 ++++++ heimdall-frontend/source/qml/qml.qrc | 1 + 15 files changed, 448 insertions(+), 205 deletions(-) create mode 100644 heimdall-frontend/source/qml/ArrayExtensions.js create mode 100644 heimdall-frontend/source/qml/bindings/Firmware.cpp create mode 100644 heimdall-frontend/source/qml/bindings/Firmware.h (limited to 'heimdall-frontend/source') diff --git a/heimdall-frontend/source/FirmwareInfo.cpp b/heimdall-frontend/source/FirmwareInfo.cpp index 7a1043c..193091e 100644 --- a/heimdall-frontend/source/FirmwareInfo.cpp +++ b/heimdall-frontend/source/FirmwareInfo.cpp @@ -19,7 +19,7 @@ THE SOFTWARE.*/ // Qt -#include "QRegExp" +#include // Heimdall Frontend #include "Alerts.h" @@ -28,6 +28,11 @@ using namespace HeimdallFrontend; +void DeviceInfo::Register(void) +{ + qmlRegisterType("HeimdallFrontend", 1, 0, "DeviceInfo"); +} + DeviceInfo::DeviceInfo() { } @@ -141,6 +146,10 @@ void DeviceInfo::WriteXml(QXmlStreamWriter& xml) const } +void PlatformInfo::Register(void) +{ + qmlRegisterType("HeimdallFrontend", 1, 0, "PlatformInfo"); +} PlatformInfo::PlatformInfo() { @@ -244,6 +253,10 @@ void PlatformInfo::WriteXml(QXmlStreamWriter& xml) const } +void FileInfo::Register(void) +{ + qmlRegisterType("HeimdallFrontend", 1, 0, "FileInfo"); +} FileInfo::FileInfo() { @@ -347,6 +360,20 @@ FirmwareInfo::FirmwareInfo() noReboot = false; } + +FirmwareInfo::~FirmwareInfo() +{ + for (DeviceInfo *deviceInfo : deviceInfos) + { + delete deviceInfo; + } + + for (FileInfo *fileInfo : fileInfos) + { + delete fileInfo; + } +} + void FirmwareInfo::Clear(void) { name = ""; @@ -549,9 +576,9 @@ bool FirmwareInfo::ParseXml(QXmlStreamReader& xml) { if (xml.name() == "device") { - DeviceInfo deviceInfo; + DeviceInfo *deviceInfo = new DeviceInfo{}; - if (!deviceInfo.ParseXml(xml)) + if (!deviceInfo->ParseXml(xml)) return (false); deviceInfos.append(deviceInfo); @@ -631,9 +658,9 @@ bool FirmwareInfo::ParseXml(QXmlStreamReader& xml) { if (xml.name() == "file") { - FileInfo fileInfo; + FileInfo *fileInfo = new FileInfo{}; - if (!fileInfo.ParseXml(xml)) + if (!fileInfo->ParseXml(xml)) return (false); fileInfos.append(fileInfo); @@ -745,9 +772,9 @@ void FirmwareInfo::WriteXml(QXmlStreamWriter& xml) const xml.writeStartElement("devices"); - for (const DeviceInfo& deviceInfo : deviceInfos) + for (const DeviceInfo *deviceInfo : deviceInfos) { - deviceInfo.WriteXml(xml); + deviceInfo->WriteXml(xml); } xml.writeEndElement(); @@ -775,7 +802,7 @@ void FirmwareInfo::WriteXml(QXmlStreamWriter& xml) const for (int i = 0; i < fileInfos.length(); i++) { - fileInfos[i].WriteXml(xml, Packaging::ClashlessFilename(fileInfos, i)); + fileInfos[i]->WriteXml(xml, Packaging::ClashlessFilename(fileInfos, i)); } xml.writeEndElement(); diff --git a/heimdall-frontend/source/FirmwareInfo.h b/heimdall-frontend/source/FirmwareInfo.h index 8e6713e..ea9555f 100644 --- a/heimdall-frontend/source/FirmwareInfo.h +++ b/heimdall-frontend/source/FirmwareInfo.h @@ -28,8 +28,14 @@ namespace HeimdallFrontend { - class DeviceInfo - { + class DeviceInfo : public QObject + { + Q_OBJECT + + Q_PROPERTY(QString manufacturer READ GetManufacturer) + Q_PROPERTY(QString product READ GetProduct) + Q_PROPERTY(QString name READ GetName) + private: QString manufacturer; @@ -38,6 +44,8 @@ namespace HeimdallFrontend public: + static void Register(void); + DeviceInfo(); DeviceInfo(const QString& manufacturer, const QString& product, const QString& name); @@ -75,8 +83,13 @@ namespace HeimdallFrontend } }; - class PlatformInfo + class PlatformInfo : public QObject { + Q_OBJECT + + Q_PROPERTY(QString name READ GetName) + Q_PROPERTY(QString version READ GetVersion) + private: QString name; @@ -84,6 +97,8 @@ namespace HeimdallFrontend public: + static void Register(void); + PlatformInfo(); void Clear(void); @@ -113,8 +128,13 @@ namespace HeimdallFrontend } }; - class FileInfo + class FileInfo : public QObject { + Q_OBJECT + + Q_PROPERTY(int partitionId READ GetPartitionId) + Q_PROPERTY(QString filename READ GetFilename) + private: unsigned int partitionId; @@ -122,6 +142,8 @@ namespace HeimdallFrontend public: + static void Register(void); + FileInfo(); FileInfo(unsigned int partitionId, const QString& filename); @@ -149,8 +171,27 @@ namespace HeimdallFrontend } }; - class FirmwareInfo + class FirmwareInfo : public QObject { + Q_OBJECT + + Q_PROPERTY(QString name READ GetName) + Q_PROPERTY(QString version READ GetVersion) + Q_PROPERTY(HeimdallFrontend::PlatformInfo *platformInfo READ GetPlatformInfo) + + Q_PROPERTY(QList developers READ GetDevelopers) + Q_PROPERTY(QString url READ GetUrl) + Q_PROPERTY(QString donateUrl READ GetDonateUrl) + + Q_PROPERTY(QList deviceInfos READ GetDeviceInfos) + + Q_PROPERTY(QString pitFilename READ GetPitFilename) + Q_PROPERTY(bool repartition READ GetRepartition) + + Q_PROPERTY(bool noReboot READ GetNoReboot) + + Q_PROPERTY(QList fileInfos READ GetFileInfos) + public: enum @@ -168,18 +209,21 @@ namespace HeimdallFrontend QString url; QString donateUrl; - QList deviceInfos; + QList deviceInfos; QString pitFilename; bool repartition; bool noReboot; - QList fileInfos; + QList fileInfos; public: + static void Register(void); + FirmwareInfo(); + ~FirmwareInfo(); void Clear(void); bool IsCleared(void) const; @@ -207,14 +251,14 @@ namespace HeimdallFrontend this->version = version; } - const PlatformInfo& GetPlatformInfo(void) const + const PlatformInfo *GetPlatformInfo(void) const { - return (platformInfo); + return (&platformInfo); } - PlatformInfo& GetPlatformInfo(void) + PlatformInfo *GetPlatformInfo(void) { - return (platformInfo); + return (&platformInfo); } const QList& GetDevelopers(void) const @@ -247,12 +291,12 @@ namespace HeimdallFrontend this->donateUrl = donateUrl; } - const QList& GetDeviceInfos(void) const + const QList& GetDeviceInfos(void) const { return (deviceInfos); } - QList& GetDeviceInfos(void) + QList& GetDeviceInfos(void) { return (deviceInfos); } @@ -287,16 +331,20 @@ namespace HeimdallFrontend this->noReboot = noReboot; } - const QList& GetFileInfos(void) const + const QList& GetFileInfos(void) const { return (fileInfos); } - QList& GetFileInfos(void) + QList& GetFileInfos(void) { return (fileInfos); } }; } +Q_DECLARE_METATYPE(HeimdallFrontend::DeviceInfo *) +Q_DECLARE_METATYPE(HeimdallFrontend::PlatformInfo *) +Q_DECLARE_METATYPE(HeimdallFrontend::FileInfo *) + #endif diff --git a/heimdall-frontend/source/GZipFile.cpp b/heimdall-frontend/source/GZipFile.cpp index af75f39..200471e 100644 --- a/heimdall-frontend/source/GZipFile.cpp +++ b/heimdall-frontend/source/GZipFile.cpp @@ -1,10 +1,32 @@ +/* Copyright (c) 2010-2014 Benjamin Dobell, Glass Echidna + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE.*/ + +// Heimdall Frontend #import "GZipFile.h" using namespace HeimdallFrontend; GZipFile::GZipFile(const QString& path) : file(path), - gzFile(nullptr) + gzFile(nullptr), + temporary(false) { } diff --git a/heimdall-frontend/source/PackageData.cpp b/heimdall-frontend/source/PackageData.cpp index 23ef720..c17917b 100644 --- a/heimdall-frontend/source/PackageData.cpp +++ b/heimdall-frontend/source/PackageData.cpp @@ -18,12 +18,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ +// Qt +#include + // Heimdall Frontend #include "Alerts.h" #include "PackageData.h" using namespace HeimdallFrontend; +void PackageData::Register(void) +{ + qmlRegisterType("HeimdallFrontend", 1, 0, "PackageData"); +} + PackageData::PackageData() { } diff --git a/heimdall-frontend/source/PackageData.h b/heimdall-frontend/source/PackageData.h index 28be679..71302db 100644 --- a/heimdall-frontend/source/PackageData.h +++ b/heimdall-frontend/source/PackageData.h @@ -29,8 +29,14 @@ namespace HeimdallFrontend { - class PackageData + class PackageData : public QObject { + Q_OBJECT + + Q_PROPERTY(HeimdallFrontend::FirmwareInfo *firmwareInfo READ GetFirmwareInfo) + Q_PROPERTY(QList filePaths READ GetFilePaths) + Q_PROPERTY(QString packagePath READ GetPackagePath) + private: FirmwareInfo firmwareInfo; @@ -39,6 +45,8 @@ namespace HeimdallFrontend public: + static void Register(void); + PackageData(); ~PackageData(); @@ -47,14 +55,14 @@ namespace HeimdallFrontend bool IsCleared(void) const; - const FirmwareInfo& GetFirmwareInfo(void) const + const FirmwareInfo *GetFirmwareInfo(void) const { - return (firmwareInfo); + return (&firmwareInfo); } - FirmwareInfo& GetFirmwareInfo(void) + FirmwareInfo *GetFirmwareInfo(void) { - return (firmwareInfo); + return (&firmwareInfo); } const QList& GetFilePaths(void) const @@ -79,4 +87,6 @@ namespace HeimdallFrontend }; } +Q_DECLARE_METATYPE(HeimdallFrontend::PackageData *) + #endif diff --git a/heimdall-frontend/source/Packaging.cpp b/heimdall-frontend/source/Packaging.cpp index 7e0e1c0..39894a5 100644 --- a/heimdall-frontend/source/Packaging.cpp +++ b/heimdall-frontend/source/Packaging.cpp @@ -46,7 +46,7 @@ const char *Packaging::ustarMagic = "ustar"; bool Packaging::DecompressGZippedFile(const QString &path, const QString &outputPath) { - GZipFile gzipFile(path); + GZipFile gzipFile{path}; if (!gzipFile.Open(GZipFile::ReadOnly)) { @@ -93,7 +93,7 @@ bool Packaging::DecompressGZippedFile(const QString &path, const QString &output progressDialog.close(); return (true); -} +}; bool Packaging::ExtractTar(QFile& tarFile, const QDir& outputDirectory, QList& outputFilePaths) { @@ -387,9 +387,9 @@ bool Packaging::WriteTarEntry(const QString& entryFilename, const QString& fileP return (true); } -bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile) +bool Packaging::CreateTar(const FirmwareInfo *firmwareInfo, QFile& outputTarFile) { - const QList& fileInfos = firmwareInfo.GetFileInfos(); + const QList& fileInfos = firmwareInfo->GetFileInfos(); QProgressDialog progressDialog("Packaging files...", "Cancel", 0, fileInfos.length() + 2); progressDialog.setWindowModality(Qt::ApplicationModal); @@ -406,7 +406,7 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile } QXmlStreamWriter xml(&firmwareXmlFile); - firmwareInfo.WriteXml(xml); + firmwareInfo->WriteXml(xml); firmwareXmlFile.close(); if (!outputTarFile.open(QFile::WriteOnly)) @@ -424,7 +424,7 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile for (int j = 0; j < i; j++) { - if (fileInfos[i].GetFilename() == fileInfos[j].GetFilename()) + if (fileInfos[i]->GetFilename() == fileInfos[j]->GetFilename()) { skip = true; break; @@ -445,7 +445,7 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile return (false); } - if (!WriteTarEntry(filename, fileInfos[i].GetFilename(), outputTarFile)) + if (!WriteTarEntry(filename, fileInfos[i]->GetFilename(), outputTarFile)) { outputTarFile.resize(0); outputTarFile.close(); @@ -468,12 +468,12 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile } } - int lastSlash = firmwareInfo.GetPitFilename().lastIndexOf('/'); + int lastSlash = firmwareInfo->GetPitFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = firmwareInfo.GetPitFilename().lastIndexOf('\\'); + lastSlash = firmwareInfo->GetPitFilename().lastIndexOf('\\'); - QString pitFilename = ClashlessFilename(fileInfos, firmwareInfo.GetPitFilename().mid(lastSlash + 1)); + QString pitFilename = ClashlessFilename(fileInfos, firmwareInfo->GetPitFilename().mid(lastSlash + 1)); if (pitFilename == "firmware.xml") { @@ -481,7 +481,7 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile return (false); } - if (!WriteTarEntry(pitFilename, firmwareInfo.GetPitFilename(), outputTarFile)) + if (!WriteTarEntry(pitFilename, firmwareInfo->GetPitFilename(), outputTarFile)) { outputTarFile.resize(0); outputTarFile.close(); @@ -524,7 +524,7 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile return (true); } -bool Packaging::ExtractPackage(const QString& packagePath, PackageData& packageData) +bool Packaging::ExtractPackage(const QString& packagePath, PackageData *packageData) { QTemporaryDir outputDirectory; @@ -551,16 +551,16 @@ bool Packaging::ExtractPackage(const QString& packagePath, PackageData& packageD { if (path.endsWith("firmware.xml")) { - if (!packageData.ReadFirmwareInfo(path)) + if (!packageData->ReadFirmwareInfo(path)) { - packageData.Clear(); + packageData->Clear(); return (false); } outputDirectory.setAutoRemove(false); - packageData.GetFilePaths().append(decompressedFilePaths); - packageData.SetPackagePath(outputDirectory.path()); + packageData->GetFilePaths().append(decompressedFilePaths); + packageData->SetPackagePath(outputDirectory.path()); return (true); } } @@ -569,9 +569,9 @@ bool Packaging::ExtractPackage(const QString& packagePath, PackageData& packageD return (false); } -bool Packaging::BuildPackage(const QString& packagePath, const FirmwareInfo& firmwareInfo) +bool Packaging::BuildPackage(const QString& packagePath, const FirmwareInfo *firmwareInfo) { - GZipFile packageFile(packagePath); + GZipFile packageFile{packagePath}; if (!packageFile.Open(GZipFile::WriteOnly)) { @@ -636,30 +636,30 @@ bool Packaging::BuildPackage(const QString& packagePath, const FirmwareInfo& fir packageFile.SetTemporary(false); return (true); -} +}; -QString Packaging::ClashlessFilename(const QList& fileInfos, int fileInfoIndex) +QString Packaging::ClashlessFilename(const QList& fileInfos, int fileInfoIndex) { - int lastSlash = fileInfos[fileInfoIndex].GetFilename().lastIndexOf('/'); + int lastSlash = fileInfos[fileInfoIndex]->GetFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = fileInfos[fileInfoIndex].GetFilename().lastIndexOf('\\'); + lastSlash = fileInfos[fileInfoIndex]->GetFilename().lastIndexOf('\\'); - QString filename = fileInfos[fileInfoIndex].GetFilename().mid(lastSlash + 1); + QString filename = fileInfos[fileInfoIndex]->GetFilename().mid(lastSlash + 1); unsigned int renameIndex = 0; // Check for name clashes for (int i = 0; i < fileInfoIndex; i++) { - lastSlash = fileInfos[i].GetFilename().lastIndexOf('/'); + lastSlash = fileInfos[i]->GetFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = fileInfos[i].GetFilename().lastIndexOf('\\'); + lastSlash = fileInfos[i]->GetFilename().lastIndexOf('\\'); - QString otherFilename = fileInfos[i].GetFilename().mid(lastSlash + 1); + QString otherFilename = fileInfos[i]->GetFilename().mid(lastSlash + 1); // If the filenames are the same, but the files themselves aren't the same (i.e. not the same path), then rename. - if (filename == otherFilename && fileInfos[i].GetFilename() != fileInfos[fileInfoIndex].GetFilename()) + if (filename == otherFilename && fileInfos[i]->GetFilename() != fileInfos[fileInfoIndex]->GetFilename()) renameIndex++; } @@ -683,14 +683,14 @@ QString Packaging::ClashlessFilename(const QList& fileInfos, int fileI bool validIndexOffset = true; // Before we append a rename index we must ensure it doesn't produce further collisions. - for (const FileInfo& fileInfo : fileInfos) + for (const FileInfo *fileInfo : fileInfos) { - int lastSlash = fileInfo.GetFilename().lastIndexOf('/'); + int lastSlash = fileInfo->GetFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = fileInfo.GetFilename().lastIndexOf('\\'); + lastSlash = fileInfo->GetFilename().lastIndexOf('\\'); - QString otherFilename = fileInfo.GetFilename().mid(lastSlash + 1); + QString otherFilename = fileInfo->GetFilename().mid(lastSlash + 1); if (otherFilename.length() > filename.length() + 1) { @@ -752,14 +752,14 @@ QString Packaging::ClashlessFilename(const QList& fileInfos, int fileI bool valid = true; - for (const FileInfo& fileInfo : fileInfos) + for (const FileInfo *fileInfo : fileInfos) { - int lastSlash = fileInfo.GetFilename().lastIndexOf('/'); + int lastSlash = fileInfo->GetFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = fileInfo.GetFilename().lastIndexOf('\\'); + lastSlash = fileInfo->GetFilename().lastIndexOf('\\'); - if (filename == fileInfo.GetFilename().mid(lastSlash + 1)) + if (filename == fileInfo->GetFilename().mid(lastSlash + 1)) { valid = false; break; @@ -778,19 +778,19 @@ QString Packaging::ClashlessFilename(const QList& fileInfos, int fileI } } -QString Packaging::ClashlessFilename(const QList& fileInfos, const QString& filename) +QString Packaging::ClashlessFilename(const QList& fileInfos, const QString& filename) { unsigned int renameIndex = 0; // Check for name clashes - for (const FileInfo& fileInfo : fileInfos) + for (const FileInfo *fileInfo : fileInfos) { - int lastSlash = fileInfo.GetFilename().lastIndexOf('/'); + int lastSlash = fileInfo->GetFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = fileInfo.GetFilename().lastIndexOf('\\'); + lastSlash = fileInfo->GetFilename().lastIndexOf('\\'); - QString otherFilename = fileInfo.GetFilename().mid(lastSlash + 1); + QString otherFilename = fileInfo->GetFilename().mid(lastSlash + 1); if (filename == otherFilename) renameIndex++; @@ -816,14 +816,14 @@ QString Packaging::ClashlessFilename(const QList& fileInfos, const QSt bool validIndexOffset = true; // Before we append a rename index we must ensure it doesn't produce further collisions. - for (const FileInfo& fileInfo : fileInfos) + for (const FileInfo *fileInfo : fileInfos) { - int lastSlash = fileInfo.GetFilename().lastIndexOf('/'); + int lastSlash = fileInfo->GetFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = fileInfo.GetFilename().lastIndexOf('\\'); + lastSlash = fileInfo->GetFilename().lastIndexOf('\\'); - QString otherFilename = fileInfo.GetFilename().mid(lastSlash + 1); + QString otherFilename = fileInfo->GetFilename().mid(lastSlash + 1); if (otherFilename.length() > filename.length() + 1) { @@ -883,14 +883,14 @@ QString Packaging::ClashlessFilename(const QList& fileInfos, const QSt for (int i = 0; i < 8; i++) filename.append(QChar(qrand() % ('Z' - 'A' + 1) + 'A')); - for (const FileInfo& fileInfo : fileInfos) + for (const FileInfo *fileInfo : fileInfos) { - int lastSlash = fileInfo.GetFilename().lastIndexOf('/'); + int lastSlash = fileInfo->GetFilename().lastIndexOf('/'); if (lastSlash < 0) - lastSlash = fileInfo.GetFilename().lastIndexOf('\\'); + lastSlash = fileInfo->GetFilename().lastIndexOf('\\'); - if (filename == fileInfo.GetFilename().mid(lastSlash + 1)) + if (filename == fileInfo->GetFilename().mid(lastSlash + 1)) { valid = false; break; diff --git a/heimdall-frontend/source/Packaging.h b/heimdall-frontend/source/Packaging.h index 80b6d81..e8f83e1 100644 --- a/heimdall-frontend/source/Packaging.h +++ b/heimdall-frontend/source/Packaging.h @@ -104,17 +104,17 @@ namespace HeimdallFrontend static bool ExtractTar(QFile& tarFile, const QDir& outputDirectory, QList& outputFilePaths); static bool WriteTarEntry(const QString& entryFilename, const QString& filePath, QFile& outputTarFile); - static bool CreateTar(const FirmwareInfo& firmwareInfo, QFile& outputTarFile); // Uses original TAR format. + static bool CreateTar(const FirmwareInfo *firmwareInfo, QFile& outputTarFile); // Uses original TAR format. public: static const char *ustarMagic; - static bool ExtractPackage(const QString& packagePath, PackageData& packageData); - static bool BuildPackage(const QString& packagePath, const FirmwareInfo& firmwareInfo); + static bool ExtractPackage(const QString& packagePath, PackageData *packageData); + static bool BuildPackage(const QString& packagePath, const FirmwareInfo *firmwareInfo); - static QString ClashlessFilename(const QList& fileInfos, int fileInfoIndex); - static QString ClashlessFilename(const QList& fileInfos, const QString& filename); + static QString ClashlessFilename(const QList& fileInfos, int fileInfoIndex); + static QString ClashlessFilename(const QList& fileInfos, const QString& filename); }; } diff --git a/heimdall-frontend/source/main.cpp b/heimdall-frontend/source/main.cpp index 53e9f2d..b86631c 100644 --- a/heimdall-frontend/source/main.cpp +++ b/heimdall-frontend/source/main.cpp @@ -20,9 +20,10 @@ // Qt #include -#include +#include // Heimdall Frontend +#include "Firmware.h" #include "mainwindow.h" #if defined(QT_STATIC) @@ -37,10 +38,23 @@ QQmlDebuggingEnabler enabler; using namespace HeimdallFrontend; +void registerQmlTypes() +{ + Firmware::Register(); + + DeviceInfo::Register(); + PlatformInfo::Register(); + FileInfo::Register(); + + PackageData::Register(); +} + int main(int argc, char *argv[]) { QApplication application(argc, argv); + registerQmlTypes(); + QQmlApplicationEngine engine; engine.load(QUrl(QString("qrc:/main.qml"))); diff --git a/heimdall-frontend/source/mainwindow.cpp b/heimdall-frontend/source/mainwindow.cpp index ab83105..255c0b5 100644 --- a/heimdall-frontend/source/mainwindow.cpp +++ b/heimdall-frontend/source/mainwindow.cpp @@ -114,8 +114,8 @@ void MainWindow::UpdateUnusedPartitionIds(void) } // Remove any used partition IDs from unusedPartitionIds - for (const FileInfo& fileInfo : workingPackageData.GetFirmwareInfo().GetFileInfos()) - unusedPartitionIds.removeOne(fileInfo.GetPartitionId()); + for (const FileInfo *fileInfo : workingPackageData.GetFirmwareInfo()->GetFileInfos()) + unusedPartitionIds.removeOne(fileInfo->GetPartitionId()); } bool MainWindow::ReadPit(const QString& path) @@ -158,35 +158,35 @@ void MainWindow::UpdatePackageUserInterface(void) } else { - firmwareNameLineEdit->setText(loadedPackageData.GetFirmwareInfo().GetName()); - versionLineEdit->setText(loadedPackageData.GetFirmwareInfo().GetVersion()); + firmwareNameLineEdit->setText(loadedPackageData.GetFirmwareInfo()->GetName()); + versionLineEdit->setText(loadedPackageData.GetFirmwareInfo()->GetVersion()); QString developerNames; - if (!loadedPackageData.GetFirmwareInfo().GetDevelopers().isEmpty()) + if (!loadedPackageData.GetFirmwareInfo()->GetDevelopers().isEmpty()) { - developerNames = loadedPackageData.GetFirmwareInfo().GetDevelopers()[0]; - for (int i = 1; i < loadedPackageData.GetFirmwareInfo().GetDevelopers().length(); i++) - developerNames += ", " + loadedPackageData.GetFirmwareInfo().GetDevelopers()[i]; + developerNames = loadedPackageData.GetFirmwareInfo()->GetDevelopers()[0]; + for (int i = 1; i < loadedPackageData.GetFirmwareInfo()->GetDevelopers().length(); i++) + developerNames += ", " + loadedPackageData.GetFirmwareInfo()->GetDevelopers()[i]; } developerNamesLineEdit->setText(developerNames); - platformLineEdit->setText(loadedPackageData.GetFirmwareInfo().GetPlatformInfo().GetName() + " (" - + loadedPackageData.GetFirmwareInfo().GetPlatformInfo().GetVersion() + ")"); + platformLineEdit->setText(loadedPackageData.GetFirmwareInfo()->GetPlatformInfo()->GetName() + " (" + + loadedPackageData.GetFirmwareInfo()->GetPlatformInfo()->GetVersion() + ")"); - for (const DeviceInfo& deviceInfo : loadedPackageData.GetFirmwareInfo().GetDeviceInfos()) + for (const DeviceInfo *deviceInfo : loadedPackageData.GetFirmwareInfo()->GetDeviceInfos()) { - supportedDevicesListWidget->addItem(deviceInfo.GetManufacturer() + " " + deviceInfo.GetName() + ": " + deviceInfo.GetProduct()); + supportedDevicesListWidget->addItem(deviceInfo->GetManufacturer() + " " + deviceInfo->GetName() + ": " + deviceInfo->GetProduct()); } - for (const FileInfo& fileInfo : loadedPackageData.GetFirmwareInfo().GetFileInfos()) + for (const FileInfo *fileInfo : loadedPackageData.GetFirmwareInfo()->GetFileInfos()) { - includedFilesListWidget->addItem(fileInfo.GetFilename()); + includedFilesListWidget->addItem(fileInfo->GetFilename()); } - repartitionRadioButton->setChecked(loadedPackageData.GetFirmwareInfo().GetRepartition()); - noRebootRadioButton->setChecked(loadedPackageData.GetFirmwareInfo().GetNoReboot()); + repartitionRadioButton->setChecked(loadedPackageData.GetFirmwareInfo()->GetRepartition()); + noRebootRadioButton->setChecked(loadedPackageData.GetFirmwareInfo()->GetNoReboot()); } UpdateLoadPackageInterfaceAvailability(); @@ -229,8 +229,8 @@ void MainWindow::UpdateLoadPackageInterfaceAvailability(void) } else { - developerHomepageButton->setEnabled(!loadedPackageData.GetFirmwareInfo().GetUrl().isEmpty()); - developerDonateButton->setEnabled(!loadedPackageData.GetFirmwareInfo().GetDonateUrl().isEmpty()); + developerHomepageButton->setEnabled(!loadedPackageData.GetFirmwareInfo()->GetUrl().isEmpty()); + developerDonateButton->setEnabled(!loadedPackageData.GetFirmwareInfo()->GetDonateUrl().isEmpty()); loadFirmwareButton->setEnabled(!!(heimdallState & HeimdallState::Stopped)); } } @@ -242,11 +242,11 @@ void MainWindow::UpdateFlashInterfaceAvailability(void) partitionNameComboBox->setEnabled(partitionsListWidget->currentRow() >= 0); bool allPartitionsValid = true; - QList& fileList = workingPackageData.GetFirmwareInfo().GetFileInfos(); + QList& fileList = workingPackageData.GetFirmwareInfo()->GetFileInfos(); - for (const FileInfo& fileInfo : fileList) + for (const FileInfo *fileInfo : fileList) { - if (fileInfo.GetFilename().isEmpty()) + if (fileInfo->GetFilename().isEmpty()) { allPartitionsValid = false; break; @@ -276,10 +276,10 @@ void MainWindow::UpdateCreatePackageInterfaceAvailability(void) { if (!!(heimdallState & HeimdallState::Stopped)) { - const FirmwareInfo& firmwareInfo = workingPackageData.GetFirmwareInfo(); + const FirmwareInfo *firmwareInfo = workingPackageData.GetFirmwareInfo(); - bool fieldsPopulated = !(firmwareInfo.GetName().isEmpty() || firmwareInfo.GetVersion().isEmpty() || firmwareInfo.GetPlatformInfo().GetName().isEmpty() - || firmwareInfo.GetPlatformInfo().GetVersion().isEmpty() || firmwareInfo.GetDevelopers().isEmpty() || firmwareInfo.GetDeviceInfos().isEmpty()); + bool fieldsPopulated = !(firmwareInfo->GetName().isEmpty() || firmwareInfo->GetVersion().isEmpty() || firmwareInfo->GetPlatformInfo()->GetName().isEmpty() + || firmwareInfo->GetPlatformInfo()->GetVersion().isEmpty() || firmwareInfo->GetDevelopers().isEmpty() || firmwareInfo->GetDeviceInfos().isEmpty()); buildPackageButton->setEnabled(fieldsPopulated); addDeveloperButton->setEnabled(!addDeveloperButton->text().isEmpty()); @@ -369,12 +369,12 @@ void MainWindow::UpdatePartitionNamesInterface(void) if (partitionsListWidgetRow >= 0) { - const FileInfo& partitionInfo = workingPackageData.GetFirmwareInfo().GetFileInfos()[partitionsListWidget->currentRow()]; + const FileInfo *partitionInfo = workingPackageData.GetFirmwareInfo()->GetFileInfos()[partitionsListWidget->currentRow()]; for (unsigned int id : unusedPartitionIds) partitionNameComboBox->addItem(currentPitData.FindEntry(id)->GetPartitionName()); - partitionNameComboBox->addItem(currentPitData.FindEntry(partitionInfo.GetPartitionId())->GetPartitionName()); + partitionNameComboBox->addItem(currentPitData.FindEntry(partitionInfo->GetPartitionId())->GetPartitionName()); partitionNameComboBox->setCurrentIndex(unusedPartitionIds.length()); } @@ -507,7 +507,7 @@ void MainWindow::SelectFirmwarePackage(void) if (firmwarePackageLineEdit->text() != "") { - if (Packaging::ExtractPackage(firmwarePackageLineEdit->text(), loadedPackageData)) + if (Packaging::ExtractPackage(firmwarePackageLineEdit->text(), &loadedPackageData)) UpdatePackageUserInterface(); else loadedPackageData.Clear(); @@ -516,14 +516,14 @@ void MainWindow::SelectFirmwarePackage(void) void MainWindow::OpenDeveloperHomepage(void) { - if(!QDesktopServices::openUrl(QUrl(loadedPackageData.GetFirmwareInfo().GetUrl(), QUrl::TolerantMode))) - Alerts::DisplayWarning(QString("Cannot open invalid URL:\n%1").arg(loadedPackageData.GetFirmwareInfo().GetUrl())); + if(!QDesktopServices::openUrl(QUrl(loadedPackageData.GetFirmwareInfo()->GetUrl(), QUrl::TolerantMode))) + Alerts::DisplayWarning(QString("Cannot open invalid URL:\n%1").arg(loadedPackageData.GetFirmwareInfo()->GetUrl())); } void MainWindow::OpenDeveloperDonationWebpage(void) { - if (!QDesktopServices::openUrl(QUrl(loadedPackageData.GetFirmwareInfo().GetDonateUrl(), QUrl::TolerantMode))) - Alerts::DisplayWarning(QString("Cannot open invalid URL:\n%1").arg(loadedPackageData.GetFirmwareInfo().GetDonateUrl())); + if (!QDesktopServices::openUrl(QUrl(loadedPackageData.GetFirmwareInfo()->GetDonateUrl(), QUrl::TolerantMode))) + Alerts::DisplayWarning(QString("Cannot open invalid URL:\n%1").arg(loadedPackageData.GetFirmwareInfo()->GetDonateUrl())); } void MainWindow::LoadFirmwarePackage(void) @@ -532,37 +532,37 @@ void MainWindow::LoadFirmwarePackage(void) currentPitData.Clear(); // Loaded packages FileInfo store filenames, but the working package FileInfo need absolute paths - for (const FileInfo& packageFileInfo : loadedPackageData.GetFirmwareInfo().GetFileInfos()) + for (const FileInfo *packageFileInfo : loadedPackageData.GetFirmwareInfo()->GetFileInfos()) { bool fileFound = false; for (const QString& packageFilePath : loadedPackageData.GetFilePaths()) { - if (packageFilePath.endsWith(packageFileInfo.GetFilename())) + if (packageFilePath.endsWith(packageFileInfo->GetFilename())) { - FileInfo partitionInfo(packageFileInfo.GetPartitionId(), packageFilePath); - workingPackageData.GetFirmwareInfo().GetFileInfos().append(partitionInfo); + FileInfo *partitionInfo = new FileInfo{packageFileInfo->GetPartitionId(), packageFilePath}; + workingPackageData.GetFirmwareInfo()->GetFileInfos().append(partitionInfo); fileFound = true; break; - } + }; } if (!fileFound) - Alerts::DisplayWarning(QString("%1 is missing from the package.").arg(packageFileInfo.GetFilename())); + Alerts::DisplayWarning(QString("%1 is missing from the package.").arg(packageFileInfo->GetFilename())); } workingPackageData.GetFilePaths().append(loadedPackageData.GetFilePaths()); workingPackageData.SetPackagePath(loadedPackageData.GetPackagePath()); - QString pitFilename = loadedPackageData.GetFirmwareInfo().GetPitFilename(); + QString pitFilename = loadedPackageData.GetFirmwareInfo()->GetPitFilename(); // Find the PIT file and read it for (const QString& filePath : workingPackageData.GetFilePaths()) { if (filePath.endsWith(pitFilename)) { - workingPackageData.GetFirmwareInfo().SetPitFilename(filePath); + workingPackageData.GetFirmwareInfo()->SetPitFilename(filePath); if (!ReadPit(filePath)) { @@ -578,8 +578,8 @@ void MainWindow::LoadFirmwarePackage(void) } } - workingPackageData.GetFirmwareInfo().SetRepartition(loadedPackageData.GetFirmwareInfo().GetRepartition()); - workingPackageData.GetFirmwareInfo().SetNoReboot(loadedPackageData.GetFirmwareInfo().GetNoReboot()); + workingPackageData.GetFirmwareInfo()->SetRepartition(loadedPackageData.GetFirmwareInfo()->GetRepartition()); + workingPackageData.GetFirmwareInfo()->SetNoReboot(loadedPackageData.GetFirmwareInfo()->GetNoReboot()); loadedPackageData.Clear(false); @@ -590,9 +590,9 @@ void MainWindow::LoadFirmwarePackage(void) partitionsListWidget->clear(); // Populate partitionsListWidget with partition names (from the PIT file) - for (const FileInfo& partitionInfo : workingPackageData.GetFirmwareInfo().GetFileInfos()) + for (const FileInfo *partitionInfo : workingPackageData.GetFirmwareInfo()->GetFileInfos()) { - const PitEntry *pitEntry = currentPitData.FindEntry(partitionInfo.GetPartitionId()); + const PitEntry *pitEntry = currentPitData.FindEntry(partitionInfo->GetPartitionId()); if (pitEntry) { @@ -618,15 +618,15 @@ void MainWindow::LoadFirmwarePackage(void) partitionFileBrowseButton->setEnabled(false); repartitionCheckBox->setEnabled(true); - repartitionCheckBox->setChecked(workingPackageData.GetFirmwareInfo().GetRepartition()); + repartitionCheckBox->setChecked(workingPackageData.GetFirmwareInfo()->GetRepartition()); noRebootCheckBox->setEnabled(true); - noRebootCheckBox->setChecked(workingPackageData.GetFirmwareInfo().GetNoReboot()); + noRebootCheckBox->setChecked(workingPackageData.GetFirmwareInfo()->GetNoReboot()); partitionsListWidget->setEnabled(true); addPartitionButton->setEnabled(true); removePartitionButton->setEnabled(partitionsListWidget->currentRow() >= 0); - pitLineEdit->setText(workingPackageData.GetFirmwareInfo().GetPitFilename()); + pitLineEdit->setText(workingPackageData.GetFirmwareInfo()->GetPitFilename()); functionTabWidget->setCurrentWidget(flashTab); @@ -640,20 +640,19 @@ void MainWindow::SelectPartitionName(int index) unsigned int newPartitionIndex = unusedPartitionIds[index]; unusedPartitionIds.removeAt(index); - FileInfo& fileInfo = workingPackageData.GetFirmwareInfo().GetFileInfos()[partitionsListWidget->currentRow()]; - unusedPartitionIds.append(fileInfo.GetPartitionId()); - fileInfo.SetPartitionId(newPartitionIndex); + FileInfo *fileInfo = workingPackageData.GetFirmwareInfo()->GetFileInfos()[partitionsListWidget->currentRow()]; + unusedPartitionIds.append(fileInfo->GetPartitionId()); + fileInfo->SetPartitionId(newPartitionIndex); PitEntry *pitEntry = currentPitData.FindEntry(newPartitionIndex); - QString title("File"); - if (pitEntry && strlen(pitEntry->GetFlashFilename()) > 0) + if (strlen(pitEntry->GetFlashFilename()) > 0) title += " (" + QString(pitEntry->GetFlashFilename()) + ")"; partitionFileGroup->setTitle(title); - if (!fileInfo.GetFilename().isEmpty()) + if (!fileInfo->GetFilename().isEmpty()) { QString partitionFilename = pitEntry->GetFlashFilename(); int lastPeriod = partitionFilename.lastIndexOf(QChar('.')); @@ -662,9 +661,9 @@ void MainWindow::SelectPartitionName(int index) { QString partitionFileExtension = partitionFilename.mid(lastPeriod + 1); - lastPeriod = fileInfo.GetFilename().lastIndexOf(QChar('.')); + lastPeriod = fileInfo->GetFilename().lastIndexOf(QChar('.')); - if (lastPeriod < 0 || fileInfo.GetFilename().mid(lastPeriod + 1) != partitionFileExtension) + if (lastPeriod < 0 || fileInfo->GetFilename().mid(lastPeriod + 1) != partitionFileExtension) Alerts::DisplayWarning(QString("%1 partition expects files with file extension \"%2\".").arg(pitEntry->GetPartitionName(), partitionFileExtension)); } } @@ -684,8 +683,8 @@ void MainWindow::SelectPartitionFile(void) if (path != "") { - FileInfo& fileInfo = workingPackageData.GetFirmwareInfo().GetFileInfos()[partitionsListWidget->currentRow()]; - PitEntry *pitEntry = currentPitData.FindEntry(fileInfo.GetPartitionId()); + FileInfo *fileInfo = workingPackageData.GetFirmwareInfo()->GetFileInfos()[partitionsListWidget->currentRow()]; + PitEntry *pitEntry = currentPitData.FindEntry(fileInfo->GetPartitionId()); QString partitionFilename = pitEntry->GetFlashFilename(); int lastPeriod = partitionFilename.lastIndexOf(QChar('.')); @@ -700,7 +699,7 @@ void MainWindow::SelectPartitionFile(void) Alerts::DisplayWarning(QString("%1 partition expects files with file extension \"%2\".").arg(pitEntry->GetPartitionName(), partitionFileExtension)); } - fileInfo.SetFilename(path); + fileInfo->SetFilename(path); partitionFileLineEdit->setText(path); pitBrowseButton->setEnabled(true); @@ -716,19 +715,19 @@ void MainWindow::SelectPartition(int row) { if (row >= 0) { - const FileInfo& partitionInfo = workingPackageData.GetFirmwareInfo().GetFileInfos()[row]; + const FileInfo *partitionInfo = workingPackageData.GetFirmwareInfo()->GetFileInfos()[row]; UpdatePartitionNamesInterface(); - partitionIdLineEdit->setText(QString::number(partitionInfo.GetPartitionId())); - partitionFileLineEdit->setText(partitionInfo.GetFilename()); + partitionIdLineEdit->setText(QString::number(partitionInfo->GetPartitionId())); + partitionFileLineEdit->setText(partitionInfo->GetFilename()); partitionFileBrowseButton->setEnabled(true); removePartitionButton->setEnabled(true); QString title("File"); - PitEntry *pitEntry = currentPitData.FindEntry(partitionInfo.GetPartitionId()); + PitEntry *pitEntry = currentPitData.FindEntry(partitionInfo->GetPartitionId()); if (pitEntry && strlen(pitEntry->GetFlashFilename()) > 0) title += " (" + QString(pitEntry->GetFlashFilename()) + ")"; @@ -751,23 +750,23 @@ void MainWindow::SelectPartition(int row) void MainWindow::AddPartition(void) { - FileInfo partitionInfo(unusedPartitionIds.first(), ""); - workingPackageData.GetFirmwareInfo().GetFileInfos().append(partitionInfo); + FileInfo *partitionInfo = new FileInfo{unusedPartitionIds.first(), ""}; + workingPackageData.GetFirmwareInfo()->GetFileInfos().append(partitionInfo); UpdateUnusedPartitionIds(); pitBrowseButton->setEnabled(false); addPartitionButton->setEnabled(false); - partitionsListWidget->addItem(currentPitData.FindEntry(partitionInfo.GetPartitionId())->GetPartitionName()); + partitionsListWidget->addItem(currentPitData.FindEntry(partitionInfo->GetPartitionId())->GetPartitionName()); partitionsListWidget->setCurrentRow(partitionsListWidget->count() - 1); partitionsListWidget->setEnabled(false); UpdateInterfaceAvailability(); -} +}; void MainWindow::RemovePartition(void) { - workingPackageData.GetFirmwareInfo().GetFileInfos().removeAt(partitionsListWidget->currentRow()); + delete workingPackageData.GetFirmwareInfo()->GetFileInfos().takeAt(partitionsListWidget->currentRow()); UpdateUnusedPartitionIds(); QListWidgetItem *item = partitionsListWidget->currentItem(); @@ -788,18 +787,18 @@ void MainWindow::SelectPit(void) if (validPit) { // In order to map files in the old PIT to file in the new one, we first must use partition names instead of IDs. - QList fileInfos = workingPackageData.GetFirmwareInfo().GetFileInfos(); + QList& fileInfos = workingPackageData.GetFirmwareInfo()->GetFileInfos(); int partitionNamesCount = fileInfos.length(); QString *partitionNames = new QString[fileInfos.length()]; for (int i = 0; i < fileInfos.length(); i++) - partitionNames[i] = currentPitData.FindEntry(fileInfos[i].GetPartitionId())->GetPartitionName(); + partitionNames[i] = currentPitData.FindEntry(fileInfos[i]->GetPartitionId())->GetPartitionName(); currentPitData.Clear(); if (ReadPit(path)) { - workingPackageData.GetFirmwareInfo().SetPitFilename(path); + workingPackageData.GetFirmwareInfo()->SetPitFilename(path); partitionsListWidget->clear(); int partitionInfoIndex = 0; @@ -810,12 +809,12 @@ void MainWindow::SelectPit(void) if (pitEntry) { - fileInfos[partitionInfoIndex++].SetPartitionId(pitEntry->GetIdentifier()); + fileInfos[partitionInfoIndex++]->SetPartitionId(pitEntry->GetIdentifier()); partitionsListWidget->addItem(pitEntry->GetPartitionName()); } else { - fileInfos.removeAt(partitionInfoIndex); + delete fileInfos.takeAt(partitionInfoIndex); } } } @@ -829,9 +828,9 @@ void MainWindow::SelectPit(void) { Alerts::DisplayError("The file selected was not a valid PIT file."); - if (!workingPackageData.GetFirmwareInfo().GetPitFilename().isEmpty()) + if (!workingPackageData.GetFirmwareInfo()->GetPitFilename().isEmpty()) { - if (ReadPit(workingPackageData.GetFirmwareInfo().GetPitFilename())) + if (ReadPit(workingPackageData.GetFirmwareInfo()->GetPitFilename())) { validPit = true; } @@ -849,7 +848,7 @@ void MainWindow::SelectPit(void) delete [] partitionNames; - pitLineEdit->setText(workingPackageData.GetFirmwareInfo().GetPitFilename()); + pitLineEdit->setText(workingPackageData.GetFirmwareInfo()->GetPitFilename()); repartitionCheckBox->setEnabled(validPit); noRebootCheckBox->setEnabled(validPit); @@ -865,14 +864,14 @@ void MainWindow::SelectPit(void) void MainWindow::SetRepartition(int enabled) { - workingPackageData.GetFirmwareInfo().SetRepartition(enabled); + workingPackageData.GetFirmwareInfo()->SetRepartition(enabled); repartitionCheckBox->setChecked(enabled); } void MainWindow::SetNoReboot(int enabled) { - workingPackageData.GetFirmwareInfo().SetNoReboot(enabled); + workingPackageData.GetFirmwareInfo()->SetNoReboot(enabled); noRebootCheckBox->setChecked(enabled); } @@ -897,28 +896,28 @@ void MainWindow::StartFlash(void) heimdallState = HeimdallState::Flashing; heimdallFailed = false; - const FirmwareInfo& firmwareInfo = workingPackageData.GetFirmwareInfo(); - const QList& fileInfos = firmwareInfo.GetFileInfos(); + const FirmwareInfo *firmwareInfo = workingPackageData.GetFirmwareInfo(); + const QList& fileInfos = firmwareInfo->GetFileInfos(); QStringList arguments; arguments.append("flash"); - if (firmwareInfo.GetRepartition()) + if (firmwareInfo->GetRepartition()) arguments.append("--repartition"); arguments.append("--pit"); - arguments.append(firmwareInfo.GetPitFilename()); + arguments.append(firmwareInfo->GetPitFilename()); - for (const FileInfo& fileInfo : fileInfos) + for (const FileInfo *fileInfo : fileInfos) { QString flag; - flag.sprintf("--%u", fileInfo.GetPartitionId()); + flag.sprintf("--%u", fileInfo->GetPartitionId()); arguments.append(flag); - arguments.append(fileInfo.GetFilename()); + arguments.append(fileInfo->GetFilename()); } - if (firmwareInfo.GetNoReboot()) + if (firmwareInfo->GetNoReboot()) { arguments.append("--no-reboot"); heimdallState |= HeimdallState::NoReboot; @@ -937,36 +936,36 @@ void MainWindow::StartFlash(void) void MainWindow::FirmwareNameChanged(const QString& text) { - workingPackageData.GetFirmwareInfo().SetName(text); + workingPackageData.GetFirmwareInfo()->SetName(text); UpdateInterfaceAvailability(); } void MainWindow::FirmwareVersionChanged(const QString& text) { - workingPackageData.GetFirmwareInfo().SetVersion(text); + workingPackageData.GetFirmwareInfo()->SetVersion(text); UpdateInterfaceAvailability(); } void MainWindow::PlatformNameChanged(const QString& text) { - workingPackageData.GetFirmwareInfo().GetPlatformInfo().SetName(text); + workingPackageData.GetFirmwareInfo()->GetPlatformInfo()->SetName(text); UpdateInterfaceAvailability(); } void MainWindow::PlatformVersionChanged(const QString& text) { - workingPackageData.GetFirmwareInfo().GetPlatformInfo().SetVersion(text); + workingPackageData.GetFirmwareInfo()->GetPlatformInfo()->SetVersion(text); UpdateInterfaceAvailability(); } void MainWindow::HomepageUrlChanged(const QString& text) { - workingPackageData.GetFirmwareInfo().SetUrl(text); + workingPackageData.GetFirmwareInfo()->SetUrl(text); } void MainWindow::DonateUrlChanged(const QString& text) { - workingPackageData.GetFirmwareInfo().SetDonateUrl(text); + workingPackageData.GetFirmwareInfo()->SetDonateUrl(text); } void MainWindow::DeveloperNameChanged(const QString& text) @@ -985,7 +984,7 @@ void MainWindow::SelectDeveloper(int row) void MainWindow::AddDeveloper(void) { - workingPackageData.GetFirmwareInfo().GetDevelopers().append(createDeveloperNameLineEdit->text()); + workingPackageData.GetFirmwareInfo()->GetDevelopers().append(createDeveloperNameLineEdit->text()); createDevelopersListWidget->addItem(createDeveloperNameLineEdit->text()); createDeveloperNameLineEdit->clear(); @@ -995,7 +994,7 @@ void MainWindow::AddDeveloper(void) void MainWindow::RemoveDeveloper(void) { - workingPackageData.GetFirmwareInfo().GetDevelopers().removeAt(createDevelopersListWidget->currentRow()); + workingPackageData.GetFirmwareInfo()->GetDevelopers().removeAt(createDevelopersListWidget->currentRow()); QListWidgetItem *item = createDevelopersListWidget->currentItem(); createDevelopersListWidget->setCurrentRow(-1); @@ -1023,8 +1022,8 @@ void MainWindow::SelectDevice(int row) void MainWindow::AddDevice(void) { - workingPackageData.GetFirmwareInfo().GetDeviceInfos().append(DeviceInfo(deviceManufacturerLineEdit->text(), deviceProductCodeLineEdit->text(), - deviceNameLineEdit->text())); + DeviceInfo *deviceInfo = new DeviceInfo{deviceManufacturerLineEdit->text(), deviceProductCodeLineEdit->text(), deviceNameLineEdit->text()}; + workingPackageData.GetFirmwareInfo()->GetDeviceInfos().append(deviceInfo); createDevicesListWidget->addItem(deviceManufacturerLineEdit->text() + " " + deviceNameLineEdit->text() + ": " + deviceProductCodeLineEdit->text()); deviceManufacturerLineEdit->clear(); @@ -1036,7 +1035,7 @@ void MainWindow::AddDevice(void) void MainWindow::RemoveDevice(void) { - workingPackageData.GetFirmwareInfo().GetDeviceInfos().removeAt(createDevicesListWidget->currentRow()); + delete workingPackageData.GetFirmwareInfo()->GetDeviceInfos().takeAt(createDevicesListWidget->currentRow()); QListWidgetItem *item = createDevicesListWidget->currentItem(); createDevicesListWidget->setCurrentRow(-1); diff --git a/heimdall-frontend/source/qml/ArrayExtensions.js b/heimdall-frontend/source/qml/ArrayExtensions.js new file mode 100644 index 0000000..d034a8f --- /dev/null +++ b/heimdall-frontend/source/qml/ArrayExtensions.js @@ -0,0 +1,3 @@ +Array.prototype.extend = function(other) { + other.forEach(function(item) { this.push(item) }, this); +}; diff --git a/heimdall-frontend/source/qml/DropFiles.qml b/heimdall-frontend/source/qml/DropFiles.qml index 9187b4f..2745b4e 100644 --- a/heimdall-frontend/source/qml/DropFiles.qml +++ b/heimdall-frontend/source/qml/DropFiles.qml @@ -2,7 +2,9 @@ import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.2 +import "ArrayExtensions.js" as ArrayExtensions import "FileUtils.js" as FileUtils +import HeimdallFrontend 1.0 as Native DropFilesForm { id: background @@ -30,13 +32,16 @@ DropFilesForm { if (count > 0) { for (var i = 0; i < count; i++) { if (FileUtils.isFile(urls[i])) { - var filename = FileUtils.filenameFromUrl(urls[i]); - - fileModel.append({ icon: "drop_zone.svg", text: filename }); - - if (FileUtils.isArchive(filename)) { - fileUrls.push(FileUtils.extractArchive(urls[i])); + if (FileUtils.isArchive(urls[i])) { + var packageData = Native.Firmware.extractArchive(urls[i]); + packageData.filePaths.forEach(function(path) { + var filename = FileUtils.filenameFromPath(path); + fileModel.append({ icon: "drop_zone.svg", text: filename }); + }); + fileUrls.extend(packageData.filePaths); } else { + var filename = FileUtils.filenameFromUrl(urls[i]); + fileModel.append({ icon: "drop_zone.svg", text: filename }); fileUrls.push(urls[i]); } } diff --git a/heimdall-frontend/source/qml/FileUtils.js b/heimdall-frontend/source/qml/FileUtils.js index 3735a37..1b19818 100644 --- a/heimdall-frontend/source/qml/FileUtils.js +++ b/heimdall-frontend/source/qml/FileUtils.js @@ -1,42 +1,46 @@ function clipFileExtension(filename) { - var periodIndex = filename.lastIndexOf('.'); + var periodIndex = filename.lastIndexOf('.'); - if (periodIndex > 0) { - return filename.slice(0, periodIndex - 1); - } else if (periodIndex === 0) { - return ""; - } + if (periodIndex > 0) { + return filename.slice(0, periodIndex); + } else if (periodIndex === 0) { + return ""; + } - return filename; + return filename; } function filenameFromUrl(url) { - var urlString = url.toString(); - return urlString.slice(urlString.lastIndexOf('/') + 1); + var urlString = url.toString(); + return urlString.slice(urlString.lastIndexOf('/') + 1); +} + +function filenameFromPath(path) { + return filenameFromUrl(path); } function fileExtension(url) { - var filename = filenameFromUrl(url); - var periodIndex = filename.lastIndexOf('.'); + var filename = filenameFromUrl(url); + var periodIndex = filename.lastIndexOf('.'); - if (periodIndex >= 0) { - return filename.slice(periodIndex + 1); - } + if (periodIndex >= 0) { + return filename.slice(periodIndex + 1); + } - return ""; + return ""; } // TODO: Real implemention - call out to C++ and validate with QFileInfo etc. function isFile(url) { - var filename = filenameFromUrl(url); - return filename.length > 0; + var filename = filenameFromUrl(url); + return filename.length > 0; } function isArchive(url) { - var filename = filenameFromUrl(url); - var extension = fileExtension(filename); - return (extension === 'tar' || extension === 'zip') - || (extension === 'gz' && fileExtension(clipFileExtension(filename)) === 'tar'); + var filename = filenameFromUrl(url); + var extension = fileExtension(filename); + return (extension === 'tar' || extension === 'zip') + || (extension === 'gz' && fileExtension(clipFileExtension(filename)) === 'tar'); } function extractArchive(url) { diff --git a/heimdall-frontend/source/qml/bindings/Firmware.cpp b/heimdall-frontend/source/qml/bindings/Firmware.cpp new file mode 100644 index 0000000..28e269f --- /dev/null +++ b/heimdall-frontend/source/qml/bindings/Firmware.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2010-2014 Benjamin Dobell, Glass Echidna + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE.*/ + +// Qt +#include + +// Heimdall Frontend +#include "Firmware.h" +#include "Packaging.h" + +using namespace HeimdallFrontend; + +Firmware::Firmware() +{ +} + +QObject *Firmware::QmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + return new Firmware{}; +} + +void Firmware::Register(void) +{ + qmlRegisterSingletonType("HeimdallFrontend", 1, 0, "Firmware", &Firmware::QmlInstance); +} + +PackageData *Firmware::extractArchive(const QString &url) +{ + PackageData *packageData = new PackageData{}; + Packaging::ExtractPackage(QUrl{url}.toLocalFile(), packageData); + return packageData; +} diff --git a/heimdall-frontend/source/qml/bindings/Firmware.h b/heimdall-frontend/source/qml/bindings/Firmware.h new file mode 100644 index 0000000..200d290 --- /dev/null +++ b/heimdall-frontend/source/qml/bindings/Firmware.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010-2014 Benjamin Dobell, Glass Echidna + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE.*/ + +#ifndef FIRMWARE_H +#define FIRMWARE_H + +// Qt +#include + +// Heimdall Frontend +#include "PackageData.h" + +namespace HeimdallFrontend +{ + class Firmware : public QObject + { + Q_OBJECT + Q_DISABLE_COPY(Firmware) + + private: + + Firmware(); + + static QObject *QmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine); + + public: + + static void Register(void); + + Q_INVOKABLE HeimdallFrontend::PackageData *extractArchive(const QString& url); + }; +} + +Q_DECLARE_METATYPE(HeimdallFrontend::Firmware *) + +#endif diff --git a/heimdall-frontend/source/qml/qml.qrc b/heimdall-frontend/source/qml/qml.qrc index 641c200..f158406 100644 --- a/heimdall-frontend/source/qml/qml.qrc +++ b/heimdall-frontend/source/qml/qml.qrc @@ -1,5 +1,6 @@ + ArrayExtensions.js DropFiles.qml DropFilesForm.qml FileUtils.js -- cgit v1.2.3