summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorGilbert Gonzales <gilbert@lindenlab.com>2012-09-04 13:35:38 -0700
committerGilbert Gonzales <gilbert@lindenlab.com>2012-09-04 13:35:38 -0700
commit5c14f6e783c2581d0e4401d82581e7a5def99043 (patch)
tree579fe240496416f3c09ed7b9e29d1e06b0b2a570 /indra/newview
parent5fbb161ba0a28e64474efc295b12bccffdcdb0e0 (diff)
parent7bad109c3d7e6d70649839634586a09033cfb207 (diff)
merging in latest changes
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llappviewer.cpp5
-rw-r--r--indra/newview/llconversationlog.cpp81
-rw-r--r--indra/newview/llconversationlog.h27
-rw-r--r--indra/newview/llconversationloglist.cpp39
-rw-r--r--indra/newview/llconversationloglist.h1
-rw-r--r--indra/newview/llconversationloglistitem.h4
-rw-r--r--indra/newview/llconversationmodel.h4
-rw-r--r--indra/newview/llfloaterconversationlog.cpp5
-rw-r--r--indra/newview/llfloaterconversationpreview.cpp40
-rw-r--r--indra/newview/llfloaterconversationpreview.h2
-rw-r--r--indra/newview/llimfloatercontainer.cpp128
-rw-r--r--indra/newview/llimfloatercontainer.h6
-rw-r--r--indra/newview/llparticipantlist.cpp13
-rw-r--r--indra/newview/llvoicechannel.cpp2
-rw-r--r--indra/newview/llvoicechannel.h2
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml28
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation_log_view.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_participant_view.xml7
-rw-r--r--indra/newview/skins/default/xui/en/panel_blocked_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml3
20 files changed, 338 insertions, 68 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 08a1a237f5..4dacde4792 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1834,7 +1834,10 @@ bool LLAppViewer::cleanup()
LLMuteList::getInstance()->cache(gAgent.getID());
//save call log list
- LLConversationLog::instance().cache();
+ if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+ {
+ LLConversationLog::instance().cache();
+ }
if (mPurgeOnExit)
{
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 486cea4064..7db6a93709 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -33,7 +33,8 @@ struct Conversation_params
{
Conversation_params(time_t time)
: mTime(time),
- mTimestamp(LLConversation::createTimestamp(time))
+ mTimestamp(LLConversation::createTimestamp(time)),
+ mIsConversationPast(true)
{}
time_t mTime;
@@ -44,6 +45,7 @@ struct Conversation_params
LLUUID mSessionID;
LLUUID mParticipantID;
bool mIsVoice;
+ bool mIsConversationPast;
bool mHasOfflineIMs;
};
@@ -60,6 +62,7 @@ LLConversation::LLConversation(const Conversation_params& params)
mSessionID(params.mSessionID),
mParticipantID(params.mParticipantID),
mIsVoice(params.mIsVoice),
+ mIsConversationPast(params.mIsConversationPast),
mHasOfflineIMs(params.mHasOfflineIMs)
{
setListenIMFloaterOpened();
@@ -74,6 +77,7 @@ LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
mSessionID(session.mSessionID),
mParticipantID(session.mOtherParticipantID),
mIsVoice(session.mStartedAsIMCall),
+ mIsConversationPast(false),
mHasOfflineIMs(session.mHasOfflineMessage)
{
setListenIMFloaterOpened();
@@ -89,6 +93,7 @@ LLConversation::LLConversation(const LLConversation& conversation)
mSessionID = conversation.getSessionID();
mParticipantID = conversation.getParticipantID();
mIsVoice = conversation.isVoice();
+ mIsConversationPast = conversation.isConversationPast();
mHasOfflineIMs = conversation.hasOfflineMessages();
setListenIMFloaterOpened();
@@ -99,6 +104,14 @@ LLConversation::~LLConversation()
mIMFloaterShowedConnection.disconnect();
}
+void LLConversation::setIsVoice(bool is_voice)
+{
+ if (mIsConversationPast)
+ return;
+
+ mIsVoice = is_voice;
+}
+
void LLConversation::onIMFloaterShown(const LLUUID& session_id)
{
if (mSessionID == session_id)
@@ -172,11 +185,34 @@ LLConversationLog::LLConversationLog()
{
loadFromFile(getFileName());
- LLIMMgr::instance().addSessionObserver(this);
-
+ LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
+ if (ctrl)
+ {
+ ctrl->getSignal()->connect(boost::bind(&LLConversationLog::observeIMSession, this));
+
+ if (ctrl->getValue().asBoolean())
+ {
+ LLIMMgr::instance().addSessionObserver(this);
+ }
+ }
+
mFriendObserver = new LLConversationLogFriendObserver;
LLAvatarTracker::instance().addObserver(mFriendObserver);
+
}
+
+void LLConversationLog::observeIMSession()
+{
+ if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+ {
+ LLIMMgr::instance().addSessionObserver(this);
+ }
+ else
+ {
+ LLIMMgr::instance().removeSessionObserver(this);
+ }
+}
+
void LLConversationLog::logConversation(const LLConversation& conversation)
{
mConversations.push_back(conversation);
@@ -228,6 +264,21 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
{
LLConversation conversation(*session);
LLConversationLog::instance().logConversation(conversation);
+ session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2));
+ }
+}
+
+void LLConversationLog::sessionRemoved(const LLUUID& session_id)
+{
+ conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin();
+
+ for (; rev_iter != mConversations.rend(); ++rev_iter)
+ {
+ if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast())
+ {
+ rev_iter->setIsPast(true);
+ return; // return here because only one session with session_id may be active
+ }
}
}
@@ -350,3 +401,27 @@ void LLConversationLog::notifyObservers()
(*iter)->changed();
}
}
+
+void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask)
+{
+ std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
+ for (; iter != mObservers.end(); ++iter)
+ {
+ (*iter)->changed(session_id, mask);
+ }
+}
+
+void LLConversationLog::onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state)
+{
+ conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin();
+
+ for (; rev_iter != mConversations.rend(); ++rev_iter)
+ {
+ if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast() && LLVoiceChannel::STATE_CALL_STARTED == state)
+ {
+ rev_iter->setIsVoice(true);
+ notifyPrticularConversationObservers(session_id, LLConversationLogObserver::VOICE_STATE);
+ return; // return here because only one session with session_id may be active
+ }
+ }
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index a7457d55e3..9fd54c61c9 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -57,8 +57,12 @@ public:
const std::string& getTimestamp() const { return mTimestamp; }
const time_t& getTime() const { return mTime; }
bool isVoice() const { return mIsVoice; }
+ bool isConversationPast() const { return mIsConversationPast; }
bool hasOfflineMessages() const { return mHasOfflineIMs; }
+ void setIsVoice(bool is_voice);
+ void setIsPast (bool is_past) { mIsConversationPast = is_past; }
+
/*
* Resets flag of unread offline message to false when im floater with this conversation is opened.
*/
@@ -87,6 +91,7 @@ private:
LLUUID mParticipantID;
bool mIsVoice;
bool mHasOfflineIMs;
+ bool mIsConversationPast; // once session is finished conversation became past forever
std::string mTimestamp; // conversation start time in form of: mm/dd/yyyy hh:mm
};
@@ -122,12 +127,14 @@ public:
// LLIMSessionObserver triggers
virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
- virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){} // Stub
- virtual void sessionRemoved(const LLUUID& session_id){} // Stub
- virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){} // Stub
+ virtual void sessionRemoved(const LLUUID& session_id);
+ virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){}; // Stub
+ virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){}; // Stub
- // Triggered by LLFriendObserver change
void notifyObservers();
+ void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask);
+
+ void onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state);
/**
* public method which is called on viewer exit to save conversation log
@@ -138,10 +145,11 @@ private:
LLConversationLog();
+ void observeIMSession();
+
/**
* constructs file name in which conversations log will be saved
- * file name template: agentID.call_log.
- * For example: a086icaa-782d-88d0-ae29-987a55c99sss.call_log
+ * file name is conversation.log
*/
std::string getFileName();
@@ -158,8 +166,15 @@ private:
class LLConversationLogObserver
{
public:
+
+ enum EConversationChange
+ {
+ VOICE_STATE = 1
+ };
+
virtual ~LLConversationLogObserver(){}
virtual void changed() = 0;
+ virtual void changed(const LLUUID& session_id, U32 mask){};
};
#endif /* LLCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 257ec082a5..d39e090c22 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -141,6 +141,28 @@ void LLConversationLogList::changed()
refresh();
}
+void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
+{
+ if (mask & LLConversationLogObserver::VOICE_STATE)
+ {
+ std::vector<LLPanel*> panels;
+ LLFlatListViewEx::getItems(panels);
+
+ std::vector<LLPanel*>::iterator iter = panels.begin();
+
+ for (; iter != panels.end(); ++iter)
+ {
+ LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter);
+
+ if (item && session_id == item->getConversation()->getSessionID() && !item->getConversation()->isConversationPast())
+ {
+ item->initIcons();
+ return;
+ }
+ }
+ }
+}
+
void LLConversationLogList::addNewItem(const LLConversation* conversation)
{
LLConversationLogListItem* item = new LLConversationLogListItem(&*conversation);
@@ -241,15 +263,18 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
{
LLAvatarActions::offerTeleport(selected_id);
}
- else if("add_rem_friend" == command_name)
+ else if("add_friend" == command_name)
{
- if (LLAvatarActions::isFriend(selected_id))
+ if (!LLAvatarActions::isFriend(selected_id))
{
- LLAvatarActions::removeFriendDialog(selected_id);
+ LLAvatarActions::requestFriendshipDialog(selected_id);
}
- else
+ }
+ else if("remove_friend" == command_name)
+ {
+ if (LLAvatarActions::isFriend(selected_id))
{
- LLAvatarActions::requestFriendshipDialog(selected_id);
+ LLAvatarActions::removeFriendDialog(selected_id);
}
}
else if ("invite_to_group" == command_name)
@@ -336,6 +361,10 @@ bool LLConversationLogList::isActionChecked(const LLSD& userdata)
{
return is_p2p && LLAvatarActions::isFriend(selected_id);
}
+ else if ("is_not_friend" == command_name)
+ {
+ return is_p2p && !LLAvatarActions::isFriend(selected_id);
+ }
return false;
}
diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h
index dff34a74c6..5e7fc0a9fb 100644
--- a/indra/newview/llconversationloglist.h
+++ b/indra/newview/llconversationloglist.h
@@ -68,6 +68,7 @@ public:
* Changes from LLConversationLogObserver
*/
virtual void changed();
+ virtual void changed(const LLUUID& session_id, U32 mask);
private:
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
index 8943e11604..2aaafa0fba 100644
--- a/indra/newview/llconversationloglistitem.h
+++ b/indra/newview/llconversationloglistitem.h
@@ -64,10 +64,10 @@ public:
void onDoubleClick();
-private:
-
void initIcons();
+private:
+
const LLConversation* mConversation;
LLTextBox* mConversationName;
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index af3756c45d..1a2e09dfab 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -59,8 +59,8 @@ public:
virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
- virtual BOOL isItemRenameable() const { return FALSE; }
- virtual BOOL renameItem(const std::string& new_name) { return FALSE; }
+ virtual BOOL isItemRenameable() const { return TRUE; }
+ virtual BOOL renameItem(const std::string& new_name) { mName = new_name; return TRUE; }
virtual BOOL isItemMovable( void ) const { return FALSE; }
virtual BOOL isItemRemovable( void ) const { return FALSE; }
virtual BOOL isItemInTrash( void) const { return FALSE; }
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index c77a9e74bb..4375ce5726 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -28,6 +28,7 @@
#include "llconversationloglist.h"
#include "llfiltereditor.h"
#include "llfloaterconversationlog.h"
+#include "llfloaterreg.h"
#include "llmenubutton.h"
LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key)
@@ -97,6 +98,10 @@ void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
{
mConversationLogList->toggleSortFriendsOnTop();
}
+ else if ("view_nearby_chat_history" == command_name)
+ {
+ LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
+ }
}
bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata)
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index ae6f1441eb..7083fb987d 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -29,6 +29,7 @@
#include "llfloaterconversationpreview.h"
#include "llimview.h"
#include "lllineeditor.h"
+#include "lltrans.h"
LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
: LLFloater(session_id),
@@ -44,20 +45,28 @@ BOOL LLFloaterConversationPreview::postBuild()
getChild<LLUICtrl>("more_history")->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this));
const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
- if (conv)
- {
- std::string name = conv->getConversationName();
- LLStringUtil::format_map_t args;
- args["[NAME]"] = name;
- std::string title = getString("Title", args);
- setTitle(title);
+ std::string name;
+ std::string file;
- getChild<LLLineEditor>("description")->setValue(name);
+ if (mSessionID != LLUUID::null && conv)
+ {
+ name = conv->getConversationName();
+ file = conv->getHistoryFileName();
+ }
+ else
+ {
+ name = LLTrans::getString("NearbyChatTitle");
+ file = "chat";
}
- std::string file = conv->getHistoryFileName();
- LLLogChat::loadChatHistory(file, mMessages, true);
+ LLStringUtil::format_map_t args;
+ args["[NAME]"] = name;
+ std::string title = getString("Title", args);
+ setTitle(title);
+
+ getChild<LLLineEditor>("description")->setValue(name);
+ LLLogChat::loadChatHistory(file, mMessages, true);
mCurrentPage = mMessages.size() / mPageSize;
return LLFloater::postBuild();
@@ -68,7 +77,7 @@ void LLFloaterConversationPreview::draw()
LLFloater::draw();
}
-void LLFloaterConversationPreview::onOpen(const LLSD& session_id)
+void LLFloaterConversationPreview::onOpen(const LLSD& key)
{
showHistory();
}
@@ -88,13 +97,8 @@ void LLFloaterConversationPreview::showHistory()
int delta = 0;
if (mCurrentPage)
{
- // stinson 08/28/2012 : This operation could be simplified using integer math with the mod (%) operator.
- // e.g. The following code should give the same output.
- // int remainder = mMessages.size() % mPageSize;
- // delta = (remainder == 0) ? 0 : (mPageSize - remainder);
- // Though without examining further, the remainder might be a more appropriate value.
- double num_of_pages = static_cast<double>(mMessages.size()) / static_cast<double>(mPageSize);
- delta = static_cast<int>((ceil(num_of_pages) - num_of_pages) * static_cast<double>(mPageSize));
+ int remainder = mMessages.size() % mPageSize;
+ delta = (remainder == 0) ? 0 : (mPageSize - remainder);
}
std::advance(iter, (mCurrentPage * mPageSize) - delta);
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index 5105ef3702..2246a44761 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -39,7 +39,7 @@ public:
virtual BOOL postBuild();
virtual void draw();
- virtual void onOpen(const LLSD& session_id);
+ virtual void onOpen(const LLSD& key);
private:
void onMoreHistoryBtnClick();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index d382b61921..5261d30cd9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -40,6 +40,7 @@
#include "llavatarnamecache.h"
#include "llgroupiconctrl.h"
#include "llfloateravatarpicker.h"
+#include "llfloaterpreference.h"
#include "llimview.h"
#include "lltransientfloatermgr.h"
#include "llviewercontrol.h"
@@ -53,6 +54,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
mExpandCollapseBtn(NULL),
mConversationsRoot(NULL)
{
+ mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction, this, _2));
+
// Firstly add our self to IMSession observers, so we catch session events
LLIMMgr::getInstance()->addSessionObserver(this);
@@ -437,6 +440,25 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
}
}
+void LLIMFloaterContainer::onCustomAction(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ if ("chat_preferences" == command)
+ {
+ LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+ if (floater_prefs)
+ {
+ LLTabContainer* tab_container = floater_prefs->getChild<LLTabContainer>("pref core");
+ LLPanel* chat_panel = tab_container->getPanelByName("chat");
+ if (tab_container && chat_panel)
+ {
+ tab_container->selectTabPanel(chat_panel);
+ }
+ }
+ }
+}
+
void LLIMFloaterContainer::repositioningWidgets()
{
LLRect panel_rect = mConversationsListPanel->getRect();
@@ -444,21 +466,45 @@ void LLIMFloaterContainer::repositioningWidgets()
int index = 0;
for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
widget_it != mConversationsWidgets.end();
- widget_it++, ++index)
+ widget_it++)
{
- LLFolderViewItem* widget = widget_it->second;
+ LLFolderViewFolder* widget = dynamic_cast<LLFolderViewFolder*>(widget_it->second);
widget->setVisible(TRUE);
widget->setRect(LLRect(0,
panel_rect.getHeight() - item_height*index,
panel_rect.getWidth(),
panel_rect.getHeight() - item_height*(index+1)));
+ index++;
+ // Reposition the children as well
+ // Merov : This is highly suspiscious but gets the debug hack to work. This needs to be revised though.
+ if (widget->getItemsCount() != 0)
+ {
+ BOOL is_open = widget->isOpen();
+ widget->setOpen(TRUE);
+ LLFolderViewFolder::items_t::const_iterator current = widget->getItemsBegin();
+ LLFolderViewFolder::items_t::const_iterator end = widget->getItemsEnd();
+ while (current != end)
+ {
+ LLFolderViewItem* item = (*current);
+ item->setVisible(TRUE);
+ item->setRect(LLRect(0,
+ panel_rect.getHeight() - item_height*index,
+ panel_rect.getWidth(),
+ panel_rect.getHeight() - item_height*(index+1)));
+ index++;
+ current++;
+ }
+ widget->setOpen(is_open);
+ }
}
}
// CHUI-137 : Temporary implementation of conversations list
void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
{
- std::string display_name = uuid.isNull()? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid);
+ bool is_nearby_chat = uuid.isNull();
+
+ std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid);
// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
// Note: this happens often, when reattaching a torn off conversation for instance
@@ -472,24 +518,69 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
// and nothing wrong will happen removing it if it doesn't exist
removeConversationListItem(uuid,false);
- // Create a conversation item
- LLConversationItem* item = new LLConversationItemSession(display_name, uuid, getRootViewModel());
+ // Create a conversation session model
+ LLConversationItem* item = NULL;
+ LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
+ if (speaker_manager)
+ {
+ item = new LLParticipantList(speaker_manager, NULL, getRootViewModel(), true, false);
+ }
+ if (!item)
+ {
+ llinfos << "Merov debug : Couldn't create conversation session item : " << display_name << llendl;
+ return;
+ }
+ // *TODO: Should we flag LLConversationItemSession with a mIsNearbyChat?
+ item->renameItem(display_name);
+
mConversationsItems[uuid] = item;
// Create a widget from it
- LLFolderViewItem* widget = createConversationItemWidget(item);
+ LLConversationViewSession* widget = createConversationItemWidget(item);
mConversationsWidgets[uuid] = widget;
- // Add a new conversation widget to the root folder of a folder view.
+ // Add a new conversation widget to the root folder of the folder view
widget->addToFolder(mConversationsRoot);
// Add it to the UI
+ mConversationsListPanel->addChild(widget);
widget->setVisible(TRUE);
+
+ // Create the participants widgets now
+ // Note: usually, we do not get an updated avatar list at that point
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+ llinfos << "Merov debug : create participant, children size = " << item->getChildrenCount() << llendl;
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+ participant_view->addToFolder(widget);
+ mConversationsListPanel->addChild(participant_view);
+ participant_view->setVisible(TRUE);
+ current_participant_model++;
+ }
+ // Debugging hack : uncomment to force the creation of a dummy participant
+ // This hack is to be eventually deleted
+ if (item->getChildrenCount() == 0)
+ {
+ llinfos << "Merov debug : create dummy participant" << llendl;
+ // Create a dummy participant : we let that leak but that's just for debugging...
+ std::string name("Debug Test : ");
+ name += display_name;
+ LLUUID test_id;
+ test_id.generate(name);
+ LLConversationItemParticipant* participant_model = new LLConversationItemParticipant(name, test_id, getRootViewModel());
+ // Create the dummy widget
+ LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+ participant_view->addToFolder(widget);
+ mConversationsListPanel->addChild(participant_view);
+ participant_view->setVisible(TRUE);
+ }
+ // End debugging hack
repositioningWidgets();
- mConversationsListPanel->addChild(widget);
-
return;
}
@@ -524,7 +615,7 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
}
}
-LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
+LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
{
LLConversationViewSession::Params params;
@@ -541,4 +632,21 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
return LLUICtrlFactory::create<LLConversationViewSession>(params);
}
+LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParticipant(LLConversationItem* item)
+{
+ LLConversationViewSession::Params params;
+
+ params.name = item->getDisplayName();
+ //params.icon = bridge->getIcon();
+ //params.icon_open = bridge->getOpenIcon();
+ //params.creation_date = bridge->getCreationDate();
+ params.root = mConversationsRoot;
+ params.listener = item;
+ params.rect = LLRect (0, 0, 0, 0);
+ params.tool_tip = params.name;
+ params.container = this;
+
+ return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
// EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index d6dda8ea2d..a72a3e2221 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -37,6 +37,7 @@
#include "llgroupmgr.h"
#include "lltrans.h"
#include "llconversationmodel.h"
+#include "llconversationview.h"
class LLButton;
class LLLayoutPanel;
@@ -102,6 +103,8 @@ private:
void onAddButtonClicked();
void onAvatarPicked(const uuid_vec_t& ids);
+ void onCustomAction (const LLSD& userdata);
+
LLButton* mExpandCollapseBtn;
LLLayoutPanel* mMessagesPane;
LLLayoutPanel* mConversationsPane;
@@ -113,7 +116,8 @@ public:
void addConversationListItem(const LLUUID& uuid);
private:
- LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
+ LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
+ LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
// Conversation list data
LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 35c1a34a26..fa3432fc89 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -648,10 +648,10 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
if (is_avatar)
{
- // Create a participant view model instance and add it to the linked list
+ // Create a participant view model instance
LLAvatarName avatar_name;
bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
- participant = new LLConversationItemParticipant(!has_name ? "Avatar" : avatar_name.mDisplayName , avatar_id, mRootViewModel);
+ participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel);
if (mAvatarList)
{
mAvatarList->getIDs().push_back(avatar_id);
@@ -661,7 +661,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
else
{
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
- // Create a participant view model instance and add it to the linked list
+ // Create a participant view model instance
participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
if (mAvatarList)
{
@@ -672,6 +672,13 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
// *TODO : Merov : need to declare and bind a name update callback on that "participant" instance. See LLAvatarListItem::updateAvatarName() for pattern.
// For the moment, we'll get the correct name only if it's already in the name cache (see call to LLAvatarNameCache::get() here above)
+
+ // *TODO : Merov : need to update the online/offline status of the participant.
+ // Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
+
+ llinfos << "Merov debug : added participant, name = " << participant->getName() << llendl;
+
+ // Add the participant model to the session's children list
addParticipant(participant);
adjustParticipant(avatar_id);
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index bd12328a6b..ceff75a0cc 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -414,7 +414,7 @@ void LLVoiceChannel::doSetState(const EState& new_state)
mState = new_state;
if (!mStateChangedCallback.empty())
- mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent);
+ mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent, mSessionID);
}
//static
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index b8597ee5cb..fed44974fd 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -52,7 +52,7 @@ public:
OUTGOING_CALL
} EDirection;
- typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent)> state_changed_signal_t;
+ typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent, const LLUUID& session_id)> state_changed_signal_t;
// on current channel changed signal
typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t;
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
index b8d0eef956..8796b87955 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
@@ -57,20 +57,28 @@
parameter="can_offer_teleport"/>
</menu_item_call>
<menu_item_separator />
- <menu_item_check
- label="Add friend/Remove friend"
+ <menu_item_call
+ label="Add Friend"
layout="topleft"
- name="Friend_add_remove">
- <menu_item_check.on_click
+ name="add_friend">
+ <on_click
function="Calllog.Action"
- parameter="add_rem_friend" />
- <menu_item_check.on_check
+ parameter="add_friend"/>
+ <on_visible
+ function="Calllog.Check"
+ parameter="is_not_friend" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend"
+ layout="topleft"
+ name="remove_friend">
+ <on_click
+ function="Calllog.Action"
+ parameter="remove_friend"/>
+ <on_visible
function="Calllog.Check"
parameter="is_friend" />
- <menu_item_check.on_enable
- function="Calllog.Enable"
- parameter="add_rem_friend" />
- </menu_item_check>
+ </menu_item_call>
<menu_item_call
label="Invite to group..."
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
index 4ab8cb4f7d..ce65b23971 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
@@ -34,4 +34,12 @@
function="CallLog.Check"
parameter="sort_friends_on_top" />
</menu_item_check>
+ <menu_item_separator />
+ <menu_item_call
+ label="View Nearby chat history..."
+ name="view_nearby_chat_history">
+ <on_click
+ function="CallLog.Action"
+ parameter="view_nearby_chat_history" />
+ </menu_item_call>
</toggleable_menu>
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 6401b0e3b7..df2700c94c 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -2,6 +2,13 @@
<toggleable_menu
layout="topleft"
name="participant_manu_view">
+ <menu_item_call
+ label="Chat preferences..."
+ name="chat_preferences">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="chat_preferences" />
+ </menu_item_call>
<menu_item_check
label="Open conversation log"
name="Conversation"
diff --git a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
index 84e7e467b1..752321b949 100644
--- a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
@@ -60,7 +60,6 @@
<text
follows="left|right"
font="SansSerifSmall"
- font.color="DkGray"
height="15"
layout="topleft"
left_pad="5"
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
index cee7d8581a..8a58eb1ca6 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
@@ -28,7 +28,6 @@
visible="false"
width="380" />
<icon
- default_icon_name="voice_session_icon"
follows="top|left"
height="20"
layout="topleft"
@@ -72,7 +71,6 @@
<text
follows="left|right"
font="SansSerifSmall"
- font.color="DkGray"
height="15"
layout="topleft"
left_pad="5"
@@ -84,7 +82,6 @@
<text
follows="right"
font="SansSerifSmall"
- font.color="DkGray"
height="15"
layout="topleft"
left_pad="5"