diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index 5e89b33..2fa47fc 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -1,6 +1,5 @@ #include "mainwindow.h" -#include <iostream> #include <QFileDialog> #include <QLineEdit> #include <QMenuBar> @@ -139,6 +138,8 @@ void MainWindow::InitializeMenuBar() file_menu->addAction(tr("&View SI File"), tr("Ctrl+I"), this, &MainWindow::ViewSIFile); + file_menu->addAction(tr("E&xtract All"), this, &MainWindow::ExtractAll); + file_menu->addSeparator(); file_menu->addAction(tr("E&xit"), this, &MainWindow::close); @@ -244,6 +245,39 @@ QString MainWindow::GetOpenFileName() return QFileDialog::getOpenFileName(this, QString(), QString(), kFileFilter); } +bool MainWindow::ExtractAllRecursiveInternal(const QDir &dir, const si::Core *obj) +{ + if (!dir.mkpath(QStringLiteral("."))) { + QMessageBox::critical(this, tr("Extract All Failed"), tr("Failed to create directory \"%1\". Try extracting somewhere else.").arg(dir.absolutePath())); + return false; + } + + for (const Core *child : obj->GetChildren()) { + if (const Object *obj = dynamic_cast<const Object*>(child)) { + if (!obj->data().empty()) { + QString realFilename = QString::fromStdString(obj->filename()); + realFilename = realFilename.mid(realFilename.lastIndexOf('\\')+1); + + QString output = dir.filePath(realFilename); + + if (!obj->ExtractToFile(output.toUtf8())) { + QMessageBox::critical(this, tr("Extract All Failed"), tr("Failed to create file \"%1\". Try extracting somewhere else.").arg(output)); + return false; + } + } + + if (obj->HasChildren()) { + // Extract its children too + if (!ExtractAllRecursiveInternal(QDir(dir.filePath(QString::fromStdString(obj->name()))), obj)) { + return false; + } + } + } + } + + return true; +} + void MainWindow::NewFile() { model_.SetCore(nullptr); @@ -354,6 +388,22 @@ void MainWindow::ViewSIFile() } } +void MainWindow::ExtractAll() +{ + QString s = QFileDialog::getExistingDirectory(this, tr("Extract All To...")); + if (s.isEmpty()) { + return; + } + + QDir dir(s); + if (!dir.exists()) { + QMessageBox::critical(this, tr("Extract All Failed"), tr("Directory \"%1\" is not valid. Try extracting somewhere else.").arg(s)); + return; + } + + ExtractAllRecursiveInternal(dir, &interleaf_); +} + void MainWindow::ExtraChanged() { if (last_set_data_) { diff --git a/app/mainwindow.h b/app/mainwindow.h index 1b26b8b..053265f 100644 --- a/app/mainwindow.h +++ b/app/mainwindow.h @@ -8,6 +8,7 @@ #include <QPlainTextEdit> #include <QStackedWidget> #include <QTreeView> +#include <qdir.h> #include "objectmodel.h" #include "panel.h" @@ -36,6 +37,8 @@ private: QString GetOpenFileName(); + bool ExtractAllRecursiveInternal(const QDir &dir, const si::Core *obj); + static const QString kFileFilter; QStackedWidget *config_stack_; @@ -78,6 +81,7 @@ private slots: void ReplaceClicked(); void ViewSIFile(); + void ExtractAll(); void ExtraChanged(); void LocationChanged(const si::Vector3 &v);