Browse Source

LibGUI: Don't recompute line-wrapping over and over during set_text()

This makes the TextEditor start up fast for large files again.
Andreas Kling 5 years ago
parent
commit
fc14bdd442

+ 25 - 16
Libraries/LibGUI/GTextDocument.cpp

@@ -11,6 +11,7 @@ GTextDocument::GTextDocument(Client* client)
 
 void GTextDocument::set_text(const StringView& text)
 {
+    m_client_notifications_enabled = false;
     m_spans.clear();
     remove_all_lines();
 
@@ -30,6 +31,10 @@ void GTextDocument::set_text(const StringView& text)
             add_line(i);
     }
     add_line(i);
+    m_client_notifications_enabled = true;
+
+    for (auto* client : m_clients)
+        client->document_did_set_text();
 }
 
 int GTextDocumentLine::first_non_whitespace_column() const
@@ -122,29 +127,37 @@ void GTextDocumentLine::truncate(GTextDocument& document, int length)
 void GTextDocument::append_line(NonnullOwnPtr<GTextDocumentLine> line)
 {
     lines().append(move(line));
-    for (auto* client : m_clients)
-        client->document_did_append_line();
+    if (m_client_notifications_enabled) {
+        for (auto* client : m_clients)
+            client->document_did_append_line();
+    }
 }
 
 void GTextDocument::insert_line(int line_index, NonnullOwnPtr<GTextDocumentLine> line)
 {
     lines().insert(line_index, move(line));
-    for (auto* client : m_clients)
-        client->document_did_insert_line(line_index);
+    if (m_client_notifications_enabled) {
+        for (auto* client : m_clients)
+            client->document_did_insert_line(line_index);
+    }
 }
 
 void GTextDocument::remove_line(int line_index)
 {
     lines().remove(line_index);
-    for (auto* client : m_clients)
-        client->document_did_remove_line(line_index);
+    if (m_client_notifications_enabled) {
+        for (auto* client : m_clients)
+            client->document_did_remove_line(line_index);
+    }
 }
 
 void GTextDocument::remove_all_lines()
 {
     lines().clear();
-    for (auto* client : m_clients)
-        client->document_did_remove_all_lines();
+    if (m_client_notifications_enabled) {
+        for (auto* client : m_clients)
+            client->document_did_remove_all_lines();
+    }
 }
 
 GTextDocument::Client::~Client()
@@ -163,8 +176,10 @@ void GTextDocument::unregister_client(Client& client)
 
 void GTextDocument::update_views(Badge<GTextDocumentLine>)
 {
-    for (auto* client : m_clients)
-        client->document_did_change();
+    if (m_client_notifications_enabled) {
+        for (auto* client : m_clients)
+            client->document_did_change();
+    }
 }
 
 String GTextDocument::text_in_range(const GTextRange& a_range) const
@@ -326,9 +341,3 @@ Optional<GTextDocumentSpan> GTextDocument::first_non_skippable_span_after(const
     }
     return {};
 }
-
-
-
-
-
-

+ 2 - 0
Libraries/LibGUI/GTextDocument.h

@@ -36,6 +36,7 @@ public:
         virtual void document_did_remove_line(int) = 0;
         virtual void document_did_remove_all_lines() = 0;
         virtual void document_did_change() = 0;
+        virtual void document_did_set_text() = 0;
     };
 
     static NonnullRefPtr<GTextDocument> create(Client* client = nullptr)
@@ -90,6 +91,7 @@ private:
     Vector<GTextDocumentSpan> m_spans;
 
     HashTable<Client*> m_clients;
+    bool m_client_notifications_enabled { true };
 };
 
 class GTextDocumentLine {

+ 8 - 0
Libraries/LibGUI/GTextEditor.cpp

@@ -1613,6 +1613,14 @@ void GTextEditor::document_did_change()
     update();
 }
 
+void GTextEditor::document_did_set_text()
+{
+    m_line_visual_data.clear();
+    for (int i = 0; i < m_document->line_count(); ++i)
+        m_line_visual_data.append(make<LineVisualData>());
+    document_did_change();
+}
+
 void GTextEditor::set_document(GTextDocument& document)
 {
     if (m_document.ptr() == &document)

+ 1 - 0
Libraries/LibGUI/GTextEditor.h

@@ -133,6 +133,7 @@ private:
     virtual void document_did_remove_line(int) override;
     virtual void document_did_remove_all_lines() override;
     virtual void document_did_change() override;
+    virtual void document_did_set_text() override;
 
     void create_actions();
     void paint_ruler(Painter&);