feat: Allow recents to also display other providers
This commit is contained in:
parent
440ba3823e
commit
85f0e04d0e
@ -337,12 +337,12 @@ namespace hex {
|
|||||||
void add(bool addToList = true) {
|
void add(bool addToList = true) {
|
||||||
auto typeName = T().getTypeName();
|
auto typeName = T().getTypeName();
|
||||||
|
|
||||||
(void)EventManager::subscribe<RequestCreateProvider>([expectedName = typeName](const std::string &name, hex::prv::Provider **provider) {
|
(void)EventManager::subscribe<RequestCreateProvider>([expectedName = typeName](const std::string &name, bool skipLoadInterface, hex::prv::Provider **provider) {
|
||||||
if (name != expectedName) return;
|
if (name != expectedName) return;
|
||||||
|
|
||||||
auto newProvider = new T();
|
prv::Provider *newProvider = new T();
|
||||||
|
|
||||||
hex::ImHexApi::Provider::add(newProvider);
|
hex::ImHexApi::Provider::add(newProvider, skipLoadInterface);
|
||||||
|
|
||||||
if (provider != nullptr)
|
if (provider != nullptr)
|
||||||
*provider = newProvider;
|
*provider = newProvider;
|
||||||
|
@ -129,7 +129,7 @@ namespace hex {
|
|||||||
EVENT_DEF(RequestOpenFile, std::fs::path);
|
EVENT_DEF(RequestOpenFile, std::fs::path);
|
||||||
EVENT_DEF(RequestChangeTheme, u32);
|
EVENT_DEF(RequestChangeTheme, u32);
|
||||||
EVENT_DEF(RequestOpenPopup, std::string);
|
EVENT_DEF(RequestOpenPopup, std::string);
|
||||||
EVENT_DEF(RequestCreateProvider, std::string, hex::prv::Provider **);
|
EVENT_DEF(RequestCreateProvider, std::string, bool, hex::prv::Provider **);
|
||||||
|
|
||||||
EVENT_DEF(RequestShowInfoPopup, std::string);
|
EVENT_DEF(RequestShowInfoPopup, std::string);
|
||||||
EVENT_DEF(RequestShowErrorPopup, std::string);
|
EVENT_DEF(RequestShowErrorPopup, std::string);
|
||||||
|
@ -137,7 +137,7 @@ namespace hex {
|
|||||||
void resetDirty();
|
void resetDirty();
|
||||||
bool isDirty();
|
bool isDirty();
|
||||||
|
|
||||||
void add(prv::Provider *provider);
|
void add(prv::Provider *provider, bool skipLoadInterface = false);
|
||||||
|
|
||||||
template<std::derived_from<prv::Provider> T>
|
template<std::derived_from<prv::Provider> T>
|
||||||
void add(auto &&...args) {
|
void add(auto &&...args) {
|
||||||
@ -146,7 +146,7 @@ namespace hex {
|
|||||||
|
|
||||||
void remove(prv::Provider *provider, bool noQuestions = false);
|
void remove(prv::Provider *provider, bool noQuestions = false);
|
||||||
|
|
||||||
prv::Provider* createProvider(const std::string &unlocalizedName);
|
prv::Provider* createProvider(const std::string &unlocalizedName, bool skipLoadInterface = false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,8 @@ namespace hex::fs {
|
|||||||
Resources,
|
Resources,
|
||||||
Constants,
|
Constants,
|
||||||
Encodings,
|
Encodings,
|
||||||
Logs
|
Logs,
|
||||||
|
Recent
|
||||||
};
|
};
|
||||||
|
|
||||||
std::optional<std::fs::path> getExecutablePath();
|
std::optional<std::fs::path> getExecutablePath();
|
||||||
|
@ -104,6 +104,9 @@ namespace hex::prv {
|
|||||||
|
|
||||||
virtual std::pair<Region, bool> getRegionValidity(u64 address) const;
|
virtual std::pair<Region, bool> getRegionValidity(u64 address) const;
|
||||||
|
|
||||||
|
void skipLoadInterface() { this->m_skipLoadInterface = true; }
|
||||||
|
[[nodiscard]] bool shouldSkipLoadInterface() const { return this->m_skipLoadInterface; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
u32 m_currPage = 0;
|
u32 m_currPage = 0;
|
||||||
u64 m_baseAddress = 0;
|
u64 m_baseAddress = 0;
|
||||||
@ -115,6 +118,7 @@ namespace hex::prv {
|
|||||||
u32 m_id;
|
u32 m_id;
|
||||||
|
|
||||||
bool m_dirty = false;
|
bool m_dirty = false;
|
||||||
|
bool m_skipLoadInterface = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static u32 s_idCounter;
|
static u32 s_idCounter;
|
||||||
|
@ -268,10 +268,13 @@ namespace hex {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(prv::Provider *provider) {
|
void add(prv::Provider *provider, bool skipLoadInterface) {
|
||||||
if (Task::getRunningTaskCount() > 0)
|
if (Task::getRunningTaskCount() > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skipLoadInterface)
|
||||||
|
provider->skipLoadInterface();
|
||||||
|
|
||||||
s_providers.push_back(provider);
|
s_providers.push_back(provider);
|
||||||
EventManager::post<EventProviderCreated>(provider);
|
EventManager::post<EventProviderCreated>(provider);
|
||||||
|
|
||||||
@ -310,9 +313,9 @@ namespace hex {
|
|||||||
delete provider;
|
delete provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
prv::Provider* createProvider(const std::string &unlocalizedName) {
|
prv::Provider* createProvider(const std::string &unlocalizedName, bool skipLoadInterface) {
|
||||||
prv::Provider* result = nullptr;
|
prv::Provider* result = nullptr;
|
||||||
EventManager::post<RequestCreateProvider>(unlocalizedName, &result);
|
EventManager::post<RequestCreateProvider>(unlocalizedName, skipLoadInterface, &result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -232,6 +232,9 @@ namespace hex::fs {
|
|||||||
case ImHexPath::Yara:
|
case ImHexPath::Yara:
|
||||||
result = appendPath(getDataPaths(), "yara");
|
result = appendPath(getDataPaths(), "yara");
|
||||||
break;
|
break;
|
||||||
|
case ImHexPath::Recent:
|
||||||
|
result = appendPath(getConfigPaths(), "recent");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!listNonExisting) {
|
if (!listNonExisting) {
|
||||||
|
@ -251,6 +251,9 @@ namespace hex::prv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json Provider::storeSettings(nlohmann::json settings) const {
|
nlohmann::json Provider::storeSettings(nlohmann::json settings) const {
|
||||||
|
settings["displayName"] = this->getName();
|
||||||
|
settings["type"] = this->getTypeName();
|
||||||
|
|
||||||
settings["baseAddress"] = this->m_baseAddress;
|
settings["baseAddress"] = this->m_baseAddress;
|
||||||
settings["currPage"] = this->m_currPage;
|
settings["currPage"] = this->m_currPage;
|
||||||
|
|
||||||
@ -263,7 +266,7 @@ namespace hex::prv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Region, bool> Provider::getRegionValidity(u64 address) const {
|
std::pair<Region, bool> Provider::getRegionValidity(u64 address) const {
|
||||||
if (address > this->getActualSize())
|
if (address < this->getActualSize())
|
||||||
return { Region::Invalid(), false };
|
return { Region::Invalid(), false };
|
||||||
|
|
||||||
bool insideValidRegion = false;
|
bool insideValidRegion = false;
|
||||||
|
@ -59,18 +59,20 @@ namespace hex::init {
|
|||||||
bool createDirectories() {
|
bool createDirectories() {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
|
using enum fs::ImHexPath;
|
||||||
constexpr std::array paths = {
|
constexpr std::array paths = {
|
||||||
fs::ImHexPath::Patterns,
|
Patterns,
|
||||||
fs::ImHexPath::PatternsInclude,
|
PatternsInclude,
|
||||||
fs::ImHexPath::Magic,
|
Magic,
|
||||||
fs::ImHexPath::Plugins,
|
Plugins,
|
||||||
fs::ImHexPath::Resources,
|
Resources,
|
||||||
fs::ImHexPath::Config,
|
Config,
|
||||||
fs::ImHexPath::Constants,
|
Constants,
|
||||||
fs::ImHexPath::Yara,
|
Yara,
|
||||||
fs::ImHexPath::Encodings,
|
Encodings,
|
||||||
fs::ImHexPath::Python,
|
Python,
|
||||||
fs::ImHexPath::Logs
|
Logs,
|
||||||
|
Recent
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if ImHex is installed in portable mode
|
// Check if ImHex is installed in portable mode
|
||||||
|
@ -27,8 +27,8 @@ namespace hex::plugin::builtin::prv {
|
|||||||
[[nodiscard]] std::string getName() const override;
|
[[nodiscard]] std::string getName() const override;
|
||||||
[[nodiscard]] std::vector<std::pair<std::string, std::string>> getDataInformation() const override { return { }; }
|
[[nodiscard]] std::vector<std::pair<std::string, std::string>> getDataInformation() const override { return { }; }
|
||||||
|
|
||||||
void loadSettings(const nlohmann::json &settings) override { hex::unused(settings); }
|
void loadSettings(const nlohmann::json &settings) override;
|
||||||
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override { return settings; }
|
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override;
|
||||||
|
|
||||||
[[nodiscard]] std::string getTypeName() const override {
|
[[nodiscard]] std::string getTypeName() const override {
|
||||||
return "hex.builtin.provider.intel_hex";
|
return "hex.builtin.provider.intel_hex";
|
||||||
|
@ -13,11 +13,16 @@
|
|||||||
|
|
||||||
#include "provider_extra_data.hpp"
|
#include "provider_extra_data.hpp"
|
||||||
|
|
||||||
|
#include "content/providers/file_provider.hpp"
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
static void openFile(const std::fs::path &path) {
|
static void openFile(const std::fs::path &path) {
|
||||||
ImHexApi::Provider::createProvider("hex.builtin.provider.file");
|
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
||||||
EventManager::post<EventFileLoaded>(path);
|
if (auto *fileProvider = dynamic_cast<prv::FileProvider*>(provider); fileProvider != nullptr) {
|
||||||
|
fileProvider->setPath(path);
|
||||||
|
(void)fileProvider->open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerEventHandlers() {
|
void registerEventHandlers() {
|
||||||
@ -77,6 +82,9 @@ namespace hex::plugin::builtin {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EventManager::subscribe<EventProviderCreated>([](hex::prv::Provider *provider) {
|
EventManager::subscribe<EventProviderCreated>([](hex::prv::Provider *provider) {
|
||||||
|
if (provider->shouldSkipLoadInterface())
|
||||||
|
return;
|
||||||
|
|
||||||
if (provider->hasFilePicker()) {
|
if (provider->hasFilePicker()) {
|
||||||
if (!provider->handleFilePicker()) {
|
if (!provider->handleFilePicker()) {
|
||||||
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||||
@ -95,9 +103,6 @@ namespace hex::plugin::builtin {
|
|||||||
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
||||||
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!provider->isWritable())
|
|
||||||
View::showErrorPopup("hex.builtin.popup.error.read_only"_lang);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -232,4 +232,16 @@ namespace hex::plugin::builtin::prv {
|
|||||||
return { Region { closestInterval.start, (closestInterval.stop - closestInterval.start) + 1}, true };
|
return { Region { closestInterval.start, (closestInterval.stop - closestInterval.start) + 1}, true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntelHexProvider::loadSettings(const nlohmann::json &settings) {
|
||||||
|
Provider::loadSettings(settings);
|
||||||
|
|
||||||
|
this->m_sourceFilePath = settings["path"].get<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json IntelHexProvider::storeSettings(nlohmann::json settings) const {
|
||||||
|
settings["path"] = this->m_sourceFilePath.string();
|
||||||
|
|
||||||
|
return Provider::storeSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,9 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (ImGui::Button("hex.builtin.common.open"_lang)) {
|
if (ImGui::Button("hex.builtin.common.open"_lang)) {
|
||||||
if (provider->open())
|
if (provider->open()) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
View::showErrorPopup("hex.builtin.view.provider_settings.load_error"_lang);
|
View::showErrorPopup("hex.builtin.view.provider_settings.load_error"_lang);
|
||||||
ImHexApi::Provider::remove(provider);
|
ImHexApi::Provider::remove(provider);
|
||||||
|
@ -6,18 +6,17 @@
|
|||||||
#include <hex/ui/view.hpp>
|
#include <hex/ui/view.hpp>
|
||||||
#include <hex/helpers/fs.hpp>
|
#include <hex/helpers/fs.hpp>
|
||||||
#include <hex/helpers/logger.hpp>
|
#include <hex/helpers/logger.hpp>
|
||||||
|
#include <hex/helpers/file.hpp>
|
||||||
|
|
||||||
#include <hex/api/project_file_manager.hpp>
|
#include <hex/api/project_file_manager.hpp>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <implot.h>
|
#include <implot.h>
|
||||||
#include <imnodes.h>
|
|
||||||
#include <hex/ui/imgui_imhex_extensions.h>
|
#include <hex/ui/imgui_imhex_extensions.h>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <romfs/romfs.hpp>
|
#include <romfs/romfs.hpp>
|
||||||
|
|
||||||
#include <fonts/fontawesome_font.h>
|
|
||||||
#include <fonts/codicons_font.h>
|
#include <fonts/codicons_font.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -25,12 +24,74 @@
|
|||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
static ImGui::Texture s_bannerTexture, s_backdropTexture;
|
static ImGui::Texture s_bannerTexture, s_backdropTexture;
|
||||||
static std::list<std::fs::path> s_recentFilePaths;
|
|
||||||
|
|
||||||
static std::fs::path s_safetyBackupPath;
|
static std::fs::path s_safetyBackupPath;
|
||||||
|
|
||||||
static std::string s_tipOfTheDay;
|
static std::string s_tipOfTheDay;
|
||||||
|
|
||||||
|
struct RecentProvider {
|
||||||
|
std::string displayName;
|
||||||
|
std::string type;
|
||||||
|
std::fs::path filePath;
|
||||||
|
|
||||||
|
nlohmann::json data;
|
||||||
|
|
||||||
|
bool operator==(const RecentProvider &other) const {
|
||||||
|
return displayName == other.displayName && type == other.type && data == other.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static std::vector<RecentProvider> s_recentProviders;
|
||||||
|
|
||||||
|
static void updateRecentProviders() {
|
||||||
|
s_recentProviders.clear();
|
||||||
|
|
||||||
|
// Query all recent providers
|
||||||
|
std::vector<std::fs::path> recentFiles;
|
||||||
|
for (const auto &folder : fs::getDefaultPaths(fs::ImHexPath::Recent)) {
|
||||||
|
for (const auto &entry : std::fs::directory_iterator(folder)) {
|
||||||
|
if (entry.is_regular_file())
|
||||||
|
recentFiles.push_back(entry.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort recent provider files by last modified time
|
||||||
|
std::sort(recentFiles.begin(), recentFiles.end(), [](const auto &a, const auto &b) {
|
||||||
|
return std::fs::last_write_time(a) > std::fs::last_write_time(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (u32 i = 0; i < recentFiles.size() && s_recentProviders.size() < 5; i++) {
|
||||||
|
auto &path = recentFiles[i];
|
||||||
|
try {
|
||||||
|
auto jsonData = nlohmann::json::parse(fs::File(path, fs::File::Mode::Read).readString());
|
||||||
|
s_recentProviders.push_back(RecentProvider {
|
||||||
|
.displayName = jsonData["displayName"],
|
||||||
|
.type = jsonData["type"],
|
||||||
|
.filePath = path,
|
||||||
|
.data = jsonData
|
||||||
|
});
|
||||||
|
} catch (...) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-duplicate recent providers
|
||||||
|
s_recentProviders.erase(std::unique(s_recentProviders.begin(), s_recentProviders.end()), s_recentProviders.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadRecentProvider(const RecentProvider &recentProvider) {
|
||||||
|
auto *provider = ImHexApi::Provider::createProvider(recentProvider.type, true);
|
||||||
|
if (provider != nullptr) {
|
||||||
|
provider->loadSettings(recentProvider.data);
|
||||||
|
|
||||||
|
if (!provider->open() || !provider->isAvailable()) {
|
||||||
|
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
||||||
|
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRecentProviders();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void loadDefaultLayout() {
|
static void loadDefaultLayout() {
|
||||||
auto layouts = ContentRegistry::Interface::getLayouts();
|
auto layouts = ContentRegistry::Interface::getLayouts();
|
||||||
if (!layouts.empty()) {
|
if (!layouts.empty()) {
|
||||||
@ -153,9 +214,9 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::UnderlinedText("hex.builtin.welcome.start.recent"_lang);
|
ImGui::UnderlinedText("hex.builtin.welcome.start.recent"_lang);
|
||||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
|
||||||
{
|
{
|
||||||
for (auto &path : s_recentFilePaths) {
|
for (const auto &recentProvider : s_recentProviders) {
|
||||||
if (ImGui::BulletHyperlink(std::fs::path(path).filename().string().c_str())) {
|
if (ImGui::BulletHyperlink(recentProvider.displayName.c_str())) {
|
||||||
EventManager::post<RequestOpenFile>(path);
|
loadRecentProvider(recentProvider);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,6 +375,8 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createWelcomeScreen() {
|
void createWelcomeScreen() {
|
||||||
|
updateRecentProviders();
|
||||||
|
|
||||||
(void)EventManager::subscribe<EventFrameBegin>(drawWelcomeScreen);
|
(void)EventManager::subscribe<EventFrameBegin>(drawWelcomeScreen);
|
||||||
(void)EventManager::subscribe<EventFrameBegin>(drawNoViewsBackground);
|
(void)EventManager::subscribe<EventFrameBegin>(drawNoViewsBackground);
|
||||||
|
|
||||||
@ -405,35 +468,16 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
(void)EventManager::subscribe<EventFileLoaded>([](const auto &path) {
|
(void)EventManager::subscribe<EventProviderOpened>([](prv::Provider *provider) {
|
||||||
s_recentFilePaths.push_front(path);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::list<std::fs::path> uniques;
|
auto recentPath = fs::getDefaultPaths(fs::ImHexPath::Recent).front();
|
||||||
for (auto &file : s_recentFilePaths) {
|
auto fileName = hex::format("{:%y%m%d_%H%M%S}.json", fmt::gmtime(std::chrono::system_clock::now()));
|
||||||
|
fs::File recentFile(recentPath / fileName, fs::File::Mode::Create);
|
||||||
|
|
||||||
bool exists = false;
|
recentFile.write(provider->storeSettings().dump(4));
|
||||||
for (auto &unique : uniques) {
|
|
||||||
if (file == unique)
|
|
||||||
exists = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!exists && !file.empty())
|
updateRecentProviders();
|
||||||
uniques.push_back(file);
|
|
||||||
|
|
||||||
if (uniques.size() > 5)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
s_recentFilePaths = uniques;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::vector<std::string> recentFilesVector;
|
|
||||||
for (const auto &recentPath : s_recentFilePaths)
|
|
||||||
recentFilesVector.push_back(recentPath.string());
|
|
||||||
|
|
||||||
ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files", recentFilesVector);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
EventManager::subscribe<EventProviderCreated>([](auto) {
|
EventManager::subscribe<EventProviderCreated>([](auto) {
|
||||||
@ -442,23 +486,23 @@ namespace hex::plugin::builtin {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1075, [&] {
|
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1075, [&] {
|
||||||
if (ImGui::BeginMenu("hex.builtin.menu.file.open_recent"_lang, !s_recentFilePaths.empty())) {
|
if (ImGui::BeginMenu("hex.builtin.menu.file.open_recent"_lang, !s_recentProviders.empty())) {
|
||||||
// Copy to avoid changing list while iteration
|
// Copy to avoid changing list while iteration
|
||||||
std::list<std::fs::path> recentFilePaths = s_recentFilePaths;
|
auto recentProviders = s_recentProviders;
|
||||||
for (auto &path : recentFilePaths) {
|
for (auto &recentProvider : recentProviders) {
|
||||||
auto filename = std::fs::path(path).filename().string();
|
if (ImGui::MenuItem(recentProvider.displayName.c_str())) {
|
||||||
if (ImGui::MenuItem(filename.c_str())) {
|
loadRecentProvider(recentProvider);
|
||||||
EventManager::post<RequestOpenFile>(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::MenuItem("hex.builtin.menu.file.clear_recent"_lang)) {
|
if (ImGui::MenuItem("hex.builtin.menu.file.clear_recent"_lang)) {
|
||||||
s_recentFilePaths.clear();
|
s_recentProviders.clear();
|
||||||
ContentRegistry::Settings::write(
|
|
||||||
"hex.builtin.setting.imhex",
|
// Remove all recent files
|
||||||
"hex.builtin.setting.imhex.recent_files",
|
for (const auto &recentPath : fs::getDefaultPaths(fs::ImHexPath::Recent))
|
||||||
std::vector<std::string> {});
|
for (const auto &entry : std::fs::directory_iterator(recentPath))
|
||||||
|
std::fs::remove(entry.path());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
@ -474,12 +518,6 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &pathString : ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files")) {
|
|
||||||
std::fs::path path = std::u8string(pathString.begin(), pathString.end());
|
|
||||||
if (fs::exists(path))
|
|
||||||
s_recentFilePaths.emplace_back(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImHexApi::System::getInitArguments().contains("tip-of-the-day")) {
|
if (ImHexApi::System::getInitArguments().contains("tip-of-the-day")) {
|
||||||
s_tipOfTheDay = ImHexApi::System::getInitArguments()["tip-of-the-day"];
|
s_tipOfTheDay = ImHexApi::System::getInitArguments()["tip-of-the-day"];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user