llfloaterchat.cpp

Go to the documentation of this file.
00001 
00037 #include "llviewerprecompiledheaders.h"
00038 #include <iostream>
00039 
00040 #include "llfloaterchat.h"
00041 #include "llfloateractivespeakers.h"
00042 #include "llfloaterscriptdebug.h"
00043 
00044 #include "llchat.h"
00045 #include "llfontgl.h"
00046 #include "llrect.h"
00047 #include "llerror.h"
00048 #include "llstring.h"
00049 #include "message.h"
00050 
00051 // project include
00052 #include "llagent.h"
00053 #include "llbutton.h"
00054 #include "llcheckboxctrl.h"
00055 #include "llcombobox.h"
00056 #include "llconsole.h"
00057 #include "llfloaterchatterbox.h"
00058 #include "llfloatermute.h"
00059 #include "llkeyboard.h"
00060 //#include "lllineeditor.h"
00061 #include "llmutelist.h"
00062 #include "llregionnamecache.h"
00063 //#include "llresizehandle.h"
00064 #include "llchatbar.h"
00065 #include "lllineeditor.h"
00066 #include "llstatusbar.h"
00067 #include "lltextbox.h"
00068 #include "llviewertexteditor.h"
00069 #include "llviewergesture.h"                    // for triggering gestures
00070 #include "llviewermessage.h"
00071 #include "llviewerwindow.h"
00072 #include "llviewercontrol.h"
00073 #include "llvieweruictrlfactory.h"
00074 #include "llviewerobjectlist.h"
00075 #include "llviewerregion.h"
00076 #include "llchatbar.h"
00077 #include "lllogchat.h"
00078 #include "lltexteditor.h"
00079 #include "llfloaterhtml.h"
00080 #include "llweb.h"
00081 
00082 #include <algorithm>  // For find
00083 
00084 // Used for LCD display
00085 extern void AddNewIMToLCD(const LLString &newLine);
00086 extern void AddNewChatToLCD(const LLString &newLine);
00087 //
00088 // Constants
00089 //
00090 const F32 INSTANT_MSG_SIZE = 8.0f;
00091 const F32 CHAT_MSG_SIZE = 8.0f;
00092 const LLColor4 INSTANT_MSG_COLOR(1, 1, 1, 1);
00093 const LLColor4 MUTED_MSG_COLOR(0.5f, 0.5f, 0.5f, 1.f);
00094 const S32 MAX_CHATTER_COUNT = 16;
00095 
00096 //
00097 // Global statics
00098 //
00099 LLColor4 get_text_color(const LLChat& chat);
00100 
00101 //
00102 // Member Functions
00103 //
00104 LLFloaterChat::LLFloaterChat(const LLSD& seed)
00105 :       LLFloater("chat floater", "FloaterChatRect", "", 
00106                           RESIZE_YES, 440, 100, DRAG_ON_TOP, MINIMIZE_NO, CLOSE_YES),
00107         mPanel(NULL)
00108 {
00109         mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL);
00110         mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
00111         // do not automatically open singleton floaters (as result of getInstance())
00112         BOOL no_open = FALSE;
00113         gUICtrlFactory->buildFloater(this,"floater_chat_history.xml",&getFactoryMap(),no_open);
00114 
00115         childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes
00116         childSetVisible("Chat History Editor with mute",FALSE);
00117         childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
00118         setDefaultBtn("Chat");
00119 }
00120 
00121 LLFloaterChat::~LLFloaterChat()
00122 {
00123         // Children all cleaned up by default view destructor.
00124 }
00125 
00126 void LLFloaterChat::setVisible(BOOL visible)
00127 {
00128         LLFloater::setVisible( visible );
00129 
00130         gSavedSettings.setBOOL("ShowChatHistory", visible);
00131 }
00132 
00133 void LLFloaterChat::draw()
00134 {
00135         // enable say and shout only when text available
00136                 
00137         childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
00138 
00139         LLChatBar* chat_barp = (LLChatBar*)getChildByName("chat_panel", TRUE);
00140         if (chat_barp)
00141         {
00142                 chat_barp->refresh();
00143         }
00144 
00145         mPanel->refreshSpeakers();
00146         LLFloater::draw();
00147 }
00148 
00149 BOOL LLFloaterChat::postBuild()
00150 {
00151         mPanel = (LLPanelActiveSpeakers*)LLUICtrlFactory::getPanelByName(this, "active_speakers_panel");
00152 
00153         LLChatBar* chat_barp = (LLChatBar*)getChildByName("chat_panel", TRUE);
00154         if (chat_barp)
00155         {
00156                 chat_barp->setGestureCombo(LLUICtrlFactory::getComboBoxByName(this, "Gesture"));
00157         }
00158         return TRUE;
00159 }
00160 
00161 // public virtual
00162 void LLFloaterChat::onClose(bool app_quitting)
00163 {
00164         if (!app_quitting)
00165         {
00166                 gSavedSettings.setBOOL("ShowChatHistory", FALSE);
00167         }
00168         setVisible(FALSE);
00169 }
00170 
00171 void LLFloaterChat::onVisibilityChange(BOOL new_visibility)
00172 {
00173         // Hide the chat overlay when our history is visible.
00174         gConsole->setVisible( !new_visibility );
00175         LLFloater::onVisibilityChange(new_visibility);
00176 }
00177 
00178 
00179 void add_timestamped_line(LLViewerTextEditor* edit, const LLString& line, const LLColor4& color)
00180 {
00181         bool prepend_newline = true;
00182         if (gSavedSettings.getBOOL("ChatShowTimestamps"))
00183         {
00184                 edit->appendTime(prepend_newline);
00185                 prepend_newline = false;
00186         }
00187         edit->appendColoredText(line, false, prepend_newline, color);
00188 }
00189 
00190 void log_chat_text(const LLChat& chat)
00191 {
00192                 LLString histstr;
00193                 if ( chat.mFromIM )
00194                         histstr = "IM: ";
00195 
00196                 if (gSavedPerAccountSettings.getBOOL("LogChatTimestamp"))
00197                         histstr += LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + chat.mText;
00198                 else
00199                         histstr += chat.mText;
00200 
00201                 LLLogChat::saveHistory("chat",histstr);
00202 }
00203 
00204 LLString LLFloaterChat::getChatAvatar(const LLChat& chat)
00205 {
00206         if ( chat.mFromIM || chat.mSourceType == CHAT_SOURCE_AGENT )
00207         {
00208                 // Chat is from an IM, so the speaker is the actual avatar
00209                 return getAvatarName(chat.mFromID, chat.mFromName);
00210         }
00211         else
00212         {
00213                 // this is llSay or similar, the speaker is the object
00214                 LLUUID chatter_id = mObjectOwners[chat.mFromID].mOwnerID;
00215                 mObjectOwners[chat.mFromID].mObjectName = chat.mFromName;
00216 
00217                 if ( chatter_id.isNull() )
00218                 {
00219                         // Owner is unknown, request
00220                         requestObjectOwner(chat.mFromID, chat.mSourceHost);
00221                         return "";
00222                 }
00223                 else
00224                 {
00225                         return getAvatarName(chatter_id, chat.mFromName);
00226                 }
00227         }
00228 }
00229 
00230 
00231 LLString LLFloaterChat::getAvatarName(const LLUUID &speaker_id, const LLString &speaker_name)
00232 {
00233         LLString ret = "";      
00234 
00235         if ( !speaker_id.isNull() )
00236         {
00237                 // Get actual name of the speaker. This will differ if it's an object talking
00238                 char first_name[DB_FIRST_NAME_BUF_SIZE];                /* Flawfinder: ignore */
00239                 char last_name[DB_FIRST_NAME_BUF_SIZE];         /* Flawfinder: ignore */
00240                 first_name[0] = '\0';
00241                 last_name[0] = '\0';
00242 
00243                 if ( gCacheName->getName(speaker_id, first_name, last_name) )
00244                 {
00245                         // Name was in cache, good
00246                         ret = first_name;
00247                         ret += " ";
00248                         ret += last_name;
00249         
00250                         if ( ret == speaker_name )
00251                         {
00252                                 // Don't add the info if it matches what would appear as the speaker's name
00253                                 ret = "";
00254                         }
00255                 }
00256                 else
00257                 {
00258                         // Name not in the cache, but we don't want to lose it, so we queue it up.
00259                         LLNameLookupEntry ent(speaker_id, speaker_name);
00260 
00261                         std::deque<LLNameLookupEntry>::iterator pos = std::find(mLookupQueue.begin(), mLookupQueue.end(), ent);
00262                         S32 dist = 0;
00263 
00264                         if ( pos == mLookupQueue.end() )
00265                         {
00266                                 mLookupQueue.push_back(ent);
00267                                 dist = mLookupQueue.size();
00268 
00269                                 // request the name, write to window later.
00270                                 gCacheName->get(speaker_id, FALSE, cache_name_callback, this);
00271                         }
00272                         else
00273                         {
00274                                 dist = std::distance(mLookupQueue.begin(), pos);
00275                         }
00276 
00277                         std::ostringstream o;
00278                         o << dist+1;
00279 
00280                         ret = "";
00281                 }
00282         }
00283 
00284         return ret;
00285 }
00286 
00287 //static
00288 void LLFloaterChat::requestObjectOwner(const LLUUID &object_id, const LLHost &host)
00289 {
00290         if ( object_id.isNull() ) return;
00291 
00292         llinfos << "Requesting object data for " << object_id << llendl;
00293 
00294         LLMessageSystem* msg = gMessageSystem;
00295 
00296         msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
00297         msg->nextBlockFast(_PREHASH_AgentData);
00298         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00299         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00300         msg->nextBlockFast(_PREHASH_ObjectData);
00301         msg->addU32Fast(_PREHASH_RequestFlags, 0x0 );
00302         msg->addUUIDFast(_PREHASH_ObjectID, object_id );
00303         
00304 //      LLViewerObject *chatter = gObjectList.findObject(object_id);
00305 //      LLViewerRegion *regionp;
00306 //      if ( chatter )
00307 //      {
00308 //              regionp = chatter->getRegion();
00309 //      }
00310 //      else
00311 //      {
00312 //              llwarns << "Couldn't find speaking object " << object_id << ", don't know which region to use for the message. Trying with agent's" << llendl;
00313 //              regionp = gAgent.getRegion();
00314 //      }
00315 
00316 
00317         //msg->sendReliable( regionp->getHost() );
00318         msg->sendReliable( host );
00319 }
00320 
00321 //static
00322 void LLFloaterChat::processObjectPropertiesFamily(LLMessageSystem *msg, void **user_data)
00323 {
00324 
00325         LLUUID id;
00326         LLUUID owner_id;
00327         U32 request_flags;
00328 
00329         msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags,     request_flags );
00330         msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID,                id );
00331         msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID,         owner_id );
00332 
00333         LLFloaterChat* chat_floater = LLFloaterChat::getInstance(LLSD());
00334 
00335         llinfos << "Processing properties for " << id << ". Owner is " << owner_id << llendl;
00336 
00337         if ( chat_floater->mObjectOwners.count( id ) > 0 )
00338         {
00339                 // We've got an entry for this object, so we were looking for information on it
00340                 LLOwnerCacheEntry *ent = &chat_floater->mObjectOwners[id];
00341 
00342                 if ( ent->mOwnerID == LLUUID::null )
00343                 {
00344                         // We were looking for info, and it just arrived.
00345                         llinfos << "First arrival of requested data for object " << id << llendl;
00346                         LLString name = chat_floater->getAvatarName(owner_id, ent->mObjectName);
00347                         if ( !name.empty() )
00348                         {
00349                                 LLChat chat(ent->mObjectName + " is owned by " + name);
00350                                 chat.mFromName = "Name Lookup";
00351                                 addChatHistory(chat);
00352                         }
00353                         else
00354                         {
00355                                 llinfos << "Got owner, but name lookup failed for " << owner_id << ", queueing up" << llendl;
00356                         }
00357                 }
00358 
00359                 ent->mOwnerID = owner_id;
00360         }
00361 }
00362 //static
00363 void LLFloaterChat::cache_name_callback(const LLUUID &id, const char *first, const char *last, BOOL is_group, void *data)
00364 {
00365         LLFloaterChat *floater = (LLFloaterChat*)data;
00366 
00367         std::deque<LLNameLookupEntry>::iterator pos = std::find(floater->mLookupQueue.begin(), floater->mLookupQueue.end(), LLNameLookupEntry(id));
00368         if ( pos == floater->mLookupQueue.end() )
00369         {
00370                 llwarns << "Strange, callback called, but we weren't looking for UUID " << id << llendl;
00371                 return;
00372         }
00373 
00374         LLString name = first;
00375         name += " ";
00376         name += last;
00377 
00378         LLChat chat(pos->mObject + " is owned by " + name);
00379         chat.mFromName = "Name Lookup";
00380 
00381         floater->mLookupQueue.erase(pos);
00382         addChatHistory(chat);
00383 }
00384 
00385 // static
00386 LLString LLFloaterChat::getChatPosition(const LLChat &chat)
00387 {
00388         if ( chat.mRegionID.isNull() ) return "";
00389         return llformat("secondlife://%s/%.0f/%.0f/%.0f", gRegionNameCache->get( chat.mRegionID ).c_str(),
00390                                                           chat.mPosAgent.mV[VX],
00391                                                           chat.mPosAgent.mV[VY],
00392                                                           chat.mPosAgent.mV[VZ]);
00393 }
00394 
00395 // static
00396 void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
00397 {       
00398         if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file) 
00399         {
00400                 log_chat_text(chat);
00401         }
00402         
00403         LLColor4 color = get_text_color(chat);
00404         
00405         if (!log_to_file) color = LLColor4::grey;       //Recap from log file.
00406 
00407         if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
00408         {
00409                 LLFloaterScriptDebug::addScriptLine(chat.mText,
00410                                                                                         chat.mFromName, 
00411                                                                                         color, 
00412                                                                                         chat.mFromID);
00413                 if (!gSavedSettings.getBOOL("ScriptErrorsAsChat"))
00414                 {
00415                         return;
00416                 }
00417         }
00418         
00419         // could flash the chat button in the status bar here. JC
00420         LLFloaterChat* chat_floater = LLFloaterChat::getInstance(LLSD());
00421         LLViewerTextEditor*     history_editor = (LLViewerTextEditor*)chat_floater->getChildByName("Chat History Editor", TRUE);
00422         LLViewerTextEditor*     history_editor_with_mute = (LLViewerTextEditor*)chat_floater->getChildByName("Chat History Editor with mute", TRUE);
00423 
00424         history_editor->setParseHTML(TRUE);
00425         history_editor_with_mute->setParseHTML(TRUE);
00426         
00427         LLString owner_coords_line;
00428 
00429         if ( LLUICtrlFactory::getCheckBoxByName(chat_floater,"log owner coords")->get() )
00430         {
00431                 // Add owner and position info, if needed
00432                 if ( !chat.mFromID.isNull() && chat.mSourceType == CHAT_SOURCE_OBJECT )
00433                 {
00434                         owner_coords_line = chat_floater->getChatAvatar(chat);
00435                         if ( owner_coords_line.empty() )
00436                         {
00437                                 owner_coords_line = "(requesting)";
00438                         }
00439                 }
00440 
00441                 LLString pos = getChatPosition(chat);
00442 
00443                 if ( !pos.empty() && !owner_coords_line.empty() ) 
00444                 {
00445                         owner_coords_line = "Owner: " + owner_coords_line;
00446                         owner_coords_line += " ";
00447                 }
00448 
00449                 if ( ! pos.empty() )
00450                 {
00451                         owner_coords_line += "at ";
00452                         owner_coords_line += pos;
00453                 }
00454 
00455                 if ( ! owner_coords_line.empty() )
00456                 {
00457                         owner_coords_line = " [" + owner_coords_line + "]";
00458                         //owner_coords_line = " " + owner_coords_line;
00459                 }
00460         }
00461 
00462         LLString chat_text(chat.mText + owner_coords_line);
00463         if ( chat.mFromIM )
00464         {
00465                 chat_text = "IM: " + chat_text;
00466         }
00467 
00468         if (!chat.mMuted)
00469         {
00470                 add_timestamped_line(history_editor, chat_text, color);
00471                 add_timestamped_line(history_editor_with_mute, chat_text, color);
00472         }
00473         else
00474         {
00475                 // desaturate muted chat
00476                 LLColor4 muted_color = lerp(color, LLColor4::grey, 0.5f);
00477                 add_timestamped_line(history_editor_with_mute, chat_text, color);
00478         }
00479         
00480         // add objects as transient speakers that can be muted
00481         if (chat.mSourceType == CHAT_SOURCE_OBJECT)
00482         {
00483                 chat_floater->mPanel->setSpeaker(chat.mFromID, chat.mFromName, LLSpeaker::STATUS_NOT_IN_CHANNEL, LLSpeaker::SPEAKER_OBJECT);
00484         }
00485 }
00486 
00487 // static
00488 void LLFloaterChat::setHistoryCursorAndScrollToEnd()
00489 {
00490         LLViewerTextEditor*     history_editor = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor", TRUE);
00491         LLViewerTextEditor*     history_editor_with_mute = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor with mute", TRUE);
00492         
00493         history_editor->setCursorAndScrollToEnd();
00494         history_editor_with_mute->setCursorAndScrollToEnd();
00495 }
00496 
00497 
00498 //static 
00499 void LLFloaterChat::onClickMute(void *data)
00500 {
00501         LLFloaterChat* self = (LLFloaterChat*)data;
00502 
00503         LLComboBox*     chatter_combo = LLUICtrlFactory::getComboBoxByName(self,"chatter combobox");
00504 
00505         const LLString& name = chatter_combo->getSimple();
00506         LLUUID id = chatter_combo->getCurrentID();
00507 
00508         if (name.empty()) return;
00509 
00510         LLMute mute(id);
00511         mute.setFromDisplayName(name);
00512         gMuteListp->add(mute);
00513         
00514         if (gFloaterMute)
00515         {
00516                 gFloaterMute->show();
00517         }
00518 }
00519 
00520 //static
00521 void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data)
00522 {
00523         LLFloaterChat* floater = (LLFloaterChat*)data;
00524 
00525 
00526         //LLCheckBoxCtrl*       
00527         BOOL show_mute = LLUICtrlFactory::getCheckBoxByName(floater,"show mutes")->get();
00528         LLViewerTextEditor*     history_editor = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor", TRUE);
00529         LLViewerTextEditor*     history_editor_with_mute = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor with mute", TRUE);
00530 
00531         if (!history_editor || !history_editor_with_mute)
00532                 return;
00533 
00534         //BOOL show_mute = floater->mShowMuteCheckBox->get();
00535         if (show_mute)
00536         {
00537                 history_editor->setVisible(FALSE);
00538                 history_editor_with_mute->setVisible(TRUE);
00539                 history_editor_with_mute->setCursorAndScrollToEnd();
00540         }
00541         else
00542         {
00543                 history_editor->setVisible(TRUE);
00544                 history_editor_with_mute->setVisible(FALSE);
00545                 history_editor->setCursorAndScrollToEnd();
00546         }
00547 }
00548 
00549 // Put a line of chat in all the right places
00550 void LLFloaterChat::addChat(const LLChat& chat,
00551                           BOOL local_agent)
00552 {
00553         LLColor4 text_color = get_text_color(chat);
00554 
00555         BOOL invisible_script_debug_chat = 
00556                         chat.mChatType == CHAT_TYPE_DEBUG_MSG
00557                         && !gSavedSettings.getBOOL("ScriptErrorsAsChat");
00558 
00559 #if LL_WINDOWS && LL_LCD_COMPILE
00560         // add into LCD displays
00561         if (!invisible_script_debug_chat)
00562         {
00563                 if (!from_instant_message)
00564                 {
00565                         AddNewChatToLCD(chat.mText);
00566                 }
00567                 else
00568                 {
00569                         AddNewIMToLCD(chat.mText);
00570                 }
00571         }
00572 #endif
00573         if (!invisible_script_debug_chat 
00574                 && !chat.mMuted 
00575                 && gConsole 
00576                 && !local_agent)
00577         {
00578                 F32 size = CHAT_MSG_SIZE;
00579                 LLString prefix;
00580                 if(chat.mFromIM)
00581                 {
00582                         text_color = INSTANT_MSG_COLOR;
00583                         size = INSTANT_MSG_SIZE;
00584                         prefix = "IM: ";
00585                 }
00586                 gConsole->addLine(prefix + chat.mText, size, text_color);
00587         }
00588 
00589         if(chat.mFromIM && gSavedPerAccountSettings.getBOOL("LogChatIM"))
00590                 log_chat_text(chat);
00591         
00592         if(chat.mFromIM && (gSavedSettings.getBOOL("IMInChatHistory") || chat.mSourceType != CHAT_SOURCE_AGENT) )
00593                 addChatHistory(chat,false);
00594         
00595         if(!chat.mFromIM)
00596                 addChatHistory(chat);
00597 }
00598 
00599 LLColor4 get_text_color(const LLChat& chat)
00600 {
00601         LLColor4 text_color;
00602 
00603         if(chat.mMuted)
00604         {
00605                 text_color.setVec(0.8f, 0.8f, 0.8f, 1.f);
00606         }
00607         else
00608         {
00609                 switch(chat.mSourceType)
00610                 {
00611                 case CHAT_SOURCE_SYSTEM:
00612                         text_color = gSavedSettings.getColor4("SystemChatColor");
00613                         break;
00614                 case CHAT_SOURCE_AGENT:
00615                     if (chat.mFromID.isNull())
00616                         {
00617                                 text_color = gSavedSettings.getColor4("SystemChatColor");
00618                         }
00619                         else
00620                         {
00621                                 text_color = gSavedSettings.getColor4("AgentChatColor");
00622                         }
00623                         break;
00624                 case CHAT_SOURCE_OBJECT:
00625                         if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
00626                         {
00627                                 text_color = gSavedSettings.getColor4("ScriptErrorColor");
00628                         }
00629                         else if ( chat.mChatType == CHAT_TYPE_OWNER )
00630                         {
00631                                 text_color = gSavedSettings.getColor4("llOwnerSayChatColor");
00632                         }
00633                         else
00634                         {
00635                                 text_color = gSavedSettings.getColor4("ObjectChatColor");
00636                         }
00637                         break;
00638                 default:
00639                         text_color.setToWhite();
00640                 }
00641 
00642                 if (!chat.mPosAgent.isExactlyZero())
00643                 {
00644                         LLVector3 pos_agent = gAgent.getPositionAgent();
00645                         F32 distance = dist_vec(pos_agent, chat.mPosAgent);
00646                         if (distance > gAgent.getNearChatRadius())
00647                         {
00648                                 // diminish far-off chat
00649                                 text_color.mV[VALPHA] = 0.8f;
00650                         }
00651                 }
00652         }
00653 
00654         return text_color;
00655 }
00656 
00657 //static
00658 void LLFloaterChat::loadHistory()
00659 {
00660         LLLogChat::loadHistory("chat", &chatFromLogFile, (void *)LLFloaterChat::getInstance(LLSD())); 
00661 }
00662 
00663 //static
00664 void LLFloaterChat::chatFromLogFile(LLString line, void* userdata)
00665 {
00666         LLChat chat;
00667                                 
00668         chat.mText = line;
00669         addChatHistory(chat,  FALSE);
00670 }
00671 
00672 //static
00673 void* LLFloaterChat::createSpeakersPanel(void* data)
00674 {
00675         return new LLPanelActiveSpeakers(gLocalSpeakerMgr, TRUE);
00676 }
00677 
00678 //static
00679 void* LLFloaterChat::createChatPanel(void* data)
00680 {
00681         LLChatBar* chatp = new LLChatBar("floating_chat_bar");
00682         return chatp;
00683 }
00684 
00685 //static 
00686 void LLFloaterChat::hideInstance(const LLSD& id)
00687 {
00688         LLFloaterChat* floaterp = LLFloaterChat::getInstance(LLSD());
00689         // don't do anything when hosted in the chatterbox
00690         if(floaterp->getHost())
00691         {
00692                 LLFloaterChatterBox::hideInstance(LLSD());
00693         }
00694         else
00695         {
00696                 LLUISingleton<LLFloaterChat>::hideInstance(id);
00697         }
00698 }
00699 
00700 // static
00701 void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata)
00702 {
00703         LLFloaterChat* self = (LLFloaterChat*)userdata;
00704 
00705         self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel"));
00706 }
00707 

Generated on Thu Jul 1 06:08:32 2010 for Second Life Viewer by  doxygen 1.4.7