aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llimview.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/llimview.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz
Second Life viewer sources 1.23.0-RC
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llimview.cpp481
1 files changed, 223 insertions, 258 deletions
diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp
index 10e8ff8..a90ea39 100644
--- a/linden/indra/newview/llimview.cpp
+++ b/linden/indra/newview/llimview.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,
@@ -97,6 +98,96 @@ std::map<std::string,std::string> LLFloaterIM::sForceCloseSessionMap;
97// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0); 98// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0);
98//} 99//}
99 100
101class LLViewerChatterBoxInvitationAcceptResponder :
102 public LLHTTPClient::Responder
103{
104public:
105 LLViewerChatterBoxInvitationAcceptResponder(
106 const LLUUID& session_id,
107 LLIMMgr::EInvitationType invitation_type)
108 {
109 mSessionID = session_id;
110 mInvitiationType = invitation_type;
111 }
112
113 void result(const LLSD& content)
114 {
115 if ( gIMMgr)
116 {
117 LLFloaterIMPanel* floaterp =
118 gIMMgr->findFloaterBySession(mSessionID);
119
120 if (floaterp)
121 {
122 //we've accepted our invitation
123 //and received a list of agents that were
124 //currently in the session when the reply was sent
125 //to us. Now, it is possible that there were some agents
126 //to slip in/out between when that message was sent to us
127 //and now.
128
129 //the agent list updates we've received have been
130 //accurate from the time we were added to the session
131 //but unfortunately, our base that we are receiving here
132 //may not be the most up to date. It was accurate at
133 //some point in time though.
134 floaterp->setSpeakers(content);
135
136 //we now have our base of users in the session
137 //that was accurate at some point, but maybe not now
138 //so now we apply all of the udpates we've received
139 //in case of race conditions
140 floaterp->updateSpeakersList(
141 gIMMgr->getPendingAgentListUpdates(mSessionID));
142
143 if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
144 {
145 floaterp->requestAutoConnect();
146 LLFloaterIMPanel::onClickStartCall(floaterp);
147 // always open IM window when connecting to voice
148 LLFloaterChatterBox::showInstance(TRUE);
149 }
150 else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
151 {
152 LLFloaterChatterBox::showInstance(TRUE);
153 }
154 }
155
156 gIMMgr->clearPendingAgentListUpdates(mSessionID);
157 gIMMgr->clearPendingInvitation(mSessionID);
158 }
159 }
160
161 void error(U32 statusNum, const std::string& reason)
162 {
163 //throw something back to the viewer here?
164 if ( gIMMgr )
165 {
166 gIMMgr->clearPendingAgentListUpdates(mSessionID);
167 gIMMgr->clearPendingInvitation(mSessionID);
168
169 LLFloaterIMPanel* floaterp =
170 gIMMgr->findFloaterBySession(mSessionID);
171
172 if ( floaterp )
173 {
174 if ( 404 == statusNum )
175 {
176 std::string error_string;
177 error_string = "does not exist";
178
179 floaterp->showSessionStartError(
180 error_string);
181 }
182 }
183 }
184 }
185
186private:
187 LLUUID mSessionID;
188 LLIMMgr::EInvitationType mInvitiationType;
189};
190
100 191
101// the other_participant_id is either an agent_id, a group_id, or an inventory 192// the other_participant_id is either an agent_id, a group_id, or an inventory
102// folder item_id (collection of calling cards) 193// folder item_id (collection of calling cards)
@@ -256,41 +347,105 @@ protected:
256}; 347};
257 348
258 349
259class LLIMMgr::LLIMSessionInvite 350bool inviteUserResponse(const LLSD& notification, const LLSD& response)
260{ 351{
261public: 352 const LLSD& payload = notification["payload"];
262 LLIMSessionInvite( 353 LLUUID session_id = payload["session_id"].asUUID();
263 const LLUUID& session_id, 354 EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
264 const std::string& session_name, 355 LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
265 const LLUUID& caller_id, 356 S32 option = LLNotification::getSelectedOption(notification, response);
266 const std::string& caller_name, 357 switch(option)
267 EInstantMessage type, 358 {
268 EInvitationType inv_type, 359 case 0: // accept
269 const std::string& session_handle, 360 {
270 const std::string& notify_box, 361 if (type == IM_SESSION_P2P_INVITE)
271 const std::string& session_uri) : 362 {
272 mSessionID(session_id), 363 // create a normal IM session
273 mSessionName(session_name), 364 session_id = gIMMgr->addP2PSession(
274 mCallerID(caller_id), 365 payload["session_name"].asString(),
275 mCallerName(caller_name), 366 payload["caller_id"].asUUID(),
276 mType(type), 367 payload["session_handle"].asString(),
277 mInvType(inv_type), 368 payload["session_uri"].asString());
278 mSessionHandle(session_handle), 369
279 mNotifyBox(notify_box), 370 LLFloaterIMPanel* im_floater =
280 mSessionURI(session_uri) 371 gIMMgr->findFloaterBySession(
281 {}; 372 session_id);
282 373 if (im_floater)
283 LLUUID mSessionID; 374 {
284 std::string mSessionName; 375 im_floater->requestAutoConnect();
285 LLUUID mCallerID; 376 LLFloaterIMPanel::onClickStartCall(im_floater);
286 std::string mCallerName; 377 // always open IM window when connecting to voice
287 EInstantMessage mType; 378 LLFloaterChatterBox::showInstance(session_id);
288 EInvitationType mInvType; 379 }
289 std::string mSessionHandle; 380
290 std::string mNotifyBox; 381 gIMMgr->clearPendingAgentListUpdates(session_id);
291 std::string mSessionURI; 382 gIMMgr->clearPendingInvitation(session_id);
292}; 383 }
384 else
385 {
386 gIMMgr->addSession(
387 payload["session_name"].asString(),
388 type,
389 session_id);
390
391 std::string url = gAgent.getRegion()->getCapability(
392 "ChatSessionRequest");
393
394 LLSD data;
395 data["method"] = "accept invitation";
396 data["session-id"] = session_id;
397 LLHTTPClient::post(
398 url,
399 data,
400 new LLViewerChatterBoxInvitationAcceptResponder(
401 session_id,
402 inv_type));
403 }
404 }
405 break;
406 case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
407 {
408 // mute the sender of this invite
409 if (!LLMuteList::getInstance()->isMuted(payload["caller_id"].asUUID()))
410 {
411 LLMute mute(payload["caller_id"].asUUID(), payload["caller_name"].asString(), LLMute::AGENT);
412 LLMuteList::getInstance()->add(mute);
413 }
414 }
415 /* FALLTHROUGH */
416
417 case 1: // decline
418 {
419 if (type == IM_SESSION_P2P_INVITE)
420 {
421 if(gVoiceClient)
422 {
423 std::string s = payload["session_handle"].asString();
424 gVoiceClient->declineInvite(s);
425 }
426 }
427 else
428 {
429 std::string url = gAgent.getRegion()->getCapability(
430 "ChatSessionRequest");
431
432 LLSD data;
433 data["method"] = "decline invitation";
434 data["session-id"] = session_id;
435 LLHTTPClient::post(
436 url,
437 data,
438 NULL);
439 }
440 }
293 441
442 gIMMgr->clearPendingAgentListUpdates(session_id);
443 gIMMgr->clearPendingInvitation(session_id);
444 break;
445 }
446
447 return false;
448}
294 449
295// 450//
296// Public Static Member Functions 451// Public Static Member Functions
@@ -513,7 +668,7 @@ void LLIMMgr::addMessage(
513 } 668 }
514} 669}
515 670
516void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLStringUtil::format_map_t& args) 671void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
517{ 672{
518 LLUIString message; 673 LLUIString message;
519 674
@@ -523,7 +678,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
523 LLFloaterChat* floaterp = LLFloaterChat::getInstance(); 678 LLFloaterChat* floaterp = LLFloaterChat::getInstance();
524 679
525 message = floaterp->getString(message_name); 680 message = floaterp->getString(message_name);
526 message.setArgList(args); 681 message.setArgs(args);
527 682
528 LLChat chat(message); 683 LLChat chat(message);
529 chat.mSourceType = CHAT_SOURCE_SYSTEM; 684 chat.mSourceType = CHAT_SOURCE_SYSTEM;
@@ -535,7 +690,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
535 if (floaterp) 690 if (floaterp)
536 { 691 {
537 message = floaterp->getString(message_name); 692 message = floaterp->getString(message_name);
538 message.setArgList(args); 693 message.setArgs(args);
539 694
540 gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString()); 695 gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
541 } 696 }
@@ -691,7 +846,7 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
691 LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); 846 LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
692 //mTabContainer->removeTabPanel(floater); 847 //mTabContainer->removeTabPanel(floater);
693 848
694 clearPendingInviation(session_id); 849 clearPendingInvitation(session_id);
695 clearPendingAgentListUpdates(session_id); 850 clearPendingAgentListUpdates(session_id);
696 } 851 }
697} 852}
@@ -738,22 +893,22 @@ void LLIMMgr::inviteToSession(
738 ad_hoc_invite = TRUE; 893 ad_hoc_invite = TRUE;
739 } 894 }
740 895
741 LLIMSessionInvite* invite = new LLIMSessionInvite( 896 LLSD payload;
742 session_id, 897 payload["session_id"] = session_id;
743 session_name, 898 payload["session_name"] = session_name;
744 caller_id, 899 payload["caller_id"] = caller_id;
745 caller_name, 900 payload["caller_name"] = caller_name;
746 type, 901 payload["type"] = type;
747 inv_type, 902 payload["inv_type"] = inv_type;
748 session_handle, 903 payload["session_handle"] = session_handle;
749 notify_box_type, 904 payload["session_uri"] = session_uri;
750 session_uri); 905 payload["notify_box_type"] = notify_box_type;
751 906
752 LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id); 907 LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
753 if (channelp && channelp->callStarted()) 908 if (channelp && channelp->callStarted())
754 { 909 {
755 // you have already started a call to the other user, so just accept the invite 910 // you have already started a call to the other user, so just accept the invite
756 inviteUserResponse(0, invite); // inviteUserResponse deletes 911 LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 0);
757 return; 912 return;
758 } 913 }
759 914
@@ -767,7 +922,7 @@ void LLIMMgr::inviteToSession(
767 if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly")) 922 if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
768 { 923 {
769 // invite not from a friend, so decline 924 // invite not from a friend, so decline
770 inviteUserResponse(1, invite); // inviteUserResponse deletes 925 LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 1);
771 return; 926 return;
772 } 927 }
773 } 928 }
@@ -777,231 +932,41 @@ void LLIMMgr::inviteToSession(
777 { 932 {
778 if (caller_name.empty()) 933 if (caller_name.empty())
779 { 934 {
780 gCacheName->get(caller_id, FALSE, onInviteNameLookup, invite); 935 gCacheName->getName(caller_id, onInviteNameLookup, new LLSD(payload));
781 } 936 }
782 else 937 else
783 { 938 {
784 LLStringUtil::format_map_t args; 939 LLSD args;
785 args["[NAME]"] = caller_name; 940 args["NAME"] = caller_name;
786 args["[GROUP]"] = session_name; 941 args["GROUP"] = session_name;
787 942
788 LLNotifyBox::showXml(notify_box_type, 943 LLNotifications::instance().add(notify_box_type,
789 args, 944 args,
790 inviteUserResponse, 945 payload,
791 (void*)invite); // inviteUserResponse deletes 946 &inviteUserResponse);
792 947
793 } 948 }
794 mPendingInvitations[session_id.asString()] = LLSD(); 949 mPendingInvitations[session_id.asString()] = LLSD();
795 } 950 }
796 else
797 {
798 delete invite;
799 }
800} 951}
801 952
802//static 953//static
803void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata) 954void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata)
804{ 955{
805 LLIMSessionInvite* invite = (LLIMSessionInvite*)userdata; 956 LLSD payload = *(LLSD*)userdata;
957 delete (LLSD*)userdata;
806 958
807 invite->mCallerName = first + " " + last; 959 payload["caller_name"] = first + " " + last;
808 invite->mSessionName = invite->mCallerName; 960 payload["session_name"] = payload["caller_name"].asString();
809 961
810 LLStringUtil::format_map_t args; 962 LLSD args;
811 args["[NAME]"] = invite->mCallerName; 963 args["NAME"] = payload["caller_name"].asString();
812 964
813 LLNotifyBox::showXml( 965 LLNotifications::instance().add(
814 invite->mNotifyBox, 966 payload["notify_box_type"].asString(),
815 args, 967 args,
816 inviteUserResponse, 968 payload,
817 (void*)invite); 969 &inviteUserResponse);
818}
819
820class LLViewerChatterBoxInvitationAcceptResponder :
821 public LLHTTPClient::Responder
822{
823public:
824 LLViewerChatterBoxInvitationAcceptResponder(
825 const LLUUID& session_id,
826 LLIMMgr::EInvitationType invitation_type)
827 {
828 mSessionID = session_id;
829 mInvitiationType = invitation_type;
830 }
831
832 void result(const LLSD& content)
833 {
834 if ( gIMMgr)
835 {
836 LLFloaterIMPanel* floaterp =
837 gIMMgr->findFloaterBySession(mSessionID);
838
839 if (floaterp)
840 {
841 //we've accepted our invitation
842 //and received a list of agents that were
843 //currently in the session when the reply was sent
844 //to us. Now, it is possible that there were some agents
845 //to slip in/out between when that message was sent to us
846 //and now.
847
848 //the agent list updates we've received have been
849 //accurate from the time we were added to the session
850 //but unfortunately, our base that we are receiving here
851 //may not be the most up to date. It was accurate at
852 //some point in time though.
853 floaterp->setSpeakers(content);
854
855 //we now have our base of users in the session
856 //that was accurate at some point, but maybe not now
857 //so now we apply all of the udpates we've received
858 //in case of race conditions
859 floaterp->updateSpeakersList(
860 gIMMgr->getPendingAgentListUpdates(mSessionID));
861
862 if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
863 {
864 floaterp->requestAutoConnect();
865 LLFloaterIMPanel::onClickStartCall(floaterp);
866 // always open IM window when connecting to voice
867 LLFloaterChatterBox::showInstance(TRUE);
868 }
869 else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
870 {
871 LLFloaterChatterBox::showInstance(TRUE);
872 }
873 }
874
875 gIMMgr->clearPendingAgentListUpdates(mSessionID);
876 gIMMgr->clearPendingInviation(mSessionID);
877 }
878 }
879
880 void error(U32 statusNum, const std::string& reason)
881 {
882 //throw something back to the viewer here?
883 if ( gIMMgr )
884 {
885 gIMMgr->clearPendingAgentListUpdates(mSessionID);
886 gIMMgr->clearPendingInviation(mSessionID);
887
888 LLFloaterIMPanel* floaterp =
889 gIMMgr->findFloaterBySession(mSessionID);
890
891 if ( floaterp )
892 {
893 if ( 404 == statusNum )
894 {
895 std::string error_string;
896 error_string = "does not exist";
897
898 floaterp->showSessionStartError(
899 error_string);
900 }
901 }
902 }
903 }
904
905private:
906 LLUUID mSessionID;
907 LLIMMgr::EInvitationType mInvitiationType;
908};
909
910//static
911void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
912{
913 LLIMSessionInvite* invitep = (LLIMSessionInvite*)user_data;
914
915 switch(option)
916 {
917 case 0: // accept
918 {
919 if (invitep->mType == IM_SESSION_P2P_INVITE)
920 {
921 // create a normal IM session
922 invitep->mSessionID = gIMMgr->addP2PSession(
923 invitep->mSessionName,
924 invitep->mCallerID,
925 invitep->mSessionHandle,
926 invitep->mSessionURI );
927
928 LLFloaterIMPanel* im_floater =
929 gIMMgr->findFloaterBySession(
930 invitep->mSessionID);
931 if (im_floater)
932 {
933 im_floater->requestAutoConnect();
934 LLFloaterIMPanel::onClickStartCall(im_floater);
935 // always open IM window when connecting to voice
936 LLFloaterChatterBox::showInstance(invitep->mSessionID);
937 }
938
939 gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
940 gIMMgr->clearPendingInviation(invitep->mSessionID);
941 }
942 else
943 {
944 gIMMgr->addSession(
945 invitep->mSessionName,
946 invitep->mType,
947 invitep->mSessionID);
948
949 std::string url = gAgent.getRegion()->getCapability(
950 "ChatSessionRequest");
951
952 LLSD data;
953 data["method"] = "accept invitation";
954 data["session-id"] = invitep->mSessionID;
955 LLHTTPClient::post(
956 url,
957 data,
958 new LLViewerChatterBoxInvitationAcceptResponder(
959 invitep->mSessionID,
960 invitep->mInvType));
961 }
962 }
963 break;
964 case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
965 {
966 // mute the sender of this invite
967 if (!LLMuteList::getInstance()->isMuted(invitep->mCallerID))
968 {
969 LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
970 LLMuteList::getInstance()->add(mute);
971 }
972 }
973 /* FALLTHROUGH */
974
975 case 1: // decline
976 {
977 if (invitep->mType == IM_SESSION_P2P_INVITE)
978 {
979 if(gVoiceClient)
980 {
981 gVoiceClient->declineInvite(invitep->mSessionHandle);
982 }
983 }
984 else
985 {
986 std::string url = gAgent.getRegion()->getCapability(
987 "ChatSessionRequest");
988
989 LLSD data;
990 data["method"] = "decline invitation";
991 data["session-id"] = invitep->mSessionID;
992 LLHTTPClient::post(
993 url,
994 data,
995 NULL);
996 }
997 }
998
999 gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
1000 gIMMgr->clearPendingInviation(invitep->mSessionID);
1001 break;
1002 }
1003
1004 delete invitep;
1005} 970}
1006 971
1007void LLIMMgr::refresh() 972void LLIMMgr::refresh()
@@ -1075,7 +1040,7 @@ BOOL LLIMMgr::hasSession(const LLUUID& session_id)
1075 return (findFloaterBySession(session_id) != NULL); 1040 return (findFloaterBySession(session_id) != NULL);
1076} 1041}
1077 1042
1078void LLIMMgr::clearPendingInviation(const LLUUID& session_id) 1043void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
1079{ 1044{
1080 if ( mPendingInvitations.has(session_id.asString()) ) 1045 if ( mPendingInvitations.has(session_id.asString()) )
1081 { 1046 {