aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llimpanel.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:54 -0500
committerJacek Antonelli2008-08-15 23:44:54 -0500
commitb2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch)
tree3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/newview/llimpanel.cpp
parentSecond Life viewer sources 1.14.0.1 (diff)
downloadmeta-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.cpp497
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//
75static LLString sTitleString = "Instant Message with [NAME]"; 76static LLString sTitleString = "Instant Message with [NAME]";
76static LLString sTypingStartString = "[NAME]: ..."; 77static LLString sTypingStartString = "[NAME]: ...";
78static LLString sSessionStartString = "Starting session with [NAME] please wait.";
79
80void 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?"
111bool 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
81LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, const LLRect& rect, 167LLFloaterIMPanel::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
191LLFloaterIMPanel::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
219void 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
108void 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
196BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids) 330BOOL 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)
474BOOL LLFloaterIMPanel::isAddAllowed() const 575BOOL 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
515void LLFloaterIMPanel::addTeleportButton(const LLUUID& lure_id) 613void 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
560void 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
571void LLFloaterIMPanel::onTeleport(void* userdata) 634void 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
592void LLFloaterIMPanel::onInputEditorFocusLost(LLLineEditor* caller, void* userdata) 654void 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
702void 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
641void LLFloaterIMPanel::sendMsg() 741void 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
845void 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
714void LLFloaterIMPanel::setTyping(BOOL typing) 871void LLFloaterIMPanel::setTyping(BOOL typing)
715{ 872{