diff --git a/Userland/Applications/HexEditor/HexEditor.cpp b/Userland/Applications/HexEditor/HexEditor.cpp index 2ec79ef0c5..471a78d025 100644 --- a/Userland/Applications/HexEditor/HexEditor.cpp +++ b/Userland/Applications/HexEditor/HexEditor.cpp @@ -34,6 +34,15 @@ namespace HexEditor { +HexEditor::OffsetFormat HexEditor::offset_format_from_string(StringView string) +{ + if (string.equals_ignoring_ascii_case("decimal"sv)) { + return OffsetFormat::Decimal; + } + // Default to hex if invalid + return OffsetFormat::Hexadecimal; +} + HexEditor::HexEditor() : m_document(make(ByteBuffer::create_zeroed(0).release_value_but_fixme_should_propagate_errors())) { @@ -249,6 +258,15 @@ void HexEditor::set_show_offsets_column(bool value) update_content_size(); } +void HexEditor::set_offset_format(OffsetFormat format) +{ + if (format == m_offset_format) + return; + + m_offset_format = format; + update_content_size(); +} + void HexEditor::set_bytes_per_row(size_t bytes_per_row) { if (bytes_per_row == this->bytes_per_row()) @@ -471,6 +489,8 @@ int HexEditor::offset_area_width() const { if (!m_show_offsets_column) return 0; + // By a fun coincidence, decimal and hexadecimal are both 10 characters for the 32-bit range. + // (decimal is up to 10 digits; hex is 8 digits with a 2-character prefix) return m_padding + font().width_rounded_up("0X12345678"sv) + m_padding; } @@ -721,7 +741,15 @@ void HexEditor::paint_event(GUI::PaintEvent& event) }; bool is_current_line = (m_position / bytes_per_row()) == row; - auto offset_text = String::formatted("{:#08X}", row * bytes_per_row()).release_value_but_fixme_should_propagate_errors(); + String offset_text; + switch (m_offset_format) { + case OffsetFormat::Decimal: + offset_text = MUST(String::formatted("{:010d}", row * bytes_per_row())); + break; + case OffsetFormat::Hexadecimal: + offset_text = MUST(String::formatted("{:#08X}", row * bytes_per_row())); + break; + } painter.draw_text( side_offset_rect, offset_text, diff --git a/Userland/Applications/HexEditor/HexEditor.h b/Userland/Applications/HexEditor/HexEditor.h index 88358d51a6..a145e5f35f 100644 --- a/Userland/Applications/HexEditor/HexEditor.h +++ b/Userland/Applications/HexEditor/HexEditor.h @@ -32,6 +32,12 @@ public: Text }; + enum class OffsetFormat { + Decimal, + Hexadecimal, + }; + static OffsetFormat offset_format_from_string(StringView); + virtual ~HexEditor() override = default; size_t buffer_size() const { return m_document->size(); } @@ -56,6 +62,7 @@ public: bool copy_selected_hex_to_clipboard_as_c_code(); void set_show_offsets_column(bool); + void set_offset_format(OffsetFormat); size_t bytes_per_group() const { return m_bytes_per_group; } void set_bytes_per_group(size_t); @@ -98,6 +105,7 @@ private: size_t m_bytes_per_group { 4 }; size_t m_groups_per_row { 4 }; bool m_show_offsets_column { true }; + OffsetFormat m_offset_format { OffsetFormat::Hexadecimal }; bool m_in_drag_select { false }; Selection m_selection; size_t m_position { 0 }; diff --git a/Userland/Applications/HexEditor/HexEditorWidget.cpp b/Userland/Applications/HexEditor/HexEditorWidget.cpp index 064db1334a..00cb644ea8 100644 --- a/Userland/Applications/HexEditor/HexEditorWidget.cpp +++ b/Userland/Applications/HexEditor/HexEditorWidget.cpp @@ -634,6 +634,31 @@ ErrorOr HexEditorWidget::initialize_menubar(GUI::Window& window) m_show_offsets_column_action->set_checked(show_offsets_column); m_editor->set_show_offsets_column(show_offsets_column); view_menu->add_action(*m_show_offsets_column_action); + + auto offset_format = HexEditor::offset_format_from_string(Config::read_string("HexEditor"sv, "Layout"sv, "OffsetFormat"sv)); + m_editor->set_offset_format(offset_format); + m_offset_format_actions.set_exclusive(true); + auto offset_format_menu = view_menu->add_submenu("Offset Format"_string); + auto offset_format_decimal_action = GUI::Action::create_checkable("&Decimal", [this](auto&) { + m_editor->set_offset_format(HexEditor::OffsetFormat::Decimal); + Config::write_string("HexEditor"sv, "Layout"sv, "OffsetFormat"sv, "decimal"sv); + }); + auto offset_format_hexadecimal_action = GUI::Action::create_checkable("&Hexadecimal", [this](auto&) { + m_editor->set_offset_format(HexEditor::OffsetFormat::Hexadecimal); + Config::write_string("HexEditor"sv, "Layout"sv, "OffsetFormat"sv, "hexadecimal"sv); + }); + switch (offset_format) { + case HexEditor::OffsetFormat::Decimal: + offset_format_decimal_action->set_checked(true); + break; + case HexEditor::OffsetFormat::Hexadecimal: + offset_format_hexadecimal_action->set_checked(true); + break; + } + m_offset_format_actions.add_action(offset_format_decimal_action); + m_offset_format_actions.add_action(offset_format_hexadecimal_action); + offset_format_menu->add_action(offset_format_decimal_action); + offset_format_menu->add_action(offset_format_hexadecimal_action); view_menu->add_separator(); auto bytes_per_row = Config::read_i32("HexEditor"sv, "Layout"sv, "BytesPerRow"sv, 16); diff --git a/Userland/Applications/HexEditor/HexEditorWidget.h b/Userland/Applications/HexEditor/HexEditorWidget.h index aeb5bfbeb4..7c6fb7df4e 100644 --- a/Userland/Applications/HexEditor/HexEditorWidget.h +++ b/Userland/Applications/HexEditor/HexEditorWidget.h @@ -88,6 +88,7 @@ private: RefPtr m_fill_selection_action; RefPtr m_show_offsets_column_action; + GUI::ActionGroup m_offset_format_actions; GUI::ActionGroup m_bytes_per_row_actions; GUI::ActionGroup m_value_inspector_mode_actions;