summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorTofu Linden <tofu.linden@lindenlab.com>2010-01-25 10:12:54 -0800
committerTofu Linden <tofu.linden@lindenlab.com>2010-01-25 10:12:54 -0800
commit6ff6ed4d1148a66b188472c94b58bd573389942d (patch)
treea4a6e2a4711c3d9a3dd019e98507a568cac4ba60 /indra
parentf11f8b34478f0d408689fe7959f233567001374d (diff)
parent254b7d72d17c279aa906ee235f08ff1fa9e2b9cf (diff)
PE merge.
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/lltextbase.cpp10
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llavataractions.cpp13
-rw-r--r--indra/newview/llavataractions.h4
-rw-r--r--indra/newview/llavatarlistitem.cpp12
-rw-r--r--indra/newview/llavatarlistitem.h2
-rw-r--r--indra/newview/llcallfloater.cpp6
-rw-r--r--indra/newview/llchathistory.cpp5
-rw-r--r--indra/newview/llchathistory.h2
-rw-r--r--indra/newview/llfloatergroups.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp9
-rw-r--r--indra/newview/llfloaterpreference.h3
-rw-r--r--indra/newview/llfloaterreporter.cpp2
-rw-r--r--indra/newview/llgrouplist.cpp4
-rw-r--r--indra/newview/llimview.cpp2
-rw-r--r--indra/newview/llmutelist.cpp76
-rw-r--r--indra/newview/llmutelist.h9
-rw-r--r--indra/newview/llnearbychat.cpp5
-rw-r--r--indra/newview/llpanelavatar.cpp48
-rw-r--r--indra/newview/llpanelavatar.h16
-rw-r--r--indra/newview/llpanelgroup.cpp33
-rw-r--r--indra/newview/llpanelgroup.h8
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp54
-rw-r--r--indra/newview/llpanelimcontrolpanel.h12
-rw-r--r--indra/newview/llpanelme.cpp2
-rw-r--r--indra/newview/llpanelpeople.cpp45
-rw-r--r--indra/newview/llpanelpeople.h9
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp15
-rw-r--r--indra/newview/llpanelplaces.cpp14
-rw-r--r--indra/newview/llpanelprofileview.cpp54
-rw-r--r--indra/newview/llpanelprofileview.h20
-rw-r--r--indra/newview/llparticipantlist.cpp2
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/lltransientdockablefloater.cpp24
-rw-r--r--indra/newview/lltransientfloatermgr.cpp4
-rw-r--r--indra/newview/lltransientfloatermgr.h2
-rw-r--r--indra/newview/llvoiceclient.cpp127
-rw-r--r--indra/newview/llvoiceclient.h2
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml3
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml28
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_land_money.xml90
43 files changed, 489 insertions, 314 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 17aecaf32f..47db990a37 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1009,6 +1009,16 @@ void LLTextBase::draw()
void LLTextBase::setColor( const LLColor4& c )
{
mFgColor = c;
+ //textsegments have own style property ,
+ //so we have to update it also to apply changes, EXT-4433
+ for(segment_set_t::iterator it = mSegments.begin(); it != mSegments.end(); it++)
+ {
+ LLTextSegment* segment = it->get();
+ if(segment)
+ {
+ segment->setColor(mFgColor);
+ }
+ }
}
//virtual
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c29a3a0035..72d2e1aba0 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10314,6 +10314,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>VoiceDefaultInternalLevel</key>
+ <map>
+ <key>Comment</key>
+ <string>Internal level of voice set by default. Is equivalent to 0.5 (from 0.0-1.0 range) external voice level (internal = 400 * external^2).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>100</integer>
+ </map>
<key>VoiceEarLocation</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 40c9bb6afa..bb14c41cec 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -263,18 +263,9 @@ bool LLAvatarActions::isCalling(const LLUUID &id)
}
//static
-bool LLAvatarActions::canCall(const LLUUID &id)
+bool LLAvatarActions::canCall()
{
- // For now we do not need to check whether passed UUID is ID of agent's friend.
- // Use common check of Voice Client state.
- {
- // don't need to check online/offline status because "usual resident" (resident that is not a friend)
- // can be only ONLINE. There is no way to see "usual resident" in OFFLINE status. If we see "usual
- // resident" it automatically means that the resident is ONLINE. So to make a call to the "usual resident"
- // we need to check only that "our" voice is enabled.
- return LLVoiceClient::voiceEnabled();
- }
-
+ return LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
}
// static
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index a4504ae679..ebfd40b796 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -129,10 +129,10 @@ public:
static bool isCalling(const LLUUID &id);
/**
- * @return true if call to the resident can be made (resident is online and voice is enabled)
+ * @return true if call to the resident can be made
*/
- static bool canCall(const LLUUID &id);
+ static bool canCall();
/**
* Invite avatar to a group.
*/
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 66ab32f3e8..2bcd097717 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -440,17 +440,17 @@ LLAvatarListItem::icon_color_map_t& LLAvatarListItem::getItemIconColorMap()
// static
void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
{
+ //speaking indicator width + padding
+ S32 speaking_indicator_width = avatar_item->getRect().getWidth() - avatar_item->mSpeakingIndicator->getRect().mLeft;
+
//profile btn width + padding
- S32 profile_btn_width = avatar_item->getRect().getWidth() - avatar_item->mProfileBtn->getRect().mLeft;
+ S32 profile_btn_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mProfileBtn->getRect().mLeft;
//info btn width + padding
S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft;
- //speaking indicator width + padding
- S32 speaking_indicator_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mSpeakingIndicator->getRect().mLeft;
-
// last interaction time textbox width + padding
- S32 last_interaction_time_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
+ S32 last_interaction_time_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
// icon width + padding
S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft;
@@ -462,9 +462,9 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
sChildrenWidths[--index] = icon_width;
sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space"
sChildrenWidths[--index] = last_interaction_time_width;
- sChildrenWidths[--index] = speaking_indicator_width;
sChildrenWidths[--index] = info_btn_width;
sChildrenWidths[--index] = profile_btn_width;
+ sChildrenWidths[--index] = speaking_indicator_width;
}
void LLAvatarListItem::updateChildren()
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 479a4833cb..61c0a8660e 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -129,9 +129,9 @@ private:
* @see updateChildren()
*/
typedef enum e_avatar_item_child {
+ ALIC_SPEAKER_INDICATOR,
ALIC_PROFILE_BUTTON,
ALIC_INFO_BUTTON,
- ALIC_SPEAKER_INDICATOR,
ALIC_INTERACTION_TIME,
ALIC_NAME,
ALIC_ICON,
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index d4c8adadc6..d9df537e03 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -43,6 +43,7 @@
#include "llavatariconctrl.h"
#include "llavatarlist.h"
#include "llbottomtray.h"
+#include "lldraghandle.h"
#include "llimfloater.h"
#include "llfloaterreg.h"
#include "llparticipantlist.h"
@@ -158,6 +159,11 @@ BOOL LLCallFloater::postBuild()
connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
+ setIsChrome(true);
+ //chrome="true" hides floater caption
+ if (mDragHandle)
+ mDragHandle->setTitleVisible(TRUE);
+
return TRUE;
}
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index a46cd84b60..d6a7edee5b 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -550,8 +550,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
if (mLastFromName == chat.mFromName
&& mLastFromID == chat.mFromID
&& mLastMessageTime.notNull()
- && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
- )
+ && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
+ && mLastMessageTimeStr.size() == chat.mTimeStr.size()) //*HACK to distinguish between current and previous chat session's histories
{
view = getSeparator();
p.top_pad = mTopSeparatorPad;
@@ -585,6 +585,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
mLastFromName = chat.mFromName;
mLastFromID = chat.mFromID;
mLastMessageTime = new_message_time;
+ mLastMessageTimeStr = chat.mTimeStr;
}
std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index f2d403f639..c2c60e60cf 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -125,6 +125,8 @@ class LLChatHistory : public LLUICtrl
std::string mLastFromName;
LLUUID mLastFromID;
LLDate mLastMessageTime;
+ std::string mLastMessageTimeStr;
+
std::string mMessageHeaderFilename;
std::string mMessageSeparatorFilename;
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 29f415bd43..c71764c2e5 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -75,7 +75,7 @@ LLFloaterGroupPicker::~LLFloaterGroupPicker()
void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)
{
mPowersMask = powers_mask;
- postBuild();
+ init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), mPowersMask);
}
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index fc036cb354..60c15c253d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1435,6 +1435,7 @@ BOOL LLPanelPreference::postBuild()
media_enabled_ctrl->set(enabled);
media_enabled_ctrl->setTentative(!(video_enabled == music_enabled == media_enabled));
getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(enabled);
+ getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));
}
apply();
@@ -1485,6 +1486,14 @@ void LLPanelPreference::saveSettings()
}
}
+void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value)
+{
+ if (checkbox && checkbox->getValue())
+ {
+ LLNotificationsUtil::add("FriendsAndGroupsOnly");
+ }
+}
+
void LLPanelPreference::cancel()
{
for (control_values_map_t::iterator iter = mSavedValues.begin();
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 6f382620ee..8b02a4049d 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -166,6 +166,9 @@ public:
virtual void saveSettings();
private:
+ //for "Only friends and groups can call or IM me"
+ static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&);
+
typedef std::map<LLControlVariable*, LLSD> control_values_map_t;
control_values_map_t mSavedValues;
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 2efae0c8db..4a1eb51dbe 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -324,7 +324,7 @@ void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string
std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect");
childSetText("owner_name", avatar_link);
- childSetText("object_name", avatar_name); // name
+ childSetText("object_name", avatar_name);
childSetText("abuser_name_edit", avatar_name);
}
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index e75d35bea4..e01709aa3a 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -48,6 +48,7 @@
#include "lltextutil.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
+#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
S32 LLGroupListItem::sIconWidth = 0;
@@ -271,6 +272,9 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
if (userdata.asString() == "activate")
return gAgent.getGroupID() != selected_group_id;
+ if (userdata.asString() == "call")
+ return LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();
+
return real_group_selected;
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c2a7969c0d..32b0cbff38 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1680,6 +1680,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
case LLVoiceChannel::STATE_ERROR :
getChild<LLTextBox>("noanswer")->setVisible(true);
getChild<LLButton>("Cancel")->setVisible(false);
+ setCanClose(true);
mLifetimeTimer.start();
break;
case LLVoiceChannel::STATE_HUNG_UP :
@@ -1692,6 +1693,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
getChild<LLTextBox>("nearby")->setVisible(true);
}
getChild<LLButton>("Cancel")->setVisible(false);
+ setCanClose(true);
mLifetimeTimer.start();
}
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 7ee4c64f8f..c1666f5666 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -52,23 +52,15 @@
#include <boost/tokenizer.hpp>
-#include "llcrc.h"
-#include "lldir.h"
#include "lldispatcher.h"
-#include "llsdserialize.h"
#include "llxfermanager.h"
-#include "message.h"
#include "llagent.h"
#include "llviewergenericmessage.h" // for gGenericDispatcher
-#include "llviewerwindow.h"
#include "llworld.h" //for particle system banning
-#include "llchat.h"
#include "llimpanel.h"
#include "llimview.h"
#include "llnotifications.h"
-#include "lluistring.h"
-#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "lltrans.h"
@@ -219,61 +211,17 @@ LLMuteList* LLMuteList::getInstance()
// LLMuteList()
//-----------------------------------------------------------------------------
LLMuteList::LLMuteList() :
- mIsLoaded(FALSE),
- mUserVolumesLoaded(FALSE)
+ mIsLoaded(FALSE)
{
gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
}
-void LLMuteList::loadUserVolumes()
-{
- // call once, after LLDir::setLindenUserDir() has been called
- if (mUserVolumesLoaded)
- return;
- mUserVolumesLoaded = TRUE;
-
- // load per-resident voice volume information
- // conceptually, this is part of the mute list information, although it is only stored locally
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
-
- LLSD settings_llsd;
- llifstream file;
- file.open(filename);
- if (file.is_open())
- {
- LLSDSerialize::fromXML(settings_llsd, file);
- }
-
- for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
- iter != settings_llsd.endMap(); ++iter)
- {
- mUserVolumeSettings.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal()));
- }
-}
-
//-----------------------------------------------------------------------------
// ~LLMuteList()
//-----------------------------------------------------------------------------
LLMuteList::~LLMuteList()
{
- // If we quit from the login screen we will not have an SL account
- // name. Don't try to save, otherwise we'll dump a file in
- // C:\Program Files\SecondLife\ or similar. JC
- std::string user_dir = gDirUtilp->getLindenUserDir();
- if (!user_dir.empty())
- {
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
- LLSD settings_llsd;
-
- for(user_volume_map_t::iterator iter = mUserVolumeSettings.begin(); iter != mUserVolumeSettings.end(); ++iter)
- {
- settings_llsd[iter->first.asString()] = iter->second;
- }
- llofstream file;
- file.open(filename);
- LLSDSerialize::toPrettyXML(settings_llsd, file);
- }
}
BOOL LLMuteList::isLinden(const std::string& name) const
@@ -715,8 +663,6 @@ BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) c
//-----------------------------------------------------------------------------
void LLMuteList::requestFromServer(const LLUUID& agent_id)
{
- loadUserVolumes();
-
std::string agent_id_string;
std::string filename;
agent_id.toString(agent_id_string);
@@ -751,26 +697,6 @@ void LLMuteList::cache(const LLUUID& agent_id)
}
}
-void LLMuteList::setSavedResidentVolume(const LLUUID& id, F32 volume)
-{
- // store new value in volume settings file
- mUserVolumeSettings[id] = volume;
-}
-
-F32 LLMuteList::getSavedResidentVolume(const LLUUID& id)
-{
- const F32 DEFAULT_VOLUME = 0.5f;
-
- user_volume_map_t::iterator found_it = mUserVolumeSettings.find(id);
- if (found_it != mUserVolumeSettings.end())
- {
- return found_it->second;
- }
- //FIXME: assumes default, should get this from somewhere
- return DEFAULT_VOLUME;
-}
-
-
//-----------------------------------------------------------------------------
// Static message handlers
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 409b637bf2..e1e81a24b4 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -127,12 +127,7 @@ public:
// call this method on logout to save everything.
void cache(const LLUUID& agent_id);
- void setSavedResidentVolume(const LLUUID& id, F32 volume);
- F32 getSavedResidentVolume(const LLUUID& id);
-
private:
- void loadUserVolumes();
-
BOOL loadFromFile(const std::string& filename);
BOOL saveToFile(const std::string& filename);
@@ -179,12 +174,8 @@ private:
observer_set_t mObservers;
BOOL mIsLoaded;
- BOOL mUserVolumesLoaded;
friend class LLDispatchEmptyMuteList;
-
- typedef std::map<LLUUID, F32> user_volume_map_t;
- user_volume_map_t mUserVolumeSettings;
};
class LLMuteListObserver
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a7c1e73328..0a8d020b4f 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -101,6 +101,11 @@ BOOL LLNearbyChat::postBuild()
getDockTongue(), LLDockControl::TOP, boost::bind(&LLNearbyChat::getAllowedRect, this, _1)));
}
+ setIsChrome(true);
+ //chrome="true" hides floater caption
+ if (mDragHandle)
+ mDragHandle->setTitleVisible(TRUE);
+
return true;
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 85e95ca1d6..fe5b20813a 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -165,6 +165,8 @@ BOOL LLPanelAvatarNotes::postBuild()
resetControls();
resetData();
+ gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
+
return TRUE;
}
@@ -337,6 +339,8 @@ LLPanelAvatarNotes::~LLPanelAvatarNotes()
if(getAvatarId().notNull())
{
LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
}
}
@@ -346,6 +350,17 @@ void LLPanelAvatarNotes::changed(U32 mask)
childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));
}
+// virtual
+void LLPanelAvatarNotes::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
void LLPanelAvatarNotes::setAvatarId(const LLUUID& id)
{
if(id.notNull())
@@ -437,7 +452,6 @@ void LLPanelProfileTab::updateButtons()
bool enable_map_btn = is_avatar_online && gAgent.isGodlike() || is_agent_mappable(getAvatarId());
childSetEnabled("show_on_map_btn", enable_map_btn);
- childSetEnabled("call", LLAvatarActions::canCall(getAvatarId()));
}
//////////////////////////////////////////////////////////////////////////
@@ -485,6 +499,8 @@ BOOL LLPanelAvatarProfile::postBuild()
pic = getChild<LLTextureCtrl>("real_world_pic");
pic->setFallbackImageName("default_profile_picture.j2c");
+ gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
+
resetControls();
resetData();
@@ -568,8 +584,6 @@ void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_d
fillPartnerData(avatar_data);
- fillOnlineStatus(avatar_data);
-
fillAccountStatus(avatar_data);
}
@@ -637,21 +651,6 @@ void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data)
}
}
-void LLPanelAvatarProfile::fillOnlineStatus(const LLAvatarData* avatar_data)
-{
- bool online = avatar_data->flags & AVATAR_ONLINE;
- if(LLAvatarActions::isFriend(avatar_data->avatar_id))
- {
- // Online status NO could be because they are hidden
- // If they are a friend, we may know the truth!
- online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id);
- }
- childSetValue("online_status", online ?
- "Online" : "Offline");
- childSetColor("online_status", online ?
- LLColor4::green : LLColor4::red);
-}
-
void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)
{
LLStringUtil::format_map_t args;
@@ -757,6 +756,8 @@ LLPanelAvatarProfile::~LLPanelAvatarProfile()
if(getAvatarId().notNull())
{
LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
}
}
@@ -766,6 +767,17 @@ void LLPanelAvatarProfile::changed(U32 mask)
childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));
}
+// virtual
+void LLPanelAvatarProfile::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
void LLPanelAvatarProfile::setAvatarId(const LLUUID& id)
{
if(id.notNull())
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 22efa5dc35..ce59f1e93d 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -36,6 +36,7 @@
#include "llpanel.h"
#include "llavatarpropertiesprocessor.h"
#include "llcallingcard.h"
+#include "llvoiceclient.h"
class LLComboBox;
class LLLineEditor;
@@ -122,6 +123,7 @@ private:
class LLPanelAvatarProfile
: public LLPanelProfileTab
, public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
public:
LLPanelAvatarProfile();
@@ -134,6 +136,10 @@ public:
*/
virtual void changed(U32 mask);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
/*virtual*/ void setAvatarId(const LLUUID& id);
/**
@@ -172,11 +178,6 @@ protected:
virtual void fillPartnerData(const LLAvatarData* avatar_data);
/**
- * Fills Avatar's online status.
- */
- virtual void fillOnlineStatus(const LLAvatarData* avatar_data);
-
- /**
* Fills account status.
*/
virtual void fillAccountStatus(const LLAvatarData* avatar_data);
@@ -257,6 +258,7 @@ private:
class LLPanelAvatarNotes
: public LLPanelProfileTab
, public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
public:
LLPanelAvatarNotes();
@@ -269,6 +271,10 @@ public:
*/
virtual void changed(U32 mask);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index c30ef3221d..1d447a22d7 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -101,6 +101,8 @@ LLPanelGroup::LLPanelGroup()
LLPanelGroup::~LLPanelGroup()
{
LLGroupMgr::getInstance()->removeObserver(this);
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver(this);
}
void LLPanelGroup::onOpen(const LLSD& key)
@@ -188,6 +190,8 @@ BOOL LLPanelGroup::postBuild()
if(panel_general)
panel_general->setupCtrls(this);
+
+ gVoiceClient->addObserver(this);
return TRUE;
}
@@ -300,6 +304,17 @@ void LLPanelGroup::changed(LLGroupChange gc)
update(gc);
}
+// virtual
+void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ childSetEnabled("btn_call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
void LLPanelGroup::notifyObservers()
{
changed(GC_ALL);
@@ -356,6 +371,13 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
(*it)->setGroupID(group_id);
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
+ if(gdatap)
+ {
+ childSetValue("group_name", gdatap->mName);
+ childSetToolTip("group_name",gdatap->mName);
+ }
+
LLButton* button_apply = findChild<LLButton>("btn_apply");
LLButton* button_refresh = findChild<LLButton>("btn_refresh");
LLButton* button_create = findChild<LLButton>("btn_create");
@@ -457,17 +479,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
}
reposButtons();
-
- LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
-
- if(gdatap)
- {
- childSetValue("group_name", gdatap->mName);
- childSetToolTip("group_name",gdatap->mName);
-
- //group data is already present, call update manually
- update(GC_ALL);
- }
}
bool LLPanelGroup::apply(LLPanelGroupTab* tab)
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 7ea5e67b44..8c84695677 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -35,6 +35,7 @@
#include "llgroupmgr.h"
#include "llpanel.h"
#include "lltimer.h"
+#include "llvoiceclient.h"
struct LLOfferInfo;
@@ -47,7 +48,8 @@ class LLAgent;
class LLPanelGroup : public LLPanel,
- public LLGroupMgrObserver
+ public LLGroupMgrObserver,
+ public LLVoiceClientStatusObserver
{
public:
LLPanelGroup();
@@ -64,6 +66,10 @@ public:
// Group manager observer trigger.
virtual void changed(LLGroupChange gc);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
void showNotice(const std::string& subject,
const std::string& message,
const bool& has_inventory,
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index a334eb9d68..ff1e43b526 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -64,21 +64,52 @@ void LLPanelChatControlPanel::onOpenVoiceControlsClicked()
LLFloaterReg::showInstance("voice_controls");
}
+void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ updateCallButton();
+}
+
void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
{
updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
}
+void LLPanelChatControlPanel::updateCallButton()
+{
+ // hide/show call button
+ bool voice_enabled = LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
+
+ LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
+ if (!session) return;
+
+ bool session_initialized = session->mSessionInitialized;
+ bool callback_enabled = session->mCallBackEnabled;
+
+ BOOL enable_connect = session_initialized
+ && voice_enabled
+ && callback_enabled;
+ childSetEnabled("call_btn", enable_connect);
+}
+
void LLPanelChatControlPanel::updateButtons(bool is_call_started)
{
childSetVisible("end_call_btn_panel", is_call_started);
childSetVisible("voice_ctrls_btn_panel", is_call_started);
childSetVisible("call_btn_panel", ! is_call_started);
+ updateCallButton();
+
}
LLPanelChatControlPanel::~LLPanelChatControlPanel()
{
mVoiceChannelStateChangeConnection.disconnect();
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver(this);
}
BOOL LLPanelChatControlPanel::postBuild()
@@ -87,26 +118,9 @@ BOOL LLPanelChatControlPanel::postBuild()
childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
- return TRUE;
-}
-
-void LLPanelChatControlPanel::draw()
-{
- // hide/show start call and end call buttons
- bool voice_enabled = LLVoiceClient::voiceEnabled();
-
- LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
- if (!session) return;
+ gVoiceClient->addObserver(this);
- bool session_initialized = session->mSessionInitialized;
- bool callback_enabled = session->mCallBackEnabled;
-
- BOOL enable_connect = session_initialized
- && voice_enabled
- && callback_enabled;
- childSetEnabled("call_btn", enable_connect);
-
- LLPanel::draw();
+ return TRUE;
}
void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
@@ -266,6 +280,8 @@ void LLPanelGroupControlPanel::draw()
// Need to resort the participant list if it's in sort by recent speaker order.
if (mParticipantList)
mParticipantList->updateRecentSpeakersOrder();
+ //* TODO: find better way to properly enable call button for group and remove this call from draw()
+ updateCallButton();
LLPanelChatControlPanel::draw();
}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index 25fdf944c9..3ab505a084 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -39,7 +39,9 @@
class LLParticipantList;
-class LLPanelChatControlPanel : public LLPanel
+class LLPanelChatControlPanel
+ : public LLPanel
+ , public LLVoiceClientStatusObserver
{
public:
LLPanelChatControlPanel() :
@@ -47,15 +49,21 @@ public:
~LLPanelChatControlPanel();
virtual BOOL postBuild();
- virtual void draw();
void onCallButtonClicked();
void onEndCallButtonClicked();
void onOpenVoiceControlsClicked();
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
void updateButtons(bool is_call_started);
+
+ // Enables/disables call button depending on voice availability
+ void updateCallButton();
virtual void setSessionId(const LLUUID& session_id);
const LLUUID& getSessionId() { return mSessionId; }
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index ece93125b3..0f0fb4b94e 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -198,8 +198,6 @@ void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_d
{
fillCommonData(avatar_data);
- fillOnlineStatus(avatar_data);
-
fillPartnerData(avatar_data);
fillAccountStatus(avatar_data);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index c14b282488..b01cdcc832 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -462,6 +462,9 @@ LLPanelPeople::~LLPanelPeople()
delete mFriendListUpdater;
delete mRecentListUpdater;
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver(this);
+
LLView::deleteViewByHandle(mGroupPlusMenuHandle);
LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
LLView::deleteViewByHandle(mFriendsViewSortMenuHandle);
@@ -612,6 +615,8 @@ BOOL LLPanelPeople::postBuild()
if(recent_view_sort)
mRecentViewSortMenuHandle = recent_view_sort->getHandle();
+ gVoiceClient->addObserver(this);
+
// call this method in case some list is empty and buttons can be in inconsistent state
updateButtons();
@@ -621,6 +626,17 @@ BOOL LLPanelPeople::postBuild()
return TRUE;
}
+// virtual
+void LLPanelPeople::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ updateButtons();
+}
+
void LLPanelPeople::updateFriendList()
{
if (!mOnlineFriendList || !mAllFriendList)
@@ -775,41 +791,20 @@ void LLPanelPeople::updateButtons()
}
}
+ bool enable_calls = gVoiceClient->voiceWorking() && gVoiceClient->voiceEnabled();
+
buttonSetEnabled("teleport_btn", friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));
buttonSetEnabled("view_profile_btn", item_selected);
buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection
- buttonSetEnabled("call_btn", multiple_selected && canCall());
+ buttonSetEnabled("call_btn", multiple_selected && enable_calls);
buttonSetEnabled("share_btn", item_selected); // not implemented yet
bool none_group_selected = item_selected && selected_id.isNull();
buttonSetEnabled("group_info_btn", !none_group_selected);
- buttonSetEnabled("group_call_btn", !none_group_selected);
+ buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);
buttonSetEnabled("chat_btn", !none_group_selected);
}
-bool LLPanelPeople::canCall()
-{
- std::vector<LLUUID> selected_uuids;
- getCurrentItemIDs(selected_uuids);
-
- bool result = false;
-
- std::vector<LLUUID>::const_iterator
- id = selected_uuids.begin(),
- uuids_end = selected_uuids.end();
-
- for (;id != uuids_end; ++id)
- {
- if (LLAvatarActions::canCall(*id))
- {
- result = true;
- break;
- }
- }
-
- return result;
-}
-
std::string LLPanelPeople::getActiveTabName() const
{
return mTabContainer->getCurrentPanel()->getName();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 7580fdbeef..6d3d436156 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -36,13 +36,16 @@
#include <llpanel.h>
#include "llcallingcard.h" // for avatar tracker
+#include "llvoiceclient.h"
class LLFilterEditor;
class LLTabContainer;
class LLAvatarList;
class LLGroupList;
-class LLPanelPeople : public LLPanel
+class LLPanelPeople
+ : public LLPanel
+ , public LLVoiceClientStatusObserver
{
LOG_CLASS(LLPanelPeople);
public:
@@ -52,6 +55,9 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ bool notifyChildren(const LLSD& info);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable call buttons
+ // when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
// internals
class Updater;
@@ -73,7 +79,6 @@ private:
bool isFriendOnline(const LLUUID& id);
bool isItemsFreeOfFriends(const std::vector<LLUUID>& uuids);
- bool canCall();
void updateButtons();
std::string getActiveTabName() const;
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index c1c10e6022..d9651a6045 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -183,20 +183,7 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
}
else if (item == std::string("can_call"))
{
- bool result = false;
- std::vector<LLUUID>::const_iterator
- id = mUUIDs.begin(),
- uuids_end = mUUIDs.end();
-
- for (;id != uuids_end; ++id)
- {
- if (LLAvatarActions::canCall(*id))
- {
- result = true;
- break;
- }
- }
- return result;
+ return LLAvatarActions::canCall();
}
return false;
}
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index a4f0e55a93..a8a9717750 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -384,6 +384,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)
// Otherwise stop using land selection and deselect land.
if (mPlaceInfoType == AGENT_INFO_TYPE)
{
+ // We don't know if we are already added to LLViewerParcelMgr observers list
+ // so try to remove observer not to add an extra one.
+ parcel_mgr->removeObserver(mParcelObserver);
+
parcel_mgr->addObserver(mParcelObserver);
parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
}
@@ -898,6 +902,8 @@ void LLPanelPlaces::changedParcelSelection()
if (!region || !parcel)
return;
+ LLVector3d prev_pos_global = mPosGlobal;
+
// If agent is inside the selected parcel show agent's region<X, Y, Z>,
// otherwise show region<X, Y, Z> of agent's selection point.
bool is_current_parcel = is_agent_in_selected_parcel(parcel);
@@ -914,7 +920,13 @@ void LLPanelPlaces::changedParcelSelection()
}
}
- mPlaceProfile->resetLocation();
+ // Reset location info only if global position is changed
+ // to reduce unnecessary text and icons updates.
+ if (prev_pos_global != mPosGlobal)
+ {
+ mPlaceProfile->resetLocation();
+ }
+
mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel);
updateVerbs();
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index 7832f63e6a..044036ea50 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -101,8 +101,6 @@ void LLPanelProfileView::onOpen(const LLSD& key)
id = key["id"];
}
- // subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself
- mAvatarStatusObserver->subscribe();
if(id.notNull() && getAvatarId() != id)
{
setAvatarId(id);
@@ -111,12 +109,9 @@ void LLPanelProfileView::onOpen(const LLSD& key)
// Update the avatar name.
gCacheName->get(getAvatarId(), FALSE,
boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4));
-/*
-// disable this part of code according to EXT-2022. See processOnlineStatus
- // status should only show if viewer has permission to view online/offline. EXT-453
- mStatusText->setVisible(isGrantedToSeeOnlineStatus());
+
updateOnlineStatus();
-*/
+
LLPanelProfile::onOpen(key);
}
@@ -164,27 +159,43 @@ bool LLPanelProfileView::isGrantedToSeeOnlineStatus()
// *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status.
// When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer
// see comments for ChangeUserRights template message. EXT-453.
-// return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
- return true;
+ // If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880
+ return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
}
+// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880
void LLPanelProfileView::updateOnlineStatus()
{
+ // set text box visible to show online status for non-friends who has not set in Preferences
+ // "Only Friends & Groups can see when I am online"
+ mStatusText->setVisible(TRUE);
+
const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
if (NULL == relationship)
- return;
+ {
+ // this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor.
+ // in LLPanelProfileView::processOnlineStatus()
- bool online = relationship->isOnline();
+ // subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself.
+ // do not subscribe for friend avatar because online status can be wrong overridden
+ // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set.
+ mAvatarStatusObserver->subscribe();
+ return;
+ }
+ // For friend let check if he allowed me to see his status
- std::string status = getString(online ? "status_online" : "status_offline");
+ // status should only show if viewer has permission to view online/offline. EXT-453, EXT-3880
+ mStatusText->setVisible(isGrantedToSeeOnlineStatus());
- mStatusText->setValue(status);
+ bool online = relationship->isOnline();
+ processOnlineStatus(online);
}
void LLPanelProfileView::processOnlineStatus(bool online)
{
- mAvatarIsOnline = online;
- mStatusText->setVisible(online);
+ std::string status = getString(online ? "status_online" : "status_offline");
+
+ mStatusText->setValue(status);
}
void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group)
@@ -193,17 +204,4 @@ void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string&
getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_name);
}
-void LLPanelProfileView::togglePanel(LLPanel* panel, const LLSD& key)
-{
- // *TODO: unused method?
-
- LLPanelProfile::togglePanel(panel);
- if(FALSE == panel->getVisible())
- {
- // LLPanelProfile::togglePanel shows/hides all children,
- // we don't want to display online status for non friends, so re-hide it here
- mStatusText->setVisible(mAvatarIsOnline);
- }
-}
-
// EOF
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
index 5dc617d4a0..9b87e146a8 100644
--- a/indra/newview/llpanelprofileview.h
+++ b/indra/newview/llpanelprofileview.h
@@ -64,8 +64,6 @@ public:
/*virtual*/ BOOL postBuild();
- /*virtual*/ void togglePanel(LLPanel* panel, const LLSD& key = LLSD());
-
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type,
void *cargo_data, EAcceptance *accept,
@@ -81,8 +79,21 @@ public:
protected:
void onBackBtnClick();
- bool isGrantedToSeeOnlineStatus(); // deprecated after EXT-2022 is implemented
- void updateOnlineStatus(); // deprecated after EXT-2022 is implemented
+ bool isGrantedToSeeOnlineStatus();
+
+ /**
+ * Displays avatar's online status if possible.
+ *
+ * Requirements from EXT-3880:
+ * For friends:
+ * - Online when online and privacy settings allow to show
+ * - Offline when offline and privacy settings allow to show
+ * - Else: nothing
+ * For other avatars:
+ * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
+ * - Else: Offline
+ */
+ void updateOnlineStatus();
void processOnlineStatus(bool online);
private:
@@ -96,7 +107,6 @@ private:
LLTextBox* mStatusText;
AvatarStatusObserver* mAvatarStatusObserver;
- bool mAvatarIsOnline;
};
#endif //LL_LLPANELPROFILEVIEW_H
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 88b706fb6b..c0302eee9e 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -628,7 +628,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
}
else if (item == "can_call")
{
- return LLVoiceClient::voiceEnabled();
+ return LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();
}
return true;
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 9608cd1263..6f9a1ccdbe 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -70,8 +70,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy
{
mDisplayName = name;
}
-
- gVoiceClient->setUserVolume(id, LLMuteList::getInstance()->getSavedResidentVolume(id));
}
diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp
index c9bfe178ce..9d39aa5182 100644
--- a/indra/newview/lltransientdockablefloater.cpp
+++ b/indra/newview/lltransientdockablefloater.cpp
@@ -48,6 +48,14 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockContro
LLTransientDockableFloater::~LLTransientDockableFloater()
{
LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
+ LLView* dock = getDockWidget();
+ LLTransientFloaterMgr::getInstance()->removeControlView(
+ LLTransientFloaterMgr::DOCKED, this);
+ if (dock != NULL)
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(
+ LLTransientFloaterMgr::DOCKED, dock);
+ }
}
void LLTransientDockableFloater::setVisible(BOOL visible)
@@ -55,18 +63,18 @@ void LLTransientDockableFloater::setVisible(BOOL visible)
LLView* dock = getDockWidget();
if(visible && isDocked())
{
- LLTransientFloaterMgr::getInstance()->addControlView(this);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->addControlView(dock);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
else
{
- LLTransientFloaterMgr::getInstance()->removeControlView(this);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
@@ -78,18 +86,18 @@ void LLTransientDockableFloater::setDocked(bool docked, bool pop_on_undock)
LLView* dock = getDockWidget();
if(docked)
{
- LLTransientFloaterMgr::getInstance()->addControlView(this);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->addControlView(dock);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
else
{
- LLTransientFloaterMgr::getInstance()->removeControlView(this);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index 8f1a738453..d82403070b 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -46,6 +46,7 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()
&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));
mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
+ mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));
mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));
}
@@ -132,7 +133,8 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
return;
}
- bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
+ bool hide = isControlClicked(mGroupControls.find(DOCKED)->second, x, y)
+ && isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
if (hide)
{
hideTransientFloaters(x, y);
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index 1f99325a7f..9c5ae295f2 100644
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
@@ -51,7 +51,7 @@ protected:
public:
enum ETransientGroup
{
- GLOBAL, IM
+ GLOBAL, DOCKED, IM
};
void registerTransientFloater(LLTransientFloater* floater);
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index c84afa5af1..8ca0fd6ef6 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -37,8 +37,10 @@
// library includes
#include "llnotificationsutil.h"
+#include "llsdserialize.h"
#include "llsdutil.h"
+
// project includes
#include "llvoavatar.h"
#include "llbufferstream.h"
@@ -1092,6 +1094,119 @@ static void killGateway()
#endif
+class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage>
+{
+ LOG_CLASS(LLSpeakerVolumeStorage);
+public:
+
+ /**
+ * Sets internal voluem level for specified user.
+ *
+ * @param[in] speaker_id - LLUUID of user to store volume level for
+ * @param[in] volume - internal volume level to be stored for user.
+ */
+ void storeSpeakerVolume(const LLUUID& speaker_id, S32 volume);
+
+ /**
+ * Gets stored internal volume level for specified speaker.
+ *
+ * If specified user is not found default level will be returned. It is equivalent of
+ * external level 0.5 from the 0.0..1.0 range.
+ * Default internal level is calculated as: internal = 400 * external^2
+ * Maps 0.0 to 1.0 to internal values 0-400 with default 0.5 == 100
+ *
+ * @param[in] speaker_id - LLUUID of user to get his volume level
+ */
+ S32 getSpeakerVolume(const LLUUID& speaker_id);
+
+private:
+ friend class LLSingleton<LLSpeakerVolumeStorage>;
+ LLSpeakerVolumeStorage();
+ ~LLSpeakerVolumeStorage();
+
+ const static std::string SETTINGS_FILE_NAME;
+
+ void load();
+ void save();
+
+ typedef std::map<LLUUID, S32> speaker_data_map_t;
+ speaker_data_map_t mSpeakersData;
+};
+
+const std::string LLSpeakerVolumeStorage::SETTINGS_FILE_NAME = "volume_settings.xml";
+
+LLSpeakerVolumeStorage::LLSpeakerVolumeStorage()
+{
+ load();
+}
+
+LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage()
+{
+ save();
+}
+
+void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, S32 volume)
+{
+ mSpeakersData[speaker_id] = volume;
+}
+
+S32 LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id)
+{
+ // default internal level of user voice.
+ const static LLUICachedControl<S32> DEFAULT_INTERNAL_VOLUME_LEVEL("VoiceDefaultInternalLevel", 100);
+ S32 ret_val = DEFAULT_INTERNAL_VOLUME_LEVEL;
+ speaker_data_map_t::const_iterator it = mSpeakersData.find(speaker_id);
+
+ if (it != mSpeakersData.end())
+ {
+ ret_val = it->second;
+ }
+ return ret_val;
+}
+
+void LLSpeakerVolumeStorage::load()
+{
+ // load per-resident voice volume information
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME);
+
+ LLSD settings_llsd;
+ llifstream file;
+ file.open(filename);
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(settings_llsd, file);
+ }
+
+ for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+ iter != settings_llsd.endMap(); ++iter)
+ {
+ mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+ }
+}
+
+void LLSpeakerVolumeStorage::save()
+{
+ // If we quit from the login screen we will not have an SL account
+ // name. Don't try to save, otherwise we'll dump a file in
+ // C:\Program Files\SecondLife\ or similar. JC
+ std::string user_dir = gDirUtilp->getLindenUserDir();
+ if (!user_dir.empty())
+ {
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME);
+ LLSD settings_llsd;
+
+ for(speaker_data_map_t::const_iterator iter = mSpeakersData.begin(); iter != mSpeakersData.end(); ++iter)
+ {
+ settings_llsd[iter->first.asString()] = iter->second;
+ }
+
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(settings_llsd, file);
+ }
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////////
LLVoiceClient::LLVoiceClient() :
@@ -4914,7 +5029,9 @@ LLVoiceClient::participantState *LLVoiceClient::sessionState::addParticipant(con
}
mParticipantsByUUID.insert(participantUUIDMap::value_type(&(result->mAvatarID), result));
-
+
+ result->mUserVolume = LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID);
+
LL_DEBUGS("Voice") << "participant \"" << result->mURI << "\" added." << LL_ENDL;
}
@@ -5853,6 +5970,11 @@ bool LLVoiceClient::voiceEnabled()
return gSavedSettings.getBOOL("EnableVoiceChat") && !gSavedSettings.getBOOL("CmdLineDisableVoice");
}
+bool LLVoiceClient::voiceWorking()
+{
+ return (stateLoggedIn <= mState) && (mState <= stateLeavingSession);
+}
+
void LLVoiceClient::setLipSyncEnabled(BOOL enabled)
{
mLipSyncEnabled = enabled;
@@ -6158,6 +6280,9 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
participant->mUserVolume = llclamp(ivol, 0, 400);
participant->mVolumeDirty = TRUE;
mAudioSession->mVolumeDirty = TRUE;
+
+ // store this volume setting for future sessions
+ LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, participant->mUserVolume);
}
}
}
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 6231c6ba29..8f668dff19 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -191,6 +191,8 @@ static void updatePosition(void);
void inputUserControlState(bool down); // interpret any sort of up-down mic-open control input according to ptt-toggle prefs
void setVoiceEnabled(bool enabled);
static bool voiceEnabled();
+ // Checks is voice working judging from mState
+ bool voiceWorking();
void setUsePTT(bool usePTT);
void setPTTIsToggle(bool PTTIsToggle);
bool getPTTIsToggle();
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 613530b7aa..d2e5473157 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -11,7 +11,7 @@
can_dock="false"
can_minimize="true"
can_close="true"
- visible="true"
+ visible="false"
width="360"
can_resize="true"
min_width="250"
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
index f473a51ff6..c4411db8c5 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -56,7 +56,7 @@
height="18"
default_icon_name="Generic_Person"
layout="topleft"
- left="0"
+ left="5"
name="user_icon"
top="0"
width="18" />
@@ -78,6 +78,7 @@
follows="top|right"
height="16"
layout="topleft"
+ right="-3"
name="speaking_indicator"
left_pad="5"
visible="true"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 960da7a274..41f4621d66 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -244,6 +244,16 @@ Save all changes to clothing/body parts?
<notification
icon="alertmodal.tga"
+ name="FriendsAndGroupsOnly"
+ type="alertmodal">
+ Non-friends won't know that you've choosen to ignore their calls and instant messages.
+ <usetemplate
+ name="okbutton"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="GrantModifyRights"
type="alertmodal">
Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission.
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index 615ade99a2..c605975c8e 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -65,28 +65,18 @@
height="15"
layout="topleft"
left_pad="5"
+ right="-72"
name="last_interaction"
text_color="LtGray_50"
value="0s"
width="24" />
- <output_monitor
- auto_update="true"
- follows="right"
- draw_border="false"
- height="16"
- layout="topleft"
- left_pad="5"
- mouse_opaque="true"
- name="speaking_indicator"
- visible="true"
- width="20" />
<button
follows="right"
height="16"
image_pressed="Info_Press"
image_unselected="Info_Over"
left_pad="3"
- right="-31"
+ right="-53"
name="info_btn"
top_delta="-2"
width="16" />
@@ -96,9 +86,21 @@
image_overlay="ForwardArrow_Off"
layout="topleft"
left_pad="5"
- right="-3"
+ right="-28"
name="profile_btn"
tool_tip="View profile"
top_delta="-2"
width="20" />
+ <output_monitor
+ auto_update="true"
+ follows="right"
+ draw_border="false"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ right="-3"
+ mouse_opaque="true"
+ name="speaking_indicator"
+ visible="true"
+ width="20" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
index 2075d7e05b..db156f7877 100644
--- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
@@ -2,7 +2,7 @@
<panel
border="false"
follows="all"
- height="380"
+ height="420"
label="Land &amp; L$"
layout="topleft"
left="0"
@@ -237,7 +237,7 @@
</text>
<tab_container
follows="all"
- height="173"
+ height="180"
halign="center"
layout="topleft"
left="0"
@@ -250,7 +250,7 @@
<panel
border="false"
follows="all"
- height="173"
+ height="180"
label="PLANNING"
layout="topleft"
left="0"
@@ -275,7 +275,7 @@
<panel
border="false"
follows="all"
- height="173"
+ height="180"
label="DETAILS"
layout="topleft"
left="0"
@@ -296,41 +296,44 @@
word_wrap="true">
Loading...
</text_editor>
+
+ <button
+ height="20"
+ image_overlay="Arrow_Left_Off"
+ layout="topleft"
+ left="5"
+ name="earlier_details_button"
+ tool_tip="Go back in time"
+ top_pad="10"
+ width="25" />
<button
- follows="left|top"
- height="18"
- image_overlay="Arrow_Left_Off"
- layout="topleft"
- name="earlier_details_button"
- tool_tip="Back"
- right="-45"
- bottom="0"
- width="25" />
- <button
- follows="left|top"
- height="18"
- image_overlay="Arrow_Right_Off"
- layout="topleft"
- left_pad="10"
- name="later_details_button"
- tool_tip="Next"
- width="25" />
- </panel>
+ height="20"
+ image_overlay="Arrow_Right_Off"
+ layout="topleft"
+ left_pad="5"
+ name="later_details_button"
+ tool_tip="Go forward in time"
+ top_delta="0"
+ width="25" />
+
+
+ </panel>
<panel
border="false"
follows="all"
- height="173"
+ height="180"
label="SALES"
layout="topleft"
left_delta="0"
help_topic="group_money_sales_tab"
+ mouse_opaque="false"
name="group_money_sales_tab"
top="0"
width="300">
<text_editor
type="string"
follows="all"
- height="140"
+ height="130"
layout="topleft"
left="0"
max_length="4096"
@@ -340,25 +343,24 @@
word_wrap="true">
Loading...
</text_editor>
- <button
- bottom="0"
- follows="left|top"
- height="18"
- image_overlay="Arrow_Left_Off"
- layout="topleft"
- name="earlier_sales_button"
- tool_tip="Back"
- right="-45"
- width="25" />
- <button
- follows="left|top"
- height="18"
- image_overlay="Arrow_Right_Off"
- layout="topleft"
- left_pad="10"
- name="later_sales_button"
- tool_tip="Next"
- width="25" />
+ <button
+ height="20"
+ image_overlay="Arrow_Left_Off"
+ layout="topleft"
+ left="5"
+ name="earlier_sales_button"
+ tool_tip="Go back in time"
+ top_pad="10"
+ width="25" />
+ <button
+ height="20"
+ image_overlay="Arrow_Right_Off"
+ layout="topleft"
+ left_pad="5"
+ name="later_sales_button"
+ tool_tip="Go forward in time"
+ top_delta="0"
+ width="25" />
</panel>
</tab_container>
</panel>