Newer
Older
/**
* @file llfloatertopobjects.cpp
* @brief Shows top colliders, top scripts, etc.
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* 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
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatertopobjects.h"
// library includes
#include "llavatarnamecache.h"
#include "llfontgl.h"
#include "llagent.h"
#include "llbutton.h"
#include "llfloatergodtools.h"
James Cook
committed
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "llscrolllistcell.h"
#include "lllineeditor.h"
#include "lltextbox.h"
#include "lltracker.h"
#include "llviewermessage.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lluictrlfactory.h"
James Cook
committed
//LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL;
// Globals
// const U32 TIME_STR_LENGTH = 30;
James Cook
committed
/*
// static
void LLFloaterTopObjects::show()
{
if (sInstance)
{
sInstance->setVisibleAndFrontmost();
return;
}
sInstance = new LLFloaterTopObjects();
sInstance->center();
}
James Cook
committed
*/
LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
: LLFloater(key),
James Cook
committed
mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this));
mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this));
mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this));
mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this));
mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this));
mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this));
mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this));
mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this));
mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this));
}
LLFloaterTopObjects::~LLFloaterTopObjects()
{
}
// virtual
BOOL LLFloaterTopObjects::postBuild()
{
LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list");
getChild<LLUICtrl>("objects_list")->setFocus(TRUE);
objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this);
objects_list->setCommitOnSelectionChange(TRUE);
LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor");
if (line_editor)
{
line_editor->setCommitOnFocusLost(FALSE);
line_editor->setCommitCallback(onGetByOwnerName, this);
line_editor = getChild<LLLineEditor>("object_name_editor");
if (line_editor)
{
line_editor->setCommitOnFocusLost(FALSE);
line_editor->setCommitCallback(onGetByObjectName, this);
}*/
mCurrentMode = STAT_REPORT_TOP_SCRIPTS;
mFlags = 0;
mFilter.clear();
James Cook
committed
// static
void LLFloaterTopObjects::setMode(U32 mode)
{
LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
if(!instance) return;
instance->mCurrentMode = mode;
}
James Cook
committed
// static
void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data)
{
James Cook
committed
LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
if(!instance) return;
James Cook
committed
LLFloaterReg::showInstance("top_objects");
instance->handleReply(msg, data);
//HACK: for some reason sometimes top scripts originally comes back
//with no results even though they're there
James Cook
committed
if (!instance->mObjectListIDs.size() && !instance->mInitialized)
James Cook
committed
instance->onRefresh();
instance->mInitialized = TRUE;
}
}
void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
{
U32 request_flags;
U32 total_count;
msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags);
msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count);
msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ReportType, mCurrentMode);
LLScrollListCtrl *list = getChild<LLScrollListCtrl>("objects_list");
S32 block_count = msg->getNumberOfBlocks("ReportData");
for (S32 block = 0; block < block_count; ++block)
{
U32 task_local_id;
U32 time_stamp = 0;
LLUUID task_id;
F32 location_x, location_y, location_z;
F32 score;
std::string name_buf;
std::string owner_buf;
F32 mono_score = 0.f;
bool have_extended_data = false;
Kelly Washington
committed
S32 public_urls = 0;
msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationX, location_x, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationY, location_y, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationZ, location_z, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
if(msg->has("DataExtended"))
have_extended_data = true;
msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
msg->getF32("DataExtended", "MonoScore", mono_score, block);
msg->getS32("DataExtended", "PublicURLs", public_urls, block);
LLSD columns;
columns[0]["column"] = "score";
columns[0]["value"] = llformat("%0.3f", score);
columns[0]["font"] = "SANSSERIF";
columns[1]["column"] = "name";
columns[1]["value"] = name_buf;
columns[1]["font"] = "SANSSERIF";
// Owner names can have trailing spaces sent from server
LLStringUtil::trim(owner_buf);
if (LLAvatarNameCache::useDisplayNames())
{
// ...convert hard-coded name from server to a username
// *TODO: Send owner_id from server and look up display name
owner_buf = LLCacheName::buildUsername(owner_buf);
}
else
{
// ...just strip out legacy "Resident" name
owner_buf = LLCacheName::cleanFullName(owner_buf);
}
columns[2]["column"] = "owner";
columns[2]["value"] = owner_buf;
columns[2]["font"] = "SANSSERIF";
columns[3]["column"] = "location";
columns[3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
columns[3]["font"] = "SANSSERIF";
columns[4]["column"] = "time";
columns[4]["type"] = "date";
columns[4]["value"] = LLDate((time_t)time_stamp);
columns[4]["font"] = "SANSSERIF";
if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS
&& have_extended_data)
columns[5]["column"] = "mono_time";
columns[5]["value"] = llformat("%0.3f", mono_score);
columns[5]["font"] = "SANSSERIF";
Kelly Washington
committed
columns[6]["column"] = "URLs";
columns[6]["value"] = llformat("%d", public_urls);
columns[6]["font"] = "SANSSERIF";
element["columns"] = columns;
list->addElement(element);
mObjectListData.append(element);
mObjectListIDs.push_back(task_id);
mtotalScore += score;
}
if (total_count == 0 && list->getItemCount() == 0)
{
list->setCommentText(getString("none_descriptor"));
}
else
{
list->selectFirstItem();
}
if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS)
{
Steven Bennetts
committed
setTitle(getString("top_scripts_title"));
list->setColumnLabel("score", getString("scripts_score_label"));
list->setColumnLabel("mono_time", getString("scripts_mono_time_label"));
Steven Bennetts
committed
LLUIString format = getString("top_scripts_text");
format.setArg("[COUNT]", llformat("%d", total_count));
format.setArg("[TIME]", llformat("%0.1f", mtotalScore));
getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
Steven Bennetts
committed
setTitle(getString("top_colliders_title"));
list->setColumnLabel("score", getString("colliders_score_label"));
list->setColumnLabel("mono_time", "");
Steven Bennetts
committed
LLUIString format = getString("top_colliders_text");
format.setArg("[COUNT]", llformat("%d", total_count));
getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
James Cook
committed
void LLFloaterTopObjects::onCommitObjectsList()
James Cook
committed
updateSelectionInfo();
}
void LLFloaterTopObjects::updateSelectionInfo()
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLUUID object_id = list->getCurrentID();
if (object_id.isNull()) return;
Aaron Brashears
committed
std::string object_id_string = object_id.asString();
getChild<LLUICtrl>("id_editor")->setValue(LLSD(object_id_string));
LLScrollListItem* sli = list->getFirstSelected();
llassert(sli);
if (sli)
{
getChild<LLUICtrl>("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString());
getChild<LLUICtrl>("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString());
}
// static
void LLFloaterTopObjects::onDoubleClickObjectsList(void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
self->showBeacon();
}
// static
James Cook
committed
void LLFloaterTopObjects::onClickShowBeacon()
James Cook
committed
showBeacon();
}
void LLFloaterTopObjects::doToObjects(int action, bool all)
{
LLMessageSystem *msg = gMessageSystem;
LLViewerRegion* region = gAgent.getRegion();
if (!region) return;
LLCtrlListInterface *list = getChild<LLUICtrl>("objects_list")->getListInterface();
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
bool start_message = true;
for (id_itor = mObjectListIDs.begin(); id_itor != mObjectListIDs.end(); ++id_itor)
{
LLUUID task_id = *id_itor;
if (!all && !list->isSelected(task_id))
{
// Selected only
continue;
}
if (start_message)
{
if (action == ACTION_RETURN)
{
msg->newMessageFast(_PREHASH_ParcelReturnObjects);
}
else
{
msg->newMessageFast(_PREHASH_ParcelDisableObjects);
}
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_ParcelData);
msg->addS32Fast(_PREHASH_LocalID, -1); // Whole region
msg->addS32Fast(_PREHASH_ReturnType, RT_NONE);
start_message = false;
}
msg->nextBlockFast(_PREHASH_TaskIDs);
msg->addUUIDFast(_PREHASH_TaskID, task_id);
if (msg->isSendFullFast(_PREHASH_TaskIDs))
{
msg->sendReliable(region->getHost());
start_message = true;
}
}
if (!start_message)
{
msg->sendReliable(region->getHost());
}
}
//static
bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response)
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
James Cook
committed
LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
if(!instance) return false;
James Cook
committed
instance->doToObjects(ACTION_RETURN, true);
James Cook
committed
void LLFloaterTopObjects::onReturnAll()
LLNotificationsUtil::add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll);
James Cook
committed
void LLFloaterTopObjects::onReturnSelected()
James Cook
committed
doToObjects(ACTION_RETURN, false);
bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
James Cook
committed
LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
if(!instance) return false;
James Cook
committed
instance->doToObjects(ACTION_DISABLE, true);
James Cook
committed
void LLFloaterTopObjects::onDisableAll()
LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
James Cook
committed
void LLFloaterTopObjects::onDisableSelected()
James Cook
committed
doToObjects(ACTION_DISABLE, false);
James Cook
committed
James Cook
committed
LLCtrlListInterface *list = childGetListInterface("objects_list");
if (list)
{
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
James Cook
committed
mObjectListData.clear();
mObjectListIDs.clear();
mtotalScore = 0.f;
James Cook
committed
void LLFloaterTopObjects::onRefresh()
{
U32 mode = STAT_REPORT_TOP_SCRIPTS;
U32 flags = 0;
std::string filter = "";
James Cook
committed
mode = mCurrentMode;
flags = mFlags;
filter = mFilter;
clearList();
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LandStatRequest);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
msg->nextBlockFast(_PREHASH_RequestData);
msg->addU32Fast(_PREHASH_ReportType, mode);
msg->addU32Fast(_PREHASH_RequestFlags, flags);
msg->addStringFast(_PREHASH_Filter, filter);
msg->addS32Fast(_PREHASH_ParcelLocalID, 0);
msg->sendReliable(gAgent.getRegionHost());
James Cook
committed
mFilter.clear();
mFlags = 0;
James Cook
committed
void LLFloaterTopObjects::onGetByObjectName()
James Cook
committed
mFlags = STAT_FILTER_BY_OBJECT;
mFilter = getChild<LLUICtrl>("object_name_editor")->getValue().asString();
James Cook
committed
onRefresh();
James Cook
committed
void LLFloaterTopObjects::onGetByOwnerName()
James Cook
committed
mFlags = STAT_FILTER_BY_OWNER;
mFilter = getChild<LLUICtrl>("owner_name_editor")->getValue().asString();
James Cook
committed
onRefresh();
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
std::string name = first_selected->getColumn(1)->getValue().asString();
std::string pos_string = first_selected->getColumn(3)->getValue().asString();
F32 x, y, z;
S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
if (matched != 3) return;
LLVector3 pos_agent(x, y, z);
LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
std::string tooltip("");
LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);
}