diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloaterchat.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfloaterchat.cpp | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp new file mode 100644 index 0000000..0ffc518 --- /dev/null +++ b/linden/indra/newview/llfloaterchat.cpp | |||
@@ -0,0 +1,439 @@ | |||
1 | /** | ||
2 | * @file llfloaterchat.cpp | ||
3 | * @brief LLFloaterChat class implementation | ||
4 | * | ||
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * 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 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | /** | ||
29 | * Actually the "Chat History" floater. | ||
30 | * Should be llfloaterchathistory, not llfloaterchat. | ||
31 | */ | ||
32 | |||
33 | #include "llviewerprecompiledheaders.h" | ||
34 | |||
35 | #include "llfloaterchat.h" | ||
36 | #include "llfloaterscriptdebug.h" | ||
37 | |||
38 | #include "llchat.h" | ||
39 | #include "llfontgl.h" | ||
40 | #include "llrect.h" | ||
41 | #include "llerror.h" | ||
42 | #include "llstring.h" | ||
43 | #include "message.h" | ||
44 | |||
45 | // project include | ||
46 | #include "llagent.h" | ||
47 | #include "llbutton.h" | ||
48 | #include "llcheckboxctrl.h" | ||
49 | #include "llcombobox.h" | ||
50 | #include "llconsole.h" | ||
51 | #include "llfloatermute.h" | ||
52 | #include "llkeyboard.h" | ||
53 | //#include "lllineeditor.h" | ||
54 | #include "llmutelist.h" | ||
55 | //#include "llresizehandle.h" | ||
56 | #include "llstatusbar.h" | ||
57 | #include "llviewertexteditor.h" | ||
58 | #include "llviewergesture.h" // for triggering gestures | ||
59 | #include "llviewermessage.h" | ||
60 | #include "llviewerwindow.h" | ||
61 | #include "llviewercontrol.h" | ||
62 | #include "llvieweruictrlfactory.h" | ||
63 | #include "llchatbar.h" | ||
64 | #include "lllogchat.h" | ||
65 | #include "lltexteditor.h" | ||
66 | #include "llfloaterhtml.h" | ||
67 | #include "llweb.h" | ||
68 | |||
69 | // | ||
70 | // Constants | ||
71 | // | ||
72 | const char FLOATER_TITLE[] = "Chat History"; | ||
73 | const F32 INSTANT_MSG_SIZE = 8.0f; | ||
74 | const F32 CHAT_MSG_SIZE = 8.0f; | ||
75 | const LLColor4 INSTANT_MSG_COLOR(1, 1, 1, 1); | ||
76 | const LLColor4 MUTED_MSG_COLOR(0.5f, 0.5f, 0.5f, 1.f); | ||
77 | const S32 MAX_CHATTER_COUNT = 16; | ||
78 | |||
79 | // | ||
80 | // Global statics | ||
81 | // | ||
82 | LLFloaterChat* gFloaterChat = NULL; | ||
83 | |||
84 | LLColor4 get_text_color(const LLChat& chat); | ||
85 | |||
86 | // | ||
87 | // Member Functions | ||
88 | // | ||
89 | LLFloaterChat::LLFloaterChat() | ||
90 | : LLFloater("chat floater", "FloaterChatRect", FLOATER_TITLE, | ||
91 | RESIZE_YES, 440, 100, DRAG_ON_TOP, MINIMIZE_NO, CLOSE_YES) | ||
92 | { | ||
93 | |||
94 | gUICtrlFactory->buildFloater(this,"floater_chat_history.xml"); | ||
95 | |||
96 | childSetAction("Mute resident",onClickMute,this); | ||
97 | childSetAction("Chat", onClickChat, this); | ||
98 | childSetCommitCallback("chatter combobox",onCommitUserSelect,this); | ||
99 | childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes | ||
100 | childSetVisible("Chat History Editor with mute",FALSE); | ||
101 | setDefaultBtn("Chat"); | ||
102 | } | ||
103 | |||
104 | LLFloaterChat::~LLFloaterChat() | ||
105 | { | ||
106 | // Children all cleaned up by default view destructor. | ||
107 | } | ||
108 | |||
109 | void LLFloaterChat::setVisible(BOOL visible) | ||
110 | { | ||
111 | LLFloater::setVisible( visible ); | ||
112 | |||
113 | gSavedSettings.setBOOL("ShowChatHistory", visible); | ||
114 | |||
115 | // Hide the chat overlay when our history is visible. | ||
116 | gConsole->setVisible( !visible ); | ||
117 | } | ||
118 | |||
119 | |||
120 | // public virtual | ||
121 | void LLFloaterChat::onClose(bool app_quitting) | ||
122 | { | ||
123 | LLFloater::setVisible( FALSE ); | ||
124 | |||
125 | if (!app_quitting) | ||
126 | { | ||
127 | gSavedSettings.setBOOL("ShowChatHistory", FALSE); | ||
128 | } | ||
129 | |||
130 | // Hide the chat overlay when our history is visible. | ||
131 | gConsole->setVisible( TRUE ); | ||
132 | } | ||
133 | |||
134 | |||
135 | // public | ||
136 | void LLFloaterChat::show() | ||
137 | { | ||
138 | open(); | ||
139 | } | ||
140 | |||
141 | void add_timestamped_line(LLViewerTextEditor* edit, const LLString& line, const LLColor4& color) | ||
142 | { | ||
143 | bool prepend_newline = true; | ||
144 | if (gSavedSettings.getBOOL("ChatShowTimestamps")) | ||
145 | { | ||
146 | edit->appendTime(prepend_newline); | ||
147 | prepend_newline = false; | ||
148 | } | ||
149 | edit->appendColoredText(line, false, prepend_newline, color); | ||
150 | } | ||
151 | |||
152 | // static | ||
153 | void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) | ||
154 | { | ||
155 | if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file) | ||
156 | { | ||
157 | LLLogChat::saveHistory("chat",chat.mText); | ||
158 | } | ||
159 | |||
160 | LLColor4 color = get_text_color(chat); | ||
161 | |||
162 | if (!log_to_file) color = LLColor4::grey; //Recap from log file. | ||
163 | |||
164 | if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) | ||
165 | { | ||
166 | LLFloaterScriptDebug::addScriptLine(chat.mText, | ||
167 | chat.mFromName, | ||
168 | color, | ||
169 | chat.mFromID); | ||
170 | if (!gSavedSettings.getBOOL("ScriptErrorsAsChat")) | ||
171 | { | ||
172 | return; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | // could flash the chat button in the status bar here. JC | ||
177 | if (!gFloaterChat) return; | ||
178 | |||
179 | LLViewerTextEditor* HistoryEditor = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor"); | ||
180 | LLViewerTextEditor* HistoryEditorWithMute = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor with mute"); | ||
181 | |||
182 | HistoryEditor->setParseHTML(TRUE); | ||
183 | HistoryEditorWithMute->setParseHTML(TRUE); | ||
184 | |||
185 | if (!chat.mMuted) | ||
186 | { | ||
187 | add_timestamped_line(HistoryEditor, chat.mText, color); | ||
188 | add_timestamped_line(HistoryEditorWithMute, chat.mText, color); | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | // desaturate muted chat | ||
193 | LLColor4 muted_color = lerp(color, LLColor4::grey, 0.5f); | ||
194 | add_timestamped_line(HistoryEditorWithMute, chat.mText, color); | ||
195 | } | ||
196 | |||
197 | if (!chat.mMuted | ||
198 | && chat.mSourceType != CHAT_SOURCE_SYSTEM | ||
199 | && chat.mFromID.notNull() | ||
200 | && chat.mFromID != gAgent.getID()) | ||
201 | { | ||
202 | |||
203 | LLComboBox* ChatterCombo = LLUICtrlFactory::getComboBoxByName(gFloaterChat,"chatter combobox"); | ||
204 | |||
205 | if(!ChatterCombo) | ||
206 | return; | ||
207 | |||
208 | if (!ChatterCombo->setCurrentByID(chat.mFromID)) | ||
209 | { | ||
210 | // if we have too many items... | ||
211 | if (ChatterCombo->getItemCount() >= MAX_CHATTER_COUNT) | ||
212 | { | ||
213 | ChatterCombo->remove(0); | ||
214 | } | ||
215 | |||
216 | LLMute mute(chat.mFromID, chat.mFromName); | ||
217 | if (chat.mSourceType == CHAT_SOURCE_OBJECT) | ||
218 | { | ||
219 | mute.mType = LLMute::OBJECT; | ||
220 | } | ||
221 | else if (chat.mSourceType == CHAT_SOURCE_AGENT) | ||
222 | { | ||
223 | mute.mType = LLMute::AGENT; | ||
224 | } | ||
225 | LLString item = mute.getDisplayName(); | ||
226 | ChatterCombo->add(item, chat.mFromID); | ||
227 | ChatterCombo->setCurrentByIndex(ChatterCombo->getItemCount() - 1); | ||
228 | gFloaterChat->childSetEnabled("Mute resident",TRUE); | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | |||
233 | // static | ||
234 | void LLFloaterChat::setHistoryCursorAndScrollToEnd() | ||
235 | { | ||
236 | if (gFloaterChat) | ||
237 | { | ||
238 | LLViewerTextEditor* HistoryEditor = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor"); | ||
239 | LLViewerTextEditor* HistoryEditorWithMute = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor with mute"); | ||
240 | |||
241 | HistoryEditor->setCursorAndScrollToEnd(); | ||
242 | HistoryEditorWithMute->setCursorAndScrollToEnd(); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | |||
247 | // static | ||
248 | void LLFloaterChat::toggle(void*) | ||
249 | { | ||
250 | if (gFloaterChat->getVisible()) | ||
251 | { | ||
252 | gFloaterChat->close(); | ||
253 | } | ||
254 | else | ||
255 | { | ||
256 | gFloaterChat->show(); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | // static | ||
261 | BOOL LLFloaterChat::visible(void*) | ||
262 | { | ||
263 | return (gFloaterChat && gFloaterChat->getVisible()); | ||
264 | } | ||
265 | |||
266 | //static | ||
267 | void LLFloaterChat::onClickMute(void *data) | ||
268 | { | ||
269 | LLFloaterChat* self = (LLFloaterChat*)data; | ||
270 | |||
271 | LLComboBox* ChatterCombo = LLUICtrlFactory::getComboBoxByName(self,"chatter combobox"); | ||
272 | |||
273 | const LLString& name = ChatterCombo->getSimple(); | ||
274 | LLUUID id = ChatterCombo->getCurrentID(); | ||
275 | |||
276 | if (name.empty()) return; | ||
277 | |||
278 | LLMute mute(id); | ||
279 | mute.setFromDisplayName(name); | ||
280 | gMuteListp->add(mute); | ||
281 | |||
282 | if (gFloaterMute) | ||
283 | { | ||
284 | gFloaterMute->show(); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | //static | ||
289 | void LLFloaterChat::onClickChat(void*) | ||
290 | { | ||
291 | // we need this function as a level of indirection because otherwise startChat would | ||
292 | // cast the data pointer to a character string, and dump garbage in the chat | ||
293 | LLChatBar::startChat(NULL); | ||
294 | } | ||
295 | |||
296 | //static | ||
297 | void LLFloaterChat::onCommitUserSelect(LLUICtrl* caller, void* data) | ||
298 | { | ||
299 | LLFloaterChat* floater = (LLFloaterChat*)data; | ||
300 | LLComboBox* combo = (LLComboBox*)caller; | ||
301 | |||
302 | if (combo->getCurrentIndex() == -1) | ||
303 | { | ||
304 | floater->childSetEnabled("Mute resident",FALSE); | ||
305 | } | ||
306 | else | ||
307 | { | ||
308 | floater->childSetEnabled("Mute resident",TRUE); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | //static | ||
313 | void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data) | ||
314 | { | ||
315 | LLFloaterChat* floater = (LLFloaterChat*)data; | ||
316 | |||
317 | |||
318 | //LLCheckBoxCtrl* | ||
319 | BOOL show_mute = LLUICtrlFactory::getCheckBoxByName(floater,"show mutes")->get(); | ||
320 | LLViewerTextEditor* HistoryEditor = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor"); | ||
321 | LLViewerTextEditor* HistoryEditorWithMute = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor with mute"); | ||
322 | |||
323 | if (!HistoryEditor || !HistoryEditorWithMute) | ||
324 | return; | ||
325 | |||
326 | //BOOL show_mute = floater->mShowMuteCheckBox->get(); | ||
327 | if (show_mute) | ||
328 | { | ||
329 | HistoryEditor->setVisible(FALSE); | ||
330 | HistoryEditorWithMute->setVisible(TRUE); | ||
331 | HistoryEditorWithMute->setCursorAndScrollToEnd(); | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | HistoryEditor->setVisible(TRUE); | ||
336 | HistoryEditorWithMute->setVisible(FALSE); | ||
337 | HistoryEditor->setCursorAndScrollToEnd(); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | // Put a line of chat in all the right places | ||
342 | void LLFloaterChat::addChat(const LLChat& chat, | ||
343 | BOOL from_instant_message, | ||
344 | BOOL local_agent) | ||
345 | { | ||
346 | LLColor4 text_color = get_text_color(chat); | ||
347 | |||
348 | BOOL invisible_script_debug_chat = | ||
349 | chat.mChatType == CHAT_TYPE_DEBUG_MSG | ||
350 | && !gSavedSettings.getBOOL("ScriptErrorsAsChat"); | ||
351 | |||
352 | if (!invisible_script_debug_chat | ||
353 | && !chat.mMuted | ||
354 | && gConsole | ||
355 | && !local_agent) | ||
356 | { | ||
357 | F32 size = CHAT_MSG_SIZE; | ||
358 | if(from_instant_message) | ||
359 | { | ||
360 | text_color = INSTANT_MSG_COLOR; | ||
361 | size = INSTANT_MSG_SIZE; | ||
362 | } | ||
363 | gConsole->addLine(chat.mText, size, text_color); | ||
364 | } | ||
365 | |||
366 | if( !from_instant_message || gSavedSettings.getBOOL("IMInChatHistory") ) | ||
367 | { | ||
368 | addChatHistory(chat); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | LLColor4 get_text_color(const LLChat& chat) | ||
373 | { | ||
374 | LLColor4 text_color; | ||
375 | |||
376 | if(chat.mMuted) | ||
377 | { | ||
378 | text_color.setVec(0.8f, 0.8f, 0.8f, 1.f); | ||
379 | } | ||
380 | else | ||
381 | { | ||
382 | switch(chat.mSourceType) | ||
383 | { | ||
384 | case CHAT_SOURCE_SYSTEM: | ||
385 | text_color = gSavedSettings.getColor4("SystemChatColor"); | ||
386 | break; | ||
387 | case CHAT_SOURCE_AGENT: | ||
388 | if (chat.mFromID.isNull()) | ||
389 | { | ||
390 | text_color = gSavedSettings.getColor4("SystemChatColor"); | ||
391 | } | ||
392 | else | ||
393 | { | ||
394 | text_color = gSavedSettings.getColor4("AgentChatColor"); | ||
395 | } | ||
396 | break; | ||
397 | case CHAT_SOURCE_OBJECT: | ||
398 | if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) | ||
399 | { | ||
400 | text_color = gSavedSettings.getColor4("ScriptErrorColor"); | ||
401 | } | ||
402 | else | ||
403 | { | ||
404 | text_color = gSavedSettings.getColor4("ObjectChatColor"); | ||
405 | } | ||
406 | break; | ||
407 | default: | ||
408 | text_color.setToWhite(); | ||
409 | } | ||
410 | |||
411 | if (!chat.mPosAgent.isExactlyZero()) | ||
412 | { | ||
413 | LLVector3 pos_agent = gAgent.getPositionAgent(); | ||
414 | F32 distance = dist_vec(pos_agent, chat.mPosAgent); | ||
415 | if (distance > gAgent.getNearChatRadius()) | ||
416 | { | ||
417 | // diminish far-off chat | ||
418 | text_color.mV[VALPHA] = 0.8f; | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | |||
423 | return text_color; | ||
424 | } | ||
425 | |||
426 | //static | ||
427 | void LLFloaterChat::loadHistory() | ||
428 | { | ||
429 | LLLogChat::loadHistory("chat", &chatFromLogFile, (void *)gFloaterChat); | ||
430 | } | ||
431 | |||
432 | //static | ||
433 | void LLFloaterChat::chatFromLogFile(LLString line, void* userdata) | ||
434 | { | ||
435 | LLChat chat; | ||
436 | |||
437 | chat.mText = line; | ||
438 | addChatHistory(chat, FALSE); | ||
439 | } | ||