diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index 027581078a46df3bf0053b4bbb713a4689166c49..523175dee08bc566c3c5b47506047a33f209cca0 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -52,7 +52,8 @@ typedef enum e_chat_type CHAT_TYPE_DEBUG_MSG = 6, CHAT_TYPE_REGION = 7, CHAT_TYPE_OWNER = 8, - CHAT_TYPE_DIRECT = 9 // From llRegionSayTo() + CHAT_TYPE_DIRECT = 9, // From llRegionSayTo() + CHAT_TYPE_OOC = 64 } EChatType; typedef enum e_chat_audible_level diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h index 3f13691a3051287526707b84aba491c200c4c630..bac309cd8089f25c8b8f6e440a8e125817c74adb 100644 --- a/indra/llui/llchatentry.h +++ b/indra/llui/llchatentry.h @@ -79,11 +79,13 @@ class LLChatEntry : public LLTextEditor */ void expandText(); +public: /** * Implements line history so previous entries can be recalled by CTRL UP/DOWN */ void updateHistory(); +private: BOOL handleSpecialKey(const KEY key, const MASK mask); diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 8833e85772670da55ed1a440193949e8e5cde1b0..0300e14fc950cb4f76bf5f84c4242672e9f7b41a 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -173,6 +173,12 @@ BOOL LLChatBar::handleKeyHere( KEY key, MASK mask ) sendChat(CHAT_TYPE_SHOUT); handled = TRUE; } + else if (mask == MASK_ALT) + { + // shout + sendChat(CHAT_TYPE_OOC); + handled = TRUE; + } else if (mask == MASK_NONE) { // say diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index d543012e83519253e2bfa9f8f0e4892740cd4201..65b8db2bb9b87bda24939fa19806fefa40dc69de 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -508,6 +508,12 @@ BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask ) sendChat(CHAT_TYPE_SHOUT); handled = TRUE; } + else if (KEY_RETURN == key && mask == MASK_ALT) + { + // shout + sendChat(CHAT_TYPE_OOC); + handled = TRUE; + } if((mask == MASK_ALT) && isTornOff()) { @@ -687,7 +693,7 @@ EChatType LLFloaterIMNearbyChat::processChatTypeTriggers(EChatType type, std::st void LLFloaterIMNearbyChat::sendChat( EChatType type ) { - processChatIntern(mInputEditor, type); + processChat(mInputEditor, type, [&](const auto& emojistr) { updateUsedEmojis(emojistr); }); // If the user wants to stop chatting on hitting return, lose focus // and go out of chat mode. diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h index c3db4943abf934ae9108a90cb5b8e7281fc82b50..e4c6f0d42fe5b8469e87b2c2aca5202554a833e0 100644 --- a/indra/newview/llfloaterimnearbychat.h +++ b/indra/newview/llfloaterimnearbychat.h @@ -92,10 +92,7 @@ class LLFloaterIMNearbyChat final static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); template <class T> - void processChatIntern(T* editor, EChatType type); - - template <class T> - static void processChat(T* editor, EChatType type); + static void processChat(T* editor, EChatType type, std::function<void(const LLWString&)> func = nullptr); static bool isWordsName(const std::string& name); @@ -149,7 +146,7 @@ class LLFloaterIMNearbyChat final }; template <class T> -void LLFloaterIMNearbyChat::processChat(T* editor, EChatType type) +void LLFloaterIMNearbyChat::processChat(T* editor, EChatType type, std::function<void(const LLWString&)> emoji_func) { if (editor) { @@ -158,10 +155,11 @@ void LLFloaterIMNearbyChat::processChat(T* editor, EChatType type) LLWStringUtil::replaceChar(text, 182, '\n'); // Convert paragraph symbols back into newlines. if (!text.empty()) { - // Check if this is destined for another channel - S32 channel = 0; - stripChannelNumber(text, &channel); - + if (emoji_func != nullptr) + { + emoji_func(text); + } + else { LLEmojiDictionary* dictionary = LLEmojiDictionary::getInstance(); llassert_always(dictionary); @@ -180,59 +178,17 @@ void LLFloaterIMNearbyChat::processChat(T* editor, EChatType type) LLFloaterEmojiPicker::saveState(); } - std::string utf8text = wstring_to_utf8str(text); - // Try to trigger a gesture, if not chat to a script. - std::string utf8_revised_text; - if (0 == channel) - { - applyOOCClose(utf8text); - applyMUPose(utf8text); - - // discard returned "found" boolean - if (!LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text)) - { - utf8_revised_text = utf8text; - } - } - else - { - utf8_revised_text = utf8text; - } - - utf8_revised_text = utf8str_trim(utf8_revised_text); - - type = processChatTypeTriggers(type, utf8_revised_text); - - if (!utf8_revised_text.empty() && !ALChatCommand::parseCommand(utf8_revised_text)) - { - // Chat with animation - sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayTypingAnim")); - } - } - - editor->setText(LLStringExplicit("")); - } - - gAgent.stopTyping(); -} - -template <class T> -void LLFloaterIMNearbyChat::processChatIntern(T* editor, EChatType type) -{ - if (editor) - { - LLWString text = editor->getWText(); - LLWStringUtil::trim(text); - LLWStringUtil::replaceChar(text, 182, '\n'); // Convert paragraph symbols back into newlines. - if (!text.empty()) - { // Check if this is destined for another channel S32 channel = 0; stripChannelNumber(text, &channel); - updateUsedEmojis(text); - std::string utf8text = wstring_to_utf8str(text); + + if (type == CHAT_TYPE_OOC) + { + utf8text = fmt::format("{} {} {}", gSavedSettings.getString("ChatOOCPrefix"), utf8text, gSavedSettings.getString("ChatOOCPostfix")); + } + // Try to trigger a gesture, if not chat to a script. std::string utf8_revised_text; if (0 == channel) @@ -253,7 +209,8 @@ void LLFloaterIMNearbyChat::processChatIntern(T* editor, EChatType type) utf8_revised_text = utf8str_trim(utf8_revised_text); - type = processChatTypeTriggers(type, utf8_revised_text); + EChatType nType = (type == CHAT_TYPE_OOC ? CHAT_TYPE_NORMAL : type); + type = processChatTypeTriggers(nType, utf8_revised_text); if (!utf8_revised_text.empty() && !ALChatCommand::parseCommand(utf8_revised_text)) { diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 54b41240a16b2e3c8792474d5b9f8b0a9ffc8b37..1b88249332d4ad0eea5ec19d9ee5bf9a4e8845ed 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -306,7 +306,7 @@ void LLFloaterIMSession::onTeleportClicked(const LLUICtrl* pCtrl) } // [/SL:KB] -void LLFloaterIMSession::sendMsgFromInputEditor() +void LLFloaterIMSession::sendMsgFromInputEditor(bool ooc_chat) { if (gAgent.isGodlike() || (mDialog != IM_NOTHING_SPECIAL) @@ -323,6 +323,12 @@ void LLFloaterIMSession::sendMsgFromInputEditor() // Truncate and convert to UTF8 for transport std::string utf8_text = wstring_to_utf8str(text); + + if (ooc_chat) + { + utf8_text = fmt::format("{} {} {}", gSavedSettings.getString("ChatOOCPrefix"), utf8_text, gSavedSettings.getString("ChatOOCPostfix")); + } + applyOOCClose(utf8_text); applyMUPose(utf8_text); sendMsg(utf8_text); @@ -1514,6 +1520,20 @@ void LLFloaterIMSession::onIMChicletCreated( const LLUUID& session_id ) LLFloaterIMSession::addToHost(session_id); } +// virtual +BOOL LLFloaterIMSession::handleKeyHere(KEY key, MASK mask) +{ + BOOL handled = FALSE; + + if (KEY_RETURN == key && mask == MASK_ALT) + { + mInputEditor->updateHistory(); + sendMsgFromInputEditor(true); + handled = TRUE; + } + return handled; +} + boost::signals2::connection LLFloaterIMSession::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb) { return LLFloaterIMSession::sIMFloaterShowedSignal.connect(cb); diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index 6b169206abe037793ed0a826a1f28ed59ae6fa48..e58960d3858cd15077fcc984646aa9783f26daa0 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -97,7 +97,7 @@ class LLFloaterIMSession final /*virtual*/ void updateMessages(); void reloadMessages(bool clean_messages = false); static void onSendMsg(LLUICtrl*, void*); - void sendMsgFromInputEditor(); + void sendMsgFromInputEditor(bool ooc_chat = false); void sendMsg(const std::string& msg); // callback for LLIMModel on new messages @@ -143,6 +143,8 @@ class LLFloaterIMSession final bool needsTitleOverwrite() { return mSessionNameUpdatedForTyping && mOtherTyping; } S32 getLastChatMessageIndex() {return mLastMessageIndex;} + + BOOL handleKeyHere(KEY key, MASK mask) override; private: /*virtual*/ void refresh();