From 2849175a302f26be03b5da404ef93363d42ed313 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 17 Oct 2009 12:03:23 -0400
Subject: [PATCH] Introduce LLFloaterRegListener "clickButton" event operation.
 Based on discussion with James and Richard, this operation should allow an
 automation script to locate a visible LLFloater and simulate clicking any one
 of its LLButton children by name. As yet untested.

---
 indra/llui/llfloaterreglistener.cpp | 48 +++++++++++++++++++++++++++++
 indra/llui/llfloaterreglistener.h   |  1 +
 2 files changed, 49 insertions(+)

diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp
index cb8fa6dfdae..57d148b5af4 100644
--- a/indra/llui/llfloaterreglistener.cpp
+++ b/indra/llui/llfloaterreglistener.cpp
@@ -18,6 +18,8 @@
 // external library headers
 // other Linden headers
 #include "llfloaterreg.h"
+#include "llfloater.h"
+#include "llbutton.h"
 
 LLFloaterRegListener::LLFloaterRegListener(const std::string& pumpName):
     LLDispatchListener(pumpName, "op")
@@ -28,6 +30,10 @@ LLFloaterRegListener::LLFloaterRegListener(const std::string& pumpName):
     add("showInstance", &LLFloaterRegListener::showInstance, requiredName);
     add("hideInstance", &LLFloaterRegListener::hideInstance, requiredName);
     add("toggleInstance", &LLFloaterRegListener::toggleInstance, requiredName);
+    LLSD requiredNameButton;
+    requiredNameButton["name"] = LLSD();
+    requiredNameButton["button"] = LLSD();
+    add("clickButton", &LLFloaterRegListener::clickButton, requiredNameButton);
 }
 
 void LLFloaterRegListener::getBuildMap(const LLSD& event) const
@@ -64,3 +70,45 @@ void LLFloaterRegListener::toggleInstance(const LLSD& event) const
 {
     LLFloaterReg::toggleInstance(event["name"], event["key"]);
 }
+
+void LLFloaterRegListener::clickButton(const LLSD& event) const
+{
+    // If the caller requests a reply, build the reply.
+    LLReqID reqID(event);
+    LLSD reply(reqID.makeResponse());
+
+    LLFloater* floater = LLFloaterReg::findInstance(event["name"], event["key"]);
+    if (! LLFloater::isShown(floater))
+    {
+        reply["type"]  = "LLFloater";
+        reply["name"]  = event["name"];
+        reply["key"]   = event["key"];
+        reply["error"] = floater? "!isShown()" : "NULL";
+    }
+    else
+    {
+        // Here 'floater' points to an LLFloater instance with the specified
+        // name and key which isShown().
+        LLButton* button = floater->findChild<LLButton>(event["button"]);
+        if (! LLButton::isAvailable(button))
+        {
+            reply["type"]  = "LLButton";
+            reply["name"]  = event["button"];
+            reply["error"] = button? "!isAvailable()" : "NULL";
+        }
+        else
+        {
+            // Here 'button' points to an isAvailable() LLButton child of
+            // 'floater' with the specified button name. Pretend to click it.
+            button->onCommit();
+            // Leave reply["error"] isUndefined(): no error, i.e. success.
+        }
+    }
+
+    // Send a reply only if caller asked for a reply.
+    LLSD replyPump(event["reply"]);
+    if (replyPump.isString())       // isUndefined() if absent
+    {
+        LLEventPumps::instance().obtain(replyPump).post(reply);
+    }
+}
diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h
index 58d2c079365..304ecd10904 100644
--- a/indra/llui/llfloaterreglistener.h
+++ b/indra/llui/llfloaterreglistener.h
@@ -30,6 +30,7 @@ class LLFloaterRegListener: public LLDispatchListener
     void showInstance(const LLSD& event) const;
     void hideInstance(const LLSD& event) const;
     void toggleInstance(const LLSD& event) const;
+    void clickButton(const LLSD& event) const;
 };
 
 #endif /* ! defined(LL_LLFLOATERREGLISTENER_H) */
-- 
GitLab