2023-11-12 01:22:01 +01:00
|
|
|
#include <hex/helpers/http_requests.hpp>
|
|
|
|
#include <hex/helpers/fmt.hpp>
|
|
|
|
#include <hex/helpers/literals.hpp>
|
|
|
|
#include <hex/helpers/fs.hpp>
|
2023-11-21 14:38:01 +01:00
|
|
|
#include <hex/api/localization_manager.hpp>
|
2023-11-12 01:22:01 +01:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include <imgui.h>
|
|
|
|
|
|
|
|
#include <hex/ui/imgui_imhex_extensions.h>
|
|
|
|
#include <content/popups/popup_notification.hpp>
|
|
|
|
|
|
|
|
#include <wolv/io/file.hpp>
|
|
|
|
#include <wolv/utils/guards.hpp>
|
|
|
|
|
|
|
|
namespace hex::plugin::builtin {
|
2023-12-01 13:53:51 +01:00
|
|
|
|
|
|
|
using namespace hex::literals;
|
|
|
|
|
|
|
|
void drawFileToolSplitter() {
|
|
|
|
std::array sizeText = {
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.5_75_floppy"_lang),
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.3_5_floppy"_lang),
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.zip100"_lang),
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.zip200"_lang),
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.cdrom650"_lang),
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.cdrom700"_lang),
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.fat32"_lang),
|
|
|
|
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.custom"_lang)
|
|
|
|
};
|
|
|
|
std::array<u64, sizeText.size()> sizes = {
|
|
|
|
1200_KiB,
|
|
|
|
1400_KiB,
|
|
|
|
100_MiB,
|
|
|
|
200_MiB,
|
|
|
|
650_MiB,
|
|
|
|
700_MiB,
|
|
|
|
4_GiB,
|
|
|
|
1
|
|
|
|
};
|
|
|
|
|
|
|
|
static std::u8string selectedFile;
|
|
|
|
static std::u8string baseOutputPath;
|
|
|
|
static u64 splitSize = sizes[0];
|
|
|
|
static int selectedItem = 0;
|
|
|
|
static TaskHolder splitterTask;
|
|
|
|
|
|
|
|
if (ImGui::BeginChild("split_settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 7 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
|
|
|
|
ImGui::BeginDisabled(splitterTask.isRunning());
|
|
|
|
{
|
|
|
|
ImGui::InputText("##path", selectedFile);
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("...##input")) {
|
|
|
|
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
|
|
|
selectedFile = path.u8string();
|
|
|
|
});
|
2023-11-12 01:22:01 +01:00
|
|
|
}
|
2023-12-01 13:53:51 +01:00
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::TextUnformatted("hex.builtin.tools.file_tools.splitter.input"_lang);
|
|
|
|
|
|
|
|
ImGui::InputText("##base_path", baseOutputPath);
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("...##output")) {
|
|
|
|
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
|
|
|
|
baseOutputPath = path.u8string();
|
|
|
|
});
|
2023-11-12 01:22:01 +01:00
|
|
|
}
|
2023-12-01 13:53:51 +01:00
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::TextUnformatted("hex.builtin.tools.file_tools.splitter.output"_lang);
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
if (ImGui::Combo("###part_size", &selectedItem, sizeText.data(), sizeText.size())) {
|
|
|
|
splitSize = sizes[selectedItem];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
ImGui::BeginDisabled(splitterTask.isRunning() || selectedItem != sizes.size() - 1);
|
2023-11-12 01:22:01 +01:00
|
|
|
{
|
2023-12-01 13:53:51 +01:00
|
|
|
ImGui::InputScalar("###custom_size", ImGuiDataType_U64, &splitSize);
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::TextUnformatted("Bytes");
|
|
|
|
}
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
}
|
|
|
|
ImGui::EndChild();
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
ImGui::BeginDisabled(selectedFile.empty() || baseOutputPath.empty() || splitSize == 0);
|
|
|
|
{
|
|
|
|
if (splitterTask.isRunning())
|
|
|
|
ImGuiExt::TextSpinner("hex.builtin.tools.file_tools.splitter.picker.splitting"_lang);
|
|
|
|
else {
|
|
|
|
if (ImGui::Button("hex.builtin.tools.file_tools.splitter.picker.split"_lang)) {
|
|
|
|
splitterTask = TaskManager::createTask("hex.builtin.tools.file_tools.splitter.picker.splitting", 0, [](auto &task) {
|
|
|
|
ON_SCOPE_EXIT {
|
|
|
|
selectedFile.clear();
|
|
|
|
baseOutputPath.clear();
|
|
|
|
};
|
|
|
|
|
|
|
|
wolv::io::File file(selectedFile, wolv::io::File::Mode::Read);
|
|
|
|
|
|
|
|
if (!file.isValid()) {
|
|
|
|
PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.open"_lang);
|
|
|
|
return;
|
|
|
|
}
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
if (file.getSize() < splitSize) {
|
|
|
|
PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.size"_lang);
|
|
|
|
return;
|
|
|
|
}
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
task.setMaxValue(file.getSize());
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
u32 index = 1;
|
|
|
|
for (u64 offset = 0; offset < file.getSize(); offset += splitSize) {
|
|
|
|
task.update(offset);
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
std::fs::path path = baseOutputPath;
|
|
|
|
path += hex::format(".{:05}", index);
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
wolv::io::File partFile(path, wolv::io::File::Mode::Create);
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
if (!partFile.isValid()) {
|
|
|
|
PopupError::open(hex::format("hex.builtin.tools.file_tools.splitter.picker.error.create"_lang, index));
|
|
|
|
return;
|
|
|
|
}
|
2023-11-12 01:22:01 +01:00
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
constexpr static auto BufferSize = 0xFF'FFFF;
|
|
|
|
for (u64 partOffset = 0; partOffset < splitSize; partOffset += BufferSize) {
|
|
|
|
partFile.writeVector(file.readVector(std::min<u64>(BufferSize, splitSize - partOffset)));
|
|
|
|
partFile.flush();
|
2023-11-12 01:22:01 +01:00
|
|
|
}
|
|
|
|
|
2023-12-01 13:53:51 +01:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
PopupInfo::open("hex.builtin.tools.file_tools.splitter.picker.success"_lang);
|
|
|
|
});
|
2023-11-12 01:22:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-01 13:53:51 +01:00
|
|
|
ImGui::EndDisabled();
|
2023-11-12 01:22:01 +01:00
|
|
|
}
|
2023-12-01 13:53:51 +01:00
|
|
|
|
2023-11-12 01:22:01 +01:00
|
|
|
}
|