LibGUI+GMLPlayground: Replace text using ReplaceAllTextCommand

This commit is contained in:
SimonFJ20 2022-04-12 22:46:26 +02:00 committed by Andreas Kling
parent 343d699627
commit 661e7d691e
5 changed files with 65 additions and 1 deletions

View file

@ -227,7 +227,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(edit_menu->try_add_action(GUI::Action::create("&Format GML", { Mod_Ctrl | Mod_Shift, Key_I }, [&](auto&) {
auto formatted_gml_or_error = GUI::GML::format_gml(editor->text());
if (!formatted_gml_or_error.is_error()) {
editor->set_text(formatted_gml_or_error.release_value());
editor->replace_all_text_while_keeping_undo_stack(formatted_gml_or_error.release_value());
} else {
GUI::MessageBox::show(
window,

View file

@ -884,6 +884,40 @@ void RemoveTextCommand::undo()
m_document.set_all_cursors(new_cursor);
}
ReplaceAllTextCommand::ReplaceAllTextCommand(GUI::TextDocument& document, String const& text, GUI::TextRange const& range)
: TextDocumentUndoCommand(document)
, m_text(text)
, m_range(range)
{
}
void ReplaceAllTextCommand::redo()
{
m_document.remove(m_range);
m_document.set_all_cursors(m_range.start());
auto new_cursor = m_document.insert_at(m_range.start(), m_text, m_client);
m_range.set_end(new_cursor);
m_document.set_all_cursors(new_cursor);
}
void ReplaceAllTextCommand::undo()
{
m_document.remove(m_range);
m_document.set_all_cursors(m_range.start());
auto new_cursor = m_document.insert_at(m_range.start(), m_text);
m_document.set_all_cursors(new_cursor);
}
bool ReplaceAllTextCommand::merge_with(GUI::Command const&)
{
return false;
}
String ReplaceAllTextCommand::action_text() const
{
return "Playground format text";
}
TextPosition TextDocument::insert_at(TextPosition const& position, StringView text, Client const* client)
{
TextPosition cursor = position;

View file

@ -236,4 +236,20 @@ private:
TextRange m_range;
};
class ReplaceAllTextCommand : public GUI::TextDocumentUndoCommand {
public:
ReplaceAllTextCommand(GUI::TextDocument& document, String const& text, GUI::TextRange const& range);
void redo() override;
void undo() override;
bool merge_with(GUI::Command const&) override;
String action_text() const override;
String const& text() const { return m_text; }
TextRange const& range() const { return m_range; }
private:
String m_text;
GUI::TextRange m_range;
};
}

View file

@ -1446,6 +1446,19 @@ void TextEditor::insert_at_cursor_or_replace_selection(StringView text)
}
}
void TextEditor::replace_all_text_while_keeping_undo_stack(StringView text)
{
auto start = GUI::TextPosition(0, 0);
auto last_line_index = line_count() - 1;
auto end = GUI::TextPosition(last_line_index, line(last_line_index).length());
auto range = GUI::TextRange(start, end);
auto normalized_range = range.normalized();
execute<ReplaceAllTextCommand>(text, range);
did_change();
set_cursor(normalized_range.start());
update();
}
void TextEditor::cut()
{
if (!is_editable())

View file

@ -123,6 +123,7 @@ public:
TextRange normalized_selection() const { return m_selection.normalized(); }
void insert_at_cursor_or_replace_selection(StringView);
void replace_all_text_while_keeping_undo_stack(StringView text);
bool write_to_file(String const& path);
bool write_to_file(Core::File&);
bool has_selection() const { return m_selection.is_valid(); }