mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 01:07:36 +00:00
HexEditor: Implement undo and redo actions
This commit is contained in:
parent
24f729d0ef
commit
8b0a464f5c
6 changed files with 204 additions and 7 deletions
|
@ -82,8 +82,22 @@ void HexEditor::fill_selection(u8 fill_byte)
|
|||
if (!has_selection())
|
||||
return;
|
||||
|
||||
for (size_t i = m_selection_start; i < m_selection_end; i++)
|
||||
m_document->set(i, fill_byte);
|
||||
ByteBuffer old_values;
|
||||
ByteBuffer new_values;
|
||||
|
||||
size_t length = m_selection_end - m_selection_start;
|
||||
|
||||
new_values.resize(length);
|
||||
old_values.resize(length);
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
size_t position = m_selection_start + i;
|
||||
old_values[i] = m_document->get(position).value;
|
||||
new_values[i] = fill_byte;
|
||||
m_document->set(position, fill_byte);
|
||||
}
|
||||
|
||||
did_complete_action(m_selection_start, move(old_values), move(new_values));
|
||||
|
||||
update();
|
||||
did_change();
|
||||
|
@ -465,6 +479,8 @@ void HexEditor::hex_mode_keydown_event(GUI::KeyEvent& event)
|
|||
|
||||
VERIFY(m_position <= m_document->size());
|
||||
|
||||
auto old_value = m_document->get(m_position).value;
|
||||
|
||||
// yes, this is terrible... but it works.
|
||||
auto value = (event.key() >= KeyCode::Key_0 && event.key() <= KeyCode::Key_9)
|
||||
? event.key() - KeyCode::Key_0
|
||||
|
@ -472,11 +488,14 @@ void HexEditor::hex_mode_keydown_event(GUI::KeyEvent& event)
|
|||
|
||||
if (!m_cursor_at_low_nibble) {
|
||||
u8 existing_change = m_document->get(m_position).value;
|
||||
existing_change = value << 4 | (existing_change & 0xF); // shift new value left 4 bits, OR with existing last 4 bits
|
||||
m_document->set(m_position, existing_change);
|
||||
u8 new_value = value << 4 | (existing_change & 0xF); // shift new value left 4 bits, OR with existing last 4 bits
|
||||
m_document->set(m_position, new_value);
|
||||
did_complete_action(m_position, old_value, new_value);
|
||||
m_cursor_at_low_nibble = true;
|
||||
} else {
|
||||
m_document->set(m_position, (m_document->get(m_position).value & 0xF0) | value); // save the first 4 bits, OR the new value in the last 4
|
||||
u8 new_value = (m_document->get(m_position).value & 0xF0) | value; // save the first 4 bits, OR the new value in the last 4
|
||||
m_document->set(m_position, new_value);
|
||||
did_complete_action(m_position, old_value, new_value);
|
||||
if (m_position + 1 < m_document->size())
|
||||
m_position++;
|
||||
m_cursor_at_low_nibble = false;
|
||||
|
@ -498,7 +517,11 @@ void HexEditor::text_mode_keydown_event(GUI::KeyEvent& event)
|
|||
if (event.code_point() == 0) // This is a control key
|
||||
return;
|
||||
|
||||
m_document->set(m_position, event.code_point());
|
||||
auto old_value = m_document->get(m_position).value;
|
||||
auto new_value = event.code_point();
|
||||
m_document->set(m_position, new_value);
|
||||
did_complete_action(m_position, old_value, new_value);
|
||||
|
||||
if (m_position + 1 < m_document->size())
|
||||
m_position++;
|
||||
m_cursor_at_low_nibble = false;
|
||||
|
@ -797,3 +820,56 @@ void HexEditor::reset_cursor_blink_state()
|
|||
m_cursor_blink_active = true;
|
||||
m_blink_timer->restart();
|
||||
}
|
||||
|
||||
void HexEditor::did_complete_action(size_t position, u8 old_value, u8 new_value)
|
||||
{
|
||||
if (old_value == new_value)
|
||||
return;
|
||||
|
||||
auto command = make<HexDocumentUndoCommand>(m_document->make_weak_ptr(), position);
|
||||
|
||||
// We know this won't allocate because the buffers start empty
|
||||
MUST(command->try_add_changed_byte(old_value, new_value));
|
||||
// FIXME: Handle errors
|
||||
MUST(m_undo_stack.try_push(move(command)));
|
||||
}
|
||||
|
||||
void HexEditor::did_complete_action(size_t position, ByteBuffer&& old_values, ByteBuffer&& new_values)
|
||||
{
|
||||
auto command = make<HexDocumentUndoCommand>(m_document->make_weak_ptr(), position);
|
||||
|
||||
// FIXME: Handle errors
|
||||
MUST(command->try_add_changed_bytes(move(old_values), move(new_values)));
|
||||
MUST(m_undo_stack.try_push(move(command)));
|
||||
}
|
||||
|
||||
bool HexEditor::undo()
|
||||
{
|
||||
if (!m_undo_stack.can_undo())
|
||||
return false;
|
||||
|
||||
m_undo_stack.undo();
|
||||
reset_cursor_blink_state();
|
||||
update();
|
||||
update_status();
|
||||
did_change();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexEditor::redo()
|
||||
{
|
||||
if (!m_undo_stack.can_redo())
|
||||
return false;
|
||||
|
||||
m_undo_stack.redo();
|
||||
reset_cursor_blink_state();
|
||||
update();
|
||||
update_status();
|
||||
did_change();
|
||||
return true;
|
||||
}
|
||||
|
||||
GUI::UndoStack& HexEditor::undo_stack()
|
||||
{
|
||||
return m_undo_stack;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue