diff options
31 files changed, 686 insertions, 101 deletions
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 64a4824a17..09124c3013 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -530,7 +530,8 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask) if ( !selectNextItemPair(true, reset_selection) && reset_selection) { // If case we are in accordion tab notify parent to go to the previous accordion - notifyParent(LLSD().with("action","select_prev")); + if(notifyParent(LLSD().with("action","select_prev")) > 0 )//message was processed + resetSelection(); } break; } @@ -539,7 +540,8 @@ BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask) if ( !selectNextItemPair(false, reset_selection) && reset_selection) { // If case we are in accordion tab notify parent to go to the next accordion - notifyParent(LLSD().with("action","select_next")); + if( notifyParent(LLSD().with("action","select_next")) > 0 ) //message was processed + resetSelection(); } break; } diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index c42ae040d6..202ed04fbc 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3905,7 +3905,7 @@ BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu) item = LLUICtrlFactory::create<LLContextMenuBranch>(p); LLMenuGL::sMenuContainer->addChild(item->getBranch()); - item->setFont( LLFontGL::getFontSansSerifSmall() ); + item->setFont( LLFontGL::getFontSansSerif() ); return append( item ); } diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 3bd4f898c8..71b23e1383 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -33,6 +33,7 @@ #include "llviewerprecompiledheaders.h" #include "llavatarlist.h" +#include "llagent.h" // for comparator // newview #include "llcallingcard.h" // for LLAvatarTracker @@ -420,3 +421,17 @@ bool LLAvatarItemNameComparator::doCompare(const LLAvatarListItem* avatar_item1, return name1 < name2; } +bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const +{ + //keep agent on top, if first is agent, + //then we need to return true to elevate this id, otherwise false. + if(avatar_item1->getAvatarId() == gAgent.getID()) + { + return true; + } + else if (avatar_item2->getAvatarId() == gAgent.getID()) + { + return false; + } + return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2); +} diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 9058fec540..e913be0f62 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -155,4 +155,16 @@ protected: virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const; }; +class LLAvatarItemAgentOnTopComparator : public LLAvatarItemNameComparator +{ + LOG_CLASS(LLAvatarItemAgentOnTopComparator); + +public: + LLAvatarItemAgentOnTopComparator() {}; + virtual ~LLAvatarItemAgentOnTopComparator() {}; + +protected: + virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const; +}; + #endif // LL_LLAVATARLIST_H diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 6f2e666cc7..ab657e0e99 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -67,6 +67,10 @@ LLBottomTray::LLBottomTray(const LLSD&) , mGesturePanel(NULL) , mCamButton(NULL) { + // Firstly add ourself to IMSession observers, so we catch session events + // before chiclets do that. + LLIMMgr::getInstance()->addSessionObserver(this); + mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml"); @@ -76,7 +80,6 @@ LLBottomTray::LLBottomTray(const LLSD&) mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraPresets, _2)); - LLIMMgr::getInstance()->addSessionObserver(this); //managing chiclets for voice calls LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLBottomTray::onNewIM, this, _1)); diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 1f23840109..20739d2401 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -42,6 +42,8 @@ #include "llagentdata.h" // for gAgentID #include "llavatarlist.h" #include "llbottomtray.h" +#include "llimfloater.h" +#include "llfloaterreg.h" #include "llparticipantlist.h" #include "llspeakers.h" #include "lltransientfloatermgr.h" @@ -95,7 +97,6 @@ LLCallFloater::LLCallFloater(const LLSD& key) LLCallFloater::~LLCallFloater() { - mChannelChangedConnection.disconnect(); delete mPaticipants; mPaticipants = NULL; @@ -128,8 +129,6 @@ BOOL LLCallFloater::postBuild() // update list for current session updateSession(); - // subscribe to to be notified Voice Channel is changed - mChannelChangedConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::onCurrentChannelChanged, this, _1)); return TRUE; } @@ -245,6 +244,17 @@ void LLCallFloater::updateSession() refreshPartisipantList(); updateModeratorState(); + + //show floater for voice calls + if (!is_local_chat) + { + LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + bool show_me = !(im_floater && im_floater->getVisible()); + if (show_me) + { + setVisible(true); + } + } } void LLCallFloater::refreshPartisipantList() @@ -270,10 +280,9 @@ void LLCallFloater::refreshPartisipantList() if (!non_avatar_caller) { - bool do_not_use_context_menu_in_local_chat = LLLocalSpeakerMgr::getInstance() != mSpeakerManager; - mPaticipants = new LLParticipantList(mSpeakerManager, mAvatarList, do_not_use_context_menu_in_local_chat); + mPaticipants = new LLParticipantList(mSpeakerManager, mAvatarList); - if (!do_not_use_context_menu_in_local_chat) + if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager) { mAvatarList->setNoItemsCommentText(getString("no_one_near")); } @@ -281,7 +290,7 @@ void LLCallFloater::refreshPartisipantList() } } -void LLCallFloater::onCurrentChannelChanged(const LLUUID& /*session_id*/) +void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) { // Don't update participant list if no channel info is available. // Fix for ticket EXT-3427 @@ -291,9 +300,11 @@ void LLCallFloater::onCurrentChannelChanged(const LLUUID& /*session_id*/) { return; } + LLCallFloater* call_floater = LLFloaterReg::getTypedInstance<LLCallFloater>("voice_controls"); + // Forget speaker manager from the previous session to avoid using it after session was destroyed. - mSpeakerManager = NULL; - updateSession(); + call_floater->mSpeakerManager = NULL; + call_floater->updateSession(); } void LLCallFloater::updateTitle() diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index b2288a42ff..f9c9149085 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -70,6 +70,8 @@ public: */ /*virtual*/ void onChange(); + static void sOnCurrentChannelChanged(const LLUUID& session_id); + private: typedef enum e_voice_controls_type { @@ -93,7 +95,9 @@ private: * Refreshes participant list according to current Voice Channel */ void refreshPartisipantList(); - void onCurrentChannelChanged(const LLUUID& session_id); + + + void updateTitle(); void initAgentData(); void setModeratorMutedVoice(bool moderator_muted); @@ -108,8 +112,6 @@ private: LLPanel* mAgentPanel; LLOutputMonitorCtrl* mSpeakingIndicator; bool mIsModeratorMutedVoice; - - boost::signals2::connection mChannelChangedConnection; }; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index ee60df1b4b..fc8dc0ff8f 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -202,6 +202,8 @@ public: userName->setValue(SL); } + mMinUserNameWidth = style_params.font.getValueFromBlock()->getWidth(userName->getWText().c_str()) + PADDING; + setTimeField(chat); LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon"); @@ -218,7 +220,37 @@ public: icon->setValue(LLSD("SL_Logo")); } - } + } + + /*virtual*/ void draw() + { + LLTextEditor* user_name = getChild<LLTextEditor>("user_name"); + LLTextBox* time_box = getChild<LLTextBox>("time_box"); + + LLRect user_name_rect = user_name->getRect(); + S32 user_name_width = user_name_rect.getWidth(); + S32 time_box_width = time_box->getRect().getWidth(); + + if (time_box->getVisible() && user_name_width <= mMinUserNameWidth) + { + time_box->setVisible(FALSE); + + user_name_rect.mRight += time_box_width; + user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); + user_name->setRect(user_name_rect); + } + + if (!time_box->getVisible() && user_name_width > mMinUserNameWidth + time_box_width) + { + user_name_rect.mRight -= time_box_width; + user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); + user_name->setRect(user_name_rect); + + time_box->setVisible(TRUE); + } + + LLPanel::draw(); + } void nameUpdatedCallback(const LLUUID& id,const std::string& first,const std::string& last,BOOL is_group) { @@ -228,6 +260,8 @@ public: mLastName = last; } protected: + static const S32 PADDING = 20; + void showContextMenu(S32 x,S32 y) { if(mSourceType == CHAT_SOURCE_SYSTEM) @@ -307,6 +341,7 @@ protected: std::string mLastName; std::string mFrom; + S32 mMinUserNameWidth; }; diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index c6fe076911..21a0381495 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -66,11 +66,13 @@ static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer"); static const LLRect CHICLET_RECT(0, 25, 25, 0); static const LLRect CHICLET_ICON_RECT(0, 22, 22, 0); -static const LLRect VOICE_INDICATOR_RECT(25, 25, 45, 0); +static const LLRect VOICE_INDICATOR_RECT(50, 25, 70, 0); +static const LLRect COUNTER_RECT(25, 25, 50, 0); static const S32 OVERLAY_ICON_SHIFT = 2; // used for shifting of an overlay icon for new massages in a chiclet // static const S32 LLChicletPanel::s_scroll_ratio = 10; +const S32 LLChicletNotificationCounterCtrl::MAX_DISPLAYED_COUNT = 99; boost::signals2::signal<LLChiclet* (const LLUUID&), @@ -154,6 +156,7 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p) , mMaxDisplayedCount(p.max_displayed_count) , mIsNewMessagesState(false) , mFlashToLitTimer(NULL) +, mContextMenu(NULL) { LLButton::Params button_params = p.button; mButton = LLUICtrlFactory::create<LLButton>(button_params); @@ -169,6 +172,7 @@ LLSysWellChiclet::~LLSysWellChiclet() void LLSysWellChiclet::setCounter(S32 counter) { + // note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter) std::string s_count; if(counter != 0) { @@ -229,6 +233,21 @@ void LLSysWellChiclet::setNewMessagesState(bool new_messages) mIsNewMessagesState = new_messages; } +// virtual +BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if(!mContextMenu) + { + createMenu(); + } + if (mContextMenu) + { + mContextMenu->show(x, y); + LLMenuGL::showPopup(this, mContextMenu, x, y); + } + return TRUE; +} + /************************************************************************/ /* LLIMWellChiclet implementation */ /************************************************************************/ @@ -248,6 +267,47 @@ LLIMWellChiclet::~LLIMWellChiclet() LLIMMgr::getInstance()->removeSessionObserver(this); } +void LLIMWellChiclet::onMenuItemClicked(const LLSD& user_data) +{ + std::string action = user_data.asString(); + if("close all" == action) + { + LLIMWellWindow::getInstance()->closeAll(); + } +} + +bool LLIMWellChiclet::enableMenuItem(const LLSD& user_data) +{ + std::string item = user_data.asString(); + if (item == "can close all") + { + return !LLIMWellWindow::getInstance()->isWindowEmpty(); + } + return true; +} + +void LLIMWellChiclet::createMenu() +{ + if(mContextMenu) + { + llwarns << "Menu already exists" << llendl; + return; + } + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("IMWellChicletMenu.Action", + boost::bind(&LLIMWellChiclet::onMenuItemClicked, this, _2)); + + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + enable_registrar.add("IMWellChicletMenu.EnableItem", + boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2)); + + mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> + ("menu_im_well_button.xml", + LLMenuGL::sMenuContainer, + LLViewerMenuHolderGL::child_registry_t::instance()); +} + void LLIMWellChiclet::messageCountChanged(const LLSD& session_data) { setCounter(LLBottomTray::getInstance()->getTotalUnreadIMCount()); @@ -281,6 +341,47 @@ void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& no } } +void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) +{ + std::string action = user_data.asString(); + if("close all" == action) + { + LLNotificationWellWindow::getInstance()->closeAll(); + } +} + +bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data) +{ + std::string item = user_data.asString(); + if (item == "can close all") + { + return mUreadSystemNotifications != 0; + } + return true; +} + +void LLNotificationChiclet::createMenu() +{ + if(mContextMenu) + { + llwarns << "Menu already exists" << llendl; + return; + } + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("NotificationWellChicletMenu.Action", + boost::bind(&LLNotificationChiclet::onMenuItemClicked, this, _2)); + + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + enable_registrar.add("NotificationWellChicletMenu.EnableItem", + boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2)); + + mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> + ("menu_notification_well_button.xml", + LLMenuGL::sMenuContainer, + LLViewerMenuHolderGL::child_registry_t::instance()); +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -365,7 +466,7 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p) // shift an icon a little bit to the right and up corner of a chiclet overlay_icon_rect.translate(OVERLAY_ICON_SHIFT, OVERLAY_ICON_SHIFT); - setShowCounter(false); + enableCounterControl(false); } void LLIMChiclet::setShowSpeaker(bool show) @@ -378,30 +479,87 @@ void LLIMChiclet::setShowSpeaker(bool show) onChicletSizeChanged(); } } + +void LLIMChiclet::enableCounterControl(bool enable) +{ + mCounterEnabled = enable; + if(!enable) + { + LLChiclet::setShowCounter(false); + } +} + +void LLIMChiclet::setShowCounter(bool show) +{ + if(!mCounterEnabled) + { + return; + } + + bool needs_resize = getShowCounter() != show; + if(needs_resize) + { + LLChiclet::setShowCounter(show); + toggleCounterControl(); + onChicletSizeChanged(); + } +} + void LLIMChiclet::initSpeakerControl() { // virtual } -void LLIMChiclet::toggleSpeakerControl() +void LLIMChiclet::setRequiredWidth() { - LLRect speaker_rect = mSpeakerCtrl->getRect(); - S32 required_width = getRect().getWidth(); + bool show_speaker = getShowSpeaker(); + bool show_counter = getShowCounter(); + S32 required_width = CHICLET_RECT.getWidth(); - if(getShowSpeaker()) + if (show_counter) { - required_width = required_width + speaker_rect.getWidth(); - initSpeakerControl(); + required_width += COUNTER_RECT.getWidth(); } - else + if (show_speaker) { - required_width = required_width - speaker_rect.getWidth(); - } - + required_width += VOICE_INDICATOR_RECT.getWidth(); + } + reshape(required_width, getRect().getHeight()); +} + +void LLIMChiclet::toggleSpeakerControl() +{ + if(getShowSpeaker()) + { + if(getShowCounter()) + { + mSpeakerCtrl->setRect(VOICE_INDICATOR_RECT); + } + else + { + mSpeakerCtrl->setRect(COUNTER_RECT); + } + initSpeakerControl(); + } + + setRequiredWidth(); mSpeakerCtrl->setVisible(getShowSpeaker()); } +void LLIMChiclet::setCounter(S32 counter) +{ + mCounterCtrl->setCounter(counter); + setShowCounter(counter); + setShowNewMessagesIcon(counter); +} + +void LLIMChiclet::toggleCounterControl() +{ + setRequiredWidth(); + mCounterCtrl->setVisible(getShowCounter()); +} + void LLIMChiclet::setShowNewMessagesIcon(bool show) { if(mNewMessagesIcon) @@ -502,6 +660,7 @@ LLIMP2PChiclet::Params::Params() unread_notifications.v_pad(5); unread_notifications.text_color(LLColor4::white); unread_notifications.mouse_opaque(false); + unread_notifications.rect(COUNTER_RECT); unread_notifications.visible(false); speaker.name("speaker"); @@ -540,12 +699,6 @@ LLIMP2PChiclet::LLIMP2PChiclet(const Params& p) mSpeakerCtrl->setVisible(getShowSpeaker()); } -void LLIMP2PChiclet::setCounter(S32 counter) -{ - mCounterCtrl->setCounter(counter); - setShowNewMessagesIcon(counter); -} - void LLIMP2PChiclet::initSpeakerControl() { mSpeakerCtrl->setSpeakerId(getOtherParticipantId()); @@ -658,6 +811,7 @@ LLAdHocChiclet::Params::Params() unread_notifications.v_pad(5); unread_notifications.text_color(LLColor4::white); unread_notifications.mouse_opaque(false); + unread_notifications.rect(COUNTER_RECT); unread_notifications.visible(false); @@ -732,12 +886,6 @@ void LLAdHocChiclet::switchToCurrentSpeaker() mSpeakerCtrl->setSpeakerId(speaker_id); } -void LLAdHocChiclet::setCounter(S32 counter) -{ - mCounterCtrl->setCounter(counter); - setShowNewMessagesIcon(counter); -} - void LLAdHocChiclet::createPopupMenu() { if(mPopupMenu) @@ -809,6 +957,7 @@ LLIMGroupChiclet::Params::Params() unread_notifications.font_halign(LLFontGL::HCENTER); unread_notifications.v_pad(5); unread_notifications.text_color(LLColor4::white); + unread_notifications.rect(COUNTER_RECT); unread_notifications.visible(false); speaker.name("speaker"); @@ -849,12 +998,6 @@ LLIMGroupChiclet::~LLIMGroupChiclet() LLGroupMgr::getInstance()->removeObserver(this); } -void LLIMGroupChiclet::setCounter(S32 counter) -{ - mCounterCtrl->setCounter(counter); - setShowNewMessagesIcon(counter); -} - void LLIMGroupChiclet::draw() { switchToCurrentSpeaker(); @@ -1546,11 +1689,16 @@ S32 LLChicletPanel::getTotalUnreadIMCount() ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLChicletNotificationCounterCtrl::Params::Params() +: max_displayed_count("max_displayed_count", MAX_DISPLAYED_COUNT) +{ +} LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p) : LLTextBox(p) , mCounter(0) , mInitialWidth(0) + , mMaxDisplayedCount(p.max_displayed_count) { mInitialWidth = getRect().getWidth(); } @@ -1559,11 +1707,21 @@ void LLChicletNotificationCounterCtrl::setCounter(S32 counter) { mCounter = counter; - std::stringstream stream; - stream << getCounter(); + // note same code in LLSysWellChiclet::setCounter(S32 counter) + std::string s_count; + if(counter != 0) + { + static std::string more_messages_exist("+"); + std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : ""); + s_count = llformat("%d%s" + , llmin(counter, mMaxDisplayedCount) + , more_messages.c_str() + ); + } + if(mCounter != 0) { - setText(stream.str()); + setText(s_count); } else { diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index b3341f78a8..259476c2ad 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -52,10 +52,19 @@ class LLChicletNotificationCounterCtrl : public LLTextBox { public: + static const S32 MAX_DISPLAYED_COUNT; + struct Params : public LLInitParam::Block<Params, LLTextBox::Params> { - Params() - {}; + /** + * Contains maximum displayed count of unread messages. Default value is 9. + * + * If count is less than "max_unread_count" will be displayed as is. + * Otherwise 9+ will be shown (for default value). + */ + Optional<S32> max_displayed_count; + + Params(); }; /** @@ -93,6 +102,7 @@ private: S32 mCounter; S32 mInitialWidth; + S32 mMaxDisplayedCount; }; /** @@ -359,6 +369,32 @@ public: virtual void toggleSpeakerControl(); /** + * Sets number of unread messages. Will update chiclet's width if number text + * exceeds size of counter and notify it's parent about size change. + */ + virtual void setCounter(S32); + + /** + * Enables/disables the counter control for a chiclet. + */ + virtual void enableCounterControl(bool enable); + + /** + * Sets show counter state. + */ + virtual void setShowCounter(bool show); + + /** + * Shows/Hides for counter control for a chiclet. + */ + virtual void toggleCounterControl(); + + /** + * Sets required width for a chiclet according to visible controls. + */ + virtual void setRequiredWidth(); + + /** * Shows/hides overlay icon concerning new unread messages. */ virtual void setShowNewMessagesIcon(bool show); @@ -400,6 +436,7 @@ protected: protected: bool mShowSpeaker; + bool mCounterEnabled; LLIconCtrl* mNewMessagesIcon; LLChicletNotificationCounterCtrl* mCounterCtrl; @@ -453,12 +490,6 @@ public: /* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id); /** - * Sets number of unread messages. Will update chiclet's width if number text - * exceeds size of counter and notify it's parent about size change. - */ - /*virtual*/ void setCounter(S32); - - /** * Init Speaker Control with speaker's ID */ /*virtual*/ void initSpeakerControl(); @@ -527,12 +558,6 @@ public: /*virtual*/ void setSessionId(const LLUUID& session_id); /** - * Sets number of unread messages. Will update chiclet's width if number text - * exceeds size of counter and notify it's parent about size change. - */ - /*virtual*/ void setCounter(S32); - - /** * Keep Speaker Control with actual speaker's ID */ /*virtual*/ void draw(); @@ -695,12 +720,6 @@ public: /*virtual*/ void changed(LLGroupChange gc); /** - * Sets number of unread messages. Will update chiclet's width if number text - * exceeds size of counter and notify it's parent about size change. - */ - /*virtual*/ void setCounter(S32); - - /** * Init Speaker Control with speaker's ID */ /*virtual*/ void initSpeakerControl(); @@ -806,6 +825,13 @@ protected: */ void changeLitState(); + /** + * Displays menu. + */ + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + + virtual void createMenu() = 0; + protected: class FlashToLitTimer; LLButton* mButton; @@ -814,7 +840,7 @@ protected: bool mIsNewMessagesState; FlashToLitTimer* mFlashToLitTimer; - + LLContextMenu* mContextMenu; }; /** @@ -835,6 +861,21 @@ protected: LLIMWellChiclet(const Params& p); /** + * Processes clicks on chiclet popup menu. + */ + virtual void onMenuItemClicked(const LLSD& user_data); + + /** + * Enables chiclet menu items. + */ + bool enableMenuItem(const LLSD& user_data); + + /** + * Creates menu. + */ + /*virtual*/ void createMenu(); + + /** * Handles changes in a session (message was added, messages were read, etc.) * * It get total count of unread messages from a LLIMMgr in all opened sessions and display it. @@ -854,6 +895,21 @@ class LLNotificationChiclet : public LLSysWellChiclet protected: LLNotificationChiclet(const Params& p); + /** + * Processes clicks on chiclet menu. + */ + void onMenuItemClicked(const LLSD& user_data); + + /** + * Enables chiclet menu items. + */ + bool enableMenuItem(const LLSD& user_data); + + /** + * Creates menu. + */ + /*virtual*/ void createMenu(); + // connect counter updaters to the corresponding signals void connectCounterUpdatersToSignal(const std::string& notification_type); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 826cb0bb3b..832626e007 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -657,7 +657,7 @@ void LLFavoritesBarCtrl::updateButtons() int first_changed_item_index = 0; int rightest_point = getRect().mRight - mChevronButton->getRect().getWidth(); //lets find first changed button - while (child_it != childs->end()) + while (child_it != childs->end() && first_changed_item_index < mItems.count()) { LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (*child_it); if (button) @@ -679,9 +679,8 @@ void LLFavoritesBarCtrl::updateButtons() } // now first_changed_item_index should contains a number of button that need to change - if (first_changed_item_index < mItems.count()) + if (first_changed_item_index <= mItems.count()) { - mUpdateDropDownItems = true; // Rebuild the buttons only // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator @@ -726,6 +725,10 @@ void LLFavoritesBarCtrl::updateButtons() // Chevron button if (mFirstDropDownItem < mItems.count()) { + // if updateButton had been called it means: + //or there are some new favorites, or width had been changed + // so if we need to display chevron button, we must update dropdown items too. + mUpdateDropDownItems = true; S32 buttonHGap = 2; // default value buttonXMLNode->getAttributeS32("left", buttonHGap); LLRect rect; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 9e878f8c75..f5362acbfe 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -238,15 +238,17 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction) { - bool is_p2p_session = dynamic_cast<LLVoiceChannelP2P*>(mVoiceChannel); - std::string other_avatar_name; + std::string you = LLTrans::getString("You"); + std::string started_call = LLTrans::getString("started_call"); + std::string joined_call = LLTrans::getString("joined_call"); + std::string other_avatar_name = ""; - if(is_p2p_session) + switch(mSessionType) { + case AVALINE_SESSION: + // *TODO: test avaline calls (EXT-2211) + case P2P_SESSION: gCacheName->getFullName(mOtherParticipantID, other_avatar_name); - std::string you = LLTrans::getString("You"); - std::string started_call = LLTrans::getString("started_call"); - std::string joined_call = LLTrans::getString("joined_call"); if(direction == LLVoiceChannel::INCOMING_CALL) { @@ -280,10 +282,45 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES { mSpeakers->update(true); } - } - else // group || ad-hoc calls - { + break; + + case GROUP_SESSION: + case ADHOC_SESSION: + // *TODO: determine call starter's name "other_avatar_name" (EXT-2211) + // decide how to show notifications for a group/adhoc chat already opened + // for now there is no notification from voice channel for this case + if(direction == LLVoiceChannel::INCOMING_CALL) + { + switch(new_state) + { + case LLVoiceChannel::STATE_CALL_STARTED : + LLIMModel::getInstance()->addMessageSilently(mSessionID, other_avatar_name, mOtherParticipantID, started_call); + break; + case LLVoiceChannel::STATE_CONNECTED : + LLIMModel::getInstance()->addMessageSilently(mSessionID, you, gAgent.getID(), joined_call); + default: + break; + } + } + else // outgoing call + { + switch(new_state) + { + case LLVoiceChannel::STATE_CALL_STARTED : + LLIMModel::getInstance()->addMessageSilently(mSessionID, you, gAgent.getID(), started_call); + break; + default: + break; + } + } + + // Update speakers list when connected + if (LLVoiceChannel::STATE_CONNECTED == new_state) + { + mSpeakers->update(true); + } + break; } } @@ -1279,6 +1316,28 @@ void LLCallDialogManager::onVoiceChannelChanged(const LLUUID &session_id) sPreviousSessionlName = sCurrentSessionlName; sCurrentSessionlName = session->mName; } + + if (LLVoiceChannel::getCurrentVoiceChannel()->getState() == LLVoiceChannel::STATE_CALL_STARTED && + LLVoiceChannel::getCurrentVoiceChannel()->getCallDirection() == LLVoiceChannel::OUTGOING_CALL) + { + + //*TODO get rid of duplicated code + LLSD mCallDialogPayload; + mCallDialogPayload["session_id"] = sSession->mSessionID; + mCallDialogPayload["session_name"] = sSession->mName; + mCallDialogPayload["other_user_id"] = sSession->mOtherParticipantID; + mCallDialogPayload["old_channel_name"] = sPreviousSessionlName; + mCallDialogPayload["state"] = LLVoiceChannel::STATE_CALL_STARTED; + mCallDialogPayload["disconnected_channel_name"] = sSession->mName; + mCallDialogPayload["session_type"] = sSession->mSessionType; + + LLOutgoingCallDialog* ocd = LLFloaterReg::getTypedInstance<LLOutgoingCallDialog>("outgoing_call", LLOutgoingCallDialog::OCD_KEY); + if(ocd) + { + ocd->show(mCallDialogPayload); + } + } + } void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction) diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 93e5b8fa15..afb9892d12 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -49,11 +49,14 @@ #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif +static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR; + LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu/* = true*/): mSpeakerMgr(data_source), mAvatarList(avatar_list), mSortOrder(E_SORT_BY_NAME) , mParticipantListMenu(NULL) +, mExcludeAgent(true) { mSpeakerAddListener = new SpeakerAddListener(*this); mSpeakerRemoveListener = new SpeakerRemoveListener(*this); @@ -97,6 +100,8 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av mModeratorList.insert(speakerp->mID); } } + // we need to exclude agent id for non group chat + mExcludeAgent = !gAgent.isInGroup(mSpeakerMgr->getSessionID()); mAvatarList->setDirty(true); sort(); } @@ -110,13 +115,16 @@ LLParticipantList::~LLParticipantList() // It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged() // See ticket EXT-3427 // hide menu before deleting it to stop enable and check handlers from triggering. - if(mParticipantListMenu) + if(mParticipantListMenu && !LLApp::isExiting()) { mParticipantListMenu->hide(); } - delete mParticipantListMenu; - mParticipantListMenu = NULL; + if (mParticipantListMenu) + { + delete mParticipantListMenu; + mParticipantListMenu = NULL; + } } void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible) @@ -307,7 +315,16 @@ void LLParticipantList::sort() // TODO: Implement more sorting orders after specs updating (EM) switch ( mSortOrder ) { case E_SORT_BY_NAME : - mAvatarList->sortByName(); + // if mExcludeAgent == true , then no need to keep agent on top of the list + if(mExcludeAgent) + { + mAvatarList->sortByName(); + } + else + { + mAvatarList->setComparator(&AGENT_ON_TOP_NAME_COMPARATOR); + mAvatarList->sort(); + } break; default : llwarns << "Unrecognized sort order for " << mAvatarList->getName() << llendl; @@ -317,7 +334,7 @@ void LLParticipantList::sort() void LLParticipantList::addAvatarIDExceptAgent(std::vector<LLUUID>& existing_list, const LLUUID& avatar_id) { - if (gAgent.getID() == avatar_id) return; + if (mExcludeAgent && gAgent.getID() == avatar_id) return; existing_list.push_back(avatar_id); adjustParticipant(avatar_id); diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index bc6c6c2b50..72c413d188 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -229,6 +229,12 @@ class LLParticipantList LLParticipantListMenu* mParticipantListMenu; EParticipantSortOrder mSortOrder; + /* + * This field manages an adding a new avatar_id in the mAvatarList + * If true, then agent_id wont be added into mAvatarList + * Also by default this field is controlling a sort procedure, @c sort() + */ + bool mExcludeAgent; // boost::connections boost::signals2::connection mAvatarListDoubleClickConnection; diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp index 5edc4804ca..fd39bde118 100644 --- a/indra/newview/llspeakbutton.cpp +++ b/indra/newview/llspeakbutton.cpp @@ -119,6 +119,9 @@ LLSpeakButton::LLSpeakButton(const Params& p) // never show "muted" because you can't mute yourself mOutputMonitor->setIsMuted(false); mOutputMonitor->setIsAgentControl(true); + + //*TODO find a better place to do that + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1)); } LLSpeakButton::~LLSpeakButton() diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 3769ddb1cc..26f9824f9c 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -48,6 +48,8 @@ #include "llchiclet.h" #include "lltoastpanel.h" #include "llnotificationmanager.h" +#include "llnotificationsutil.h" +#include "llspeakers.h" //--------------------------------------------------------------------------------- LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key), @@ -350,6 +352,8 @@ LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& } // Initialize chiclet. + mChiclet->setChicletSizeChangedCallback(boost::bind(&LLIMWellWindow::RowPanel::onChicletSizeChanged, this, mChiclet, _2)); + mChiclet->enableCounterControl(true); mChiclet->setCounter(chicletCounter); mChiclet->setSessionId(sessionId); mChiclet->setIMSessionName(name); @@ -364,6 +368,16 @@ LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& } //--------------------------------------------------------------------------------- +void LLIMWellWindow::RowPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param) +{ + LLTextBox* text = getChild<LLTextBox>("contact_name"); + S32 new_text_left = mChiclet->getRect().mRight + CHICLET_HPAD; + LLRect text_rect = text->getRect(); + text_rect.mLeft = new_text_left; + text->setRect(text_rect); +} + +//--------------------------------------------------------------------------------- LLIMWellWindow::RowPanel::~RowPanel() { } @@ -610,6 +624,23 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p) } } +void LLNotificationWellWindow::closeAll() +{ + // Need to clear notification channel, to add storable toasts into the list. + clearScreenChannels(); + std::vector<LLPanel*> items; + mMessageList->getItems(items); + for (std::vector<LLPanel*>::iterator + iter = items.begin(), + iter_end = items.end(); + iter != iter_end; ++iter) + { + LLSysWellItem* sys_well_item = dynamic_cast<LLSysWellItem*>(*iter); + if (sys_well_item) + onItemClose(sys_well_item); + } +} + ////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS void LLNotificationWellWindow::initChannel() @@ -891,4 +922,80 @@ void LLIMWellWindow::onNewIM(const LLSD& data) } +void LLIMWellWindow::closeAll() +{ + // Generate an ignorable alert dialog if there is an active voice IM sesion + bool need_confirmation = false; + const LLIMModel& im_model = LLIMModel::instance(); + std::vector<LLSD> values; + mMessageList->getValues(values); + for (std::vector<LLSD>::iterator + iter = values.begin(), + iter_end = values.end(); + iter != iter_end; ++iter) + { + LLIMSpeakerMgr* speaker_mgr = im_model.getSpeakerManager(*iter); + if (speaker_mgr && speaker_mgr->isVoiceActive()) + { + need_confirmation = true; + break; + } + } + if ( need_confirmation ) + { + //Bring up a confirmation dialog + LLNotificationsUtil::add + ("ConfirmCloseAll", LLSD(), LLSD(), + boost::bind(&LLIMWellWindow::confirmCloseAll, this, _1, _2)); + } + else + { + closeAllImpl(); + } +} + +void LLIMWellWindow::closeAllImpl() +{ + std::vector<LLSD> values; + mMessageList->getValues(values); + + for (std::vector<LLSD>::iterator + iter = values.begin(), + iter_end = values.end(); + iter != iter_end; ++iter) + { + LLPanel* panel = mMessageList->getItemByValue(*iter); + + RowPanel* im_panel = dynamic_cast <RowPanel*> (panel); + if (im_panel) + { + gIMMgr->leaveSession(*iter); + continue; + } + + ObjectRowPanel* obj_panel = dynamic_cast <ObjectRowPanel*> (panel); + if (obj_panel) + { + LLScriptFloaterManager::instance() + .removeNotificationByObjectId(*iter); + } + } +} + +bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch(option) + { + case 0: + { + closeAllImpl(); + return true; + } + default: + break; + } + return false; +} + // EOF diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 736b1b9fb4..6cfa25b84d 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -147,6 +147,9 @@ public: // Operating with items void addItem(LLSysWellItem::Params p); + // Closes all notifications and removes them from the Notification Well + void closeAll(); + protected: /*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; } @@ -196,6 +199,8 @@ public: void addIMRow(const LLUUID& session_id); bool hasIMRow(const LLUUID& session_id); + void closeAll(); + protected: /*virtual*/ const std::string& getAnchorViewName() { return IM_WELL_ANCHOR_NAME; } @@ -205,7 +210,8 @@ private: void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId); void delIMRow(const LLUUID& sessionId); - + bool confirmCloseAll(const LLSD& notification, const LLSD& response); + void closeAllImpl(); /** * Scrolling row panel. @@ -220,6 +226,8 @@ private: void onMouseLeave(S32 x, S32 y, MASK mask); BOOL handleMouseDown(S32 x, S32 y, MASK mask); private: + static const S32 CHICLET_HPAD = 10; + void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param); void onClosePanel(); public: LLIMChiclet* mChiclet; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5cfd587bd1..23bcca9603 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -439,6 +439,12 @@ void init_menus() // menu holder appears on top of menu bar so you can see the menu title // flash when an item is triggered (the flash occurs in the holder) gViewerWindow->getRootView()->addChild(gMenuHolder); + + // This removes tool tip view from main view and adds it + // to root view in front of menu holder. + // Otherwise tool tips for menu items would be overlapped by menu, since + // main view is behind of menu holder now. + gViewerWindow->getRootView()->addChild(gToolTipView); gViewerWindow->setMenuBackgroundColor(false, LLViewerLogin::getInstance()->isInProductionGrid()); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ea40f2aae1..6a31bbfa1e 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1078,6 +1078,28 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); } + // *NOTE dzaporozhan + // Restored from viewer-1-23 to fix EXT-3520 + // Saves Group Notice Attachments to inventory. + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ImprovedInstantMessage); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_MessageBlock); + msg->addBOOLFast(_PREHASH_FromGroup, FALSE); + msg->addUUIDFast(_PREHASH_ToAgentID, mFromID); + msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); + msg->addUUIDFast(_PREHASH_ID, mTransactionID); + msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary + std::string name; + LLAgentUI::buildFullname(name); + msg->addStringFast(_PREHASH_FromAgentName, name); + msg->addStringFast(_PREHASH_Message, ""); + msg->addU32Fast(_PREHASH_ParentEstateID, 0); + msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); + msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); + std::string from_string; // Used in the pop-up. std::string chatHistory_string; // Used in chat history. @@ -1129,6 +1151,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // Show falls through to accept. case IOR_ACCEPT: + msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1)); + msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData), sizeof(mFolderID.mData)); + msg->sendReliable(mHost); + //don't spam them if they are getting flooded if (check_offer_throttle(mFromName, true)) { diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 60a2c3b638..69d2458217 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -316,8 +316,6 @@ void LLVoiceChannel::activate() } } - sCurrentVoiceChannelChangedSignal(this->mSessionID); - if (mState == STATE_NO_CHANNEL_INFO) { // responsible for setting status to active @@ -327,6 +325,9 @@ void LLVoiceChannel::activate() { setState(STATE_CALL_STARTED); } + + //do not send earlier, channel should be initialized, should not be in STATE_NO_CHANNEL_INFO state + sCurrentVoiceChannelChangedSignal(this->mSessionID); } void LLVoiceChannel::getChannelInfo() diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 4dbfd5bc81..412f8b6d68 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -50,8 +50,10 @@ with the same filename but different name <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true" /> <texture name="Arrow_Right_Press" file_name="navbar/Arrow_Right_Press.png" preload="true" /> +<!-- <texture name="Arrow_Left" file_name="widgets/Arrow_Left.png" preload="true" /> <texture name="Arrow_Right" file_name="widgets/Arrow_Right.png" preload="true" /> +--> <texture name="Arrow_Small_Up" file_name="widgets/Arrow_Small_Up.png" preload="true" /> <texture name="Arrow_Small_Left" file_name="widgets/Arrow_Small_Left.png" preload="true" /> diff --git a/indra/newview/skins/default/xui/en/menu_im_well_button.xml b/indra/newview/skins/default/xui/en/menu_im_well_button.xml new file mode 100644 index 0000000000..f8dfba91ff --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_im_well_button.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<context_menu + layout="topleft" + name="IM Well Button Context Menu"> + <menu_item_call + label="Close All" + layout="topleft" + name="Close All"> + <menu_item_call.on_click + function="IMWellChicletMenu.Action" + parameter="close all" /> + <menu_item_call.on_enable + function="IMWellChicletMenu.EnableItem" + parameter="can close all" /> + </menu_item_call> +</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml new file mode 100644 index 0000000000..263ac40f4e --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<context_menu + layout="topleft" + name="Notification Well Button Context Menu"> + <menu_item_call + label="Close All" + layout="topleft" + name="Close All"> + <menu_item_call.on_click + function="NotificationWellChicletMenu.Action" + parameter="close all" /> + <menu_item_call.on_enable + function="NotificationWellChicletMenu.EnableItem" + parameter="can close all" /> + </menu_item_call> +</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml index 449202aaaa..faf33bd1b1 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml @@ -51,6 +51,8 @@ <menu_item_call.on_click function="Avatar.Pay" /> </menu_item_call> + <menu_item_separator + layout="topleft" /> <menu_item_check label="Block Voice" layout="topleft" @@ -64,8 +66,6 @@ function="ParticipantList.EnableItem" parameter="can_block" /> </menu_item_check> - <menu_item_separator - layout="topleft" /> <menu_item_check label="Block Text" layout="topleft" @@ -79,6 +79,8 @@ function="ParticipantList.EnableItem" parameter="can_mute_text" /> </menu_item_check> + <menu_item_separator + layout="topleft" /> <context_menu label="Moderator Options >" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 87d1fc071d..d4b712e048 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5773,6 +5773,17 @@ They will be blocked for a few seconds for your security. </form> </notification> + <notification + icon="alert.tga" + name="ConfirmCloseAll" + type="alertmodal"> +Are you sure you want to close all IMs? + <usetemplate + name="okcancelignore" + notext="Cancel" + yestext="Ok"/> + </notification> + <notification icon="notifytip.tga" name="AttachmentSaved" type="notifytip"> Attachment has been saved. diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml index 3ed91cb48f..3416b2369d 100644 --- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml +++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml @@ -69,9 +69,9 @@ name="contact_name" layout="topleft" top="10" - left_pad="20" + left_pad="10" height="14" - width="245" + width="255" length="1" follows="right|left" use_ellipses="true" 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 index 0a3fd1699f..30e652befd 100644 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml @@ -21,32 +21,32 @@ value="Unknown" width="100" /> <button - follows="left|top" + follows="left|top|right" height="20" label="Profile" name="view_profile_btn" width="100" /> <button - follows="left|top" + follows="left|top|right" height="20" label="Add Friend" name="add_friend_btn" width="100" /> <button - follows="left|top" + follows="left|top|right" height="20" label="Teleport" name="teleport_btn" width="100" /> <button - follows="left|top" + follows="left|top|right" height="20" label="Share" name="share_btn" width="100" /> <!--Removing pay button to save space - will update spec - verified by Erica/Steve --> <!-- <button - follows="left|top" + follows="left|top|right" height="20" label="Pay" name="pay_btn" @@ -56,13 +56,14 @@ bg_alpha_color="DkGray2" border="false" top_pad="10" - follows="left|bottom" + follows="left|bottom|right" height="70" left="1" name="panel_call_buttons" width="109"> <button bottom="10" + follows="left|top|right" height="20" label="Call" left_delta="5" @@ -70,6 +71,7 @@ width="100" /> <button bottom="35" + follows="left|top|right" height="20" label="Leave Call" name="end_call_btn" @@ -77,6 +79,7 @@ width="100" /> <button bottom="10" + follows="left|top|right" height="20" label="Voice Controls" name="voice_ctrls_btn" diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 68e58b27ec..9f06e64560 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -60,6 +60,7 @@ layout="topleft" left="10" name="back_btn" + tool_tip="Back" tab_stop="false" top="0" width="23" /> diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index c3138bb443..8fc2ae39f0 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -145,6 +145,7 @@ layout="topleft" left="10" name="back_btn" + tool_tip="Back" tab_stop="false" top="0" width="23" /> diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index db03f334e5..8a5c023133 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -96,6 +96,7 @@ background_visible="true" layout="topleft" left_pad="5" name="edit_btn" + tool_tip="Edit landmark information" top="0" width="70" /> <button @@ -106,6 +107,7 @@ background_visible="true" image_unselected="ForwardArrow_Off" layout="topleft" name="overflow_btn" + tool_tip="Show additional options" right="-10" top="0" width="18" /> diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml index 3384852f27..4f40e00815 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml @@ -55,6 +55,7 @@ left_pad="5" right="-3" name="profile_btn" + tool_tip="Show item info" top="1" visible="false" width="20" /> |