/** * @file llfloaterchatterbox.cpp * @author Richard * @date 2007-05-08 * @brief Implementation of the chatterbox integrated conversation ui * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llfloaterreg.h" #include "llfloaterchatterbox.h" #include "lluictrlfactory.h" #include "llfloaterfriends.h" #include "llfloatergroups.h" #include "llviewercontrol.h" #include "llvoicechannel.h" #include "llimpanel.h" #include "llimview.h" // // LLFloaterMyFriends // LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed) : LLFloater(seed) { mFactoryMap["friends_panel"] = LLCallbackMap(LLFloaterMyFriends::createFriendsPanel, NULL); mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL); //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_my_friends.xml"); } LLFloaterMyFriends::~LLFloaterMyFriends() { } BOOL LLFloaterMyFriends::postBuild() { return TRUE; } void LLFloaterMyFriends::onOpen(const LLSD& key) { if (key.asString() == "friends") { childShowTab("friends_and_groups", "friends_panel"); } else if (key.asString() == "groups") { childShowTab("friends_and_groups", "groups_panel"); } } //static void* LLFloaterMyFriends::createFriendsPanel(void* data) { return new LLPanelFriends(); } //static void* LLFloaterMyFriends::createGroupsPanel(void* data) { return new LLPanelGroups(); } //static LLFloaterMyFriends* LLFloaterMyFriends::getInstance() { return LLFloaterReg::getTypedInstance<LLFloaterMyFriends>("contacts", "friends") ; } // // LLFloaterChatterBox // LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) : LLMultiFloater(seed), mActiveVoiceFloater(NULL) { mAutoResize = FALSE; //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_chatterbox.xml", FALSE); } LLFloaterChatterBox::~LLFloaterChatterBox() { } BOOL LLFloaterChatterBox::postBuild() { setVisibleCallback(boost::bind(&LLFloaterChatterBox::onVisibilityChange, this, _2)); if (gSavedSettings.getBOOL("ContactsTornOff")) { LLFloaterMyFriends* floater_contacts = LLFloaterMyFriends::getInstance(); if(floater_contacts) { // add then remove to set up relationship for re-attach addFloater(floater_contacts, FALSE); removeFloater(floater_contacts); // reparent to floater view gFloaterView->addChild(floater_contacts); } } else { addFloater(LLFloaterMyFriends::getInstance(), TRUE); } mTabContainer->lockTabs(); return TRUE; } BOOL LLFloaterChatterBox::handleKeyHere(KEY key, MASK mask) { if (key == 'W' && mask == MASK_CONTROL) { LLFloater* floater = getActiveFloater(); // is user closeable and is system closeable if (floater && floater->canClose()) { if (floater->isCloseable()) { floater->closeFloater(); } else { // close chatterbox window if frontmost tab is reserved, non-closeable tab // such as contacts or near me closeFloater(); } } return TRUE; } return LLMultiFloater::handleKeyHere(key, mask); } void LLFloaterChatterBox::draw() { // clear new im notifications when chatterbox is visible if (!isMinimized()) { gIMMgr->clearNewIMNotification(); } LLFloater* current_active_floater = getCurrentVoiceFloater(); // set icon on tab for floater currently associated with active voice channel if(mActiveVoiceFloater != current_active_floater) { // remove image from old floater's tab if (mActiveVoiceFloater) { mTabContainer->setTabImage(mActiveVoiceFloater, ""); } } // update image on current active tab if (current_active_floater) { LLColor4 icon_color = LLColor4::white; LLVoiceChannel* channelp = LLVoiceChannel::getCurrentVoiceChannel(); if (channelp) { if (channelp->isActive()) { icon_color = LLColor4::green; } else if (channelp->getState() == LLVoiceChannel::STATE_ERROR) { icon_color = LLColor4::red; } else // active, but not connected { icon_color = LLColor4::yellow; } } mTabContainer->setTabImage(current_active_floater, "active_voice_tab.tga", icon_color); } mActiveVoiceFloater = current_active_floater; LLMultiFloater::draw(); } void LLFloaterChatterBox::onOpen(const LLSD& key) { //*TODO:Skinning show the session id associated with key if (key.asString() == "local") { } else if (key.isDefined()) { /*LLFloaterIMPanel* impanel = gIMMgr->findFloaterBySession(key.asUUID()); if (impanel) { impanel->openFloater(); }*/ } } void LLFloaterChatterBox::onVisibilityChange ( const LLSD& new_visibility ) { } void LLFloaterChatterBox::removeFloater(LLFloater* floaterp) { if(!floaterp) return; if (floaterp->getName() == "chat floater") { // only my friends floater now locked mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1); gSavedSettings.setBOOL("ChatHistoryTornOff", TRUE); floaterp->setCanClose(TRUE); } else if (floaterp->getName() == "floater_my_friends") { // only chat floater now locked mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1); gSavedSettings.setBOOL("ContactsTornOff", TRUE); floaterp->setCanClose(TRUE); } LLMultiFloater::removeFloater(floaterp); } void LLFloaterChatterBox::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point) { if(!floaterp) return; S32 num_locked_tabs = mTabContainer->getNumLockedTabs(); // already here if (floaterp->getHost() == this) { openFloater(floaterp->getKey()); return; } // make sure my friends and chat history both locked when re-attaching chat history if (floaterp->getName() == "chat floater") { mTabContainer->unlockTabs(); // add chat history as second tab if contact window is present, first tab otherwise if (getChildView("floater_my_friends")) { // assuming contacts window is first tab, select it mTabContainer->selectFirstTab(); // and add ourselves after LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT); } else { LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START); } // make sure first two tabs are now locked mTabContainer->lockTabs(num_locked_tabs + 1); gSavedSettings.setBOOL("ChatHistoryTornOff", FALSE); floaterp->setCanClose(FALSE); } else if (floaterp->getName() == "floater_my_friends") { mTabContainer->unlockTabs(); // add contacts window as first tab LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START); // make sure first two tabs are now locked mTabContainer->lockTabs(num_locked_tabs + 1); gSavedSettings.setBOOL("ContactsTornOff", FALSE); floaterp->setCanClose(FALSE); } else { LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); // openFloater(floaterp->getKey()); } // make sure active voice icon shows up for new tab if (floaterp == mActiveVoiceFloater) { mTabContainer->setTabImage(floaterp, "active_voice_tab.tga"); } } //static LLFloaterChatterBox* LLFloaterChatterBox::getInstance() { return LLFloaterReg::getTypedInstance<LLFloaterChatterBox>("communicate", LLSD()) ; } //static LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater() { if (!LLVoiceClient::getInstance()->voiceEnabled()) { return NULL; } if (LLVoiceChannelProximal::getInstance() == LLVoiceChannel::getCurrentVoiceChannel()) { return NULL; } else { LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(); if(!floater) return NULL; // iterator over all IM tabs (skip friends and near me) for (S32 i = 0; i < floater->getFloaterCount(); i++) { LLPanel* panelp = floater->mTabContainer->getPanelByIndex(i); if (panelp->getName() == "im_floater") { // only LLFloaterIMPanels are called "im_floater" LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp; LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID()); if (voice_channel == LLVoiceChannel::getCurrentVoiceChannel()) { return im_floaterp; } } } } return NULL; }