mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-03 05:57:40 -05:00
impr: Split up optional provider features into multiple abstract interfaces
This commit is contained in:
@@ -9,7 +9,9 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class DiskProvider : public hex::prv::Provider {
|
||||
class DiskProvider : public prv::Provider,
|
||||
public prv::IProviderDataDescription,
|
||||
public prv::IProviderLoadInterface {
|
||||
public:
|
||||
DiskProvider() = default;
|
||||
~DiskProvider() override = default;
|
||||
@@ -32,7 +34,6 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override;
|
||||
|
||||
[[nodiscard]] bool hasLoadInterface() const override { return true; }
|
||||
bool drawLoadInterface() override;
|
||||
|
||||
void loadSettings(const nlohmann::json &settings) override;
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class FileProvider : public hex::prv::Provider {
|
||||
class FileProvider : public prv::Provider,
|
||||
public prv::IProviderDataDescription,
|
||||
public prv::IProviderFilePicker,
|
||||
public prv::IProviderMenuItems {
|
||||
public:
|
||||
FileProvider() = default;
|
||||
~FileProvider() override = default;
|
||||
@@ -31,12 +34,10 @@ namespace hex::plugin::builtin {
|
||||
void saveAs(const std::fs::path &path) override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override;
|
||||
std::variant<std::string, i128> queryInformation(const std::string &category, const std::string &argument) override;
|
||||
|
||||
[[nodiscard]] bool hasFilePicker() const override { return true; }
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override;
|
||||
[[nodiscard]] bool handleFilePicker() override;
|
||||
|
||||
std::vector<MenuEntry> getMenuEntries() override;
|
||||
|
||||
void setPath(const std::fs::path &path);
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class GDBProvider : public hex::prv::CachedProvider {
|
||||
class GDBProvider : public prv::CachedProvider,
|
||||
public prv::IProviderDataDescription,
|
||||
public prv::IProviderLoadInterface {
|
||||
public:
|
||||
GDBProvider();
|
||||
~GDBProvider() override = default;
|
||||
@@ -37,7 +39,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
[[nodiscard]] bool isConnected() const;
|
||||
|
||||
[[nodiscard]] bool hasLoadInterface() const override { return true; }
|
||||
bool drawLoadInterface() override;
|
||||
|
||||
void loadSettings(const nlohmann::json &settings) override;
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class IntelHexProvider : public hex::prv::Provider {
|
||||
class IntelHexProvider : public hex::prv::Provider,
|
||||
public hex::prv::IProviderDataDescription,
|
||||
public hex::prv::IProviderFilePicker {
|
||||
public:
|
||||
IntelHexProvider() = default;
|
||||
~IntelHexProvider() override = default;
|
||||
@@ -36,7 +38,6 @@ namespace hex::plugin::builtin {
|
||||
return "hex.builtin.provider.intel_hex";
|
||||
}
|
||||
|
||||
[[nodiscard]] bool hasFilePicker() const override { return true; }
|
||||
[[nodiscard]] bool handleFilePicker() override;
|
||||
|
||||
std::pair<Region, bool> getRegionValidity(u64 address) const override;
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class MemoryFileProvider : public hex::prv::Provider {
|
||||
class MemoryFileProvider : public hex::prv::Provider,
|
||||
public prv::IProviderMenuItems {
|
||||
public:
|
||||
explicit MemoryFileProvider() = default;
|
||||
~MemoryFileProvider() override = default;
|
||||
@@ -28,7 +29,6 @@ namespace hex::plugin::builtin {
|
||||
void save() override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override;
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override { return { }; }
|
||||
|
||||
std::vector<MenuEntry> getMenuEntries() override;
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] u64 getActualSize() const override { return 0x00; }
|
||||
|
||||
[[nodiscard]] std::string getName() const override { return "ImHex"; }
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override { return { }; }
|
||||
|
||||
void loadSettings(const nlohmann::json &settings) override { std::ignore = settings; }
|
||||
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override { return settings; }
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ProcessMemoryProvider : public hex::prv::Provider {
|
||||
class ProcessMemoryProvider : public prv::Provider,
|
||||
public prv::IProviderDataDescription,
|
||||
public prv::IProviderLoadInterface,
|
||||
public prv::IProviderSidebarInterface {
|
||||
public:
|
||||
ProcessMemoryProvider() = default;
|
||||
~ProcessMemoryProvider() override = default;
|
||||
@@ -58,10 +61,8 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] bool open() override;
|
||||
void close() override;
|
||||
|
||||
[[nodiscard]] bool hasLoadInterface() const override { return true; }
|
||||
[[nodiscard]] bool hasInterface() const override { return true; }
|
||||
bool drawLoadInterface() override;
|
||||
void drawInterface() override;
|
||||
void drawSidebarInterface() override;
|
||||
|
||||
void loadSettings(const nlohmann::json &) override {}
|
||||
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json) const override { return { }; }
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class UDPProvider : public hex::prv::Provider {
|
||||
class UDPProvider : public hex::prv::Provider,
|
||||
public hex::prv::IProviderSidebarInterface,
|
||||
public hex::prv::IProviderLoadInterface {
|
||||
public:
|
||||
UDPProvider() = default;
|
||||
~UDPProvider() override = default;
|
||||
@@ -24,11 +26,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
[[nodiscard]] u64 getActualSize() const override;
|
||||
|
||||
|
||||
[[nodiscard]] bool hasLoadInterface() const override { return true; }
|
||||
[[nodiscard]] bool drawLoadInterface() override;
|
||||
bool hasInterface() const override { return true; }
|
||||
void drawInterface() override;
|
||||
void drawSidebarInterface() override;
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
void close() override;
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ViewProvider : public hex::prv::Provider {
|
||||
class ViewProvider : public prv::Provider,
|
||||
public prv::IProviderDataDescription,
|
||||
public prv::IProviderMenuItems {
|
||||
public:
|
||||
ViewProvider() = default;
|
||||
~ViewProvider() override = default;
|
||||
@@ -48,7 +50,7 @@ namespace hex::plugin::builtin {
|
||||
void setBaseAddress(u64 address) override { std::ignore = address; }
|
||||
|
||||
|
||||
void setProvider(u64 startAddress, size_t size, hex::prv::Provider *provider);
|
||||
void setProvider(u64 startAddress, size_t size, Provider *provider);
|
||||
void setName(const std::string &name);
|
||||
|
||||
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
|
||||
|
||||
@@ -40,13 +40,15 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
for (auto &[name, value] : m_provider->getDataDescription()) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(name.c_str());
|
||||
ImGuiExt::TextFormattedWrappedSelectable("{}", value);
|
||||
ImGui::PopID();
|
||||
if (auto *dataDescriptionProvider = dynamic_cast<prv::IProviderDataDescription*>(m_provider); dataDescriptionProvider != nullptr) {
|
||||
for (auto &[name, value] : dataDescriptionProvider->getDataDescription()) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(name.c_str());
|
||||
ImGuiExt::TextFormattedWrappedSelectable("{}", value);
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
@@ -198,8 +198,8 @@ namespace hex::plugin::builtin {
|
||||
if (provider->shouldSkipLoadInterface())
|
||||
return;
|
||||
|
||||
if (provider->hasFilePicker()) {
|
||||
if (!provider->handleFilePicker()) {
|
||||
if (auto *filePickerProvider = dynamic_cast<prv::IProviderFilePicker*>(provider); filePickerProvider != nullptr) {
|
||||
if (!filePickerProvider->handleFilePicker()) {
|
||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
return;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (!provider->hasLoadInterface()) {
|
||||
else if (dynamic_cast<prv::IProviderLoadInterface*>(provider) == nullptr) {
|
||||
TaskManager::createBlockingTask("hex.builtin.provider.opening", TaskManager::NoProgress, [provider]() {
|
||||
if (!provider->open() || !provider->isAvailable()) {
|
||||
ui::ToastError::open(hex::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
std::vector<FileProvider::MenuEntry> FileProvider::getMenuEntries() {
|
||||
FileProvider::MenuEntry loadMenuItem;
|
||||
MenuEntry loadMenuItem;
|
||||
|
||||
if (m_loadedIntoMemory)
|
||||
loadMenuItem = { "hex.builtin.provider.file.menu.direct_access"_lang, ICON_VS_ARROW_SWAP, [this] { this->convertToDirectAccess(); } };
|
||||
|
||||
@@ -282,7 +282,7 @@ namespace hex::plugin::builtin {
|
||||
return m_selectedProcess != nullptr;
|
||||
}
|
||||
|
||||
void ProcessMemoryProvider::drawInterface() {
|
||||
void ProcessMemoryProvider::drawSidebarInterface() {
|
||||
ImGuiExt::Header("hex.builtin.provider.process_memory.memory_regions"_lang, true);
|
||||
|
||||
auto availableX = ImGui::GetContentRegionAvail().x;
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace hex::plugin::builtin {
|
||||
/* Not supported */
|
||||
}
|
||||
|
||||
void UDPProvider::drawInterface() {
|
||||
void UDPProvider::drawSidebarInterface() {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
if (ImGui::BeginTable("##Messages", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImGui::GetContentRegionAvail())) {
|
||||
|
||||
@@ -124,11 +124,16 @@ namespace hex::plugin::builtin {
|
||||
else
|
||||
return hex::format("{} View", m_provider->getName());
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<ViewProvider::Description> ViewProvider::getDataDescription() const {
|
||||
if (m_provider == nullptr)
|
||||
return { };
|
||||
|
||||
return m_provider->getDataDescription();
|
||||
if (auto *dataDescriptionProvider = dynamic_cast<const IProviderDataDescription*>(m_provider); dataDescriptionProvider != nullptr) {
|
||||
return dataDescriptionProvider->getDataDescription();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ViewProvider::loadSettings(const nlohmann::json &settings) {
|
||||
@@ -181,7 +186,7 @@ namespace hex::plugin::builtin {
|
||||
return { Region::Invalid(), false };
|
||||
}
|
||||
|
||||
std::vector<prv::Provider::MenuEntry> ViewProvider::getMenuEntries() {
|
||||
std::vector<prv::IProviderMenuItems::MenuEntry> ViewProvider::getMenuEntries() {
|
||||
return {
|
||||
MenuEntry { Lang("hex.builtin.provider.rename"), ICON_VS_TAG, [this] { this->renameFile(); } }
|
||||
};
|
||||
|
||||
@@ -15,12 +15,18 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Reports::addReportProvider([](const prv::Provider *provider) -> std::string {
|
||||
std::string result;
|
||||
|
||||
result += "## Data description\n\n";
|
||||
result += "| Type | Value |\n";
|
||||
result += "| ---- | ----- |\n";
|
||||
if (auto *dataDescriptionProvider = dynamic_cast<const prv::IProviderDataDescription*>(provider); dataDescriptionProvider != nullptr) {
|
||||
auto descriptions = dataDescriptionProvider->getDataDescription();
|
||||
if (!descriptions.empty()) {
|
||||
result += "## Data description\n\n";
|
||||
result += "| Type | Value |\n";
|
||||
result += "| ---- | ----- |\n";
|
||||
|
||||
for (const auto &[type, value] : dataDescriptionProvider->getDataDescription())
|
||||
result += hex::format("| {} | {} |\n", type, value);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &[type, value] : provider->getDataDescription())
|
||||
result += hex::format("| {} | {} |\n", type, value);
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -353,9 +353,11 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
static void drawProviderContextMenu(prv::Provider *provider) {
|
||||
for (const auto &menuEntry : provider->getMenuEntries()) {
|
||||
if (ImGui::MenuItemEx(menuEntry.name.c_str(), menuEntry.icon)) {
|
||||
menuEntry.callback();
|
||||
if (auto *menuItemProvider = dynamic_cast<prv::IProviderMenuItems*>(provider); menuItemProvider != nullptr) {
|
||||
for (const auto &menuEntry : menuItemProvider->getMenuEntries()) {
|
||||
if (ImGui::MenuItemEx(menuEntry.name.c_str(), menuEntry.icon)) {
|
||||
menuEntry.callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,28 +368,30 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGuiExt::TextFormatted("{}", provider->getName().c_str());
|
||||
|
||||
const auto &description = provider->getDataDescription();
|
||||
if (!description.empty()) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::GetIO().KeyShift && !description.empty()) {
|
||||
if (auto *dataDescriptionProvider = dynamic_cast<const prv::IProviderDataDescription*>(provider); dataDescriptionProvider != nullptr) {
|
||||
const auto &description = dataDescriptionProvider->getDataDescription();
|
||||
if (!description.empty()) {
|
||||
ImGui::Separator();
|
||||
if (ImGui::GetIO().KeyShift && !description.empty()) {
|
||||
|
||||
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoKeepColumnsVisible, ImVec2(400_scaled, 0))) {
|
||||
ImGui::TableSetupColumn("type");
|
||||
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
|
||||
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoKeepColumnsVisible, ImVec2(400_scaled, 0))) {
|
||||
ImGui::TableSetupColumn("type");
|
||||
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextRow();
|
||||
|
||||
for (auto &[name, value] : description) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedWrapped("{}", value);
|
||||
for (auto &[name, value] : description) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedWrapped("{}", value);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
} else {
|
||||
ImGuiExt::TextFormattedDisabled("hex.builtin.provider.tooltip.show_more"_lang);
|
||||
}
|
||||
} else {
|
||||
ImGuiExt::TextFormattedDisabled("hex.builtin.provider.tooltip.show_more"_lang);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,10 +427,14 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
|
||||
EventFrameBegin::subscribe([] {
|
||||
if (rightClickedProvider != nullptr && !rightClickedProvider->getMenuEntries().empty()) {
|
||||
if (ImGui::BeginPopup("ProviderMenu")) {
|
||||
drawProviderContextMenu(rightClickedProvider);
|
||||
ImGui::EndPopup();
|
||||
if (rightClickedProvider != nullptr) {
|
||||
if (auto *menuItemProvider = dynamic_cast<prv::IProviderMenuItems*>(rightClickedProvider); menuItemProvider != nullptr) {
|
||||
if (!menuItemProvider->getMenuEntries().empty()) {
|
||||
if (ImGui::BeginPopup("ProviderMenu")) {
|
||||
drawProviderContextMenu(rightClickedProvider);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1453,7 +1453,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
bool foundCorrectType = false;
|
||||
|
||||
auto mimeType = magic::getMIMEType(provider, 0, 100_KiB, true);
|
||||
auto mimeType = magic::getMIMEType(provider, 0, 4_KiB, true);
|
||||
runtime.addPragma("MIME", [&mimeType, &foundCorrectType](const pl::PatternLanguage &runtime, const std::string &value) {
|
||||
std::ignore = runtime;
|
||||
|
||||
|
||||
@@ -10,20 +10,20 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ViewProviderSettings::ViewProviderSettings() : View::Modal("hex.builtin.view.provider_settings.name") {
|
||||
EventProviderCreated::subscribe(this, [this](const hex::prv::Provider *provider) {
|
||||
if (provider->hasLoadInterface() && !provider->shouldSkipLoadInterface())
|
||||
if (dynamic_cast<const prv::IProviderLoadInterface*>(provider) != nullptr && !provider->shouldSkipLoadInterface())
|
||||
this->getWindowOpenState() = true;
|
||||
});
|
||||
|
||||
ContentRegistry::Interface::addSidebarItem(ICON_VS_SERVER_PROCESS, [] {
|
||||
auto provider = hex::ImHexApi::Provider::get();
|
||||
|
||||
if (provider != nullptr)
|
||||
provider->drawInterface();
|
||||
if (auto *sidebarInterfaceProvider = dynamic_cast<prv::IProviderSidebarInterface*>(provider); sidebarInterfaceProvider != nullptr)
|
||||
sidebarInterfaceProvider->drawSidebarInterface();
|
||||
},
|
||||
[] {
|
||||
auto provider = hex::ImHexApi::Provider::get();
|
||||
|
||||
return provider != nullptr && provider->hasInterface() && provider->isAvailable();
|
||||
return provider != nullptr && dynamic_cast<prv::IProviderSidebarInterface*>(provider) != nullptr && provider->isAvailable();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void ViewProviderSettings::drawContent() {
|
||||
auto provider = hex::ImHexApi::Provider::get();
|
||||
if (provider != nullptr) {
|
||||
bool settingsValid = provider->drawLoadInterface();
|
||||
if (auto *loadInterfaceProvider = dynamic_cast<prv::IProviderLoadInterface*>(provider); loadInterfaceProvider != nullptr) {
|
||||
bool settingsValid = loadInterfaceProvider->drawLoadInterface();
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
|
||||
Reference in New Issue
Block a user