aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloaterchat.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloaterchat.cpp
parentREADME.txt (diff)
downloadmeta-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.cpp439
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//
72const char FLOATER_TITLE[] = "Chat History";
73const F32 INSTANT_MSG_SIZE = 8.0f;
74const F32 CHAT_MSG_SIZE = 8.0f;
75const LLColor4 INSTANT_MSG_COLOR(1, 1, 1, 1);
76const LLColor4 MUTED_MSG_COLOR(0.5f, 0.5f, 0.5f, 1.f);
77const S32 MAX_CHATTER_COUNT = 16;
78
79//
80// Global statics
81//
82LLFloaterChat* gFloaterChat = NULL;
83
84LLColor4 get_text_color(const LLChat& chat);
85
86//
87// Member Functions
88//
89LLFloaterChat::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
104LLFloaterChat::~LLFloaterChat()
105{
106 // Children all cleaned up by default view destructor.
107}
108
109void 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
121void 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
136void LLFloaterChat::show()
137{
138 open();
139}
140
141void 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
153void 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
234void 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
248void LLFloaterChat::toggle(void*)
249{
250 if (gFloaterChat->getVisible())
251 {
252 gFloaterChat->close();
253 }
254 else
255 {
256 gFloaterChat->show();
257 }
258}
259
260// static
261BOOL LLFloaterChat::visible(void*)
262{
263 return (gFloaterChat && gFloaterChat->getVisible());
264}
265
266//static
267void 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
289void 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
297void 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
313void 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
342void 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
372LLColor4 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
427void LLFloaterChat::loadHistory()
428{
429 LLLogChat::loadHistory("chat", &chatFromLogFile, (void *)gFloaterChat);
430}
431
432//static
433void LLFloaterChat::chatFromLogFile(LLString line, void* userdata)
434{
435 LLChat chat;
436
437 chat.mText = line;
438 addChatHistory(chat, FALSE);
439}