diff options
Diffstat (limited to 'indra')
27 files changed, 1110 insertions, 883 deletions
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 51611d547c..b087205a5c 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1371,7 +1371,7 @@ void LLFloater::setHost(LLMultiFloater* host) mButtonScale = 1.f; //mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE; } - updateTitleButtons(); + if (host) { mHostHandle = host->getHandle(); @@ -1381,6 +1381,8 @@ void LLFloater::setHost(LLMultiFloater* host) { mHostHandle.markDead(); } + + updateTitleButtons(); } void LLFloater::moveResizeHandlesToFront() diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index d32caec5f9..58643868e8 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -177,6 +177,8 @@ public: F32 getVisibleAmount() const; S32 getVisibleDim() const; + bool isCollapsed() const { return mCollapsed;} + void setOrientation(LLLayoutStack::ELayoutOrientation orientation); void storeOriginalDim(); diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index f3a48835b1..540ac74aee 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -468,23 +468,12 @@ BOOL LLMultiFloater::postBuild() void LLMultiFloater::updateResizeLimits() { - static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0); - const LLFloater::Params& default_params = LLFloater::getDefaultParams(); - S32 floater_header_size = default_params.header_height; - S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size; // initialize minimum size constraint to the original xml values. S32 new_min_width = mOrigMinWidth; S32 new_min_height = mOrigMinHeight; - // possibly increase minimum size constraint due to children's minimums. - for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) - { - LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx); - if (floaterp) - { - new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2); - new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height); - } - } + + computeResizeLimits(new_min_width, new_min_height); + setResizeLimits(new_min_width, new_min_height); S32 cur_height = getRect().getHeight(); @@ -510,3 +499,22 @@ void LLMultiFloater::updateResizeLimits() gFloaterView->adjustToFitScreen(this, TRUE); } } + +void LLMultiFloater::computeResizeLimits(S32& new_min_width, S32& new_min_height) +{ + static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0); + const LLFloater::Params& default_params = LLFloater::getDefaultParams(); + S32 floater_header_size = default_params.header_height; + S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size; + + // possibly increase minimum size constraint due to children's minimums. + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx); + if (floaterp) + { + new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2); + new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height); + } + } +} diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index 9fa917eca1..f299ae5dd3 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -93,6 +93,9 @@ protected: LLTabContainer::TabPosition mTabPos; BOOL mAutoResize; S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late + +private: + virtual void computeResizeLimits(S32& new_min_width, S32& new_min_height); }; #endif // LL_MULTI_FLOATER_H diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ee8c15752b..d1fc8bdb7e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2,6 +2,28 @@ <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="llsd.xsd"> <map> + <key>IMShowTime</key> + <map> + <key>Comment</key> + <string>Enable(disable) timestamp showing in the chat.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>IMShowNamesForP2PConv</key> + <map> + <key>Comment</key> + <string>Enable(disable) showing of a names in the chat.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>CrashHostUrl</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 8cdd8ed838..fdc52b7394 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -22,6 +22,61 @@ <key>Value</key> <string>The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.</string> </map> + <key>ConversationsExpandMessagePaneFirst</key> + <map> + <key>Comment</key> + <string>Expand either messages or conversations list pane from Conversations compact mode.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ConversationsListPaneCollapsed</key> + <map> + <key>Comment</key> + <string>Stores the expanded/collapsed state of the conversations list pane in Conversations floater.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ConversationsListPaneWidth</key> + <map> + <key>Comment</key> + <string>Conversations floater list pane width.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>268</integer> + </map> + <key>ConversationsMessagePaneCollapsed</key> + <map> + <key>Comment</key> + <string>Stores the expanded/collapsed state of Conversations floater message pane.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ConversationsMessagePaneWidth</key> + <map> + <key>Comment</key> + <string>Conversations floater message pane width.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>412</integer> + </map> <key>InstantMessageLogPath</key> <map> <key>Comment</key> diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 3da868945b..c514261b60 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -700,9 +700,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL return; } + bool from_me = chat.mFromID == gAgent.getID(); mEditor->setPlainText(use_plain_text_chat_history); - if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty()) + if (!mEditor->scrolledToEnd() && !from_me && !chat.mFromName.empty()) { mUnreadChatSources.insert(chat.mFromName); mMoreChatPanel->setVisible(TRUE); @@ -775,18 +776,28 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL style_params.readonly_color(LLColor4::grey); } + bool prependNewLineState = mEditor->getText().size() != 0; + + // show timestamps and names in the compact mode if (use_plain_text_chat_history) { LLStyle::Params timestamp_style(style_params); + + // timestams showing + if (args["show_time"].asBoolean()) + { if (!message_from_log) { LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor"); timestamp_style.color(timestamp_color); timestamp_style.readonly_color(timestamp_color); } - mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style); + mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style); + prependNewLineState = false; + } - if (utf8str_trim(chat.mFromName).size() != 0) + // names showing + if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0) { // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull()) @@ -803,25 +814,40 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL link_params.is_link = true; link_params.link_href = url; - mEditor->appendText(chat.mFromName + delimiter, - false, link_params); + mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params); + prependNewLineState = false; } else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) { LLStyle::Params link_params(style_params); link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); + if (from_me) + { std::string localized_name; + bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst"); + mEditor->appendText((is_localized? localized_name:"(You)") + delimiter, + prependNewLineState, link_params); + prependNewLineState = false; + } + else + { // Add link to avatar's inspector and delimiter to message. - mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params); + mEditor->appendText(std::string(link_params.link_href) + delimiter, + prependNewLineState, link_params); + prependNewLineState = false; + } } else { - mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, false, style_params); + mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, + prependNewLineState, style_params); + prependNewLineState = false; } } } - else + else // showing timestamp and name in the expanded mode { + prependNewLineState = false; LLView* view = NULL; LLInlineViewSegment::Params p; p.force_newline = true; @@ -901,7 +927,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL //MESSAGE TEXT PROCESSING //*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010) - if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull()) + if (use_plain_text_chat_history && !from_me && chat.mFromID.notNull()) { std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT; if (message.length() > slurl_about.length() && @@ -916,13 +942,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL message = chat.mFromName + message; } - mEditor->appendText(message, FALSE, style_params); + mEditor->appendText(message, prependNewLineState, style_params); + prependNewLineState = false; } mEditor->blockUndo(); // automatically scroll to end when receiving chat from myself - if (chat.mFromID == gAgentID) + if (from_me) { mEditor->setCursorAndScrollToEnd(); } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 1c29323594..3ed575086c 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -423,13 +423,13 @@ void LLFloaterPreference::saveAvatarProperties( void ) BOOL LLFloaterPreference::postBuild() { - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate)); - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate)); - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate)); - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged)); @@ -457,14 +457,11 @@ BOOL LLFloaterPreference::postBuild() void LLFloaterPreference::onBusyResponseChanged() { // set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise - if (LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString()) - { - gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE ); - } - else - { - gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE ); - } + bool busy_flag = + LLTrans::getString("BusyModeResponseDefault") + != getChild<LLUICtrl>("busy_response")->getValue().asString(); + + gSavedPerAccountSettings.setBOOL("BusyResponseChanged", busy_flag ); } LLFloaterPreference::~LLFloaterPreference() diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 724ae3c25e..cd795fcfc7 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -28,6 +28,7 @@ #include "llimfloater.h" +#include "lldraghandle.h" #include "llnotificationsutil.h" #include "llagent.h" @@ -43,6 +44,7 @@ #include "lllayoutstack.h" #include "lllineeditor.h" #include "lllogchat.h" +#include "llnearbychat.h" #include "llpanelimcontrolpanel.h" #include "llscreenchannel.h" #include "llsyswellwindow.h" @@ -50,7 +52,6 @@ #include "llchathistory.h" #include "llnotifications.h" #include "llviewerwindow.h" -#include "llvoicechannel.h" #include "lltransientfloatermgr.h" #include "llinventorymodel.h" #include "llrootview.h" @@ -58,18 +59,21 @@ #include "llviewerchat.h" #include "llnotificationmanager.h" - LLIMFloater::LLIMFloater(const LLUUID& session_id) : LLTransientDockableFloater(NULL, true, session_id), mControlPanel(NULL), mSessionID(session_id), mLastMessageIndex(-1), mDialog(IM_NOTHING_SPECIAL), - mChatHistory(NULL), mInputEditor(NULL), + mCloseBtn(NULL), + mExpandCollapseBtn(NULL), + mTearOffBtn(NULL), mSavedTitle(), mTypingStart(), + mIsP2PChat(false), mShouldSendTypingState(false), + mChatHistory(NULL), mMeTyping(false), mOtherTyping(false), mTypingTimer(), @@ -77,17 +81,16 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) mPositioned(false), mSessionInitialized(false) { - LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionID); - if (im_session) + mSession = LLIMModel::getInstance()->findIMSession(mSessionID); + + if (mSession) { - mSessionInitialized = im_session->mSessionInitialized; + mIsP2PChat = mSession->isP2PSessionType(); + mSessionInitialized = mSession->mSessionInitialized; - mDialog = im_session->mType; - switch(mDialog){ - case IM_NOTHING_SPECIAL: - case IM_SESSION_P2P_INVITE: - mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this); - break; + mDialog = mSession->mType; + switch (mDialog) + { case IM_SESSION_CONFERENCE_START: mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); break; @@ -104,7 +107,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); } break; - default: break; + default: + break; } } setOverlapsScreenChannel(true); @@ -112,6 +116,54 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); setDocked(true); + mCommitCallbackRegistrar.add("IMSession.Menu.Action", + boost::bind(&LLIMFloater::onIMSessionMenuItemClicked, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem", + boost::bind(&LLIMFloater::onIMCompactExpandedMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem", + boost::bind(&LLIMFloater::onIMShowModesMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable", + boost::bind(&LLIMFloater::onIMShowModesMenuItemEnable, this, _2)); +} + +bool LLIMFloater::onIMCompactExpandedMenuItemCheck(const LLSD& userdata) +{ + std::string item = userdata.asString(); + bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory"); + + return is_plain_text_mode? item == "compact_view" : item == "expanded_view"; +} + +bool LLIMFloater::onIMShowModesMenuItemCheck(const LLSD& userdata) +{ + return gSavedSettings.getBOOL(userdata.asString()); +} + +// enable/disable states for the "show time" and "show names" items of the show-modes menu +bool LLIMFloater::onIMShowModesMenuItemEnable(const LLSD& userdata) +{ + std::string item = userdata.asString(); + bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory"); + bool is_not_names = (item != "IMShowNamesForP2PConv"); + return (plain_text && (is_not_names || mIsP2PChat)); +} + +void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata) +{ + std::string item = userdata.asString(); + + if (item == "compact_view" || item == "expanded_view") + { + gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view"); + } + else + { + bool prev_value = gSavedSettings.getBOOL(item); + gSavedSettings.setBOOL(item, !prev_value); + } + + LLIMFloater::processChatHistoryStyleUpdate(); + LLNearbyChat::processChatHistoryStyleUpdate(); } void LLIMFloater::onFocusLost() @@ -133,6 +185,19 @@ void LLIMFloater::onFocusReceived() } } +/*virtual*/ +void LLIMFloater::onOpen(const LLSD& key) +{ + LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost()); + if (host_floater) + { + // Show the messages pane when opening a floater hosted in the Conversations + host_floater->collapseMessagesPane(false); + } + + updateHeaderAndToolbar(); +} + // virtual void LLIMFloater::onClose(bool app_quitting) { @@ -147,8 +212,8 @@ void LLIMFloater::onClose(bool app_quitting) } /* static */ -void LLIMFloater::newIMCallback(const LLSD& data){ - +void LLIMFloater::newIMCallback(const LLSD& data) +{ if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull()) { LLUUID session_id = data["session_id"].asUUID(); @@ -209,8 +274,7 @@ void LLIMFloater::sendMsg() if (mSessionInitialized) { - LLIMModel::sendMessage(utf8_text, mSessionID, - mOtherParticipantUUID,mDialog); + LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog); } else { @@ -225,32 +289,51 @@ void LLIMFloater::sendMsg() } } - - LLIMFloater::~LLIMFloater() { + mVoiceChannelStateChangeConnection.disconnect(); + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); } //virtual BOOL LLIMFloater::postBuild() { - const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID); + const LLUUID& other_party_id = + LLIMModel::getInstance()->getOtherParticipantID(mSessionID); if (other_party_id.notNull()) { mOtherParticipantUUID = other_party_id; } + boundVoiceChannel(); + + mCloseBtn = getChild<LLButton>("close_btn"); + mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this)); + + mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn"); + mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + + if (mControlPanel) + { mControlPanel->setSessionId(mSessionID); mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")); - LLButton* slide_left = getChild<LLButton>("slide_left_btn"); - slide_left->setVisible(mControlPanel->getParent()->getVisible()); - slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + mExpandCollapseBtn->setImageOverlay( + getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon")); + } + else + { + mExpandCollapseBtn->setEnabled(false); + getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false); + } - LLButton* slide_right = getChild<LLButton>("slide_right_btn"); - slide_right->setVisible(!mControlPanel->getParent()->getVisible()); - slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + mTearOffBtn = getChild<LLButton>("tear_off_btn"); + mTearOffBtn->setCommitCallback(boost::bind(&LLIMFloater::onTearOffClicked, this)); mInputEditor = getChild<LLLineEditor>("chat_editor"); mInputEditor->setMaxTextLength(1023); @@ -277,18 +360,16 @@ BOOL LLIMFloater::postBuild() mTypingStart = LLTrans::getString("IM_typing_start_string"); // Disable input editor if session cannot accept text - LLIMModel::LLIMSession* im_session = - LLIMModel::instance().findIMSession(mSessionID); - if( im_session && !im_session->mTextIMPossible ) + if ( mSession && !mSession->mTextIMPossible ) { mInputEditor->setEnabled(FALSE); mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label")); } - if ( im_session && im_session->isP2PSessionType()) + if (mIsP2PChat) { // look up display name for window title - LLAvatarNameCache::get(im_session->mOtherParticipantID, + LLAvatarNameCache::get(mSession->mOtherParticipantID, boost::bind(&LLIMFloater::onAvatarNameCache, this, _1, _2)); } @@ -298,6 +379,10 @@ BOOL LLIMFloater::postBuild() updateSessionName(session_name, session_name); } + childSetAction("voice_call_btn", boost::bind(&LLIMFloater::onCallButtonClicked, this)); + + LLVoiceClient::getInstance()->addObserver(this); + //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" //see LLFloaterIMPanel for how it is done (IB) @@ -311,6 +396,94 @@ BOOL LLIMFloater::postBuild() } } +void LLIMFloater::onTearOffClicked() +{ + onClickTearOff(this); + + updateHeaderAndToolbar(); +} + +void LLIMFloater::boundVoiceChannel() +{ + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + if(voice_channel) + { + mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback( + boost::bind(&LLIMFloater::onVoiceChannelStateChanged, this, _1, _2)); + + //call (either p2p, group or ad-hoc) can be already in started state + updateCallState(voice_channel->getState()); + } +} + +void LLIMFloater::updateCallState(LLVoiceChannel::EState state) +{ + bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED; + getChild<LLButton>("voice_call_btn")->setImageOverlay( + is_call_started? getString("call_btn_stop") : getString("call_btn_start")); + enableDisableCallBtn(); + +} + +void LLIMFloater::enableDisableCallBtn() +{ + bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() + && LLVoiceClient::getInstance()->isVoiceWorking(); + + if (!mSession) + { + getChildView("voice_call_btn")->setEnabled(false); + return; + } + + bool session_initialized = mSession->mSessionInitialized; + bool callback_enabled = mSession->mCallBackEnabled; + + BOOL enable_connect = session_initialized + && voice_enabled + && callback_enabled; + getChildView("voice_call_btn")->setEnabled(enable_connect); +} + + +void LLIMFloater::onCallButtonClicked() +{ + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + if (voice_channel) + { + bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED; + if (is_call_active) + { + gIMMgr->endCall(mSessionID); + } + else + { + gIMMgr->startCall(mSessionID); + } + } +} + +/*void LLIMFloater::onOpenVoiceControlsClicked() +{ + LLFloaterReg::showInstance("voice_controls"); +}*/ + +void LLIMFloater::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) + { + return; + } + + enableDisableCallBtn(); +} + +void LLIMFloater::onVoiceChannelStateChanged( + const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) +{ + updateCallState(new_state); +} + void LLIMFloater::updateSessionName(const std::string& ui_title, const std::string& ui_label) { @@ -343,17 +516,6 @@ void LLIMFloater::draw() LLTransientDockableFloater::draw(); } - -// static -void* LLIMFloater::createPanelIMControl(void* userdata) -{ - LLIMFloater *self = (LLIMFloater*)userdata; - self->mControlPanel = new LLPanelIMControlPanel(); - self->mControlPanel->setXMLFilename("panel_im_control_panel.xml"); - return self->mControlPanel; -} - - // static void* LLIMFloater::createPanelGroupControl(void* userdata) { @@ -374,12 +536,26 @@ void* LLIMFloater::createPanelAdHocControl(void* userdata) void LLIMFloater::onSlide() { - mControlPanel->getParent()->setVisible(!mControlPanel->getParent()->getVisible()); + LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost()); + if (host_floater) + { + // Hide the messages pane if a floater is hosted in the Conversations + host_floater->collapseMessagesPane(true); + } + else ///< floater is torn off + { + if (mControlPanel) + { + bool expand = !mControlPanel->getParent()->getVisible(); - gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getParent()->getVisible()); + // Expand/collapse the IM control panel + mControlPanel->getParent()->setVisible(expand); - getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible()); - getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible()); + gSavedSettings.setBOOL("IMShowControlPanel", expand); + + mExpandCollapseBtn->setImageOverlay(getString(expand ? "collapse_icon" : "expand_icon")); + } + } } //static @@ -387,7 +563,8 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id) { closeHiddenIMToasts(); - if (!gIMMgr->hasSession(session_id)) return NULL; + if (!gIMMgr->hasSession(session_id)) + return NULL; if(!isChatMultiTab()) { @@ -407,7 +584,8 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id) bool exist = findInstance(session_id); LLIMFloater* floater = getInstance(session_id); - if (!floater) return NULL; + if (!floater) + return NULL; if(isChatMultiTab()) { @@ -521,7 +699,8 @@ BOOL LLIMFloater::getVisible() { if(isChatMultiTab()) { - LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); + LLIMFloaterContainer* im_container = + LLIMFloaterContainer::getInstance(); // Treat inactive floater as invisible. bool is_active = im_container->getActiveFloater() == this; @@ -533,7 +712,8 @@ BOOL LLIMFloater::getVisible() } // getVisible() returns TRUE when Tabbed IM window is minimized. - return is_active && !im_container->isMinimized() && im_container->getVisible(); + return is_active && !im_container->isMinimized() + && im_container->getVisible(); } else { @@ -546,7 +726,8 @@ bool LLIMFloater::toggle(const LLUUID& session_id) { if(!isChatMultiTab()) { - LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); + LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>( + "impanel", session_id); if (floater && floater->getVisible() && floater->hasFocus()) { // clicking on chiclet to close floater just hides it to maintain existing @@ -586,52 +767,61 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id) if (mSessionID != im_session_id) { mSessionID = im_session_id; + setKey(im_session_id); + if (mControlPanel) + { mControlPanel->setSessionId(im_session_id); } + boundVoiceChannel(); - // updating "Call" button from group control panel here to enable it without placing into draw() (EXT-4796) - if(gAgent.isInGroup(im_session_id)) - { - mControlPanel->updateCallButton(); + mSession = LLIMModel::getInstance()->findIMSession(mSessionID); + mIsP2PChat = mSession && mSession->isP2PSessionType(); } //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) - //need to send delayed messaged collected while waiting for session initialization - if (!mQueuedMsgsForInit.size()) return; + if (!mQueuedMsgsForInit.size()) + return; LLSD::array_iterator iter; for ( iter = mQueuedMsgsForInit.beginArray(); - iter != mQueuedMsgsForInit.endArray(); - ++iter) + iter != mQueuedMsgsForInit.endArray(); ++iter) { LLIMModel::sendMessage(iter->asString(), mSessionID, mOtherParticipantUUID, mDialog); } } -void LLIMFloater::updateMessages() +void LLIMFloater::appendMessage(const LLChat& chat, const LLSD &args) { - bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory"); + LLChat& tmp_chat = const_cast<LLChat&>(chat); + if (!chat.mMuted) + { + tmp_chat.mFromName = chat.mFromName; + LLSD chat_args; + if (args) chat_args = args; + chat_args["use_plain_text_chat_history"] = + gSavedSettings.getBOOL("PlainTextChatHistory"); + chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); + chat_args["show_names_for_p2p_conv"] = !mIsP2PChat + || gSavedSettings.getBOOL("IMShowNamesForP2PConv"); + + mChatHistory->appendMessage(chat, chat_args); + } +} + +void LLIMFloater::updateMessages() +{ std::list<LLSD> messages; // we shouldn't reset unread message counters if IM floater doesn't have focus - if (hasFocus()) - { - LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1); - } - else - { - LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex+1); - } + LLIMModel::instance().getMessages( + mSessionID, messages, mLastMessageIndex + 1, hasFocus()); if (messages.size()) { - LLSD chat_args; - chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history; - std::ostringstream message; std::list<LLSD>::const_reverse_iterator iter = messages.rbegin(); std::list<LLSD>::const_reverse_iterator iter_end = messages.rend(); @@ -681,7 +871,7 @@ void LLIMFloater::updateMessages() chat.mText = message; } - mChatHistory->appendMessage(chat, chat_args); + appendMessage(chat); mLastMessageIndex = msg["index"].asInteger(); // if it is a notification - next message is a notification history log, so skip it @@ -773,14 +963,16 @@ void LLIMFloater::setTyping(bool typing) if ( mTypingTimer.getElapsedTimeF32() > 1.f ) { // Still typing, send 'start typing' notification - LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE); + LLIMModel::instance().sendTypingState(mSessionID, + mOtherParticipantUUID, TRUE); mShouldSendTypingState = false; } } else { // Send 'stop typing' notification immediately - LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE); + LLIMModel::instance().sendTypingState(mSessionID, + mOtherParticipantUUID, FALSE); mShouldSendTypingState = false; } } @@ -807,7 +999,8 @@ void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing) void LLIMFloater::processAgentListUpdates(const LLSD& body) { - if ( !body.isMap() ) return; + if (!body.isMap()) + return; if ( body.has("agent_updates") && body["agent_updates"].isMap() ) { @@ -834,14 +1027,7 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body) } } -void LLIMFloater::updateChatHistoryStyle() -{ - mChatHistory->clear(); - mLastMessageIndex = -1; - updateMessages(); -} - -void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue) +void LLIMFloater::processChatHistoryStyleUpdate() { LLFontGL* font = LLViewerChat::getChatFont(); LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); @@ -851,11 +1037,10 @@ void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue) LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter); if (floater) { - floater->updateChatHistoryStyle(); + floater->reloadMessages(); floater->mInputEditor->setFont(font); } } - } void LLIMFloater::processSessionUpdate(const LLSD& session_update) @@ -869,7 +1054,8 @@ void LLIMFloater::processSessionUpdate(const LLSD& session_update) if (voice_moderated) { - setTitle(session_label + std::string(" ") + LLTrans::getString("IM_moderated_chat_label")); + setTitle(session_label + std::string(" ") + + LLTrans::getString("IM_moderated_chat_label")); } else { @@ -887,7 +1073,6 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) { - if (mDialog == IM_NOTHING_SPECIAL) { LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop, @@ -971,7 +1156,6 @@ BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop) BOOL LLIMFloater::isInviteAllowed() const { - return ( (IM_SESSION_CONFERENCE_START == mDialog) || (IM_SESSION_INVITE == mDialog) ); } @@ -1023,8 +1207,7 @@ BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids) LLHTTPClient::post( url, data, - new LLSessionInviteResponder( - mSessionID)); + new LLSessionInviteResponder(mSessionID)); } else { @@ -1076,10 +1259,62 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info) speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); } } + } +} + +void LLIMFloater::updateHeaderAndToolbar() +{ + bool is_hosted = getHost() != NULL; + + if (is_hosted) + { + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + if (!mButtons[i]) + { + continue; + } + // Hide the standard header buttons in a docked IM floater. + mButtons[i]->setVisible(false); } } + bool is_control_panel_visible = false; + if (mControlPanel) + { + // Control panel should be visible only in torn off floaters. + is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel"); + mControlPanel->getParent()->setVisible(is_control_panel_visible); + } + + // Display collapse image (<<) if the floater is hosted + // or if it is torn off but has an open control panel. + bool is_expanded = is_hosted || is_control_panel_visible; + mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon")); + + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID); + if (session) + { + // The button (>>) should be disabled for torn off P2P conversations. + mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType()); + } + else + { + llwarns << "IM session not found." << llendl; + } + + if (mDragHandle) + { + // toggle floater's drag handle and title visibility + mDragHandle->setVisible(!is_hosted); + } + + mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon")); + + mCloseBtn->setVisible(is_hosted); +} + // static void LLIMFloater::closeHiddenIMToasts() { @@ -1093,7 +1328,8 @@ void LLIMFloater::closeHiddenIMToasts() } }; - LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel(); + LLNotificationsUI::LLScreenChannel* channel = + LLNotificationsUI::LLChannelManager::getNotificationScreenChannel(); if (channel != NULL) { channel->closeHiddenToasts(IMToastMatcher()); @@ -1135,15 +1371,19 @@ void LLIMFloater::initIMFloater() void LLIMFloater::sRemoveTypingIndicator(const LLSD& data) { LLUUID session_id = data["session_id"]; - if (session_id.isNull()) return; + if (session_id.isNull()) + return; LLUUID from_id = data["from_id"]; - if (gAgentID == from_id || LLUUID::null == from_id) return; + if (gAgentID == from_id || LLUUID::null == from_id) + return; LLIMFloater* floater = LLIMFloater::findInstance(session_id); - if (!floater) return; + if (!floater) + return; - if (IM_NOTHING_SPECIAL != floater->mDialog) return; + if (IM_NOTHING_SPECIAL != floater->mDialog) + return; floater->removeTypingIndicator(); } @@ -1154,9 +1394,11 @@ void LLIMFloater::onIMChicletCreated( const LLUUID& session_id ) if (isChatMultiTab()) { LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); - if (!im_box) return; + if (!im_box) + return; - if (LLIMFloater::findInstance(session_id)) return; + if (LLIMFloater::findInstance(session_id)) + return; LLIMFloater* new_tab = LLIMFloater::getInstance(session_id); @@ -1182,7 +1424,8 @@ void LLIMFloater::onClickCloseBtn() LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); - if (is_call_with_chat && voice_channel != NULL && voice_channel->isActive()) + if (is_call_with_chat && voice_channel != NULL + && voice_channel->isActive()) { LLSD payload; payload["session_id"] = mSessionID; diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index f7cd35b5eb..8e7ab4cc21 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -27,12 +27,16 @@ #ifndef LL_IMFLOATER_H #define LL_IMFLOATER_H +#include "llimview.h" #include "llinstantmessage.h" #include "lllogchat.h" #include "lltooldraganddrop.h" +#include "llvoicechannel.h" +#include "llvoiceclient.h" #include "lltransientdockablefloater.h" class LLAvatarName; +class LLButton; class LLLineEditor; class LLPanelChatControlPanel; class LLChatHistory; @@ -43,14 +47,16 @@ class LLInventoryCategory; * Individual IM window that appears at the bottom of the screen, * optionally "docked" to the bottom tray. */ -class LLIMFloater : public LLTransientDockableFloater +class LLIMFloater + : public LLTransientDockableFloater + , public LLVoiceClientStatusObserver { LOG_CLASS(LLIMFloater); public: LLIMFloater(const LLUUID& session_id); virtual ~LLIMFloater(); - + // LLView overrides /*virtual*/ BOOL postBuild(); /*virtual*/ void setVisible(BOOL visible); @@ -59,6 +65,7 @@ public: /*virtual*/ void draw(); // LLFloater overrides + /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); @@ -78,7 +85,7 @@ public: // get new messages from LLIMModel void updateMessages(); void reloadMessages(); - static void onSendMsg( LLUICtrl*, void*); + static void onSendMsg(LLUICtrl*, void*); void sendMsg(); // callback for LLIMModel on new messages @@ -89,17 +96,26 @@ public: void setPositioned(bool b) { mPositioned = b; }; void onVisibilityChange(const LLSD& new_visibility); + + // Implements LLVoiceClientStatusObserver::onChange() to enable the call + // button when voice is available + void onChange(EStatusType status, const std::string &channelURI, + bool proximal); + + virtual void onVoiceChannelStateChanged( + const LLVoiceChannel::EState& old_state, + const LLVoiceChannel::EState& new_state); + void processIMTyping(const LLIMInfo* im_info, BOOL typing); void processAgentListUpdates(const LLSD& body); void processSessionUpdate(const LLSD& session_update); - void updateChatHistoryStyle(); - static void processChatHistoryStyleUpdate(const LLSD& newvalue); + static void processChatHistoryStyleUpdate(); BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, - void *cargo_data, EAcceptance *accept, - std::string& tooltip_msg); + BOOL drop, EDragAndDropType cargo_type, + void *cargo_data, EAcceptance *accept, + std::string& tooltip_msg); /** * Returns true if chat is displayed in multi tabbed floater @@ -117,8 +133,7 @@ public: virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } protected: - /* virtual */ - void onClickCloseBtn(); + /* virtual */ void onClickCloseBtn(); private: // process focus events to set a currently active session @@ -127,24 +142,37 @@ private: // Update the window title, input field help text, etc. void updateSessionName(const std::string& ui_title, const std::string& ui_label); - + // For display name lookups for IM window titles void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - + BOOL dropCallingCard(LLInventoryItem* item, BOOL drop); BOOL dropCategory(LLInventoryCategory* category, BOOL drop); BOOL isInviteAllowed() const; BOOL inviteToSession(const uuid_vec_t& agent_ids); - - static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); - static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); - static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); - void setTyping(bool typing); - void onSlide(); - static void* createPanelIMControl(void* userdata); - static void* createPanelGroupControl(void* userdata); - static void* createPanelAdHocControl(void* userdata); + void appendMessage(const LLChat& chat, const LLSD &args = 0); + static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata ); + static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); + static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); + void setTyping(bool typing); + void onSlide(); + static void* createPanelGroupControl(void* userdata); + static void* createPanelAdHocControl(void* userdata); + + void onTearOffClicked(); + + bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata); + bool onIMShowModesMenuItemCheck(const LLSD& userdata); + bool onIMShowModesMenuItemEnable(const LLSD& userdata); + void onIMSessionMenuItemClicked(const LLSD& userdata); + void onCallButtonClicked(); + + void boundVoiceChannel(); + void enableDisableCallBtn(); + + // refresh a visual state of the Call button + void updateCallState(LLVoiceChannel::EState state); // Add the "User is typing..." indicator. void addTypingIndicator(const LLIMInfo* im_info); @@ -152,17 +180,22 @@ private: // Remove the "User is typing..." indicator. void removeTypingIndicator(const LLIMInfo* im_info = NULL); + /// Update floater header and toolbar buttons when hosted/torn off state is toggled. + void updateHeaderAndToolbar(); + static void closeHiddenIMToasts(); static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response); LLPanelChatControlPanel* mControlPanel; LLUUID mSessionID; + LLIMModel::LLIMSession* mSession; S32 mLastMessageIndex; + LLChatHistory* mChatHistory; + EInstantMessage mDialog; LLUUID mOtherParticipantUUID; - LLChatHistory* mChatHistory; LLLineEditor* mInputEditor; bool mPositioned; @@ -171,12 +204,19 @@ private: bool mMeTyping; bool mOtherTyping; bool mShouldSendTypingState; + bool mIsP2PChat; LLFrameTimer mTypingTimer; LLFrameTimer mTypingTimeoutTimer; bool mSessionInitialized; LLSD mQueuedMsgsForInit; -}; + // connection to voice channel state change signal + boost::signals2::connection mVoiceChannelStateChangeConnection; + + LLButton* mCloseBtn; + LLButton* mExpandCollapseBtn; + LLButton* mTearOffBtn; +}; #endif // LL_IMFLOATER_H diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index c8e48b0d42..b051440589 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -28,18 +28,23 @@ #include "llviewerprecompiledheaders.h" #include "llimfloatercontainer.h" + #include "llfloaterreg.h" -#include "llimview.h" +#include "lllayoutstack.h" + +#include "llagent.h" #include "llavatariconctrl.h" #include "llgroupiconctrl.h" -#include "llagent.h" +#include "llimview.h" #include "lltransientfloatermgr.h" +#include "llviewercontrol.h" // // LLIMFloaterContainer // LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed) : LLMultiFloater(seed) + ,mExpandCollapseBtn(NULL) { mAutoResize = FALSE; LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); @@ -49,6 +54,9 @@ LLIMFloaterContainer::~LLIMFloaterContainer() { mNewMessageConnection.disconnect(); LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); + + gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed()); + gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed()); } BOOL LLIMFloaterContainer::postBuild() @@ -56,6 +64,19 @@ BOOL LLIMFloaterContainer::postBuild() mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1)); // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button // mTabContainer will be initialized in LLMultiFloater::addChild() + + setTabContainer(getChild<LLTabContainer>("im_box_tab_container")); + + mConversationsStack = getChild<LLLayoutStack>("conversations_stack"); + mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel"); + mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel"); + + mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn"); + mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this)); + + collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed")); + collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed")); + return TRUE; } @@ -74,6 +95,7 @@ void LLIMFloaterContainer::onOpen(const LLSD& key) */ } +// virtual void LLIMFloaterContainer::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point) @@ -89,6 +111,12 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); + LLView* floater_contents = floaterp->getChild<LLView>("contents_view"); + + // we don't show the header when the floater is hosted, + // so reshape floater contents to occupy the header space + floater_contents->setShape(floaterp->getRect()); + LLUUID session_id = floaterp->getKey(); LLIconCtrl* icon = 0; @@ -116,11 +144,56 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, mTabContainer->setTabImage(floaterp, icon); } +// virtual +void LLIMFloaterContainer::removeFloater(LLFloater* floaterp) +{ + LLMultiFloater::removeFloater(floaterp); + + LLRect contents_rect = floaterp->getRect(); + + // reduce the floater contents height by header height + contents_rect.mTop -= floaterp->getHeaderHeight(); + + LLView* floater_contents = floaterp->getChild<LLView>("contents_view"); + floater_contents->setShape(contents_rect); +} + void LLIMFloaterContainer::onCloseFloater(LLUUID& id) { mSessions.erase(id); } +// virtual +void LLIMFloaterContainer::computeResizeLimits(S32& new_min_width, S32& new_min_height) +{ + bool is_left_pane_expanded = !mConversationsPane->isCollapsed(); + bool is_right_pane_expanded = !mMessagesPane->isCollapsed(); + + S32 conversations_pane_min_dim = mConversationsPane->getMinDim(); + + if (is_right_pane_expanded) + { + S32 conversations_pane_width = + (is_left_pane_expanded ? gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") : conversations_pane_min_dim); + + // possibly increase minimum size constraint due to children's minimums. + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx)); + if (floaterp) + { + new_min_width = llmax(new_min_width, + floaterp->getMinWidth() + conversations_pane_width + LLPANEL_BORDER_WIDTH * 2); + new_min_height = llmax(new_min_height, floaterp->getMinHeight()); + } + } + } + else + { + new_min_width = conversations_pane_min_dim; + } +} + void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data) { LLUUID session_id = data["session_id"].asUUID(); @@ -135,6 +208,21 @@ void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data) } } +void LLIMFloaterContainer::onExpandCollapseButtonClicked() +{ + if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed() + && gSavedPerAccountSettings.getBOOL("ConversationsExpandMessagePaneFirst")) + { + // Expand the messages pane from ultra minimized state + // if it was collapsed last in order. + collapseMessagesPane(false); + } + else + { + collapseConversationsPane(!mConversationsPane->isCollapsed()); + } +} + LLIMFloaterContainer* LLIMFloaterContainer::findInstance() { return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container"); @@ -161,4 +249,67 @@ void LLIMFloaterContainer::setMinimized(BOOL b) } } +void LLIMFloaterContainer::collapseMessagesPane(bool collapse) +{ + if (mMessagesPane->isCollapsed() == collapse) + { + return; + } + + if (collapse) + { + // Save the messages pane width before collapsing it. + gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", mMessagesPane->getRect().getWidth()); + + // Save the order in which the panels are closed to reverse user's last action. + gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed()); + } + + // Show/hide the messages pane. + mConversationsStack->collapsePanel(mMessagesPane, collapse); + + updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth")); +} + +void LLIMFloaterContainer::collapseConversationsPane(bool collapse) +{ + if (mConversationsPane->isCollapsed() == collapse) + { + return; + } + + LLView* button_panel = getChild<LLView>("conversations_pane_buttons_expanded"); + button_panel->setVisible(!collapse); + mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon")); + + if (collapse) + { + // Save the conversations pane width before collapsing it. + gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", mConversationsPane->getRect().getWidth()); + + // Save the order in which the panels are closed to reverse user's last action. + gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed()); + } + + mConversationsStack->collapsePanel(mConversationsPane, collapse); + + S32 collapsed_width = mConversationsPane->getMinDim(); + updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - collapsed_width); +} + +void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width) +{ + LLRect floater_rect = getRect(); + floater_rect.mRight += ((collapse ? -1 : 1) * delta_width); + setShape(floater_rect); + + updateResizeLimits(); + + bool is_left_pane_expanded = !mConversationsPane->isCollapsed(); + bool is_right_pane_expanded = !mMessagesPane->isCollapsed(); + + setCanResize(is_left_pane_expanded || is_right_pane_expanded); + setCanMinimize(is_left_pane_expanded || is_right_pane_expanded); +} + // EOF diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index 892ecef48d..92938ff405 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -35,6 +35,9 @@ #include "llavatarpropertiesprocessor.h" #include "llgroupmgr.h" +class LLButton; +class LLLayoutPanel; +class LLLayoutStack; class LLTabContainer; class LLIMFloaterContainer : public LLMultiFloater @@ -50,6 +53,7 @@ public: /*virtual*/ void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); + /*virtual*/ void removeFloater(LLFloater* floaterp); static LLFloater* getCurrentVoiceFloater(); @@ -59,12 +63,27 @@ public: virtual void setMinimized(BOOL b); + void collapseMessagesPane(bool collapse); + private: typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t; avatarID_panel_map_t mSessions; boost::signals2::connection mNewMessageConnection; + /*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height); + void onNewMessageReceived(const LLSD& data); + + void onExpandCollapseButtonClicked(); + + void collapseConversationsPane(bool collapse); + + void updateState(bool collapse, S32 delta_width); + + LLButton* mExpandCollapseBtn; + LLLayoutPanel* mMessagesPane; + LLLayoutPanel* mConversationsPane; + LLLayoutStack* mConversationsStack; }; #endif // LL_LLIMFLOATERCONTAINER_H diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index a7c4618fa4..18d39b7aa4 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -716,6 +716,16 @@ bool LLIMModel::clearSession(const LLUUID& session_id) return true; } +void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index, const bool sendNoUnreadMsgs) +{ + getMessagesSilently(session_id, messages, start_index); + + if (sendNoUnreadMsgs) + { + sendNoUnreadMessages(session_id); + } +} + void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index) { LLIMSession* session = findIMSession(session_id); @@ -757,13 +767,6 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id) mNoUnreadMsgsSignal(arg); } -void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index) -{ - getMessagesSilently(session_id, messages, start_index); - - sendNoUnreadMessages(session_id); -} - bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { LLIMSession* session = findIMSession(session_id); @@ -2497,6 +2500,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString()); } // log message to file + else { std::string session_name; diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 7c2cd03d97..9d19af4b62 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -192,12 +192,6 @@ public: bool clearSession(const LLUUID& session_id); /** - * Populate supplied std::list with messages starting from index specified by start_index without - * emitting no unread messages signal. - */ - void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0); - - /** * Sends no unread messages signal. */ void sendNoUnreadMessages(const LLUUID& session_id); @@ -205,7 +199,7 @@ public: /** * Populate supplied std::list with messages starting from index specified by start_index */ - void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0); + void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0, const bool sendNoUnreadMsgs = true); /** * Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id @@ -288,6 +282,12 @@ public: private: /** + * Populate supplied std::list with messages starting from index specified by start_index without + * emitting no unread messages signal. + */ + void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0); + + /** * Add message to a list of message associated with session specified by session_id */ bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index a7303ad035..3c4b0b9aae 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -25,7 +25,6 @@ */ #include "llviewerprecompiledheaders.h" - #include "llnearbychat.h" #include "llviewercontrol.h" #include "llviewerwindow.h" @@ -55,8 +54,42 @@ #include "llfloaterreg.h" #include "lltrans.h" -static const S32 RESIZE_BAR_THICKNESS = 3; +// --- 2 functions in the global namespace :( --- +bool isWordsName(const std::string& name) +{ + // checking to see if it's display name plus username in parentheses + S32 open_paren = name.find(" (", 0); + S32 close_paren = name.find(')', 0); + + if (open_paren != std::string::npos && + close_paren == name.length()-1) + { + return true; + } + else + { + //checking for a single space + S32 pos = name.find(' ', 0); + return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos; + } +} + +std::string appendTime() +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"]"; + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + return timeStr; +} + +static const S32 RESIZE_BAR_THICKNESS = 3; static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat"); @@ -90,38 +123,32 @@ BOOL LLNearbyChat::postBuild() return true; } -std::string appendTime() -{ - time_t utc_time; - utc_time = time_corrected(); - std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" - +LLTrans::getString("TimeMin")+"]"; - - LLSD substitution; - - substitution["datetime"] = (S32) utc_time; - LLStringUtil::format (timeStr, substitution); - - return timeStr; -} - -void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) +void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args) { LLChat& tmp_chat = const_cast<LLChat&>(chat); if(tmp_chat.mTimeStr.empty()) tmp_chat.mTimeStr = appendTime(); - bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory"); - if (!chat.mMuted) { tmp_chat.mFromName = chat.mFromName; - LLSD chat_args = args; - chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history; + LLSD chat_args; + if (args) chat_args = args; + chat_args["use_plain_text_chat_history"] = + gSavedSettings.getBOOL("PlainTextChatHistory"); + chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); + chat_args["show_names_for_p2p_conv"] = false + || gSavedSettings.getBOOL("IMShowNamesForP2PConv"); + mChatHistory->appendMessage(chat, chat_args); } +} + +void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) +{ + appendMessage(chat, args); if(archive) { @@ -130,12 +157,9 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) mMessageArchive.erase(mMessageArchive.begin()); } - if (args["do_not_log"].asBoolean()) - { - return; - } - - if (gSavedPerAccountSettings.getBOOL("LogNearbyChat")) + // logging + if (!args["do_not_log"].asBoolean() + && gSavedPerAccountSettings.getBOOL("LogNearbyChat")) { std::string from_name = chat.mFromName; @@ -162,10 +186,10 @@ void LLNearbyChat::onNearbySpeakers() LLFloaterSidePanelContainer::showPanel("people", "panel_people", param); } - void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata) { } + bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata) { std::string str = userdata.asString(); @@ -213,7 +237,7 @@ void LLNearbyChat::updateChatHistoryStyle() } //static -void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue) +void LLNearbyChat::processChatHistoryStyleUpdate() { LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat"); @@ -221,25 +245,6 @@ void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue) nearby_chat->updateChatHistoryStyle(); } -bool isWordsName(const std::string& name) -{ - // checking to see if it's display name plus username in parentheses - S32 open_paren = name.find(" (", 0); - S32 close_paren = name.find(')', 0); - - if (open_paren != std::string::npos && - close_paren == name.length()-1) - { - return true; - } - else - { - //checking for a single space - S32 pos = name.find(' ', 0); - return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos; - } -} - void LLNearbyChat::loadHistory() { LLSD do_not_log; diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 7c5975cbc5..47f4de1c6d 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -34,7 +34,8 @@ class LLResizeBar; class LLChatHistory; -class LLNearbyChat: public LLPanel +class LLNearbyChat +: public LLPanel { public: LLNearbyChat(const Params& p = LLPanel::getDefaultParams()); @@ -57,7 +58,7 @@ public: virtual void updateChatHistoryStyle(); - static void processChatHistoryStyleUpdate(const LLSD& newvalue); + static void processChatHistoryStyleUpdate(); void loadHistory(); @@ -67,7 +68,8 @@ public: private: void getAllowedRect (LLRect& rect); - + // prepare chat's params and out one message to chatHistory + void appendMessage(const LLChat& chat, const LLSD &args = 0); void onNearbySpeakers (); diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index eda0749cdb..bc4097cd93 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -1,31 +1,30 @@ -/** +/** * @file llpanelavatar.cpp * @brief LLPanelAvatar and related class implementations * * $LicenseInfo:firstyear=2004&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$ */ #include "llviewerprecompiledheaders.h" - #include "llfloaterreg.h" #include "llpanelimcontrolpanel.h" @@ -39,92 +38,15 @@ #include "llavatarlist.h" #include "llparticipantlist.h" #include "llimview.h" -#include "llvoicechannel.h" #include "llspeakers.h" #include "lltrans.h" -void LLPanelChatControlPanel::onCallButtonClicked() -{ - gIMMgr->startCall(mSessionId); -} - -void LLPanelChatControlPanel::onEndCallButtonClicked() -{ - gIMMgr->endCall(mSessionId); -} - -void LLPanelChatControlPanel::onOpenVoiceControlsClicked() -{ - LLFloaterReg::showInstance("voice_controls"); -} - -void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal) -{ - if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) - { - return; - } - - updateCallButton(); -} - -void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) -{ - updateButtons(new_state); -} - -void LLPanelChatControlPanel::updateCallButton() -{ - // hide/show call button - bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); - - LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId); - - if (!session) - { - getChildView("call_btn")->setEnabled(false); - return; - } - - bool session_initialized = session->mSessionInitialized; - bool callback_enabled = session->mCallBackEnabled; - - BOOL enable_connect = session_initialized - && voice_enabled - && callback_enabled; - getChildView("call_btn")->setEnabled(enable_connect); -} - -void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state) -{ - bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED; - getChildView("end_call_btn_panel")->setVisible( is_call_started); - getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel")); - getChildView("call_btn_panel")->setVisible( ! is_call_started); - - getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED); - - updateCallButton(); - -} - LLPanelChatControlPanel::~LLPanelChatControlPanel() { - mVoiceChannelStateChangeConnection.disconnect(); - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver(this); - } } BOOL LLPanelChatControlPanel::postBuild() { - childSetAction("call_btn", boost::bind(&LLPanelChatControlPanel::onCallButtonClicked, this)); - childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this)); - childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this)); - - LLVoiceClient::getInstance()->addObserver(this); - return TRUE; } @@ -132,224 +54,8 @@ void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id) { //Method is called twice for AdHoc and Group chat. Second time when server init reply received mSessionId = session_id; - LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionId); - if(voice_channel) - { - mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2)); - - //call (either p2p, group or ad-hoc) can be already in started state - updateButtons(voice_channel->getState()); - } -} - -LLPanelIMControlPanel::LLPanelIMControlPanel() -{ -} - -LLPanelIMControlPanel::~LLPanelIMControlPanel() -{ - LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); -} - -BOOL LLPanelIMControlPanel::postBuild() -{ - childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this)); - childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this)); - - childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this)); - childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this)); - childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this)); - - childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this)); - childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this)); - childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this)); - - getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2)); - - getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId())); - - setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this)); - - return LLPanelChatControlPanel::postBuild(); -} - -void LLPanelIMControlPanel::draw() -{ - bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID); - - getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted); - getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted); - - if (getChildView("volume_ctrl_panel")->getVisible()) - { - - bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat); - - LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); - mute_btn->setValue( is_muted_voice ); - - LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider"); - volume_slider->setEnabled( !is_muted_voice ); - - F32 volume; - - if (is_muted_voice) - { - // it's clearer to display their volume as zero - volume = 0.f; - } - else - { - // actual volume - volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID); - } - volume_slider->setValue( (F64)volume ); - } - - LLPanelChatControlPanel::draw(); } -void LLPanelIMControlPanel::onClickMuteVolume() -{ - // By convention, we only display and toggle voice mutes, not all mutes - LLMuteList* mute_list = LLMuteList::getInstance(); - bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); - - LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); - if (!is_muted) - { - mute_list->add(mute, LLMute::flagVoiceChat); - } - else - { - mute_list->remove(mute, LLMute::flagVoiceChat); - } -} - -void LLPanelIMControlPanel::onClickBlock() -{ - LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); - - LLMuteList::getInstance()->add(mute); -} - -void LLPanelIMControlPanel::onClickUnblock() -{ - LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); - - LLMuteList::getInstance()->remove(mute); -} - -void LLPanelIMControlPanel::onVolumeChange(const LLSD& data) -{ - F32 volume = (F32)data.asReal(); - LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); -} - -void LLPanelIMControlPanel::onTeleportButtonClicked() -{ - LLAvatarActions::offerTeleport(mAvatarID); -} -void LLPanelIMControlPanel::onPayButtonClicked() -{ - LLAvatarActions::pay(mAvatarID); -} - -void LLPanelIMControlPanel::onViewProfileButtonClicked() -{ - LLAvatarActions::showProfile(mAvatarID); -} - -void LLPanelIMControlPanel::onAddFriendButtonClicked() -{ - LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon"); - std::string full_name = avatar_icon->getFullName(); - LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name); -} - -void LLPanelIMControlPanel::onShareButtonClicked() -{ - LLAvatarActions::share(mAvatarID); -} - -void LLPanelIMControlPanel::onFocusReceived() -{ - // Disable all the buttons (Call, Teleport, etc) if disconnected. - if (gDisconnected) - { - setAllChildrenEnabled(FALSE); - } -} - -void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id) -{ - LLPanelChatControlPanel::setSessionId(session_id); - - LLIMModel& im_model = LLIMModel::instance(); - - LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); - mAvatarID = im_model.getOtherParticipantID(session_id); - LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this); - - // Disable "Add friend" button for friends. - getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID)); - - // Disable "Teleport" button if friend is offline - if(LLAvatarActions::isFriend(mAvatarID)) - { - getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID)); - } - - getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID); - - // Disable most profile buttons if the participant is - // not really an SL avatar (e.g., an Avaline caller). - LLIMModel::LLIMSession* im_session = - im_model.findIMSession(session_id); - if( im_session && !im_session->mOtherParticipantIsAvatar ) - { - getChildView("view_profile_btn")->setEnabled(FALSE); - getChildView("add_friend_btn")->setEnabled(FALSE); - - getChildView("share_btn")->setEnabled(FALSE); - getChildView("teleport_btn")->setEnabled(FALSE); - getChildView("pay_btn")->setEnabled(FALSE); - - getChild<LLTextBox>("avatar_name")->setValue(im_session->mName); - getChild<LLTextBox>("avatar_name")->setToolTip(im_session->mName); - } - else - { - // If the participant is an avatar, fetch the currect name - gCacheName->get(mAvatarID, false, - boost::bind(&LLPanelIMControlPanel::onNameCache, this, _1, _2, _3)); - } -} - -//virtual -void LLPanelIMControlPanel::changed(U32 mask) -{ - getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID)); - - // Disable "Teleport" button if friend is offline - if(LLAvatarActions::isFriend(mAvatarID)) - { - getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID)); - } -} - -void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group) -{ - if ( id == mAvatarID ) - { - std::string avatar_name = full_name; - getChild<LLTextBox>("avatar_name")->setValue(avatar_name); - getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name); - - bool is_linden = LLStringUtil::endsWith(full_name, " Linden"); - getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden); - } -} LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id): mParticipantList(NULL) @@ -358,7 +64,6 @@ mParticipantList(NULL) BOOL LLPanelGroupControlPanel::postBuild() { - childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this)); return LLPanelChatControlPanel::postBuild(); } @@ -378,10 +83,6 @@ void LLPanelGroupControlPanel::draw() LLPanelChatControlPanel::draw(); } -void LLPanelGroupControlPanel::onGroupInfoButtonClicked() -{ - LLGroupActions::show(mGroupID); -} void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata) { @@ -398,23 +99,17 @@ void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata) } -void LLPanelGroupControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) -{ - LLPanelChatControlPanel::onVoiceChannelStateChanged(old_state, new_state); - mParticipantList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED); -} - void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id) { LLPanelChatControlPanel::setSessionId(session_id); mGroupID = session_id; - // for group and Ad-hoc chat we need to include agent into list + // for group and Ad-hoc chat we need to include agent into list if(!mParticipantList) { LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id); - mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false); + mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false); } } @@ -428,4 +123,3 @@ BOOL LLPanelAdHocControlPanel::postBuild() //We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat return LLPanelChatControlPanel::postBuild(); } - diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index bba847b5d4..02915ec4bb 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -28,14 +28,12 @@ #define LL_LLPANELIMCONTROLPANEL_H #include "llpanel.h" -#include "llvoicechannel.h" #include "llcallingcard.h" class LLParticipantList; -class LLPanelChatControlPanel +class LLPanelChatControlPanel : public LLPanel - , public LLVoiceClientStatusObserver { public: LLPanelChatControlPanel() : @@ -44,21 +42,6 @@ public: virtual BOOL postBuild(); - void onCallButtonClicked(); - void onEndCallButtonClicked(); - void onOpenVoiceControlsClicked(); - - // Implements LLVoiceClientStatusObserver::onChange() to enable the call - // button when voice is available - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - - virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); - - void updateButtons(LLVoiceChannel::EState state); - - // Enables/disables call button depending on voice availability - void updateCallButton(); - virtual void setSessionId(const LLUUID& session_id); const LLUUID& getSessionId() { return mSessionId; } @@ -69,41 +52,6 @@ private: boost::signals2::connection mVoiceChannelStateChangeConnection; }; - -class LLPanelIMControlPanel : public LLPanelChatControlPanel, LLFriendObserver -{ -public: - LLPanelIMControlPanel(); - ~LLPanelIMControlPanel(); - - BOOL postBuild(); - - void setSessionId(const LLUUID& session_id); - - // LLFriendObserver trigger - virtual void changed(U32 mask); - -protected: - void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group); - -private: - void onViewProfileButtonClicked(); - void onAddFriendButtonClicked(); - void onShareButtonClicked(); - void onTeleportButtonClicked(); - void onPayButtonClicked(); - void onFocusReceived(); - - void onClickMuteVolume(); - void onClickBlock(); - void onClickUnblock(); - /*virtual*/ void draw(); - void onVolumeChange(const LLSD& data); - - LLUUID mAvatarID; -}; - - class LLPanelGroupControlPanel : public LLPanelChatControlPanel { public: @@ -121,9 +69,7 @@ protected: LLParticipantList* mParticipantList; private: - void onGroupInfoButtonClicked(); void onSortMenuItemClicked(const LLSD& userdata); - /*virtual*/ void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); }; class LLPanelAdHocControlPanel : public LLPanelGroupControlPanel diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index 0d66b8f10b..c84790d839 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -51,6 +51,7 @@ LLContextMenu* NearbyMenu::createMenu() // set up the callbacks for all of the avatar menu items LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + LLContextMenu* menu; if ( mUUIDs.size() == 1 ) { @@ -73,7 +74,7 @@ LLContextMenu* NearbyMenu::createMenu() enable_registrar.add("Avatar.CheckItem", boost::bind(&NearbyMenu::checkContextMenuItem, this, _2)); // create the context menu from the XUI - return createFromFile("menu_people_nearby.xml"); + menu = createFromFile("menu_people_nearby.xml"); } else { @@ -89,8 +90,10 @@ LLContextMenu* NearbyMenu::createMenu() enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2)); // create the context menu from the XUI - return createFromFile("menu_people_nearby_multiselect.xml"); + menu = createFromFile("menu_people_nearby_multiselect.xml"); } + + return menu; } bool NearbyMenu::enableContextMenuItem(const LLSD& userdata) diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 975a6c67d8..59d26edff2 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -32,6 +32,7 @@ #include "llagent.h" #include "llimview.h" +#include "llpanelpeoplemenus.h" #include "llnotificationsutil.h" #include "llparticipantlist.h" #include "llspeakers.h" @@ -197,10 +198,10 @@ private: uuid_set_t mAvalineCallers; }; -LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, +LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu/* = true*/, - bool exclude_agent /*= true*/, + bool exclude_agent /*= true*/, bool can_toggle_icons /*= true*/) : mSpeakerMgr(data_source), mAvatarList(avatar_list), @@ -233,8 +234,9 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, if (use_context_menu) { - mParticipantListMenu = new LLParticipantListMenu(*this); - mAvatarList->setContextMenu(mParticipantListMenu); + //mParticipantListMenu = new LLParticipantListMenu(*this); + //mAvatarList->setContextMenu(mParticipantListMenu); + mAvatarList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu); } else { @@ -670,7 +672,7 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents:: return mParent.onSpeakerMuteEvent(event, userdata); } -LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() +/*LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() { // set up the callbacks for all of the avatar menu items LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -708,7 +710,7 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() main_menu->arrangeAndClear(); return main_menu; -} +}*/ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y) { diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index b9358cf37c..1c6f51e131 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -29,7 +29,6 @@ #include "llevent.h" #include "lleventtimer.h" -#include "llspeakers.h" #include "llvoicechannel.h" class LLSpeakerMgr; diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index e123de46c2..ce40f44a64 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -1,49 +1,122 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <multi_floater - can_close="false" + can_close="true" can_minimize="true" can_resize="true" - height="390" + height="430" layout="topleft" + min_height="50" name="floater_im_box" help_topic="floater_im_box" save_rect="true" save_visibility="true" single_instance="true" title="CONVERSATIONS" - width="396"> - <tab_container - follows="left|right|top|bottom" - height="390" + width="680"> + <string + name="collapse_icon" + value="TabIcon_Open_Off"/> + <string + name="expand_icon" + value="TabIcon_Close_Off"/> + <layout_stack + animate="true" + follows="all" + height="430" layout="topleft" - left="1" - name="im_box_tab_container" - tab_position="bottom" - tab_width="64" - tab_max_width = "134" - tab_height="16" - use_custom_icon_ctrl="true" - tab_icon_ctrl_pad="2" - halign="left" - use_ellipses="true" + left="0" + name="conversations_stack" + orientation="horizontal" top="0" - width="394"> - <first_tab - tab_bottom_image_flash="Toolbar_Left_Flash"/> - <middle_tab - tab_bottom_image_flash="Toolbar_Middle_Flash"/> - <last_tab - tab_bottom_image_flash="Toolbar_Right_Flash"/> - </tab_container> - <icon - color="DefaultShadowLight" - enabled="false" - follows="left|right|bottom" - height="17" - image_name="tabarea.tga" - layout="bottomleft" - left="1" - name="im_box_tab_container_icon" - bottom="10" - width="394" /> + width="680"> + <layout_panel + auto_resize="true" + height="430" + name="conversations_layout_panel" + min_dim="41" + width="268"> + <layout_stack + animate="false" + follows="left|top|right" + height="35" + layout="topleft" + left="0" + name="conversations_pane_buttons_stack" + orientation="horizontal" + top="0" + width="268"> + <layout_panel + auto_resize="true" + height="35" + name="conversations_pane_buttons_expanded"> + <menu_button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left="10" + name="sort_btn" + top="5" + width="31" /> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="4" + name="add_btn" + tool_tip="Add button on the left panel" + width="31"/> + </layout_panel> + <layout_panel + auto_resize="false" + height="35" + name="conversations_pane_buttons_collapsed" + width="41"> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="TabIcon_Open_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left="5" + name="expand_collapse_btn" + width="31" /> + </layout_panel> + </layout_stack> + <panel + follows="all" + layout="topleft" + name="conversations_list_panel" + opaque="true" + top_pad="0" + left="5" + height="390" + width="263"/> + </layout_panel> + <layout_panel + auto_resize="true" + height="430" + name="messages_layout_panel" + width="412"> + <panel_container + follows="all" + height="430" + layout="topleft" + left="10" + name="im_box_tab_container" + top="0" + width="402"/> + </layout_panel> + </layout_stack> </multi_floater> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index ca73883e53..a332bb5b12 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - legacy_header_height="18" background_visible="true" default_tab_group="1" height="355" @@ -13,30 +12,141 @@ visible="false" width="394" can_resize="true" + can_tear_off="false" min_width="250" min_height="190"> + <floater.string name="call_btn_start">VoicePTT_Off</floater.string> + <floater.string name="call_btn_stop">VoicePTT_On</floater.string> + <floater.string + name="collapse_icon" + value="TabIcon_Open_Off"/> + <floater.string + name="expand_icon" + value="TabIcon_Close_Off"/> + <floater.string + name="tear_off_icon" + value="tearoffbox.tga"/> + <floater.string + name="return_icon" + value="Icon_Dock_Foreground"/> + <view + follows="all" + layout="topleft" + name="contents_view" + top="0" + left="0" + height="355" + width="394"> + <panel + follows="left|top|right" + layout="topleft" + name="toolbar_panel" + top="0" + left="0" + height="35" + width="394"> + <menu_button + menu_filename="menu_im_session_showmodes.xml" + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Left_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + layout="topleft" + left="5" + name="view_options_btn" + top="5" + width="31" /> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="4" + name="add_btn" + width="31"> + <commit_callback + function="Chats.add" /> + </button> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Right_Over" + image_overlay="VoicePTT_Off" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" + layout="topleft" + top="5" + left_pad="4" + name="voice_call_btn" + width="31"> + <commit_callback + function="Chats.add" /> + </button> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Icon_Close_Foreground" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left="283" + name="close_btn" + width="31" /> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="TabIcon_Open_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="5" + name="expand_collapse_btn" + width="31" /> + <button + follows="right|top" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="tearoffbox.tga" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + top="5" + left_pad="5" + name="tear_off_btn" + width="31" /> + </panel> <layout_stack animate="true" default_tab_group="2" follows="all" - height="320" + height="310" width="394" layout="topleft" orientation="horizontal" name="im_panels" tab_group="1" - top="20" + top_pad="0" left="0"> <layout_panel name="im_control_panel_holder" min_width="115" width="150" - height="320" + height="310" auto_resize="false"> <panel name="panel_im_control_panel" layout="topleft" - height="320" + height="310" width="150" follows="all"/> </layout_panel> @@ -46,39 +156,22 @@ tab_group="2" top="0" height="200" - width="254" + width="254" user_resize="true"> - <button - height="20" - follows="left|top" - top="0" - left="2" - image_overlay="TabIcon_Open_Off" - layout="topleft" - width="25" - name="slide_left_btn" /> - <button - height="20" - follows="left|top" - top="0" - left="2" - image_overlay="TabIcon_Close_Off" - width="25" - name="slide_right_btn" /> <chat_history - font="SansSerifSmall" - follows="left|right|top|bottom" - height="150" + font="SansSerifSmall" + follows="all" + height="170" name="chat_history" parse_highlights="true" parse_urls="true" - left="1" + left="1" width="249"> </chat_history> <line_editor bottom="0" follows="left|right|bottom" - font="SansSerifSmall" + font="SansSerifSmall" height="20" label="To" layout="bottomleft" @@ -88,4 +181,5 @@ </line_editor> </layout_panel> </layout_stack> + </view> </floater> diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml new file mode 100644 index 0000000000..483f24afd0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_modes" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_check + label="Compact view" + name="compact_view"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="compact_view"/> + <menu_item_check.on_check + function="IMSession.Menu.CompactExpandedModes.CheckItem" + parameter="compact_view"/> + </menu_item_check> + <menu_item_check + label="Expanded view" + name="expanded_view"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="expanded_view"/> + <menu_item_check.on_check + function="IMSession.Menu.CompactExpandedModes.CheckItem" + parameter="expanded_view"/> + </menu_item_check> + <menu_item_separator layout="topleft" /> + <menu_item_check name="IMShowTime" label="Show time"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="IMShowTime" /> + <menu_item_check.on_check + function="IMSession.Menu.ShowModes.CheckItem" + parameter="IMShowTime" /> + <menu_item_check.on_enable + function="IMSession.Menu.ShowModes.Enable" + parameter="IMShowTime" /> + </menu_item_check> + <menu_item_check name="IMShowNamesForP2PConv" label="Show names in one-to-one conversations"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="IMShowNamesForP2PConv" /> + <menu_item_check.on_check + function="IMSession.Menu.ShowModes.CheckItem" + parameter="IMShowNamesForP2PConv" /> + <menu_item_check.on_enable + function="IMSession.Menu.ShowModes.Enable" + parameter="IMShowNamesForP2PConv" /> + + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml index ad10e53a4e..a5295ebe01 100644 --- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml @@ -47,55 +47,6 @@ layout="topleft" min_height="28" width="130" - name="group_info_btn_panel"> - <button - follows="left|right|bottom" - height="23" - label="Group Profile" - name="group_info_btn" - use_ellipses="true" - top="5" - width="130" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="28" - layout="topleft" - min_height="28" - width="130" - name="call_btn_panel"> - <button - follows="all" - height="23" - label="Call Group" - name="call_btn" - use_ellipses="true" - width="130" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="28" - layout="topleft" - min_height="28" - width="130" - name="end_call_btn_panel" - visible="false"> - <button - follows="all" - height="23" - label="Leave Call" - name="end_call_btn" - use_ellipses="true" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="28" - layout="topleft" - min_height="28" - width="130" name="voice_ctrls_btn_panel" visible="false"> <button diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml deleted file mode 100644 index 8fcd6ccbaf..0000000000 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ /dev/null @@ -1,166 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - height="300" - name="panel_im_control_panel" - width="150"> - <avatar_icon - follows="left|top" - height="105" - left_delta="20" - name="avatar_icon" - top="-5" - width="114"/> - <layout_stack - mouse_opaque="false" - border_size="0" - clip="false" - follows="all" - height="183" - layout="topleft" - left="5" - name="button_stack" - orientation="vertical" - top_pad="5" - width="145"> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="20" - layout="topleft" - left="2" - min_height="20" - width="140" - name="view_profile_btn_panel" - top="0" > - <button - follows="left|top|right" - height="23" - label="Profile" - name="view_profile_btn" - top="0" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="add_friend_btn_panel"> - <button - follows="left|top|right" - height="23" - label="Add Friend" - name="add_friend_btn" - top="5" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="teleport_btn_panel"> - <button - auto_resize="false" - follows="left|top|right" - height="23" - label="Teleport" - name="teleport_btn" - tool_tip = "Offer to teleport this person" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="share_btn_panel"> - <button - auto_resize="true" - follows="left|top|right" - height="23" - label="Share" - name="share_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="pay_btn_panel"> - <button - auto_resize="true" - follows="left|top|right" - height="23" - label="Pay" - name="pay_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="call_btn_panel"> - <button - follows="left|top|right" - height="23" - label="Call" - name="call_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="end_call_btn_panel" - visible="false"> - <button - follows="left|top|right" - height="23" - label="End Call" - name="end_call_btn" - width="140" /> - </layout_panel> - <layout_panel - auto_resize="false" - follows="top|left|right" - height="25" - layout="topleft" - min_height="25" - width="140" - name="voice_ctrls_btn_panel" - visible="false"> - <button - follows="left|top|right" - height="23" - label="Voice Controls" - name="voice_ctrls_btn" - width="140" /> - </layout_panel> - <layout_panel - mouse_opaque="false" - auto_resize="true" - follows="top|left" - height="0" - layout="topleft" - min_height="0" - width="140" - name="spacer"/> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e932310622..d7bc998b36 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -405,6 +405,7 @@ Please try logging in again in a minute.</string> <string name="TrackYourCamera">Track your camera</string> <string name="ControlYourCamera">Control your camera</string> <string name="NotConnected">Not Connected</string> + <string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name --> <!-- Sim Access labels --> <string name="SIM_ACCESS_PG">General</string> |