summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/llchat.h19
-rw-r--r--indra/llui/llflashtimer.cpp8
-rw-r--r--indra/llui/llflashtimer.h2
-rw-r--r--indra/llui/llfloaterreglistener.cpp24
-rw-r--r--indra/llui/llfloaterreglistener.h12
-rw-r--r--indra/llui/llluafloater.cpp295
-rw-r--r--indra/llui/llluafloater.h54
-rw-r--r--indra/llui/llmenugl.h28
-rw-r--r--indra/llui/llnotifications.cpp2
-rw-r--r--indra/llui/llscrolllistctrl.cpp2
-rw-r--r--indra/llui/lltextbase.cpp2
-rw-r--r--indra/llui/lltexteditor.cpp13
-rw-r--r--indra/llui/lltexteditor.h14
-rw-r--r--indra/llui/lltextvalidate.cpp1
-rw-r--r--indra/llui/lltoolbar.cpp2
-rw-r--r--indra/llui/llui.cpp3
-rw-r--r--indra/llui/lluictrl.cpp14
-rw-r--r--indra/llui/lluictrl.h47
19 files changed, 495 insertions, 49 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index a0314cb5f2..69e1b57245 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -49,6 +49,7 @@ set(llui_SOURCE_FILES
lllineeditor.cpp
llloadingindicator.cpp
lllocalcliprect.cpp
+ llluafloater.cpp
llmenubutton.cpp
llmenugl.cpp
llmodaldialog.cpp
@@ -164,6 +165,7 @@ set(llui_HEADER_FILES
lllineeditor.h
llloadingindicator.h
lllocalcliprect.h
+ llluafloater.h
llmenubutton.h
llmenugl.h
llmodaldialog.h
diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h
index 56105add7e..70d7e82970 100644
--- a/indra/llui/llchat.h
+++ b/indra/llui/llchat.h
@@ -89,7 +89,8 @@ public:
mPosAgent(),
mURL(),
mChatStyle(CHAT_STYLE_NORMAL),
- mSessionID()
+ mSessionID(),
+ mIsScript(false)
{ }
std::string mText; // UTF-8 line of text
@@ -107,6 +108,22 @@ public:
std::string mURL;
EChatStyle mChatStyle;
LLUUID mSessionID;
+
+ bool mIsScript;
};
+static const std::string LUA_PREFIX("[LUA]");
+
+inline
+std::string without_LUA_PREFIX(const std::string& string, bool is_lua)
+{
+ if (is_lua)
+ {
+ return string.substr(LUA_PREFIX.size());
+ }
+ else
+ {
+ return string;
+ }
+}
#endif
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
index 2de05f04c5..2711e8088d 100644
--- a/indra/llui/llflashtimer.cpp
+++ b/indra/llui/llflashtimer.cpp
@@ -35,7 +35,7 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
mIsCurrentlyHighlighted(false),
mUnset(false)
{
- mEventTimer.stop();
+ stop();
// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
@@ -53,7 +53,7 @@ void LLFlashTimer::unset()
mCallback = NULL;
}
-BOOL LLFlashTimer::tick()
+bool LLFlashTimer::tick()
{
mIsCurrentlyHighlighted = !mIsCurrentlyHighlighted;
@@ -74,12 +74,12 @@ void LLFlashTimer::startFlashing()
{
mIsFlashingInProgress = true;
mIsCurrentlyHighlighted = true;
- mEventTimer.start();
+ start();
}
void LLFlashTimer::stopFlashing()
{
- mEventTimer.stop();
+ stop();
mIsFlashingInProgress = false;
mIsCurrentlyHighlighted = false;
mCurrentTickCount = 0;
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
index 037e32ac50..988b577ed2 100644
--- a/indra/llui/llflashtimer.h
+++ b/indra/llui/llflashtimer.h
@@ -46,7 +46,7 @@ public:
LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
~LLFlashTimer() {};
- /*virtual*/ BOOL tick();
+ bool tick() override;
void startFlashing();
void stopFlashing();
diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp
index aa3d1a1171..8316101264 100644
--- a/indra/llui/llfloaterreglistener.cpp
+++ b/indra/llui/llfloaterreglistener.cpp
@@ -3,25 +3,25 @@
* @author Nat Goodspeed
* @date 2009-08-12
* @brief Implementation for llfloaterreglistener.
- *
+ *
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -37,6 +37,7 @@
#include "llfloaterreg.h"
#include "llfloater.h"
#include "llbutton.h"
+#include "llluafloater.h"
LLFloaterRegListener::LLFloaterRegListener():
LLEventAPI("LLFloaterReg",
@@ -72,6 +73,13 @@ LLFloaterRegListener::LLFloaterRegListener():
"Simulate clicking the named [\"button\"] in the visible floater named in [\"name\"]",
&LLFloaterRegListener::clickButton,
requiredNameButton);
+
+ add("showLuaFloater",
+ "Open the new floater using XML file specified in [\"xml_path\"] with ID in [\"reqid\"]",
+ &LLLuaFloater::showLuaFloater, {llsd::map("xml_path", LLSD(), "reqid", LLSD())});
+ add("getFloaterEvents",
+ "Return the table of Lua Floater events which are send to the script",
+ &LLFloaterRegListener::getLuaFloaterEvents);
}
void LLFloaterRegListener::getBuildMap(const LLSD& event) const
@@ -154,3 +162,9 @@ void LLFloaterRegListener::clickButton(const LLSD& event) const
LLEventPumps::instance().obtain(replyPump).post(reply);
}
}
+
+void LLFloaterRegListener::getLuaFloaterEvents(const LLSD &event) const
+{
+ Response response(llsd::map("events", LLLuaFloater::getEventsData()), event);
+}
+
diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h
index a36072892c..9cb0af2de5 100644
--- a/indra/llui/llfloaterreglistener.h
+++ b/indra/llui/llfloaterreglistener.h
@@ -3,25 +3,25 @@
* @author Nat Goodspeed
* @date 2009-08-12
* @brief Wrap (subset of) LLFloaterReg API with an event API
- *
+ *
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -49,6 +49,8 @@ private:
void toggleInstance(const LLSD& event) const;
void instanceVisible(const LLSD& event) const;
void clickButton(const LLSD& event) const;
+
+ void getLuaFloaterEvents(const LLSD &event) const;
};
#endif /* ! defined(LL_LLFLOATERREGLISTENER_H) */
diff --git a/indra/llui/llluafloater.cpp b/indra/llui/llluafloater.cpp
new file mode 100644
index 0000000000..e584a67a00
--- /dev/null
+++ b/indra/llui/llluafloater.cpp
@@ -0,0 +1,295 @@
+/**
+ * @file llluafloater.cpp
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ *
+ */
+
+#include "llluafloater.h"
+
+#include "fsyspath.h"
+#include "llevents.h"
+
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llscrolllistctrl.h"
+#include "lltexteditor.h"
+
+const std::string LISTENER_NAME("LLLuaFloater");
+
+std::set<std::string> EVENT_LIST = {
+ "commit",
+ "double_click",
+ "mouse_enter",
+ "mouse_leave",
+ "mouse_down",
+ "mouse_up",
+ "right_mouse_down",
+ "right_mouse_up",
+ "post_build",
+ "floater_close",
+ "keystroke"
+};
+
+LLLuaFloater::LLLuaFloater(const LLSD &key) :
+ LLFloater(key),
+ mDispatchListener(LLUUID::generateNewID().asString(), "action"),
+ mReplyPumpName(key["reply"].asString()),
+ mReqID(key)
+{
+ auto ctrl_lookup = [this](const LLSD &event, std::function<LLSD(LLUICtrl*,const LLSD&)> cb)
+ {
+ LLUICtrl *ctrl = getChild<LLUICtrl>(event["ctrl_name"].asString());
+ if (!ctrl)
+ {
+ LL_WARNS("LuaFloater") << "Control not found: " << event["ctrl_name"] << LL_ENDL;
+ return LLSD();
+ }
+ return cb(ctrl, event);
+ };
+
+ LLSD requiredParams = llsd::map("ctrl_name", LLSD(), "value", LLSD());
+ mDispatchListener.add("set_enabled", "", [ctrl_lookup](const LLSD &event)
+ {
+ return ctrl_lookup(event, [](LLUICtrl *ctrl, const LLSD &event) { ctrl->setEnabled(event["value"].asBoolean()); return LLSD(); });
+ }, requiredParams);
+ mDispatchListener.add("set_visible", "", [ctrl_lookup](const LLSD &event)
+ {
+ return ctrl_lookup(event, [](LLUICtrl *ctrl, const LLSD &event) { ctrl->setVisible(event["value"].asBoolean()); return LLSD(); });
+ }, requiredParams);
+ mDispatchListener.add("set_value", "", [ctrl_lookup](const LLSD &event)
+ {
+ return ctrl_lookup(event, [](LLUICtrl *ctrl, const LLSD &event) { ctrl->setValue(event["value"]); return LLSD(); });
+ }, requiredParams);
+
+ mDispatchListener.add("add_list_element", "", [this](const LLSD &event)
+ {
+ LLScrollListCtrl *ctrl = getChild<LLScrollListCtrl>(event["ctrl_name"].asString());
+ if(ctrl)
+ {
+ LLSD element_data = event["value"];
+ if (element_data.isArray())
+ {
+ for (const auto &row : llsd::inArray(element_data))
+ {
+ ctrl->addElement(row);
+ }
+ }
+ else
+ {
+ ctrl->addElement(element_data);
+ }
+ }
+ }, requiredParams);
+
+ mDispatchListener.add("add_text", "", [this](const LLSD &event)
+ {
+ LLTextEditor *editor = getChild<LLTextEditor>(event["ctrl_name"].asString());
+ if (editor)
+ {
+ editor->pasteTextWithLinebreaks(stringize(event["value"]));
+ editor->addLineBreakChar(true);
+ }
+ }, requiredParams);
+
+ mDispatchListener.add("set_title", "", [this](const LLSD &event)
+ {
+ setTitle(event["value"].asString());
+ }, llsd::map("value", LLSD()));
+
+ mDispatchListener.add("get_value", "", [ctrl_lookup](const LLSD &event)
+ {
+ return ctrl_lookup(event, [](LLUICtrl *ctrl, const LLSD &event) { return llsd::map("value", ctrl->getValue()); });
+ }, llsd::map("ctrl_name", LLSD(), "reqid", LLSD()));
+}
+
+LLLuaFloater::~LLLuaFloater()
+{
+ //post empty LLSD() to indicate done, in case it wasn't handled by the script after CLOSE_EVENT
+ post(LLSD());
+}
+
+BOOL LLLuaFloater::postBuild()
+{
+ for (LLView *view : *getChildList())
+ {
+ LLUICtrl *ctrl = dynamic_cast<LLUICtrl*>(view);
+ if (ctrl)
+ {
+ LLSD data;
+ data["ctrl_name"] = view->getName();
+
+ ctrl->setCommitCallback([this, data](LLUICtrl *ctrl, const LLSD &param)
+ {
+ LLSD event(data);
+ event["value"] = ctrl->getValue();
+ postEvent(event, "commit");
+ });
+ }
+ }
+
+ //optional field to send additional specified events to the script
+ if (mKey.has("extra_events"))
+ {
+ //the first value is ctrl name, the second contains array of events to send
+ for (const auto &[name, data] : llsd::inMap(mKey["extra_events"]))
+ {
+ for (const auto &event : llsd::inArray(data))
+ {
+ registerCallback(name, event);
+ }
+ }
+ }
+
+ //send pump name to the script after the floater is built
+ postEvent(llsd::map("command_name", mDispatchListener.getPumpName()), "post_build");
+
+ return true;
+}
+
+void LLLuaFloater::onClose(bool app_quitting)
+{
+ postEvent(llsd::map("app_quitting", app_quitting), "floater_close");
+}
+
+bool event_is(const std::string &event_name, const std::string &list_event)
+{
+ llassert(EVENT_LIST.find(list_event) != EVENT_LIST.end());
+ return (event_name == list_event);
+}
+
+void LLLuaFloater::registerCallback(const std::string &ctrl_name, const std::string &event)
+{
+ LLUICtrl *ctrl = getChild<LLUICtrl>(ctrl_name);
+ if (!ctrl) return;
+
+ LLSD data;
+ data["ctrl_name"] = ctrl_name;
+ data["event"] = event;
+
+ auto mouse_event_cb = [this, data](LLUICtrl *ctrl, const LLSD &param) { post(data); };
+
+ auto mouse_event_coords_cb = [this, data](LLUICtrl *ctrl, S32 x, S32 y, MASK mask)
+ {
+ LLSD event(data);
+ post(event.with("x", x).with("y", y));
+ };
+
+ auto post_with_value = [this, data](LLSD value)
+ {
+ LLSD event(data);
+ post(event.with("value", value));
+ };
+
+ if (event_is(event, "mouse_enter"))
+ {
+ ctrl->setMouseEnterCallback(mouse_event_cb);
+ }
+ else if (event_is(event, "mouse_leave"))
+ {
+ ctrl->setMouseLeaveCallback(mouse_event_cb);
+ }
+ else if (event_is(event, "mouse_down"))
+ {
+ ctrl->setMouseDownCallback(mouse_event_coords_cb);
+ }
+ else if (event_is(event, "mouse_up"))
+ {
+ ctrl->setMouseUpCallback(mouse_event_coords_cb);
+ }
+ else if (event_is(event, "right_mouse_down"))
+ {
+ ctrl->setRightMouseDownCallback(mouse_event_coords_cb);
+ }
+ else if (event_is(event, "right_mouse_up"))
+ {
+ ctrl->setRightMouseUpCallback(mouse_event_coords_cb);
+ }
+ else if (event_is(event, "double_click"))
+ {
+ LLScrollListCtrl *list = dynamic_cast<LLScrollListCtrl *>(ctrl);
+ if (list)
+ {
+ list->setDoubleClickCallback( [post_with_value, list](){ post_with_value(LLSD(list->getCurrentID())); });
+ }
+ else
+ {
+ ctrl->setDoubleClickCallback(mouse_event_coords_cb);
+ }
+ }
+ else if (event_is(event, "keystroke"))
+ {
+ LLTextEditor* text_editor = dynamic_cast<LLTextEditor*>(ctrl);
+ if (text_editor)
+ {
+ text_editor->setKeystrokeCallback([post_with_value](LLTextEditor *editor) { post_with_value(editor->getValue()); });
+ }
+ LLLineEditor* line_editor = dynamic_cast<LLLineEditor*>(ctrl);
+ if (line_editor)
+ {
+ line_editor->setKeystrokeCallback([post_with_value](LLLineEditor *editor, void* userdata) { post_with_value(editor->getValue()); }, NULL);
+ }
+ }
+ else
+ {
+ LL_WARNS("LuaFloater") << "Can't register callback for unknown event: " << event << " , control: " << ctrl_name << LL_ENDL;
+ }
+}
+
+void LLLuaFloater::post(const LLSD &data)
+{
+ // send event data to the script signed with ["reqid"] key
+ LLSD stamped_data(data);
+ mReqID.stamp(stamped_data);
+ LLEventPumps::instance().obtain(mReplyPumpName).post(stamped_data);
+}
+
+void LLLuaFloater::postEvent(LLSD data, const std::string &event_name)
+{
+ llassert(EVENT_LIST.find(event_name) != EVENT_LIST.end());
+ post(data.with("event", event_name));
+}
+
+void LLLuaFloater::showLuaFloater(const LLSD &data)
+{
+ fsyspath fs_path(data["xml_path"].asString());
+ std::string path = fs_path.lexically_normal().u8string();
+ if (!fs_path.is_absolute())
+ {
+ std::string lib_path = gDirUtilp->getExpandedFilename(LL_PATH_SCRIPTS, "lua");
+ path = (fsyspath(lib_path) / path).u8string();
+ }
+
+ LLLuaFloater *floater = new LLLuaFloater(data);
+ floater->buildFromFile(path);
+ floater->openFloater(floater->getKey());
+}
+
+LLSD LLLuaFloater::getEventsData()
+{
+ LLSD event_data;
+ for (auto &it : EVENT_LIST)
+ {
+ event_data.append(it);
+ }
+ return event_data;
+}
diff --git a/indra/llui/llluafloater.h b/indra/llui/llluafloater.h
new file mode 100644
index 0000000000..ccc3ccb39b
--- /dev/null
+++ b/indra/llui/llluafloater.h
@@ -0,0 +1,54 @@
+/**
+ * @file llluafloater.h
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLUAFLOATER_H
+#define LL_LLLUAFLOATER_H
+
+#include "llfloater.h"
+#include "lleventdispatcher.h"
+#include "llevents.h"
+
+class LLLuaFloater : public LLFloater
+{
+public:
+ LLLuaFloater(const LLSD &key);
+ BOOL postBuild();
+ virtual ~LLLuaFloater();
+
+ void registerCallback(const std::string &ctrl_name, const std::string &event);
+ void onClose(bool app_quitting);
+
+ void post(const LLSD &data);
+ void postEvent(LLSD data, const std::string &event);
+ static void showLuaFloater(const LLSD &data);
+ static LLSD getEventsData();
+
+private:
+ LLReqID mReqID;
+ LLDispatchListener mDispatchListener;
+
+ std::string mReplyPumpName;
+};
+#endif
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 72e041672a..baa6e9624d 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -562,16 +562,17 @@ public:
// add a context menu branch
BOOL appendContextSubMenu(LLMenuGL *menu);
- const LLFontGL *getFont() const { return mFont; }
-
- protected:
- void createSpilloverBranch();
- void cleanupSpilloverBranch();
// Add the menu item to this menu.
virtual BOOL append( LLMenuItemGL* item );
// add a menu - this will create a cascading menu
- virtual BOOL appendMenu( LLMenuGL* menu );
+ virtual BOOL appendMenu(LLMenuGL *menu);
+
+ const LLFontGL *getFont() const { return mFont; }
+
+protected:
+ void createSpilloverBranch();
+ void cleanupSpilloverBranch();
// Used in LLContextMenu and in LLTogleableMenu
// to add an item of context menu branch
@@ -810,9 +811,10 @@ public:
void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
-private:
// add a menu - this will create a drop down menu.
- virtual BOOL appendMenu( LLMenuGL* menu );
+ virtual BOOL appendMenu(LLMenuGL *menu);
+
+private:
// rearrange the child rects so they fit the shape of the menu
// bar.
virtual void arrange( void );
@@ -948,16 +950,18 @@ public:
LLUICtrl::EnableCallbackRegistry::currentRegistrar().add(name, boost::bind(&view_listener_t::handleEvent, listener, _2));
}
- static void addCommit(view_listener_t* listener, const std::string& name)
+ typedef LLUICtrl::CommitCallbackInfo cb_info;
+ static void addCommit(view_listener_t *listener, const std::string &name, cb_info::EUntrustedCall handle_untrusted = cb_info::UNTRUSTED_ALLOW)
{
- LLUICtrl::CommitCallbackRegistry::currentRegistrar().add(name, boost::bind(&view_listener_t::handleEvent, listener, _2));
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add(name,
+ cb_info([listener](LLUICtrl*, const LLSD& param){ return listener->handleEvent(param); }, handle_untrusted));
}
- static void addMenu(view_listener_t* listener, const std::string& name)
+ static void addMenu(view_listener_t *listener, const std::string &name, cb_info::EUntrustedCall handle_untrusted = cb_info::UNTRUSTED_ALLOW)
{
// For now, add to both click and enable registries
addEnable(listener, name);
- addCommit(listener, name);
+ addCommit(listener, name, handle_untrusted);
}
static void cleanup()
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 2fbae73b65..7905ff7ce0 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1243,7 +1243,7 @@ LLNotifications::LLNotifications()
mIgnoreAllNotifications(false)
{
mListener.reset(new LLNotificationsListener(*this));
- LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", { boost::bind(&LLNotifications::addFromCallback, this, _2) });
// touch the instance tracker for notification channels, so that it will still be around in our destructor
LLInstanceTracker<LLNotificationChannel, std::string>::instanceCount();
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 7fb732eca3..d32af15f0c 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1991,7 +1991,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
// set up the callbacks for all of the avatar/group menu items
// (N.B. callbacks don't take const refs as id is local scope)
bool is_group = (mContextMenuType == MENU_GROUP);
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ ScopedRegistrarHelper registrar;
registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group));
registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c1eedf93a7..32b28834b2 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2085,7 +2085,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
// set up the callbacks for all of the potential menu items, N.B. we
// don't use const ref strings in callbacks in case url goes out of scope
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ CommitRegistrarHelper registrar(LLUICtrl::CommitCallbackRegistry::currentRegistrar());
registrar.add("Url.Open", boost::bind(&LLUrlAction::openURL, url));
registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url));
registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index e030861f20..5f5f47c45c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1131,7 +1131,7 @@ void LLTextEditor::removeChar()
// Add a single character to the text
S32 LLTextEditor::addChar(S32 pos, llwchar wc)
{
- if ((wstring_utf8_length(getWText()) + wchar_utf8_length(wc)) > mMaxTextByteLength)
+ if ( (wstring_utf8_length( getWText() ) + wchar_utf8_length( wc )) > mMaxTextByteLength)
{
LLUI::getInstance()->reportBadKeystroke();
return 0;
@@ -1161,17 +1161,17 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc)
return delta;
}
- return execute(new TextCmdAddChar(pos, FALSE, wc, LLTextSegmentPtr()));
-}
+ return execute(new TextCmdAddChar(pos, FALSE, wc, LLTextSegmentPtr()));
+ }
void LLTextEditor::addChar(llwchar wc)
{
- if (!getEnabled())
+ if( !getEnabled() )
{
return;
}
- if (hasSelection())
+ if( hasSelection() )
{
deleteSelection(TRUE);
}
@@ -1595,7 +1595,8 @@ void LLTextEditor::cleanStringForPaste(LLWString & clean_string)
}
-void LLTextEditor::pasteTextWithLinebreaks(LLWString & clean_string)
+template <>
+void LLTextEditor::pasteTextWithLinebreaks<LLWString>(const LLWString & clean_string)
{
std::basic_string<llwchar>::size_type start = 0;
std::basic_string<llwchar>::size_type pos = clean_string.find('\n',start);
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index e917f65fbd..0963c83d28 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -34,6 +34,7 @@
#include "llstyle.h"
#include "lleditmenuhandler.h"
#include "llviewborder.h" // for params
+#include "llstring.h"
#include "lltextbase.h"
#include "lltextvalidate.h"
@@ -249,7 +250,9 @@ protected:
// Undoable operations
void addChar(llwchar c); // at mCursorPos
S32 addChar(S32 pos, llwchar wc);
+public:
void addLineBreakChar(BOOL group_together = FALSE);
+protected:
S32 overwriteChar(S32 pos, llwchar wc);
void removeChar();
S32 removeChar(S32 pos);
@@ -303,8 +306,17 @@ private:
//
void pasteHelper(bool is_primary);
void cleanStringForPaste(LLWString & clean_string);
- void pasteTextWithLinebreaks(LLWString & clean_string);
+public:
+ template <typename STRINGTYPE>
+ void pasteTextWithLinebreaks(const STRINGTYPE& clean_string)
+ {
+ pasteTextWithLinebreaks<LLWString>(ll_convert(clean_string));
+ }
+ template <>
+ void pasteTextWithLinebreaks<LLWString>(const LLWString & clean_string);
+
+private:
void onKeyStroke();
// Concrete TextCmd sub-classes used by the LLTextEditor base class
diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp
index 9e27ed6232..10b3be1c23 100644
--- a/indra/llui/lltextvalidate.cpp
+++ b/indra/llui/lltextvalidate.cpp
@@ -31,6 +31,7 @@
#include "lltextvalidate.h"
#include "llnotificationsutil.h"
+#include "lltimer.h"
#include "lltrans.h"
#include "llresmgr.h" // for LLLocale
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 8a6cb683d2..cb9539a573 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -144,7 +144,7 @@ void LLToolBar::createContextMenu()
{
// Setup bindings specific to this instance for the context menu options
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit_reg;
+ CommitRegistrarHelper commit_reg(LLUICtrl::CommitCallbackRegistry::currentRegistrar());
commit_reg.add("Toolbars.EnableSetting", boost::bind(&LLToolBar::onSettingEnable, this, _2));
commit_reg.add("Toolbars.RemoveSelectedCommand", boost::bind(&LLToolBar::onRemoveSelectedCommand, this));
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index c7539fcec7..07a962e515 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -167,8 +167,7 @@ mHelpImpl(NULL)
LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
- LLUICtrl::CommitCallbackRegistry::Registrar& reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar();
-
+ LLUICtrl::CommitRegistrarHelper reg(LLUICtrl::CommitCallbackRegistry::defaultRegistrar());
// Callbacks for associating controls with floater visibility:
reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD()));
reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD()));
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 69093393d9..68d15eb424 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -220,10 +220,10 @@ void LLUICtrl::initFromParams(const Params& p)
}
else
{
- commit_callback_t* initfunc = (CommitCallbackRegistry::getValue(p.init_callback.function_name));
- if (initfunc)
+ LLUICtrl::CommitCallbackInfo *info = (CommitCallbackRegistry::getValue(p.init_callback.function_name));
+ if (info && info->callback_func)
{
- (*initfunc)(this, p.init_callback.parameter);
+ (info->callback_func)(this, p.init_callback.parameter);
}
}
}
@@ -283,13 +283,13 @@ LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCa
{
std::string function_name = cb.function_name;
setFunctionName(function_name);
- commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));
- if (func)
+ LLUICtrl::CommitCallbackInfo *info = (CommitCallbackRegistry::getValue(function_name));
+ if (info && info->callback_func)
{
if (cb.parameter.isProvided())
- return boost::bind((*func), _1, cb.parameter);
+ return boost::bind((info->callback_func), _1, cb.parameter);
else
- return commit_signal_t::slot_type(*func);
+ return commit_signal_t::slot_type(info->callback_func);
}
else if (!function_name.empty())
{
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index d21e8dc1c6..46d651b19c 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -273,11 +273,56 @@ public:
template <typename F, typename DERIVED> class CallbackRegistry : public LLRegistrySingleton<std::string, F, DERIVED >
{};
+ struct CommitCallbackInfo
+ {
+ enum EUntrustedCall
+ {
+ UNTRUSTED_ALLOW,
+ UNTRUSTED_BLOCK,
+ UNTRUSTED_THROTTLE
+ };
+
+ CommitCallbackInfo(commit_callback_t func = {}, EUntrustedCall handle_untrusted = UNTRUSTED_ALLOW) :
+ callback_func(func),
+ handle_untrusted(handle_untrusted)
+ {
+ }
- class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>
+ public:
+ commit_callback_t callback_func;
+ EUntrustedCall handle_untrusted;
+ };
+ typedef LLUICtrl::CommitCallbackInfo cb_info;
+ class CommitCallbackRegistry : public CallbackRegistry<CommitCallbackInfo, CommitCallbackRegistry>
{
LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry);
};
+
+ class CommitRegistrarHelper
+ {
+ public:
+ CommitRegistrarHelper(LLUICtrl::CommitCallbackRegistry::Registrar &registrar) : mRegistrar(registrar) {}
+
+ template <typename... ARGS> void add(const std::string &name, ARGS &&...args)
+ {
+ mRegistrar.add(name, {std::forward<ARGS>(args)...});
+ }
+ private:
+ LLUICtrl::CommitCallbackRegistry::Registrar &mRegistrar;
+ };
+
+ class ScopedRegistrarHelper
+ {
+ public:
+ template <typename... ARGS> void add(const std::string &name, ARGS &&...args)
+ {
+ mRegistrar.add(name, {std::forward<ARGS>(args)...});
+ }
+
+ private:
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar mRegistrar;
+ };
+
// the enable callback registry is also used for visiblity callbacks
class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>
{