PageRenderTime 84ms CodeModel.GetById 17ms app.highlight 61ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llfloatertopobjects.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 502 lines | 354 code | 76 blank | 72 comment | 43 complexity | b858e06ea5f12daadb027593f468111f MD5 | raw file
  1/** 
  2 * @file llfloatertopobjects.cpp
  3 * @brief Shows top colliders, top scripts, etc.
  4 *
  5 * $LicenseInfo:firstyear=2005&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 "llfloatertopobjects.h"
 30
 31// library includes
 32#include "message.h"
 33#include "llavatarnamecache.h"
 34#include "llfontgl.h"
 35
 36#include "llagent.h"
 37#include "llbutton.h"
 38#include "llfloatergodtools.h"
 39#include "llfloaterreg.h"
 40#include "llnotificationsutil.h"
 41#include "llparcel.h"
 42#include "llscrolllistctrl.h"
 43#include "llscrolllistitem.h"
 44#include "llscrolllistcell.h"
 45#include "lllineeditor.h"
 46#include "lltextbox.h"
 47#include "lltracker.h"
 48#include "llviewermessage.h"
 49#include "llviewerparcelmgr.h"
 50#include "llviewerregion.h"
 51#include "lluictrlfactory.h"
 52#include "llviewerwindow.h"
 53
 54//LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL;
 55
 56// Globals
 57// const U32 TIME_STR_LENGTH = 30;
 58/*
 59// static
 60void LLFloaterTopObjects::show()
 61{
 62	if (sInstance)
 63	{
 64		sInstance->setVisibleAndFrontmost();
 65		return;
 66	}
 67
 68	sInstance = new LLFloaterTopObjects();
 69	sInstance->center();
 70}
 71*/
 72LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
 73:	LLFloater(key),
 74	mInitialized(FALSE),
 75	mtotalScore(0.f)
 76{
 77	mCommitCallbackRegistrar.add("TopObjects.ShowBeacon",		boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this));
 78	mCommitCallbackRegistrar.add("TopObjects.ReturnSelected",	boost::bind(&LLFloaterTopObjects::onReturnSelected, this));
 79	mCommitCallbackRegistrar.add("TopObjects.ReturnAll",		boost::bind(&LLFloaterTopObjects::onReturnAll, this));
 80	mCommitCallbackRegistrar.add("TopObjects.DisableSelected",	boost::bind(&LLFloaterTopObjects::onDisableSelected, this));
 81	mCommitCallbackRegistrar.add("TopObjects.DisableAll",		boost::bind(&LLFloaterTopObjects::onDisableAll, this));
 82	mCommitCallbackRegistrar.add("TopObjects.Refresh",			boost::bind(&LLFloaterTopObjects::onRefresh, this));
 83	mCommitCallbackRegistrar.add("TopObjects.GetByObjectName",	boost::bind(&LLFloaterTopObjects::onGetByObjectName, this));
 84	mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName",	boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this));
 85	mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this));
 86}
 87
 88LLFloaterTopObjects::~LLFloaterTopObjects()
 89{
 90}
 91
 92// virtual
 93BOOL LLFloaterTopObjects::postBuild()
 94{
 95	LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list");
 96	getChild<LLUICtrl>("objects_list")->setFocus(TRUE);
 97	objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this);
 98	objects_list->setCommitOnSelectionChange(TRUE);
 99
100	setDefaultBtn("show_beacon_btn");
101
102	/*
103	LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor");
104	if (line_editor)
105	{
106		line_editor->setCommitOnFocusLost(FALSE);
107		line_editor->setCommitCallback(onGetByOwnerName, this);
108	}
109
110	line_editor = getChild<LLLineEditor>("object_name_editor");
111	if (line_editor)
112	{
113		line_editor->setCommitOnFocusLost(FALSE);
114		line_editor->setCommitCallback(onGetByObjectName, this);
115	}*/
116
117	mCurrentMode = STAT_REPORT_TOP_SCRIPTS;
118	mFlags = 0;
119	mFilter.clear();
120
121	return TRUE;
122}
123// static
124void LLFloaterTopObjects::setMode(U32 mode)
125{
126	LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
127	if(!instance) return;
128	instance->mCurrentMode = mode; 
129}
130
131// static 
132void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data)
133{
134	LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
135	if(!instance) return;
136	// Make sure dialog is on screen
137	LLFloaterReg::showInstance("top_objects");
138	instance->handleReply(msg, data);
139
140	//HACK: for some reason sometimes top scripts originally comes back
141	//with no results even though they're there
142	if (!instance->mObjectListIDs.size() && !instance->mInitialized)
143	{
144		instance->onRefresh();
145		instance->mInitialized = TRUE;
146	}
147
148}
149
150void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
151{
152	U32 request_flags;
153	U32 total_count;
154
155	msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags);
156	msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count);
157	msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ReportType, mCurrentMode);
158
159	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("objects_list");
160
161	S32 block_count = msg->getNumberOfBlocks("ReportData");
162	for (S32 block = 0; block < block_count; ++block)
163	{
164		U32 task_local_id;
165		U32 time_stamp = 0;
166		LLUUID task_id;
167		F32 location_x, location_y, location_z;
168		F32 score;
169		std::string name_buf;
170		std::string owner_buf;
171		F32 mono_score = 0.f;
172		bool have_extended_data = false;
173		S32 public_urls = 0;
174
175		msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
176		msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
177		msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationX, location_x, block);
178		msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationY, location_y, block);
179		msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationZ, location_z, block);
180		msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
181		msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
182		msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
183		if(msg->has("DataExtended"))
184		{
185			have_extended_data = true;
186			msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
187			msg->getF32("DataExtended", "MonoScore", mono_score, block);
188			msg->getS32("DataExtended", "PublicURLs", public_urls, block);
189		}
190
191		LLSD element;
192
193		element["id"] = task_id;
194
195		LLSD columns;
196		columns[0]["column"] = "score";
197		columns[0]["value"] = llformat("%0.3f", score);
198		columns[0]["font"] = "SANSSERIF";
199		
200		columns[1]["column"] = "name";
201		columns[1]["value"] = name_buf;
202		columns[1]["font"] = "SANSSERIF";
203		
204		// Owner names can have trailing spaces sent from server
205		LLStringUtil::trim(owner_buf);
206		
207		if (LLAvatarNameCache::useDisplayNames())
208		{
209			// ...convert hard-coded name from server to a username
210			// *TODO: Send owner_id from server and look up display name
211			owner_buf = LLCacheName::buildUsername(owner_buf);
212		}
213		else
214		{
215			// ...just strip out legacy "Resident" name
216			owner_buf = LLCacheName::cleanFullName(owner_buf);
217		}
218		columns[2]["column"] = "owner";
219		columns[2]["value"] = owner_buf;
220		columns[2]["font"] = "SANSSERIF";
221
222		columns[3]["column"] = "location";
223		columns[3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
224		columns[3]["font"] = "SANSSERIF";
225		columns[4]["column"] = "time";
226		columns[4]["type"] = "date";
227		columns[4]["value"] = LLDate((time_t)time_stamp);
228		columns[4]["font"] = "SANSSERIF";
229
230		if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS
231			&& have_extended_data)
232		{
233			columns[5]["column"] = "mono_time";
234			columns[5]["value"] = llformat("%0.3f", mono_score);
235			columns[5]["font"] = "SANSSERIF";
236
237			columns[6]["column"] = "URLs";
238			columns[6]["value"] = llformat("%d", public_urls);
239			columns[6]["font"] = "SANSSERIF";
240		}
241		element["columns"] = columns;
242		list->addElement(element);
243		
244		mObjectListData.append(element);
245		mObjectListIDs.push_back(task_id);
246
247		mtotalScore += score;
248	}
249
250	if (total_count == 0 && list->getItemCount() == 0)
251	{
252		list->setCommentText(getString("none_descriptor"));
253	}
254	else
255	{
256		list->selectFirstItem();
257	}
258
259	if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS)
260	{
261		setTitle(getString("top_scripts_title"));
262		list->setColumnLabel("score", getString("scripts_score_label"));
263		list->setColumnLabel("mono_time", getString("scripts_mono_time_label"));
264		
265		LLUIString format = getString("top_scripts_text");
266		format.setArg("[COUNT]", llformat("%d", total_count));
267		format.setArg("[TIME]", llformat("%0.1f", mtotalScore));
268		getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
269	}
270	else
271	{
272		setTitle(getString("top_colliders_title"));
273		list->setColumnLabel("score", getString("colliders_score_label"));
274		list->setColumnLabel("mono_time", "");
275		LLUIString format = getString("top_colliders_text");
276		format.setArg("[COUNT]", llformat("%d", total_count));
277		getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
278	}
279}
280
281void LLFloaterTopObjects::onCommitObjectsList()
282{
283	updateSelectionInfo();
284}
285
286void LLFloaterTopObjects::updateSelectionInfo()
287{
288	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
289
290	if (!list) return;
291
292	LLUUID object_id = list->getCurrentID();
293	if (object_id.isNull()) return;
294
295	std::string object_id_string = object_id.asString();
296
297	getChild<LLUICtrl>("id_editor")->setValue(LLSD(object_id_string));
298	LLScrollListItem* sli = list->getFirstSelected();
299	llassert(sli);
300	if (sli)
301	{
302		getChild<LLUICtrl>("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString());
303		getChild<LLUICtrl>("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString());
304	}
305}
306
307// static
308void LLFloaterTopObjects::onDoubleClickObjectsList(void* data)
309{
310	LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
311	self->showBeacon();
312}
313
314// static
315void LLFloaterTopObjects::onClickShowBeacon()
316{
317	showBeacon();
318}
319
320void LLFloaterTopObjects::doToObjects(int action, bool all)
321{
322	LLMessageSystem *msg = gMessageSystem;
323
324	LLViewerRegion* region = gAgent.getRegion();
325	if (!region) return;
326
327	LLCtrlListInterface *list = getChild<LLUICtrl>("objects_list")->getListInterface();
328	if (!list || list->getItemCount() == 0) return;
329
330	uuid_vec_t::iterator id_itor;
331
332	bool start_message = true;
333
334	for (id_itor = mObjectListIDs.begin(); id_itor != mObjectListIDs.end(); ++id_itor)
335	{
336		LLUUID task_id = *id_itor;
337		if (!all && !list->isSelected(task_id))
338		{
339			// Selected only
340			continue;
341		}
342		if (start_message)
343		{
344			if (action == ACTION_RETURN)
345			{
346				msg->newMessageFast(_PREHASH_ParcelReturnObjects);
347			}
348			else
349			{
350				msg->newMessageFast(_PREHASH_ParcelDisableObjects);
351			}
352			msg->nextBlockFast(_PREHASH_AgentData);
353			msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID());
354			msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
355			msg->nextBlockFast(_PREHASH_ParcelData);
356			msg->addS32Fast(_PREHASH_LocalID, -1); // Whole region
357			msg->addS32Fast(_PREHASH_ReturnType, RT_NONE);
358			start_message = false;
359		}
360
361		msg->nextBlockFast(_PREHASH_TaskIDs);
362		msg->addUUIDFast(_PREHASH_TaskID, task_id);
363
364		if (msg->isSendFullFast(_PREHASH_TaskIDs))
365		{
366			msg->sendReliable(region->getHost());
367			start_message = true;
368		}
369	}
370
371	if (!start_message)
372	{
373		msg->sendReliable(region->getHost());
374	}
375}
376
377//static
378bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response)
379{
380	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
381	LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
382	if(!instance) return false;
383	if (option == 0)
384	{
385		instance->doToObjects(ACTION_RETURN, true);
386	}
387	return false;
388}
389
390void LLFloaterTopObjects::onReturnAll()
391{	
392	LLNotificationsUtil::add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll);
393}
394
395
396void LLFloaterTopObjects::onReturnSelected()
397{
398	doToObjects(ACTION_RETURN, false);
399}
400
401
402//static
403bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
404{
405	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
406	LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
407	if(!instance) return false;
408	if (option == 0)
409	{
410		instance->doToObjects(ACTION_DISABLE, true);
411	}
412	return false;
413}
414
415void LLFloaterTopObjects::onDisableAll()
416{
417	LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
418}
419
420void LLFloaterTopObjects::onDisableSelected()
421{
422	doToObjects(ACTION_DISABLE, false);
423}
424
425
426void LLFloaterTopObjects::clearList()
427{
428	LLCtrlListInterface *list = childGetListInterface("objects_list");
429	
430	if (list) 
431	{
432		list->operateOnAll(LLCtrlListInterface::OP_DELETE);
433	}
434
435	mObjectListData.clear();
436	mObjectListIDs.clear();
437	mtotalScore = 0.f;
438}
439
440
441void LLFloaterTopObjects::onRefresh()
442{
443	U32 mode = STAT_REPORT_TOP_SCRIPTS;
444	U32 flags = 0;
445	std::string filter = "";
446
447	mode   = mCurrentMode;
448	flags  = mFlags;
449	filter = mFilter;
450	clearList();
451
452	LLMessageSystem *msg = gMessageSystem;
453	msg->newMessageFast(_PREHASH_LandStatRequest);
454	msg->nextBlockFast(_PREHASH_AgentData);
455	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
456	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
457	msg->nextBlockFast(_PREHASH_RequestData);
458	msg->addU32Fast(_PREHASH_ReportType, mode);
459	msg->addU32Fast(_PREHASH_RequestFlags, flags);
460	msg->addStringFast(_PREHASH_Filter, filter);
461	msg->addS32Fast(_PREHASH_ParcelLocalID, 0);
462
463	msg->sendReliable(gAgent.getRegionHost());
464
465	mFilter.clear();
466	mFlags = 0;
467}
468
469void LLFloaterTopObjects::onGetByObjectName()
470{
471	mFlags  = STAT_FILTER_BY_OBJECT;
472	mFilter = getChild<LLUICtrl>("object_name_editor")->getValue().asString();
473	onRefresh();
474}
475
476void LLFloaterTopObjects::onGetByOwnerName()
477{
478	mFlags  = STAT_FILTER_BY_OWNER;
479	mFilter = getChild<LLUICtrl>("owner_name_editor")->getValue().asString();
480	onRefresh();
481}
482
483void LLFloaterTopObjects::showBeacon()
484{
485	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
486	if (!list) return;
487
488	LLScrollListItem* first_selected = list->getFirstSelected();
489	if (!first_selected) return;
490
491	std::string name = first_selected->getColumn(1)->getValue().asString();
492	std::string pos_string =  first_selected->getColumn(3)->getValue().asString();
493
494	F32 x, y, z;
495	S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
496	if (matched != 3) return;
497
498	LLVector3 pos_agent(x, y, z);
499	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
500	std::string tooltip("");
501	LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);
502}