1
0
mirror of synced 2024-09-25 03:58:27 +02:00

sys: Added create file and resize option

Fixes #172
This commit is contained in:
WerWolv 2021-07-27 21:07:36 +02:00
parent 405b97e4d3
commit 2ccf8e777c
10 changed files with 259 additions and 110 deletions

View File

@ -24,9 +24,11 @@ namespace hex::prv {
bool isAvailable() override;
bool isReadable() override;
bool isWritable() override;
bool isResizable() override;
void read(u64 offset, void *buffer, size_t size, bool overlays) override;
void write(u64 offset, const void *buffer, size_t size) override;
void resize(ssize_t newSize) override;
void readRaw(u64 offset, void *buffer, size_t size) override;
void writeRaw(u64 offset, const void *buffer, size_t size) override;
@ -41,6 +43,7 @@ namespace hex::prv {
#else
int m_file;
#endif
std::string m_path;
void *m_mappedFile;
size_t m_fileSize;
@ -49,6 +52,9 @@ namespace hex::prv {
struct stat m_fileStats = { 0 };
bool m_readable, m_writable;
void open();
void close();
};
}

View File

@ -46,6 +46,7 @@ namespace hex {
s64 m_gotoAddress = 0;
char m_baseAddressBuffer[0x20] = { 0 };
u64 m_resizeSize = 0;
std::vector<u8> m_dataToSave;
@ -59,9 +60,10 @@ namespace hex {
void drawGotoPopup();
void drawEditPopup();
void openFile(std::string path);
bool saveToFile(std::string path, const std::vector<u8>& data);
bool loadFromFile(std::string path, std::vector<u8>& data);
bool createFile(std::string_view path);
void openFile(std::string_view path);
bool saveToFile(std::string_view path, const std::vector<u8>& data);
bool loadFromFile(std::string_view path, std::vector<u8>& data);
enum class Language { C, Cpp, CSharp, Rust, Python, Java, JavaScript };
void copyBytes();

View File

@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
{ "hex.welcome.header.main", "Wilkommen zu ImHex" },
{ "hex.welcome.header.start", "Start" },
{ "hex.welcome.start.create_file", "Neue Datei Erstellen" },
{ "hex.welcome.start.open_file", "Datei Öffnen" },
{ "hex.welcome.start.open_project", "Projekt Öffnen" },
{ "hex.welcome.start.recent", "Kürzlich geöffnet" },
@ -139,7 +140,8 @@ namespace hex::plugin::builtin {
{ "hex.view.help.calc_cheat_sheet", "Rechner Cheat Sheet" },
{ "hex.view.hexeditor.name", "Hex editor" },
{ "hex.view.hexeditor.open_file", "Datei öffnen" },
{ "hex.view.hexeditor.create_file", "Neu" },
{ "hex.view.hexeditor.open_file", "Öffnen" },
{ "hex.view.hexeditor.open_project", "Projekt öffnen" },
{ "hex.view.hexeditor.save_project", "Projekt speichern" },
{ "hex.view.hexeditor.save_data", "Daten speichern" },
@ -189,6 +191,7 @@ namespace hex::plugin::builtin {
{ "hex.view.hexeditor.goto.offset.end", "Ende" },
{ "hex.view.hexeditor.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
{ "hex.view.hexeditor.error.open", "Öffnen der Datei fehlgeschlagen!" },
{ "hex.view.hexeditor.error.create", "Erstellen der neuen Datei fehlgeschlagen!" },
{ "hex.view.hexeditor.menu.edit.undo", "Rückgängig" },
{ "hex.view.hexeditor.menu.edit.redo", "Wiederholen" },
{ "hex.view.hexeditor.menu.edit.copy", "Kopieren" },
@ -206,6 +209,7 @@ namespace hex::plugin::builtin {
{ "hex.view.hexeditor.menu.edit.paste", "Einfügen" },
{ "hex.view.hexeditor.menu.edit.bookmark", "Lesezeichen erstellen" },
{ "hex.view.hexeditor.menu.edit.set_base", "Basisadresse setzen" },
{ "hex.view.hexeditor.menu.edit.resize", "Grösse ändern" },
{ "hex.view.information.name", "Dateninformationen" },
{ "hex.view.information.control", "Einstellungen" },
@ -276,6 +280,8 @@ namespace hex::plugin::builtin {
{ "hex.view.yara.whole_data", "Gesammte Daten Übereinstimmung!" },
{ "hex.view.yara.no_rules", "Keine Yara Regeln gefunden. Platziere sie in ImHex' 'yara' Ordner" },
{ "hex.view.constants.name", "Konstanten" },
/* Builtin plugin features */
{ "hex.builtin.command.calc.desc", "Rechner" },

View File

@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
{ "hex.welcome.header.main", "Welcome to ImHex" },
{ "hex.welcome.header.start", "Start" },
{ "hex.welcome.start.create_file", "Create New File" },
{ "hex.welcome.start.open_file", "Open File" },
{ "hex.welcome.start.open_project", "Open Project" },
{ "hex.welcome.start.recent", "Recent Files" },
@ -139,7 +140,8 @@ namespace hex::plugin::builtin {
{ "hex.view.help.calc_cheat_sheet", "Calculator Cheat Sheet" },
{ "hex.view.hexeditor.name", "Hex editor" },
{ "hex.view.hexeditor.open_file", "Open File" },
{ "hex.view.hexeditor.create_file", "New" },
{ "hex.view.hexeditor.open_file", "Open" },
{ "hex.view.hexeditor.open_project", "Open Project" },
{ "hex.view.hexeditor.save_project", "Save Project" },
{ "hex.view.hexeditor.save_data", "Save Data" },
@ -189,6 +191,7 @@ namespace hex::plugin::builtin {
{ "hex.view.hexeditor.goto.offset.end", "End" },
{ "hex.view.hexeditor.error.read_only", "Couldn't get write access. File opened in read-only mode." },
{ "hex.view.hexeditor.error.open", "Failed to open file!" },
{ "hex.view.hexeditor.error.create", "Failed to create new file!" },
{ "hex.view.hexeditor.menu.edit.undo", "Undo" },
{ "hex.view.hexeditor.menu.edit.redo", "Redo" },
{ "hex.view.hexeditor.menu.edit.copy", "Copy" },
@ -206,6 +209,7 @@ namespace hex::plugin::builtin {
{ "hex.view.hexeditor.menu.edit.paste", "Paste" },
{ "hex.view.hexeditor.menu.edit.bookmark", "Create bookmark" },
{ "hex.view.hexeditor.menu.edit.set_base", "Set base address" },
{ "hex.view.hexeditor.menu.edit.resize", "Resize" },
{ "hex.view.information.name", "Data Information" },
{ "hex.view.information.control", "Control" },
@ -276,6 +280,8 @@ namespace hex::plugin::builtin {
{ "hex.view.yara.whole_data", "Whole file matches!" },
{ "hex.view.yara.no_rules", "No YARA rules found. Put them in ImHex' 'yara' folder" },
{ "hex.view.constants.name", "Constants" },
/* Builtin plugin features */
{ "hex.builtin.command.calc.desc", "Calculator" },

View File

@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
{ "hex.welcome.header.main", "Benvenuto in ImHex" },
{ "hex.welcome.header.start", "Inizia" },
// { "hex.welcome.start.create_file", "Create New File" },
{ "hex.welcome.start.open_file", "Apri un File" },
{ "hex.welcome.start.open_project", "Apri un Progetto" },
{ "hex.welcome.start.recent", "File recenti" },
@ -139,7 +140,8 @@ namespace hex::plugin::builtin {
{ "hex.view.help.calc_cheat_sheet", "Calcolatrice Cheat Sheet" },
{ "hex.view.hexeditor.name", "Hex editor" },
{ "hex.view.hexeditor.open_file", "Apri File" },
// { "hex.view.hexeditor.create_file", "New" },
{ "hex.view.hexeditor.open_file", "Apri" },
{ "hex.view.hexeditor.menu.file.open_recent", "File recenti" },
{ "hex.view.hexeditor.open_project", "Apri i Progetti" },
{ "hex.view.hexeditor.save_project", "Salva i Progetti" },
@ -189,6 +191,7 @@ namespace hex::plugin::builtin {
{ "hex.view.hexeditor.goto.offset.end", "Fine" },
{ "hex.view.hexeditor.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
{ "hex.view.hexeditor.error.open", "Impossibile aprire il File!" },
// { "hex.view.hexeditor.error.create", "Failed to create new file!" },
{ "hex.view.hexeditor.menu.edit.undo", "Annulla" },
{ "hex.view.hexeditor.menu.edit.redo", "Ripeti" },
{ "hex.view.hexeditor.menu.edit.copy", "Copia" },
@ -206,6 +209,7 @@ namespace hex::plugin::builtin {
{ "hex.view.hexeditor.menu.edit.paste", "Incolla" },
{ "hex.view.hexeditor.menu.edit.bookmark", "Crea segnalibro" },
{ "hex.view.hexeditor.menu.edit.set_base", "Imposta indirizzo di base" },
// { "hex.view.hexeditor.menu.edit.resize", "Resize" },
{ "hex.view.information.name", "Informazione sui Dati" },
{ "hex.view.information.control", "Controllo" },
@ -276,6 +280,8 @@ namespace hex::plugin::builtin {
{ "hex.view.yara.whole_data", "Tutti i file combaciano!" },
{ "hex.view.yara.no_rules", "Nessuna regola di YARA. Aggiungile in nella cartella 'yara' di 'ImHex'" },
// { "hex.view.constants.name", "Constants" },
/* Builtin plugin features */
{ "hex.builtin.command.calc.desc", "Calcolatrice" },

View File

@ -22,12 +22,15 @@ namespace hex::prv {
virtual bool isAvailable() = 0;
virtual bool isReadable() = 0;
virtual bool isWritable() = 0;
virtual bool isResizable() = 0;
virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true);
virtual void readRelative(u64 offset, void *buffer, size_t size, bool overlays = true);
virtual void write(u64 offset, const void *buffer, size_t size);
virtual void writeRelative(u64 offset, const void *buffer, size_t size);
virtual void resize(ssize_t newSize);
virtual void readRaw(u64 offset, void *buffer, size_t size) = 0;
virtual void writeRaw(u64 offset, const void *buffer, size_t size) = 0;
virtual size_t getActualSize() = 0;

View File

@ -34,6 +34,8 @@ namespace hex::prv {
this->write(offset + this->getBaseAddress(), buffer, size);
}
void Provider::resize(ssize_t newSize) { }
void Provider::applyOverlays(u64 offset, void *buffer, size_t size) {
for (auto &overlay : this->m_overlays) {
auto overlayOffset = overlay->getAddress();

View File

@ -13,7 +13,128 @@
namespace hex::prv {
FileProvider::FileProvider(std::string_view path) : Provider(), m_path(path) {
this->m_fileStatsValid = stat(path.data(), &this->m_fileStats) == 0;
this->open();
}
FileProvider::~FileProvider() {
this->close();
}
bool FileProvider::isAvailable() {
#if defined(OS_WINDOWS)
return this->m_file != nullptr && this->m_mapping != nullptr && this->m_mappedFile != nullptr;
#else
return this->m_file != -1 && this->m_mappedFile != nullptr;
#endif
}
bool FileProvider::isReadable() {
return isAvailable() && this->m_readable;
}
bool FileProvider::isWritable() {
return isAvailable() && this->m_writable;
}
bool FileProvider::isResizable() {
return true;
}
void FileProvider::read(u64 offset, void *buffer, size_t size, bool overlays) {
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
return;
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset - this->getBaseAddress(), size);
for (u64 i = 0; i < size; i++)
if (getPatches().contains(offset + i))
reinterpret_cast<u8*>(buffer)[i] = getPatches()[offset + PageSize * this->m_currPage + i];
if (overlays)
this->applyOverlays(offset, buffer, size);
}
void FileProvider::write(u64 offset, const void *buffer, size_t size) {
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
return;
addPatch(offset, buffer, size);
}
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
offset -= this->getBaseAddress();
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
return;
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, size);
}
void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
offset -= this->getBaseAddress();
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
return;
std::memcpy(reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, buffer, size);
}
void FileProvider::resize(ssize_t newSize) {
close();
#if defined(OS_WINDOWS)
std::wstring widePath;
{
auto length = static_cast<int>(this->m_path.length() + 1);
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, nullptr, 0);
auto buffer = new wchar_t[wideLength];
MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, buffer, wideLength);
widePath = buffer;
delete[] buffer;
}
auto handle = ::CreateFileW(widePath.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (handle != INVALID_HANDLE_VALUE) {
::SetFilePointerEx(handle, LARGE_INTEGER { .QuadPart = newSize }, nullptr, FILE_BEGIN);
::SetEndOfFile(handle);
::CloseHandle(handle);
}
#else
auto handle = ::open(path.data(), O_RDWR | O_CREAT);
truncate(handle, newSize - 1);
close(handle);
#endif
open();
}
size_t FileProvider::getActualSize() {
return this->m_fileSize;
}
std::vector<std::pair<std::string, std::string>> FileProvider::getDataInformation() {
std::vector<std::pair<std::string, std::string>> result;
result.emplace_back("hex.builtin.provider.file.path"_lang, this->m_path);
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
if (this->m_fileStatsValid) {
result.emplace_back("hex.builtin.provider.file.creation"_lang, ctime(&this->m_fileStats.st_ctime));
result.emplace_back("hex.builtin.provider.file.access"_lang, ctime(&this->m_fileStats.st_atime));
result.emplace_back("hex.builtin.provider.file.modification"_lang, ctime(&this->m_fileStats.st_mtime));
}
return result;
}
void FileProvider::open() {
this->m_fileStatsValid = stat(this->m_path.data(), &this->m_fileStats) == 0;
this->m_readable = true;
this->m_writable = true;
@ -21,10 +142,10 @@ namespace hex::prv {
#if defined(OS_WINDOWS)
std::wstring widePath;
{
auto length = path.length() + 1;
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, path.data(), length, 0, 0);
auto length = this->m_path.length() + 1;
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, 0, 0);
wchar_t* buffer = new wchar_t[wideLength];
MultiByteToWideChar(CP_UTF8, 0, path.data(), length, buffer, wideLength);
MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, buffer, wideLength);
widePath = buffer;
delete[] buffer;
}
@ -72,12 +193,12 @@ namespace hex::prv {
fileCleanup.release();
mappingCleanup.release();
ProjectFile::setFilePath(path);
ProjectFile::setFilePath(this->m_path);
#else
this->m_file = open(path.data(), O_RDWR);
this->m_file = ::open(path.data(), O_RDWR);
if (this->m_file == -1) {
this->m_file = open(path.data(), O_RDONLY);
this->m_file = ::open(path.data(), O_RDONLY);
this->m_writable = false;
}
@ -90,97 +211,21 @@ namespace hex::prv {
this->m_mappedFile = mmap(nullptr, this->m_fileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, this->m_file, 0);
#endif
#endif
}
FileProvider::~FileProvider() {
#if defined(OS_WINDOWS)
void FileProvider::close() {
#if defined(OS_WINDOWS)
if (this->m_mappedFile != nullptr)
UnmapViewOfFile(this->m_mappedFile);
::UnmapViewOfFile(this->m_mappedFile);
if (this->m_mapping != nullptr)
CloseHandle(this->m_mapping);
::CloseHandle(this->m_mapping);
if (this->m_file != nullptr)
CloseHandle(this->m_file);
#else
munmap(this->m_mappedFile, this->m_fileSize);
close(this->m_file);
#endif
}
bool FileProvider::isAvailable() {
#if defined(OS_WINDOWS)
return this->m_file != nullptr && this->m_mapping != nullptr && this->m_mappedFile != nullptr;
#else
return this->m_file != -1 && this->m_mappedFile != nullptr;
#endif
}
bool FileProvider::isReadable() {
return isAvailable() && this->m_readable;
}
bool FileProvider::isWritable() {
return isAvailable() && this->m_writable;
}
void FileProvider::read(u64 offset, void *buffer, size_t size, bool overlays) {
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
return;
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset - this->getBaseAddress(), size);
for (u64 i = 0; i < size; i++)
if (getPatches().contains(offset + i))
reinterpret_cast<u8*>(buffer)[i] = getPatches()[offset + PageSize * this->m_currPage + i];
if (overlays)
this->applyOverlays(offset, buffer, size);
}
void FileProvider::write(u64 offset, const void *buffer, size_t size) {
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
return;
addPatch(offset, buffer, size);
}
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
offset -= this->getBaseAddress();
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
return;
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, size);
}
void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
offset -= this->getBaseAddress();
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
return;
std::memcpy(reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, buffer, size);
}
size_t FileProvider::getActualSize() {
return this->m_fileSize;
}
std::vector<std::pair<std::string, std::string>> FileProvider::getDataInformation() {
std::vector<std::pair<std::string, std::string>> result;
result.emplace_back("hex.builtin.provider.file.path"_lang, this->m_path);
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
if (this->m_fileStatsValid) {
result.emplace_back("hex.builtin.provider.file.creation"_lang, ctime(&this->m_fileStats.st_ctime));
result.emplace_back("hex.builtin.provider.file.access"_lang, ctime(&this->m_fileStats.st_atime));
result.emplace_back("hex.builtin.provider.file.modification"_lang, ctime(&this->m_fileStats.st_mtime));
}
return result;
::CloseHandle(this->m_file);
#else
::munmap(this->m_mappedFile, this->m_fileSize);
::close(this->m_file);
#endif
}
}

View File

@ -16,6 +16,13 @@
#include <filesystem>
#if defined(OS_WINDOWS)
#include <windows.h>
#else
#include <fcntl.h>
#include <unistd.h>
#endif
namespace hex {
ViewHexEditor::ViewHexEditor() : View("hex.view.hexeditor.name"_lang) {
@ -168,7 +175,16 @@ namespace hex {
});
EventManager::subscribe<RequestOpenWindow>(this, [this](std::string name) {
if (name == "Open File") {
if (name == "Create File") {
View::openFileBrowser("hex.view.hexeditor.create_file"_lang, DialogMode::Save, { }, [this](auto path) {
if (!this->createFile(path)) {
View::showErrorPopup("hex.view.hexeditor.error.create"_lang);
return;
}
this->openFile(path);
this->getWindowOpenState() = true;
});
} else if (name == "Open File") {
View::openFileBrowser("hex.view.hexeditor.open_file"_lang, DialogMode::Open, { }, [this](auto path) {
this->openFile(path);
this->getWindowOpenState() = true;
@ -361,6 +377,24 @@ namespace hex {
ImGui::EndPopup();
}
if (ImGui::BeginPopupModal("hex.view.hexeditor.menu.edit.resize"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::InputScalar("hex.common.size"_lang, ImGuiDataType_U64, &this->m_resizeSize, nullptr, nullptr, "0x%016llx", ImGuiInputTextFlags_CharsHexadecimal);
ImGui::NewLine();
confirmButtons("hex.common.set"_lang, "hex.common.cancel"_lang,
[this, &provider]{
provider->resize(this->m_resizeSize);
ImGui::CloseCurrentPopup();
}, []{
ImGui::CloseCurrentPopup();
});
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
}
void ViewHexEditor::drawMenu() {
@ -583,17 +617,47 @@ namespace hex {
}
}
return false;
}
bool ViewHexEditor::createFile(std::string_view path) {
#if defined(OS_WINDOWS)
std::wstring widePath;
{
auto length = path.length() + 1;
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, path.data(), length, 0, 0);
auto buffer = new wchar_t[wideLength];
MultiByteToWideChar(CP_UTF8, 0, path.data(), length, buffer, wideLength);
widePath = buffer;
delete[] buffer;
}
void ViewHexEditor::openFile(std::string path) {
auto handle = ::CreateFileW(widePath.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return false;
::SetFilePointer(handle, 1, nullptr, FILE_BEGIN);
::SetEndOfFile(handle);
::CloseHandle(handle);
#else
auto handle = ::open(path.data(), O_RDWR | O_CREAT);
if (handle == -1)
return false;
lseek(handle, 0, SEEK_SET);
write(handle, "", 1);
close(handle);
#endif
return true;
}
void ViewHexEditor::openFile(std::string_view path) {
auto& provider = SharedData::currentProvider;
if (provider != nullptr)
delete provider;
delete provider;
provider = new prv::FileProvider(path);
if (!provider->isWritable()) {
@ -615,13 +679,13 @@ namespace hex {
this->getWindowOpenState() = true;
EventManager::post<EventFileLoaded>(path);
EventManager::post<EventFileLoaded>(std::string(path));
EventManager::post<EventDataChanged>();
EventManager::post<EventPatternChanged>();
}
bool ViewHexEditor::saveToFile(std::string path, const std::vector<u8>& data) {
FILE *file = fopen(path.c_str(), "wb");
bool ViewHexEditor::saveToFile(std::string_view path, const std::vector<u8>& data) {
FILE *file = fopen(path.data(), "wb");
if (file == nullptr)
return false;
@ -632,8 +696,8 @@ namespace hex {
return true;
}
bool ViewHexEditor::loadFromFile(std::string path, std::vector<u8>& data) {
FILE *file = fopen(path.c_str(), "rb");
bool ViewHexEditor::loadFromFile(std::string_view path, std::vector<u8>& data) {
FILE *file = fopen(path.data(), "rb");
if (file == nullptr)
return false;
@ -1228,6 +1292,13 @@ R"(
std::memset(this->m_baseAddressBuffer, 0x00, sizeof(this->m_baseAddressBuffer));
View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.edit.set_base"_lang); });
}
if (ImGui::MenuItem("hex.view.hexeditor.menu.edit.resize"_lang, nullptr, false, provider != nullptr && provider->isResizable())) {
View::doLater([this, &provider]{
this->m_resizeSize = provider->getActualSize();
ImGui::OpenPopup("hex.view.hexeditor.menu.edit.resize"_lang);
});
}
}
}

View File

@ -424,6 +424,8 @@ namespace hex {
ImGui::TableNextColumn();
ImGui::TextUnformatted("hex.welcome.header.start"_lang);
{
if (ImGui::BulletHyperlink("hex.welcome.start.create_file"_lang))
EventManager::post<RequestOpenWindow>("Create File");
if (ImGui::BulletHyperlink("hex.welcome.start.open_file"_lang))
EventManager::post<RequestOpenWindow>("Open File");
if (ImGui::BulletHyperlink("hex.welcome.start.open_project"_lang))