#include #include #include #include #include #include #include #include #include #include #include #include namespace hex::plugin::builtin { static void openFile(const std::fs::path &path) { auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.file", true); if (auto *fileProvider = dynamic_cast(provider); fileProvider != nullptr) { fileProvider->setPath(path); if (fileProvider->open()) EventManager::post(fileProvider); } } void registerEventHandlers() { EventManager::subscribe([](GLFWwindow *window) { if (ImHexApi::Provider::isDirty()) { glfwSetWindowShouldClose(window, GLFW_FALSE); PopupQuestion::open("hex.builtin.popup.exit_application.desc"_lang, []{ ImHexApi::Provider::resetDirty(); ImHexApi::System::closeImHex(); }, [] { } ); } else if (TaskManager::getRunningTaskCount() > 0 || TaskManager::getRunningBackgroundTaskCount() > 0) { glfwSetWindowShouldClose(window, GLFW_FALSE); TaskManager::doLater([] { for (auto &task : TaskManager::getRunningTasks()) task->interrupt(); PopupTasksWaiting::open(); }); } }); EventManager::subscribe([](hex::prv::Provider *provider, bool *shouldClose) { if (provider->isDirty()) { *shouldClose = false; PopupQuestion::open("hex.builtin.popup.close_provider.desc"_lang, []{ ImHexApi::Provider::remove(ImHexApi::Provider::impl::getClosingProvider(), true); }, [] { } ); } }); EventManager::subscribe([](hex::prv::Provider *oldProvider, hex::prv::Provider *newProvider) { hex::unused(oldProvider); hex::unused(newProvider); EventManager::post(); }); EventManager::subscribe([](hex::prv::Provider *provider) { if (provider != nullptr && ImHexApi::Provider::get() == provider) EventManager::post(); EventManager::post(nullptr, provider); }); EventManager::subscribe(openFile); EventManager::subscribe([](const std::string &name) { if (name == "Create File") { auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true); if (newProvider != nullptr && !newProvider->open()) hex::ImHexApi::Provider::remove(newProvider); else EventManager::post(newProvider); } else if (name == "Open File") { fs::openFileBrowser(fs::DialogMode::Open, { }, [](const auto &path) { if (path.extension() == ".hexproj") { if (!ProjectFile::load(path)) { PopupError::open("hex.builtin.popup.error.project.load"_lang); } } else { FileProvider* newProvider = static_cast( ImHexApi::Provider::createProvider("hex.builtin.provider.file", true) ); if (newProvider == nullptr) return; newProvider->setPath(path); if (!newProvider->open()) hex::ImHexApi::Provider::remove(newProvider); else EventManager::post(newProvider); } }); } else if (name == "Open Project") { fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} }, [](const auto &path) { if (!ProjectFile::load(path)) { PopupError::open("hex.builtin.popup.error.project.load"_lang); } }); } }); EventManager::subscribe([](auto, auto) { EventManager::post(); }); // Handles the provider initialization, and calls EventProviderOpened if successful EventManager::subscribe([](hex::prv::Provider *provider) { if (provider->shouldSkipLoadInterface()) return; if (provider->hasFilePicker()) { if (!provider->handleFilePicker()) { TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); }); return; } if (!provider->open()) { PopupError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage())); TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); }); return; } EventManager::post(provider); } else if (provider->hasLoadInterface()) EventManager::post(View::toWindowName("hex.builtin.view.provider_settings.load_popup")); else { if (!provider->open() || !provider->isAvailable()) { PopupError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage())); TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); }); return; } EventManager::post(provider); } }); EventManager::subscribe([](const ImHexApi::HexEditor::ProviderRegion ®ion) { ImHexApi::HexEditor::impl::setCurrentSelection(region); }); EventManager::subscribe([](const std::string &message) { PopupInfo::open(message); }); EventManager::subscribe([](const std::string &message) { PopupError::open(message); }); EventManager::subscribe([](const std::string &message) { PopupFatal::open(message); }); fs::setFileBrowserErrorCallback([](const std::string& errMsg){ #if defined(NFD_PORTAL) PopupError::open(hex::format("hex.builtin.popup.error.file_dialog.portal"_lang, errMsg)); #else PopupError::open(hex::format("hex.builtin.popup.error.file_dialog.common"_lang, errMsg)); #endif }); } }