diff options
author | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:54 -0500 |
commit | b2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch) | |
tree | 3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/newview/llimpanel.cpp | |
parent | Second Life viewer sources 1.14.0.1 (diff) | |
download | meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.zip meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.gz meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.bz2 meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.xz |
Second Life viewer sources 1.15.0.2
Diffstat (limited to 'linden/indra/newview/llimpanel.cpp')
-rw-r--r-- | linden/indra/newview/llimpanel.cpp | 497 |
1 files changed, 327 insertions, 170 deletions
diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp index 088d601..d95abf3 100644 --- a/linden/indra/newview/llimpanel.cpp +++ b/linden/indra/newview/llimpanel.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 |
@@ -74,40 +75,171 @@ const S32 MIN_HEIGHT = 130; | |||
74 | // | 75 | // |
75 | static LLString sTitleString = "Instant Message with [NAME]"; | 76 | static LLString sTitleString = "Instant Message with [NAME]"; |
76 | static LLString sTypingStartString = "[NAME]: ..."; | 77 | static LLString sTypingStartString = "[NAME]: ..."; |
78 | static LLString sSessionStartString = "Starting session with [NAME] please wait."; | ||
79 | |||
80 | void session_starter_helper(const LLUUID& temp_session_id, | ||
81 | const LLUUID& other_participant_id, | ||
82 | EInstantMessage im_type) | ||
83 | { | ||
84 | LLMessageSystem *msg = gMessageSystem; | ||
85 | |||
86 | msg->newMessageFast(_PREHASH_ImprovedInstantMessage); | ||
87 | msg->nextBlockFast(_PREHASH_AgentData); | ||
88 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
89 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
90 | |||
91 | msg->nextBlockFast(_PREHASH_MessageBlock); | ||
92 | msg->addBOOLFast(_PREHASH_FromGroup, FALSE); | ||
93 | msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id); | ||
94 | msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); | ||
95 | msg->addU8Fast(_PREHASH_Dialog, im_type); | ||
96 | msg->addUUIDFast(_PREHASH_ID, temp_session_id); | ||
97 | msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary | ||
98 | |||
99 | std::string name; | ||
100 | gAgent.buildFullname(name); | ||
101 | |||
102 | msg->addStringFast(_PREHASH_FromAgentName, name); | ||
103 | msg->addStringFast(_PREHASH_Message, LLString::null); | ||
104 | msg->addU32Fast(_PREHASH_ParentEstateID, 0); | ||
105 | msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); | ||
106 | msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); | ||
107 | } | ||
108 | |||
109 | // Returns true if any messages were sent, false otherwise. | ||
110 | // Is sort of equivalent to "does the server need to do anything?" | ||
111 | bool send_start_session_messages(const LLUUID& temp_session_id, | ||
112 | const LLUUID& other_participant_id, | ||
113 | const LLDynamicArray<LLUUID>& ids, | ||
114 | EInstantMessage dialog) | ||
115 | { | ||
116 | if ( (dialog == IM_SESSION_911_START) || | ||
117 | (dialog == IM_SESSION_GROUP_START) || | ||
118 | (dialog == IM_SESSION_CONFERENCE_START) ) | ||
119 | { | ||
120 | S32 count = ids.size(); | ||
121 | S32 bucket_size = UUID_BYTES * count; | ||
122 | U8* bucket; | ||
123 | U8* pos; | ||
124 | |||
125 | session_starter_helper(temp_session_id, | ||
126 | other_participant_id, | ||
127 | dialog); | ||
128 | |||
129 | switch(dialog) | ||
130 | { | ||
131 | case IM_SESSION_GROUP_START: | ||
132 | case IM_SESSION_911_START: | ||
133 | gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket, | ||
134 | EMPTY_BINARY_BUCKET, | ||
135 | EMPTY_BINARY_BUCKET_SIZE); | ||
136 | break; | ||
137 | case IM_SESSION_CONFERENCE_START: | ||
138 | bucket = new U8[bucket_size]; | ||
139 | pos = bucket; | ||
140 | |||
141 | // *FIX: this could suffer from endian issues | ||
142 | for(S32 i = 0; i < count; ++i) | ||
143 | { | ||
144 | memcpy(pos, &(ids.get(i)), UUID_BYTES); | ||
145 | pos += UUID_BYTES; | ||
146 | } | ||
147 | gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket, | ||
148 | bucket, | ||
149 | bucket_size); | ||
150 | delete[] bucket; | ||
151 | |||
152 | break; | ||
153 | default: | ||
154 | break; | ||
155 | } | ||
156 | gAgent.sendReliableMessage(); | ||
157 | |||
158 | return true; | ||
159 | } | ||
160 | |||
161 | return false; | ||
162 | } | ||
77 | 163 | ||
78 | // Member Functions | 164 | // Member Functions |
79 | // | 165 | // |
80 | 166 | ||
81 | LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, const LLRect& rect, | 167 | LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, |
82 | const std::string& session_label, | 168 | const LLRect& rect, |
83 | const LLUUID& session_id, | 169 | const std::string& session_label, |
84 | const LLUUID& other_participant_id, | 170 | const LLUUID& session_id, |
85 | EInstantMessage dialog) : | 171 | const LLUUID& other_participant_id, |
172 | EInstantMessage dialog) : | ||
173 | LLFloater(name, rect, session_label), | ||
174 | mInputEditor(NULL), | ||
175 | mHistoryEditor(NULL), | ||
176 | mSessionUUID(session_id), | ||
177 | mOtherParticipantUUID(other_participant_id), | ||
178 | mDialog(dialog), | ||
179 | mTyping(FALSE), | ||
180 | mOtherTyping(FALSE), | ||
181 | mTypingLineStartIndex(0), | ||
182 | mSentTypingState(TRUE), | ||
183 | mFirstKeystrokeTimer(), | ||
184 | mLastKeystrokeTimer(), | ||
185 | mSessionInitialized(FALSE), | ||
186 | mSessionInitRequested(FALSE) | ||
187 | { | ||
188 | init(session_label); | ||
189 | } | ||
190 | |||
191 | LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, | ||
192 | const LLRect& rect, | ||
193 | const std::string& session_label, | ||
194 | const LLUUID& session_id, | ||
195 | const LLUUID& other_participant_id, | ||
196 | const LLDynamicArray<LLUUID>& ids, | ||
197 | EInstantMessage dialog) : | ||
86 | LLFloater(name, rect, session_label), | 198 | LLFloater(name, rect, session_label), |
87 | mInputEditor(NULL), | 199 | mInputEditor(NULL), |
88 | mHistoryEditor(NULL), | 200 | mHistoryEditor(NULL), |
89 | mSessionLabel(session_label), | ||
90 | mSessionUUID(session_id), | 201 | mSessionUUID(session_id), |
91 | mOtherParticipantUUID(other_participant_id), | 202 | mOtherParticipantUUID(other_participant_id), |
92 | mLureID(), | ||
93 | mDialog(dialog), | 203 | mDialog(dialog), |
94 | mTyping(FALSE), | 204 | mTyping(FALSE), |
95 | mOtherTyping(FALSE), | 205 | mOtherTyping(FALSE), |
96 | mTypingLineStartIndex(0), | 206 | mTypingLineStartIndex(0), |
97 | mSentTypingState(TRUE), | 207 | mSentTypingState(TRUE), |
98 | mFirstKeystrokeTimer(), | 208 | mFirstKeystrokeTimer(), |
99 | mLastKeystrokeTimer() | 209 | mLastKeystrokeTimer(), |
210 | mSessionInitialized(FALSE), | ||
211 | mSessionInitRequested(FALSE) | ||
212 | { | ||
213 | init(session_label); | ||
214 | |||
215 | mSessionInitialTargetIDs = ids; | ||
216 | } | ||
217 | |||
218 | |||
219 | void LLFloaterIMPanel::init(const LLString& session_label) | ||
100 | { | 220 | { |
101 | init(); | 221 | gUICtrlFactory->buildFloater(this, |
222 | "floater_instant_message.xml", | ||
223 | NULL, | ||
224 | FALSE); | ||
225 | |||
102 | setLabel(session_label); | 226 | setLabel(session_label); |
103 | setTitle(session_label); | 227 | setTitle(session_label); |
104 | mInputEditor->setMaxTextLength(1023); | 228 | mInputEditor->setMaxTextLength(1023); |
105 | } | ||
106 | 229 | ||
230 | if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) | ||
231 | { | ||
232 | LLLogChat::loadHistory(session_label, | ||
233 | &chatFromLogFile, | ||
234 | (void *)this); | ||
235 | } | ||
107 | 236 | ||
108 | void LLFloaterIMPanel::init() | 237 | if(IM_SESSION_911_START == mDialog) |
109 | { | 238 | { |
110 | gUICtrlFactory->buildFloater(this, "floater_instant_message.xml", NULL, FALSE); | 239 | LLTextBox* live_help_text = |
240 | LLUICtrlFactory::getTextBoxByName(this, "live_help_dialog"); | ||
241 | addHistoryLine(live_help_text->getText()); | ||
242 | } | ||
111 | } | 243 | } |
112 | 244 | ||
113 | 245 | ||
@@ -120,6 +252,8 @@ BOOL LLFloaterIMPanel::postBuild() | |||
120 | requires("live_help_dialog", WIDGET_TYPE_TEXT_BOX); | 252 | requires("live_help_dialog", WIDGET_TYPE_TEXT_BOX); |
121 | requires("title_string", WIDGET_TYPE_TEXT_BOX); | 253 | requires("title_string", WIDGET_TYPE_TEXT_BOX); |
122 | requires("typing_start_string", WIDGET_TYPE_TEXT_BOX); | 254 | requires("typing_start_string", WIDGET_TYPE_TEXT_BOX); |
255 | requires("session_start_string", WIDGET_TYPE_TEXT_BOX); | ||
256 | requires("teleport_btn", WIDGET_TYPE_BUTTON); | ||
123 | 257 | ||
124 | if (checkRequirements()) | 258 | if (checkRequirements()) |
125 | { | 259 | { |
@@ -137,24 +271,19 @@ BOOL LLFloaterIMPanel::postBuild() | |||
137 | LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn"); | 271 | LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn"); |
138 | close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); | 272 | close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); |
139 | 273 | ||
274 | LLButton* tp_btn = LLUICtrlFactory::getButtonByName(this, "teleport_btn"); | ||
275 | tp_btn->setClickedCallback(&LLFloaterIMPanel::onTeleport, this); | ||
276 | tp_btn->setVisible(FALSE); | ||
277 | tp_btn->setEnabled(FALSE); | ||
278 | |||
140 | mHistoryEditor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "im_history"); | 279 | mHistoryEditor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "im_history"); |
141 | mHistoryEditor->setParseHTML(TRUE); | 280 | mHistoryEditor->setParseHTML(TRUE); |
142 | if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) | ||
143 | { | ||
144 | LLLogChat::loadHistory(mSessionLabel, &chatFromLogFile, (void *)this); | ||
145 | } | ||
146 | 281 | ||
147 | if (IM_SESSION_GROUP_START == mDialog | 282 | if (IM_SESSION_GROUP_START == mDialog |
148 | || IM_SESSION_911_START == mDialog) | 283 | || IM_SESSION_911_START == mDialog) |
149 | { | 284 | { |
150 | profile_btn->setEnabled(FALSE); | 285 | profile_btn->setEnabled(FALSE); |
151 | if(IM_SESSION_911_START == mDialog) | ||
152 | { | ||
153 | LLTextBox* live_help_text = LLUICtrlFactory::getTextBoxByName(this, "live_help_dialog"); | ||
154 | addHistoryLine(live_help_text->getText()); | ||
155 | } | ||
156 | } | 286 | } |
157 | |||
158 | LLTextBox* title = LLUICtrlFactory::getTextBoxByName(this, "title_string"); | 287 | LLTextBox* title = LLUICtrlFactory::getTextBoxByName(this, "title_string"); |
159 | sTitleString = title->getText(); | 288 | sTitleString = title->getText(); |
160 | 289 | ||
@@ -162,6 +291,11 @@ BOOL LLFloaterIMPanel::postBuild() | |||
162 | 291 | ||
163 | sTypingStartString = typing_start->getText(); | 292 | sTypingStartString = typing_start->getText(); |
164 | 293 | ||
294 | LLTextBox* session_start = LLUICtrlFactory::getTextBoxByName( | ||
295 | this, | ||
296 | "session_start_string"); | ||
297 | sSessionStartString = session_start->getText(); | ||
298 | |||
165 | return TRUE; | 299 | return TRUE; |
166 | } | 300 | } |
167 | 301 | ||
@@ -195,12 +329,14 @@ void LLFloaterIMPanel::draw() | |||
195 | 329 | ||
196 | BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids) | 330 | BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids) |
197 | { | 331 | { |
198 | if(isAddAllowed()) | 332 | S32 count = ids.count(); |
333 | |||
334 | if( isAddAllowed() && (count > 0) ) | ||
199 | { | 335 | { |
200 | llinfos << "LLFloaterIMPanel::addParticipants() - adding participants" << llendl; | 336 | llinfos << "LLFloaterIMPanel::addParticipants() - adding participants" << llendl; |
201 | const S32 MAX_AGENTS = 50; | 337 | const S32 MAX_AGENTS = 50; |
202 | S32 count = ids.count(); | ||
203 | if(count > MAX_AGENTS) return FALSE; | 338 | if(count > MAX_AGENTS) return FALSE; |
339 | |||
204 | LLMessageSystem *msg = gMessageSystem; | 340 | LLMessageSystem *msg = gMessageSystem; |
205 | msg->newMessageFast(_PREHASH_ImprovedInstantMessage); | 341 | msg->newMessageFast(_PREHASH_ImprovedInstantMessage); |
206 | msg->nextBlockFast(_PREHASH_AgentData); | 342 | msg->nextBlockFast(_PREHASH_AgentData); |
@@ -210,7 +346,7 @@ BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids) | |||
210 | msg->addBOOLFast(_PREHASH_FromGroup, FALSE); | 346 | msg->addBOOLFast(_PREHASH_FromGroup, FALSE); |
211 | msg->addUUIDFast(_PREHASH_ToAgentID, mOtherParticipantUUID); | 347 | msg->addUUIDFast(_PREHASH_ToAgentID, mOtherParticipantUUID); |
212 | msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); | 348 | msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); |
213 | msg->addU8Fast(_PREHASH_Dialog, mDialog); | 349 | msg->addU8Fast(_PREHASH_Dialog, IM_SESSION_ADD); |
214 | msg->addUUIDFast(_PREHASH_ID, mSessionUUID); | 350 | msg->addUUIDFast(_PREHASH_ID, mSessionUUID); |
215 | msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary | 351 | msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary |
216 | std::string name; | 352 | std::string name; |
@@ -220,57 +356,21 @@ BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids) | |||
220 | msg->addU32Fast(_PREHASH_ParentEstateID, 0); | 356 | msg->addU32Fast(_PREHASH_ParentEstateID, 0); |
221 | msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); | 357 | msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); |
222 | msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); | 358 | msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); |
223 | if (IM_SESSION_GROUP_START == mDialog) | 359 | |
224 | { | 360 | // *FIX: this could suffer from endian issues |
225 | // *HACK: binary bucket contains session label - the server | 361 | S32 bucket_size = UUID_BYTES * count; |
226 | // will actually add agents. | 362 | U8* bucket = new U8[bucket_size]; |
227 | llinfos << "Group IM session name '" << mSessionLabel | 363 | U8* pos = bucket; |
228 | << "'" << llendl; | 364 | for(S32 i = 0; i < count; ++i) |
229 | msg->addStringFast(_PREHASH_BinaryBucket, mSessionLabel); | ||
230 | gAgent.sendReliableMessage(); | ||
231 | } | ||
232 | else if (IM_SESSION_911_START == mDialog) | ||
233 | { | ||
234 | // HACK -- we modify the name of the session going out to | ||
235 | // the helpers to help them easily identify "Help" | ||
236 | // sessions in their collection of IM panels. | ||
237 | LLString name; | ||
238 | gAgent.getName(name); | ||
239 | LLString buffer = LLString("HELP ") + name; | ||
240 | llinfos << "LiveHelp IM session '" << buffer << "'." << llendl; | ||
241 | msg->addStringFast(_PREHASH_BinaryBucket, buffer.c_str()); | ||
242 | |||
243 | // automaticaly open a wormhole when this reliable message gets through | ||
244 | msg->sendReliable( | ||
245 | gAgent.getRegionHost(), | ||
246 | 3, // retries | ||
247 | TRUE, // ping-based | ||
248 | 5.0f, // timeout | ||
249 | send_lure_911, | ||
250 | (void**)&mSessionUUID); | ||
251 | } | ||
252 | else | ||
253 | { | 365 | { |
254 | if (mDialog != IM_SESSION_ADD | 366 | memcpy(pos, &(ids.get(i)), UUID_BYTES); |
255 | && mDialog != IM_SESSION_OFFLINE_ADD) | 367 | pos += UUID_BYTES; |
256 | { | ||
257 | llwarns << "LLFloaterIMPanel::addParticipants() - dialog type " << mDialog | ||
258 | << " is not an ADD" << llendl; | ||
259 | } | ||
260 | // *FIX: this could suffer from endian issues | ||
261 | S32 bucket_size = UUID_BYTES * count; | ||
262 | U8* bucket = new U8[bucket_size]; | ||
263 | U8* pos = bucket; | ||
264 | for(S32 i = 0; i < count; ++i) | ||
265 | { | ||
266 | memcpy(pos, &(ids.get(i)), UUID_BYTES); /* Flawfinder: ignore */ | ||
267 | pos += UUID_BYTES; | ||
268 | } | ||
269 | msg->addBinaryDataFast(_PREHASH_BinaryBucket, bucket, bucket_size); | ||
270 | delete[] bucket; | ||
271 | gAgent.sendReliableMessage(); | ||
272 | } | 368 | } |
273 | 369 | msg->addBinaryDataFast(_PREHASH_BinaryBucket, | |
370 | bucket, | ||
371 | bucket_size); | ||
372 | delete[] bucket; | ||
373 | gAgent.sendReliableMessage(); | ||
274 | } | 374 | } |
275 | else | 375 | else |
276 | { | 376 | { |
@@ -279,6 +379,7 @@ BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids) | |||
279 | // successful add, because everyone that needed to get added | 379 | // successful add, because everyone that needed to get added |
280 | // was added. | 380 | // was added. |
281 | } | 381 | } |
382 | |||
282 | return TRUE; | 383 | return TRUE; |
283 | } | 384 | } |
284 | 385 | ||
@@ -312,7 +413,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 | |||
312 | { | 413 | { |
313 | LLString histstr = timestring + utf8msg; | 414 | LLString histstr = timestring + utf8msg; |
314 | 415 | ||
315 | LLLogChat::saveHistory(mSessionLabel,histstr); | 416 | LLLogChat::saveHistory(getTitle(),histstr); |
316 | } | 417 | } |
317 | } | 418 | } |
318 | 419 | ||
@@ -474,11 +575,8 @@ BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop) | |||
474 | BOOL LLFloaterIMPanel::isAddAllowed() const | 575 | BOOL LLFloaterIMPanel::isAddAllowed() const |
475 | { | 576 | { |
476 | 577 | ||
477 | return ((IM_SESSION_ADD == mDialog) | 578 | return ((IM_SESSION_CONFERENCE_START == mDialog) |
478 | || (IM_SESSION_OFFLINE_ADD == mDialog) | 579 | || (IM_SESSION_ADD) ); |
479 | || (IM_SESSION_GROUP_START == mDialog) | ||
480 | || (IM_SESSION_911_START == mDialog) | ||
481 | || (IM_SESSION_CARDLESS_START == mDialog)); | ||
482 | } | 580 | } |
483 | 581 | ||
484 | 582 | ||
@@ -512,72 +610,36 @@ void LLFloaterIMPanel::onClickClose( void* userdata ) | |||
512 | } | 610 | } |
513 | } | 611 | } |
514 | 612 | ||
515 | void LLFloaterIMPanel::addTeleportButton(const LLUUID& lure_id) | 613 | void LLFloaterIMPanel::addTeleportButton() |
516 | { | 614 | { |
517 | LLButton* btn = LLViewerUICtrlFactory::getButtonByName(this, "Teleport Btn"); | 615 | LLButton* btn = |
518 | if (!btn) | 616 | LLViewerUICtrlFactory::getButtonByName(this, "teleport_btn"); |
519 | { | ||
520 | S32 BTN_VPAD = 2; | ||
521 | S32 BTN_HPAD = 2; | ||
522 | 617 | ||
523 | const char* teleport_label = "Teleport"; | 618 | if ( !btn->getEnabled() ) |
524 | 619 | { | |
525 | const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); | 620 | //it's required, don't need to check for null here |
526 | S32 p_btn_width = 75; | 621 | // adjust the size of the editor to make room for the button |
527 | S32 c_btn_width = 60; | ||
528 | S32 t_btn_width = 75; | ||
529 | |||
530 | // adjust the size of the editor to make room for the new button | ||
531 | LLRect rect = mInputEditor->getRect(); | 622 | LLRect rect = mInputEditor->getRect(); |
532 | S32 editor_right = rect.mRight - t_btn_width; | 623 | S32 editor_right = rect.mRight - btn->getRect().getWidth(); |
533 | rect.mRight = editor_right; | 624 | rect.mRight = editor_right; |
534 | mInputEditor->reshape(rect.getWidth(), rect.getHeight(), FALSE); | 625 | mInputEditor->reshape(rect.getWidth(), rect.getHeight(), FALSE); |
535 | mInputEditor->setRect(rect); | 626 | mInputEditor->setRect(rect); |
536 | |||
537 | const S32 IMPANEL_PAD = 1 + LLPANEL_BORDER_WIDTH; | ||
538 | const S32 IMPANEL_INPUT_HEIGHT = 20; | ||
539 | |||
540 | rect.setLeftTopAndSize( | ||
541 | mRect.getWidth() - IMPANEL_PAD - p_btn_width - c_btn_width - t_btn_width - BTN_HPAD - RESIZE_HANDLE_WIDTH, | ||
542 | IMPANEL_INPUT_HEIGHT + IMPANEL_PAD - BTN_VPAD, | ||
543 | t_btn_width, | ||
544 | BTN_HEIGHT); | ||
545 | |||
546 | btn = new LLButton( | ||
547 | "Teleport Btn", rect, | ||
548 | "","", "", | ||
549 | &LLFloaterIMPanel::onTeleport, this, | ||
550 | font, teleport_label, teleport_label ); | ||
551 | |||
552 | btn->setFollowsBottom(); | ||
553 | btn->setFollowsRight(); | ||
554 | addChild( btn ); | ||
555 | } | ||
556 | btn->setEnabled(TRUE); | ||
557 | mLureID = lure_id; | ||
558 | } | ||
559 | 627 | ||
560 | void LLFloaterIMPanel::removeTeleportButton() | 628 | btn->setVisible(TRUE); |
561 | { | 629 | btn->setEnabled(TRUE); |
562 | // TODO -- purge the button | ||
563 | LLButton* btn = LLViewerUICtrlFactory::getButtonByName(this, "Teleport Btn"); | ||
564 | if (btn) | ||
565 | { | ||
566 | btn->setEnabled(FALSE); | ||
567 | } | 630 | } |
568 | } | 631 | } |
569 | 632 | ||
570 | // static | 633 | // static |
571 | void LLFloaterIMPanel::onTeleport(void* userdata) | 634 | void LLFloaterIMPanel::onTeleport(void* userdata) |
572 | { | 635 | { |
573 | LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; | 636 | LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; |
574 | if(self) | 637 | if(self) |
575 | { | 638 | { |
576 | send_simple_im(self->mLureID, | 639 | send_simple_im(self->mSessionUUID, //to |
577 | "", | 640 | "", |
578 | IM_LURE_911, | 641 | IM_TELEPORT_911, |
579 | LLUUID::null); | 642 | self->mSessionUUID);//session |
580 | self->removeTeleportButton(); | ||
581 | } | 643 | } |
582 | } | 644 | } |
583 | 645 | ||
@@ -589,7 +651,7 @@ void LLFloaterIMPanel::onInputEditorFocusReceived( LLUICtrl* caller, void* userd | |||
589 | } | 651 | } |
590 | 652 | ||
591 | // static | 653 | // static |
592 | void LLFloaterIMPanel::onInputEditorFocusLost(LLLineEditor* caller, void* userdata) | 654 | void LLFloaterIMPanel::onInputEditorFocusLost(LLUICtrl* caller, void* userdata) |
593 | { | 655 | { |
594 | LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; | 656 | LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; |
595 | self->setTyping(FALSE); | 657 | self->setTyping(FALSE); |
@@ -637,6 +699,44 @@ void LLFloaterIMPanel::onClose(bool app_quitting) | |||
637 | destroy(); | 699 | destroy(); |
638 | } | 700 | } |
639 | 701 | ||
702 | void deliver_message(const std::string& utf8_text, | ||
703 | const LLUUID& im_session_id, | ||
704 | const LLUUID& other_participant_id, | ||
705 | EInstantMessage dialog) | ||
706 | { | ||
707 | std::string name; | ||
708 | gAgent.buildFullname(name); | ||
709 | |||
710 | const LLRelationship* info = NULL; | ||
711 | info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); | ||
712 | U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; | ||
713 | |||
714 | // default to IM_SESSION_SEND unless it's nothing special - in | ||
715 | // which case it's probably an IM to everyone. | ||
716 | U8 new_dialog = dialog; | ||
717 | |||
718 | if ( dialog == IM_SESSION_911_START ) | ||
719 | { | ||
720 | new_dialog = IM_SESSION_911_SEND; | ||
721 | } | ||
722 | else if ( dialog != IM_NOTHING_SPECIAL ) | ||
723 | { | ||
724 | new_dialog = IM_SESSION_SEND; | ||
725 | } | ||
726 | |||
727 | pack_instant_message( | ||
728 | gMessageSystem, | ||
729 | gAgent.getID(), | ||
730 | FALSE, | ||
731 | gAgent.getSessionID(), | ||
732 | other_participant_id, | ||
733 | name.c_str(), | ||
734 | utf8_text.c_str(), | ||
735 | offline, | ||
736 | (EInstantMessage)new_dialog, | ||
737 | im_session_id); | ||
738 | gAgent.sendReliableMessage(); | ||
739 | } | ||
640 | 740 | ||
641 | void LLFloaterIMPanel::sendMsg() | 741 | void LLFloaterIMPanel::sendMsg() |
642 | { | 742 | { |
@@ -654,50 +754,82 @@ void LLFloaterIMPanel::sendMsg() | |||
654 | // Truncate and convert to UTF8 for transport | 754 | // Truncate and convert to UTF8 for transport |
655 | std::string utf8_text = wstring_to_utf8str(text); | 755 | std::string utf8_text = wstring_to_utf8str(text); |
656 | utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); | 756 | utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); |
657 | std::string name; | ||
658 | gAgent.buildFullname(name); | ||
659 | |||
660 | const LLRelationship* info = NULL; | ||
661 | info = LLAvatarTracker::instance().getBuddyInfo(mOtherParticipantUUID); | ||
662 | U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; | ||
663 | |||
664 | // default to IM_SESSION_SEND unless it's nothing special - in | ||
665 | // which case it's probably an IM to everyone. | ||
666 | U8 dialog = (mDialog == IM_NOTHING_SPECIAL) | ||
667 | ? (U8)IM_NOTHING_SPECIAL : (U8)IM_SESSION_SEND; | ||
668 | pack_instant_message( | ||
669 | gMessageSystem, | ||
670 | gAgent.getID(), | ||
671 | FALSE, | ||
672 | gAgent.getSessionID(), | ||
673 | mOtherParticipantUUID, | ||
674 | name.c_str(), | ||
675 | utf8_text.c_str(), | ||
676 | offline, | ||
677 | (EInstantMessage)dialog, | ||
678 | mSessionUUID); | ||
679 | gAgent.sendReliableMessage(); | ||
680 | 757 | ||
681 | // local echo | 758 | if ( !mSessionInitialized ) |
682 | if((mDialog == IM_NOTHING_SPECIAL) && (mOtherParticipantUUID.notNull())) | ||
683 | { | 759 | { |
684 | std::string history_echo; | 760 | //we send requests (if we need to) to initialize our session |
685 | gAgent.buildFullname(history_echo); | 761 | if ( !mSessionInitRequested ) |
686 | |||
687 | // Look for IRC-style emotes here. | ||
688 | char tmpstr[5]; /* Flawfinder: ignore */ | ||
689 | strncpy(tmpstr,utf8_text.substr(0,4).c_str(), sizeof(tmpstr) -1); /* Flawfinder: ignore */ | ||
690 | tmpstr[sizeof(tmpstr) -1] = '\0'; | ||
691 | if (!strncmp(tmpstr, "/me ", 4) || !strncmp(tmpstr, "/me'", 4)) | ||
692 | { | 762 | { |
693 | utf8_text.replace(0,3,""); | 763 | mSessionInitRequested = TRUE; |
764 | if ( !send_start_session_messages(mSessionUUID, | ||
765 | mOtherParticipantUUID, | ||
766 | mSessionInitialTargetIDs, | ||
767 | mDialog) ) | ||
768 | { | ||
769 | //we don't need to need to wait for any responses | ||
770 | //so we don't need to disable | ||
771 | mSessionInitialized = TRUE; | ||
772 | } | ||
773 | else | ||
774 | { | ||
775 | //queue up the message to send once the session is | ||
776 | //initialized | ||
777 | mQueuedMsgsForInit.append(utf8_text); | ||
778 | |||
779 | //locally echo a little "starting session" message | ||
780 | LLUIString session_start = sSessionStartString; | ||
781 | |||
782 | session_start.setArg("[NAME]", getTitle()); | ||
783 | mSessionStartMsgPos = | ||
784 | mHistoryEditor->getText().length(); | ||
785 | |||
786 | bool log_to_file = false; | ||
787 | addHistoryLine(session_start, | ||
788 | LLColor4::grey, | ||
789 | log_to_file); | ||
790 | |||
791 | } | ||
694 | } | 792 | } |
695 | else | 793 | else |
696 | { | 794 | { |
697 | history_echo += ": "; | 795 | //queue up the message to send once the session is |
796 | //initialized | ||
797 | mQueuedMsgsForInit.append(utf8_text); | ||
798 | } | ||
799 | } | ||
800 | |||
801 | if ( mSessionInitialized ) | ||
802 | { | ||
803 | deliver_message(utf8_text, | ||
804 | mSessionUUID, | ||
805 | mOtherParticipantUUID, | ||
806 | mDialog); | ||
807 | |||
808 | // local echo | ||
809 | if((mDialog == IM_NOTHING_SPECIAL) && | ||
810 | (mOtherParticipantUUID.notNull())) | ||
811 | { | ||
812 | std::string history_echo; | ||
813 | gAgent.buildFullname(history_echo); | ||
814 | |||
815 | // Look for IRC-style emotes here. | ||
816 | char tmpstr[5]; /* Flawfinder: ignore */ | ||
817 | strncpy(tmpstr, | ||
818 | utf8_text.substr(0,4).c_str(), | ||
819 | sizeof(tmpstr) -1); /* Flawfinder: ignore */ | ||
820 | tmpstr[sizeof(tmpstr) -1] = '\0'; | ||
821 | if (!strncmp(tmpstr, "/me ", 4) || | ||
822 | !strncmp(tmpstr, "/me'", 4)) | ||
823 | { | ||
824 | utf8_text.replace(0,3,""); | ||
825 | } | ||
826 | else | ||
827 | { | ||
828 | history_echo += ": "; | ||
829 | } | ||
830 | history_echo += utf8_text; | ||
831 | addHistoryLine(history_echo); | ||
698 | } | 832 | } |
699 | history_echo += utf8_text; | ||
700 | addHistoryLine(history_echo); | ||
701 | } | 833 | } |
702 | 834 | ||
703 | gViewerStats->incStat(LLViewerStats::ST_IM_COUNT); | 835 | gViewerStats->incStat(LLViewerStats::ST_IM_COUNT); |
@@ -710,6 +842,31 @@ void LLFloaterIMPanel::sendMsg() | |||
710 | mSentTypingState = TRUE; | 842 | mSentTypingState = TRUE; |
711 | } | 843 | } |
712 | 844 | ||
845 | void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) | ||
846 | { | ||
847 | mSessionUUID = session_id; | ||
848 | mSessionInitialized = TRUE; | ||
849 | |||
850 | //we assume the history editor hasn't moved at all since | ||
851 | //we added the starting session message | ||
852 | //so, we count how many characters to remove | ||
853 | S32 chars_to_remove = mHistoryEditor->getText().length() - | ||
854 | mSessionStartMsgPos; | ||
855 | mHistoryEditor->removeTextFromEnd(chars_to_remove); | ||
856 | |||
857 | //and now, send the queued msg | ||
858 | LLSD::array_iterator iter; | ||
859 | for ( iter = mQueuedMsgsForInit.beginArray(); | ||
860 | iter != mQueuedMsgsForInit.endArray(); | ||
861 | ++iter) | ||
862 | { | ||
863 | deliver_message(iter->asString(), | ||
864 | mSessionUUID, | ||
865 | mOtherParticipantUUID, | ||
866 | mDialog); | ||
867 | } | ||
868 | } | ||
869 | |||
713 | 870 | ||
714 | void LLFloaterIMPanel::setTyping(BOOL typing) | 871 | void LLFloaterIMPanel::setTyping(BOOL typing) |
715 | { | 872 | { |