aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloaterchatterbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llfloaterchatterbox.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterchatterbox.cpp b/linden/indra/newview/llfloaterchatterbox.cpp
new file mode 100644
index 0000000..11d2ee6
--- /dev/null
+++ b/linden/indra/newview/llfloaterchatterbox.cpp
@@ -0,0 +1,342 @@
1/**
2 * @file llfloaterchatterbox.cpp
3 * @author Richard
4 * @date 2007-05-08
5 * @brief Implementation of the chatterbox integrated conversation ui
6 *
7 * Copyright (c) 2007-2007, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlife.com/developers/opensource/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlife.com/developers/opensource/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 */
30
31
32#include "llviewerprecompiledheaders.h"
33
34#include "llfloaterchatterbox.h"
35#include "llvieweruictrlfactory.h"
36#include "llfloaterchat.h"
37#include "llfloaterfriends.h"
38#include "llfloatergroups.h"
39#include "llviewercontrol.h"
40#include "llimview.h"
41#include "llimpanel.h"
42
43//
44// LLFloaterMyFriends
45//
46
47LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed)
48{
49 mFactoryMap["friends_panel"] = LLCallbackMap(LLFloaterMyFriends::createFriendsPanel, NULL);
50 mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL);
51 // do not automatically open singleton floaters (as result of getInstance())
52 BOOL no_open = FALSE;
53 gUICtrlFactory->buildFloater(this, "floater_my_friends.xml", &getFactoryMap(), no_open);
54}
55
56LLFloaterMyFriends::~LLFloaterMyFriends()
57{
58}
59
60BOOL LLFloaterMyFriends::postBuild()
61{
62 mTabs = LLUICtrlFactory::getTabContainerByName(this, "friends_and_groups");
63
64 return TRUE;
65}
66
67
68void LLFloaterMyFriends::onClose(bool app_quitting)
69{
70 setVisible(FALSE);
71}
72
73//static
74LLFloaterMyFriends* LLFloaterMyFriends::showInstance(const LLSD& id)
75{
76 LLFloaterMyFriends* floaterp = LLUIInstanceMgr<LLFloaterMyFriends>::showInstance(id);
77 // garbage values in id will be interpreted as 0, or the friends tab
78 floaterp->mTabs->selectTab(id);
79
80 return floaterp;
81}
82
83//static
84void LLFloaterMyFriends::hideInstance(const LLSD& id)
85{
86 if(instanceVisible(id))
87 {
88 LLFloaterChatterBox::hideInstance(LLSD());
89 }
90}
91
92// is the specified panel currently visible
93//static
94BOOL LLFloaterMyFriends::instanceVisible(const LLSD& id)
95{
96 // if singleton not created yet, trivially return false
97 if (!findInstance(id)) return FALSE;
98
99 LLFloaterMyFriends* floaterp = getInstance(id);
100 return floaterp->isInVisibleChain() && floaterp->mTabs->getCurrentPanelIndex() == id.asInteger();
101}
102
103//static
104void* LLFloaterMyFriends::createFriendsPanel(void* data)
105{
106 return new LLPanelFriends();
107}
108
109//static
110void* LLFloaterMyFriends::createGroupsPanel(void* data)
111{
112 return new LLPanelGroups();
113}
114
115//
116// LLFloaterChatterBox
117//
118LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) :
119 mActiveVoiceFloater(NULL)
120{
121 mAutoResize = FALSE;
122
123 gUICtrlFactory->buildFloater(this, "floater_chatterbox.xml", NULL, FALSE);
124 addFloater(LLFloaterMyFriends::getInstance(0), TRUE);
125 if (gSavedSettings.getBOOL("ChatHistoryTornOff"))
126 {
127 LLFloaterChat* floater_chat = LLFloaterChat::getInstance(LLSD());
128 // add then remove to set up relationship for re-attach
129 addFloater(floater_chat, FALSE);
130 removeFloater(floater_chat);
131 // reparent to floater view
132 gFloaterView->addChild(floater_chat);
133 }
134 else
135 {
136 addFloater(LLFloaterChat::getInstance(LLSD()), FALSE);
137 }
138 mTabContainer->lockTabs();
139}
140
141LLFloaterChatterBox::~LLFloaterChatterBox()
142{
143}
144
145BOOL LLFloaterChatterBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
146{
147 if (getEnabled()
148 && mask == MASK_CONTROL)
149 {
150 if (key == 'W')
151 {
152 LLFloater* floater = getActiveFloater();
153 // is user closeable and is system closeable
154 if (floater && floater->canClose())
155 {
156 if (floater->isCloseable())
157 {
158 floater->close();
159 }
160 else
161 {
162 // close chatterbox window if frontmost tab is reserved, non-closeable tab
163 // such as contacts or near me
164 close();
165 }
166 }
167 return TRUE;
168 }
169 }
170
171 return LLMultiFloater::handleKeyHere(key, mask, called_from_parent);
172}
173
174void LLFloaterChatterBox::draw()
175{
176 // clear new im notifications when chatterbox is visible
177 if (!isMinimized())
178 {
179 gIMMgr->clearNewIMNotification();
180 }
181 LLFloater* current_active_floater = getCurrentVoiceFloater();
182 // set icon on tab for floater currently associated with active voice channel
183 if(mActiveVoiceFloater != current_active_floater)
184 {
185 // remove image from old floater's tab
186 if (mActiveVoiceFloater)
187 {
188 mTabContainer->setTabImage(mActiveVoiceFloater, "");
189 }
190 }
191
192 // update image on current active tab
193 if (current_active_floater)
194 {
195 LLColor4 icon_color = LLColor4::white;
196 LLVoiceChannel* channelp = LLVoiceChannel::getCurrentVoiceChannel();
197 if (channelp)
198 {
199 if (channelp->isActive())
200 {
201 icon_color = LLColor4::green;
202 }
203 else if (channelp->getState() == LLVoiceChannel::STATE_ERROR)
204 {
205 icon_color = LLColor4::red;
206 }
207 else // active, but not connected
208 {
209 icon_color = LLColor4::yellow;
210 }
211 }
212 mTabContainer->setTabImage(current_active_floater, "active_voice_tab.tga", icon_color);
213 }
214
215 mActiveVoiceFloater = current_active_floater;
216
217 LLFloater::draw();
218}
219
220void LLFloaterChatterBox::onOpen()
221{
222 gSavedSettings.setBOOL("ShowCommunicate", TRUE);
223}
224
225void LLFloaterChatterBox::onClose(bool app_quitting)
226{
227 setVisible(FALSE);
228 gSavedSettings.setBOOL("ShowCommunicate", FALSE);
229}
230
231void LLFloaterChatterBox::removeFloater(LLFloater* floaterp)
232{
233 if (floaterp->getName() == "chat floater")
234 {
235 // only my friends floater now locked
236 mTabContainer->lockTabs(1);
237 gSavedSettings.setBOOL("ChatHistoryTornOff", TRUE);
238 floaterp->setCanClose(TRUE);
239 }
240 LLMultiFloater::removeFloater(floaterp);
241}
242
243void LLFloaterChatterBox::addFloater(LLFloater* floaterp,
244 BOOL select_added_floater,
245 LLTabContainerCommon::eInsertionPoint insertion_point)
246{
247 // make sure my friends and chat history both locked when re-attaching chat history
248 if (floaterp->getName() == "chat floater")
249 {
250 // select my friends tab
251 mTabContainer->selectFirstTab();
252 // add chat history to the right of the my friends tab
253 //*TODO: respect select_added_floater so that we don't leave first tab selected
254 LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT);
255 // make sure first two tabs are now locked
256 mTabContainer->lockTabs(2);
257 gSavedSettings.setBOOL("ChatHistoryTornOff", FALSE);
258 floaterp->setCanClose(FALSE);
259 }
260 else
261 {
262 LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
263 }
264
265 // make sure active voice icon shows up for new tab
266 if (floaterp == mActiveVoiceFloater)
267 {
268 mTabContainer->setTabImage(floaterp, "active_voice_tab.tga");
269 }
270}
271
272
273//static
274LLFloaterChatterBox* LLFloaterChatterBox::showInstance(const LLSD& seed)
275{
276 LLFloaterChatterBox* floater = LLUISingleton<LLFloaterChatterBox>::showInstance(seed);
277
278 // if TRUE, show tab for active voice channel, otherwise, just show last tab
279 if (seed.asBoolean())
280 {
281 LLFloater* floater_to_show = getCurrentVoiceFloater();
282 if (floater_to_show)
283 {
284 floater_to_show->open();
285 }
286 else
287 {
288 // just open chatterbox if there is no active voice window
289 LLUISingleton<LLFloaterChatterBox>::getInstance(seed)->open();
290 }
291 }
292
293 return floater;
294}
295
296//static
297BOOL LLFloaterChatterBox::instanceVisible(const LLSD &seed)
298{
299 if (seed.asBoolean())
300 {
301 LLFloater* floater_to_show = getCurrentVoiceFloater();
302 if (floater_to_show)
303 {
304 return floater_to_show->isInVisibleChain();
305 }
306 }
307
308 return LLUISingleton<LLFloaterChatterBox>::instanceVisible(seed);
309}
310
311//static
312LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
313{
314 if (!LLVoiceClient::voiceEnabled())
315 {
316 return NULL;
317 }
318 if (LLVoiceChannelProximal::getInstance() == LLVoiceChannel::getCurrentVoiceChannel())
319 {
320 // show near me tab if in proximal channel
321 return LLFloaterChat::getInstance(LLSD());
322 }
323 else
324 {
325 LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(LLSD());
326 // iterator over all IM tabs (skip friends and near me)
327 for (S32 i = 0; i < floater->getFloaterCount(); i++)
328 {
329 LLPanel* panelp = floater->mTabContainer->getPanelByIndex(i);
330 if (panelp->getName() == "im_floater")
331 {
332 // only LLFloaterIMPanels are called "im_floater"
333 LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
334 if (im_floaterp->getVoiceChannel() == LLVoiceChannel::getCurrentVoiceChannel())
335 {
336 return im_floaterp;
337 }
338 }
339 }
340 }
341 return NULL;
342}