aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llimpanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llimpanel.cpp')
-rw-r--r--linden/indra/newview/llimpanel.cpp218
1 files changed, 113 insertions, 105 deletions
diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp
index 25d0b63..a5950ce 100644
--- a/linden/indra/newview/llimpanel.cpp
+++ b/linden/indra/newview/llimpanel.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -307,13 +308,13 @@ void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
307 if ( 403 == status ) 308 if ( 403 == status )
308 { 309 {
309 //403 == no ability 310 //403 == no ability
310 LLNotifyBox::showXml( 311 LLNotifications::instance().add(
311 "VoiceNotAllowed", 312 "VoiceNotAllowed",
312 channelp->getNotifyArgs()); 313 channelp->getNotifyArgs());
313 } 314 }
314 else 315 else
315 { 316 {
316 LLNotifyBox::showXml( 317 LLNotifications::instance().add(
317 "VoiceCallGenericError", 318 "VoiceCallGenericError",
318 channelp->getNotifyArgs()); 319 channelp->getNotifyArgs());
319 } 320 }
@@ -349,7 +350,7 @@ LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const std::string& sess
349 mSessionName(session_name), 350 mSessionName(session_name),
350 mIgnoreNextSessionLeave(FALSE) 351 mIgnoreNextSessionLeave(FALSE)
351{ 352{
352 mNotifyArgs["[VOICE_CHANNEL_NAME]"] = mSessionName; 353 mNotifyArgs["VOICE_CHANNEL_NAME"] = mSessionName;
353 354
354 if (!sVoiceChannelMap.insert(std::make_pair(session_id, this)).second) 355 if (!sVoiceChannelMap.insert(std::make_pair(session_id, this)).second)
355 { 356 {
@@ -385,13 +386,13 @@ void LLVoiceChannel::setChannelInfo(
385 { 386 {
386 if (mURI.empty()) 387 if (mURI.empty())
387 { 388 {
388 LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs); 389 LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs);
389 llwarns << "Received empty URI for channel " << mSessionName << llendl; 390 llwarns << "Received empty URI for channel " << mSessionName << llendl;
390 deactivate(); 391 deactivate();
391 } 392 }
392 else if (mCredentials.empty()) 393 else if (mCredentials.empty())
393 { 394 {
394 LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs); 395 LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs);
395 llwarns << "Received empty credentials for channel " << mSessionName << llendl; 396 llwarns << "Received empty credentials for channel " << mSessionName << llendl;
396 deactivate(); 397 deactivate();
397 } 398 }
@@ -434,25 +435,26 @@ void LLVoiceChannel::handleStatusChange(EStatusType type)
434 switch(type) 435 switch(type)
435 { 436 {
436 case STATUS_LOGIN_RETRY: 437 case STATUS_LOGIN_RETRY:
437 mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle(); 438 //mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle();
439 LLNotifications::instance().add("VoiceLoginRetry");
438 break; 440 break;
439 case STATUS_LOGGED_IN: 441 case STATUS_LOGGED_IN:
440 if (!mLoginNotificationHandle.isDead()) 442 //if (!mLoginNotificationHandle.isDead())
441 { 443 //{
442 LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get(); 444 // LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get();
443 if (notifyp) 445 // if (notifyp)
444 { 446 // {
445 notifyp->close(); 447 // notifyp->close();
446 } 448 // }
447 mLoginNotificationHandle.markDead(); 449 // mLoginNotificationHandle.markDead();
448 } 450 //}
449 break; 451 break;
450 case STATUS_LEFT_CHANNEL: 452 case STATUS_LEFT_CHANNEL:
451 if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) 453 if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended)
452 { 454 {
453 // if forceably removed from channel 455 // if forceably removed from channel
454 // update the UI and revert to default channel 456 // update the UI and revert to default channel
455 LLNotifyBox::showXml("VoiceChannelDisconnected", mNotifyArgs); 457 LLNotifications::instance().add("VoiceChannelDisconnected", mNotifyArgs);
456 deactivate(); 458 deactivate();
457 } 459 }
458 mIgnoreNextSessionLeave = FALSE; 460 mIgnoreNextSessionLeave = FALSE;
@@ -503,7 +505,13 @@ void LLVoiceChannel::deactivate()
503 if (callStarted()) 505 if (callStarted())
504 { 506 {
505 setState(STATE_HUNG_UP); 507 setState(STATE_HUNG_UP);
508 // mute the microphone if required when returning to the proximal channel
509 if (gSavedSettings.getBOOL("AutoDisengageMic") && sCurrentVoiceChannel == this)
510 {
511 gSavedSettings.setBOOL("PTTCurrentlyEnabled", true);
512 }
506 } 513 }
514
507 if (sCurrentVoiceChannel == this) 515 if (sCurrentVoiceChannel == this)
508 { 516 {
509 // default channel is proximal channel 517 // default channel is proximal channel
@@ -522,11 +530,14 @@ void LLVoiceChannel::activate()
522 // deactivate old channel and mark ourselves as the active one 530 // deactivate old channel and mark ourselves as the active one
523 if (sCurrentVoiceChannel != this) 531 if (sCurrentVoiceChannel != this)
524 { 532 {
525 if (sCurrentVoiceChannel) 533 // mark as current before deactivating the old channel to prevent
534 // activating the proximal channel between IM calls
535 LLVoiceChannel* old_channel = sCurrentVoiceChannel;
536 sCurrentVoiceChannel = this;
537 if (old_channel)
526 { 538 {
527 sCurrentVoiceChannel->deactivate(); 539 old_channel->deactivate();
528 } 540 }
529 sCurrentVoiceChannel = this;
530 } 541 }
531 542
532 if (mState == STATE_NO_CHANNEL_INFO) 543 if (mState == STATE_NO_CHANNEL_INFO)
@@ -794,9 +805,9 @@ void LLVoiceChannelGroup::handleError(EStatusType status)
794 // notification 805 // notification
795 if (!notify.empty()) 806 if (!notify.empty())
796 { 807 {
797 LLNotifyBox::showXml(notify, mNotifyArgs); 808 LLNotificationPtr notification = LLNotifications::instance().add(notify, mNotifyArgs);
798 // echo to im window 809 // echo to im window
799 gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, LLNotifyBox::getTemplateMessage(notify, mNotifyArgs)); 810 gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, notification->getMessage());
800 } 811 }
801 812
802 LLVoiceChannel::handleError(status); 813 LLVoiceChannel::handleError(status);
@@ -897,7 +908,7 @@ void LLVoiceChannelProximal::handleError(EStatusType status)
897 // notification 908 // notification
898 if (!notify.empty()) 909 if (!notify.empty())
899 { 910 {
900 LLNotifyBox::showXml(notify, mNotifyArgs); 911 LLNotifications::instance().add(notify, mNotifyArgs);
901 } 912 }
902 913
903 LLVoiceChannel::handleError(status); 914 LLVoiceChannel::handleError(status);
@@ -935,12 +946,12 @@ void LLVoiceChannelP2P::handleStatusChange(EStatusType type)
935 if (mState == STATE_RINGING) 946 if (mState == STATE_RINGING)
936 { 947 {
937 // other user declined call 948 // other user declined call
938 LLNotifyBox::showXml("P2PCallDeclined", mNotifyArgs); 949 LLNotifications::instance().add("P2PCallDeclined", mNotifyArgs);
939 } 950 }
940 else 951 else
941 { 952 {
942 // other user hung up 953 // other user hung up
943 LLNotifyBox::showXml("VoiceChannelDisconnectedP2P", mNotifyArgs); 954 LLNotifications::instance().add("VoiceChannelDisconnectedP2P", mNotifyArgs);
944 } 955 }
945 deactivate(); 956 deactivate();
946 } 957 }
@@ -958,7 +969,7 @@ void LLVoiceChannelP2P::handleError(EStatusType type)
958 switch(type) 969 switch(type)
959 { 970 {
960 case ERROR_NOT_AVAILABLE: 971 case ERROR_NOT_AVAILABLE:
961 LLNotifyBox::showXml("P2PCallNoAnswer", mNotifyArgs); 972 LLNotifications::instance().add("P2PCallNoAnswer", mNotifyArgs);
962 break; 973 break;
963 default: 974 default:
964 break; 975 break;
@@ -1082,6 +1093,10 @@ LLFloaterIMPanel::LLFloaterIMPanel(
1082 mNumUnreadMessages(0), 1093 mNumUnreadMessages(0),
1083 mShowSpeakersOnConnect(TRUE), 1094 mShowSpeakersOnConnect(TRUE),
1084 mAutoConnect(FALSE), 1095 mAutoConnect(FALSE),
1096 mTextIMPossible(TRUE),
1097 mProfileButtonEnabled(TRUE),
1098 mCallBackEnabled(TRUE),
1099 mSpeakers(NULL),
1085 mSpeakerPanel(NULL), 1100 mSpeakerPanel(NULL),
1086 mFirstKeystrokeTimer(), 1101 mFirstKeystrokeTimer(),
1087 mLastKeystrokeTimer() 1102 mLastKeystrokeTimer()
@@ -1110,6 +1125,9 @@ LLFloaterIMPanel::LLFloaterIMPanel(
1110 mSentTypingState(TRUE), 1125 mSentTypingState(TRUE),
1111 mShowSpeakersOnConnect(TRUE), 1126 mShowSpeakersOnConnect(TRUE),
1112 mAutoConnect(FALSE), 1127 mAutoConnect(FALSE),
1128 mTextIMPossible(TRUE),
1129 mProfileButtonEnabled(TRUE),
1130 mCallBackEnabled(TRUE),
1113 mSpeakers(NULL), 1131 mSpeakers(NULL),
1114 mSpeakerPanel(NULL), 1132 mSpeakerPanel(NULL),
1115 mFirstKeystrokeTimer(), 1133 mFirstKeystrokeTimer(),
@@ -1155,7 +1173,13 @@ void LLFloaterIMPanel::init(const std::string& session_label)
1155 break; 1173 break;
1156 // just received text from another user 1174 // just received text from another user
1157 case IM_NOTHING_SPECIAL: 1175 case IM_NOTHING_SPECIAL:
1176
1158 xml_filename = "floater_instant_message.xml"; 1177 xml_filename = "floater_instant_message.xml";
1178
1179 mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID);
1180 mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID);
1181 mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID);
1182
1159 mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID); 1183 mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
1160 break; 1184 break;
1161 default: 1185 default:
@@ -1288,11 +1312,17 @@ BOOL LLFloaterIMPanel::postBuild()
1288 1312
1289 mHistoryEditor = getChild<LLViewerTextEditor>("im_history"); 1313 mHistoryEditor = getChild<LLViewerTextEditor>("im_history");
1290 mHistoryEditor->setParseHTML(TRUE); 1314 mHistoryEditor->setParseHTML(TRUE);
1315 mHistoryEditor->setParseHighlights(TRUE);
1291 1316
1292 if ( IM_SESSION_GROUP_START == mDialog ) 1317 if ( IM_SESSION_GROUP_START == mDialog )
1293 { 1318 {
1294 childSetEnabled("profile_btn", FALSE); 1319 childSetEnabled("profile_btn", FALSE);
1295 } 1320 }
1321
1322 if(!mProfileButtonEnabled)
1323 {
1324 childSetEnabled("profile_callee_btn", FALSE);
1325 }
1296 1326
1297 sTitleString = getString("title_string"); 1327 sTitleString = getString("title_string");
1298 sTypingStartString = getString("typing_start_string"); 1328 sTypingStartString = getString("typing_start_string");
@@ -1361,7 +1391,8 @@ void LLFloaterIMPanel::draw()
1361 1391
1362 BOOL enable_connect = (region && region->getCapability("ChatSessionRequest") != "") 1392 BOOL enable_connect = (region && region->getCapability("ChatSessionRequest") != "")
1363 && mSessionInitialized 1393 && mSessionInitialized
1364 && LLVoiceClient::voiceEnabled(); 1394 && LLVoiceClient::voiceEnabled()
1395 && mCallBackEnabled;
1365 1396
1366 // hide/show start call and end call buttons 1397 // hide/show start call and end call buttons
1367 childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); 1398 childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
@@ -1370,7 +1401,12 @@ void LLFloaterIMPanel::draw()
1370 childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty()); 1401 childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
1371 1402
1372 LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID()); 1403 LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
1373 if (self_speaker.notNull() && self_speaker->mModeratorMutedText) 1404 if(!mTextIMPossible)
1405 {
1406 mInputEditor->setEnabled(FALSE);
1407 mInputEditor->setLabel(getString("unavailable_text_label"));
1408 }
1409 else if (self_speaker.notNull() && self_speaker->mModeratorMutedText)
1374 { 1410 {
1375 mInputEditor->setEnabled(FALSE); 1411 mInputEditor->setEnabled(FALSE);
1376 mInputEditor->setLabel(getString("muted_text_label")); 1412 mInputEditor->setLabel(getString("muted_text_label"));
@@ -1659,62 +1695,32 @@ BOOL LLFloaterIMPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
1659 EAcceptance* accept, 1695 EAcceptance* accept,
1660 std::string& tooltip_msg) 1696 std::string& tooltip_msg)
1661{ 1697{
1662 BOOL accepted = FALSE; 1698
1663 switch(cargo_type) 1699 if (mDialog == IM_NOTHING_SPECIAL)
1664 { 1700 {
1665 case DAD_CALLINGCARD: 1701 LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionUUID, drop,
1702 cargo_type, cargo_data, accept);
1703 }
1704
1705 // handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
1706 else if (isInviteAllowed())
1707 {
1708 *accept = ACCEPT_NO;
1709
1710 if (cargo_type == DAD_CALLINGCARD)
1666 { 1711 {
1667 accepted = dropCallingCard((LLInventoryItem*)cargo_data, drop); 1712 if (dropCallingCard((LLInventoryItem*)cargo_data, drop))
1668 break; 1713 {
1714 *accept = ACCEPT_YES_MULTI;
1715 }
1669 } 1716 }
1670 case DAD_CATEGORY: 1717 else if (cargo_type == DAD_CATEGORY)
1671 { 1718 {
1672 accepted = dropCategory((LLInventoryCategory*)cargo_data, drop); 1719 if (dropCategory((LLInventoryCategory*)cargo_data, drop))
1673 break;
1674 }
1675
1676 // See stdenums.h
1677 case DAD_TEXTURE:
1678 case DAD_SOUND:
1679 // DAD_CALLINGCARD above
1680 case DAD_LANDMARK:
1681 case DAD_SCRIPT:
1682 case DAD_CLOTHING:
1683 case DAD_OBJECT:
1684 case DAD_NOTECARD:
1685 // DAD_CATEGORY above
1686 case DAD_BODYPART:
1687 case DAD_ANIMATION:
1688 case DAD_GESTURE:
1689 {
1690 if (mDialog == IM_NOTHING_SPECIAL)
1691 { 1720 {
1692 // See LLDropTarget for similar code. 1721 *accept = ACCEPT_YES_MULTI;
1693 LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
1694 if(gInventory.getItem(inv_item->getUUID())
1695 && LLToolDragAndDrop::isInventoryGiveAcceptable(inv_item))
1696 {
1697 accepted = true;
1698 if(drop)
1699 {
1700 LLToolDragAndDrop::giveInventory(mOtherParticipantUUID, inv_item);
1701 LLStringUtil::format_map_t args;
1702 gIMMgr->addSystemMessage(mSessionUUID, "inventory_item_offered", args);
1703 }
1704 }
1705 } 1722 }
1706 break;
1707 } 1723 }
1708 default:
1709 break;
1710 }
1711 if (accepted)
1712 {
1713 *accept = ACCEPT_YES_MULTI;
1714 }
1715 else
1716 {
1717 *accept = ACCEPT_NO;
1718 } 1724 }
1719 return TRUE; 1725 return TRUE;
1720} 1726}
@@ -1832,9 +1838,9 @@ void LLFloaterIMPanel::onClickHistory( void* userdata )
1832 } 1838 }
1833 else 1839 else
1834 { 1840 {
1835 LLStringUtil::format_map_t args; 1841 LLSD args;
1836 args["[NAME]"] = fullname; 1842 args["[NAME]"] = fullname;
1837 gViewerWindow->alertXml("IMLogNotFound", args); 1843 LLNotifications::instance().add("IMLogNotFound", args);
1838 llinfos << file_path << llendl; 1844 llinfos << file_path << llendl;
1839 } 1845 }
1840 } 1846 }
@@ -2358,35 +2364,33 @@ void LLFloaterIMPanel::showSessionStartError(
2358 //their own XML file which would be read in by any LLIMPanel 2364 //their own XML file which would be read in by any LLIMPanel
2359 //post build function instead of repeating the same info 2365 //post build function instead of repeating the same info
2360 //in the group, adhoc and normal IM xml files. 2366 //in the group, adhoc and normal IM xml files.
2361 LLStringUtil::format_map_t args; 2367 LLSD args;
2362 args["[REASON]"] = 2368 args["REASON"] =
2363 LLFloaterIM::sErrorStringsMap[error_string]; 2369 LLFloaterIM::sErrorStringsMap[error_string];
2364 args["[RECIPIENT]"] = getTitle(); 2370 args["RECIPIENT"] = getTitle();
2371
2372 LLSD payload;
2373 payload["session_id"] = mSessionUUID;
2365 2374
2366 gViewerWindow->alertXml( 2375 LLNotifications::instance().add(
2367 "ChatterBoxSessionStartError", 2376 "ChatterBoxSessionStartError",
2368 args, 2377 args,
2369 onConfirmForceCloseError, 2378 payload,
2370 new LLUUID(mSessionUUID)); 2379 onConfirmForceCloseError);
2371} 2380}
2372 2381
2373void LLFloaterIMPanel::showSessionEventError( 2382void LLFloaterIMPanel::showSessionEventError(
2374 const std::string& event_string, 2383 const std::string& event_string,
2375 const std::string& error_string) 2384 const std::string& error_string)
2376{ 2385{
2377 LLStringUtil::format_map_t args; 2386 LLSD args;
2378 std::string event; 2387 args["REASON"] =
2379 2388 LLFloaterIM::sErrorStringsMap[error_string];
2380 event = LLFloaterIM::sEventStringsMap[event_string]; 2389 args["EVENT"] =
2381 args["[RECIPIENT]"] = getTitle(); 2390 LLFloaterIM::sEventStringsMap[event_string];
2382 LLStringUtil::format(event, args); 2391 args["RECIPIENT"] = getTitle();
2383
2384
2385 args = LLStringUtil::format_map_t();
2386 args["[REASON]"] = LLFloaterIM::sErrorStringsMap[error_string];
2387 args["[EVENT]"] = event;
2388 2392
2389 gViewerWindow->alertXml( 2393 LLNotifications::instance().add(
2390 "ChatterBoxSessionEventError", 2394 "ChatterBoxSessionEventError",
2391 args); 2395 args);
2392} 2396}
@@ -2394,16 +2398,19 @@ void LLFloaterIMPanel::showSessionEventError(
2394void LLFloaterIMPanel::showSessionForceClose( 2398void LLFloaterIMPanel::showSessionForceClose(
2395 const std::string& reason_string) 2399 const std::string& reason_string)
2396{ 2400{
2397 LLStringUtil::format_map_t args; 2401 LLSD args;
2402
2403 args["NAME"] = getTitle();
2404 args["REASON"] = LLFloaterIM::sForceCloseSessionMap[reason_string];
2398 2405
2399 args["[NAME]"] = getTitle(); 2406 LLSD payload;
2400 args["[REASON]"] = LLFloaterIM::sForceCloseSessionMap[reason_string]; 2407 payload["session_id"] = mSessionUUID;
2401 2408
2402 gViewerWindow->alertXml( 2409 LLNotifications::instance().add(
2403 "ForceCloseChatterBoxSession", 2410 "ForceCloseChatterBoxSession",
2404 args, 2411 args,
2405 LLFloaterIMPanel::onConfirmForceCloseError, 2412 payload,
2406 new LLUUID(mSessionUUID)); 2413 LLFloaterIMPanel::onConfirmForceCloseError);
2407 2414
2408} 2415}
2409 2416
@@ -2413,10 +2420,10 @@ void LLFloaterIMPanel::onKickSpeaker(void* user_data)
2413 2420
2414} 2421}
2415 2422
2416void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data) 2423bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const LLSD& response)
2417{ 2424{
2418 //only 1 option really 2425 //only 1 option really
2419 LLUUID session_id = *((LLUUID*) data); 2426 LLUUID session_id = notification["payload"]["session_id"];
2420 2427
2421 if ( gIMMgr ) 2428 if ( gIMMgr )
2422 { 2429 {
@@ -2425,6 +2432,7 @@ void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data)
2425 2432
2426 if ( floaterp ) floaterp->close(FALSE); 2433 if ( floaterp ) floaterp->close(FALSE);
2427 } 2434 }
2435 return false;
2428} 2436}
2429 2437
2430 2438