summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llflatlistview.cpp6
-rw-r--r--indra/llui/llmenugl.cpp2
-rw-r--r--indra/newview/llavatarlist.cpp15
-rw-r--r--indra/newview/llavatarlist.h12
-rw-r--r--indra/newview/llbottomtray.cpp5
-rw-r--r--indra/newview/llcallfloater.cpp29
-rw-r--r--indra/newview/llcallfloater.h8
-rw-r--r--indra/newview/llchathistory.cpp37
-rw-r--r--indra/newview/llchiclet.cpp224
-rw-r--r--indra/newview/llchiclet.h98
-rw-r--r--indra/newview/llfavoritesbar.cpp9
-rw-r--r--indra/newview/llimview.cpp77
-rw-r--r--indra/newview/llparticipantlist.cpp27
-rw-r--r--indra/newview/llparticipantlist.h6
-rw-r--r--indra/newview/llspeakbutton.cpp3
-rw-r--r--indra/newview/llsyswellwindow.cpp107
-rw-r--r--indra/newview/llsyswellwindow.h10
-rw-r--r--indra/newview/llviewermenu.cpp6
-rw-r--r--indra/newview/llviewermessage.cpp26
-rw-r--r--indra/newview/llvoicechannel.cpp5
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_im_well_button.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_notification_well_button.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_participant_list.xml6
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_activeim_row.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml15
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_place_profile.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history_item.xml1
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 &gt;"
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" />