Explorar o código

Inspector: Make properties editable :^)

This patch makes it possible to live-edit remote object properties by
simply double clicking on them in the property table view.

This is pretty neat! :^)
Andreas Kling %!s(int64=5) %!d(string=hai) anos
pai
achega
b2be8466fb

+ 10 - 0
DevTools/Inspector/RemoteObjectPropertyModel.cpp

@@ -26,6 +26,7 @@
 
 #include "RemoteObjectPropertyModel.h"
 #include "RemoteObject.h"
+#include "RemoteProcess.h"
 
 RemoteObjectPropertyModel::RemoteObjectPropertyModel(RemoteObject& object)
     : m_object(object)
@@ -70,3 +71,12 @@ void RemoteObjectPropertyModel::update()
     });
     did_update();
 }
+
+void RemoteObjectPropertyModel::set_data(const GUI::ModelIndex& index, const GUI::Variant& new_value)
+{
+    auto& property = m_properties[index.row()];
+    uintptr_t address = m_object.json.get("address").to_number<uintptr_t>();
+    RemoteProcess::the().set_property(address, property.name.to_string(), new_value.to_string());
+    property.value = new_value.to_string();
+    did_update();
+}

+ 2 - 0
DevTools/Inspector/RemoteObjectPropertyModel.h

@@ -49,7 +49,9 @@ public:
     virtual int column_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return Column::__Count; }
     virtual String column_name(int) const override;
     virtual GUI::Variant data(const GUI::ModelIndex&, Role = Role::Display) const override;
+    virtual void set_data(const GUI::ModelIndex&, const GUI::Variant&) override;
     virtual void update() override;
+    virtual bool is_editable(const GUI::ModelIndex& index) const override { return index.column() == Column::Value; }
 
 private:
     explicit RemoteObjectPropertyModel(RemoteObject&);

+ 18 - 0
DevTools/Inspector/RemoteProcess.cpp

@@ -31,11 +31,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+RemoteProcess* s_the;
+
+RemoteProcess& RemoteProcess::the()
+{
+    return *s_the;
+}
+
 RemoteProcess::RemoteProcess(pid_t pid)
     : m_pid(pid)
     , m_object_graph_model(RemoteObjectGraphModel::create(*this))
     , m_socket(Core::LocalSocket::construct())
 {
+    s_the = this;
 }
 
 void RemoteProcess::handle_identify_response(const JsonObject& response)
@@ -104,6 +112,16 @@ void RemoteProcess::set_inspected_object(uintptr_t address)
     send_request(request);
 }
 
+void RemoteProcess::set_property(uintptr_t object, const StringView& name, const JsonValue& value)
+{
+    JsonObject request;
+    request.set("type", "SetProperty");
+    request.set("address", object);
+    request.set("name", JsonValue(name));
+    request.set("value", value);
+    send_request(request);
+}
+
 void RemoteProcess::update()
 {
     m_socket->on_connected = [this] {

+ 4 - 0
DevTools/Inspector/RemoteProcess.h

@@ -34,6 +34,8 @@ class RemoteObject;
 
 class RemoteProcess {
 public:
+    static RemoteProcess& the();
+
     explicit RemoteProcess(pid_t);
     void update();
 
@@ -45,6 +47,8 @@ public:
 
     void set_inspected_object(uintptr_t);
 
+    void set_property(uintptr_t object, const StringView& name, const JsonValue& value);
+
     Function<void()> on_update;
 
 private:

+ 5 - 0
DevTools/Inspector/main.cpp

@@ -30,6 +30,7 @@
 #include "RemoteProcess.h"
 #include <LibGUI/Application.h>
 #include <LibGUI/BoxLayout.h>
+#include <LibGUI/ModelEditingDelegate.h>
 #include <LibGUI/Splitter.h>
 #include <LibGUI/TableView.h>
 #include <LibGUI/TreeView.h>
@@ -77,6 +78,10 @@ int main(int argc, char** argv)
 
     auto& properties_table_view = splitter.add<GUI::TableView>();
     properties_table_view.set_size_columns_to_fit_content(true);
+    properties_table_view.set_editable(true);
+    properties_table_view.aid_create_editing_delegate = [](auto&) {
+        return make<GUI::StringModelEditingDelegate>();
+    };
 
     tree_view.on_activation = [&](auto& index) {
         auto* remote_object = static_cast<RemoteObject*>(index.internal_data());