aboutsummaryrefslogtreecommitdiffstats
path: root/heimdall-frontend/Source
diff options
context:
space:
mode:
Diffstat (limited to 'heimdall-frontend/Source')
-rw-r--r--heimdall-frontend/Source/FirmwareInfo.cpp2
-rw-r--r--heimdall-frontend/Source/Packaging.cpp25
-rw-r--r--heimdall-frontend/Source/aboutform.cpp95
-rw-r--r--heimdall-frontend/Source/aboutform.h17
-rw-r--r--heimdall-frontend/Source/mainwindow.cpp384
-rw-r--r--heimdall-frontend/Source/mainwindow.h25
6 files changed, 419 insertions, 129 deletions
diff --git a/heimdall-frontend/Source/FirmwareInfo.cpp b/heimdall-frontend/Source/FirmwareInfo.cpp
index 741ea6c..e11a002 100644
--- a/heimdall-frontend/Source/FirmwareInfo.cpp
+++ b/heimdall-frontend/Source/FirmwareInfo.cpp
@@ -772,7 +772,9 @@ void FirmwareInfo::WriteXml(QXmlStreamWriter& xml) const
xml.writeStartElement("files");
for (int i = 0; i < fileInfos.length(); i++)
+ {
fileInfos[i].WriteXml(xml, Packaging::ClashlessFilename(fileInfos, i));
+ }
xml.writeEndElement();
diff --git a/heimdall-frontend/Source/Packaging.cpp b/heimdall-frontend/Source/Packaging.cpp
index 79084e9..9bf7d46 100644
--- a/heimdall-frontend/Source/Packaging.cpp
+++ b/heimdall-frontend/Source/Packaging.cpp
@@ -301,7 +301,7 @@ bool Packaging::WriteTarEntry(const QString& filePath, QTemporaryFile *tarFile,
// Note: We don't support base-256 encoding. Support could be added later.
sprintf(tarHeader.fields.size, "%011llo", file.size());
- sprintf(tarHeader.fields.modifiedTime, "%011llo", qtFileInfo.lastModified().toMSecsSinceEpoch() / 1000);
+ sprintf(tarHeader.fields.modifiedTime, "%011llo", qtFileInfo.lastModified().toTime_t());
// Regular File
tarHeader.fields.typeFlag = '0';
@@ -381,6 +381,24 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QTemporaryFile *tarF
for (int i = 0; i < fileInfos.length(); i++)
{
+ // If the file was already compressed we don't compress it again.
+ bool skip = false;
+
+ for (int j = 0; j < i; j++)
+ {
+ if (fileInfos[i].GetFilename() == fileInfos[j].GetFilename())
+ {
+ skip = true;
+ break;
+ }
+ }
+
+ if (skip)
+ {
+ progressDialog.setValue(i);
+ continue;
+ }
+
QString filename = ClashlessFilename(fileInfos, i);
if (filename == "firmware.xml")
@@ -389,7 +407,7 @@ bool Packaging::CreateTar(const FirmwareInfo& firmwareInfo, QTemporaryFile *tarF
return (false);
}
- if (!WriteTarEntry(fileInfos[i].GetFilename(), tarFile, ClashlessFilename(fileInfos, i)))
+ if (!WriteTarEntry(fileInfos[i].GetFilename(), tarFile, filename))
{
tarFile->resize(0);
tarFile->close();
@@ -666,7 +684,8 @@ QString Packaging::ClashlessFilename(const QList<FileInfo>& fileInfos, int fileI
QString otherFilename = fileInfos[i].GetFilename().mid(lastSlash + 1);
- if (filename == otherFilename)
+ // 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())
renameIndex++;
}
diff --git a/heimdall-frontend/Source/aboutform.cpp b/heimdall-frontend/Source/aboutform.cpp
index bce9791..9bb975a 100644
--- a/heimdall-frontend/Source/aboutform.cpp
+++ b/heimdall-frontend/Source/aboutform.cpp
@@ -18,12 +18,107 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.*/
+// Qt
+#include <QDir>
+#include <QProcess>
+
// Heimdall Frontend
#include "aboutform.h"
+#define UNUSED(x) (void)(x)
+
using namespace HeimdallFrontend;
AboutForm::AboutForm(QWidget *parent) : QWidget(parent)
{
setupUi(this);
+
+ // Heimdall Command Line
+ QObject::connect(&heimdallProcess, SIGNAL(readyRead()), this, SLOT(HandleHeimdallStdout()));
+ QObject::connect(&heimdallProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(HandleHeimdallReturned(int, QProcess::ExitStatus)));
+ QObject::connect(&heimdallProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(HandleHeimdallError(QProcess::ProcessError)));
+
+ heimdallFailed = false;
+
+ RetrieveHeimdallVersion();
+}
+
+void AboutForm::RetrieveHeimdallVersion(void)
+{
+ heimdallProcess.setReadChannel(QProcess::StandardOutput);
+
+ heimdallProcess.start("heimdall", QStringList("version"));
+ heimdallProcess.waitForFinished(350);
+
+ // OS X was playing up and not finding heimdall, so we're manually checking the PATH.
+ if (heimdallFailed)
+ {
+ QStringList environment = QProcess::systemEnvironment();
+
+ QStringList paths;
+
+ // Ensure /usr/bin is in PATH
+ for (int i = 0; i < environment.length(); i++)
+ {
+ if (environment[i].left(5) == "PATH=")
+ {
+ paths = environment[i].mid(5).split(':');
+ paths.prepend("/usr/bin");
+ break;
+ }
+ }
+
+ int pathIndex = -1;
+
+ while (heimdallFailed && ++pathIndex < paths.length())
+ {
+ QString heimdallPath = paths[pathIndex];
+
+ if (heimdallPath.length() > 0)
+ {
+ heimdallFailed = false;
+
+ if (heimdallPath[heimdallPath.length() - 1] != QDir::separator())
+ heimdallPath += QDir::separator();
+
+ heimdallPath += "heimdall";
+
+ heimdallProcess.start(heimdallPath, QStringList("version"));
+ heimdallProcess.waitForFinished(350);
+ }
+ }
+
+ if (heimdallFailed)
+ versionCopyrightLabel->setText(versionCopyrightLabel->text().replace("%HEIMDALL-VERSION%", ""));
+ }
+}
+
+void AboutForm::HandleHeimdallStdout(void)
+{
+ QString version = heimdallProcess.readAll();
+
+ if (version.length() > 0)
+ {
+ if (version.at(0) == QChar('v'))
+ version = version.mid(1);
+
+ versionCopyrightLabel->setText(versionCopyrightLabel->text().replace("%HEIMDALL-VERSION%", "Version " + version + "<br />"));
+ }
+}
+
+void AboutForm::HandleHeimdallReturned(int exitCode, QProcess::ExitStatus exitStatus)
+{
+ UNUSED(exitCode);
+ UNUSED(exitStatus);
+
+ // If for some reason %HEIMDALL-VERSION% hasn't been replaced yet, we'll replace it with an empty string.
+ versionCopyrightLabel->setText(versionCopyrightLabel->text().replace("%HEIMDALL-VERSION%", ""));
}
+
+void AboutForm::HandleHeimdallError(QProcess::ProcessError error)
+{
+ UNUSED(error);
+
+ heimdallFailed = true;
+}
+
diff --git a/heimdall-frontend/Source/aboutform.h b/heimdall-frontend/Source/aboutform.h
index 12429ab..6223e3b 100644
--- a/heimdall-frontend/Source/aboutform.h
+++ b/heimdall-frontend/Source/aboutform.h
@@ -19,6 +19,7 @@
THE SOFTWARE.*/
// Qt
+#include <QProcess>
#include <QWidget>
// Heimdall Frontend
@@ -28,8 +29,24 @@ namespace HeimdallFrontend
{
class AboutForm : public QWidget, public Ui::AboutForm
{
+ Q_OBJECT
+
+ private:
+
+ bool heimdallFailed;
+ QProcess heimdallProcess;
+
+ void RetrieveHeimdallVersion(void);
+
public:
explicit AboutForm(QWidget *parent = 0);
+
+ public slots:
+
+ // Heimdall Command Line
+ void HandleHeimdallStdout(void);
+ void HandleHeimdallReturned(int exitCode, QProcess::ExitStatus exitStatus);
+ void HandleHeimdallError(QProcess::ProcessError error);
};
}
diff --git a/heimdall-frontend/Source/mainwindow.cpp b/heimdall-frontend/Source/mainwindow.cpp
index c3c97e1..621ac38 100644
--- a/heimdall-frontend/Source/mainwindow.cpp
+++ b/heimdall-frontend/Source/mainwindow.cpp
@@ -32,18 +32,18 @@
#include "mainwindow.h"
#include "Packaging.h"
+#define UNUSED(x) (void)(x)
+
using namespace HeimdallFrontend;
void MainWindow::StartHeimdall(const QStringList& arguments)
{
- flashProgressBar->setEnabled(true);
UpdateInterfaceAvailability();
+
+ heimdallProcess.setReadChannel(QProcess::StandardOutput);
- int pathIndex = -1;
- process.setReadChannel(QProcess::StandardOutput);
-
- process.start("heimdall", arguments);
- process.waitForStarted(3000);
+ heimdallProcess.start("heimdall", arguments);
+ heimdallProcess.waitForStarted(3000);
// OS X was playing up and not finding heimdall, so we're manually checking the PATH.
if (heimdallFailed)
@@ -63,6 +63,8 @@ void MainWindow::StartHeimdall(const QStringList& arguments)
}
}
+ int pathIndex = -1;
+
while (heimdallFailed && ++pathIndex < paths.length())
{
QString heimdallPath = paths[pathIndex];
@@ -76,8 +78,8 @@ void MainWindow::StartHeimdall(const QStringList& arguments)
heimdallPath += "heimdall";
- process.start(heimdallPath, arguments);
- process.waitForStarted(3000);
+ heimdallProcess.start(heimdallPath, arguments);
+ heimdallProcess.waitForStarted(3000);
}
}
@@ -86,7 +88,6 @@ void MainWindow::StartHeimdall(const QStringList& arguments)
flashLabel->setText("Failed to start Heimdall!");
heimdallState = MainWindow::kHeimdallStateStopped;
- flashProgressBar->setEnabled(false);
UpdateInterfaceAvailability();
}
}
@@ -101,8 +102,8 @@ void MainWindow::UpdateUnusedPartitionIds(void)
{
const PitEntry *pitEntry = currentPitData.GetEntry(i);
- if (!pitEntry->GetUnused() && strcmp(pitEntry->GetPartitionName(), "PIT") != 0)
- unusedPartitionIds.append(pitEntry->GetPartitionIdentifier());
+ if (pitEntry->GetBlockCount() > 0 && strcmp(pitEntry->GetPartitionName(), "PIT") != 0 && strcmp(pitEntry->GetPartitionName(), "PT") != 0)
+ unusedPartitionIds.append(pitEntry->GetIdentifier());
}
// Remove any used partition IDs from unusedPartitionIds
@@ -145,14 +146,9 @@ void MainWindow::UpdatePackageUserInterface(void)
developerNamesLineEdit->clear();
platformLineEdit->clear();
-
- developerHomepageButton->setEnabled(false);
- developerDonateButton->setEnabled(false);
repartitionRadioButton->setChecked(false);
noRebootRadioButton->setChecked(false);
-
- loadFirmwareButton->setEnabled(false);
}
else
{
@@ -173,16 +169,6 @@ void MainWindow::UpdatePackageUserInterface(void)
platformLineEdit->setText(loadedPackageData.GetFirmwareInfo().GetPlatformInfo().GetName() + " ("
+ loadedPackageData.GetFirmwareInfo().GetPlatformInfo().GetVersion() + ")");
- if (!loadedPackageData.GetFirmwareInfo().GetUrl().isEmpty())
- developerHomepageButton->setEnabled(true);
- else
- developerHomepageButton->setEnabled(false);
-
- if (!loadedPackageData.GetFirmwareInfo().GetDonateUrl().isEmpty())
- developerDonateButton->setEnabled(true);
- else
- developerDonateButton->setEnabled(false);
-
for (int i = 0; i < loadedPackageData.GetFirmwareInfo().GetDeviceInfos().length(); i++)
{
const DeviceInfo& deviceInfo = loadedPackageData.GetFirmwareInfo().GetDeviceInfos()[i];
@@ -197,9 +183,9 @@ void MainWindow::UpdatePackageUserInterface(void)
repartitionRadioButton->setChecked(loadedPackageData.GetFirmwareInfo().GetRepartition());
noRebootRadioButton->setChecked(loadedPackageData.GetFirmwareInfo().GetNoReboot());
-
- loadFirmwareButton->setEnabled(true);
}
+
+ UpdateLoadPackageInterfaceAvailability();
}
bool MainWindow::IsArchive(QString path)
@@ -209,9 +195,9 @@ bool MainWindow::IsArchive(QString path)
|| path.endsWith(".bz2", Qt::CaseInsensitive) || path.endsWith(".7z", Qt::CaseInsensitive) || path.endsWith(".rar", Qt::CaseInsensitive));
}
-QString MainWindow::PromptFileSelection(void)
+QString MainWindow::PromptFileSelection(const QString& caption, const QString& filter)
{
- QString path = QFileDialog::getOpenFileName(this, "Select File", lastDirectory);
+ QString path = QFileDialog::getOpenFileName(this, caption, lastDirectory, filter);
if (path != "")
lastDirectory = path.left(path.lastIndexOf('/') + 1);
@@ -219,9 +205,9 @@ QString MainWindow::PromptFileSelection(void)
return (path);
}
-QString MainWindow::PromptFileCreation(void)
+QString MainWindow::PromptFileCreation(const QString& caption, const QString& filter)
{
- QString path = QFileDialog::getSaveFileName(this, "Save File", lastDirectory);
+ QString path = QFileDialog::getSaveFileName(this, caption, lastDirectory, filter);
if (path != "")
lastDirectory = path.left(path.lastIndexOf('/') + 1);
@@ -229,50 +215,101 @@ QString MainWindow::PromptFileCreation(void)
return (path);
}
-void MainWindow::UpdatePartitionNamesInterface(void)
+void MainWindow::UpdateLoadPackageInterfaceAvailability(void)
{
- populatingPartitionNames = true;
+ if (loadedPackageData.IsCleared())
+ {
+ developerHomepageButton->setEnabled(false);
+ developerDonateButton->setEnabled(false);
- partitionNameComboBox->clear();
+ loadFirmwareButton->setEnabled(false);
+ }
+ else
+ {
+ if (!loadedPackageData.GetFirmwareInfo().GetUrl().isEmpty())
+ developerHomepageButton->setEnabled(true);
+ else
+ developerHomepageButton->setEnabled(false);
- int partitionsListWidgetRow = partitionsListWidget->currentRow();
+ if (!loadedPackageData.GetFirmwareInfo().GetDonateUrl().isEmpty())
+ developerDonateButton->setEnabled(true);
+ else
+ developerDonateButton->setEnabled(false);
- if (partitionsListWidgetRow >= 0)
+ loadFirmwareButton->setEnabled(heimdallState == MainWindow::kHeimdallStateStopped);
+ }
+}
+
+void MainWindow::UpdateFlashInterfaceAvailability(void)
+{
+ if (heimdallState == MainWindow::kHeimdallStateStopped)
{
- const FileInfo& partitionInfo = workingPackageData.GetFirmwareInfo().GetFileInfos()[partitionsListWidget->currentRow()];
+ partitionNameComboBox->setEnabled(partitionsListWidget->currentRow() >= 0);
- for (int i = 0; i < unusedPartitionIds.length(); i++)
- partitionNameComboBox->addItem(currentPitData.FindEntry(unusedPartitionIds[i])->GetPartitionName());
+ bool allPartitionsValid = true;
+ QList<FileInfo>& fileList = workingPackageData.GetFirmwareInfo().GetFileInfos();
- partitionNameComboBox->addItem(currentPitData.FindEntry(partitionInfo.GetPartitionId())->GetPartitionName());
- partitionNameComboBox->setCurrentIndex(unusedPartitionIds.length());
+ for (int i = 0; i < fileList.length(); i++)
+ {
+ if (fileList[i].GetFilename().isEmpty())
+ {
+ allPartitionsValid = false;
+ break;
+ }
+ }
- partitionNameComboBox->setEnabled(true);
+ bool validFlashSettings = allPartitionsValid && fileList.length() > 0;
+
+ flashProgressBar->setEnabled(false);
+ optionsGroup->setEnabled(true);
+ startFlashButton->setEnabled(validFlashSettings);
}
else
{
partitionNameComboBox->setEnabled(false);
- }
- populatingPartitionNames = false;
+ flashProgressBar->setEnabled(true);
+ optionsGroup->setEnabled(false);
+ startFlashButton->setEnabled(false);
+ }
}
-void MainWindow::UpdateInterfaceAvailability(void)
+void MainWindow::UpdateCreatePackageInterfaceAvailability(void)
{
- if (heimdallState != MainWindow::kHeimdallStateStopped)
+ if (heimdallState == MainWindow::kHeimdallStateStopped)
{
- startFlashButton->setEnabled(false);
+ const FirmwareInfo& firmwareInfo = workingPackageData.GetFirmwareInfo();
- detectDeviceButton->setEnabled(false);
- closePcScreenButton->setEnabled(false);
- pitSaveAsButton->setEnabled(false);
- downloadPitButton->setEnabled(false);
- printPitButton->setEnabled(false);
+ if (firmwareInfo.GetName().isEmpty() || firmwareInfo.GetVersion().isEmpty() || firmwareInfo.GetPlatformInfo().GetName().isEmpty()
+ || firmwareInfo.GetPlatformInfo().GetVersion().isEmpty() || firmwareInfo.GetDevelopers().isEmpty() || firmwareInfo.GetDeviceInfos().isEmpty())
+ {
+ buildPackageButton->setEnabled(false);
+ }
+ else
+ {
+ buildPackageButton->setEnabled(true);
+ }
+
+ if (addDeveloperButton->text().isEmpty())
+ addDeveloperButton->setEnabled(false);
+ else
+ addDeveloperButton->setEnabled(true);
- return;
+ if (createDevelopersListWidget->currentRow() >= 0)
+ removeDeveloperButton->setEnabled(true);
+ else
+ removeDeveloperButton->setEnabled(false);
}
else
{
+ buildPackageButton->setEnabled(false);
+ }
+}
+
+void MainWindow::UpdateUtilitiesInterfaceAvailability(void)
+{
+ if (heimdallState == MainWindow::kHeimdallStateStopped)
+ {
detectDeviceButton->setEnabled(true);
closePcScreenButton->setEnabled(true);
pitSaveAsButton->setEnabled(true);
@@ -281,43 +318,86 @@ void MainWindow::UpdateInterfaceAvailability(void)
downloadPitButton->setEnabled(true);
else
downloadPitButton->setEnabled(false);
+
+ if (printPitDeviceRadioBox->isChecked())
+ {
+ // Device
+ printLocalPitGroup->setEnabled(false);
+ printPitButton->setEnabled(true);
+ }
+ else
+ {
+ // Local File
+ printLocalPitGroup->setEnabled(true);
+ printLocalPitLineEdit->setEnabled(true);
+ printLocalPitBrowseButton->setEnabled(true);
+ printPitButton->setEnabled(!printLocalPitLineEdit->text().isEmpty());
+ }
+ }
+ else
+ {
+ detectDeviceButton->setEnabled(false);
+ closePcScreenButton->setEnabled(false);
+ pitSaveAsButton->setEnabled(false);
+ downloadPitButton->setEnabled(false);
- printPitButton->setEnabled(true);
+ printLocalPitGroup->setEnabled(false);
+ printPitButton->setEnabled(false);
}
+}
+
+void MainWindow::UpdateInterfaceAvailability(void)
+{
+ UpdateLoadPackageInterfaceAvailability();
+ UpdateFlashInterfaceAvailability();
+ UpdateCreatePackageInterfaceAvailability();
+ UpdateUtilitiesInterfaceAvailability();
- bool allPartitionsValid = true;
+ if (heimdallState == MainWindow::kHeimdallStateStopped)
+ {
+ // Enable/disable tabs
- QList<FileInfo>& fileList = workingPackageData.GetFirmwareInfo().GetFileInfos();
+ for (int i = 0; i < functionTabWidget->count(); i++)
+ functionTabWidget->setTabEnabled(i, true);
- for (int i = 0; i < fileList.length(); i++)
+ functionTabWidget->setTabEnabled(functionTabWidget->indexOf(createPackageTab), startFlashButton->isEnabled());
+ }
+ else
{
- if (fileList[i].GetFilename().isEmpty())
+ // Disable non-current tabs
+
+ for (int i = 0; i < functionTabWidget->count(); i++)
{
- allPartitionsValid = false;
- break;
+ if (i == functionTabWidget->currentIndex())
+ functionTabWidget->setTabEnabled(i, true);
+ else
+ functionTabWidget->setTabEnabled(i, false);
}
}
-
- bool validSettings = allPartitionsValid && fileList.length() > 0;
-
- startFlashButton->setEnabled(validSettings);
-
- functionTabWidget->setTabEnabled(functionTabWidget->indexOf(createPackageTab), validSettings);
}
-void MainWindow::UpdateBuildPackageButton(void)
+void MainWindow::UpdatePartitionNamesInterface(void)
{
- const FirmwareInfo& firmwareInfo = workingPackageData.GetFirmwareInfo();
+ populatingPartitionNames = true;
- if (firmwareInfo.GetName().isEmpty() || firmwareInfo.GetVersion().isEmpty() || firmwareInfo.GetPlatformInfo().GetName().isEmpty()
- || firmwareInfo.GetPlatformInfo().GetVersion().isEmpty() || firmwareInfo.GetDevelopers().isEmpty() || firmwareInfo.GetDeviceInfos().isEmpty())
- {
- buildPackageButton->setEnabled(false);
- }
- else
+ partitionNameComboBox->clear();
+
+ int partitionsListWidgetRow = partitionsListWidget->currentRow();
+
+ if (partitionsListWidgetRow >= 0)
{
- buildPackageButton->setEnabled(true);
+ const FileInfo& partitionInfo = workingPackageData.GetFirmwareInfo().GetFileInfos()[partitionsListWidget->currentRow()];
+
+ for (int i = 0; i < unusedPartitionIds.length(); i++)
+ partitionNameComboBox->addItem(currentPitData.FindEntry(unusedPartitionIds[i])->GetPartitionName());
+
+ partitionNameComboBox->addItem(currentPitData.FindEntry(partitionInfo.GetPartitionId())->GetPartitionName());
+ partitionNameComboBox->setCurrentIndex(unusedPartitionIds.length());
}
+
+ populatingPartitionNames = false;
+
+ UpdateFlashInterfaceAvailability();
}
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
@@ -388,15 +468,21 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
// Utilities Tab
QObject::connect(detectDeviceButton, SIGNAL(clicked()), this, SLOT(DetectDevice()));
+
QObject::connect(closePcScreenButton, SIGNAL(clicked()), this, SLOT(ClosePcScreen()));
+
+ QObject::connect(printPitDeviceRadioBox, SIGNAL(toggled(bool)), this, SLOT(DevicePrintPitToggled(bool)));
+ QObject::connect(printPitLocalFileRadioBox, SIGNAL(toggled(bool)), this, SLOT(LocalFilePrintPitToggled(bool)));
+ QObject::connect(printLocalPitBrowseButton, SIGNAL(clicked()), this, SLOT(SelectPrintPitFile()));
QObject::connect(printPitButton, SIGNAL(clicked()), this, SLOT(PrintPit()));
+
QObject::connect(pitSaveAsButton, SIGNAL(clicked()), this, SLOT(SelectPitDestination()));
QObject::connect(downloadPitButton, SIGNAL(clicked()), this, SLOT(DownloadPit()));
// Heimdall Command Line
- QObject::connect(&process, SIGNAL(readyRead()), this, SLOT(HandleHeimdallStdout()));
- QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(HandleHeimdallReturned(int, QProcess::ExitStatus)));
- QObject::connect(&process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(HandleHeimdallError(QProcess::ProcessError)));
+ QObject::connect(&heimdallProcess, SIGNAL(readyRead()), this, SLOT(HandleHeimdallStdout()));
+ QObject::connect(&heimdallProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(HandleHeimdallReturned(int, QProcess::ExitStatus)));
+ QObject::connect(&heimdallProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(HandleHeimdallError(QProcess::ProcessError)));
}
MainWindow::~MainWindow()
@@ -429,7 +515,7 @@ void MainWindow::SelectFirmwarePackage(void)
loadedPackageData.Clear();
UpdatePackageUserInterface();
- QString path = PromptFileSelection();
+ QString path = PromptFileSelection("Select Package", "*.tar.gz");
firmwarePackageLineEdit->setText(path);
if (firmwarePackageLineEdit->text() != "")
@@ -458,7 +544,6 @@ void MainWindow::LoadFirmwarePackage(void)
workingPackageData.Clear();
currentPitData.Clear();
- // Make flashSettings responsible for the temporary files
workingPackageData.GetFiles().append(loadedPackageData.GetFiles());
loadedPackageData.RemoveAllFiles();
@@ -575,10 +660,18 @@ void MainWindow::SelectPartitionName(int index)
unusedPartitionIds.append(fileInfo.GetPartitionId());
fileInfo.SetPartitionId(newPartitionIndex);
+ PitEntry *pitEntry = currentPitData.FindEntry(newPartitionIndex);
+
+ QString title("File");
+
+ if (pitEntry && strlen(pitEntry->GetFlashFilename()) > 0)
+ title += " (" + QString(pitEntry->GetFlashFilename()) + ")";
+
+ partitionFileGroup->setTitle(title);
+
if (!fileInfo.GetFilename().isEmpty())
{
- PitEntry *pitEntry = currentPitData.FindEntry(newPartitionIndex);
- QString partitionFilename = pitEntry->GetFilename();
+ QString partitionFilename = pitEntry->GetFlashFilename();
int lastPeriod = partitionFilename.lastIndexOf(QChar('.'));
if (lastPeriod >= 0)
@@ -610,7 +703,7 @@ void MainWindow::SelectPartitionFile(void)
FileInfo& fileInfo = workingPackageData.GetFirmwareInfo().GetFileInfos()[partitionsListWidget->currentRow()];
PitEntry *pitEntry = currentPitData.FindEntry(fileInfo.GetPartitionId());
- QString partitionFilename = pitEntry->GetFilename();
+ QString partitionFilename = pitEntry->GetFlashFilename();
int lastPeriod = partitionFilename.lastIndexOf(QChar('.'));
if (lastPeriod >= 0)
@@ -648,6 +741,15 @@ void MainWindow::SelectPartition(int row)
partitionFileBrowseButton->setEnabled(true);
removePartitionButton->setEnabled(true);
+
+ QString title("File");
+
+ PitEntry *pitEntry = currentPitData.FindEntry(partitionInfo.GetPartitionId());
+
+ if (pitEntry && strlen(pitEntry->GetFlashFilename()) > 0)
+ title += " (" + QString(pitEntry->GetFlashFilename()) + ")";
+
+ partitionFileGroup->setTitle(title);
}
else
{
@@ -658,6 +760,8 @@ void MainWindow::SelectPartition(int row)
partitionFileBrowseButton->setEnabled(false);
removePartitionButton->setEnabled(false);
+
+ partitionFileGroup->setTitle("File");
}
}
@@ -673,6 +777,7 @@ void MainWindow::AddPartition(void)
partitionsListWidget->addItem(currentPitData.FindEntry(partitionInfo.GetPartitionId())->GetPartitionName());
partitionsListWidget->setCurrentRow(partitionsListWidget->count() - 1);
partitionsListWidget->setEnabled(false);
+
UpdateInterfaceAvailability();
}
@@ -693,7 +798,7 @@ void MainWindow::RemovePartition(void)
void MainWindow::SelectPit(void)
{
- QString path = PromptFileSelection();
+ QString path = PromptFileSelection("Select PIT", "*.pit");
bool validPit = path != "";
if (validPit)
@@ -723,7 +828,7 @@ void MainWindow::SelectPit(void)
if (pitEntry)
{
- fileInfos[partitionInfoIndex++].SetPartitionId(pitEntry->GetPartitionIdentifier());
+ fileInfos[partitionInfoIndex++].SetPartitionId(pitEntry->GetIdentifier());
partitionsListWidget->addItem(pitEntry->GetPartitionName());
}
else
@@ -828,25 +933,25 @@ void MainWindow::StartFlash(void)
void MainWindow::FirmwareNameChanged(const QString& text)
{
workingPackageData.GetFirmwareInfo().SetName(text);
- UpdateBuildPackageButton();
+ UpdateInterfaceAvailability();
}
void MainWindow::FirmwareVersionChanged(const QString& text)
{
workingPackageData.GetFirmwareInfo().SetVersion(text);
- UpdateBuildPackageButton();
+ UpdateInterfaceAvailability();
}
void MainWindow::PlatformNameChanged(const QString& text)
{
workingPackageData.GetFirmwareInfo().GetPlatformInfo().SetName(text);
- UpdateBuildPackageButton();
+ UpdateInterfaceAvailability();
}
void MainWindow::PlatformVersionChanged(const QString& text)
{
workingPackageData.GetFirmwareInfo().GetPlatformInfo().SetVersion(text);
- UpdateBuildPackageButton();
+ UpdateInterfaceAvailability();
}
void MainWindow::HomepageUrlChanged(const QString& text)
@@ -861,18 +966,16 @@ void MainWindow::DonateUrlChanged(const QString& text)
void MainWindow::DeveloperNameChanged(const QString& text)
{
- if (text.isEmpty())
- addDeveloperButton->setEnabled(false);
- else
- addDeveloperButton->setEnabled(true);
+ UNUSED(text);
+
+ UpdateCreatePackageInterfaceAvailability();
}
void MainWindow::SelectDeveloper(int row)
{
- if (row >= 0)
- removeDeveloperButton->setEnabled(true);
- else
- removeDeveloperButton->setEnabled(false);
+ UNUSED(row);
+
+ UpdateCreatePackageInterfaceAvailability();
}
void MainWindow::AddDeveloper(void)
@@ -881,8 +984,8 @@ void MainWindow::AddDeveloper(void)
createDevelopersListWidget->addItem(createDeveloperNameLineEdit->text());
createDeveloperNameLineEdit->clear();
-
- UpdateBuildPackageButton();
+
+ UpdateCreatePackageInterfaceAvailability();
}
void MainWindow::RemoveDeveloper(void)
@@ -894,12 +997,14 @@ void MainWindow::RemoveDeveloper(void)
delete item;
removeDeveloperButton->setEnabled(false);
-
- UpdateBuildPackageButton();
+
+ UpdateInterfaceAvailability();
}
void MainWindow::DeviceInfoChanged(const QString& text)
{
+ UNUSED(text);
+
if (deviceManufacturerLineEdit->text().isEmpty() || deviceNameLineEdit->text().isEmpty() || deviceProductCodeLineEdit->text().isEmpty())
addDeviceButton->setEnabled(false);
else
@@ -923,8 +1028,8 @@ void MainWindow::AddDevice(void)
deviceManufacturerLineEdit->clear();
deviceNameLineEdit->clear();
deviceProductCodeLineEdit->clear();
-
- UpdateBuildPackageButton();
+
+ UpdateInterfaceAvailability();
}
void MainWindow::RemoveDevice(void)
@@ -936,13 +1041,13 @@ void MainWindow::RemoveDevice(void)
delete item;
removeDeviceButton->setEnabled(false);
-
- UpdateBuildPackageButton();
+
+ UpdateInterfaceAvailability();
}
void MainWindow::BuildPackage(void)
{
- QString packagePath = PromptFileCreation();
+ QString packagePath = PromptFileCreation("Save Package", "*.tar.gz");
if (!packagePath.isEmpty())
{
@@ -995,7 +1100,7 @@ void MainWindow::ClosePcScreen(void)
void MainWindow::SelectPitDestination(void)
{
- QString path = PromptFileCreation();
+ QString path = PromptFileCreation("Save PIT", "*.pit");
if (path != "")
{
@@ -1029,6 +1134,41 @@ void MainWindow::DownloadPit(void)
StartHeimdall(arguments);
}
+void MainWindow::DevicePrintPitToggled(bool checked)
+{
+ if (checked)
+ {
+ if (printPitLocalFileRadioBox->isChecked())
+ printPitLocalFileRadioBox->setChecked(false);
+ }
+
+ UpdateUtilitiesInterfaceAvailability();
+}
+
+void MainWindow::LocalFilePrintPitToggled(bool checked)
+{
+ if (checked)
+ {
+ if (printPitDeviceRadioBox->isChecked())
+ printPitDeviceRadioBox->setChecked(false);
+ }
+
+ UpdateUtilitiesInterfaceAvailability();
+}
+
+void MainWindow::SelectPrintPitFile(void)
+{
+ QString path = PromptFileSelection("Select PIT", "*.pit");
+
+ if (path != "")
+ printLocalPitLineEdit->setText(path);
+
+ if (printLocalPitLineEdit->text() != "")
+ printPitButton->setEnabled(true);
+ else
+ printPitButton->setEnabled(false);
+}
+
void MainWindow::PrintPit(void)
{
utilityOutputPlainTextEdit->clear();
@@ -1039,14 +1179,21 @@ void MainWindow::PrintPit(void)
QStringList arguments;
arguments.append("print-pit");
+ if (printPitLocalFileRadioBox->isChecked())
+ {
+ arguments.append("--file");
+ arguments.append(printLocalPitLineEdit->text());
+ }
+
arguments.append("--stdout-errors");
+ arguments.append("--no-reboot");
StartHeimdall(arguments);
}
void MainWindow::HandleHeimdallStdout(void)
{
- QString output = process.readAll();
+ QString output = heimdallProcess.readAll();
// We often receive multiple lots of output from Heimdall at one time. So we use regular expressions
// to ensure we don't miss out on any important information.
@@ -1078,29 +1225,22 @@ void MainWindow::HandleHeimdallStdout(void)
void MainWindow::HandleHeimdallReturned(int exitCode, QProcess::ExitStatus exitStatus)
{
- // This is a work-around for strange issues as a result of a exitCode being cast to
- // a unsigned char.
- char byteExitCode = exitCode;
-
- if (exitStatus == QProcess::NormalExit && byteExitCode >= 0)
+ if (exitStatus == QProcess::NormalExit && exitCode == 0)
{
if (heimdallState == MainWindow::kHeimdallStateFlashing)
{
- if (byteExitCode == 1)
- flashLabel->setText("Failed to detect compatible device!");
- else
- flashLabel->setText("Flash completed sucessfully!");
+ flashLabel->setText("Flash completed successfully!");
}
else if (heimdallState == MainWindow::kHeimdallStateDetectingDevice)
{
- deviceDetectedRadioButton->setChecked(byteExitCode == 0);
+ deviceDetectedRadioButton->setChecked(true);
}
}
else
{
if (heimdallState == MainWindow::kHeimdallStateFlashing)
{
- QString error = process.readAllStandardError();
+ QString error = heimdallProcess.readAllStandardError();
int lastNewLineChar = error.lastIndexOf('\n');
@@ -1111,6 +1251,10 @@ void MainWindow::HandleHeimdallReturned(int exitCode, QProcess::ExitStatus exitS
flashLabel->setText(error);
}
+ else if (heimdallState == MainWindow::kHeimdallStateDetectingDevice)
+ {
+ deviceDetectedRadioButton->setChecked(false);
+ }
}
heimdallState = MainWindow::kHeimdallStateStopped;
diff --git a/heimdall-frontend/Source/mainwindow.h b/heimdall-frontend/Source/mainwindow.h
index 9d21978..bea15cd 100644
--- a/heimdall-frontend/Source/mainwindow.h
+++ b/heimdall-frontend/Source/mainwindow.h
@@ -56,6 +56,12 @@ namespace HeimdallFrontend
kHeimdallStateCount
};
+ enum
+ {
+ kPrintPitSourceDevice = 0,
+ kPrintPitSourceLocalFile
+ };
+
AboutForm aboutForm;
QString lastDirectory;
@@ -64,7 +70,7 @@ namespace HeimdallFrontend
bool heimdallFailed;
int heimdallState;
- QProcess process;
+ QProcess heimdallProcess;
PackageData loadedPackageData;
@@ -76,6 +82,7 @@ namespace HeimdallFrontend
bool verboseOutput;
+
void StartHeimdall(const QStringList& arguments);
void UpdateUnusedPartitionIds(void);
@@ -85,13 +92,16 @@ namespace HeimdallFrontend
bool IsArchive(QString path);
- QString PromptFileSelection(void);
- QString PromptFileCreation(void);
-
- void UpdatePartitionNamesInterface(void);
+ QString PromptFileSelection(const QString& caption = QString("Select File"), const QString& filter = QString());
+ QString PromptFileCreation(const QString& caption = QString("Save File"), const QString& filter = QString());
+
+ void UpdateLoadPackageInterfaceAvailability(void);
+ void UpdateFlashInterfaceAvailability(void);
+ void UpdateCreatePackageInterfaceAvailability(void);
+ void UpdateUtilitiesInterfaceAvailability(void);
void UpdateInterfaceAvailability(void);
- void UpdateBuildPackageButton(void);
+ void UpdatePartitionNamesInterface(void);
public:
@@ -155,6 +165,9 @@ namespace HeimdallFrontend
void SelectPitDestination(void);
void DownloadPit(void);
+ void DevicePrintPitToggled(bool checked);
+ void LocalFilePrintPitToggled(bool checked);
+ void SelectPrintPitFile(void);
void PrintPit(void);
// Heimdall Command Line