diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index c4ad5e699e..ef3bc2f00b 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -506,6 +506,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou rv = apr_socket_recv(apr_socket, datain, &maxinlen); if (rv != APR_SUCCESS) { + // if rv == 70060 it's WSAETIMEDOUT char buf[MAX_STRING]; LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; ll_apr_warn_status(rv); diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 71f677350a..474edaec04 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -164,7 +164,7 @@ protected: virtual bool isHighlightActive(); virtual bool isFadeItem(); virtual bool isFlashing() { return false; } - virtual void setFlashState(bool) { } + virtual void setFlashState(bool, bool) { } static LLFontGL* getLabelFontForStyle(U8 style); const LLFontGL* getLabelFont(); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 3fced2d56b..e6f068ab95 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -698,6 +698,11 @@ LLUUID LLUrlEntryAgent::getID(const std::string &string) const return LLUUID(getIDStringFromUrl(string)); } +bool LLUrlEntryAgent::isAgentID(const std::string& url) const +{ + return sAgentID == getID(url); +} + std::string LLUrlEntryAgent::getTooltip(const std::string &string) const { // return a tooltip corresponding to the URL type instead of the generic one diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index ff3fae1f2f..b195a3c77c 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -103,6 +103,7 @@ public: virtual bool getSkipProfileIcon(const std::string& string) const { return false; } virtual LLUUID getID(const std::string &string) const { return LLUUID::null; } + virtual bool isAgentID(const std::string& url) const { return false; } bool isLinkDisabled() const; @@ -247,6 +248,8 @@ public: /*virtual*/ LLStyle::Params getStyle(const std::string &url) const; /*virtual*/ LLUUID getID(const std::string &string) const; + bool isAgentID(const std::string& url) const; + LLStyle::EUnderlineLink getUnderline(const std::string& string) const; protected: diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index abbb710925..673d0f5c06 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -417,3 +417,30 @@ void LLUrlRegistry::setKeybindingHandler(LLKeyBindingToStringHandler* handler) LLUrlEntryKeybinding *entry = (LLUrlEntryKeybinding*)mUrlEntryKeybinding; entry->setHandler(handler); } + +bool LLUrlRegistry::containsAgentMention(const std::string& text) +{ + // avoid costly regexes if there is clearly no URL in the text + if (!stringHasUrl(text)) + { + return false; + } + + try + { + boost::sregex_iterator it(text.begin(), text.end(), mUrlEntryAgentMention->getPattern()); + boost::sregex_iterator end; + for (; it != end; ++it) + { + if (mUrlEntryAgentMention->isAgentID(it->str())) + { + return true; + } + } + } + catch (boost::regex_error&) + { + LL_INFOS() << "Regex error for: " << text << LL_ENDL; + } + return false; +} diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index a4aff1ba53..783b9e55cc 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -92,6 +92,8 @@ public: // Set handler for url registry to be capable of parsing and populating keybindings void setKeybindingHandler(LLKeyBindingToStringHandler* handler); + bool containsAgentMention(const std::string& text); + private: std::vector mUrlEntry; LLUrlEntryBase* mUrlEntryTrusted; diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index c05fa101c4..77cad82209 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -88,7 +88,8 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes mHasArrow(true), mIsInActiveVoiceChannel(false), mFlashStateOn(false), - mFlashStarted(false) + mFlashStarted(false), + mIsAltFlashColor(false) { mFlashTimer = new LLFlashTimer(); mAreChildrenInited = true; // inventory only @@ -159,7 +160,7 @@ void LLConversationViewSession::destroyView() LLFolderViewFolder::destroyView(); } -void LLConversationViewSession::setFlashState(bool flash_state) +void LLConversationViewSession::setFlashState(bool flash_state, bool alternate_color) { if (flash_state && !mFlashStateOn) { @@ -172,6 +173,7 @@ void LLConversationViewSession::setFlashState(bool flash_state) mFlashStateOn = flash_state; mFlashStarted = false; + mIsAltFlashColor = mFlashStateOn && (alternate_color || mIsAltFlashColor); mFlashTimer->stopFlashing(); } @@ -290,7 +292,8 @@ void LLConversationViewSession::draw() startFlashing(); // draw highlight for selected items - drawHighlight(show_context, true, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); + static LLUIColor alt_color = LLUIColorTable::instance().getColor("MentionFlashBgColor", DEFAULT_WHITE); + drawHighlight(show_context, true, sHighlightBgColor, mIsAltFlashColor ? alt_color : sFlashBgColor, sFocusOutlineColor, sMouseOverColor); // Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap. bool draw_children = getRoot() == static_cast(this) || isOpen(); diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 77c9ff9c67..903258371f 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -92,7 +92,7 @@ public: virtual void refresh(); - /*virtual*/ void setFlashState(bool flash_state); + /*virtual*/ void setFlashState(bool flash_state, bool alternate_color = false); void setHighlightState(bool hihglight_state); LLFloater* getSessionFloater(); @@ -113,6 +113,7 @@ private: LLFlashTimer* mFlashTimer; bool mFlashStateOn; bool mFlashStarted; + bool mIsAltFlashColor; bool mCollapsedMode; bool mHasArrow; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index b647a50134..81b45f0582 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -2314,14 +2314,14 @@ bool LLFloaterIMContainer::isConversationLoggingAllowed() return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0; } -void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes) +void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes, bool alternate_color) { //Finds the conversation line item to flash using the session_id LLConversationViewSession * widget = dynamic_cast(get_ptr_in_map(mConversationsWidgets,session_id)); if (widget) { - widget->setFlashState(is_flashes); + widget->setFlashState(is_flashes, alternate_color); } } diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 3adc2eb45e..5e81442ab6 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -210,7 +210,7 @@ public: void reSelectConversation(); void updateSpeakBtnState(); static bool isConversationLoggingAllowed(); - void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes); + void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes, bool alternate_color = false); void highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted); bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget); boost::signals2::connection mMicroChangedSignal; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 821c1fa2e2..0d1d4953dd 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -108,6 +108,7 @@ LLFloaterIMSessionTab::~LLFloaterIMSessionTab() { delete mRefreshTimer; LLIMMgr::instance().removeSessionObserver(this); + mEmojiCloseConn.disconnect(); LLFloaterIMContainer* im_container = LLFloaterIMContainer::findInstance(); if (im_container) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 44debf0682..4c88a4b814 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -78,6 +78,7 @@ #include "llviewerregion.h" #include "llcorehttputil.h" #include "lluiusage.h" +#include "llurlregistry.h" // [RLVa:KB] - Checked: 2013-05-10 (RLVa-1.4.9) #include "rlvactions.h" #include "rlvcommon.h" @@ -236,6 +237,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); bool store_dnd_message = false; // flag storage of a dnd message bool is_session_focused = session_floater->isTornOff() && session_floater->hasFocus(); + bool contains_mention = LLUrlRegistry::getInstance()->containsAgentMention(msg["message"].asString()); if (!LLFloater::isVisible(im_box) || im_box->isMinimized()) { conversations_floater_status = CLOSED; @@ -362,7 +364,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) if ("openconversations" == user_preferences || ON_TOP == conversations_floater_status || ("toast" == user_preferences && ON_TOP != conversations_floater_status) - || ("flash" == user_preferences && (CLOSED == conversations_floater_status + || (("flash" == user_preferences || contains_mention) && (CLOSED == conversations_floater_status || NOT_ON_TOP == conversations_floater_status)) || is_dnd_msg) { @@ -382,7 +384,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) } else { - im_box->flashConversationItemWidget(session_id, true); + im_box->flashConversationItemWidget(session_id, true, contains_mention); } } } @@ -3730,7 +3732,7 @@ void LLIMMgr::addMessage( { // LLFloaterReg::showInstance("im_container"); // LLFloaterReg::getTypedInstance("im_container")-> - // flashConversationItemWidget(new_session_id, true); + // flashConversationItemWidget(new_session_id, true, LLUrlRegistry::getInstance()->containsAgentMention(msg)); LLFloaterReg::showInstance("fs_im_container"); // } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 4d5d7f755d..30be63b166 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1147,6 +1147,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } mRadioPbrType->setEnabled(editable); const bool pbr_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR; + const bool media_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_MEDIA; const bool texture_info_selected = pbr_selected && mRadioPbrType->getSelectedIndex() != PBRTYPE_RENDER_MATERIAL_ID; mCheckSyncSettings->setEnabled(editable); @@ -1450,7 +1451,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mShinyScaleU->setValue(spec_scale_s); mBumpyScaleU->setValue(norm_scale_s); - mTexScaleU->setEnabled(editable && has_material); + mTexScaleU->setEnabled(editable && (has_material || media_selected)); // Materials alignment //mShinyScaleU->setEnabled(editable && has_material && specmap_id.notNull()); //mBumpyScaleU->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1495,7 +1496,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool norm_scale_tentative = !identical_norm_scale_t; bool spec_scale_tentative = !identical_spec_scale_t; - mTexScaleV->setEnabled(editable && has_material); + mTexScaleV->setEnabled(editable && (has_material || media_selected)); // Materials alignment //mShinyScaleV->setEnabled(editable && has_material && specmap_id.notNull()); //mBumpyScaleV->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1544,7 +1545,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mShinyOffsetU->setTentative(LLSD(spec_offset_u_tentative)); mBumpyOffsetU->setTentative(LLSD(norm_offset_u_tentative)); - mTexOffsetU->setEnabled(editable && has_material); + mTexOffsetU->setEnabled(editable && (has_material || media_selected)); // Materials alignment //mShinyOffsetU->setEnabled(editable && has_material && specmap_id.notNull()); //mBumpyOffsetU->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1577,7 +1578,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mBumpyOffsetV->setTentative(LLSD(norm_offset_v_tentative)); mShinyOffsetV->setTentative(LLSD(spec_offset_v_tentative)); - mTexOffsetV->setEnabled(editable && has_material); + mTexOffsetV->setEnabled(editable && (has_material || media_selected)); // Materials alignment //mShinyOffsetV->setEnabled(editable && has_material && specmap_id.notNull()); //mBumpyOffsetV->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1607,7 +1608,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; - mTexRotate->setEnabled(editable && has_material); + mTexRotate->setEnabled(editable && (has_material || media_selected)); // Materials alignment //mShinyRotate->setEnabled(editable && has_material && specmap_id.notNull()); //mBumpyRotate->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1729,7 +1730,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mTexRepeat->setValue(editable ? repeats : 1.0f); } mTexRepeat->setTentative(LLSD(repeats_tentative)); - mTexRepeat->setEnabled(has_material && !identical_planar_texgen && enabled); + mTexRepeat->setEnabled(!identical_planar_texgen && enabled && (has_material || media_selected)); // FIRE-11407 - Flip buttons mBtnTexFlipScaleU->setEnabled(enabled); mBtnTexFlipScaleV->setEnabled(enabled); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 2b18372c60..218cf85c4a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3295,36 +3295,43 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch) F32 offset_x = 0; F32 offset_y = 0; - for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + if (te_num < selectNode->mGLTFScaleRatios.size()) { - LLVector3 scale_ratio = selectNode->mGLTFScaleRatios[te_num][i]; + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLVector3 scale_ratio = selectNode->mGLTFScaleRatios[te_num][i]; - if (planar) - { - scale_x = scale_ratio.mV[s_axis] / object_scale.mV[s_axis]; - scale_y = scale_ratio.mV[t_axis] / object_scale.mV[t_axis]; - } - else - { - scale_x = scale_ratio.mV[s_axis] * object_scale.mV[s_axis]; - scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; - } - material->mTextureTransform[i].mScale.set(scale_x, scale_y); + if (planar) + { + scale_x = scale_ratio.mV[s_axis] / object_scale.mV[s_axis]; + scale_y = scale_ratio.mV[t_axis] / object_scale.mV[t_axis]; + } + else + { + scale_x = scale_ratio.mV[s_axis] * object_scale.mV[s_axis]; + scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; + } + material->mTextureTransform[i].mScale.set(scale_x, scale_y); - LLVector2 scales = selectNode->mGLTFScales[te_num][i]; - LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; - F64 int_part = 0; - offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); - if (offset_x < 0) - { - offset_x++; + LLVector2 scales = selectNode->mGLTFScales[te_num][i]; + LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; + F64 int_part = 0; + offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); + if (offset_x < 0) + { + offset_x++; + } + offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); + if (offset_y < 0) + { + offset_y++; + } + material->mTextureTransform[i].mOffset.set(offset_x, offset_y); } - offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); - if (offset_y < 0) - { - offset_y++; - } - material->mTextureTransform[i].mOffset.set(offset_x, offset_y); + } + else + { + llassert(false); // make sure mGLTFScaleRatios is filled } const LLGLTFMaterial* base_material = tep->getGLTFMaterial(); @@ -7202,7 +7209,6 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) if (mObject.notNull()) { - LLVector3 scale = mObject->getScale(); for (U8 i = 0; i < mObject->getNumTEs(); i++) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d76cfec99b..041502bebd 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3347,6 +3347,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) msg_notify["session_id"] = LLUUID(); msg_notify["from_id"] = chat.mFromID; msg_notify["source_type"] = chat.mSourceType; + // used to check if there is agent mention in the message + msg_notify["message"] = mesg; on_new_message(msg_notify); } diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index f836c0b9ab..f1a4af82be 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -1405,4 +1405,7 @@ +