summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llavataractions.cpp7
-rw-r--r--indra/newview/llavatarlist.cpp11
-rw-r--r--indra/newview/llavatarlistitem.cpp29
-rw-r--r--indra/newview/llavatarlistitem.h5
-rw-r--r--indra/newview/llbottomtray.cpp13
-rw-r--r--indra/newview/llbottomtray.h2
-rw-r--r--indra/newview/llcallfloater.cpp2
-rw-r--r--indra/newview/llchannelmanager.cpp2
-rw-r--r--indra/newview/llchathistory.cpp4
-rw-r--r--indra/newview/llchiclet.cpp93
-rw-r--r--indra/newview/llchiclet.h61
-rw-r--r--indra/newview/llfloateravatarpicker.cpp53
-rw-r--r--indra/newview/llfloateravatarpicker.h9
-rw-r--r--indra/newview/llgrouplist.cpp26
-rw-r--r--indra/newview/llgrouplist.h6
-rw-r--r--indra/newview/llimfloater.cpp1
-rw-r--r--indra/newview/llimview.cpp241
-rw-r--r--indra/newview/llimview.h64
-rw-r--r--indra/newview/llinventorypanel.cpp8
-rw-r--r--indra/newview/llmoveview.cpp2
-rw-r--r--indra/newview/llnotificationhandler.h5
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp22
-rw-r--r--indra/newview/llnotificationofferhandler.cpp58
-rw-r--r--indra/newview/llpanellandmarks.cpp5
-rw-r--r--indra/newview/llpanelme.cpp7
-rw-r--r--indra/newview/llpanelme.h2
-rw-r--r--indra/newview/llpanelpeople.cpp26
-rw-r--r--indra/newview/llpanelpeople.h3
-rw-r--r--indra/newview/llpanelpicks.cpp7
-rw-r--r--indra/newview/llpanelprofile.cpp6
-rw-r--r--indra/newview/llpanelprofile.h2
-rw-r--r--indra/newview/llpanelteleporthistory.cpp25
-rw-r--r--indra/newview/llscreenchannel.cpp35
-rw-r--r--indra/newview/llscreenchannel.h7
-rw-r--r--indra/newview/llscriptfloater.cpp17
-rw-r--r--indra/newview/llscriptfloater.h2
-rw-r--r--indra/newview/llsidetray.h5
-rw-r--r--indra/newview/llsyswellwindow.cpp537
-rw-r--r--indra/newview/llsyswellwindow.h107
-rw-r--r--indra/newview/lltoast.cpp33
-rw-r--r--indra/newview/lltoast.h9
-rw-r--r--indra/newview/lltoastimpanel.cpp16
-rw-r--r--indra/newview/lltoastimpanel.h3
-rw-r--r--indra/newview/llviewerfloaterreg.cpp4
-rw-r--r--indra/newview/llviewerinventory.cpp3
-rw-r--r--indra/newview/llviewermessage.cpp58
-rw-r--r--indra/newview/llvoicechannel.cpp59
-rw-r--r--indra/newview/skins/default/textures/textures.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_sys_well.xml16
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml68
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_instant_message.xml11
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/floater.xml2
57 files changed, 1229 insertions, 600 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 76b967eb82..9f525d82b9 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -410,6 +410,7 @@ set(viewer_SOURCE_FILES
lltexturestats.cpp
lltexturestatsuploader.cpp
lltextureview.cpp
+ lltextutil.cpp
lltoast.cpp
lltoastalertpanel.cpp
lltoastgroupnotifypanel.cpp
@@ -913,6 +914,7 @@ set(viewer_HEADER_FILES
lltexturestats.h
lltexturestatsuploader.h
lltextureview.h
+ lltextutil.h
lltoast.h
lltoastalertpanel.h
lltoastgroupnotifypanel.h
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index a7a6da3ac2..5af023f565 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -487,6 +487,13 @@ void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::stri
IM_ONLINE,
IM_FRIENDSHIP_OFFERED,
calling_card_folder_id);
+
+ LLSD args;
+ args["TO_NAME"] = target_name;
+ LLSD payload;
+ payload["SESSION_NAME"] = target_name;
+ payload["SUPPRES_TOST"] = true;
+ LLNotificationsUtil::add("FriendshipOffered", args, payload);
}
//static
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 202fbdebd4..3bd4f898c8 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -262,9 +262,18 @@ void LLAvatarList::refresh()
bool dirty = add_limit_exceeded || (have_filter && !have_names);
setDirty(dirty);
- // Refreshed all items, lets send refresh_complete signal.
+ // Refreshed all items.
if(!dirty)
{
+ // Highlight items matching the filter.
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++)
+ {
+ static_cast<LLAvatarListItem*>(*it)->setHighlight(mNameFilter);
+ }
+
+ // Send refresh_complete signal.
std::vector<LLSD> cur_values;
getValues(cur_values);
mRefreshCompleteSignal(this, LLSD((S32)cur_values.size()));
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 59ed391c06..072eebdf2d 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -40,6 +40,7 @@
#include "llagent.h"
#include "lloutputmonitorctrl.h"
#include "llavatariconctrl.h"
+#include "lltextutil.h"
#include "llbutton.h"
LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
@@ -155,13 +156,8 @@ void LLAvatarListItem::setOnline(bool online)
mOnlineStatus = (EOnlineStatus) online;
// Change avatar name font style depending on the new online status.
- LLStyle::Params style_params;
- style_params.color = online ? LLColor4::white : LLColor4::grey;
-
- // Rebuild the text to change its style.
- std::string text = mAvatarName->getText();
- mAvatarName->setText(LLStringUtil::null);
- mAvatarName->appendText(text, false, style_params);
+ mAvatarNameStyle.color = online ? LLColor4::white : LLColor4::grey;
+ setNameInternal(mAvatarName->getText(), mHighlihtSubstring);
// Make the icon fade if the avatar goes offline.
mAvatarIcon->setColor(online ? LLColor4::white : LLColor4::smoke);
@@ -169,8 +165,12 @@ void LLAvatarListItem::setOnline(bool online)
void LLAvatarListItem::setName(const std::string& name)
{
- mAvatarName->setValue(name);
- mAvatarName->setToolTip(name);
+ setNameInternal(name, mHighlihtSubstring);
+}
+
+void LLAvatarListItem::setHighlight(const std::string& highlight)
+{
+ setNameInternal(mAvatarName->getText(), mHighlihtSubstring = highlight);
}
void LLAvatarListItem::setAvatarId(const LLUUID& id, bool ignore_status_changes)
@@ -310,11 +310,18 @@ const std::string LLAvatarListItem::getAvatarName() const
return mAvatarName->getValue();
}
+//== PRIVATE SECITON ==========================================================
+
+void LLAvatarListItem::setNameInternal(const std::string& name, const std::string& highlight)
+{
+ LLTextUtil::textboxSetHighlightedVal(mAvatarName, mAvatarNameStyle, name, highlight);
+ mAvatarName->setToolTip(name);
+}
+
void LLAvatarListItem::onNameCache(const std::string& first_name, const std::string& last_name)
{
std::string name = first_name + " " + last_name;
- mAvatarName->setValue(name);
- mAvatarName->setToolTip(name);
+ setName(name);
}
void LLAvatarListItem::reshapeAvatarName()
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index a7b080098d..aa1b7593f5 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -37,6 +37,7 @@
#include "lloutputmonitorctrl.h"
#include "llbutton.h"
#include "lltextbox.h"
+#include "llstyle.h"
#include "llcallingcard.h" // for LLFriendObserver
@@ -71,6 +72,7 @@ public:
void setOnline(bool online);
void setName(const std::string& name);
+ void setHighlight(const std::string& highlight);
void setAvatarId(const LLUUID& id, bool ignore_status_changes = false);
void setLastInteractionTime(U32 secs_since);
//Show/hide profile/info btn, translating speaker indicator and avatar name coordinates accordingly
@@ -112,6 +114,7 @@ private:
E_UNKNOWN,
} EOnlineStatus;
+ void setNameInternal(const std::string& name, const std::string& highlight);
void onNameCache(const std::string& first_name, const std::string& last_name);
std::string formatSeconds(U32 secs);
@@ -119,12 +122,14 @@ private:
LLAvatarIconCtrl* mAvatarIcon;
LLTextBox* mAvatarName;
LLTextBox* mLastInteractionTime;
+ LLStyle::Params mAvatarNameStyle;
LLButton* mInfoBtn;
LLButton* mProfileBtn;
ContextMenu* mContextMenu;
LLUUID mAvatarId;
+ std::string mHighlihtSubstring; // substring to highlight
EOnlineStatus mOnlineStatus;
//Flag indicating that info/profile button shouldn't be shown at all.
//Speaker indicator and avatar name coords are translated accordingly
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 6d3d61d4fe..8c793873f4 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -54,25 +54,24 @@ template class LLBottomTray* LLSingleton<class LLBottomTray>::getInstance();
LLBottomTray::LLBottomTray(const LLSD&)
: mChicletPanel(NULL),
- mSysWell(NULL),
mSpeakPanel(NULL),
mSpeakBtn(NULL),
mNearbyChatBar(NULL),
mToolbarStack(NULL)
, mMovementButton(NULL)
, mResizeState(RS_NORESIZE)
-// Add more members
+, mBottomTrayContextMenu(NULL)
+, mMovementPanel(NULL)
+, mCamPanel(NULL)
+, mSnapshotPanel(NULL)
+, mGesturePanel(NULL)
+, mCamButton(NULL)
{
mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml");
mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
- mSysWell = getChild<LLNotificationChiclet>("sys_well");
-
- // init mSysWell
- // set handler for a Click operation
- mSysWell->setClickCallback(boost::bind(&LLSysWellWindow::onChicletClick, LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")));
mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 91ec01654b..fa204ee9ea 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -66,7 +66,6 @@ public:
BOOL postBuild();
LLChicletPanel* getChicletPanel() {return mChicletPanel;}
- LLNotificationChiclet* getSysWell() {return mSysWell;}
LLNearbyChatBar* getNearbyChatBar() {return mNearbyChatBar;}
void onCommitGesture(LLUICtrl* ctrl);
@@ -189,7 +188,6 @@ protected:
LLIMChiclet* createIMChiclet(const LLUUID& session_id);
LLChicletPanel* mChicletPanel;
- LLNotificationChiclet* mSysWell;
LLPanel* mSpeakPanel;
LLSpeakButton* mSpeakBtn;
LLNearbyChatBar* mNearbyChatBar;
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index ad59c780f3..895b4ed80e 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -127,7 +127,7 @@ void LLCallFloater::onOpen(const LLSD& /*key*/)
void LLCallFloater::leaveCall()
{
LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
- if (voice_channel && voice_channel->isActive())
+ if (voice_channel)
{
voice_channel->deactivate();
}
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 94c303a30f..415c118ff1 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -129,7 +129,7 @@ void LLChannelManager::onLoginCompleted()
S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
- mStartUpChannel->setMouseDownCallback(boost::bind(&LLSysWellWindow::onStartUpToastClick, LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window"), _2, _3, _4));
+ mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));
mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 96b5ae5908..efe9ea4c35 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -211,6 +211,10 @@ public:
{
icon->setValue(chat.mFromID);
}
+ else if (userName->getValue().asString()==LLTrans::getString("SECOND_LIFE"))
+ {
+ icon->setValue(LLSD("SL_Logo"));
+ }
}
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 588855d088..4b3b7a99d8 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -55,6 +55,7 @@
#include "lltransientfloatermgr.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
+static LLDefaultChildRegistry::Register<LLIMWellChiclet> t2_0("chiclet_im_well");
static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
@@ -69,7 +70,6 @@ static const S32 OVERLAY_ICON_SHIFT = 2; // used for shifting of an overlay icon
// static
const S32 LLChicletPanel::s_scroll_ratio = 10;
-S32 LLNotificationChiclet::mUreadSystemNotifications = 0;
boost::signals2::signal<LLChiclet* (const LLUUID&),
LLIMChiclet::CollectChicletCombiner<std::list<LLChiclet*> > >
@@ -78,7 +78,7 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLNotificationChiclet::Params::Params()
+LLSysWellChiclet::Params::Params()
: button("button")
, unread_notifications("unread_notifications")
{
@@ -88,7 +88,7 @@ LLNotificationChiclet::Params::Params()
}
-LLNotificationChiclet::LLNotificationChiclet(const Params& p)
+LLSysWellChiclet::LLSysWellChiclet(const Params& p)
: LLChiclet(p)
, mButton(NULL)
, mCounter(0)
@@ -96,30 +96,14 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
LLButton::Params button_params = p.button;
mButton = LLUICtrlFactory::create<LLButton>(button_params);
addChild(mButton);
-
- // connect counter handlers to the signals
- connectCounterUpdatersToSignal("notify");
- connectCounterUpdatersToSignal("groupnotify");
- connectCounterUpdatersToSignal("offer");
}
-LLNotificationChiclet::~LLNotificationChiclet()
+LLSysWellChiclet::~LLSysWellChiclet()
{
}
-void LLNotificationChiclet::connectCounterUpdatersToSignal(std::string notification_type)
-{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
- {
- n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
- n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
- }
-}
-
-void LLNotificationChiclet::setCounter(S32 counter)
+void LLSysWellChiclet::setCounter(S32 counter)
{
std::string s_count;
if(counter != 0)
@@ -132,16 +116,64 @@ void LLNotificationChiclet::setCounter(S32 counter)
mCounter = counter;
}
-boost::signals2::connection LLNotificationChiclet::setClickCallback(
+boost::signals2::connection LLSysWellChiclet::setClickCallback(
const commit_callback_t& cb)
{
return mButton->setClickedCallback(cb);
}
-void LLNotificationChiclet::setToggleState(BOOL toggled) {
+void LLSysWellChiclet::setToggleState(BOOL toggled) {
mButton->setToggleState(toggled);
}
+
+/************************************************************************/
+/* LLIMWellChiclet implementation */
+/************************************************************************/
+LLIMWellChiclet::LLIMWellChiclet(const Params& p)
+: LLSysWellChiclet(p)
+{
+ LLIMModel::instance().addNewMsgCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
+ LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
+
+ LLIMMgr::getInstance()->addSessionObserver(this);
+}
+
+LLIMWellChiclet::~LLIMWellChiclet()
+{
+ LLIMMgr::getInstance()->removeSessionObserver(this);
+}
+
+void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
+{
+ S32 total_unread = LLIMMgr::instance().getNumberOfUnreadParticipantMessages();
+ setCounter(total_unread);
+}
+
+/************************************************************************/
+/* LLNotificationChiclet implementation */
+/************************************************************************/
+LLNotificationChiclet::LLNotificationChiclet(const Params& p)
+: LLSysWellChiclet(p)
+, mUreadSystemNotifications(0)
+{
+ // connect counter handlers to the signals
+ connectCounterUpdatersToSignal("notify");
+ connectCounterUpdatersToSignal("groupnotify");
+ connectCounterUpdatersToSignal("offer");
+}
+
+void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type)
+{
+ LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
+ LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
+ if(n_handler)
+ {
+ n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
+ n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
+ }
+}
+
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -395,6 +427,10 @@ LLIMP2PChiclet::LLIMP2PChiclet(const Params& p)
sendChildToFront(mNewMessagesIcon);
setShowSpeaker(p.show_speaker);
+
+ //since mShowSpeaker initialized with false
+ //setShowSpeaker(false) will not hide mSpeakerCtrl
+ mSpeakerCtrl->setVisible(getShowSpeaker());
}
void LLIMP2PChiclet::setCounter(S32 counter)
@@ -880,16 +916,7 @@ LLChicletPanel::~LLChicletPanel()
void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
LLUUID session_id = data["session_id"].asUUID();
- LLUUID from_id = data["from_id"].asUUID();
- const std::string from = data["from"].asString();
- S32 unread = data["num_unread"].asInteger();
-
- // if new message came
- if(unread != 0)
- {
- //we do not show balloon (indicator of new messages) for system messages and our own messages
- if (from_id.isNull() || from_id == gAgentID || SYSTEM_FROM == from) return;
- }
+ S32 unread = data["participant_unread"].asInteger();
LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
if (im_floater && im_floater->getVisible())
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index c75ad2b546..609ce16713 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -39,6 +39,7 @@
#include "lltextbox.h"
#include "lloutputmonitorctrl.h"
#include "llgroupmgr.h"
+#include "llimview.h"
class LLVoiceControlPanel;
class LLMenuGL;
@@ -746,7 +747,7 @@ private:
* Implements notification chiclet. Used to display total amount of unread messages
* across all IM sessions, total amount of system notifications.
*/
-class LLNotificationChiclet : public LLChiclet
+class LLSysWellChiclet : public LLChiclet
{
public:
@@ -768,28 +769,68 @@ public:
boost::signals2::connection setClickCallback(const commit_callback_t& cb);
- /*virtual*/ ~LLNotificationChiclet();
+ /*virtual*/ ~LLSysWellChiclet();
- // methods for updating a number of unread System notifications
- void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
- void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }
void setToggleState(BOOL toggled);
protected:
- // connect counter updaters to the corresponding signals
- void connectCounterUpdatersToSignal(std::string notification_type);
- LLNotificationChiclet(const Params& p);
+ LLSysWellChiclet(const Params& p);
friend class LLUICtrlFactory;
- static S32 mUreadSystemNotifications;
-
protected:
LLButton* mButton;
S32 mCounter;
};
/**
+ * Class represented a chiclet for IM Well Icon.
+ *
+ * It displays a count of unread messages from other participants in all IM sessions.
+ */
+class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
+{
+ friend class LLUICtrlFactory;
+public:
+ virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
+ virtual void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
+ virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
+
+ ~LLIMWellChiclet();
+protected:
+ LLIMWellChiclet(const Params& p);
+
+ /**
+ * 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.
+ *
+ * @param[in] session_data contains session related data, is not used now
+ * ["session_id"] - id of an appropriate session
+ * ["participant_unread"] - count of unread messages from "real" participants.
+ *
+ * @see LLIMMgr::getNumberOfUnreadParticipantMessages()
+ */
+ void messageCountChanged(const LLSD& session_data);
+};
+
+class LLNotificationChiclet : public LLSysWellChiclet
+{
+ friend class LLUICtrlFactory;
+protected:
+ LLNotificationChiclet(const Params& p);
+
+ // connect counter updaters to the corresponding signals
+ void connectCounterUpdatersToSignal(const std::string& notification_type);
+
+ // methods for updating a number of unread System notifications
+ void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
+ void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }
+
+ S32 mUreadSystemNotifications;
+};
+
+/**
* Storage class for all IM chiclets. Provides mechanism to display,
* scroll, create, remove chiclets.
*/
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 07bb6f832b..6e3d5499a2 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -140,9 +140,14 @@ BOOL LLFloaterAvatarPicker::postBuild()
return TRUE;
}
+void LLFloaterAvatarPicker::setOkBtnEnableCb(validate_callback_t cb)
+{
+ mOkButtonValidateSignal.connect(cb);
+}
+
void LLFloaterAvatarPicker::onTabChanged()
{
- childSetEnabled("ok_btn", visibleItemsSelected());
+ childSetEnabled("ok_btn", isSelectBtnEnabled());
}
// Destroys the object
@@ -175,6 +180,10 @@ void LLFloaterAvatarPicker::onBtnSelect(void* userdata)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
+ // If select btn not enabled then do not callback
+ if (!self || !self->isSelectBtnEnabled())
+ return;
+
if(self->mCallback)
{
std::string acvtive_panel_name;
@@ -244,7 +253,7 @@ void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata)
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
if (self)
{
- self->childSetEnabled("ok_btn", self->visibleItemsSelected());
+ self->childSetEnabled("ok_btn", self->isSelectBtnEnabled());
}
}
@@ -477,3 +486,43 @@ BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask)
return LLFloater::handleKeyHere(key, mask);
}
+
+bool LLFloaterAvatarPicker::isSelectBtnEnabled()
+{
+ bool ret_val = visibleItemsSelected();
+
+ if ( ret_val && mOkButtonValidateSignal.num_slots() )
+ {
+ std::string acvtive_panel_name;
+ LLScrollListCtrl* list = NULL;
+ LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs");
+
+ if(active_panel)
+ {
+ acvtive_panel_name = active_panel->getName();
+ }
+
+ if(acvtive_panel_name == "SearchPanel")
+ {
+ list = getChild<LLScrollListCtrl>("SearchResults");
+ }
+ else if(acvtive_panel_name == "NearMePanel")
+ {
+ list = getChild<LLScrollListCtrl>("NearMe");
+ }
+ else if (acvtive_panel_name == "FriendsPanel")
+ {
+ list = getChild<LLScrollListCtrl>("Friends");
+ }
+
+ if(list)
+ {
+ std::vector<LLUUID> avatar_ids;
+ std::vector<std::string> avatar_names;
+ getSelectedAvatarData(list, avatar_names, avatar_ids);
+ return mOkButtonValidateSignal(avatar_ids);
+ }
+ }
+
+ return ret_val;
+}
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index b8ace985d9..13e491834e 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -40,6 +40,9 @@
class LLFloaterAvatarPicker : public LLFloater
{
public:
+ typedef boost::signals2::signal<bool(const std::vector<LLUUID>&), boost_boolean_combiner> validate_signal_t;
+ typedef validate_signal_t::slot_type validate_callback_t;
+
// Call this to select an avatar.
// The callback function will be called with an avatar name and UUID.
typedef void(*callback_t)(const std::vector<std::string>&, const std::vector<LLUUID>&, void*);
@@ -53,6 +56,8 @@ public:
virtual BOOL postBuild();
+ void setOkBtnEnableCb(validate_callback_t cb);
+
static void processAvatarPickerReply(class LLMessageSystem* msg, void**);
private:
@@ -65,7 +70,8 @@ private:
static void onBtnClose(void* userdata);
static void onList(class LLUICtrl* ctrl, void* userdata);
void onTabChanged();
-
+ bool isSelectBtnEnabled();
+
void populateNearMe();
void populateFriend();
BOOL visibleItemsSelected() const; // Returns true if any items in the current tab are selected.
@@ -83,6 +89,7 @@ private:
void (*mCallback)(const std::vector<std::string>& name, const std::vector<LLUUID>& id, void* userdata);
void* mCallbackUserdata;
+ validate_signal_t mOkButtonValidateSignal;
};
#endif
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 97cf139f1d..80b706a215 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -44,6 +44,7 @@
#include "llagent.h"
#include "llgroupactions.h"
#include "llfloaterreg.h"
+#include "lltextutil.h"
#include "llviewercontrol.h" // for gSavedSettings
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
@@ -133,17 +134,17 @@ void LLGroupList::refresh()
const LLGroupData& group_data = gAgent.mGroups.get(i);
if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
continue;
- addNewItem(id, group_data.mName, group_data.mInsigniaID, highlight_id == id, ADD_BOTTOM);
+ addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
}
// Sort the list.
sort();
- // add "none" to list at top
+ // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
+ if (!have_filter)
{
std::string loc_none = LLTrans::getString("GroupsNone");
- if (have_filter || findInsensitive(loc_none, mNameFilter))
- addNewItem(LLUUID::null, loc_none, LLUUID::null, highlight_id.isNull(), ADD_TOP);
+ addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
}
selectItemByUUID(highlight_id);
@@ -171,12 +172,12 @@ void LLGroupList::toggleIcons()
// PRIVATE Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos)
+void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
{
LLGroupListItem* item = new LLGroupListItem();
- item->setName(name);
item->setGroupID(id);
+ item->setName(name, mNameFilter);
item->setGroupIconID(icon_id);
// item->setContextMenu(mContextMenu);
@@ -267,10 +268,10 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
LLPanel::onMouseLeave(x, y, mask);
}
-void LLGroupListItem::setName(const std::string& name)
+void LLGroupListItem::setName(const std::string& name, const std::string& highlight)
{
mGroupName = name;
- mGroupNameBox->setValue(name);
+ LLTextUtil::textboxSetHighlightedVal(mGroupNameBox, mGroupNameStyle, name, highlight);
mGroupNameBox->setToolTip(name);
}
@@ -308,6 +309,8 @@ void LLGroupListItem::setGroupIconVisible(bool visible)
//////////////////////////////////////////////////////////////////////////
void LLGroupListItem::setActive(bool active)
{
+ // *BUG: setName() overrides the style params.
+
// Active group should be bold.
LLFontDescriptor new_desc(mGroupNameBox->getDefaultFont()->getFontDesc());
@@ -316,15 +319,12 @@ void LLGroupListItem::setActive(bool active)
// is predefined as bold (SansSerifSmallBold, for example)
new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
LLFontGL* new_font = LLFontGL::getFont(new_desc);
- LLStyle::Params style_params;
- style_params.font = new_font;
+ mGroupNameStyle.font = new_font;
// *NOTE: You cannot set the style on a text box anymore, you must
// rebuild the text. This will cause problems if the text contains
// hyperlinks, as their styles will be wrong.
- std::string text = mGroupNameBox->getText();
- mGroupNameBox->setText(LLStringUtil::null);
- mGroupNameBox->appendText(text, false, style_params);
+ mGroupNameBox->setText(mGroupName, mGroupNameStyle);
}
void LLGroupListItem::onInfoBtnClick()
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 8dbc13997c..41b4d01711 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -37,6 +37,7 @@
#include "llflatlistview.h"
#include "llpanel.h"
#include "llpointer.h"
+#include "llstyle.h"
/**
* Auto-updating list of agent groups.
@@ -66,7 +67,7 @@ public:
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
- void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+ void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM);
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
bool mShowIcons;
@@ -90,7 +91,7 @@ public:
const LLUUID& getGroupID() const { return mGroupID; }
const std::string& getGroupName() const { return mGroupName; }
- void setName(const std::string& name);
+ void setName(const std::string& name, const std::string& highlight = LLStringUtil::null);
void setGroupID(const LLUUID& group_id);
void setGroupIconID(const LLUUID& group_icon_id);
void setGroupIconVisible(bool visible);
@@ -106,6 +107,7 @@ private:
LLButton* mInfoBtn;
std::string mGroupName;
+ LLStyle::Params mGroupNameStyle;
static S32 sIconWidth; // icon width + padding
};
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 9de0b1f827..2bc07d0c27 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -237,7 +237,6 @@ BOOL LLIMFloater::postBuild()
mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + session_name);
- LLStringUtil::toUpper(session_name);
setTitle(session_name);
childSetCommitCallback("chat_editor", onSendMsg, this);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d3058e67af..6c4af0522f 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -88,6 +88,10 @@ const static std::string IM_TEXT("message");
const static std::string IM_FROM("from");
const static std::string IM_FROM_ID("from_id");
+std::string LLCallDialogManager::sPreviousSessionlName = "";
+std::string LLCallDialogManager::sCurrentSessionlName = "";
+LLIMModel::LLIMSession* LLCallDialogManager::sSession = NULL;
+
//
// Globals
//
@@ -144,11 +148,13 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
: mSessionID(session_id),
mName(name),
mType(type),
+ mParticipantUnreadMessageCount(0),
mNumUnread(0),
mOtherParticipantID(other_participant_id),
mInitialTargetIDs(ids),
mVoiceChannel(NULL),
mSpeakers(NULL),
+ mCallDialogManager(NULL),
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
@@ -167,6 +173,9 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
{
mVoiceChannelStateChangeConnection = mVoiceChannel->setStateChangedCallback(boost::bind(&LLIMSession::onVoiceChannelStateChanged, this, _1, _2));
}
+ // define what type of session was opened
+ setSessionType();
+
mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
// All participants will be added to the list of people we've recently interacted with.
@@ -199,8 +208,35 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
}
}
+void LLIMModel::LLIMSession::setSessionType()
+{
+ // set P2P type by default
+ mSessionType = P2P_SESSION;
+
+ if (dynamic_cast<LLVoiceChannelP2P*>(mVoiceChannel) && !mOtherParticipantIsAvatar) // P2P AVALINE channel was opened
+ {
+ mSessionType = AVALINE_SESSION;
+ return;
+ }
+ else if(dynamic_cast<LLVoiceChannelGroup*>(mVoiceChannel)) // GROUP channel was opened
+ {
+ if (mType == IM_SESSION_CONFERENCE_START)
+ {
+ mSessionType = ADHOC_SESSION;
+ return;
+ }
+ else if(mType == IM_SESSION_GROUP_START)
+ {
+ mSessionType = GROUP_SESSION;
+ return;
+ }
+ }
+}
+
void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
{
+ // *TODO: remove hardcoded string!!!!!!!!!!!
+
bool is_p2p_session = dynamic_cast<LLVoiceChannelP2P*>(mVoiceChannel);
bool is_incoming_call = false;
std::string other_avatar_name;
@@ -251,6 +287,9 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
LLIMModel::LLIMSession::~LLIMSession()
{
+ delete mCallDialogManager;
+ mCallDialogManager = NULL;
+
delete mSpeakers;
mSpeakers = NULL;
@@ -458,10 +497,12 @@ void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages,
}
session->mNumUnread = 0;
+ session->mParticipantUnreadMessageCount = 0;
LLSD arg;
arg["session_id"] = session_id;
arg["num_unread"] = 0;
+ arg["participant_unread"] = session->mParticipantUnreadMessageCount;
mNoUnreadMsgsSignal(arg);
}
@@ -538,10 +579,18 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
session->mNumUnread++;
+ //update count of unread messages from real participant
+ if (!(from_id.isNull() || from_id == gAgentID || SYSTEM_FROM == from))
+ {
+ ++(session->mParticipantUnreadMessageCount);
+ }
+
+
// notify listeners
LLSD arg;
arg["session_id"] = session_id;
arg["num_unread"] = session->mNumUnread;
+ arg["participant_unread"] = session->mParticipantUnreadMessageCount;
arg["message"] = utf8_text;
arg["from"] = from;
arg["from_id"] = from_id;
@@ -1184,21 +1233,141 @@ LLIMMgr::onConfirmForceCloseError(
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLOutgoingCallDialog
+// Class LLCallDialogManager
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LLOutgoingCallDialog::LLOutgoingCallDialog(const LLSD& payload) :
- LLDockableFloater(NULL, false, payload),
- mPayload(payload)
+
+LLCallDialogManager::LLCallDialogManager()
+{
+}
+
+LLCallDialogManager::~LLCallDialogManager()
+{
+}
+
+void LLCallDialogManager::initClass()
+{
+ LLVoiceChannel::setCurrentVoiceChannelChangedCallback(LLCallDialogManager::onVoiceChannelChanged);
+}
+
+void LLCallDialogManager::onVoiceChannelChanged(const LLUUID &session_id)
+{
+ LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
+ if(!session)
+ {
+ sPreviousSessionlName = sCurrentSessionlName;
+ sCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution
+ return;
+ }
+ sSession = session;
+ sSession->mVoiceChannel->setStateChangedCallback(LLCallDialogManager::onVoiceChannelStateChanged);
+ sPreviousSessionlName = sCurrentSessionlName;
+ sCurrentSessionlName = session->mName;
+}
+
+void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
+{
+ LLSD mCallDialogPayload;
+ LLOutgoingCallDialog* ocd;
+
+ mCallDialogPayload["session_id"] = sSession->mSessionID;
+ mCallDialogPayload["session_name"] = sSession->mName;
+ mCallDialogPayload["other_user_id"] = sSession->mOtherParticipantID;
+ mCallDialogPayload["old_channel_name"] = sPreviousSessionlName;
+
+ switch(new_state)
+ {
+ case LLVoiceChannel::STATE_CALL_STARTED :
+ // do not show "Calling to..." if it is incoming P2P call
+ if(sSession->mSessionType == LLIMModel::LLIMSession::P2P_SESSION && static_cast<LLVoiceChannelP2P*>(sSession->mVoiceChannel)->isIncomingCall())
+ {
+ return;
+ }
+
+ ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
+ if (ocd)
+ {
+ ocd->getChild<LLTextBox>("calling")->setVisible(true);
+ ocd->getChild<LLTextBox>("leaving")->setVisible(true);
+ ocd->getChild<LLTextBox>("connecting")->setVisible(false);
+ ocd->getChild<LLTextBox>("noanswer")->setVisible(false);
+ }
+ return;
+
+ case LLVoiceChannel::STATE_RINGING :
+ ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
+ if (ocd)
+ {
+ ocd->getChild<LLTextBox>("calling")->setVisible(false);
+ ocd->getChild<LLTextBox>("leaving")->setVisible(true);
+ ocd->getChild<LLTextBox>("connecting")->setVisible(true);
+ ocd->getChild<LLTextBox>("noanswer")->setVisible(false);
+ }
+ return;
+
+ case LLVoiceChannel::STATE_ERROR :
+ ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
+ if (ocd)
+ {
+ ocd->getChild<LLTextBox>("calling")->setVisible(false);
+ ocd->getChild<LLTextBox>("leaving")->setVisible(false);
+ ocd->getChild<LLTextBox>("connecting")->setVisible(false);
+ ocd->getChild<LLTextBox>("noanswer")->setVisible(true);
+ }
+ return;
+
+ case LLVoiceChannel::STATE_CONNECTED :
+ case LLVoiceChannel::STATE_HUNG_UP :
+ ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
+ if (ocd)
+ {
+ ocd->closeFloater();
+ }
+ return;
+
+ default:
+ break;
+ }
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLCallDialog
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LLCallDialog::LLCallDialog(const LLSD& payload) :
+LLDockableFloater(NULL, false, payload),
+mPayload(payload)
{
}
-void LLOutgoingCallDialog::getAllowedRect(LLRect& rect)
+void LLCallDialog::getAllowedRect(LLRect& rect)
{
rect = gViewerWindow->getWorldViewRectScaled();
}
+void LLCallDialog::onOpen(const LLSD& key)
+{
+ // dock the dialog to the Speak Button, where other sys messages appear
+ setDockControl(new LLDockControl(LLBottomTray::getInstance()->getChild<LLPanel>("speak_panel"),
+ this, getDockTongue(), LLDockControl::TOP, boost::bind(&LLCallDialog::getAllowedRect, this, _1)));
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLOutgoingCallDialog
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LLOutgoingCallDialog::LLOutgoingCallDialog(const LLSD& payload) :
+LLCallDialog(payload)
+{
+ LLOutgoingCallDialog* instance = LLFloaterReg::findTypedInstance<LLOutgoingCallDialog>("outgoing_call", payload);
+ if(instance && instance->getVisible())
+ {
+ instance->onCancel(instance);
+ }
+}
+
void LLOutgoingCallDialog::onOpen(const LLSD& key)
{
+ LLCallDialog::onOpen(key);
+
// tell the user which voice channel they are leaving
if (!mPayload["old_channel_name"].asString().empty())
{
@@ -1246,22 +1415,15 @@ BOOL LLOutgoingCallDialog::postBuild()
childSetAction("Cancel", onCancel, this);
- // dock the dialog to the sys well, where other sys messages appear
- setDockControl(new LLDockControl(LLBottomTray::getInstance()->getChild<LLPanel>("speak_panel"),
- this, getDockTongue(), LLDockControl::TOP,
- boost::bind(&LLOutgoingCallDialog::getAllowedRect, this, _1)));
-
return success;
}
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLIncomingCallDialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
- LLDockableFloater(NULL, false, payload),
- mPayload(payload)
+LLCallDialog(payload)
{
}
@@ -1305,13 +1467,11 @@ BOOL LLIncomingCallDialog::postBuild()
return TRUE;
}
-void LLIncomingCallDialog::getAllowedRect(LLRect& rect)
-{
- rect = gViewerWindow->getWorldViewRectScaled();
-}
void LLIncomingCallDialog::onOpen(const LLSD& key)
{
+ LLCallDialog::onOpen(key);
+
// tell the user which voice channel they would be leaving
LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
if (voice && !voice->getSessionName().empty())
@@ -1322,11 +1482,6 @@ void LLIncomingCallDialog::onOpen(const LLSD& key)
{
childSetTextArg("question", "[CURRENT_CHAT]", getString("localchat"));
}
-
- // dock the dialog to the sys well, where other sys messages appear
- setDockControl(new LLDockControl(LLBottomTray::getInstance()->getChild<LLPanel>("speak_panel"),
- this, getDockTongue(), LLDockControl::TOP,
- boost::bind(&LLIncomingCallDialog::getAllowedRect, this, _1)));
}
//static
@@ -1751,6 +1906,19 @@ S32 LLIMMgr::getNumberOfUnreadIM()
return num;
}
+S32 LLIMMgr::getNumberOfUnreadParticipantMessages()
+{
+ std::map<LLUUID, LLIMModel::LLIMSession*>::iterator it;
+
+ S32 num = 0;
+ for(it = LLIMModel::getInstance()->mId2SessionMap.begin(); it != LLIMModel::getInstance()->mId2SessionMap.end(); ++it)
+ {
+ num += (*it).second->mParticipantUnreadMessageCount;
+ }
+
+ return num;
+}
+
void LLIMMgr::clearNewIMNotification()
{
mIMReceived = FALSE;
@@ -1966,18 +2134,7 @@ void LLIMMgr::inviteToSession(
}
else
{
- if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
- {
- LLFloaterReg::showInstance("incoming_call", payload, TRUE);
- }
- else
- {
- LLSD args;
- args["NAME"] = caller_name;
- args["GROUP"] = session_name;
-
- LLNotificationsUtil::add(notify_box_type, args, payload, &inviteUserResponse);
- }
+ LLFloaterReg::showInstance("incoming_call", payload, TRUE);
}
mPendingInvitations[session_id.asString()] = LLSD();
}
@@ -1990,21 +2147,7 @@ void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::stri
std::string notify_box_type = payload["notify_box_type"].asString();
- if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
- {
- LLFloaterReg::showInstance("incoming_call", payload, TRUE);
- }
- else
- {
- LLSD args;
- args["NAME"] = payload["caller_name"].asString();
-
- LLNotificationsUtil::add(
- payload["notify_box_type"].asString(),
- args,
- payload,
- &inviteUserResponse);
- }
+ LLFloaterReg::showInstance("incoming_call", payload, TRUE);
}
void LLIMMgr::disconnectAllSessions()
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 8a0f57deb0..c002434a18 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -48,6 +48,7 @@ class LLFloaterChatterBox;
class LLUUID;
class LLFloaterIMPanel;
class LLFriendObserver;
+class LLCallDialogManager;
class LLIMModel : public LLSingleton<LLIMModel>
{
@@ -55,12 +56,20 @@ public:
struct LLIMSession
{
+ typedef enum e_session_type
+ { // for now we have 4 predefined types for a session
+ P2P_SESSION,
+ GROUP_SESSION,
+ ADHOC_SESSION,
+ AVALINE_SESSION,
+ } SType;
+
LLIMSession(const LLUUID& session_id, const std::string& name,
const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids);
virtual ~LLIMSession();
void sessionInitReplyReceived(const LLUUID& new_session_id);
-
+ void setSessionType(); //define what type of session was opened
void addMessagesFromHistory(const std::list<LLSD>& history);
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time);
void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
@@ -69,13 +78,18 @@ public:
LLUUID mSessionID;
std::string mName;
EInstantMessage mType;
+ SType mSessionType;
LLUUID mOtherParticipantID;
std::vector<LLUUID> mInitialTargetIDs;
+ LLCallDialogManager* mCallDialogManager;
// connection to voice channel state change signal
boost::signals2::connection mVoiceChannelStateChangeConnection;
- //does NOT include system messages
+ //does NOT include system messages and agent's messages
+ S32 mParticipantUnreadMessageCount;
+
+ // does include all incoming messages
S32 mNumUnread;
std::list<LLSD> mMsgs;
@@ -319,9 +333,14 @@ public:
// IM received that you haven't seen yet
BOOL getIMReceived() const;
- // Calc number of unread IMs
+ // Calc number of all unread IMs
S32 getNumberOfUnreadIM();
+ /**
+ * Calculates number of unread IMs from real participants in all stored sessions
+ */
+ S32 getNumberOfUnreadParticipantMessages();
+
// This method is used to go through all active sessions and
// disable all of them. This method is usally called when you are
// forced to log out or similar situations where you do not have a
@@ -419,7 +438,36 @@ private:
LLSD mPendingAgentListUpdates;
};
-class LLIncomingCallDialog : public LLDockableFloater
+class LLCallDialogManager : public LLInitClass<LLCallDialogManager>
+{
+public:
+ LLCallDialogManager();
+ ~LLCallDialogManager();
+
+ static void initClass();
+ static void onVoiceChannelChanged(const LLUUID &session_id);
+ static void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
+
+protected:
+ static std::string sPreviousSessionlName;
+ static std::string sCurrentSessionlName;
+ static LLIMModel::LLIMSession* sSession;
+};
+
+class LLCallDialog : public LLDockableFloater
+{
+public:
+ LLCallDialog(const LLSD& payload);
+ ~LLCallDialog() {}
+
+ virtual void onOpen(const LLSD& key);
+
+protected:
+ virtual void getAllowedRect(LLRect& rect);
+ LLSD mPayload;
+};
+
+class LLIncomingCallDialog : public LLCallDialog
{
public:
LLIncomingCallDialog(const LLSD& payload);
@@ -433,12 +481,9 @@ public:
private:
void processCallResponse(S32 response);
- void getAllowedRect(LLRect& rect);
-
- LLSD mPayload;
};
-class LLOutgoingCallDialog : public LLDockableFloater
+class LLOutgoingCallDialog : public LLCallDialog
{
public:
LLOutgoingCallDialog(const LLSD& payload);
@@ -449,9 +494,6 @@ public:
static void onCancel(void* user_data);
private:
- void getAllowedRect(LLRect& rect);
-
- LLSD mPayload;
};
// Globals
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 54f528de8d..bf70bb66fa 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -903,10 +903,12 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
if (!auto_open) return NULL;
// D. Open the inventory side panel and use that.
- LLSD key;
LLSidepanelInventory *sidepanel_inventory =
- dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->showPanel("sidepanel_inventory", key));
- if (sidepanel_inventory)
+ dynamic_cast<LLSidepanelInventory *>(side_tray->getPanel("sidepanel_inventory"));
+
+ // Use the inventory side panel only if it is already active.
+ // Activating it may unexpectedly switch off the currently active tab in some cases.
+ if (sidepanel_inventory && (LLPanel*)side_tray->getActiveTab() == (LLPanel*)sidepanel_inventory)
{
return sidepanel_inventory->getActivePanel();
}
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 9e46a4422a..c17427bec1 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -603,7 +603,7 @@ BOOL LLPanelStandStopFlying::handleToolTip(S32 x, S32 y, MASK mask)
LLToolTipMgr::instance().show(mStopFlyingButton->getToolTip());
}
- return TRUE;
+ return LLPanel::handleToolTip(x, y, mask);
}
void LLPanelStandStopFlying::reparent(LLFloaterMove* move_view)
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index da8928321a..5c240aa54a 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -266,6 +266,11 @@ public:
static bool canLogToIM(const LLNotificationPtr& notification);
/**
+ * Checks sufficient conditions to spawn IM session.
+ */
+ static bool canSpawnIMSession(const LLNotificationPtr& notification);
+
+ /**
* Writes notification message to IM session.
*/
static void logToIM(const EInstantMessage& session_type,
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 857b7e9796..6748bd7982 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -43,14 +43,27 @@ using namespace LLNotificationsUI;
const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), OBJECT_GIVE_ITEM(
"ObjectGiveItem"), OBJECT_GIVE_ITEM_UNKNOWN_USER(
- "ObjectGiveItemUnknownUser"), PAYMENT_RECIVED("PaymentRecived");
+ "ObjectGiveItemUnknownUser"), PAYMENT_RECIVED("PaymentRecived"),
+ ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
+ USER_GIVE_ITEM("UserGiveItem"), OFFER_FRIENDSHIP("OfferFriendship"),
+ FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
+ FRIENDSHIP_OFFERED("FriendshipOffered");
// static
bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
{
return GRANTED_MODIFY_RIGHTS == notification->getName()
|| REVOKED_MODIFY_RIGHTS == notification->getName()
- || PAYMENT_RECIVED == notification->getName();
+ || PAYMENT_RECIVED == notification->getName()
+ || FRIENDSHIP_OFFERED == notification->getName();
+}
+
+// static
+bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
+{
+ return ADD_FRIEND_WITH_MESSAGE == notification->getName()
+ || OFFER_FRIENDSHIP == notification->getName()
+ || FRIENDSHIP_ACCEPTED == notification->getName();
}
// static
@@ -92,13 +105,16 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification)
notification->getSubstitutions().has("NAME") ? notification->getSubstitutions()["NAME"]
: notification->getSubstitutions()["[NAME]"];
+ const std::string session_name = notification->getPayload().has(
+ "SESSION_NAME") ? notification->getPayload()["SESSION_NAME"].asString() : name;
+
// don't create IM p2p session with objects, it's necessary condition to log
if (notification->getName() != OBJECT_GIVE_ITEM && notification->getName()
!= OBJECT_GIVE_ITEM_UNKNOWN_USER)
{
LLUUID from_id = notification->getPayload()["from_id"];
- logToIM(IM_NOTHING_SPECIAL, name, name, notification->getMessage(),
+ logToIM(IM_NOTHING_SPECIAL, session_name, name, notification->getMessage(),
from_id, from_id);
}
}
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 4f353bf6a5..4d64c5c0e4 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -40,6 +40,8 @@
#include "llnotificationmanager.h"
#include "llnotifications.h"
#include "llscriptfloater.h"
+#include "llimview.h"
+#include "llnotificationsutil.h"
using namespace LLNotificationsUI;
@@ -101,20 +103,48 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
}
else
{
- LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
-
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.panel = notify_box;
- p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
-
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
- if(channel)
- channel->addToast(p);
-
- // send a signal to the counter manager
- mNewNotificationSignal();
+ if (LLHandlerUtil::canSpawnIMSession(notification))
+ {
+ const std::string name = notification->getSubstitutions().has(
+ "NAME") ? notification->getSubstitutions()["NAME"]
+ : notification->getSubstitutions()["[NAME]"];
+
+ LLUUID from_id = notification->getPayload()["from_id"];
+
+ LLUUID session_id = LLIMMgr::computeSessionID(
+ IM_NOTHING_SPECIAL, from_id);
+
+ LLIMModel::LLIMSession* session =
+ LLIMModel::instance().findIMSession(session_id);
+ if (session == NULL)
+ {
+ LLIMMgr::instance().addSession(name, IM_NOTHING_SPECIAL,
+ from_id);
+ }
+ }
+
+ if (notification->getPayload().has("SUPPRES_TOST")
+ && notification->getPayload()["SUPPRES_TOST"])
+ {
+ LLNotificationsUtil::cancel(notification);
+ }
+ else
+ {
+ LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+ if(channel)
+ channel->addToast(p);
+
+ // send a signal to the counter manager
+ mNewNotificationSignal();
+ }
}
}
else if (notify["sigtype"].asString() == "delete")
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index d731da0ec7..e87b70f6a5 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -125,7 +125,10 @@ void LLLandmarksPanel::onSearchEdit(const std::string& string)
tab->setVisible(TRUE);
// expand accordion to see matched items in each one. See EXT-2014.
- tab->changeOpenClose(false);
+ if (string != "")
+ {
+ tab->changeOpenClose(false);
+ }
LLInventorySubTreePanel* inventory_list = dynamic_cast<LLInventorySubTreePanel*>(tab->getAccordionView());
if (NULL == inventory_list) continue;
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index 046118cf75..ece93125b3 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -71,7 +71,7 @@ void LLPanelMe::onOpen(const LLSD& key)
LLPanelProfile::onOpen(key);
}
-void LLPanelMe::notifyChildren(const LLSD& info)
+bool LLPanelMe::notifyChildren(const LLSD& info)
{
if (info.has("task-panel-action") && info["task-panel-action"].asString() == "handle-tri-state")
{
@@ -104,10 +104,10 @@ void LLPanelMe::notifyChildren(const LLSD& info)
if (on_default_view)
LLSideTray::getInstance()->collapseSideBar();
- return; // this notification is only supposed to be handled by task panels
+ return true; // this notification is only supposed to be handled by task panels
}
- LLPanel::notifyChildren(info);
+ return LLPanel::notifyChildren(info);
}
void LLPanelMe::buildEditPanel()
@@ -220,6 +220,7 @@ BOOL LLPanelMyProfileEdit::postBuild()
initTexturePickerMouseEvents();
childSetTextArg("partner_edit_link", "[URL]", getString("partner_edit_link_url"));
+ childSetTextArg("my_account_link", "[URL]", getString("my_account_link_url"));
return LLPanelAvatarProfile::postBuild();
}
diff --git a/indra/newview/llpanelme.h b/indra/newview/llpanelme.h
index 17d367132e..1325192bbf 100644
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llpanelme.h
@@ -54,7 +54,7 @@ public:
LLPanelMe();
/*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void notifyChildren(const LLSD& info);
+ /*virtual*/ bool notifyChildren(const LLSD& info);
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 1743df52fc..1e4682701e 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -1003,10 +1003,28 @@ void LLPanelPeople::onAddFriendButtonClicked()
}
}
+bool LLPanelPeople::isItemsFreeOfFriends(const std::vector<LLUUID>& uuids)
+{
+ const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+ for ( std::vector<LLUUID>::const_iterator
+ id = uuids.begin(),
+ id_end = uuids.end();
+ id != id_end; ++id )
+ {
+ if (av_tracker.isBuddy (*id))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
void LLPanelPeople::onAddFriendWizButtonClicked()
{
// Show add friend wizard.
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onAvatarPicked, NULL, FALSE, TRUE);
+ // Need to disable 'ok' button when friend occurs in selection
+ if (picker) picker->setOkBtnEnableCb(boost::bind(&LLPanelPeople::isItemsFreeOfFriends, this, _1));
LLFloater* root_floater = gFloaterView->getParentFloater(this);
if (root_floater)
{
@@ -1284,7 +1302,7 @@ void LLPanelPeople::onOpen(const LLSD& key)
reSelectedCurrentTab();
}
-void LLPanelPeople::notifyChildren(const LLSD& info)
+bool LLPanelPeople::notifyChildren(const LLSD& info)
{
if (info.has("task-panel-action") && info["task-panel-action"].asString() == "handle-tri-state")
{
@@ -1292,7 +1310,7 @@ void LLPanelPeople::notifyChildren(const LLSD& info)
if (!container)
{
llwarns << "Cannot find People panel container" << llendl;
- return;
+ return true;
}
if (container->getCurrentPanelIndex() > 0)
@@ -1303,10 +1321,10 @@ void LLPanelPeople::notifyChildren(const LLSD& info)
else
LLSideTray::getInstance()->collapseSideBar();
- return; // this notification is only supposed to be handled by task panels
+ return true; // this notification is only supposed to be handled by task panels
}
- LLPanel::notifyChildren(info);
+ return LLPanel::notifyChildren(info);
}
void LLPanelPeople::showAccordion(const std::string name, bool show)
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 5ac5bcc1d7..a9cc6d0ccb 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -51,7 +51,7 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void notifyChildren(const LLSD& info);
+ /*virtual*/ bool notifyChildren(const LLSD& info);
// internals
class Updater;
@@ -72,6 +72,7 @@ private:
void updateRecentList();
bool isFriendOnline(const LLUUID& id);
+ bool isItemsFreeOfFriends(const std::vector<LLUUID>& uuids);
void updateButtons();
std::string getActiveTabName() const;
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index cc6e88a9d2..59a68bc12d 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -161,6 +161,9 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
std::string name, second_name;
gCacheName->getName(getAvatarId(),name,second_name);
childSetTextArg("pick_title", "[NAME]",name);
+
+ // Save selection, to be able to edit same item after saving changes. See EXT-3023.
+ LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
mPicksList->clear();
@@ -186,6 +189,10 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
mPicksList->addItem(picture, pick_value);
+ // Restore selection by item id.
+ if ( pick_id == selected_id )
+ mPicksList->selectItemByValue(pick_value);
+
picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 1830d00f68..3274820174 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -220,15 +220,15 @@ void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
panel->setRect(new_rect);
}
-void LLPanelProfile::notifyParent(const LLSD& info)
+S32 LLPanelProfile::notifyParent(const LLSD& info)
{
std::string action = info["action"];
// lets update Picks list after Pick was saved
if("save_new_pick" == action)
{
onOpen(info);
- return;
+ return 1;
}
- LLPanel::notifyParent(info);
+ return LLPanel::notifyParent(info);
}
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index 067beb248b..bcf4bdd0ec 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -55,7 +55,7 @@ public:
virtual void openPanel(LLPanel* panel, const LLSD& params);
- void notifyParent(const LLSD& info);
+ S32 notifyParent(const LLSD& info);
protected:
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 523487fa14..43f80f6d6a 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -38,6 +38,8 @@
#include "llsidetray.h"
#include "llworldmap.h"
#include "llteleporthistorystorage.h"
+#include "lltextutil.h"
+
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
@@ -57,7 +59,7 @@ static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
class LLTeleportHistoryFlatItem : public LLPanel
{
public:
- LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name);
+ LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name, const std::string &hl);
virtual ~LLTeleportHistoryFlatItem() {};
virtual BOOL postBuild();
@@ -82,13 +84,15 @@ private:
S32 mIndex;
std::string mRegionName;
+ std::string mHighlight;
};
-LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name)
+LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name, const std::string &hl)
: LLPanel(),
mIndex(index),
mContextMenu(context_menu),
- mRegionName(region_name)
+ mRegionName(region_name),
+ mHighlight(hl)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history_item.xml");
}
@@ -96,8 +100,7 @@ LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistor
//virtual
BOOL LLTeleportHistoryFlatItem::postBuild()
{
- LLTextBox *region = getChild<LLTextBox>("region");
- region->setValue(mRegionName);
+ LLTextUtil::textboxSetHighlightedVal(getChild<LLTextBox>("region"), LLStyle::Params(), mRegionName, mHighlight);
mProfileBtn = getChild<LLButton>("profile_btn");
@@ -316,11 +319,8 @@ void LLTeleportHistoryPanel::draw()
// virtual
void LLTeleportHistoryPanel::onSearchEdit(const std::string& string)
{
- if (sFilterSubString != string)
- {
- sFilterSubString = string;
- showTeleportHistory();
- }
+ sFilterSubString = string;
+ showTeleportHistory();
}
// virtual
@@ -521,7 +521,7 @@ void LLTeleportHistoryPanel::refresh()
if (curr_flat_view)
{
- LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(mCurrentItem, &mContextMenu, items[mCurrentItem].mTitle);
+ LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(mCurrentItem, &mContextMenu, items[mCurrentItem].mTitle, mFilterSubString);
curr_flat_view->addItem(item);
if (mLastSelectedItemIndex == mCurrentItem)
@@ -568,7 +568,8 @@ void LLTeleportHistoryPanel::replaceItem(S32 removed_index)
const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems();
LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(history_items.size(), // index will be decremented inside loop below
&mContextMenu,
- history_items[history_items.size() - 1].mTitle); // Most recent item, it was
+ history_items[history_items.size() - 1].mTitle, // Most recent item, it was
+ mFilterSubString);
// added instead of removed
fv->addItem(item, LLUUID::null, ADD_TOP);
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 24ba288c49..4f0c873c61 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -162,6 +162,8 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
if(mControlHovering)
{
new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
+ new_toast_elem.toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopFadingToasts, this));
+ new_toast_elem.toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startFadingToasts, this));
}
if(show_toast)
@@ -586,6 +588,37 @@ void LLScreenChannel::closeStartUpToast()
}
}
+void LLNotificationsUI::LLScreenChannel::stopFadingToasts()
+{
+ if (!mToastList.size()) return;
+
+ if (!mHoveredToast) return;
+
+ std::vector<ToastElem>::iterator it = mToastList.begin();
+ while (it != mToastList.end())
+ {
+ ToastElem& elem = *it;
+ elem.toast->stopFading();
+ ++it;
+ }
+}
+
+void LLNotificationsUI::LLScreenChannel::startFadingToasts()
+{
+ if (!mToastList.size()) return;
+
+ //because onMouseLeave is processed after onMouseEnter
+ if (mHoveredToast) return;
+
+ std::vector<ToastElem>::iterator it = mToastList.begin();
+ while (it != mToastList.end())
+ {
+ ToastElem& elem = *it;
+ elem.toast->startFading();
+ ++it;
+ }
+}
+
//--------------------------------------------------------------------------
void LLScreenChannel::hideToastsFromScreen()
{
@@ -713,6 +746,8 @@ void LLScreenChannel::updateShowToastsState()
}
}
+ // *TODO: mantipov: what we have to do with derived classes: LLNotificationWellWindow & LLIMWelWindow?
+ // See EXT-3081 for details
// for Message Well floater showed in a docked state - adjust channel's height
if(dynamic_cast<LLSysWellWindow*>(floater))
{
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index f39b94b89d..67f1c9bdc6 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -184,6 +184,13 @@ public:
// close the StartUp Toast
void closeStartUpToast();
+
+ /** Stop fading all toasts */
+ virtual void stopFadingToasts();
+
+ /** Start fading all toasts */
+ virtual void startFadingToasts();
+
// get StartUp Toast's state
static bool getStartUpToastShown() { return mWasStartUpToastShown; }
// tell all channels that the StartUp toast was shown and allow them showing of toasts
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 088884178b..8de99a48aa 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -207,11 +207,22 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
return;
}
+ // Need to indicate of "new message" for object chiclets according to requirements
+ // specified in the Message Bar design specification. See EXT-3142.
+ bool set_new_message = false;
+
// If an Object spawns more-than-one floater, only the newest one is shown.
// The previous is automatically closed.
script_notification_map_t::iterator it = mNotifications.find(object_id);
if(it != mNotifications.end())
{
+ LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->second.notification_id);
+ if(floater)
+ {
+ // Generate chiclet with a "new message" indicator if a docked window was opened. See EXT-3142.
+ set_new_message = floater->isShown();
+ }
+
onRemoveNotification(it->second.notification_id);
}
@@ -229,7 +240,7 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
LLBottomTray::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(object_id);
}
- toggleScriptFloater(object_id);
+ toggleScriptFloater(object_id, set_new_message);
}
void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
@@ -278,13 +289,13 @@ void LLScriptFloaterManager::removeNotificationByObjectId(const LLUUID& object_i
}
}
-void LLScriptFloaterManager::toggleScriptFloater(const LLUUID& object_id)
+void LLScriptFloaterManager::toggleScriptFloater(const LLUUID& object_id, bool set_new_message)
{
// hide "new message" icon from chiclet
LLIMChiclet* chiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(object_id);
if(chiclet)
{
- chiclet->setShowNewMessagesIcon(false);
+ chiclet->setShowNewMessagesIcon(set_new_message);
}
// kill toast
diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h
index 8b5a266691..8de7a28d0f 100644
--- a/indra/newview/llscriptfloater.h
+++ b/indra/newview/llscriptfloater.h
@@ -70,7 +70,7 @@ public:
* Toggles script floater.
* Removes "new message" icon from chiclet and removes notification toast.
*/
- void toggleScriptFloater(const LLUUID& object_id);
+ void toggleScriptFloater(const LLUUID& object_id, bool set_new_message = false);
LLUUID findObjectId(const LLUUID& notification_id);
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index cf2f6992d5..de2cfe9711 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -103,6 +103,11 @@ public:
LLPanel* getActivePanel ();
bool isPanelActive (const std::string& panel_name);
/*
+ * get currently active tab
+ */
+ const LLSideTrayTab* getActiveTab() const { return mActiveTab; }
+
+ /*
* collapse SideBar, hiding visible tab and moving tab buttons
* to the right corner of the screen
*/
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 539536b527..bef7f5d6aa 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h" // must be first include
#include "llflatlistview.h"
+#include "llfloaterreg.h"
#include "llsyswellwindow.h"
@@ -44,16 +45,15 @@
#include "lltoastpanel.h"
#include "llnotificationmanager.h"
-
//---------------------------------------------------------------------------------
LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key),
mChannel(NULL),
mMessageList(NULL),
- mSeparator(NULL)
-{
- LLIMMgr::getInstance()->addSessionObserver(this);
- LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLSysWellWindow::findIMChiclet, this, _1));
+ mSeparator(NULL),
+ NOTIFICATION_WELL_ANCHOR_NAME("notification_well_panel"),
+ IM_WELL_ANCHOR_NAME("im_well_panel")
+{
mTypedItemsCount[IT_NOTIFICATION] = 0;
mTypedItemsCount[IT_INSTANT_MESSAGE] = 0;
}
@@ -63,11 +63,6 @@ BOOL LLSysWellWindow::postBuild()
{
mMessageList = getChild<LLFlatListView>("notification_list");
- // init connections to the list's update events
- connectListUpdaterToSignal("notify");
- connectListUpdaterToSignal("groupnotify");
- connectListUpdaterToSignal("offer");
-
// get a corresponding channel
initChannel();
@@ -89,81 +84,19 @@ BOOL LLSysWellWindow::postBuild()
//---------------------------------------------------------------------------------
void LLSysWellWindow::setMinimized(BOOL minimize)
{
- // we don't show empty Message Well window
- if (!minimize && isWindowEmpty())
- {
- return;
- }
-
LLDockableFloater::setMinimized(minimize);
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
-{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
- {
- n_handler->setNotificationIDCallback(boost::bind(&LLSysWellWindow::removeItemByID, this, _1));
- }
- else
- {
- llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
- }
-}
-
-//---------------------------------------------------------------------------------
void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
{
- onChicletClick();
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::onChicletClick()
-{
- // 1 - remove StartUp toast and channel if present
- if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
- {
- LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
- }
-
- // 2 - toggle instance of SysWell's chiclet-window
- toggleWindow();
+ // just set floater visible. Screen channels will be cleared.
+ setVisible(TRUE);
}
//---------------------------------------------------------------------------------
LLSysWellWindow::~LLSysWellWindow()
{
- LLIMMgr::getInstance()->removeSessionObserver(this);
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::addItem(LLSysWellItem::Params p)
-{
- LLSD value = p.notification_id;
- // do not add clones
- if( mMessageList->getItemByValue(value))
- return;
-
- LLSysWellItem* new_item = new LLSysWellItem(p);
- if (mMessageList->addItem(new_item, value, ADD_TOP))
- {
- handleItemAdded(IT_NOTIFICATION);
-
- reshapeWindow();
-
- new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
- new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
- }
- else
- {
- llwarns << "Unable to add Notification into the list, notification ID: " << p.notification_id
- << ", title: " << p.title
- << llendl;
-
- new_item->die();
- }
}
//---------------------------------------------------------------------------------
@@ -194,42 +127,13 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::onItemClick(LLSysWellItem* item)
-{
- LLUUID id = item->getID();
- if(mChannel)
- mChannel->loadStoredToastByNotificationIDToChannel(id);
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::onItemClose(LLSysWellItem* item)
-{
- LLUUID id = item->getID();
- removeItemByID(id);
- if(mChannel)
- mChannel->killToastByNotificationID(id);
-}
-
-//--------------------------------------------------------------------------
-void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
-{
- LLSysWellItem::Params p;
- p.notification_id = id;
- p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
- addItem(p);
-}
-
//---------------------------------------------------------------------------------
void LLSysWellWindow::initChannel()
{
LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
- if(mChannel)
- {
- mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
- }
- else
+ if(NULL == mChannel)
{
llwarns << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << llendl;
}
@@ -242,57 +146,24 @@ void LLSysWellWindow::getAllowedRect(LLRect& rect)
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::toggleWindow()
-{
- if (getDockControl() == NULL)
- {
- setDockControl(new LLDockControl(
- LLBottomTray::getInstance()->getSysWell(), this,
- getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
- }
- if(!getVisible() || isMinimized())
- {
- if(mChannel)
- {
- mChannel->removeAndStoreAllStorableToasts();
- }
- if(isWindowEmpty())
- {
- return;
- }
-
- setVisible(TRUE);
- }
- else if (isDocked())
- {
- setVisible(FALSE);
- }
- else if(!isDocked())
- {
- // bring to front undocked floater
- setVisible(TRUE);
- }
-}
//---------------------------------------------------------------------------------
void LLSysWellWindow::setVisible(BOOL visible)
{
- if(visible)
+ if (visible)
{
- if (LLBottomTray::instanceExists())
+ if (NULL == getDockControl() && getDockTongue().notNull())
{
- LLBottomTray::getInstance()->getSysWell()->setToggleState(TRUE);
- }
- }
- else
- {
- if (LLBottomTray::instanceExists())
- {
- LLBottomTray::getInstance()->getSysWell()->setToggleState(FALSE);
+ setDockControl(new LLDockControl(
+ LLBottomTray::getInstance()->getChild<LLView>(getAnchorViewName()), this,
+ getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
}
}
+ // do not show empty window
+ if (NULL == mMessageList || isWindowEmpty()) visible = FALSE;
+
LLDockableFloater::setVisible(visible);
// update notification channel state
@@ -303,6 +174,12 @@ void LLSysWellWindow::setVisible(BOOL visible)
}
//---------------------------------------------------------------------------------
+void LLSysWellWindow::onFocusLost()
+{
+ setVisible(false);
+}
+
+//---------------------------------------------------------------------------------
void LLSysWellWindow::setDocked(bool docked, bool pop_on_undock)
{
LLDockableFloater::setDocked(docked, pop_on_undock);
@@ -347,104 +224,13 @@ void LLSysWellWindow::reshapeWindow()
}
//---------------------------------------------------------------------------------
-LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId)
-{
- LLChiclet* res = NULL;
- RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId);
- if (panel != NULL)
- {
- res = panel->mChiclet;
- }
-
- return res;
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
- const std::string& name, const LLUUID& otherParticipantId)
-{
- RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
- if (mMessageList->insertItemAfter(mSeparator, item, sessionId))
- {
- handleItemAdded(IT_INSTANT_MESSAGE);
- }
- else
- {
- llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
- << ", name: " << name
- << ", other participant ID: " << otherParticipantId
- << llendl;
-
- item->die();
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::delIMRow(const LLUUID& sessionId)
-{
- if (mMessageList->removeItemByValue(sessionId))
- {
- handleItemRemoved(IT_INSTANT_MESSAGE);
- }
- else
- {
- llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
- << llendl;
- }
-
- // remove all toasts that belong to this session from a screen
- if(mChannel)
- mChannel->removeToastsBySessionID(sessionId);
-
- // hide chiclet window if there are no items left
- if(isWindowEmpty())
- {
- setVisible(FALSE);
- }
-}
-
-//---------------------------------------------------------------------------------
bool LLSysWellWindow::isWindowEmpty()
{
// keep in mind, mSeparator is always in the list
return mMessageList->size() == 1;
}
-//---------------------------------------------------------------------------------
-//virtual
-void LLSysWellWindow::sessionAdded(const LLUUID& session_id,
- const std::string& name, const LLUUID& other_participant_id)
-{
- if (mMessageList->getItemByValue(session_id) == NULL)
- {
- S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
- if (chicletCounter > -1)
- {
- addIMRow(session_id, chicletCounter, name, other_participant_id);
- reshapeWindow();
- }
- }
-}
-
-//---------------------------------------------------------------------------------
-//virtual
-void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId)
-{
- delIMRow(sessionId);
- reshapeWindow();
-}
-
-void LLSysWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
- //for outgoing ad-hoc and group im sessions only
- LLChiclet* chiclet = findIMChiclet(old_session_id);
- if (chiclet)
- {
- chiclet->setSessionId(new_session_id);
- mMessageList->updateValue(old_session_id, new_session_id);
- }
-}
-
+// *TODO: mantipov: probably is deprecated
void LLSysWellWindow::handleItemAdded(EItemType added_item_type)
{
bool should_be_shown = ++mTypedItemsCount[added_item_type] == 1 && anotherTypeExists(added_item_type);
@@ -492,8 +278,12 @@ bool LLSysWellWindow::anotherTypeExists(EItemType item_type)
return exists;
}
+/************************************************************************/
+/* RowPanel implementation */
+/************************************************************************/
+
//---------------------------------------------------------------------------------
-LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
+LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
{
@@ -528,36 +318,36 @@ LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&
contactName->setValue(name);
mCloseBtn = getChild<LLButton>("hide_btn");
- mCloseBtn->setCommitCallback(boost::bind(&LLSysWellWindow::RowPanel::onClosePanel, this));
+ mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::RowPanel::onClosePanel, this));
}
//---------------------------------------------------------------------------------
-LLSysWellWindow::RowPanel::~RowPanel()
+LLIMWellWindow::RowPanel::~RowPanel()
{
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::RowPanel::onClosePanel()
+void LLIMWellWindow::RowPanel::onClosePanel()
{
gIMMgr->leaveSession(mChiclet->getSessionId());
// This row panel will be removed from the list in LLSysWellWindow::sessionRemoved().
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
+void LLIMWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
{
setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected"));
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
+void LLIMWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
{
setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));
}
//---------------------------------------------------------------------------------
// virtual
-BOOL LLSysWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLIMWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
{
// Pass the mouse down event to the chiclet (EXT-596).
if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown()
@@ -566,4 +356,263 @@ BOOL LLSysWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
return LLPanel::handleMouseDown(x, y, mask);
}
+
+
+/************************************************************************/
+/* LLNotificationWellWindow implementation */
+/************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+// PUBLIC METHODS
+LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
+: LLSysWellWindow(key)
+{
+ // init connections to the list's update events
+ connectListUpdaterToSignal("notify");
+ connectListUpdaterToSignal("groupnotify");
+ connectListUpdaterToSignal("offer");
+}
+
+// static
+LLNotificationWellWindow* LLNotificationWellWindow::getInstance(const LLSD& key /*= LLSD()*/)
+{
+ return LLFloaterReg::getTypedInstance<LLNotificationWellWindow>("notification_well_window", key);
+}
+
+// virtual
+BOOL LLNotificationWellWindow::postBuild()
+{
+ BOOL rv = LLSysWellWindow::postBuild();
+ setTitle(getString("title_notification_well_window"));
+ return rv;
+}
+
+// virtual
+void LLNotificationWellWindow::setVisible(BOOL visible)
+{
+ if (visible)
+ {
+ // when Notification channel is cleared, storable toasts will be added into the list.
+ clearScreenChannels();
+ }
+
+ LLSysWellWindow::setVisible(visible);
+}
+
+//---------------------------------------------------------------------------------
+void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
+{
+ LLSD value = p.notification_id;
+ // do not add clones
+ if( mMessageList->getItemByValue(value))
+ return;
+
+ LLSysWellItem* new_item = new LLSysWellItem(p);
+ if (mMessageList->addItem(new_item, value, ADD_TOP))
+ {
+ handleItemAdded(IT_NOTIFICATION);
+
+ reshapeWindow();
+
+ new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
+ new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
+ }
+ else
+ {
+ llwarns << "Unable to add Notification into the list, notification ID: " << p.notification_id
+ << ", title: " << p.title
+ << llendl;
+
+ new_item->die();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE METHODS
+void LLNotificationWellWindow::initChannel()
+{
+ LLSysWellWindow::initChannel();
+ if(mChannel)
+ {
+ mChannel->setOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
+ }
+}
+
+void LLNotificationWellWindow::clearScreenChannels()
+{
+ // 1 - remove StartUp toast and channel if present
+ if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
+ {
+ LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
+ }
+
+ // 2 - remove toasts in Notification channel
+ if(mChannel)
+ {
+ mChannel->removeAndStoreAllStorableToasts();
+ }
+}
+
+void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
+{
+ LLSysWellItem::Params p;
+ p.notification_id = id;
+ p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
+ addItem(p);
+}
+
+void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type)
+{
+ LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
+ LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
+ if(n_handler)
+ {
+ n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1));
+ }
+ else
+ {
+ llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
+ }
+}
+
+void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
+{
+ LLUUID id = item->getID();
+ if(mChannel)
+ mChannel->loadStoredToastByNotificationIDToChannel(id);
+}
+
+void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
+{
+ LLUUID id = item->getID();
+ removeItemByID(id);
+ if(mChannel)
+ mChannel->killToastByNotificationID(id);
+}
+
+
+
+/************************************************************************/
+/* LLIMWellWindow implementation */
+/************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+// PUBLIC METHODS
+LLIMWellWindow::LLIMWellWindow(const LLSD& key)
+: LLSysWellWindow(key)
+{
+ LLIMMgr::getInstance()->addSessionObserver(this);
+ LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1));
+}
+
+LLIMWellWindow::~LLIMWellWindow()
+{
+ LLIMMgr::getInstance()->removeSessionObserver(this);
+}
+
+// static
+LLIMWellWindow* LLIMWellWindow::getInstance(const LLSD& key /*= LLSD()*/)
+{
+ return LLFloaterReg::getTypedInstance<LLIMWellWindow>("im_well_window", key);
+}
+
+BOOL LLIMWellWindow::postBuild()
+{
+ BOOL rv = LLSysWellWindow::postBuild();
+ setTitle(getString("title_im_well_window"));
+ return rv;
+}
+
+//virtual
+void LLIMWellWindow::sessionAdded(const LLUUID& session_id,
+ const std::string& name, const LLUUID& other_participant_id)
+{
+ if (mMessageList->getItemByValue(session_id) == NULL)
+ {
+ S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
+ if (chicletCounter > -1)
+ {
+ addIMRow(session_id, chicletCounter, name, other_participant_id);
+ reshapeWindow();
+ }
+ }
+}
+
+//virtual
+void LLIMWellWindow::sessionRemoved(const LLUUID& sessionId)
+{
+ delIMRow(sessionId);
+ reshapeWindow();
+}
+
+//virtual
+void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+ //for outgoing ad-hoc and group im sessions only
+ LLChiclet* chiclet = findIMChiclet(old_session_id);
+ if (chiclet)
+ {
+ chiclet->setSessionId(new_session_id);
+ mMessageList->updateValue(old_session_id, new_session_id);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE METHODS
+LLChiclet* LLIMWellWindow::findIMChiclet(const LLUUID& sessionId)
+{
+ LLChiclet* res = NULL;
+ RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId);
+ if (panel != NULL)
+ {
+ res = panel->mChiclet;
+ }
+
+ return res;
+}
+
+//---------------------------------------------------------------------------------
+void LLIMWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
+ const std::string& name, const LLUUID& otherParticipantId)
+{
+ RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
+ if (mMessageList->insertItemAfter(mSeparator, item, sessionId))
+ {
+ handleItemAdded(IT_INSTANT_MESSAGE);
+ }
+ else
+ {
+ llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
+ << ", name: " << name
+ << ", other participant ID: " << otherParticipantId
+ << llendl;
+
+ item->die();
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLIMWellWindow::delIMRow(const LLUUID& sessionId)
+{
+ if (mMessageList->removeItemByValue(sessionId))
+ {
+ handleItemRemoved(IT_INSTANT_MESSAGE);
+ }
+ else
+ {
+ llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
+ << llendl;
+ }
+
+ // remove all toasts that belong to this session from a screen
+ if(mChannel)
+ mChannel->removeToastsBySessionID(sessionId);
+
+ // hide chiclet window if there are no items left
+ if(isWindowEmpty())
+ {
+ setVisible(FALSE);
+ }
+}
+
// EOF
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 3e4cdbdcbe..adbc83677d 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -47,7 +47,9 @@ class LLFlatListView;
class LLChiclet;
class LLIMChiclet;
-class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
+
+
+class LLSysWellWindow : public LLDockableFloater
{
public:
LLSysWellWindow(const LLSD& key);
@@ -59,31 +61,28 @@ public:
bool isWindowEmpty();
// Operating with items
- void addItem(LLSysWellItem::Params p);
void clear( void );
void removeItemByID(const LLUUID& id);
// Operating with outfit
virtual void setVisible(BOOL visible);
void adjustWindowPosition();
- void toggleWindow();
- /*virtual*/ BOOL canClose() { return FALSE; }
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
// override LLFloater's minimization according to EXT-1216
/*virtual*/ void setMinimized(BOOL minimize);
- // Handlers
- void onItemClick(LLSysWellItem* item);
- void onItemClose(LLSysWellItem* item);
- void onStoreToast(LLPanel* info_panel, LLUUID id);
- void onChicletClick();
+ /**
+ * Hides window when user clicks away from it (EXT-3084)
+ */
+ /*virtual*/ void onFocusLost();
+
void onStartUpToastClick(S32 x, S32 y, MASK mask);
// size constants for the window and for its elements
static const S32 MAX_WINDOW_HEIGHT = 200;
static const S32 MIN_WINDOW_WIDTH = 318;
-private:
+protected:
typedef enum{
IT_NOTIFICATION,
@@ -92,25 +91,19 @@ private:
// gets a rect that bounds possible positions for the SysWellWindow on a screen (EXT-1111)
void getAllowedRect(LLRect& rect);
- // connect counter and list updaters to the corresponding signals
- void connectListUpdaterToSignal(std::string notification_type);
+
+
// init Window's channel
- void initChannel();
+ virtual void initChannel();
void handleItemAdded(EItemType added_item_type);
void handleItemRemoved(EItemType removed_item_type);
bool anotherTypeExists(EItemType item_type) ;
+ const std::string NOTIFICATION_WELL_ANCHOR_NAME;
+ const std::string IM_WELL_ANCHOR_NAME;
+ virtual const std::string& getAnchorViewName() = 0;
-
- class RowPanel;
void reshapeWindow();
- LLChiclet * findIMChiclet(const LLUUID& sessionId);
- void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId);
- void delIMRow(const LLUUID& sessionId);
- // LLIMSessionObserver observe triggers
- virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
- virtual void sessionRemoved(const LLUUID& session_id);
- void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
// pointer to a corresponding channel's instance
LLNotificationsUI::LLScreenChannel* mChannel;
@@ -126,7 +119,77 @@ private:
typedef std::map<EItemType, S32> typed_items_count_t;
typed_items_count_t mTypedItemsCount;
+};
+
+/**
+ * Class intended to manage incoming notifications.
+ *
+ * It contains a list of notifications that have not been responded to.
+ */
+class LLNotificationWellWindow : public LLSysWellWindow, public LLInitClass<LLNotificationWellWindow>
+{
+public:
+ LLNotificationWellWindow(const LLSD& key);
+ static LLNotificationWellWindow* getInstance(const LLSD& key = LLSD());
+
+ static void initClass() { getInstance(); }
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void setVisible(BOOL visible);
+
+ // Operating with items
+ void addItem(LLSysWellItem::Params p);
+
+protected:
+ /*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
+
+private:
+ // init Window's channel
+ void initChannel();
+ void clearScreenChannels();
+
+
+ void onStoreToast(LLPanel* info_panel, LLUUID id);
+
+ // connect counter and list updaters to the corresponding signals
+ void connectListUpdaterToSignal(std::string notification_type);
+
+ // Handlers
+ void onItemClick(LLSysWellItem* item);
+ void onItemClose(LLSysWellItem* item);
+
+};
+
+/**
+ * Class intended to manage incoming messages in IM chats.
+ *
+ * It contains a list list of all active IM sessions.
+ */
+class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<LLIMWellWindow>
+{
+public:
+ LLIMWellWindow(const LLSD& key);
+ ~LLIMWellWindow();
+
+ static LLIMWellWindow* getInstance(const LLSD& key = LLSD());
+ static void initClass() { getInstance(); }
+
+ /*virtual*/ BOOL postBuild();
+
+ // LLIMSessionObserver observe triggers
+ /*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+ /*virtual*/ void sessionRemoved(const LLUUID& session_id);
+ /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
+protected:
+ /*virtual*/ const std::string& getAnchorViewName() { return IM_WELL_ANCHOR_NAME; }
+
private:
+ LLChiclet * findIMChiclet(const LLUUID& sessionId);
+ void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId);
+ void delIMRow(const LLUUID& sessionId);
+
+
/**
* Scrolling row panel.
*/
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index bf485b7e65..fc7c029a17 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -244,15 +244,15 @@ void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
mOnToastHoverSignal(this, MOUSE_ENTER);
setBackgroundOpaque(TRUE);
- if(mCanFade)
- {
- mTimer.stop();
- }
+
+ //toasts fading is management by Screen Channel
sendChildToFront(mHideBtn);
if(mHideBtn && mHideBtn->getEnabled())
mHideBtn->setVisible(TRUE);
mOnMouseEnterSignal(this);
+
+ LLModalDialog::onMouseEnter(x, y, mask);
}
//--------------------------------------------------------------------------
@@ -260,10 +260,8 @@ void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
{
mOnToastHoverSignal(this, MOUSE_LEAVE);
- if(mCanFade)
- {
- mTimer.start();
- }
+ //toasts fading is management by Screen Channel
+
if(mHideBtn && mHideBtn->getEnabled())
{
if( mHideBtnPressed )
@@ -273,6 +271,25 @@ void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
}
mHideBtn->setVisible(FALSE);
}
+
+ LLModalDialog::onMouseLeave(x, y, mask);
+}
+
+
+void LLNotificationsUI::LLToast::stopFading()
+{
+ if(mCanFade)
+ {
+ stopTimer();
+ }
+}
+
+void LLNotificationsUI::LLToast::startFading()
+{
+ if(mCanFade)
+ {
+ resetTimer();
+ }
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 769b2ba122..d08e46e160 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -88,6 +88,15 @@ public:
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+ //Fading
+
+ /** Stop fading timer */
+ virtual void stopFading();
+
+ /** Start fading timer */
+ virtual void startFading();
+
+
// Operating with toasts
// insert a panel to a toast
void insertPanel(LLPanel* panel);
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index f928b5f243..7beba59c83 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -40,8 +40,7 @@ const S32 LLToastIMPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 6;
//--------------------------------------------------------------------------
LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notification),
mAvatar(NULL), mUserName(NULL),
- mTime(NULL), mMessage(NULL),
- mReplyBtn(NULL)
+ mTime(NULL), mMessage(NULL)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_instant_message.xml");
@@ -50,7 +49,6 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
mUserName = getChild<LLTextBox>("user_name");
mTime = getChild<LLTextBox>("time_box");
mMessage = getChild<LLTextBox>("message");
- mReplyBtn = getChild<LLButton>("reply");
LLStyle::Params style_params;
style_params.font.name(LLFontGL::nameFromFont(style_params.font));
@@ -76,18 +74,10 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
mSessionID = p.session_id;
mNotification = p.notification;
- // if message comes from the system - there shouldn't be a reply btn
if(p.from == SYSTEM_FROM)
{
mAvatar->setVisible(FALSE);
sys_msg_icon->setVisible(TRUE);
-
- mReplyBtn->setVisible(FALSE);
- S32 btn_height = mReplyBtn->getRect().getHeight();
- LLRect msg_rect = mMessage->getRect();
- mMessage->reshape(msg_rect.getWidth(), msg_rect.getHeight() + btn_height);
- msg_rect.setLeftTopAndSize(msg_rect.mLeft, msg_rect.mTop, msg_rect.getWidth(), msg_rect.getHeight() + btn_height);
- mMessage->setRect(msg_rect);
}
else
{
@@ -95,7 +85,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
sys_msg_icon->setVisible(FALSE);
mAvatar->setValue(p.avatar_id);
- mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this));
+ setMouseDownCallback(boost::bind(&LLToastIMPanel::onClickToastIM, this));
}
S32 maxLinesCount;
@@ -113,7 +103,7 @@ LLToastIMPanel::~LLToastIMPanel()
}
//--------------------------------------------------------------------------
-void LLToastIMPanel::onClickReplyBtn()
+void LLToastIMPanel::onClickToastIM()
{
mNotification->respond(mNotification->getResponseTemplate());
}
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index af21b07a3d..23f08ef610 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -61,7 +61,7 @@ public:
private:
static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
- void onClickReplyBtn();
+ void onClickToastIM();
LLNotificationPtr mNotification;
LLUUID mSessionID;
@@ -69,7 +69,6 @@ private:
LLTextBox* mUserName;
LLTextBox* mTime;
LLTextBox* mMessage;
- LLButton* mReplyBtn;
};
#endif // LLTOASTIMPANEL_H_
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 158c857031..35c9a1d367 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -176,6 +176,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>);
+ LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>);
LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);
LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>);
@@ -195,11 +196,10 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);
LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
- LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSysWellWindow>);
LLFloaterReg::add("nearby_media", "floater_nearby_media.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNearbyMedia>);
-
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
+ LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNotificationWellWindow>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 5da77ecdb9..4482683400 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -85,7 +85,8 @@ public:
{
std::vector<LLUUID> items_to_open;
items_to_open.push_back(inventory_id);
- open_inventory_offer(items_to_open, "");
+ //inventory_handler is just a stub, because we don't know from who this offer
+ open_inventory_offer(items_to_open, "inventory_handler");
return true;
}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 507e34348b..39d69067da 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -74,6 +74,7 @@
#include "llimview.h"
#include "lltrans.h"
#include "llviewerfoldertype.h"
+#include "lluri.h"
#include "llviewergenericmessage.h"
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
@@ -828,6 +829,8 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f
for (std::vector<LLUUID>::const_iterator item_iter = items.begin();
item_iter != items.end();
++item_iter)
+ const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
+ BOOL user_is_away = gAwayTimer.getStarted();
{
const LLUUID& item_id = (*item_iter);
LLInventoryItem* item = gInventory.getItem(item_id);
@@ -836,7 +839,6 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f
LL_WARNS("Messaging") << "Unable to show inventory item: " << item_id << LL_ENDL;
continue;
}
-
////////////////////////////////////////////////////////////////////////////////
// Don't highlight if it's in certain "quiet" folders which don't need UI
// notification (e.g. trash, cof, lost-and-found).
@@ -859,6 +861,7 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f
const LLAssetType::EType asset_type = item->getType();
if (check_offer_throttle(from_name, false)) // If we are throttled, don't display
{
+ LL_DEBUGS("Messaging") << "Highlighting inventory item: " << item->getUUID() << LL_ENDL;
// If we opened this ourselves, focus it
const BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO;
switch(asset_type)
@@ -871,18 +874,28 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f
case LLAssetType::AT_LANDMARK:
{
LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID());
- LLSD args;
- args["LANDMARK_NAME"] = item->getName();
- args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown");
- LLNotificationsUtil::add("LandmarkCreated", args);
-
- // Created landmark is passed to Places panel to allow its editing.
- LLPanelPlaces *places_panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", LLSD()));
- if (places_panel)
+ if ("inventory_handler" == from_name)
+ {
+ //we have to filter inventory_handler messages to avoid notification displaying
+ LLSideTray::getInstance()->showPanel("panel_places",
+ LLSD().with("type", "landmark").with("id", item->getUUID()));
+ }
+ else if(from_name.empty())
{
- places_panel->setItem(item);
+ // we receive a message from LLOpenTaskOffer, it mean that new landmark has been added.
+ LLSD args;
+ args["LANDMARK_NAME"] = item->getName();
+ args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown");
+ LLNotificationsUtil::add("LandmarkCreated", args);
+ // Created landmark is passed to Places panel to allow its editing. In fact panel should be already displayed.
+ //TODO*:: dserduk(7/12/09) remove LLPanelPlaces dependency from here
+ LLPanelPlaces *places_panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", LLSD()));
+ if (places_panel)
+ {
+ places_panel->setItem(item);
+ }
}
- }
+ }
break;
case LLAssetType::AT_TEXTURE:
{
@@ -1448,7 +1461,7 @@ void inventory_offer_handler(LLOfferInfo* info)
args["OBJECTFROMNAME"] = info->mFromName;
args["NAME"] = info->mFromName;
args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about");
- std::string verb = "select?name=" + msg;
+ std::string verb = "select?name=" + LLURI::escape(msg);
args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str());
LLNotification::Params p("ObjectGiveItem");
@@ -1487,14 +1500,15 @@ void inventory_offer_handler(LLOfferInfo* info)
}
// Pop up inv offer notification and let the user accept (keep), or reject (and silently delete) the inventory.
- LLNotifications::instance().add(p);
+ LLNotifications::instance().add(p);
+ // TODO(EM): Recheck this after we will know how script notifications should look like.
// Inform user that there is a script floater via toast system
- {
- payload["give_inventory_notification"] = TRUE;
- LLNotificationPtr notification = LLNotifications::instance().add(p.payload(payload));
- LLScriptFloaterManager::getInstance()->setNotificationToastId(object_id, notification->getID());
- }
+ // {
+ // payload["give_inventory_notification"] = TRUE;
+ // LLNotificationPtr notification = LLNotifications::instance().add(p.payload(payload));
+ // LLScriptFloaterManager::getInstance()->setNotificationToastId(object_id, notification->getID());
+ // }
}
bool lure_callback(const LLSD& notification, const LLSD& response)
@@ -1997,13 +2011,17 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
case IM_INVENTORY_ACCEPTED:
{
args["NAME"] = name;
- LLNotificationsUtil::add("InventoryAccepted", args);
+ LLSD payload;
+ payload["from_id"] = from_id;
+ LLNotificationsUtil::add("InventoryAccepted", args, payload);
break;
}
case IM_INVENTORY_DECLINED:
{
args["NAME"] = name;
- LLNotificationsUtil::add("InventoryDeclined", args);
+ LLSD payload;
+ payload["from_id"] = from_id;
+ LLNotificationsUtil::add("InventoryDeclined", args, payload);
break;
}
// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 608060174a..175b6f1d10 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -316,6 +316,8 @@ void LLVoiceChannel::activate()
}
}
+ sCurrentVoiceChannelChangedSignal(this->mSessionID);
+
if (mState == STATE_NO_CHANNEL_INFO)
{
// responsible for setting status to active
@@ -325,8 +327,6 @@ void LLVoiceChannel::activate()
{
setState(STATE_CALL_STARTED);
}
-
- sCurrentVoiceChannelChangedSignal(this->mSessionID);
}
void LLVoiceChannel::getChannelInfo()
@@ -874,61 +874,6 @@ void LLVoiceChannelP2P::setState(EState state)
return;
}
}
- else // outgoing call
- {
- mCallDialogPayload["session_id"] = mSessionID;
- mCallDialogPayload["session_name"] = mSessionName;
- mCallDialogPayload["other_user_id"] = mOtherUserID;
- if (state == STATE_RINGING ||
- state == STATE_CALL_STARTED)
- {
- // *HACK: open outgoing call floater if needed, might be better done elsewhere.
- // *TODO: should move this squirrelly ui-fudging crap into LLOutgoingCallDialog itself
- if (!mSessionName.empty())
- {
- LLOutgoingCallDialog *ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
- if (ocd)
- {
- ocd->getChild<LLTextBox>("calling")->setVisible(true);
- ocd->getChild<LLTextBox>("leaving")->setVisible(true);
- ocd->getChild<LLTextBox>("connecting")->setVisible(false);
- ocd->getChild<LLTextBox>("noanswer")->setVisible(false);
- }
- }
- }
- /*else if (state == STATE_CONNECTED)
- {
- LLOutgoingCallDialog *ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
- if (ocd)
- {
- ocd->getChild<LLTextBox>("calling")->setVisible(false);
- ocd->getChild<LLTextBox>("leaving")->setVisible(false);
- ocd->getChild<LLTextBox>("connecting")->setVisible(true);
- ocd->getChild<LLTextBox>("noanswer")->setVisible(false);
- }
- }*/
- else if (state == STATE_ERROR)
- {
- LLOutgoingCallDialog *ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
- if (ocd)
- {
- ocd->getChild<LLTextBox>("calling")->setVisible(false);
- ocd->getChild<LLTextBox>("leaving")->setVisible(false);
- ocd->getChild<LLTextBox>("connecting")->setVisible(false);
- ocd->getChild<LLTextBox>("noanswer")->setVisible(true);
- }
- }
- else if (state == STATE_HUNG_UP ||
- state == STATE_CONNECTED)
- {
- // hide popup
- LLOutgoingCallDialog *ocd = dynamic_cast<LLOutgoingCallDialog*>(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE));
- if (ocd)
- {
- ocd->closeFloater();
- }
- }
- }
LLVoiceChannel::setState(state);
}
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index b1116dc0d2..7e309d2bad 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -204,9 +204,6 @@ with the same filename but different name
<texture name="Icon_Restore_Foreground" file_name="windows/Icon_Restore_Foreground.png" preload="false" />
<texture name="Icon_Restore_Press" file_name="windows/Icon_Restore_Press.png" preload="false" />
- <texture name="Icon_Undock_Foreground" file_name="windows/Icon_Undock_Foreground.png" preload="false" />
- <texture name="Icon_Undock_Press" file_name="windows/Icon_Undock_Press.png" preload="false" />
-
<texture name="Info" file_name="icons/Info.png" preload="false" />
<texture name="Info_Small" file_name="icons/Info_Small.png" preload="false" />
<texture name="Info_Off" file_name="navbar/Info_Off.png" preload="false" />
@@ -483,6 +480,7 @@ with the same filename but different name
<texture name="SliderThumb_Off" file_name="widgets/SliderThumb_Off.png" />
<texture name="SliderThumb_Disabled" file_name="widgets/SliderThumb_Disabled.png" />
<texture name="SliderThumb_Press" file_name="widgets/SliderThumb_Press.png" />
+ <texture name="SL_Logo" file_name="map_infohub.tga" />
<texture name="Snapshot_Off" file_name="bottomtray/Snapshot_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
<texture name="Snapshot_Over" file_name="bottomtray/Snapshot_Over.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
index be6d63716c..3fc57372de 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -6,20 +6,30 @@
top="0"
follows="right|bottom"
layout="topleft"
- name="notification_chiclet"
+ name="sys_well_window"
help_topic="notification_chiclet"
save_rect="true"
title="NOTIFICATIONS"
width="320"
min_width="320"
height="23"
- can_minimize="true"
+ can_minimize="false"
can_tear_off="false"
can_resize="true"
can_drag_on_left="false"
- can_close="false"
can_dock="true"
+ save_visibility="true"
+ single_instance="true"
>
+ <string
+ name="title_im_well_window">
+ IM SESSIONS
+ </string>
+ <string
+ name="title_notification_well_window">
+ NOTIFICATIONS
+ </string>
+
<flat_list_view
color="FloaterDefaultBackgroundColor"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d8eb65322b..f659062cfe 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4499,14 +4499,14 @@ You don&apos;t have permission to copy this.
<notification
icon="notifytip.tga"
name="InventoryAccepted"
- type="notifytip">
+ type="offer">
[NAME] received your inventory offer.
</notification>
<notification
icon="notifytip.tga"
name="InventoryDeclined"
- type="notifytip">
+ type="offer">
[NAME] declined your inventory offer.
</notification>
@@ -5128,6 +5128,13 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you [O
text="Decline"/>
</form>
</notification>
+
+ <notification
+ icon="notify.tga"
+ name="FriendshipOffered"
+ type="offer">
+ You have offered friendship to [TO_NAME]
+ </notification>
<notification
icon="notify.tga"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index ec3f7ea7c5..7f847237ce 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -319,38 +319,82 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
layout="topleft"
min_height="28"
top="0"
- name="sys_well_panel"
- width="54"
- min_width="54"
+ name="im_well_panel"
+ width="34"
+ min_width="34"
+ user_resize="false">
+ <chiclet_im_well
+ follows="right"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="im_well"
+ top="4"
+ width="34">
+ <button
+ auto_resize="true"
+ flash_color="EmphasisColor"
+ follows="right"
+ halign="center"
+ height="23"
+ image_overlay="Notices_Unread"
+ image_overlay_alignment="center"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ left="0"
+ name="Unread IM messages"
+ pad_left="0"
+ pad_right="0"
+ width="34" >
+ <button.init_callback
+ function="Button.SetDockableFloaterToggle"
+ parameter="im_well_window" />
+ </button>
+ </chiclet_im_well>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ top="0"
+ name="notification_well_panel"
+ width="34"
+ min_width="34"
user_resize="false">
<chiclet_notification
follows="right"
height="23"
layout="topleft"
left="0"
- name="sys_well"
+ name="notification_well"
top="4"
- width="54">
+ width="34">
<button
image_selected="PushButton_Selected_Press"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
auto_resize="true"
- halign="right"
+ halign="center"
height="23"
follows="right"
flash_color="EmphasisColor"
left="0"
name="Unread"
image_overlay="Notices_Unread"
- image_overlay_alignment="right"
- pad_right="6"
- pad_left="6"
- width="54"
- />
+ image_overlay_alignment="center"
+ pad_right="0"
+ pad_left="0"
+ width="34" >
+ <button.init_callback
+ function="Button.SetDockableFloaterToggle"
+ parameter="notification_well_window" />
+ </button>
</chiclet_notification>
</layout_panel>
- <icon
+ <icon
auto_resize="false"
color="0 0 0 0"
follows="left|right"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
index a833ad97d9..bbf86089cb 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
@@ -51,6 +51,10 @@
http://www.secondlife.com/account/partners.php?lang=en
</string>
<string
+ name="my_account_link_url">
+ http://secondlife.com/my
+ </string>
+ <string
name="no_partner_text"
value="None" />
<scroll_container
@@ -256,7 +260,7 @@
layout="topleft"
left="10"
name="my_account_link"
- value="Go to My Dashboard"
+ value="[[URL] Go to My Dashboard]"
width="285" />
<text
follows="left|top|right"
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 5bae5c2711..a5bab3232c 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -367,7 +367,7 @@ things in this group. There&apos;s a broad variety of Abilities.
<text_editor
type="string"
halign="left"
- height="50"
+ height="35"
layout="topleft"
left="0"
max_length="295"
@@ -426,6 +426,10 @@ things in this group. There&apos;s a broad variety of Abilities.
width="300">
<scroll_list.columns
label=""
+ name="icon"
+ width="2" />
+ <scroll_list.columns
+ label=""
name="checkbox"
width="20" />
<scroll_list.columns
diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml
index 1e570bf207..ccd754ac5e 100644
--- a/indra/newview/skins/default/xui/en/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
background_visible="true"
- height="175"
+ height="152"
label="im_panel"
layout="topleft"
left="0"
@@ -83,13 +83,4 @@
width="285"
word_wrap="true"
max_length="350" />
- <button
- follows="bottom"
- height="23"
- label="Reply"
- layout="topleft"
- left="100"
- name="reply"
- top="144"
- width="100" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index b014b8d1c0..e72cacc8d5 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -88,7 +88,6 @@
<string name="BUTTON_MINIMIZE">Minimize</string>
<string name="BUTTON_TEAR_OFF">Tear Off</string>
<string name="BUTTON_DOCK">Dock</string>
- <string name="BUTTON_UNDOCK">Undock</string>
<string name="BUTTON_HELP">Show Help</string>
<!-- searching - generic -->
diff --git a/indra/newview/skins/default/xui/en/widgets/floater.xml b/indra/newview/skins/default/xui/en/widgets/floater.xml
index b2bd9c38c9..19fb520b44 100644
--- a/indra/newview/skins/default/xui/en/widgets/floater.xml
+++ b/indra/newview/skins/default/xui/en/widgets/floater.xml
@@ -16,13 +16,11 @@
minimize_image="Icon_Minimize_Foreground"
tear_off_image="tearoffbox.tga"
dock_image="Icon_Dock_Foreground"
- undock_image="Icon_Undock_Foreground"
help_image="Icon_Help_Foreground"
close_pressed_image="Icon_Close_Press"
restore_pressed_image="Icon_Restore_Press"
minimize_pressed_image="Icon_Minimize_Press"
tear_off_pressed_image="tearoff_pressed.tga"
dock_pressed_image="Icon_Dock_Press"
- undock_pressed_image="Icon_Undock_Press"
help_pressed_image="Icon_Help_Press"
/>