From c1ccfaed5ba8c07c8b9e9d28cfca1e6806497ae0 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Wed, 19 Aug 2026 17:07:51 +0300 Subject: #5749 Add LEAP API for Cut, Copy, Paste, and Select All --- indra/newview/llwindowlistener.cpp | 90 ++++++++++++++++++++++++++++++++++++++ indra/newview/llwindowlistener.h | 4 ++ 2 files changed, 94 insertions(+) diff --git a/indra/newview/llwindowlistener.cpp b/indra/newview/llwindowlistener.cpp index 54eb61a6bf..69160bcd6e 100644 --- a/indra/newview/llwindowlistener.cpp +++ b/indra/newview/llwindowlistener.cpp @@ -120,6 +120,22 @@ LLWindowListener::LLWindowListener(LLViewerWindow *window, const KeyboardGetter& "Paste specified [\"text\"] into the current edit field\n" "Optional [\"path\"] specifies target UI element (must be focusable).", &LLWindowListener::pasteText); + add("cut", + "Cut selected content from the focused edit field.\n" + "Optional [\"path\"] specifies target UI element (must be focusable).", + &LLWindowListener::cut); + add("copy", + "Copy selected content from the focused edit field.\n" + "Optional [\"path\"] specifies target UI element (must be focusable).", + &LLWindowListener::copy); + add("paste", + "Paste clipboard contents into the focused edit field.\n" + "Optional [\"path\"] specifies target UI element (must be focusable).", + &LLWindowListener::paste); + add("selectAll", + "Select all content in the focused edit field.\n" + "Optional [\"path\"] specifies target UI element (must be focusable).", + &LLWindowListener::selectAll); } template @@ -657,3 +673,77 @@ void LLWindowListener::pasteText(LLSD const & evt) LLClipboard::instance().reset(); } } + +// Helper: optionally focus a view by path; returns false and sets response error on failure. +static bool focusViewByPath(const LLSD& evt, LLEventAPI::Response& response) +{ + if (!evt.has("path")) + return true; + + std::string path(evt["path"]); + LLView* target_view = LLUI::getInstance()->resolvePath(LLUI::getInstance()->getRootView(), path); + if (!target_view) + { + response.error(STRINGIZE(evt["op"].asString() << " request specified invalid \"path\": " << path)); + return false; + } + if (!target_view->isAvailable()) + { + response.error(STRINGIZE("Target view specified by \"path\": " << path << " is not visible")); + return false; + } + gFocusMgr.setKeyboardFocus(target_view); + return true; +} + +void LLWindowListener::cut(LLSD const & evt) +{ + Response response(LLSD(), evt); + if (!focusViewByPath(evt, response)) + return; + if (!LLEditMenuHandler::gEditMenuHandler) + { + response.error(STRINGIZE(evt["op"].asString() << " request failed: no edit menu handler available")); + return; + } + LLEditMenuHandler::gEditMenuHandler->cut(); +} + +void LLWindowListener::copy(LLSD const & evt) +{ + Response response(LLSD(), evt); + if (!focusViewByPath(evt, response)) + return; + if (!LLEditMenuHandler::gEditMenuHandler) + { + response.error(STRINGIZE(evt["op"].asString() << " request failed: no edit menu handler available")); + return; + } + LLEditMenuHandler::gEditMenuHandler->copy(); +} + +void LLWindowListener::paste(LLSD const & evt) +{ + Response response(LLSD(), evt); + if (!focusViewByPath(evt, response)) + return; + if (!LLEditMenuHandler::gEditMenuHandler) + { + response.error(STRINGIZE(evt["op"].asString() << " request failed: no edit menu handler available")); + return; + } + LLEditMenuHandler::gEditMenuHandler->paste(); +} + +void LLWindowListener::selectAll(LLSD const & evt) +{ + Response response(LLSD(), evt); + if (!focusViewByPath(evt, response)) + return; + if (!LLEditMenuHandler::gEditMenuHandler) + { + response.error(STRINGIZE(evt["op"].asString() << " request failed: no edit menu handler available")); + return; + } + LLEditMenuHandler::gEditMenuHandler->selectAll(); +} diff --git a/indra/newview/llwindowlistener.h b/indra/newview/llwindowlistener.h index 537322b19b..06e4090f6d 100644 --- a/indra/newview/llwindowlistener.h +++ b/indra/newview/llwindowlistener.h @@ -49,6 +49,10 @@ public: void mouseMove(LLSD const & evt); void mouseScroll(LLSD const & evt); void pasteText(LLSD const & evt); + void cut(LLSD const & evt); + void copy(LLSD const & evt); + void paste(LLSD const & evt); + void selectAll(LLSD const & evt); private: LLViewerWindow * mWindow; -- cgit v1.3