PageRenderTime 131ms CodeModel.GetById 30ms app.highlight 49ms RepoModel.GetById 11ms app.codeStats 0ms

/indra/newview/llnearbychat.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 338 lines | 231 code | 63 blank | 44 comment | 38 complexity | 14dd42f5a19b9918afd5b5dfbdee12d9 MD5 | raw file
  1/** 
  2 * @file LLNearbyChat.cpp
  3 * @brief Nearby chat history scrolling panel implementation
  4 *
  5 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llnearbychat.h"
 30#include "llviewercontrol.h"
 31#include "llviewerwindow.h"
 32#include "llrootview.h"
 33//#include "llchatitemscontainerctrl.h"
 34#include "lliconctrl.h"
 35#include "llfloatersidepanelcontainer.h"
 36#include "llfocusmgr.h"
 37#include "lllogchat.h"
 38#include "llresizebar.h"
 39#include "llresizehandle.h"
 40#include "llmenugl.h"
 41#include "llviewermenu.h"//for gMenuHolder
 42
 43#include "llnearbychathandler.h"
 44#include "llchannelmanager.h"
 45
 46#include "llagent.h" 			// gAgent
 47#include "llchathistory.h"
 48#include "llstylemap.h"
 49
 50#include "llavatarnamecache.h"
 51
 52#include "lldraghandle.h"
 53
 54#include "llnearbychatbar.h"
 55#include "llfloaterreg.h"
 56#include "lltrans.h"
 57
 58static const S32 RESIZE_BAR_THICKNESS = 3;
 59
 60
 61static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
 62
 63LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p) 
 64:	LLPanel(p),
 65	mChatHistory(NULL)
 66{
 67}
 68
 69BOOL LLNearbyChat::postBuild()
 70{
 71	//menu
 72	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 73	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 74
 75	enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
 76	registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
 77
 78	
 79	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 80	if(menu)
 81		mPopupMenuHandle = menu->getHandle();
 82
 83	gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
 84
 85	mChatHistory = getChild<LLChatHistory>("chat_history");
 86
 87	if(!LLPanel::postBuild())
 88		return false;
 89	
 90	return true;
 91}
 92
 93std::string appendTime()
 94{
 95	time_t utc_time;
 96	utc_time = time_corrected();
 97	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
 98		+LLTrans::getString("TimeMin")+"]";
 99
100	LLSD substitution;
101
102	substitution["datetime"] = (S32) utc_time;
103	LLStringUtil::format (timeStr, substitution);
104
105	return timeStr;
106}
107
108
109void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
110{
111	LLChat& tmp_chat = const_cast<LLChat&>(chat);
112
113	if(tmp_chat.mTimeStr.empty())
114		tmp_chat.mTimeStr = appendTime();
115
116	bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
117	
118	if (!chat.mMuted)
119	{
120		tmp_chat.mFromName = chat.mFromName;
121		LLSD chat_args = args;
122		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
123		mChatHistory->appendMessage(chat, chat_args);
124	}
125
126	if(archive)
127	{
128		mMessageArchive.push_back(chat);
129		if(mMessageArchive.size()>200)
130			mMessageArchive.erase(mMessageArchive.begin());
131	}
132
133	if (args["do_not_log"].asBoolean()) 
134	{
135		return;
136	}
137
138	if (gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
139	{
140		std::string from_name = chat.mFromName;
141
142		if (chat.mSourceType == CHAT_SOURCE_AGENT)
143		{
144			// if the chat is coming from an agent, log the complete name
145			LLAvatarName av_name;
146			LLAvatarNameCache::get(chat.mFromID, &av_name);
147
148			if (!av_name.mIsDisplayNameDefault)
149			{
150				from_name = av_name.getCompleteName();
151			}
152		}
153
154		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
155	}
156}
157
158void LLNearbyChat::onNearbySpeakers()
159{
160	LLSD param;
161	param["people_panel_tab_name"] = "nearby_panel";
162	LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
163}
164
165
166void	LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
167{
168}
169bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
170{
171	std::string str = userdata.asString();
172	if(str == "nearby_people")
173		onNearbySpeakers();	
174	return false;
175}
176
177void LLNearbyChat::removeScreenChat()
178{
179	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
180	if(chat_channel)
181	{
182		chat_channel->removeToastsFromChannel();
183	}
184}
185
186void	LLNearbyChat::setVisible(BOOL visible)
187{
188	if(visible)
189	{
190		removeScreenChat();
191	}
192
193	LLPanel::setVisible(visible);
194}
195
196
197void LLNearbyChat::getAllowedRect(LLRect& rect)
198{
199	rect = gViewerWindow->getWorldViewRectScaled();
200}
201
202void LLNearbyChat::updateChatHistoryStyle()
203{
204	mChatHistory->clear();
205
206	LLSD do_not_log;
207	do_not_log["do_not_log"] = true;
208	for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
209	{
210		// Update the messages without re-writing them to a log file.
211		addMessage(*it,false, do_not_log);
212	}
213}
214
215//static 
216void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)
217{
218	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
219	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
220	if(nearby_chat)
221		nearby_chat->updateChatHistoryStyle();
222}
223
224bool isWordsName(const std::string& name)
225{
226	// checking to see if it's display name plus username in parentheses 
227	S32 open_paren = name.find(" (", 0);
228	S32 close_paren = name.find(')', 0);
229
230	if (open_paren != std::string::npos &&
231		close_paren == name.length()-1)
232	{
233		return true;
234	}
235	else
236	{
237		//checking for a single space
238		S32 pos = name.find(' ', 0);
239		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
240	}
241}
242
243void LLNearbyChat::loadHistory()
244{
245	LLSD do_not_log;
246	do_not_log["do_not_log"] = true;
247
248	std::list<LLSD> history;
249	LLLogChat::loadAllHistory("chat", history);
250
251	std::list<LLSD>::const_iterator it = history.begin();
252	while (it != history.end())
253	{
254		const LLSD& msg = *it;
255
256		std::string from = msg[IM_FROM];
257		LLUUID from_id;
258		if (msg[IM_FROM_ID].isDefined())
259		{
260			from_id = msg[IM_FROM_ID].asUUID();
261		}
262		else
263 		{
264			std::string legacy_name = gCacheName->buildLegacyName(from);
265 			gCacheName->getUUID(legacy_name, from_id);
266 		}
267
268		LLChat chat;
269		chat.mFromName = from;
270		chat.mFromID = from_id;
271		chat.mText = msg[IM_TEXT].asString();
272		chat.mTimeStr = msg[IM_TIME].asString();
273		chat.mChatStyle = CHAT_STYLE_HISTORY;
274
275		chat.mSourceType = CHAT_SOURCE_AGENT;
276		if (from_id.isNull() && SYSTEM_FROM == from)
277		{	
278			chat.mSourceType = CHAT_SOURCE_SYSTEM;
279			
280		}
281		else if (from_id.isNull())
282		{
283			chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
284		}
285
286		addMessage(chat, true, do_not_log);
287
288		it++;
289	}
290}
291
292//static
293LLNearbyChat* LLNearbyChat::getInstance()
294{
295	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
296	return chat_bar->findChild<LLNearbyChat>("nearby_chat");
297}
298
299////////////////////////////////////////////////////////////////////////////////
300//
301void LLNearbyChat::onFocusReceived()
302{
303	setBackgroundOpaque(true);
304	LLPanel::onFocusReceived();
305}
306
307////////////////////////////////////////////////////////////////////////////////
308//
309void LLNearbyChat::onFocusLost()
310{
311	setBackgroundOpaque(false);
312	LLPanel::onFocusLost();
313}
314
315BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
316{
317	//fix for EXT-6625
318	//highlight NearbyChat history whenever mouseclick happen in NearbyChat
319	//setting focus to eidtor will force onFocusLost() call that in its turn will change 
320	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
321	
322	if(mChatHistory)
323		mChatHistory->setFocus(TRUE);
324	return LLPanel::handleMouseDown(x, y, mask);
325}
326
327void LLNearbyChat::draw()
328{
329	// *HACK: Update transparency type depending on whether our children have focus.
330	// This is needed because this floater is chrome and thus cannot accept focus, so
331	// the transparency type setting code from LLFloater::setFocus() isn't reached.
332	if (getTransparencyType() != TT_DEFAULT)
333	{
334		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
335	}
336
337	LLPanel::draw();
338}