diff options
author | Jacek Antonelli | 2008-08-15 23:45:27 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:27 -0500 |
commit | a8a62201ba762e98dff92cf49033e577fc34d8d4 (patch) | |
tree | 11f8513c5cdc222f2fac0c93eb724c089803c200 /linden/indra/newview/llimpanel.cpp | |
parent | Second Life viewer sources 1.18.6.4-RC (diff) | |
download | meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.zip meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.gz meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.bz2 meta-impy-a8a62201ba762e98dff92cf49033e577fc34d8d4.tar.xz |
Second Life viewer sources 1.19.0.0
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llimpanel.cpp | 530 |
1 files changed, 399 insertions, 131 deletions
diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp index 2307912..b80b80b 100644 --- a/linden/indra/newview/llimpanel.cpp +++ b/linden/indra/newview/llimpanel.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
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://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -63,6 +63,7 @@ | |||
63 | #include "llviewerstats.h" | 63 | #include "llviewerstats.h" |
64 | #include "llviewercontrol.h" | 64 | #include "llviewercontrol.h" |
65 | #include "llvieweruictrlfactory.h" | 65 | #include "llvieweruictrlfactory.h" |
66 | #include "llviewerwindow.h" | ||
66 | #include "lllogchat.h" | 67 | #include "lllogchat.h" |
67 | #include "llfloaterhtml.h" | 68 | #include "llfloaterhtml.h" |
68 | #include "llweb.h" | 69 | #include "llweb.h" |
@@ -92,10 +93,14 @@ static LLString sSessionStartString = "Starting session with [NAME] please wait. | |||
92 | LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap; | 93 | LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap; |
93 | LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap; | 94 | LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap; |
94 | LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL; | 95 | LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL; |
96 | LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; | ||
95 | 97 | ||
96 | void session_starter_helper(const LLUUID& temp_session_id, | 98 | BOOL LLVoiceChannel::sSuspended = FALSE; |
97 | const LLUUID& other_participant_id, | 99 | |
98 | EInstantMessage im_type) | 100 | void session_starter_helper( |
101 | const LLUUID& temp_session_id, | ||
102 | const LLUUID& other_participant_id, | ||
103 | EInstantMessage im_type) | ||
99 | { | 104 | { |
100 | LLMessageSystem *msg = gMessageSystem; | 105 | LLMessageSystem *msg = gMessageSystem; |
101 | 106 | ||
@@ -122,47 +127,111 @@ void session_starter_helper(const LLUUID& temp_session_id, | |||
122 | msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); | 127 | msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); |
123 | } | 128 | } |
124 | 129 | ||
130 | void start_deprecated_conference_chat( | ||
131 | const LLUUID& temp_session_id, | ||
132 | const LLUUID& creator_id, | ||
133 | const LLUUID& other_participant_id, | ||
134 | const LLSD& agents_to_invite) | ||
135 | { | ||
136 | U8* bucket; | ||
137 | U8* pos; | ||
138 | S32 count; | ||
139 | S32 bucket_size; | ||
140 | |||
141 | // *FIX: this could suffer from endian issues | ||
142 | count = agents_to_invite.size(); | ||
143 | bucket_size = UUID_BYTES * count; | ||
144 | bucket = new U8[bucket_size]; | ||
145 | pos = bucket; | ||
146 | |||
147 | for(S32 i = 0; i < count; ++i) | ||
148 | { | ||
149 | LLUUID agent_id = agents_to_invite[i].asUUID(); | ||
150 | |||
151 | memcpy(pos, &agent_id, UUID_BYTES); | ||
152 | pos += UUID_BYTES; | ||
153 | } | ||
154 | |||
155 | session_starter_helper( | ||
156 | temp_session_id, | ||
157 | other_participant_id, | ||
158 | IM_SESSION_CONFERENCE_START); | ||
159 | |||
160 | gMessageSystem->addBinaryDataFast( | ||
161 | _PREHASH_BinaryBucket, | ||
162 | bucket, | ||
163 | bucket_size); | ||
164 | |||
165 | gAgent.sendReliableMessage(); | ||
166 | |||
167 | delete[] bucket; | ||
168 | } | ||
169 | |||
170 | class LLStartConferenceChatResponder : public LLHTTPClient::Responder | ||
171 | { | ||
172 | public: | ||
173 | LLStartConferenceChatResponder( | ||
174 | const LLUUID& temp_session_id, | ||
175 | const LLUUID& creator_id, | ||
176 | const LLUUID& other_participant_id, | ||
177 | const LLSD& agents_to_invite) | ||
178 | { | ||
179 | mTempSessionID = temp_session_id; | ||
180 | mCreatorID = creator_id; | ||
181 | mOtherParticipantID = other_participant_id; | ||
182 | mAgents = agents_to_invite; | ||
183 | } | ||
184 | |||
185 | virtual void error(U32 statusNum, const std::string& reason) | ||
186 | { | ||
187 | //try an "old school" way. | ||
188 | if ( statusNum == 400 ) | ||
189 | { | ||
190 | start_deprecated_conference_chat( | ||
191 | mTempSessionID, | ||
192 | mCreatorID, | ||
193 | mOtherParticipantID, | ||
194 | mAgents); | ||
195 | } | ||
196 | |||
197 | //else throw an error back to the client? | ||
198 | //in theory we should have just have these error strings | ||
199 | //etc. set up in this file as opposed to the IMMgr, | ||
200 | //but the error string were unneeded here previously | ||
201 | //and it is not worth the effort switching over all | ||
202 | //the possible different language translations | ||
203 | } | ||
204 | |||
205 | private: | ||
206 | LLUUID mTempSessionID; | ||
207 | LLUUID mCreatorID; | ||
208 | LLUUID mOtherParticipantID; | ||
209 | |||
210 | LLSD mAgents; | ||
211 | }; | ||
212 | |||
125 | // Returns true if any messages were sent, false otherwise. | 213 | // Returns true if any messages were sent, false otherwise. |
126 | // Is sort of equivalent to "does the server need to do anything?" | 214 | // Is sort of equivalent to "does the server need to do anything?" |
127 | bool send_start_session_messages(const LLUUID& temp_session_id, | 215 | bool send_start_session_messages( |
128 | const LLUUID& other_participant_id, | 216 | const LLUUID& temp_session_id, |
129 | const LLDynamicArray<LLUUID>& ids, | 217 | const LLUUID& other_participant_id, |
130 | EInstantMessage dialog) | 218 | const LLDynamicArray<LLUUID>& ids, |
219 | EInstantMessage dialog) | ||
131 | { | 220 | { |
132 | if ( (dialog == IM_SESSION_GROUP_START) || | 221 | if ( dialog == IM_SESSION_GROUP_START ) |
133 | (dialog == IM_SESSION_CONFERENCE_START) ) | ||
134 | { | 222 | { |
135 | S32 count = ids.size(); | 223 | session_starter_helper( |
136 | S32 bucket_size = UUID_BYTES * count; | 224 | temp_session_id, |
137 | U8* bucket; | 225 | other_participant_id, |
138 | U8* pos; | 226 | dialog); |
139 | |||
140 | session_starter_helper(temp_session_id, | ||
141 | other_participant_id, | ||
142 | dialog); | ||
143 | 227 | ||
144 | switch(dialog) | 228 | switch(dialog) |
145 | { | 229 | { |
146 | case IM_SESSION_GROUP_START: | 230 | case IM_SESSION_GROUP_START: |
147 | gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket, | 231 | gMessageSystem->addBinaryDataFast( |
148 | EMPTY_BINARY_BUCKET, | 232 | _PREHASH_BinaryBucket, |
149 | EMPTY_BINARY_BUCKET_SIZE); | 233 | EMPTY_BINARY_BUCKET, |
150 | break; | 234 | EMPTY_BINARY_BUCKET_SIZE); |
151 | case IM_SESSION_CONFERENCE_START: | ||
152 | bucket = new U8[bucket_size]; | ||
153 | pos = bucket; | ||
154 | |||
155 | // *FIX: this could suffer from endian issues | ||
156 | for(S32 i = 0; i < count; ++i) | ||
157 | { | ||
158 | memcpy(pos, &(ids.get(i)), UUID_BYTES); | ||
159 | pos += UUID_BYTES; | ||
160 | } | ||
161 | gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket, | ||
162 | bucket, | ||
163 | bucket_size); | ||
164 | delete[] bucket; | ||
165 | |||
166 | break; | 235 | break; |
167 | default: | 236 | default: |
168 | break; | 237 | break; |
@@ -171,6 +240,44 @@ bool send_start_session_messages(const LLUUID& temp_session_id, | |||
171 | 240 | ||
172 | return true; | 241 | return true; |
173 | } | 242 | } |
243 | else if ( dialog == IM_SESSION_CONFERENCE_START ) | ||
244 | { | ||
245 | LLSD agents; | ||
246 | for (int i = 0; i < (S32) ids.size(); i++) | ||
247 | { | ||
248 | agents.append(ids.get(i)); | ||
249 | } | ||
250 | |||
251 | //we have a new way of starting conference calls now | ||
252 | LLViewerRegion* region = gAgent.getRegion(); | ||
253 | if (region) | ||
254 | { | ||
255 | std::string url = region->getCapability( | ||
256 | "ChatSessionRequest"); | ||
257 | LLSD data; | ||
258 | data["method"] = "start conference"; | ||
259 | data["session-id"] = temp_session_id; | ||
260 | |||
261 | data["params"] = agents; | ||
262 | |||
263 | LLHTTPClient::post( | ||
264 | url, | ||
265 | data, | ||
266 | new LLStartConferenceChatResponder( | ||
267 | temp_session_id, | ||
268 | gAgent.getID(), | ||
269 | other_participant_id, | ||
270 | data["params"])); | ||
271 | } | ||
272 | else | ||
273 | { | ||
274 | start_deprecated_conference_chat( | ||
275 | temp_session_id, | ||
276 | gAgent.getID(), | ||
277 | other_participant_id, | ||
278 | agents); | ||
279 | } | ||
280 | } | ||
174 | 281 | ||
175 | return false; | 282 | return false; |
176 | } | 283 | } |
@@ -194,8 +301,21 @@ void LLVoiceCallCapResponder::error(U32 status, const std::string& reason) | |||
194 | << status << ": " << reason << ")" | 301 | << status << ": " << reason << ")" |
195 | << llendl; | 302 | << llendl; |
196 | LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); | 303 | LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); |
197 | if (channelp) | 304 | if ( channelp ) |
198 | { | 305 | { |
306 | if ( 403 == status ) | ||
307 | { | ||
308 | //403 == no ability | ||
309 | LLNotifyBox::showXml( | ||
310 | "VoiceNotAllowed", | ||
311 | channelp->getNotifyArgs()); | ||
312 | } | ||
313 | else | ||
314 | { | ||
315 | LLNotifyBox::showXml( | ||
316 | "VoiceCallGenericError", | ||
317 | channelp->getNotifyArgs()); | ||
318 | } | ||
199 | channelp->deactivate(); | 319 | channelp->deactivate(); |
200 | } | 320 | } |
201 | } | 321 | } |
@@ -242,10 +362,6 @@ LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const LLString& session | |||
242 | 362 | ||
243 | LLVoiceChannel::~LLVoiceChannel() | 363 | LLVoiceChannel::~LLVoiceChannel() |
244 | { | 364 | { |
245 | // CANNOT do this here, since it will crash on quit in the LLVoiceChannelProximal singleton destructor. | ||
246 | // Do it in all other subclass destructors instead. | ||
247 | // deactivate(); | ||
248 | |||
249 | // Don't use LLVoiceClient::getInstance() here -- this can get called during atexit() time and that singleton MAY have already been destroyed. | 365 | // Don't use LLVoiceClient::getInstance() here -- this can get called during atexit() time and that singleton MAY have already been destroyed. |
250 | if(gVoiceClient) | 366 | if(gVoiceClient) |
251 | { | 367 | { |
@@ -266,7 +382,19 @@ void LLVoiceChannel::setChannelInfo( | |||
266 | 382 | ||
267 | if (mState == STATE_NO_CHANNEL_INFO) | 383 | if (mState == STATE_NO_CHANNEL_INFO) |
268 | { | 384 | { |
269 | if(!mURI.empty() && !mCredentials.empty()) | 385 | if (mURI.empty()) |
386 | { | ||
387 | LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs); | ||
388 | llwarns << "Received empty URI for channel " << mSessionName << llendl; | ||
389 | deactivate(); | ||
390 | } | ||
391 | else if (mCredentials.empty()) | ||
392 | { | ||
393 | LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs); | ||
394 | llwarns << "Received empty credentials for channel " << mSessionName << llendl; | ||
395 | deactivate(); | ||
396 | } | ||
397 | else | ||
270 | { | 398 | { |
271 | setState(STATE_READY); | 399 | setState(STATE_READY); |
272 | 400 | ||
@@ -279,12 +407,6 @@ void LLVoiceChannel::setChannelInfo( | |||
279 | activate(); | 407 | activate(); |
280 | } | 408 | } |
281 | } | 409 | } |
282 | else | ||
283 | { | ||
284 | //*TODO: notify user | ||
285 | llwarns << "Received invalid credentials for channel " << mSessionName << llendl; | ||
286 | deactivate(); | ||
287 | } | ||
288 | } | 410 | } |
289 | } | 411 | } |
290 | 412 | ||
@@ -325,7 +447,7 @@ void LLVoiceChannel::handleStatusChange(EStatusType type) | |||
325 | } | 447 | } |
326 | break; | 448 | break; |
327 | case STATUS_LEFT_CHANNEL: | 449 | case STATUS_LEFT_CHANNEL: |
328 | if (callStarted() && !mIgnoreNextSessionLeave) | 450 | if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) |
329 | { | 451 | { |
330 | // if forceably removed from channel | 452 | // if forceably removed from channel |
331 | // update the UI and revert to default channel | 453 | // update the UI and revert to default channel |
@@ -496,6 +618,38 @@ void LLVoiceChannel::initClass() | |||
496 | sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance(); | 618 | sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance(); |
497 | } | 619 | } |
498 | 620 | ||
621 | |||
622 | //static | ||
623 | void LLVoiceChannel::suspend() | ||
624 | { | ||
625 | if (!sSuspended) | ||
626 | { | ||
627 | sSuspendedVoiceChannel = sCurrentVoiceChannel; | ||
628 | sSuspended = TRUE; | ||
629 | } | ||
630 | } | ||
631 | |||
632 | //static | ||
633 | void LLVoiceChannel::resume() | ||
634 | { | ||
635 | if (sSuspended) | ||
636 | { | ||
637 | if (gVoiceClient->voiceEnabled()) | ||
638 | { | ||
639 | if (sSuspendedVoiceChannel) | ||
640 | { | ||
641 | sSuspendedVoiceChannel->activate(); | ||
642 | } | ||
643 | else | ||
644 | { | ||
645 | LLVoiceChannelProximal::getInstance()->activate(); | ||
646 | } | ||
647 | } | ||
648 | sSuspended = FALSE; | ||
649 | } | ||
650 | } | ||
651 | |||
652 | |||
499 | // | 653 | // |
500 | // LLVoiceChannelGroup | 654 | // LLVoiceChannelGroup |
501 | // | 655 | // |
@@ -507,11 +661,6 @@ LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID& session_id, const LLStrin | |||
507 | mIsRetrying = FALSE; | 661 | mIsRetrying = FALSE; |
508 | } | 662 | } |
509 | 663 | ||
510 | LLVoiceChannelGroup::~LLVoiceChannelGroup() | ||
511 | { | ||
512 | deactivate(); | ||
513 | } | ||
514 | |||
515 | void LLVoiceChannelGroup::deactivate() | 664 | void LLVoiceChannelGroup::deactivate() |
516 | { | 665 | { |
517 | if (callStarted()) | 666 | if (callStarted()) |
@@ -635,6 +784,7 @@ void LLVoiceChannelGroup::handleError(EStatusType status) | |||
635 | } | 784 | } |
636 | 785 | ||
637 | break; | 786 | break; |
787 | |||
638 | case ERROR_UNKNOWN: | 788 | case ERROR_UNKNOWN: |
639 | default: | 789 | default: |
640 | break; | 790 | break; |
@@ -677,11 +827,6 @@ LLVoiceChannelProximal::LLVoiceChannelProximal() : | |||
677 | activate(); | 827 | activate(); |
678 | } | 828 | } |
679 | 829 | ||
680 | LLVoiceChannelProximal::~LLVoiceChannelProximal() | ||
681 | { | ||
682 | // DO NOT call deactivate() here, since this will only happen at atexit() time. | ||
683 | } | ||
684 | |||
685 | BOOL LLVoiceChannelProximal::isActive() | 830 | BOOL LLVoiceChannelProximal::isActive() |
686 | { | 831 | { |
687 | return callStarted() && LLVoiceClient::getInstance()->inProximalChannel(); | 832 | return callStarted() && LLVoiceClient::getInstance()->inProximalChannel(); |
@@ -725,6 +870,9 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status) | |||
725 | case STATUS_LEFT_CHANNEL: | 870 | case STATUS_LEFT_CHANNEL: |
726 | // do not notify user when leaving proximal channel | 871 | // do not notify user when leaving proximal channel |
727 | return; | 872 | return; |
873 | case STATUS_VOICE_DISABLED: | ||
874 | gIMMgr->addSystemMessage(LLUUID::null, "unavailable", mNotifyArgs); | ||
875 | return; | ||
728 | default: | 876 | default: |
729 | break; | 877 | break; |
730 | } | 878 | } |
@@ -762,29 +910,26 @@ void LLVoiceChannelProximal::deactivate() | |||
762 | } | 910 | } |
763 | } | 911 | } |
764 | 912 | ||
913 | |||
765 | // | 914 | // |
766 | // LLVoiceChannelP2P | 915 | // LLVoiceChannelP2P |
767 | // | 916 | // |
768 | LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const LLString& session_name, const LLUUID& other_user_id) : | 917 | LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const LLString& session_name, const LLUUID& other_user_id) : |
769 | LLVoiceChannelGroup(session_id, session_name), | 918 | LLVoiceChannelGroup(session_id, session_name), |
770 | mOtherUserID(other_user_id) | 919 | mOtherUserID(other_user_id), |
920 | mReceivedCall(FALSE) | ||
771 | { | 921 | { |
772 | // make sure URI reflects encoded version of other user's agent id | 922 | // make sure URI reflects encoded version of other user's agent id |
773 | setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id)); | 923 | setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id)); |
774 | } | 924 | } |
775 | 925 | ||
776 | LLVoiceChannelP2P::~LLVoiceChannelP2P() | ||
777 | { | ||
778 | deactivate(); | ||
779 | } | ||
780 | |||
781 | void LLVoiceChannelP2P::handleStatusChange(EStatusType type) | 926 | void LLVoiceChannelP2P::handleStatusChange(EStatusType type) |
782 | { | 927 | { |
783 | // status updates | 928 | // status updates |
784 | switch(type) | 929 | switch(type) |
785 | { | 930 | { |
786 | case STATUS_LEFT_CHANNEL: | 931 | case STATUS_LEFT_CHANNEL: |
787 | if (callStarted() && !mIgnoreNextSessionLeave) | 932 | if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) |
788 | { | 933 | { |
789 | if (mState == STATE_RINGING) | 934 | if (mState == STATE_RINGING) |
790 | { | 935 | { |
@@ -832,6 +977,7 @@ void LLVoiceChannelP2P::activate() | |||
832 | // no session handle yet, we're starting the call | 977 | // no session handle yet, we're starting the call |
833 | if (mSessionHandle.empty()) | 978 | if (mSessionHandle.empty()) |
834 | { | 979 | { |
980 | mReceivedCall = FALSE; | ||
835 | LLVoiceClient::getInstance()->callUser(mOtherUserID); | 981 | LLVoiceClient::getInstance()->callUser(mOtherUserID); |
836 | } | 982 | } |
837 | // otherwise answering the call | 983 | // otherwise answering the call |
@@ -879,24 +1025,37 @@ void LLVoiceChannelP2P::setSessionHandle(const LLString& handle) | |||
879 | mSessionHandle = handle; | 1025 | mSessionHandle = handle; |
880 | // The URI of a p2p session should always be the other end's SIP URI. | 1026 | // The URI of a p2p session should always be the other end's SIP URI. |
881 | setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); | 1027 | setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); |
882 | 1028 | mReceivedCall = TRUE; | |
1029 | |||
883 | if (needs_activate) | 1030 | if (needs_activate) |
884 | { | 1031 | { |
885 | activate(); | 1032 | activate(); |
886 | } | 1033 | } |
887 | } | 1034 | } |
888 | 1035 | ||
1036 | void LLVoiceChannelP2P::setState(EState state) | ||
1037 | { | ||
1038 | // you only "answer" voice invites in p2p mode | ||
1039 | // so provide a special purpose message here | ||
1040 | if (mReceivedCall && state == STATE_RINGING) | ||
1041 | { | ||
1042 | gIMMgr->addSystemMessage(mSessionID, "answering", mNotifyArgs); | ||
1043 | mState = state; | ||
1044 | return; | ||
1045 | } | ||
1046 | LLVoiceChannel::setState(state); | ||
1047 | } | ||
1048 | |||
1049 | |||
889 | // | 1050 | // |
890 | // LLFloaterIMPanel | 1051 | // LLFloaterIMPanel |
891 | // | 1052 | // |
892 | LLFloaterIMPanel::LLFloaterIMPanel( | 1053 | LLFloaterIMPanel::LLFloaterIMPanel( |
893 | const std::string& name, | ||
894 | const LLRect& rect, | ||
895 | const std::string& session_label, | 1054 | const std::string& session_label, |
896 | const LLUUID& session_id, | 1055 | const LLUUID& session_id, |
897 | const LLUUID& other_participant_id, | 1056 | const LLUUID& other_participant_id, |
898 | EInstantMessage dialog) : | 1057 | EInstantMessage dialog) : |
899 | LLFloater(name, rect, session_label), | 1058 | LLFloater(session_label, LLRect(), session_label), |
900 | mInputEditor(NULL), | 1059 | mInputEditor(NULL), |
901 | mHistoryEditor(NULL), | 1060 | mHistoryEditor(NULL), |
902 | mSessionUUID(session_id), | 1061 | mSessionUUID(session_id), |
@@ -909,6 +1068,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( | |||
909 | mOtherTyping(FALSE), | 1068 | mOtherTyping(FALSE), |
910 | mTypingLineStartIndex(0), | 1069 | mTypingLineStartIndex(0), |
911 | mSentTypingState(TRUE), | 1070 | mSentTypingState(TRUE), |
1071 | mNumUnreadMessages(0), | ||
912 | mShowSpeakersOnConnect(TRUE), | 1072 | mShowSpeakersOnConnect(TRUE), |
913 | mAutoConnect(FALSE), | 1073 | mAutoConnect(FALSE), |
914 | mSpeakerPanel(NULL), | 1074 | mSpeakerPanel(NULL), |
@@ -919,14 +1079,12 @@ LLFloaterIMPanel::LLFloaterIMPanel( | |||
919 | } | 1079 | } |
920 | 1080 | ||
921 | LLFloaterIMPanel::LLFloaterIMPanel( | 1081 | LLFloaterIMPanel::LLFloaterIMPanel( |
922 | const std::string& name, | ||
923 | const LLRect& rect, | ||
924 | const std::string& session_label, | 1082 | const std::string& session_label, |
925 | const LLUUID& session_id, | 1083 | const LLUUID& session_id, |
926 | const LLUUID& other_participant_id, | 1084 | const LLUUID& other_participant_id, |
927 | const LLDynamicArray<LLUUID>& ids, | 1085 | const LLDynamicArray<LLUUID>& ids, |
928 | EInstantMessage dialog) : | 1086 | EInstantMessage dialog) : |
929 | LLFloater(name, rect, session_label), | 1087 | LLFloater(session_label, LLRect(), session_label), |
930 | mInputEditor(NULL), | 1088 | mInputEditor(NULL), |
931 | mHistoryEditor(NULL), | 1089 | mHistoryEditor(NULL), |
932 | mSessionUUID(session_id), | 1090 | mSessionUUID(session_id), |
@@ -952,13 +1110,15 @@ LLFloaterIMPanel::LLFloaterIMPanel( | |||
952 | 1110 | ||
953 | void LLFloaterIMPanel::init(const LLString& session_label) | 1111 | void LLFloaterIMPanel::init(const LLString& session_label) |
954 | { | 1112 | { |
1113 | mSessionLabel = session_label; | ||
1114 | |||
955 | LLString xml_filename; | 1115 | LLString xml_filename; |
956 | switch(mDialog) | 1116 | switch(mDialog) |
957 | { | 1117 | { |
958 | case IM_SESSION_GROUP_START: | 1118 | case IM_SESSION_GROUP_START: |
959 | mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); | 1119 | mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); |
960 | xml_filename = "floater_instant_message_group.xml"; | 1120 | xml_filename = "floater_instant_message_group.xml"; |
961 | mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label); | 1121 | mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel); |
962 | break; | 1122 | break; |
963 | case IM_SESSION_INVITE: | 1123 | case IM_SESSION_INVITE: |
964 | mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); | 1124 | mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); |
@@ -970,21 +1130,21 @@ void LLFloaterIMPanel::init(const LLString& session_label) | |||
970 | { | 1130 | { |
971 | xml_filename = "floater_instant_message_ad_hoc.xml"; | 1131 | xml_filename = "floater_instant_message_ad_hoc.xml"; |
972 | } | 1132 | } |
973 | mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label); | 1133 | mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel); |
974 | break; | 1134 | break; |
975 | case IM_SESSION_P2P_INVITE: | 1135 | case IM_SESSION_P2P_INVITE: |
976 | xml_filename = "floater_instant_message.xml"; | 1136 | xml_filename = "floater_instant_message.xml"; |
977 | mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, session_label, mOtherParticipantUUID); | 1137 | mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID); |
978 | break; | 1138 | break; |
979 | case IM_SESSION_CONFERENCE_START: | 1139 | case IM_SESSION_CONFERENCE_START: |
980 | mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); | 1140 | mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); |
981 | xml_filename = "floater_instant_message_ad_hoc.xml"; | 1141 | xml_filename = "floater_instant_message_ad_hoc.xml"; |
982 | mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label); | 1142 | mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel); |
983 | break; | 1143 | break; |
984 | // just received text from another user | 1144 | // just received text from another user |
985 | case IM_NOTHING_SPECIAL: | 1145 | case IM_NOTHING_SPECIAL: |
986 | xml_filename = "floater_instant_message.xml"; | 1146 | xml_filename = "floater_instant_message.xml"; |
987 | mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, session_label, mOtherParticipantUUID); | 1147 | mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID); |
988 | break; | 1148 | break; |
989 | default: | 1149 | default: |
990 | llwarns << "Unknown session type" << llendl; | 1150 | llwarns << "Unknown session type" << llendl; |
@@ -999,15 +1159,14 @@ void LLFloaterIMPanel::init(const LLString& session_label) | |||
999 | &getFactoryMap(), | 1159 | &getFactoryMap(), |
1000 | FALSE); | 1160 | FALSE); |
1001 | 1161 | ||
1002 | setLabel(session_label); | 1162 | setTitle(mSessionLabel); |
1003 | setTitle(session_label); | ||
1004 | mInputEditor->setMaxTextLength(1023); | 1163 | mInputEditor->setMaxTextLength(1023); |
1005 | // enable line history support for instant message bar | 1164 | // enable line history support for instant message bar |
1006 | mInputEditor->setEnableLineHistory(TRUE); | 1165 | mInputEditor->setEnableLineHistory(TRUE); |
1007 | 1166 | ||
1008 | if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) | 1167 | if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) |
1009 | { | 1168 | { |
1010 | LLLogChat::loadHistory(session_label, | 1169 | LLLogChat::loadHistory(mSessionLabel, |
1011 | &chatFromLogFile, | 1170 | &chatFromLogFile, |
1012 | (void *)this); | 1171 | (void *)this); |
1013 | } | 1172 | } |
@@ -1060,16 +1219,12 @@ BOOL LLFloaterIMPanel::postBuild() | |||
1060 | { | 1219 | { |
1061 | requires("chat_editor", WIDGET_TYPE_LINE_EDITOR); | 1220 | requires("chat_editor", WIDGET_TYPE_LINE_EDITOR); |
1062 | requires("im_history", WIDGET_TYPE_TEXT_EDITOR); | 1221 | requires("im_history", WIDGET_TYPE_TEXT_EDITOR); |
1063 | requires("live_help_dialog", WIDGET_TYPE_TEXT_BOX); | ||
1064 | requires("title_string", WIDGET_TYPE_TEXT_BOX); | ||
1065 | requires("typing_start_string", WIDGET_TYPE_TEXT_BOX); | ||
1066 | requires("session_start_string", WIDGET_TYPE_TEXT_BOX); | ||
1067 | 1222 | ||
1068 | if (checkRequirements()) | 1223 | if (checkRequirements()) |
1069 | { | 1224 | { |
1070 | mInputEditor = LLUICtrlFactory::getLineEditorByName(this, "chat_editor"); | 1225 | mInputEditor = LLUICtrlFactory::getLineEditorByName(this, "chat_editor"); |
1071 | mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived ); | 1226 | mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this ); |
1072 | mInputEditor->setFocusLostCallback( onInputEditorFocusLost ); | 1227 | mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this ); |
1073 | mInputEditor->setKeystrokeCallback( onInputEditorKeystroke ); | 1228 | mInputEditor->setKeystrokeCallback( onInputEditorKeystroke ); |
1074 | mInputEditor->setCommitCallback( onCommitChat ); | 1229 | mInputEditor->setCommitCallback( onCommitChat ); |
1075 | mInputEditor->setCallbackUserData(this); | 1230 | mInputEditor->setCallbackUserData(this); |
@@ -1084,6 +1239,7 @@ BOOL LLFloaterIMPanel::postBuild() | |||
1084 | childSetAction("send_btn", onClickSend, this); | 1239 | childSetAction("send_btn", onClickSend, this); |
1085 | childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); | 1240 | childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); |
1086 | 1241 | ||
1242 | childSetAction("moderator_kick_speaker", onKickSpeaker, this); | ||
1087 | //LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn"); | 1243 | //LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn"); |
1088 | //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); | 1244 | //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); |
1089 | 1245 | ||
@@ -1094,17 +1250,11 @@ BOOL LLFloaterIMPanel::postBuild() | |||
1094 | { | 1250 | { |
1095 | childSetEnabled("profile_btn", FALSE); | 1251 | childSetEnabled("profile_btn", FALSE); |
1096 | } | 1252 | } |
1097 | LLTextBox* title = LLUICtrlFactory::getTextBoxByName(this, "title_string"); | 1253 | |
1098 | sTitleString = title->getText(); | 1254 | sTitleString = getFormattedUIString("title_string"); |
1099 | 1255 | sTypingStartString = getFormattedUIString("typing_start_string"); | |
1100 | LLTextBox* typing_start = LLUICtrlFactory::getTextBoxByName(this, "typing_start_string"); | 1256 | sSessionStartString = getFormattedUIString("session_start_string"); |
1101 | 1257 | ||
1102 | sTypingStartString = typing_start->getText(); | ||
1103 | |||
1104 | LLTextBox* session_start = LLUICtrlFactory::getTextBoxByName( | ||
1105 | this, | ||
1106 | "session_start_string"); | ||
1107 | sSessionStartString = session_start->getText(); | ||
1108 | if (mSpeakerPanel) | 1258 | if (mSpeakerPanel) |
1109 | { | 1259 | { |
1110 | mSpeakerPanel->refreshSpeakers(); | 1260 | mSpeakerPanel->refreshSpeakers(); |
@@ -1112,7 +1262,7 @@ BOOL LLFloaterIMPanel::postBuild() | |||
1112 | 1262 | ||
1113 | if (mDialog == IM_NOTHING_SPECIAL) | 1263 | if (mDialog == IM_NOTHING_SPECIAL) |
1114 | { | 1264 | { |
1115 | childSetCommitCallback("mute_btn", onClickMuteVoice, this); | 1265 | childSetAction("mute_btn", onClickMuteVoice, this); |
1116 | childSetCommitCallback("speaker_volume", onVolumeChange, this); | 1266 | childSetCommitCallback("speaker_volume", onVolumeChange, this); |
1117 | } | 1267 | } |
1118 | 1268 | ||
@@ -1131,7 +1281,7 @@ void* LLFloaterIMPanel::createSpeakersPanel(void* data) | |||
1131 | } | 1281 | } |
1132 | 1282 | ||
1133 | //static | 1283 | //static |
1134 | void LLFloaterIMPanel::onClickMuteVoice(LLUICtrl* source, void* user_data) | 1284 | void LLFloaterIMPanel::onClickMuteVoice(void* user_data) |
1135 | { | 1285 | { |
1136 | LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data; | 1286 | LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data; |
1137 | if (floaterp) | 1287 | if (floaterp) |
@@ -1171,10 +1321,22 @@ void LLFloaterIMPanel::draw() | |||
1171 | && LLVoiceClient::voiceEnabled(); | 1321 | && LLVoiceClient::voiceEnabled(); |
1172 | 1322 | ||
1173 | // hide/show start call and end call buttons | 1323 | // hide/show start call and end call buttons |
1174 | childSetVisible("end_call_btn", mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); | 1324 | childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); |
1175 | childSetVisible("start_call_btn", mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED); | 1325 | childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED); |
1176 | childSetEnabled("start_call_btn", enable_connect); | 1326 | childSetEnabled("start_call_btn", enable_connect); |
1177 | childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty()); | 1327 | childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty()); |
1328 | |||
1329 | LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID()); | ||
1330 | if (self_speaker.notNull() && self_speaker->mModeratorMutedText) | ||
1331 | { | ||
1332 | mInputEditor->setEnabled(FALSE); | ||
1333 | mInputEditor->setLabel(getFormattedUIString("muted_text_label")); | ||
1334 | } | ||
1335 | else | ||
1336 | { | ||
1337 | mInputEditor->setEnabled(TRUE); | ||
1338 | mInputEditor->setLabel(getFormattedUIString("default_text_label")); | ||
1339 | } | ||
1178 | 1340 | ||
1179 | if (mAutoConnect && enable_connect) | 1341 | if (mAutoConnect && enable_connect) |
1180 | { | 1342 | { |
@@ -1215,11 +1377,11 @@ void LLFloaterIMPanel::draw() | |||
1215 | else | 1377 | else |
1216 | { | 1378 | { |
1217 | // refresh volume and mute checkbox | 1379 | // refresh volume and mute checkbox |
1218 | childSetEnabled("speaker_volume", mVoiceChannel->isActive()); | 1380 | childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive()); |
1219 | childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID)); | 1381 | childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID)); |
1220 | 1382 | ||
1221 | childSetValue("mute_btn", gMuteListp->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat)); | 1383 | childSetValue("mute_btn", gMuteListp->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat)); |
1222 | childSetEnabled("mute_btn", mVoiceChannel->isActive()); | 1384 | childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive()); |
1223 | } | 1385 | } |
1224 | LLFloater::draw(); | 1386 | LLFloater::draw(); |
1225 | } | 1387 | } |
@@ -1235,7 +1397,6 @@ public: | |||
1235 | void error(U32 statusNum, const std::string& reason) | 1397 | void error(U32 statusNum, const std::string& reason) |
1236 | { | 1398 | { |
1237 | llinfos << "Error inviting all agents to session" << llendl; | 1399 | llinfos << "Error inviting all agents to session" << llendl; |
1238 | |||
1239 | //throw something back to the viewer here? | 1400 | //throw something back to the viewer here? |
1240 | } | 1401 | } |
1241 | 1402 | ||
@@ -1272,8 +1433,8 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids) | |||
1272 | LLHTTPClient::post( | 1433 | LLHTTPClient::post( |
1273 | url, | 1434 | url, |
1274 | data, | 1435 | data, |
1275 | new LLSessionInviteResponder(mSessionUUID)); | 1436 | new LLSessionInviteResponder( |
1276 | 1437 | mSessionUUID)); | |
1277 | } | 1438 | } |
1278 | else | 1439 | else |
1279 | { | 1440 | { |
@@ -1289,6 +1450,15 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids) | |||
1289 | 1450 | ||
1290 | void LLFloaterIMPanel::addHistoryLine(const LLUUID& source, const std::string &utf8msg, const LLColor4& color, bool log_to_file) | 1451 | void LLFloaterIMPanel::addHistoryLine(const LLUUID& source, const std::string &utf8msg, const LLColor4& color, bool log_to_file) |
1291 | { | 1452 | { |
1453 | // start tab flashing when receiving im for background session from user | ||
1454 | LLMultiFloater* hostp = getHost(); | ||
1455 | if( !isInVisibleChain() | ||
1456 | && hostp | ||
1457 | && source != gAgent.getID()) | ||
1458 | { | ||
1459 | hostp->setFloaterFlashing(this, TRUE); | ||
1460 | } | ||
1461 | |||
1292 | addHistoryLine(utf8msg, color, log_to_file); | 1462 | addHistoryLine(utf8msg, color, log_to_file); |
1293 | mSpeakers->speakerChatted(source); | 1463 | mSpeakers->speakerChatted(source); |
1294 | mSpeakers->setSpeakerTyping(source, FALSE); | 1464 | mSpeakers->setSpeakerTyping(source, FALSE); |
@@ -1296,14 +1466,6 @@ void LLFloaterIMPanel::addHistoryLine(const LLUUID& source, const std::string &u | |||
1296 | 1466 | ||
1297 | void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file) | 1467 | void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file) |
1298 | { | 1468 | { |
1299 | LLMultiFloater* hostp = getHost(); | ||
1300 | if( !getVisible() && hostp && log_to_file) | ||
1301 | { | ||
1302 | // Only flash for logged ("real") messages | ||
1303 | LLTabContainer* parent = (LLTabContainer*) getParent(); | ||
1304 | parent->setTabPanelFlashing( this, TRUE ); | ||
1305 | } | ||
1306 | |||
1307 | // Now we're adding the actual line of text, so erase the | 1469 | // Now we're adding the actual line of text, so erase the |
1308 | // "Foo is typing..." text segment, and the optional timestamp | 1470 | // "Foo is typing..." text segment, and the optional timestamp |
1309 | // if it was present. JC | 1471 | // if it was present. JC |
@@ -1330,6 +1492,11 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 | |||
1330 | 1492 | ||
1331 | LLLogChat::saveHistory(getTitle(),histstr); | 1493 | LLLogChat::saveHistory(getTitle(),histstr); |
1332 | } | 1494 | } |
1495 | |||
1496 | if (!isInVisibleChain()) | ||
1497 | { | ||
1498 | mNumUnreadMessages++; | ||
1499 | } | ||
1333 | } | 1500 | } |
1334 | 1501 | ||
1335 | 1502 | ||
@@ -1340,10 +1507,7 @@ void LLFloaterIMPanel::setVisible(BOOL b) | |||
1340 | LLMultiFloater* hostp = getHost(); | 1507 | LLMultiFloater* hostp = getHost(); |
1341 | if( b && hostp ) | 1508 | if( b && hostp ) |
1342 | { | 1509 | { |
1343 | LLTabContainer* parent = (LLTabContainer*) getParent(); | 1510 | hostp->setFloaterFlashing(this, FALSE); |
1344 | |||
1345 | // When this tab is displayed, you can stop flashing. | ||
1346 | parent->setTabPanelFlashing( this, FALSE ); | ||
1347 | 1511 | ||
1348 | /* Don't change containing floater title - leave it "Instant Message" JC | 1512 | /* Don't change containing floater title - leave it "Instant Message" JC |
1349 | LLUIString title = sTitleString; | 1513 | LLUIString title = sTitleString; |
@@ -1392,7 +1556,7 @@ BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_paren | |||
1392 | else if ( KEY_ESCAPE == key ) | 1556 | else if ( KEY_ESCAPE == key ) |
1393 | { | 1557 | { |
1394 | handled = TRUE; | 1558 | handled = TRUE; |
1395 | gFocusMgr.setKeyboardFocus(NULL, NULL); | 1559 | gFocusMgr.setKeyboardFocus(NULL); |
1396 | 1560 | ||
1397 | // Close talk panel with escape | 1561 | // Close talk panel with escape |
1398 | if( !gSavedSettings.getBOOL("PinTalkViewOpen") ) | 1562 | if( !gSavedSettings.getBOOL("PinTalkViewOpen") ) |
@@ -1573,14 +1737,14 @@ void LLFloaterIMPanel::onCommitChat(LLUICtrl* caller, void* userdata) | |||
1573 | } | 1737 | } |
1574 | 1738 | ||
1575 | // static | 1739 | // static |
1576 | void LLFloaterIMPanel::onInputEditorFocusReceived( LLUICtrl* caller, void* userdata ) | 1740 | void LLFloaterIMPanel::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) |
1577 | { | 1741 | { |
1578 | LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata; | 1742 | LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata; |
1579 | self->mHistoryEditor->setCursorAndScrollToEnd(); | 1743 | self->mHistoryEditor->setCursorAndScrollToEnd(); |
1580 | } | 1744 | } |
1581 | 1745 | ||
1582 | // static | 1746 | // static |
1583 | void LLFloaterIMPanel::onInputEditorFocusLost(LLUICtrl* caller, void* userdata) | 1747 | void LLFloaterIMPanel::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) |
1584 | { | 1748 | { |
1585 | LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; | 1749 | LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; |
1586 | self->setTyping(FALSE); | 1750 | self->setTyping(FALSE); |
@@ -1628,6 +1792,14 @@ void LLFloaterIMPanel::onClose(bool app_quitting) | |||
1628 | destroy(); | 1792 | destroy(); |
1629 | } | 1793 | } |
1630 | 1794 | ||
1795 | void LLFloaterIMPanel::onVisibilityChange(BOOL new_visibility) | ||
1796 | { | ||
1797 | if (new_visibility) | ||
1798 | { | ||
1799 | mNumUnreadMessages = 0; | ||
1800 | } | ||
1801 | } | ||
1802 | |||
1631 | void deliver_message(const std::string& utf8_text, | 1803 | void deliver_message(const std::string& utf8_text, |
1632 | const LLUUID& im_session_id, | 1804 | const LLUUID& im_session_id, |
1633 | const LLUUID& other_participant_id, | 1805 | const LLUUID& other_participant_id, |
@@ -1739,19 +1911,37 @@ void LLFloaterIMPanel::sendMsg() | |||
1739 | mSentTypingState = TRUE; | 1911 | mSentTypingState = TRUE; |
1740 | } | 1912 | } |
1741 | 1913 | ||
1742 | void LLFloaterIMPanel::updateSpeakersList(LLSD speaker_updates) | 1914 | void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates) |
1743 | { | 1915 | { |
1744 | mSpeakers->processSpeakerListUpdate(speaker_updates); | 1916 | mSpeakers->updateSpeakers(speaker_updates); |
1745 | } | 1917 | } |
1746 | 1918 | ||
1747 | void LLFloaterIMPanel::setSpeakersListFromMap(LLSD speaker_map) | 1919 | void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update) |
1748 | { | 1920 | { |
1749 | mSpeakers->processSpeakerMap(speaker_map); | 1921 | if ( |
1922 | session_update.has("moderated_mode") && | ||
1923 | session_update["moderated_mode"].has("voice") ) | ||
1924 | { | ||
1925 | BOOL voice_moderated = session_update["moderated_mode"]["voice"]; | ||
1926 | |||
1927 | if (voice_moderated) | ||
1928 | { | ||
1929 | setTitle(mSessionLabel + LLString(" ") + getFormattedUIString("moderated_chat_label")); | ||
1930 | } | ||
1931 | else | ||
1932 | { | ||
1933 | setTitle(mSessionLabel); | ||
1934 | } | ||
1935 | |||
1936 | |||
1937 | //update the speakers dropdown too | ||
1938 | mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated); | ||
1939 | } | ||
1750 | } | 1940 | } |
1751 | 1941 | ||
1752 | void LLFloaterIMPanel::setSpeakersList(LLSD speaker_list) | 1942 | void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list) |
1753 | { | 1943 | { |
1754 | mSpeakers->processSpeakerList(speaker_list); | 1944 | mSpeakers->setSpeakers(speaker_list); |
1755 | } | 1945 | } |
1756 | 1946 | ||
1757 | void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) | 1947 | void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) |
@@ -1897,5 +2087,83 @@ void LLFloaterIMPanel::chatFromLogFile(LLString line, void* userdata) | |||
1897 | 2087 | ||
1898 | //self->addHistoryLine(line, LLColor4::grey, FALSE); | 2088 | //self->addHistoryLine(line, LLColor4::grey, FALSE); |
1899 | self->mHistoryEditor->appendColoredText(line, false, true, LLColor4::grey); | 2089 | self->mHistoryEditor->appendColoredText(line, false, true, LLColor4::grey); |
2090 | } | ||
2091 | |||
2092 | void LLFloaterIMPanel::showSessionStartError( | ||
2093 | const std::string& error_string) | ||
2094 | { | ||
2095 | //the error strings etc. should be really be static and local | ||
2096 | //to this file instead of in the LLFloaterIM | ||
2097 | //but they were in llimview.cpp first and unfortunately | ||
2098 | //some translations into non English languages already occurred | ||
2099 | //thus making it a tad harder to change over to a | ||
2100 | //"correct" solution. The best solution | ||
2101 | //would be to store all of the misc. strings into | ||
2102 | //their own XML file which would be read in by any LLIMPanel | ||
2103 | //post build function instead of repeating the same info | ||
2104 | //in the group, adhoc and normal IM xml files. | ||
2105 | LLString::format_map_t args; | ||
2106 | args["[REASON]"] = | ||
2107 | LLFloaterIM::sErrorStringsMap[error_string]; | ||
2108 | args["[RECIPIENT]"] = getTitle(); | ||
2109 | |||
2110 | gViewerWindow->alertXml( | ||
2111 | "ChatterBoxSessionStartError", | ||
2112 | args, | ||
2113 | onConfirmForceCloseError, | ||
2114 | new LLUUID(mSessionUUID)); | ||
2115 | } | ||
2116 | |||
2117 | void LLFloaterIMPanel::showSessionEventError( | ||
2118 | const std::string& event_string, | ||
2119 | const std::string& error_string) | ||
2120 | { | ||
2121 | LLString::format_map_t args; | ||
2122 | args["[REASON]"] = | ||
2123 | LLFloaterIM::sErrorStringsMap[error_string]; | ||
2124 | args["[EVENT]"] = | ||
2125 | LLFloaterIM::sEventStringsMap[event_string]; | ||
2126 | args["[RECIPIENT]"] = getTitle(); | ||
2127 | |||
2128 | gViewerWindow->alertXml( | ||
2129 | "ChatterBoxSessionEventError", | ||
2130 | args); | ||
2131 | } | ||
2132 | |||
2133 | void LLFloaterIMPanel::showSessionForceClose( | ||
2134 | const std::string& reason_string) | ||
2135 | { | ||
2136 | LLString::format_map_t args; | ||
2137 | |||
2138 | args["[NAME]"] = getTitle(); | ||
2139 | args["[REASON]"] = LLFloaterIM::sForceCloseSessionMap[reason_string]; | ||
2140 | |||
2141 | gViewerWindow->alertXml( | ||
2142 | "ForceCloseChatterBoxSession", | ||
2143 | args, | ||
2144 | LLFloaterIMPanel::onConfirmForceCloseError, | ||
2145 | this); | ||
1900 | 2146 | ||
1901 | } | 2147 | } |
2148 | |||
2149 | //static | ||
2150 | void LLFloaterIMPanel::onKickSpeaker(void* user_data) | ||
2151 | { | ||
2152 | |||
2153 | } | ||
2154 | |||
2155 | void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data) | ||
2156 | { | ||
2157 | //only 1 option really | ||
2158 | LLUUID session_id = *((LLUUID*) data); | ||
2159 | |||
2160 | if ( gIMMgr ) | ||
2161 | { | ||
2162 | LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession( | ||
2163 | session_id); | ||
2164 | |||
2165 | if ( floaterp ) floaterp->close(FALSE); | ||
2166 | } | ||
2167 | } | ||
2168 | |||
2169 | |||