phoenix-firestorm/indra/newview/llfloateravatarpicker.cpp

371 lines
8.6 KiB
C++

/**
* @file llfloateravatarpicker.cpp
*
* Copyright (c) 2003-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloateravatarpicker.h"
#include "message.h"
#include "llbutton.h"
#include "llfocusmgr.h"
#include "llinventoryview.h"
#include "llinventorymodel.h"
#include "lllineeditor.h"
#include "llscrolllistctrl.h"
#include "lltextbox.h"
#include "llvieweruictrlfactory.h"
#include "viewer.h"
const S32 MIN_WIDTH = 200;
const S32 MIN_HEIGHT = 340;
const LLRect FLOATER_RECT(0, 380, 240, 0);
const char FLOATER_TITLE[] = "Choose Resident";
// static
LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL;
LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback,
void* userdata,
BOOL allow_multiple,
BOOL closeOnSelect)
{
if (!sInstance)
{
sInstance = new LLFloaterAvatarPicker();
sInstance->mCallback = callback;
sInstance->mCallbackUserdata = userdata;
sInstance->mCloseOnSelect = FALSE;
sInstance->open(); /* Flawfinder: ignore */
sInstance->center();
sInstance->setAllowMultiple(allow_multiple);
}
else
{
sInstance->open(); /*Flawfinder: ignore*/
sInstance->mCallback = callback;
sInstance->mCallbackUserdata = userdata;
sInstance->setAllowMultiple(allow_multiple);
}
sInstance->mCloseOnSelect = closeOnSelect;
return sInstance;
}
// Default constructor
LLFloaterAvatarPicker::LLFloaterAvatarPicker() :
LLFloater("avatarpicker", FLOATER_RECT, FLOATER_TITLE, TRUE, MIN_WIDTH, MIN_HEIGHT),
mResultsReturned(FALSE),
mCallback(NULL),
mCallbackUserdata(NULL)
{
gUICtrlFactory->buildFloater(this, "floater_avatar_picker.xml", NULL);
}
BOOL LLFloaterAvatarPicker::postBuild()
{
childSetKeystrokeCallback("Edit", editKeystroke, this);
childSetAction("Find", onBtnFind, this);
childDisable("Find");
mListNames = LLViewerUICtrlFactory::getScrollListByName(this, "Names");
childSetDoubleClickCallback("Names",onBtnAdd);
childSetCommitCallback("Names", onList, this);
childDisable("Names");
childSetAction("Select", onBtnAdd, this);
childDisable("Select");
childSetAction("Close", onBtnClose, this);
childSetFocus("Edit");
if (mListNames)
{
mListNames->addSimpleElement("No results");
}
mInventoryPanel = (LLInventoryPanel*)this->getCtrlByNameAndType("Inventory Panel", WIDGET_TYPE_INVENTORY_PANEL);
if(mInventoryPanel)
{
mInventoryPanel->setFilterTypes(0x1 << LLInventoryType::IT_CALLINGCARD);
mInventoryPanel->setFollowsAll();
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD);
mInventoryPanel->setSelectCallback(LLFloaterAvatarPicker::onSelectionChange, this);
}
setAllowMultiple(FALSE);
return TRUE;
}
// Destroys the object
LLFloaterAvatarPicker::~LLFloaterAvatarPicker()
{
gFocusMgr.releaseFocusIfNeeded( this );
sInstance = NULL;
}
void LLFloaterAvatarPicker::onBtnFind(void* userdata)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
if(self) self->find();
}
void LLFloaterAvatarPicker::onBtnAdd(void* userdata)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
if(self->mCallback)
{
self->mCallback(self->mAvatarNames, self->mAvatarIDs, self->mCallbackUserdata);
}
if (self->mInventoryPanel)
{
self->mInventoryPanel->setSelection(LLUUID::null, FALSE);
}
if (self->mListNames)
{
self->mListNames->deselectAllItems(TRUE);
}
if(self->mCloseOnSelect)
{
self->mCloseOnSelect = FALSE;
self->close();
}
}
void LLFloaterAvatarPicker::onBtnClose(void* userdata)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
if(self) self->close();
}
void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
if (!self)
{
return;
}
self->mAvatarIDs.clear();
self->mAvatarNames.clear();
if (!self->mListNames)
{
return;
}
std::vector<LLScrollListItem*> items = self->mListNames->getAllSelected();
for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
iter != items.end(); ++iter)
{
LLScrollListItem* item = *iter;
self->mAvatarNames.push_back(item->getColumn(0)->getText());
self->mAvatarIDs.push_back(item->getUUID());
self->childSetEnabled("Select", TRUE);
}
}
void LLFloaterAvatarPicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data;
if (!self)
{
return;
}
self->mAvatarIDs.clear();
self->mAvatarNames.clear();
self->childSetEnabled("Select", FALSE);
if (!self->mListNames)
{
return;
}
std::deque<LLFolderViewItem*>::const_iterator item_it;
for (item_it = items.begin(); item_it != items.end(); ++item_it)
{
LLFolderViewEventListener* listenerp = (*item_it)->getListener();
if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
{
LLInventoryItem* item = gInventory.getItem(listenerp->getUUID());
if (item)
{
self->mAvatarIDs.push_back(item->getCreatorUUID());
self->mAvatarNames.push_back(listenerp->getName());
self->childSetEnabled("Select", TRUE);
self->mListNames->deselectAllItems();
}
}
}
}
void LLFloaterAvatarPicker::find()
{
const LLString& text = childGetValue("Edit").asString();
mQueryID.generate();
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("AvatarPickerRequest");
msg->nextBlock("AgentData");
msg->addUUID("AgentID", agent_get_id());
msg->addUUID("SessionID", agent_get_session_id());
msg->addUUID("QueryID", mQueryID); // not used right now
msg->nextBlock("Data");
msg->addString("Name", text);
agent_send_reliable_message();
if (mListNames)
{
mListNames->deleteAllItems();
mListNames->addSimpleElement("Searching...");
}
childSetEnabled("Select", FALSE);
mResultsReturned = FALSE;
}
void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple)
{
mAllowMultiple = allow_multiple;
if (mInventoryPanel)
{
mInventoryPanel->setAllowMultiSelect(mAllowMultiple);
}
if (mListNames)
{
mListNames->setAllowMultipleSelection(mAllowMultiple);
}
}
// static
void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)
{
LLUUID agent_id;
LLUUID query_id;
LLUUID avatar_id;
char first_name[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
char last_name[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
msg->getUUID("AgentData", "AgentID", agent_id);
msg->getUUID("AgentData", "QueryID", query_id);
// Not for us
if (agent_id != agent_get_id()) return;
// Dialog already closed
LLFloaterAvatarPicker *self = sInstance;
if (!self) return;
// these are not results from our last request
if (query_id != self->mQueryID)
{
return;
}
if (!self->mResultsReturned)
{
// clear "Searching" label on first results
if (self->mListNames)
{
self->mListNames->deleteAllItems();
}
}
self->mResultsReturned = TRUE;
if (self->mListNames)
{
BOOL found_one = FALSE;
S32 num_new_rows = msg->getNumberOfBlocks("Data");
for (S32 i = 0; i < num_new_rows; i++)
{
msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i);
msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, DB_FIRST_NAME_BUF_SIZE, first_name, i);
msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, DB_LAST_NAME_BUF_SIZE, last_name, i);
LLString avatar_name;
if (avatar_id.isNull())
{
self->childSetTextArg("NotFound", "[TEXT]", self->childGetText("Edit"));
avatar_name = self->childGetValue("NotFound").asString();
self->mListNames->setEnabled(FALSE);
}
else
{
avatar_name = LLString(first_name) + " " + last_name;
self->mListNames->setEnabled(TRUE);
found_one = TRUE;
}
LLSD element;
element["id"] = avatar_id; // value
element["columns"][0]["value"] = avatar_name;
self->mListNames->addElement(element);
}
if (found_one)
{
self->mListNames->selectFirstItem();
self->onList(self->mListNames, self);
self->mListNames->setFocus(TRUE);
}
}
}
//static
void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)user_data;
if (caller->getText().size() >= 3)
{
self->childSetEnabled("Find",TRUE);
}
else
{
self->childSetEnabled("Find",FALSE);
}
}
// virtual
BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
{
if (key == KEY_RETURN
&& mask == MASK_NONE)
{
if (childHasFocus("Edit"))
{
onBtnFind(this);
return TRUE;
}
else
{
onBtnAdd(this);
return TRUE;
}
}
else if (key == KEY_ESCAPE && mask == MASK_NONE)
{
close();
return TRUE;
}
return LLFloater::handleKeyHere(key, mask, called_from_parent);
}