ソースを参照

SystemMonitor: Use a TableView to display the thread stack

Using a table display this information in a much more organised and
flexible way than than what can be achieved with a TextEditor.
Rodrigo Tobar 3 年 前
コミット
1f4a6e7c22

+ 58 - 16
Userland/Applications/SystemMonitor/ThreadStackWidget.cpp

@@ -7,16 +7,70 @@
 #include "ThreadStackWidget.h"
 #include <LibCore/Timer.h>
 #include <LibGUI/BoxLayout.h>
+#include <LibGUI/Model.h>
 #include <LibSymbolication/Symbolication.h>
 #include <LibThreading/BackgroundAction.h>
 
+class ThreadStackModel final : public GUI::Model {
+
+    enum Column {
+        Address,
+        Object,
+        Symbol
+    };
+
+public:
+    int column_count(GUI::ModelIndex const&) const override { return 3; };
+    int row_count(GUI::ModelIndex const&) const override { return m_symbols.size(); };
+    bool is_column_sortable(int) const override { return false; }
+
+    String column_name(int column) const override
+    {
+        switch (column) {
+        case Column::Address:
+            return "Address";
+        case Column::Object:
+            return "Object";
+        case Column::Symbol:
+            return "Symbol";
+        default:
+            VERIFY_NOT_REACHED();
+        }
+    }
+
+    GUI::Variant data(GUI::ModelIndex const& model_index, GUI::ModelRole) const override
+    {
+        auto& symbol = m_symbols[model_index.row()];
+        switch (model_index.column()) {
+        case Column::Address:
+            return String::formatted("{:p}", symbol.address);
+        case Column::Object:
+            return symbol.object;
+        case Column::Symbol:
+            return symbol.name;
+        default:
+            VERIFY_NOT_REACHED();
+        }
+    };
+
+    void set_symbols(Vector<Symbolication::Symbol> const& symbols)
+    {
+        if (m_symbols == symbols)
+            return;
+        m_symbols = symbols;
+        invalidate();
+    }
+
+private:
+    Vector<Symbolication::Symbol> m_symbols;
+};
+
 ThreadStackWidget::ThreadStackWidget()
 {
     set_layout<GUI::VerticalBoxLayout>();
     layout()->set_margins(4);
-    m_stack_editor = add<GUI::TextEditor>();
-    m_stack_editor->set_mode(GUI::TextEditor::ReadOnly);
-    m_stack_editor->set_text("Symbolicating...");
+    m_stack_table = add<GUI::TableView>();
+    m_stack_table->set_model(adopt_ref(*new ThreadStackModel()));
 }
 
 ThreadStackWidget::~ThreadStackWidget()
@@ -74,17 +128,5 @@ void ThreadStackWidget::refresh()
 void ThreadStackWidget::custom_event(Core::CustomEvent& event)
 {
     auto& completion_event = verify_cast<CompletionEvent>(event);
-
-    StringBuilder builder;
-
-    for (auto& symbol : completion_event.symbols()) {
-        builder.appendff("{:p} {:30s}", symbol.address, symbol.object);
-        if (!symbol.name.is_empty())
-            builder.appendff("  {}", symbol.name);
-        builder.append('\n');
-    }
-
-    if (m_stack_editor->text() != builder.string_view()) {
-        m_stack_editor->set_text(builder.string_view());
-    }
+    verify_cast<ThreadStackModel>(m_stack_table->model())->set_symbols(completion_event.symbols());
 }

+ 2 - 2
Userland/Applications/SystemMonitor/ThreadStackWidget.h

@@ -6,7 +6,7 @@
 
 #pragma once
 
-#include <LibGUI/TextEditor.h>
+#include <LibGUI/TableView.h>
 #include <LibGUI/Widget.h>
 
 class ThreadStackWidget final : public GUI::Widget {
@@ -26,6 +26,6 @@ private:
 
     pid_t m_pid { -1 };
     pid_t m_tid { -1 };
-    RefPtr<GUI::TextEditor> m_stack_editor;
+    RefPtr<GUI::TableView> m_stack_table;
     RefPtr<Core::Timer> m_timer;
 };