summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-08-10 11:06:29 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-08-10 11:06:29 +0200
commit078ce97c4100de14170cb5c3b5c385187edb4ae9 (patch)
tree1fa620fd7128d5861f3edeae697d129bf07e1aa5
parent0f0a528323acfb1c355a07f791e6db17c81afaba (diff)
downloadserenity-078ce97c4100de14170cb5c3b5c385187edb4ae9.zip
GJsonArrayModel: Add an optional "massage_for_display" fieldspec hook
This allows to you install a custom callback that can do anything with Role::Display data before it's returned by GJsonArrayModel::data().
-rw-r--r--Applications/ProcessManager/NetworkStatisticsWidget.cpp44
-rw-r--r--Libraries/LibGUI/GJsonArrayModel.cpp14
-rw-r--r--Libraries/LibGUI/GJsonArrayModel.h12
3 files changed, 46 insertions, 24 deletions
diff --git a/Applications/ProcessManager/NetworkStatisticsWidget.cpp b/Applications/ProcessManager/NetworkStatisticsWidget.cpp
index 5785057b8f..4820755d5e 100644
--- a/Applications/ProcessManager/NetworkStatisticsWidget.cpp
+++ b/Applications/ProcessManager/NetworkStatisticsWidget.cpp
@@ -21,16 +21,15 @@ NetworkStatisticsWidget::NetworkStatisticsWidget(GWidget* parent)
m_adapter_table_view = new GTableView(adapters_group_box);
m_adapter_table_view->set_size_columns_to_fit_content(true);
- Vector<GJsonArrayModel::FieldSpec> net_adapters_fields = {
- { "name", "Name", TextAlignment::CenterLeft },
- { "class_name", "Class", TextAlignment::CenterLeft },
- { "mac_address", "MAC", TextAlignment::CenterLeft },
- { "ipv4_address", "IPv4", TextAlignment::CenterLeft },
- { "packets_in", "Pkt In", TextAlignment::CenterRight },
- { "packets_out", "Pkt Out", TextAlignment::CenterRight },
- { "bytes_in", "Bytes In", TextAlignment::CenterRight },
- { "bytes_out", "Bytes Out", TextAlignment::CenterRight },
- };
+ Vector<GJsonArrayModel::FieldSpec> net_adapters_fields;
+ net_adapters_fields.empend("name", "Name", TextAlignment::CenterLeft);
+ net_adapters_fields.empend("class_name", "Class", TextAlignment::CenterLeft);
+ net_adapters_fields.empend("mac_address", "MAC", TextAlignment::CenterLeft);
+ net_adapters_fields.empend("ipv4_address", "IPv4", TextAlignment::CenterLeft);
+ net_adapters_fields.empend("packets_in", "Pkt In", TextAlignment::CenterRight);
+ net_adapters_fields.empend("packets_out", "Pkt Out", TextAlignment::CenterRight);
+ net_adapters_fields.empend("bytes_in", "Bytes In", TextAlignment::CenterRight);
+ net_adapters_fields.empend("bytes_out", "Bytes Out", TextAlignment::CenterRight);
m_adapter_table_view->set_model(GJsonArrayModel::create("/proc/net/adapters", move(net_adapters_fields)));
auto* sockets_group_box = new GGroupBox("Sockets", this);
@@ -42,19 +41,18 @@ NetworkStatisticsWidget::NetworkStatisticsWidget(GWidget* parent)
m_socket_table_view = new GTableView(sockets_group_box);
m_socket_table_view->set_size_columns_to_fit_content(true);
- Vector<GJsonArrayModel::FieldSpec> net_tcp_fields = {
- { "peer_address", "Peer", TextAlignment::CenterLeft },
- { "peer_port", "Port", TextAlignment::CenterRight },
- { "local_address", "Local", TextAlignment::CenterLeft },
- { "local_port", "Port", TextAlignment::CenterRight },
- { "state", "State", TextAlignment::CenterLeft },
- { "ack_number", "Ack#", TextAlignment::CenterRight },
- { "sequence_number", "Seq#", TextAlignment::CenterRight },
- { "packets_in", "Pkt In", TextAlignment::CenterRight },
- { "packets_out", "Pkt Out", TextAlignment::CenterRight },
- { "bytes_in", "Bytes In", TextAlignment::CenterRight },
- { "bytes_out", "Bytes Out", TextAlignment::CenterRight },
- };
+ Vector<GJsonArrayModel::FieldSpec> net_tcp_fields;
+ net_tcp_fields.empend("peer_address", "Peer", TextAlignment::CenterLeft);
+ net_tcp_fields.empend("peer_port", "Port", TextAlignment::CenterRight);
+ net_tcp_fields.empend("local_address", "Local", TextAlignment::CenterLeft);
+ net_tcp_fields.empend("local_port", "Port", TextAlignment::CenterRight);
+ net_tcp_fields.empend("state", "State", TextAlignment::CenterLeft);
+ net_tcp_fields.empend("ack_number", "Ack#", TextAlignment::CenterRight);
+ net_tcp_fields.empend("sequence_number", "Seq#", TextAlignment::CenterRight);
+ net_tcp_fields.empend("packets_in", "Pkt In", TextAlignment::CenterRight);
+ net_tcp_fields.empend("packets_out", "Pkt Out", TextAlignment::CenterRight);
+ net_tcp_fields.empend("bytes_in", "Bytes In", TextAlignment::CenterRight);
+ net_tcp_fields.empend("bytes_out", "Bytes Out", TextAlignment::CenterRight);
m_socket_table_view->set_model(GJsonArrayModel::create("/proc/net/tcp", move(net_tcp_fields)));
m_update_timer = new CTimer(
diff --git a/Libraries/LibGUI/GJsonArrayModel.cpp b/Libraries/LibGUI/GJsonArrayModel.cpp
index 5721e0fd8e..be93510ddf 100644
--- a/Libraries/LibGUI/GJsonArrayModel.cpp
+++ b/Libraries/LibGUI/GJsonArrayModel.cpp
@@ -26,11 +26,14 @@ GModel::ColumnMetadata GJsonArrayModel::column_metadata(int column) const
GVariant GJsonArrayModel::data(const GModelIndex& index, Role role) const
{
+ auto& field_spec = m_fields[index.column()];
auto& object = m_array.at(index.row()).as_object();
if (role == GModel::Role::Display) {
- auto& json_field_name = m_fields[index.column()].json_field_name;
+ auto& json_field_name = field_spec.json_field_name;
auto data = object.get(json_field_name);
+ if (field_spec.massage_for_display)
+ return field_spec.massage_for_display(data);
if (data.is_int())
return data.as_int();
if (data.is_uint())
@@ -39,3 +42,12 @@ GVariant GJsonArrayModel::data(const GModelIndex& index, Role role) const
}
return {};
}
+
+void GJsonArrayModel::set_json_path(const String& json_path)
+{
+ if (m_json_path == json_path)
+ return;
+
+ m_json_path = json_path;
+ update();
+}
diff --git a/Libraries/LibGUI/GJsonArrayModel.h b/Libraries/LibGUI/GJsonArrayModel.h
index 5a75f620ba..c46e74689a 100644
--- a/Libraries/LibGUI/GJsonArrayModel.h
+++ b/Libraries/LibGUI/GJsonArrayModel.h
@@ -6,9 +6,18 @@
class GJsonArrayModel final : public GModel {
public:
struct FieldSpec {
+ FieldSpec(const String& a_json_field_name, const String& a_column_name, TextAlignment a_text_alignment, Function<GVariant(const GVariant&)>&& a_massage_for_display = {})
+ : json_field_name(a_json_field_name)
+ , column_name(a_column_name)
+ , text_alignment(a_text_alignment)
+ , massage_for_display(move(a_massage_for_display))
+ {
+ }
+
String json_field_name;
String column_name;
TextAlignment text_alignment;
+ Function<GVariant(const GVariant&)> massage_for_display;
};
static NonnullRefPtr<GJsonArrayModel> create(const String& json_path, Vector<FieldSpec>&& fields)
@@ -25,6 +34,9 @@ public:
virtual GVariant data(const GModelIndex&, Role = Role::Display) const override;
virtual void update() override;
+ const String& json_path() const { return m_json_path; }
+ void set_json_path(const String& json_path);
+
private:
GJsonArrayModel(const String& json_path, Vector<FieldSpec>&& fields)
: m_json_path(json_path)