summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2012-06-08 10:40:32 -0700
committerMerov Linden <merov@lindenlab.com>2012-06-08 10:40:32 -0700
commitb4a53226c8b1b4a31c0f1411b110a0a32fa3599f (patch)
treef96c967713d9733f8bc5bae959a53ead40e393af
parentfa0c34afc6678c9ab1814c81e11c65e4bf3d1317 (diff)
parentf7f85dd0dda563a9fb49ed65b193a9ea98da9ba2 (diff)
Merge pull from richard/viewer-chui
-rw-r--r--indra/llcommon/llassettype.cpp1
-rw-r--r--indra/llcommon/llassettype.h3
-rw-r--r--indra/llcommon/stdenums.h3
-rw-r--r--indra/llinventory/llinventorytype.cpp3
-rw-r--r--indra/llinventory/llinventorytype.h3
-rwxr-xr-xindra/newview/llavataractions.cpp4
-rw-r--r--indra/newview/llavataractions.h4
-rw-r--r--indra/newview/llavatarlistitem.cpp58
-rw-r--r--indra/newview/llavatarlistitem.h3
-rw-r--r--indra/newview/llchicletbar.cpp8
-rw-r--r--indra/newview/llimconversation.cpp12
-rw-r--r--indra/newview/llimfloater.cpp327
-rw-r--r--indra/newview/llimfloater.h26
-rw-r--r--indra/newview/llimview.cpp15
-rw-r--r--indra/newview/llimview.h4
-rw-r--r--indra/newview/llnearbychat.cpp1
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp2
-rw-r--r--indra/newview/llstartup.cpp1
-rw-r--r--indra/newview/lltoolbarview.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.h3
-rw-r--r--indra/newview/llviewerassettype.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml7
23 files changed, 315 insertions, 179 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5e566d6c7c..5ae2df3994 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
+ addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
};
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index d538accbf7..69b01731e5 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -112,6 +112,9 @@ public:
AT_WIDGET = 40,
// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
+ AT_PERSON = 45,
+ // A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
+
AT_MESH = 49,
// Mesh data in our proprietary SLM format
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 40b3364b36..efcbe76795 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -51,7 +51,8 @@ enum EDragAndDropType
DAD_LINK = 14,
DAD_MESH = 15,
DAD_WIDGET = 16,
- DAD_COUNT = 17, // number of types in this enum
+ DAD_PERSON = 17,
+ DAD_COUNT = 18, // number of types in this enum
};
// Reasons for drags to be denied.
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 8282d79b67..8807b36117 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE));
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
+ addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
}
@@ -140,7 +141,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 42 AT_NONE
LLInventoryType::IT_NONE, // 43 AT_NONE
LLInventoryType::IT_NONE, // 44 AT_NONE
- LLInventoryType::IT_NONE, // 45 AT_NONE
+ LLInventoryType::IT_PERSON, // 45 AT_PERSON
LLInventoryType::IT_NONE, // 46 AT_NONE
LLInventoryType::IT_NONE, // 47 AT_NONE
LLInventoryType::IT_NONE, // 48 AT_NONE
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 4d1e0db040..645ebab234 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -63,7 +63,8 @@ public:
IT_GESTURE = 20,
IT_MESH = 22,
IT_WIDGET = 23,
- IT_COUNT = 24,
+ IT_PERSON = 24,
+ IT_COUNT = 25,
IT_NONE = -1
};
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index c3d560540d..c9031dd26a 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -285,7 +285,7 @@ bool LLAvatarActions::canCall()
}
// static
-void LLAvatarActions::startConference(const uuid_vec_t& ids)
+void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& floater_id)
{
// *HACK: Copy into dynamic array
LLDynamicArray<LLUUID> id_array;
@@ -294,7 +294,7 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids)
id_array.push_back(*it);
}
const std::string title = LLTrans::getString("conference-title");
- LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array);
+ LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array, false, floater_id);
if (session_id != LLUUID::null)
{
LLIMFloater::show(session_id);
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index e5dad74fc8..0a69ad86a3 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -86,9 +86,9 @@ public:
static void startAdhocCall(const uuid_vec_t& ids);
/**
- * Start conference chat with the given avatars.
+ * Start conference chat with the given avatars in a specific IM floater.
*/
- static void startConference(const uuid_vec_t& ids);
+ static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
/**
* Show avatar profile.
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 30eecfe323..e670d3ea04 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -31,6 +31,7 @@
#include "llavatarlistitem.h"
#include "llbutton.h"
+#include "llclipboard.h"
#include "llfloaterreg.h"
#include "lltextutil.h"
@@ -38,6 +39,7 @@
#include "llavatarnamecache.h"
#include "llavatariconctrl.h"
#include "lloutputmonitorctrl.h"
+#include "lltooldraganddrop.h"
bool LLAvatarListItem::sStaticInitialized = false;
S32 LLAvatarListItem::sLeftPadding = 0;
@@ -334,6 +336,62 @@ BOOL LLAvatarListItem::handleDoubleClick(S32 x, S32 y, MASK mask)
return LLPanel::handleDoubleClick(x, y, mask);
}
+BOOL LLAvatarListItem::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (LLUICtrl::handleMouseDown(x, y, mask))
+ {
+ return TRUE;
+ }
+
+ gFocusMgr.setMouseCapture(this);
+
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y);
+ LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y);
+
+ return TRUE;
+}
+
+BOOL LLAvatarListItem::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+ if (LLUICtrl::childrenHandleMouseUp(x, y, mask))
+ {
+ return TRUE;
+ }
+
+ if(hasMouseCapture())
+ {
+ gFocusMgr.setMouseCapture(NULL);
+ }
+ return TRUE;
+}
+
+BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask)
+{
+ bool handled = hasMouseCapture();
+ if(handled)
+ {
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y);
+
+ if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y))
+ {
+ // First, create the global drag and drop object
+ std::vector<EDragAndDropType> types;
+ uuid_vec_t cargo_ids;
+ types.push_back(DAD_PERSON);
+ cargo_ids.push_back(mAvatarId);
+ gClipboard.setSourceObject(mAvatarId, LLAssetType::AT_PERSON);
+ LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE;
+ LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src);
+ }
+ }
+
+ return handled;
+}
+
void LLAvatarListItem::setValue( const LLSD& value )
{
if (!value.isMap()) return;;
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index c95ac39696..28a50870d4 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -112,6 +112,9 @@ public:
void onProfileBtnClick();
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
protected:
/**
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index f1bc51fbe7..8701b602ce 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -125,10 +125,12 @@ void LLChicletBar::sessionRemoved(const LLUUID& session_id)
if(getChicletPanel())
{
// IM floater should be closed when session removed and associated chiclet closed
- LLIMFloater* iMfloater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- if (iMfloater != NULL)
+ LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+ if (im_floater != NULL && !im_floater->getStartConferenceInSameFloater())
{
- iMfloater->closeFloater();
+ // Close the IM floater only if we are not planning to close the P2P chat
+ // and start a new conference in the same floater.
+ im_floater->closeFloater();
}
getChicletPanel()->removeChiclet(session_id);
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 708913bbee..c2621938e1 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -83,8 +83,10 @@ BOOL LLIMConversation::postBuild()
mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
- mParticipantListPanel->setVisible(
- mIsNearbyChat? false : gSavedSettings.getBOOL("IMShowControlPanel"));
+
+ // Show the participants list in torn off floaters only.
+ mParticipantListPanel->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")
+ && !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
mExpandCollapseBtn->setImageOverlay(
getString(mParticipantListPanel->getVisible() ? "collapse_icon" : "expand_icon"));
mExpandCollapseBtn->setEnabled(!mIsP2PChat);
@@ -209,12 +211,10 @@ void LLIMConversation::updateHeaderAndToolbar()
}
bool is_control_panel_visible = false;
- if (!mIsP2PChat)
- {
// Control panel should be visible only in torn off floaters.
is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
- mParticipantListPanel->setVisible(is_control_panel_visible);
- }
+ mParticipantListPanel->setVisible(!mIsP2PChat && is_control_panel_visible
+ && !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
// Display collapse image (<<) if the floater is hosted
// or if it is torn off but has an open control panel.
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index c99da9e9c1..dcd19b5856 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -33,12 +33,14 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llavataractions.h"
#include "llavatarnamecache.h"
#include "llbutton.h"
#include "llchannelmanager.h"
#include "llchiclet.h"
#include "llchicletbar.h"
#include "llfloaterreg.h"
+#include "llfloateravatarpicker.h"
#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
#include "llinventoryfunctions.h"
//#include "lllayoutstack.h"
@@ -71,18 +73,12 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
mTypingTimer(),
mTypingTimeoutTimer(),
mPositioned(false),
- mSessionInitialized(false)
+ mSessionInitialized(false),
+ mStartConferenceInSameFloater(false)
{
mIsNearbyChat = false;
+ initIMSession(session_id);
- mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
-
- if (mSession)
- {
- mIsP2PChat = mSession->isP2PSessionType();
- mSessionInitialized = mSession->mSessionInitialized;
- mDialog = mSession->mType;
- }
setOverlapsScreenChannel(true);
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
@@ -112,6 +108,29 @@ void LLIMFloater::onFocusReceived()
// virtual
void LLIMFloater::onClose(bool app_quitting)
{
+ LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
+ mSessionID);
+
+ if (session == NULL)
+ {
+ llwarns << "Empty session." << llendl;
+ return;
+ }
+
+ bool is_call_with_chat = session->isGroupSessionType()
+ || session->isAdHocSessionType() || session->isP2PSessionType();
+
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+ if (is_call_with_chat && voice_channel != NULL
+ && voice_channel->isActive())
+ {
+ LLSD payload;
+ payload["session_id"] = mSessionID;
+ LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+ return;
+ }
+
setTyping(false);
// The source of much argument and design thrashing
@@ -211,8 +230,24 @@ LLIMFloater::~LLIMFloater()
LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
}
-//virtual
-BOOL LLIMFloater::postBuild()
+void LLIMFloater::initIMSession(const LLUUID& session_id)
+{
+ // Change the floater key to bind it to a new session.
+ setKey(session_id);
+
+ mSessionID = session_id;
+ mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+ if (mSession)
+ {
+ mIsP2PChat = mSession->isP2PSessionType();
+ mSessionInitialized = mSession->mSessionInitialized;
+
+ mDialog = mSession->mType;
+ }
+}
+
+void LLIMFloater::initIMFloater()
{
const LLUUID& other_party_id =
LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
@@ -223,6 +258,34 @@ BOOL LLIMFloater::postBuild()
boundVoiceChannel();
+ // Show control panel in torn off floaters only.
+ mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel"));
+
+ // Disable input editor if session cannot accept text
+ if ( mSession && !mSession->mTextIMPossible )
+ {
+ mInputEditor->setEnabled(FALSE);
+ mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
+ }
+
+ if (mIsP2PChat)
+ {
+ // look up display name for window title
+ LLAvatarNameCache::get(mSession->mOtherParticipantID,
+ boost::bind(&LLIMFloater::onAvatarNameCache,
+ this, _1, _2));
+ }
+ else
+ {
+ std::string session_name(LLIMModel::instance().getName(mSessionID));
+ updateSessionName(session_name, session_name);
+ }
+}
+
+//virtual
+BOOL LLIMFloater::postBuild()
+{
+ LLIMConversation::postBuild();
mInputEditor = getChild<LLLineEditor>("chat_editor");
mInputEditor->setMaxTextLength(1023);
@@ -248,26 +311,12 @@ BOOL LLIMFloater::postBuild()
mTypingStart = LLTrans::getString("IM_typing_start_string");
- // Disable input editor if session cannot accept text
- if ( mSession && !mSession->mTextIMPossible )
- {
- mInputEditor->setEnabled(FALSE);
- mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
- }
+ LLButton* add_btn = getChild<LLButton>("add_btn");
+
+ // Allow to add chat participants depending on the session type
+ add_btn->setEnabled(isInviteAllowed());
+ add_btn->setClickedCallback(boost::bind(&LLIMFloater::onAddButtonClicked, this));
- if (mIsP2PChat)
- {
- // look up display name for window title
- LLAvatarNameCache::get(mSession->mOtherParticipantID,
- boost::bind(&LLIMFloater::onAvatarNameCache,
- this, _1, _2));
- }
- else
- {
- std::string session_name(LLIMModel::instance().getName(mSessionID));
- updateSessionName(session_name, session_name);
- }
-
childSetAction("voice_call_btn", boost::bind(&LLIMFloater::onCallButtonClicked, this));
LLVoiceClient::getInstance()->addObserver(this);
@@ -275,7 +324,75 @@ BOOL LLIMFloater::postBuild()
//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
//see LLFloaterIMPanel for how it is done (IB)
- return LLIMConversation::postBuild();
+ initIMFloater();
+
+ return TRUE;
+}
+
+void LLIMFloater::onAddButtonClicked()
+{
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::onAvatarPicked, this, _1, _2), TRUE, TRUE);
+ if (!picker)
+ {
+ return;
+ }
+
+ // Need to disable 'ok' button when selected users are already in conversation.
+ picker->setOkBtnEnableCb(boost::bind(&LLIMFloater::canAddSelectedToChat, this, _1));
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(picker);
+ }
+}
+
+void LLIMFloater::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
+{
+ if (mIsP2PChat)
+ {
+ mStartConferenceInSameFloater = true;
+ onClose(false);
+
+ uuid_vec_t temp_ids;
+ temp_ids.push_back(mOtherParticipantUUID);
+ temp_ids.insert(temp_ids.end(), ids.begin(), ids.end());
+
+ LLAvatarActions::startConference(temp_ids, mSessionID);
+ }
+ else
+ {
+ inviteToSession(ids);
+ }
+}
+
+bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
+{
+ if (!mSession
+ || mDialog == IM_SESSION_GROUP_START
+ || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
+ {
+ return false;
+ }
+
+ for (uuid_vec_t::const_iterator id = uuids.begin();
+ id != uuids.end(); ++id)
+ {
+ if (*id == mOtherParticipantUUID)
+ {
+ return false;
+ }
+
+ for (uuid_vec_t::const_iterator target_id = mSession->mInitialTargetIDs.begin();
+ target_id != mSession->mInitialTargetIDs.end(); ++target_id)
+ {
+ if (*id == *target_id)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
void LLIMFloater::boundVoiceChannel()
@@ -603,17 +720,15 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
//will be different only for an ad-hoc im session
if (mSessionID != im_session_id)
{
- mSessionID = im_session_id;
- setKey(im_session_id);
+ initIMSession(im_session_id);
boundVoiceChannel();
- mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
- mIsP2PChat = mSession && mSession->isP2PSessionType();
-
buildParticipantList();
}
-
+
+ initIMFloater();
+
//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
//need to send delayed messaged collected while waiting for session initialization
@@ -876,96 +991,62 @@ void LLIMFloater::processSessionUpdate(const LLSD& session_update)
}
}
-BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type,
- void *cargo_data, EAcceptance *accept,
- std::string& tooltip_msg)
+// virtual
+BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
{
- if (mDialog == IM_NOTHING_SPECIAL)
- {
- LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
- cargo_type, cargo_data, accept);
- }
-
- // handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
- else if (isInviteAllowed())
+ if (cargo_type == DAD_PERSON)
{
- *accept = ACCEPT_NO;
-
- if (cargo_type == DAD_CALLINGCARD)
+ if (dropPerson(static_cast<LLInventoryObject*>(cargo_data), drop))
{
- if (dropCallingCard((LLInventoryItem*) cargo_data, drop))
- {
- *accept = ACCEPT_YES_MULTI;
- }
+ *accept = ACCEPT_YES_MULTI;
}
- else if (cargo_type == DAD_CATEGORY)
+ else
{
- if (dropCategory((LLInventoryCategory*) cargo_data, drop))
- {
- *accept = ACCEPT_YES_MULTI;
- }
+ *accept = ACCEPT_NO;
}
}
return TRUE;
}
-BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
+bool LLIMFloater::dropPerson(LLInventoryObject* item, bool drop)
{
- BOOL rv = isInviteAllowed();
- if (rv && item && item->getCreatorUUID().notNull())
- {
- if (drop)
- {
- uuid_vec_t ids;
- ids.push_back(item->getCreatorUUID());
- inviteToSession(ids);
- }
- }
- else
+ bool res = item && item->getUUID().notNull();
+ if(res)
{
- // set to false if creator uuid is null.
- rv = FALSE;
- }
- return rv;
-}
+ uuid_vec_t ids;
+ ids.push_back(item->getUUID());
-BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
-{
- BOOL rv = isInviteAllowed();
- if (rv && category)
- {
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- LLUniqueBuddyCollector buddies;
- gInventory.collectDescendentsIf(category->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- buddies);
- S32 count = items.count();
- if (count == 0)
- {
- rv = FALSE;
- }
- else if (drop)
+ res = canAddSelectedToChat(ids);
+ if(res && drop)
{
- uuid_vec_t ids;
- ids.reserve(count);
- for (S32 i = 0; i < count; ++i)
+ if (mIsP2PChat)
{
- ids.push_back(items.get(i)->getCreatorUUID());
+ mStartConferenceInSameFloater = true;
+ onClose(false);
+
+ ids.push_back(mOtherParticipantUUID);
+
+ LLAvatarActions::startConference(ids, mSessionID);
+ }
+ else
+ {
+ inviteToSession(ids);
}
- inviteToSession(ids);
}
}
- return rv;
+
+ return res;
}
BOOL LLIMFloater::isInviteAllowed() const
{
return ((IM_SESSION_CONFERENCE_START == mDialog)
- || (IM_SESSION_INVITE == mDialog));
+ || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
+ || mIsP2PChat);
}
class LLSessionInviteResponder: public LLHTTPClient::Responder
@@ -1107,14 +1188,6 @@ void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD&
}
// static
-void LLIMFloater::initIMFloater()
-{
- // This is called on viewer start up
- // init chat window type before user changed it in preferences
- isChatMultiTab();
-}
-
-//static
void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
{
LLUUID session_id = data["session_id"];
@@ -1139,7 +1212,6 @@ void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
{
LLIMFloater::addToHost(session_id);
}
-
void LLIMFloater::addToHost(const LLUUID& session_id)
{
if (LLIMConversation::isChatMultiTab())
@@ -1157,32 +1229,3 @@ void LLIMFloater::addToHost(const LLUUID& session_id)
}
}
}
-
-void LLIMFloater::onClickCloseBtn()
-{
-
- LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
- mSessionID);
-
- if (session == NULL)
- {
- llwarns << "Empty session." << llendl;
- return;
- }
-
- bool is_call_with_chat = session->isGroupSessionType()
- || session->isAdHocSessionType() || session->isP2PSessionType();
-
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
- if (is_call_with_chat && voice_channel != NULL
- && voice_channel->isActive())
- {
- LLSD payload;
- payload["session_id"] = mSessionID;
- LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
- return;
- }
-
- LLFloater::onClickCloseBtn();
-}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 24f28c8aee..b02f779637 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -56,6 +56,9 @@ public:
virtual ~LLIMFloater();
+ void initIMSession(const LLUUID& session_id);
+ void initIMFloater();
+
// LLView overrides
/*virtual*/ BOOL postBuild();
/*virtual*/ void setVisible(BOOL visible);
@@ -111,20 +114,18 @@ public:
void processAgentListUpdates(const LLSD& body);
void processSessionUpdate(const LLSD& session_update);
- BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type,
- void *cargo_data, EAcceptance *accept,
- std::string& tooltip_msg);
-
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
- static void initIMFloater();
//used as a callback on receiving new IM message
static void sRemoveTypingIndicator(const LLSD& data);
static void onIMChicletCreated(const LLUUID& session_id);
-protected:
- /* virtual */ void onClickCloseBtn();
+ bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
private:
// process focus events to set a currently active session
@@ -137,8 +138,7 @@ private:
// For display name lookups for IM window titles
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
- BOOL dropCallingCard(LLInventoryItem* item, BOOL drop);
- BOOL dropCategory(LLInventoryCategory* category, BOOL drop);
+ bool dropPerson(LLInventoryObject* item, bool drop);
BOOL isInviteAllowed() const;
BOOL inviteToSession(const uuid_vec_t& agent_ids);
@@ -147,6 +147,10 @@ private:
static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
void setTyping(bool typing);
+ void onAddButtonClicked();
+ void onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
+ bool canAddSelectedToChat(const uuid_vec_t& uuids);
+
void onCallButtonClicked();
// set the enable/disable state for the Call button
@@ -186,6 +190,8 @@ private:
bool mSessionInitialized;
LLSD mQueuedMsgsForInit;
+ bool mStartConferenceInSameFloater;
+
// connection to voice channel state change signal
boost::signals2::connection mVoiceChannelStateChangeConnection;
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 46b1cb5f18..0d2b1f06b5 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2591,7 +2591,8 @@ LLUUID LLIMMgr::addSession(
const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids, bool voice)
+ const LLDynamicArray<LLUUID>& ids, bool voice,
+ const LLUUID& floater_id)
{
if (0 == ids.getLength())
{
@@ -2606,6 +2607,18 @@ LLUUID LLIMMgr::addSession(
LLUUID session_id = computeSessionID(dialog,other_participant_id);
+ if (floater_id.notNull())
+ {
+ LLIMFloater* im_floater = LLIMFloater::findInstance(floater_id);
+ if (im_floater && im_floater->getStartConferenceInSameFloater())
+ {
+ // The IM floater should be initialized with a new session_id
+ // so that it is found by that id when creating a chiclet in LLIMFloater::onIMChicletCreated,
+ // and a new floater is not created.
+ im_floater->initIMSession(session_id);
+ }
+ }
+
bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);
//works only for outgoing ad-hoc sessions
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 9d19af4b62..58a2ac5162 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -347,10 +347,12 @@ public:
// Adds a session using a specific group of starting agents
// the dialog type is assumed correct. Returns the uuid of the session.
+ // A session can be added to a floater specified by floater_id.
LLUUID addSession(const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids, bool voice = false);
+ const LLDynamicArray<LLUUID>& ids, bool voice = false,
+ const LLUUID& floater_id = LLUUID::null);
/**
* Creates a P2P session with the requisite handle for responding to voice calls.
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 8b54c6ce53..e35dbf21d4 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -130,6 +130,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
mSpeakerMgr(NULL),
mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
{
+ mIsNearbyChat = true;
mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
}
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index c84790d839..ac2109dda4 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -81,7 +81,7 @@ LLContextMenu* NearbyMenu::createMenu()
// Set up for multi-selected People
// registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs)); // *TODO: unimplemented
- registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs));
+ registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs, LLUUID::null));
registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs));
registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this));
registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog, mUUIDs));
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 2f13ba5ab1..320a602916 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2153,7 +2153,6 @@ bool idle_startup()
LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
- LLIMFloater::initIMFloater();
display_startup();
return TRUE;
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 81ad96f39e..2b5acdc1e8 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -603,7 +603,7 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
{
BOOL handled = FALSE;
- LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+ LLInventoryObject* inv_item = static_cast<LLInventoryObject*>(cargo_data);
LLAssetType::EType type = inv_item->getType();
if (type == LLAssetType::AT_WIDGET)
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 4f4eef0f3d..296ded6831 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -2527,7 +2527,7 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
item = (LLViewerInventoryItem*)preview->getDragItem();
}
}
- else if(mSource == SOURCE_VIEWER)
+ else if(mSource == SOURCE_VIEWER || mSource == SOURCE_PEOPLE)
{
item = (LLViewerInventoryItem*)gToolBarView->getDragItem();
}
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 245c2a23e6..44980ffdb3 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -67,7 +67,8 @@ public:
SOURCE_WORLD,
SOURCE_NOTECARD,
SOURCE_LIBRARY,
- SOURCE_VIEWER
+ SOURCE_VIEWER,
+ SOURCE_PEOPLE
};
void beginDrag(EDragAndDropType type,
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index a4b1c2155f..08ba5a5f25 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -83,6 +83,8 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
addEntry(LLViewerAssetType::AT_WIDGET, new ViewerAssetEntry(DAD_WIDGET));
+ addEntry(LLViewerAssetType::AT_PERSON, new ViewerAssetEntry(DAD_PERSON));
+
addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE));
};
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 beeb4eea9b..21fc2d25d4 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -59,6 +59,7 @@
top="5"
width="31" />
<button
+ enabled="false"
follows="top|left"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
@@ -69,8 +70,7 @@
top="5"
left_pad="4"
name="add_btn"
- width="31">
- </button>
+ width="31"/>
<button
follows="top|left"
height="25"
@@ -82,8 +82,7 @@
top="5"
left_pad="4"
name="voice_call_btn"
- width="31">
- </button>
+ width="31"/>
<button
follows="right|top"
height="25"