summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorGilbert Gonzales <gilbert@lindenlab.com>2012-10-11 12:18:35 -0700
committerGilbert Gonzales <gilbert@lindenlab.com>2012-10-11 12:18:35 -0700
commitb871d67710cc4168752dee976725e190c0cd9960 (patch)
treef6c56ec4da61c6bcb7331ba5d16aa133742e4eb6 /indra
parent375f380ea388b37c34ace9570822d0c117b3d2f1 (diff)
parent0ff5a0c8ceebfab0d786aaf027c7c548170afe8d (diff)
merging in latest changes
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/lllayoutstack.cpp2
-rw-r--r--indra/llui/llui.cpp12
-rwxr-xr-xindra/newview/llavataractions.cpp30
-rw-r--r--indra/newview/llavataractions.h10
-rw-r--r--indra/newview/llconversationmodel.cpp62
-rwxr-xr-xindra/newview/llconversationmodel.h3
-rwxr-xr-xindra/newview/llconversationview.cpp6
-rw-r--r--indra/newview/llimconversation.cpp23
-rw-r--r--indra/newview/llimconversation.h2
-rw-r--r--indra/newview/llimfloater.cpp30
-rw-r--r--indra/newview/llimfloatercontainer.cpp136
-rw-r--r--indra/newview/llimfloatercontainer.h3
-rw-r--r--indra/newview/llimview.cpp12
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_participant_view.xml11
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml25
16 files changed, 251 insertions, 118 deletions
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index be6d359c9a..1f2496a8e7 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -767,7 +767,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
{ // freeze new size as fraction
F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
? MAX_FRACTIONAL_SIZE
- : llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim() - 1) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+ : llclamp(total_visible_fraction * (F32)(new_dim - (panelp->getRelevantMinDim() - 1)) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
fraction_remaining -= panelp->mFractionalSize;
panelp->mFractionalSize = new_fractional_size;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 41a948e545..f43409a1ff 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1629,10 +1629,10 @@ void LLUI::initClass(const settings_map_t& settings,
LLUICtrl::CommitCallbackRegistry::Registrar& reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar();
// Callbacks for associating controls with floater visibility:
- reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD()));
- reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD()));
- reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(), FALSE));
- reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD()));
+ reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD(LLUUID())));
+ reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD(LLUUID())));
+ reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(LLUUID()), FALSE));
+ reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD(LLUUID())));
// Button initialization callback for toggle buttons
reg.add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
@@ -1647,8 +1647,8 @@ void LLUI::initClass(const settings_map_t& settings,
reg.add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
// Used by menus along with Floater.Toggle to display visibility as a check-mark
- LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD()));
- LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.IsOpen", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD()));
+ LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD(LLUUID())));
+ LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.IsOpen", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD(LLUUID())));
// Parse the master list of commands
LLCommandManager::load();
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 248685b964..3326103d03 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -697,15 +697,15 @@ namespace action_give_inventory
}
// static
-void LLAvatarActions::buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string)
+void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string)
{
llassert(avatar_names.size() > 0);
-
+
+ std::sort(avatar_names.begin(), avatar_names.end());
const std::string& separator = LLTrans::getString("words_separator");
for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
{
- LLAvatarName av_name = *it;
- residents_string.append(av_name.mDisplayName);
+ residents_string.append((*it).mDisplayName);
if (++it == avatar_names.end())
{
break;
@@ -714,6 +714,28 @@ void LLAvatarActions::buildResidentsString(const std::vector<LLAvatarName> avata
}
}
+// static
+void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string)
+{
+ std::vector<LLAvatarName> avatar_names;
+ uuid_vec_t::const_iterator it = avatar_uuids.begin();
+ for (; it != avatar_uuids.end(); ++it)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(*it, &av_name))
+ {
+ avatar_names.push_back(av_name);
+ }
+ }
+
+ // We should check whether the vector is not empty to pass the assertion
+ // that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
+ if (!avatar_names.empty())
+ {
+ LLAvatarActions::buildResidentsString(avatar_names, residents_string);
+ }
+}
+
//static
std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
{
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 6e60f624ad..6e1198cd09 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -216,7 +216,15 @@ public:
* @param avatar_names - a vector of given avatar names from which resulting string is built
* @param residents_string - the resulting string
*/
- static void buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string);
+ static void buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string);
+
+ /**
+ * Builds a string of residents' display names separated by "words_separator" string.
+ *
+ * @param avatar_uuids - a vector of given avatar uuids from which resulting string is built
+ * @param residents_string - the resulting string
+ */
+ static void buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string);
/**
* Opens the chat history for avatar
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 5fc305da81..29e7ac4e12 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -27,6 +27,10 @@
#include "llviewerprecompiledheaders.h"
+#include "llavatarnamecache.h"
+#include "llavataractions.h"
+#include "llevents.h"
+#include "llsdutil.h"
#include "llconversationmodel.h"
#include "llimview.h" //For LLIMModel
@@ -64,6 +68,14 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
{
}
+void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
+{
+ LLUUID session_id = (session ? session->getUUID() : LLUUID());
+ LLUUID participant_id = (participant ? participant->getUUID() : LLUUID());
+ LLSD event(LLSDMap("type", event_type)("session_uuid", session_id)("participant_uuid", participant_id));
+ LLEventPumps::instance().obtain("ConversationsEvents").post(event);
+}
+
// Virtual action callbacks
void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
{
@@ -130,12 +142,55 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
addChild(participant);
mIsLoaded = true;
mNeedsRefresh = true;
+ updateParticipantName(participant);
+ postEvent("add_participant", this, participant);
+}
+
+void LLConversationItemSession::updateParticipantName(LLConversationItemParticipant* participant)
+{
+ // We modify the session name only in the case of an ad-hoc session, exit otherwise (nothing to do)
+ if (getType() != CONV_SESSION_AD_HOC)
+ {
+ return;
+ }
+ // Avoid changing the default name if no participant present yet
+ if (mChildren.size() == 0)
+ {
+ return;
+ }
+ // Build a string containing the participants names and check if ready for display (we don't want "(waiting)" in there)
+ bool all_names_resolved = true;
+ uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
+ child_list_t::iterator iter = mChildren.begin();
+ while (iter != mChildren.end())
+ {
+ LLConversationItemParticipant* current_participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ temp_uuids.push_back(current_participant->getUUID());
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
+ {
+ // If the name is not in the cache yet, bail out
+ // Note: we don't bind ourselves to the LLAvatarNameCache event as we are called by
+ // onAvatarNameCache() which is itself attached to the same event.
+ all_names_resolved = false;
+ break;
+ }
+ iter++;
+ }
+ if (all_names_resolved)
+ {
+ std::string new_session_name;
+ LLAvatarActions::buildResidentsString(temp_uuids, new_session_name);
+ renameItem(new_session_name);
+ postEvent("update_session", this, NULL);
+ }
}
void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
{
removeChild(participant);
mNeedsRefresh = true;
+ postEvent("remove_participant", this, participant);
}
void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
@@ -328,10 +383,13 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
mNeedsRefresh = true;
- if (mParent)
+ LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+ if (parent_session)
{
- mParent->requestSort();
+ parent_session->requestSort();
+ parent_session->updateParticipantName(this);
}
+ postEvent("update_participant", parent_session, this);
}
void LLConversationItemParticipant::dumpDebugData()
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index bc72cd96ea..1d082852f5 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -126,6 +126,8 @@ public:
void resetRefresh() { mNeedsRefresh = false; }
bool needsRefresh() { return mNeedsRefresh; }
+ void postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant);
+
void buildParticipantMenuOptions(menuentry_vec_t& items);
protected:
@@ -147,6 +149,7 @@ public:
LLPointer<LLUIImage> getIcon() const { return NULL; }
void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; }
void addParticipant(LLConversationItemParticipant* participant);
+ void updateParticipantName(LLConversationItemParticipant* participant);
void removeParticipant(LLConversationItemParticipant* participant);
void removeParticipant(const LLUUID& participant_id);
void clearParticipants();
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 112c38d8b8..f9a3a05e59 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -183,10 +183,8 @@ void LLConversationViewSession::draw()
// draw highlight for selected items
drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
- // draw children if root folder, or any other folder that is open or animating to closed state
- bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this)
- || isOpen()
- || mCurHeight != mTargetHeight;
+ // Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap.
+ bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen();
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 2ad7f9b193..9f3c6d0f3d 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -393,7 +393,7 @@ void LLIMConversation::updateHeaderAndToolbar()
// prevent start conversation before its container
LLIMFloaterContainer::getInstance();
- bool is_torn_off = !getHost();
+ bool is_torn_off = checkIfTornOff();
if (!is_torn_off)
{
hideAllStandardButtons();
@@ -505,16 +505,12 @@ void LLIMConversation::onSlide(LLIMConversation* self)
/*virtual*/
void LLIMConversation::onOpen(const LLSD& key)
{
- LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
- bool is_hosted = !!host_floater;
- if (is_hosted)
+ if (!checkIfTornOff())
{
+ LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
// Show the messages pane when opening a floater hosted in the Conversations
host_floater->collapseMessagesPane(false);
}
-
- setTornOff(!is_hosted);
- updateHeaderAndToolbar();
}
// virtual
@@ -546,3 +542,16 @@ bool LLIMConversation::isChatMultiTab()
// Restart is required in order to change chat window type.
return true;
}
+
+bool LLIMConversation::checkIfTornOff()
+{
+ bool isTorn = !getHost();
+
+ if (isTorn != isTornOff())
+ {
+ setTornOff(isTorn);
+ updateHeaderAndToolbar();
+ }
+
+ return isTorn;
+}
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index c54081d316..0960d6db88 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -138,6 +138,8 @@ private:
*/
void reshapeChatHistory();
+ bool checkIfTornOff();
+
LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
bool mHadFocus;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index a1ed1e0b01..a8add9c6ab 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -60,10 +60,6 @@
#include "llnotificationmanager.h"
#include "llautoreplace.h"
-/// Helper function to resolve resident names from given uuids
-/// and form a string of names separated by "words_separator".
-static void build_names_string(const uuid_vec_t& uuids, std::string& names_string);
-
floater_showed_signal_t LLIMFloater::sIMFloaterShowedSignal;
LLIMFloater::LLIMFloater(const LLUUID& session_id)
@@ -476,7 +472,7 @@ void LLIMFloater::addP2PSessionParticipants(const LLSD& notification, const LLSD
void LLIMFloater::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
{
std::string names_string;
- build_names_string(uuids, names_string);
+ LLAvatarActions::buildResidentsString(uuids, names_string);
LLStringUtil::format_map_t args;
args["[NAME]"] = names_string;
@@ -581,7 +577,7 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
if (all_names_resolved)
{
std::string ui_title;
- build_names_string(temp_uuids, ui_title);
+ LLAvatarActions::buildResidentsString(temp_uuids, ui_title);
updateSessionName(ui_title, ui_title);
}
}
@@ -1332,25 +1328,3 @@ boost::signals2::connection LLIMFloater::setIMFloaterShowedCallback(const floate
{
return LLIMFloater::sIMFloaterShowedSignal.connect(cb);
}
-
-// static
-void build_names_string(const uuid_vec_t& uuids, std::string& names_string)
-{
- std::vector<LLAvatarName> avatar_names;
- uuid_vec_t::const_iterator it = uuids.begin();
- for (; it != uuids.end(); ++it)
- {
- LLAvatarName av_name;
- if (LLAvatarNameCache::get(*it, &av_name))
- {
- avatar_names.push_back(av_name);
- }
- }
-
- // We should check whether the vector is not empty to pass the assertion
- // that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
- if (!avatar_names.empty())
- {
- LLAvatarActions::buildResidentsString(avatar_names, names_string);
- }
-}
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4af170b3db..5f111b39d4 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -50,6 +50,7 @@
#include "llcallbacklist.h"
#include "llworld.h"
+#include "llsdserialize.h"
//
// LLIMFloaterContainer
//
@@ -57,6 +58,7 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
: LLMultiFloater(seed),
mExpandCollapseBtn(NULL),
mConversationsRoot(NULL),
+ mConversationsEventStream("ConversationsEvents"),
mInitialized(false)
{
mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
@@ -77,6 +79,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
LLIMFloaterContainer::~LLIMFloaterContainer()
{
+ mConversationsEventStream.stopListening("ConversationsRefresh");
+
gIdleCallbacks.deleteFunction(idle, this);
mNewMessageConnection.disconnect();
@@ -155,6 +159,9 @@ BOOL LLIMFloaterContainer::postBuild()
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ // Add listener to conversation model events
+ mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLIMFloaterContainer::onConversationModelEvent, this, _1));
+
// a scroller for folder view
LLRect scroller_view_rect = mConversationsListPanel->getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
@@ -397,62 +404,81 @@ void LLIMFloaterContainer::idle(void* user_data)
self->mConversationsRoot->update();
}
-void LLIMFloaterContainer::draw()
+bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
{
- // CHUI Notes
- // Currently, the model is not responsible for creating the view which is a good thing. This means that
- // the model could change substantially and the view could decide to echo only a portion of this model.
- // Consequently, the participant views need to be created either by the session view or by the container panel.
- // For the moment, we create them here (which makes for complicated code...) to conform to the pattern
- // implemented in llinventorypanel.cpp (see LLInventoryPanel::buildNewViews()).
- // The best however would be to have an observer on the model so that we would not pool on each draw to know
- // if the view needs refresh. The current implementation (testing for change on draw) is less
- // efficient perf wise than a listener/observer scheme. We will implement that shortly.
+ // For debug only
+ //std::ostringstream llsd_value;
+ //llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
+ //llinfos << "Merov debug : onConversationModelEvent, event = " << llsd_value.str() << llendl;
+ // end debug
- // On each session in mConversationsItems
- for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+ // Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
+ // the model could change substantially and the view could echo only a portion of this model (though currently the
+ // conversation view does echo the conversation model 1 to 1).
+ // Consequently, the participant views need to be created either by the session view or by the container panel.
+ // For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp
+ // (see LLInventoryPanel::buildNewViews()).
+
+ std::string type = event.get("type").asString();
+ LLUUID session_id = event.get("session_uuid").asUUID();
+ LLUUID participant_id = event.get("participant_uuid").asUUID();
+
+ LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
+ if (!session_view)
{
- // Get the current session descriptors
- LLConversationItem* session_model = it_session->second;
- LLUUID session_id = it_session->first;
- LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
- // If the session model has been changed, refresh the corresponding view
- if (session_model->needsRefresh())
+ // We skip events that are not associated to a session
+ return false;
+ }
+ LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+
+ if (type == "remove_participant")
+ {
+ if (participant_view)
{
+ session_view->extractItem(participant_view);
+ delete participant_view;
session_view->refresh();
+ mConversationsRoot->arrangeAll();
}
- // Iterate through each model participant child
- LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
- LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
- while (current_participant_model != end_participant_model)
+ }
+ else if (type == "add_participant")
+ {
+ if (!participant_view)
{
- LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
- LLUUID participant_id = participant_model->getUUID();
- LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
- // Is there a corresponding view? If not create it
- if (!participant_view)
- {
- participant_view = createConversationViewParticipant(participant_model);
- participant_view->addToFolder(session_view);
- participant_view->setVisible(TRUE);
- }
- else
- // Else, see if it needs refresh
+ LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+ if (session_model)
{
- if (participant_model->needsRefresh())
+ LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
+ if (participant_model)
{
- participant_view->refresh();
+ participant_view = createConversationViewParticipant(participant_model);
+ participant_view->addToFolder(session_view);
+ participant_view->setVisible(TRUE);
}
}
- // Reset the need for refresh
- session_model->resetRefresh();
- mConversationViewModel.requestSortAll();
- mConversationsRoot->arrangeAll();
- // Next participant
- current_participant_model++;
+
+ }
+ }
+ else if (type == "update_participant")
+ {
+ if (participant_view)
+ {
+ participant_view->refresh();
}
}
+ else if (type == "update_session")
+ {
+ session_view->refresh();
+ }
+
+ mConversationViewModel.requestSortAll();
+ mConversationsRoot->arrangeAll();
+ return false;
+}
+
+void LLIMFloaterContainer::draw()
+{
if (mTabContainer->getTabCount() == 0)
{
// Do not close the container when every conversation is torn off because the user
@@ -527,12 +553,25 @@ void LLIMFloaterContainer::collapseMessagesPane(bool collapse)
gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
}
+ // Save left pane rectangle before collapsing/expanding right pane.
+ LLRect prevRect = mConversationsPane->getRect();
+
// Show/hide the messages pane.
mConversationsStack->collapsePanel(mMessagesPane, collapse);
+ if (!collapse)
+ {
+ // Make sure layout is updated before resizing conversation pane.
+ mConversationsStack->updateLayout();
+ }
+
updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+ if (!collapse)
+ {
+ // Restore conversation's pane previous width after expanding messages pane.
+ mConversationsPane->setTargetDim(prevRect.getWidth());
+ }
}
-
void LLIMFloaterContainer::collapseConversationsPane(bool collapse)
{
if (mConversationsPane->isCollapsed() == collapse)
@@ -862,7 +901,13 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command,
}
else if("chat_history" == command)
{
- LLAvatarActions::viewChatHistory(conversationItem->getUUID());
+ const LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(conversationItem->getUUID());
+
+ if (NULL != session)
+ {
+ const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
+ LLFloaterReg::showInstance("preview_conversation", session_id, true);
+ }
}
else
{
@@ -1089,7 +1134,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
removeConversationListItem(uuid,false);
// Create a conversation session model
- LLConversationItem* item = NULL;
+ LLConversationItemSession* item = NULL;
LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
if (speaker_manager)
{
@@ -1101,6 +1146,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
return;
}
item->renameItem(display_name);
+ item->updateParticipantName(NULL);
mConversationsItems[uuid] = item;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 76e468f979..ceb054dfa3 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -31,6 +31,7 @@
#include <vector>
#include "llimview.h"
+#include "llevents.h"
#include "llfloater.h"
#include "llmultifloater.h"
#include "llavatarpropertiesprocessor.h"
@@ -140,6 +141,7 @@ public:
private:
LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+ bool onConversationModelEvent(const LLSD& event);
// Conversation list data
LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to
@@ -147,6 +149,7 @@ private:
conversations_widgets_map mConversationsWidgets;
LLConversationViewModel mConversationViewModel;
LLFolderView* mConversationsRoot;
+ LLEventStream mConversationsEventStream;
};
#endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b45903835a..a604c884ca 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -643,6 +643,12 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
{
session->sessionInitReplyReceived(new_session_id);
+ LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
+ if (im_floater)
+ {
+ im_floater->sessionInitReplyReceived(new_session_id);
+ }
+
if (old_session_id != new_session_id)
{
mId2SessionMap.erase(old_session_id);
@@ -651,12 +657,6 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
}
- LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
- if (im_floater)
- {
- im_floater->sessionInitReplyReceived(new_session_id);
- }
-
// auto-start the call on session initialization?
if (session->mStartCallOnInitialize)
{
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 5c74f7f9bb..8cd0463de8 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -246,7 +246,7 @@
parse_highlights="true"
parse_urls="true"
width="230"
- left="0">
+ left="5">
</chat_history>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 0043c14479..6fa0707eea 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -59,17 +59,6 @@
function="IMFloaterContainer.Check"
parameter="sort_participants_by_recent" />
</menu_item_check>
- <menu_item_check
- label="Sort participants by distance from you"
- layout="topleft"
- name="sort_participants_by_distance">
- <on_click
- function="IMFloaterContainer.Action"
- parameter="sort_participants_by_distance" />
- <on_check
- function="IMFloaterContainer.Check"
- parameter="sort_participants_by_distance" />
- </menu_item_check>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 88b30c8272..c805b6db42 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -218,8 +218,18 @@
label="Communicate"
name="Communicate"
tear_off="true">
- <menu_item_check
- label="Chat..."
+ <menu_item_check
+ label="Conversations..."
+ name="Conversations">
+ <menu_item_check.on_check
+ function="Floater.IsOpen"
+ parameter="im_container" />
+ <menu_item_check.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="im_container" />
+ </menu_item_check>
+ <menu_item_check
+ label="Nearby Chat..."
name="Nearby Chat"
shortcut="control|H"
use_mac_ctrl="true">
@@ -244,6 +254,17 @@
parameter="speak" />
</menu_item_check>
<menu_item_check
+ label="Conversations Log..."
+ name="ConversationsLog">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="conversation" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="conversation" />
+ </menu_item_check>
+ <menu_item_separator/>
+ <menu_item_check
label="Voice morphing..."
name="ShowVoice"
visibility_control="VoiceMorphingEnabled">