aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llimview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llimview.cpp')
-rw-r--r--linden/indra/newview/llimview.cpp294
1 files changed, 255 insertions, 39 deletions
diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp
index a4fd729..38471ad 100644
--- a/linden/indra/newview/llimview.cpp
+++ b/linden/indra/newview/llimview.cpp
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 6 *
7 * Second Life Viewer Source Code
7 * The source code in this file ("Source Code") is provided by Linden Lab 8 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0 9 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement 10 * ("GPL"), unless you have obtained a separate licensing agreement
@@ -42,6 +43,7 @@
42#include "llviewerwindow.h" 43#include "llviewerwindow.h"
43#include "llresmgr.h" 44#include "llresmgr.h"
44#include "llfloaternewim.h" 45#include "llfloaternewim.h"
46#include "llhttpnode.h"
45#include "llimpanel.h" 47#include "llimpanel.h"
46#include "llresizebar.h" 48#include "llresizebar.h"
47#include "lltabcontainer.h" 49#include "lltabcontainer.h"
@@ -54,7 +56,6 @@
54#include "llcallingcard.h" 56#include "llcallingcard.h"
55#include "lltoolbar.h" 57#include "lltoolbar.h"
56 58
57const EInstantMessage EVERYONE_DIALOG = IM_NOTHING_SPECIAL;
58const EInstantMessage GROUP_DIALOG = IM_SESSION_GROUP_START; 59const EInstantMessage GROUP_DIALOG = IM_SESSION_GROUP_START;
59const EInstantMessage DEFAULT_DIALOG = IM_NOTHING_SPECIAL; 60const EInstantMessage DEFAULT_DIALOG = IM_NOTHING_SPECIAL;
60 61
@@ -69,6 +70,9 @@ LLIMView* gIMView = NULL;
69static LLString sOnlyUserMessage; 70static LLString sOnlyUserMessage;
70static LLString sOfflineMessage; 71static LLString sOfflineMessage;
71 72
73static std::map<std::string,LLString> sEventStringsMap;
74static std::map<std::string,LLString> sErrorStringsMap;
75static std::map<std::string,LLString> sForceCloseSessionMap;
72// 76//
73// Helper Functions 77// Helper Functions
74// 78//
@@ -82,7 +86,8 @@ static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b )
82 86
83// the other_participant_id is either an agent_id, a group_id, or an inventory 87// the other_participant_id is either an agent_id, a group_id, or an inventory
84// folder item_id (collection of calling cards) 88// folder item_id (collection of calling cards)
85static LLUUID compute_session_id(EInstantMessage dialog, const LLUUID& other_participant_id) 89static LLUUID compute_session_id(EInstantMessage dialog,
90 const LLUUID& other_participant_id)
86{ 91{
87 LLUUID session_id; 92 LLUUID session_id;
88 if (IM_SESSION_GROUP_START == dialog) 93 if (IM_SESSION_GROUP_START == dialog)
@@ -90,6 +95,10 @@ static LLUUID compute_session_id(EInstantMessage dialog, const LLUUID& other_par
90 // slam group session_id to the group_id (other_participant_id) 95 // slam group session_id to the group_id (other_participant_id)
91 session_id = other_participant_id; 96 session_id = other_participant_id;
92 } 97 }
98 else if (IM_SESSION_CONFERENCE_START == dialog)
99 {
100 session_id.generate();
101 }
93 else 102 else
94 { 103 {
95 LLUUID agent_id = gAgent.getID(); 104 LLUUID agent_id = gAgent.getID();
@@ -121,11 +130,34 @@ BOOL LLFloaterIM::postBuild()
121{ 130{
122 requires("only_user_message", WIDGET_TYPE_TEXT_BOX); 131 requires("only_user_message", WIDGET_TYPE_TEXT_BOX);
123 requires("offline_message", WIDGET_TYPE_TEXT_BOX); 132 requires("offline_message", WIDGET_TYPE_TEXT_BOX);
133 requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
134 requires("insufficient_perms_error", WIDGET_TYPE_TEXT_BOX);
135 requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
136 requires("add_session_event", WIDGET_TYPE_TEXT_BOX);
137 requires("message_session_event", WIDGET_TYPE_TEXT_BOX);
138 requires("removed_from_group", WIDGET_TYPE_TEXT_BOX);
124 139
125 if (checkRequirements()) 140 if (checkRequirements())
126 { 141 {
127 sOnlyUserMessage = childGetText("only_user_message"); 142 sOnlyUserMessage = childGetText("only_user_message");
128 sOfflineMessage = childGetText("offline_message"); 143 sOfflineMessage = childGetText("offline_message");
144
145 sErrorStringsMap["generic"] =
146 childGetText("generic_request_error");
147 sErrorStringsMap["unverified"] =
148 childGetText("insufficient_perms_error");
149 sErrorStringsMap["no_user_911"] =
150 childGetText("user_no_help");
151
152 sEventStringsMap["add"] = childGetText("add_session_event");;
153 sEventStringsMap["message"] =
154 childGetText("message_session_event");;
155 sEventStringsMap["teleport"] =
156 childGetText("teleport_session_event");;
157
158 sForceCloseSessionMap["removed"] =
159 childGetText("removed_from_group");
160
129 return TRUE; 161 return TRUE;
130 } 162 }
131 return FALSE; 163 return FALSE;
@@ -209,16 +241,12 @@ protected:
209// static 241// static
210EInstantMessage LLIMView::defaultIMTypeForAgent(const LLUUID& agent_id) 242EInstantMessage LLIMView::defaultIMTypeForAgent(const LLUUID& agent_id)
211{ 243{
212 EInstantMessage type = IM_SESSION_CARDLESS_START; 244 EInstantMessage type = IM_NOTHING_SPECIAL;
213 if(is_agent_friend(agent_id)) 245 if(is_agent_friend(agent_id))
214 { 246 {
215 if(LLAvatarTracker::instance().isBuddyOnline(agent_id)) 247 if(LLAvatarTracker::instance().isBuddyOnline(agent_id))
216 { 248 {
217 type = IM_SESSION_ADD; 249 type = IM_SESSION_CONFERENCE_START;
218 }
219 else
220 {
221 type = IM_SESSION_OFFLINE_ADD;
222 } 250 }
223 } 251 }
224 return type; 252 return type;
@@ -426,18 +454,25 @@ BOOL LLIMView::isIMSessionOpen(const LLUUID& uuid)
426// exists, it is brought forward. Specifying id = NULL results in an 454// exists, it is brought forward. Specifying id = NULL results in an
427// im session to everyone. Returns the uuid of the session. 455// im session to everyone. Returns the uuid of the session.
428LLUUID LLIMView::addSession(const std::string& name, 456LLUUID LLIMView::addSession(const std::string& name,
429 EInstantMessage dialog, 457 EInstantMessage dialog,
430 const LLUUID& other_participant_id) 458 const LLUUID& other_participant_id)
431{ 459{
432 LLUUID session_id = compute_session_id(dialog, other_participant_id); 460 LLUUID session_id = compute_session_id(dialog, other_participant_id);
461
433 LLFloaterIMPanel* floater = findFloaterBySession(session_id); 462 LLFloaterIMPanel* floater = findFloaterBySession(session_id);
434 if(!floater) 463 if(!floater)
435 { 464 {
436 floater = createFloater(session_id, other_participant_id, name, dialog, TRUE);
437 LLDynamicArray<LLUUID> ids; 465 LLDynamicArray<LLUUID> ids;
438 ids.put(other_participant_id); 466 ids.put(other_participant_id);
467
468 floater = createFloater(session_id,
469 other_participant_id,
470 name,
471 ids,
472 dialog,
473 TRUE);
474
439 noteOfflineUsers(floater, ids); 475 noteOfflineUsers(floater, ids);
440 floater->addParticipants(ids);
441 mTalkFloater->showFloater(floater); 476 mTalkFloater->showFloater(floater);
442 } 477 }
443 else 478 else
@@ -452,30 +487,30 @@ LLUUID LLIMView::addSession(const std::string& name,
452// Adds a session using the given session_id. If the session already exists 487// Adds a session using the given session_id. If the session already exists
453// the dialog type is assumed correct. Returns the uuid of the session. 488// the dialog type is assumed correct. Returns the uuid of the session.
454LLUUID LLIMView::addSession(const std::string& name, 489LLUUID LLIMView::addSession(const std::string& name,
455 EInstantMessage dialog, 490 EInstantMessage dialog,
456 const LLUUID& session_id, 491 const LLUUID& other_participant_id,
457 const LLDynamicArray<LLUUID>& ids) 492 const LLDynamicArray<LLUUID>& ids)
458{ 493{
459 if (0 == ids.getLength()) 494 if (0 == ids.getLength())
460 { 495 {
461 return LLUUID::null; 496 return LLUUID::null;
462 } 497 }
463 498
464 LLUUID other_participant_id = ids[0]; 499 LLUUID session_id = compute_session_id(dialog,
465 LLUUID new_session_id = session_id; 500 other_participant_id);
466 if (new_session_id.isNull())
467 {
468 new_session_id = compute_session_id(dialog, other_participant_id);
469 }
470 501
471 LLFloaterIMPanel* floater = findFloaterBySession(new_session_id); 502 LLFloaterIMPanel* floater = findFloaterBySession(session_id);
472 if(!floater) 503 if(!floater)
473 { 504 {
474 // On creation, use the first element of ids as the "other_participant_id" 505 // On creation, use the first element of ids as the "other_participant_id"
475 floater = createFloater(new_session_id, other_participant_id, name, dialog, TRUE); 506 floater = createFloater(session_id,
507 other_participant_id,
508 name,
509 ids,
510 dialog,
511 TRUE);
476 noteOfflineUsers(floater, ids); 512 noteOfflineUsers(floater, ids);
477 } 513 }
478 floater->addParticipants(ids);
479 mTalkFloater->showFloater(floater); 514 mTalkFloater->showFloater(floater);
480 //mTabContainer->selectTabPanel(panel); 515 //mTabContainer->selectTabPanel(panel);
481 floater->setInputFocus(TRUE); 516 floater->setInputFocus(TRUE);
@@ -518,8 +553,7 @@ void LLIMView::refresh()
518 group; 553 group;
519 group = group_list.getNextData()) 554 group = group_list.getNextData())
520 { 555 {
521 mNewIMFloater->addTarget(group->mID, group->mName, 556 mNewIMFloater->addGroup(group->mID, (void*)(&GROUP_DIALOG), TRUE, FALSE);
522 (void*)(&GROUP_DIALOG), TRUE, FALSE);
523 } 557 }
524 558
525 // build a set of buddies in the current buddy list. 559 // build a set of buddies in the current buddy list.
@@ -539,13 +573,6 @@ void LLIMView::refresh()
539 { 573 {
540 mNewIMFloater->addAgent((*it).second, (void*)(&DEFAULT_DIALOG), FALSE); 574 mNewIMFloater->addAgent((*it).second, (void*)(&DEFAULT_DIALOG), FALSE);
541 } 575 }
542
543 if(gAgent.isGodlike())
544 {
545 // XUI:translate
546 mNewIMFloater->addTarget(LLUUID::null, "All Residents, All Grids",
547 (void*)(&EVERYONE_DIALOG), TRUE, FALSE);
548 }
549 576
550 mNewIMFloater->setScrollPos( old_scroll_pos ); 577 mNewIMFloater->setScrollPos( old_scroll_pos );
551} 578}
@@ -619,12 +646,17 @@ void LLIMView::disconnectAllSessions()
619 std::set<LLViewHandle>::iterator handle_it; 646 std::set<LLViewHandle>::iterator handle_it;
620 for(handle_it = mFloaters.begin(); 647 for(handle_it = mFloaters.begin();
621 handle_it != mFloaters.end(); 648 handle_it != mFloaters.end();
622 ++handle_it) 649 )
623 { 650 {
624 floater = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*handle_it); 651 floater = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*handle_it);
652
653 // MUST do this BEFORE calling floater->onClose() because that may remove the item from the set, causing the subsequent increment to crash.
654 ++handle_it;
655
625 if (floater) 656 if (floater)
626 { 657 {
627 floater->setEnabled(FALSE); 658 floater->setEnabled(FALSE);
659 floater->onClose(TRUE);
628 } 660 }
629 } 661 }
630} 662}
@@ -662,11 +694,12 @@ BOOL LLIMView::hasSession(const LLUUID& session_id)
662// consistency. Returns the pointer, caller (the class instance since 694// consistency. Returns the pointer, caller (the class instance since
663// it is a private method) is not responsible for deleting the 695// it is a private method) is not responsible for deleting the
664// pointer. Add the floater to this but do not select it. 696// pointer. Add the floater to this but do not select it.
665LLFloaterIMPanel* LLIMView::createFloater(const LLUUID& session_id, 697LLFloaterIMPanel* LLIMView::createFloater(
666 const LLUUID& other_participant_id, 698 const LLUUID& session_id,
667 const std::string& session_label, 699 const LLUUID& other_participant_id,
668 EInstantMessage dialog, 700 const std::string& session_label,
669 BOOL user_initiated) 701 EInstantMessage dialog,
702 BOOL user_initiated)
670{ 703{
671 if (session_id.isNull()) 704 if (session_id.isNull())
672 { 705 {
@@ -686,6 +719,33 @@ LLFloaterIMPanel* LLIMView::createFloater(const LLUUID& session_id,
686 return floater; 719 return floater;
687} 720}
688 721
722LLFloaterIMPanel* LLIMView::createFloater(
723 const LLUUID& session_id,
724 const LLUUID& other_participant_id,
725 const std::string& session_label,
726 const LLDynamicArray<LLUUID>& ids,
727 EInstantMessage dialog,
728 BOOL user_initiated)
729{
730 if (session_id.isNull())
731 {
732 llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
733 }
734 llinfos << "LLIMView::createFloater: from " << other_participant_id
735 << " in session " << session_id << llendl;
736 LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
737 LLRect(),
738 session_label,
739 session_id,
740 other_participant_id,
741 ids,
742 dialog);
743 LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END;
744 mTalkFloater->addFloater(floater, FALSE, i_pt);
745 mFloaters.insert(floater->getHandle());
746 return floater;
747}
748
689void LLIMView::noteOfflineUsers(LLFloaterIMPanel* floater, 749void LLIMView::noteOfflineUsers(LLFloaterIMPanel* floater,
690 const LLDynamicArray<LLUUID>& ids) 750 const LLDynamicArray<LLUUID>& ids)
691{ 751{
@@ -734,3 +794,159 @@ void LLIMView::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
734 floater->processIMTyping(im_info, typing); 794 floater->processIMTyping(im_info, typing);
735 } 795 }
736} 796}
797
798void LLIMView::updateFloaterSessionID(const LLUUID& old_session_id,
799 const LLUUID& new_session_id)
800{
801 LLFloaterIMPanel* floater = findFloaterBySession(old_session_id);
802 if (floater)
803 {
804 floater->sessionInitReplyReceived(new_session_id);
805 }
806}
807
808void onConfirmForceCloseError(S32 option, void* data)
809{
810 //only 1 option really
811 LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data);
812
813 if ( floater ) floater->onClose(FALSE);
814}
815
816class LLViewerIMSessionStartReply : public LLHTTPNode
817{
818public:
819 virtual void describe(Description& desc) const
820 {
821 desc.shortInfo("Used for receiving a reply to a request to initialize an IM session");
822 desc.postAPI();
823 desc.input(
824 "{\"client_session_id\": UUID, \"session_id\": UUID, \"success\" boolean, \"reason\": string");
825 desc.source(__FILE__, __LINE__);
826 }
827
828 virtual void post(ResponsePtr response,
829 const LLSD& context,
830 const LLSD& input) const
831 {
832 LLSD body;
833 LLUUID temp_session_id;
834 LLUUID session_id;
835 bool success;
836
837 body = input["body"];
838 success = body["success"].asBoolean();
839 temp_session_id = body["temp_session_id"].asUUID();
840
841 if ( success )
842 {
843 session_id = body["session_id"].asUUID();
844 gIMView->updateFloaterSessionID(temp_session_id,
845 session_id);
846 }
847 else
848 {
849 //throw an error dialog and close the temp session's
850 //floater
851 LLFloaterIMPanel* floater =
852 gIMView->findFloaterBySession(temp_session_id);
853 if (floater)
854 {
855 LLString::format_map_t args;
856 args["[REASON]"] =
857 sErrorStringsMap[body["error"].asString()];
858 args["[RECIPIENT]"] = floater->getTitle();
859
860 gViewerWindow->alertXml("IMSessionStartError",
861 args,
862 onConfirmForceCloseError,
863 floater);
864
865 }
866 }
867 }
868};
869
870class LLViewerIMSessionEventReply : public LLHTTPNode
871{
872 public:
873 virtual void describe(Description& desc) const
874 {
875 desc.shortInfo("Used for receiving a reply to a IM session event");
876 desc.postAPI();
877 desc.input(
878 "{\"event\": string, \"reason\": string, \"success\": boolean, \"session_id\": UUID");
879 desc.source(__FILE__, __LINE__);
880 }
881
882 virtual void post(ResponsePtr response,
883 const LLSD& context,
884 const LLSD& input) const
885 {
886 LLUUID session_id;
887 bool success;
888
889 LLSD body = input["body"];
890 success = body["success"].asBoolean();
891 session_id = body["session_id"].asUUID();
892
893 if ( !success )
894 {
895 //throw an error dialog
896 LLFloaterIMPanel* floater =
897 gIMView->findFloaterBySession(session_id);
898 if (floater)
899 {
900 LLString::format_map_t args;
901 args["[REASON]"] =
902 sErrorStringsMap[body["error"].asString()];
903 args["[EVENT]"] =
904 sEventStringsMap[body["event"].asString()];
905 args["[RECIPIENT]"] = floater->getTitle();
906
907 gViewerWindow->alertXml("IMSessionEventError",
908 args);
909 }
910 }
911 }
912};
913
914class LLViewerForceCloseIMSession: public LLHTTPNode
915{
916
917 virtual void post(ResponsePtr response,
918 const LLSD& context,
919 const LLSD& input) const
920 {
921 LLUUID session_id;
922 LLString reason;
923
924 session_id = input["body"]["session_id"].asUUID();
925 reason = input["body"]["reason"].asString();
926
927 LLFloaterIMPanel* floater =
928 gIMView ->findFloaterBySession(session_id);
929
930 if ( floater )
931 {
932 LLString::format_map_t args;
933
934 args["[NAME]"] = floater->getTitle();
935 args["[REASON]"] = sForceCloseSessionMap[reason];
936
937 gViewerWindow->alertXml("ForceCloseIMSession",
938 args,
939 onConfirmForceCloseError,
940 floater);
941 }
942 }
943};
944
945LLHTTPRegistration<LLViewerIMSessionStartReply>
946 gHTTPRegistrationMessageImsessionstartreply("/message/IMSessionStartReply");
947
948LLHTTPRegistration<LLViewerIMSessionEventReply>
949 gHTTPRegistrationMessageImsessioneventreply("/message/IMSessionEventReply");
950
951LLHTTPRegistration<LLViewerForceCloseIMSession>
952 gHTTPRegistrationMessageForceCloseImSession("/message/ForceCloseIMSession");