1
0
mirror of synced 2024-12-14 00:32:52 +01:00
ImHex/plugins/builtin/include/content/providers/file_provider.hpp
SparkyTD adbcc48de7
fix: Multiple file reload popups stacking on top of each other (#1654)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
This PR aims to address #1645 that caused the built in file provider's
change monitor to trigger the notification popup dialog multiple times
in a row after multiple external file changes.

### Implementation description
I added an additional boolean field
`m_changeEventAcknowledgementPending` that tracks whether there are any
pending or unacknowledged change notification dialogs to prevent further
dialogs from being opened. The flag is only reset to its initial value
once the user has acknowledged the first `PopupQuestion` dialog.

Since the file is reloaded only after the user clicks 'Yes', it is
unnecessary to ensure that only the latest popup is acknowledged.
2024-05-07 23:43:20 +02:00

80 lines
2.5 KiB
C++

#pragma once
#include <hex/providers/provider.hpp>
#include <wolv/io/file.hpp>
#include <set>
#include <string_view>
namespace hex::plugin::builtin {
class FileProvider : public hex::prv::Provider {
public:
constexpr static u64 MaxMemoryFileSize = 128 * 1024 * 1024;
FileProvider() = default;
~FileProvider() override = default;
[[nodiscard]] bool isAvailable() const override;
[[nodiscard]] bool isReadable() const override;
[[nodiscard]] bool isWritable() const override;
[[nodiscard]] bool isResizable() const override;
[[nodiscard]] bool isSavable() const override;
void resizeRaw(u64 newSize) override;
void readRaw(u64 offset, void *buffer, size_t size) override;
void writeRaw(u64 offset, const void *buffer, size_t size) override;
[[nodiscard]] u64 getActualSize() const override;
void save() override;
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]] bool handleFilePicker() override;
std::vector<MenuEntry> getMenuEntries() override;
void setPath(const std::fs::path &path);
[[nodiscard]] bool open() override;
void close() override;
void loadSettings(const nlohmann::json &settings) override;
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override;
[[nodiscard]] std::string getTypeName() const override {
return "hex.builtin.provider.file";
}
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override;
private:
void convertToMemoryFile();
void handleFileChange();
protected:
std::fs::path m_path;
wolv::io::File m_file;
size_t m_fileSize = 0;
wolv::io::ChangeTracker m_changeTracker;
std::vector<u8> m_data;
bool m_loadedIntoMemory = false;
bool m_ignoreNextChangeEvent = false;
bool m_changeEventAcknowledgementPending = false;
std::optional<struct stat> m_fileStats;
bool m_readable = false, m_writable = false;
static std::set<FileProvider*> s_openedFiles;
};
}