Browse Source

HexEditor: Only mark window as modified when document is actually dirty

kamp 2 years ago
parent
commit
24f729d0ef

+ 28 - 6
Userland/Applications/HexEditor/HexDocument.cpp

@@ -8,7 +8,13 @@
 
 void HexDocument::set(size_t position, u8 value)
 {
-    m_changes.set(position, value);
+    auto unchanged_value = get_unchanged(position);
+
+    if (value == unchanged_value) {
+        m_changes.remove(position);
+    } else {
+        m_changes.set(position, value);
+    }
 }
 
 bool HexDocument::is_dirty() const
@@ -31,6 +37,11 @@ HexDocument::Cell HexDocumentMemory::get(size_t position)
     }
 }
 
+u8 HexDocumentMemory::get_unchanged(size_t position)
+{
+    return m_buffer[position];
+}
+
 size_t HexDocumentMemory::size() const
 {
     return m_buffer.size();
@@ -108,14 +119,16 @@ HexDocument::Cell HexDocumentFile::get(size_t position)
         return Cell { tracked_change.value(), true };
     }
 
-    if (position < m_buffer_file_pos || position >= m_buffer_file_pos + m_buffer.size()) {
-        m_file->seek(position, Core::SeekMode::SetPosition);
-        m_file->read(m_buffer.data(), m_buffer.size());
-        m_buffer_file_pos = position;
-    }
+    ensure_position_in_buffer(position);
     return { m_buffer[position - m_buffer_file_pos], false };
 }
 
+u8 HexDocumentFile::get_unchanged(size_t position)
+{
+    ensure_position_in_buffer(position);
+    return m_buffer[position - m_buffer_file_pos];
+}
+
 size_t HexDocumentFile::size() const
 {
     return m_file_size;
@@ -152,3 +165,12 @@ NonnullRefPtr<Core::File> HexDocumentFile::file() const
 {
     return m_file;
 }
+
+void HexDocumentFile::ensure_position_in_buffer(size_t position)
+{
+    if (position < m_buffer_file_pos || position >= m_buffer_file_pos + m_buffer.size()) {
+        m_file->seek(position, Core::SeekMode::SetPosition);
+        m_file->read(m_buffer.data(), m_buffer.size());
+        m_buffer_file_pos = position;
+    }
+}

+ 5 - 0
Userland/Applications/HexEditor/HexDocument.h

@@ -24,6 +24,7 @@ public:
 
     virtual ~HexDocument() = default;
     virtual Cell get(size_t position) = 0;
+    virtual u8 get_unchanged(size_t position) = 0;
     virtual void set(size_t position, u8 value);
     virtual size_t size() const = 0;
     virtual Type type() const = 0;
@@ -40,6 +41,7 @@ public:
     virtual ~HexDocumentMemory() = default;
 
     Cell get(size_t position) override;
+    u8 get_unchanged(size_t position) override;
     size_t size() const override;
     Type type() const override;
     void clear_changes() override;
@@ -61,11 +63,14 @@ public:
     void write_to_file();
     bool write_to_file(NonnullRefPtr<Core::File> file);
     Cell get(size_t position) override;
+    u8 get_unchanged(size_t position) override;
     size_t size() const override;
     Type type() const override;
     void clear_changes() override;
 
 private:
+    void ensure_position_in_buffer(size_t position);
+
     NonnullRefPtr<Core::File> m_file;
     size_t m_file_size;
 

+ 1 - 1
Userland/Applications/HexEditor/HexEditor.cpp

@@ -518,7 +518,7 @@ void HexEditor::update_status()
 void HexEditor::did_change()
 {
     if (on_change)
-        on_change();
+        on_change(m_document->is_dirty());
 }
 
 void HexEditor::paint_event(GUI::PaintEvent& event)

+ 1 - 1
Userland/Applications/HexEditor/HexEditor.h

@@ -59,7 +59,7 @@ public:
     Vector<Match> find_all(ByteBuffer& needle, size_t start = 0);
     Vector<Match> find_all_strings(size_t min_length = 4);
     Function<void(size_t, EditMode, size_t, size_t)> on_status_change; // position, edit mode, selection start, selection end
-    Function<void()> on_change;
+    Function<void(bool is_document_dirty)> on_change;
 
 protected:
     HexEditor();

+ 2 - 2
Userland/Applications/HexEditor/HexEditorWidget.cpp

@@ -79,8 +79,8 @@ HexEditorWidget::HexEditorWidget()
         m_selecting_from_inspector = false;
     };
 
-    m_editor->on_change = [this] {
-        window()->set_modified(true);
+    m_editor->on_change = [this](bool is_document_dirty) {
+        window()->set_modified(is_document_dirty);
     };
 
     m_search_results->set_activates_on_selection(true);