|
|
@ -628,24 +628,33 @@ void GMainWindow::OnMenuInstallToNAND() { |
|
|
QString filename = QFileDialog::getOpenFileName(this, tr("Install File"), |
|
|
QString filename = QFileDialog::getOpenFileName(this, tr("Install File"), |
|
|
UISettings::values.roms_path, file_filter); |
|
|
UISettings::values.roms_path, file_filter); |
|
|
|
|
|
|
|
|
|
|
|
if (filename.isEmpty()) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const auto qt_raw_copy = [this](FileSys::VirtualFile src, FileSys::VirtualFile dest) { |
|
|
const auto qt_raw_copy = [this](FileSys::VirtualFile src, FileSys::VirtualFile dest) { |
|
|
if (src == nullptr || dest == nullptr) |
|
|
if (src == nullptr || dest == nullptr) |
|
|
return false; |
|
|
return false; |
|
|
if (!dest->Resize(src->GetSize())) |
|
|
if (!dest->Resize(src->GetSize())) |
|
|
return false; |
|
|
return false; |
|
|
|
|
|
|
|
|
QProgressDialog progress(fmt::format("Installing file \"{}\"...", src->GetName()).c_str(), |
|
|
|
|
|
"Cancel", 0, src->GetSize() / 0x1000, this); |
|
|
|
|
|
|
|
|
std::array<u8, 0x1000> buffer{}; |
|
|
|
|
|
const int progress_maximum = static_cast<int>(src->GetSize() / buffer.size()); |
|
|
|
|
|
|
|
|
|
|
|
QProgressDialog progress( |
|
|
|
|
|
tr("Installing file \"%1\"...").arg(QString::fromStdString(src->GetName())), |
|
|
|
|
|
tr("Cancel"), 0, progress_maximum, this); |
|
|
progress.setWindowModality(Qt::WindowModal); |
|
|
progress.setWindowModality(Qt::WindowModal); |
|
|
|
|
|
|
|
|
std::array<u8, 0x1000> buffer{}; |
|
|
|
|
|
for (size_t i = 0; i < src->GetSize(); i += 0x1000) { |
|
|
|
|
|
|
|
|
for (size_t i = 0; i < src->GetSize(); i += buffer.size()) { |
|
|
if (progress.wasCanceled()) { |
|
|
if (progress.wasCanceled()) { |
|
|
dest->Resize(0); |
|
|
dest->Resize(0); |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
progress.setValue(i / 0x1000); |
|
|
|
|
|
|
|
|
const int progress_value = static_cast<int>(i / buffer.size()); |
|
|
|
|
|
progress.setValue(progress_value); |
|
|
|
|
|
|
|
|
const auto read = src->Read(buffer.data(), buffer.size(), i); |
|
|
const auto read = src->Read(buffer.data(), buffer.size(), i); |
|
|
dest->Write(buffer.data(), read, i); |
|
|
dest->Write(buffer.data(), read, i); |
|
|
} |
|
|
} |
|
|
@ -668,13 +677,12 @@ void GMainWindow::OnMenuInstallToNAND() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const auto overwrite = [this]() { |
|
|
const auto overwrite = [this]() { |
|
|
return QMessageBox::question(this, "Failed to Install", |
|
|
|
|
|
"The file you are attempting to install already exists " |
|
|
|
|
|
"in the cache. Would you like to overwrite it?") == |
|
|
|
|
|
|
|
|
return QMessageBox::question(this, tr("Failed to Install"), |
|
|
|
|
|
tr("The file you are attempting to install already exists " |
|
|
|
|
|
"in the cache. Would you like to overwrite it?")) == |
|
|
QMessageBox::Yes; |
|
|
QMessageBox::Yes; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
if (!filename.isEmpty()) { |
|
|
|
|
|
if (filename.endsWith("xci", Qt::CaseInsensitive)) { |
|
|
if (filename.endsWith("xci", Qt::CaseInsensitive)) { |
|
|
const auto xci = std::make_shared<FileSys::XCI>( |
|
|
const auto xci = std::make_shared<FileSys::XCI>( |
|
|
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); |
|
|
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); |
|
|
@ -709,15 +717,15 @@ void GMainWindow::OnMenuInstallToNAND() { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static const QStringList tt_options{"System Application", |
|
|
|
|
|
"System Archive", |
|
|
|
|
|
"System Application Update", |
|
|
|
|
|
"Firmware Package (Type A)", |
|
|
|
|
|
"Firmware Package (Type B)", |
|
|
|
|
|
"Game", |
|
|
|
|
|
"Game Update", |
|
|
|
|
|
"Game DLC", |
|
|
|
|
|
"Delta Title"}; |
|
|
|
|
|
|
|
|
const QStringList tt_options{tr("System Application"), |
|
|
|
|
|
tr("System Archive"), |
|
|
|
|
|
tr("System Application Update"), |
|
|
|
|
|
tr("Firmware Package (Type A)"), |
|
|
|
|
|
tr("Firmware Package (Type B)"), |
|
|
|
|
|
tr("Game"), |
|
|
|
|
|
tr("Game Update"), |
|
|
|
|
|
tr("Game DLC"), |
|
|
|
|
|
tr("Delta Title")}; |
|
|
bool ok; |
|
|
bool ok; |
|
|
const auto item = QInputDialog::getItem( |
|
|
const auto item = QInputDialog::getItem( |
|
|
this, tr("Select NCA Install Type..."), |
|
|
this, tr("Select NCA Install Type..."), |
|
|
@ -739,8 +747,7 @@ void GMainWindow::OnMenuInstallToNAND() { |
|
|
nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy); |
|
|
nca, static_cast<FileSys::TitleType>(index), false, qt_raw_copy); |
|
|
if (res == FileSys::InstallResult::Success) { |
|
|
if (res == FileSys::InstallResult::Success) { |
|
|
success(); |
|
|
success(); |
|
|
} else { |
|
|
|
|
|
if (res == FileSys::InstallResult::ErrorAlreadyExists) { |
|
|
|
|
|
|
|
|
} else if (res == FileSys::InstallResult::ErrorAlreadyExists) { |
|
|
if (overwrite()) { |
|
|
if (overwrite()) { |
|
|
const auto res2 = Service::FileSystem::GetUserNANDContents()->InstallEntry( |
|
|
const auto res2 = Service::FileSystem::GetUserNANDContents()->InstallEntry( |
|
|
nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy); |
|
|
nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy); |
|
|
@ -755,8 +762,6 @@ void GMainWindow::OnMenuInstallToNAND() { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void GMainWindow::OnMenuSelectGameListRoot() { |
|
|
void GMainWindow::OnMenuSelectGameListRoot() { |
|
|
QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); |
|
|
QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); |
|
|
|