00001
00031 #include "llviewerprecompiledheaders.h"
00032
00033 #include "llfloateravatarpicker.h"
00034
00035 #include "message.h"
00036
00037 #include "llbutton.h"
00038 #include "llfocusmgr.h"
00039 #include "llinventoryview.h"
00040 #include "llinventorymodel.h"
00041 #include "lllineeditor.h"
00042 #include "llscrolllistctrl.h"
00043 #include "lltextbox.h"
00044 #include "llvieweruictrlfactory.h"
00045 #include "viewer.h"
00046
00047 const S32 MIN_WIDTH = 200;
00048 const S32 MIN_HEIGHT = 340;
00049 const LLRect FLOATER_RECT(0, 380, 240, 0);
00050 const char FLOATER_TITLE[] = "Choose Resident";
00051
00052
00053 LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL;
00054
00055
00056 LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback,
00057 void* userdata,
00058 BOOL allow_multiple,
00059 BOOL closeOnSelect)
00060 {
00061 if (!sInstance)
00062 {
00063 sInstance = new LLFloaterAvatarPicker();
00064 sInstance->mCallback = callback;
00065 sInstance->mCallbackUserdata = userdata;
00066 sInstance->mCloseOnSelect = FALSE;
00067
00068 sInstance->open();
00069 sInstance->center();
00070 sInstance->setAllowMultiple(allow_multiple);
00071 }
00072 else
00073 {
00074 sInstance->open();
00075 sInstance->mCallback = callback;
00076 sInstance->mCallbackUserdata = userdata;
00077 sInstance->setAllowMultiple(allow_multiple);
00078 }
00079
00080 sInstance->mCloseOnSelect = closeOnSelect;
00081 return sInstance;
00082 }
00083
00084
00085 LLFloaterAvatarPicker::LLFloaterAvatarPicker() :
00086 LLFloater("avatarpicker", FLOATER_RECT, FLOATER_TITLE, TRUE, MIN_WIDTH, MIN_HEIGHT),
00087 mResultsReturned(FALSE),
00088 mCallback(NULL),
00089 mCallbackUserdata(NULL)
00090 {
00091 gUICtrlFactory->buildFloater(this, "floater_avatar_picker.xml", NULL);
00092 }
00093
00094 BOOL LLFloaterAvatarPicker::postBuild()
00095 {
00096 childSetKeystrokeCallback("Edit", editKeystroke, this);
00097
00098 childSetAction("Find", onBtnFind, this);
00099 childDisable("Find");
00100
00101 mListNames = LLViewerUICtrlFactory::getScrollListByName(this, "Names");
00102 childSetDoubleClickCallback("Names",onBtnAdd);
00103 childSetCommitCallback("Names", onList, this);
00104 childDisable("Names");
00105
00106 childSetAction("Select", onBtnAdd, this);
00107 childDisable("Select");
00108
00109 childSetAction("Close", onBtnClose, this);
00110
00111 childSetFocus("Edit");
00112
00113 if (mListNames)
00114 {
00115 mListNames->addSimpleElement("No results");
00116 }
00117
00118 mInventoryPanel = (LLInventoryPanel*)this->getCtrlByNameAndType("Inventory Panel", WIDGET_TYPE_INVENTORY_PANEL);
00119 if(mInventoryPanel)
00120 {
00121 mInventoryPanel->setFilterTypes(0x1 << LLInventoryType::IT_CALLINGCARD);
00122 mInventoryPanel->setFollowsAll();
00123 mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
00124 mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD);
00125 mInventoryPanel->setSelectCallback(LLFloaterAvatarPicker::onSelectionChange, this);
00126 }
00127
00128 setAllowMultiple(FALSE);
00129
00130 return TRUE;
00131 }
00132
00133
00134 LLFloaterAvatarPicker::~LLFloaterAvatarPicker()
00135 {
00136 gFocusMgr.releaseFocusIfNeeded( this );
00137
00138 sInstance = NULL;
00139 }
00140
00141 void LLFloaterAvatarPicker::onBtnFind(void* userdata)
00142 {
00143 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
00144 if(self) self->find();
00145 }
00146
00147 void LLFloaterAvatarPicker::onBtnAdd(void* userdata)
00148 {
00149 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
00150
00151 if(self->mCallback)
00152 {
00153 self->mCallback(self->mAvatarNames, self->mAvatarIDs, self->mCallbackUserdata);
00154 }
00155 if (self->mInventoryPanel)
00156 {
00157 self->mInventoryPanel->setSelection(LLUUID::null, FALSE);
00158 }
00159 if (self->mListNames)
00160 {
00161 self->mListNames->deselectAllItems(TRUE);
00162 }
00163 if(self->mCloseOnSelect)
00164 {
00165 self->mCloseOnSelect = FALSE;
00166 self->close();
00167 }
00168 }
00169
00170 void LLFloaterAvatarPicker::onBtnClose(void* userdata)
00171 {
00172 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
00173 if(self) self->close();
00174 }
00175
00176 void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata)
00177 {
00178 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
00179 if (!self)
00180 {
00181 return;
00182 }
00183
00184 self->mAvatarIDs.clear();
00185 self->mAvatarNames.clear();
00186
00187 if (!self->mListNames)
00188 {
00189 return;
00190 }
00191
00192 std::vector<LLScrollListItem*> items = self->mListNames->getAllSelected();
00193 for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
00194 iter != items.end(); ++iter)
00195 {
00196 LLScrollListItem* item = *iter;
00197 self->mAvatarNames.push_back(item->getColumn(0)->getText());
00198 self->mAvatarIDs.push_back(item->getUUID());
00199 self->childSetEnabled("Select", TRUE);
00200 }
00201 }
00202
00203
00204 void LLFloaterAvatarPicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
00205 {
00206 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data;
00207 if (self)
00208 {
00209 self->doSelectionChange( items, user_action, data );
00210 }
00211 }
00212
00213
00214 void LLFloaterAvatarPicker::doSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
00215 {
00216 if (!mListNames)
00217 {
00218 return;
00219 }
00220
00221 std::vector<LLScrollListItem*> search_items = mListNames->getAllSelected();
00222 if ( search_items.size() == 0 )
00223 {
00224 mAvatarIDs.clear();
00225 mAvatarNames.clear();
00226 childSetEnabled("Select", FALSE);
00227 }
00228
00229 BOOL first_calling_card = TRUE;
00230 std::deque<LLFolderViewItem*>::const_iterator item_it;
00231 for (item_it = items.begin(); item_it != items.end(); ++item_it)
00232 {
00233 LLFolderViewEventListener* listenerp = (*item_it)->getListener();
00234 if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
00235 {
00236 LLInventoryItem* item = gInventory.getItem(listenerp->getUUID());
00237
00238 if (item)
00239 {
00240 if ( first_calling_card )
00241 {
00242 first_calling_card = FALSE;
00243 mAvatarIDs.clear();
00244 mAvatarNames.clear();
00245 mListNames->deselectAllItems();
00246 }
00247
00248
00249 mAvatarIDs.push_back(item->getCreatorUUID());
00250 mAvatarNames.push_back(listenerp->getName());
00251 childSetEnabled("Select", TRUE);
00252 }
00253 }
00254 }
00255 }
00256
00257
00258 void LLFloaterAvatarPicker::find()
00259 {
00260 const LLString& text = childGetValue("Edit").asString();
00261
00262 mQueryID.generate();
00263
00264 LLMessageSystem* msg = gMessageSystem;
00265
00266 msg->newMessage("AvatarPickerRequest");
00267 msg->nextBlock("AgentData");
00268 msg->addUUID("AgentID", agent_get_id());
00269 msg->addUUID("SessionID", agent_get_session_id());
00270 msg->addUUID("QueryID", mQueryID);
00271 msg->nextBlock("Data");
00272 msg->addString("Name", text);
00273
00274 agent_send_reliable_message();
00275
00276 if (mListNames)
00277 {
00278 mListNames->deleteAllItems();
00279 mListNames->addSimpleElement("Searching...");
00280 }
00281
00282 childSetEnabled("Select", FALSE);
00283 mResultsReturned = FALSE;
00284 }
00285
00286 void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple)
00287 {
00288 mAllowMultiple = allow_multiple;
00289 if (mInventoryPanel)
00290 {
00291 mInventoryPanel->setAllowMultiSelect(mAllowMultiple);
00292 }
00293 if (mListNames)
00294 {
00295 mListNames->setAllowMultipleSelection(mAllowMultiple);
00296 }
00297 }
00298
00299
00300 void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)
00301 {
00302 LLUUID agent_id;
00303 LLUUID query_id;
00304 LLUUID avatar_id;
00305 char first_name[DB_FIRST_NAME_BUF_SIZE];
00306 char last_name[DB_LAST_NAME_BUF_SIZE];
00307
00308 msg->getUUID("AgentData", "AgentID", agent_id);
00309 msg->getUUID("AgentData", "QueryID", query_id);
00310
00311
00312 if (agent_id != agent_get_id()) return;
00313
00314
00315 LLFloaterAvatarPicker *self = sInstance;
00316 if (!self) return;
00317
00318
00319 if (query_id != self->mQueryID)
00320 {
00321 return;
00322 }
00323
00324 if (!self->mResultsReturned)
00325 {
00326
00327 if (self->mListNames)
00328 {
00329 self->mListNames->deleteAllItems();
00330 }
00331 }
00332 self->mResultsReturned = TRUE;
00333
00334 if (self->mListNames)
00335 {
00336 BOOL found_one = FALSE;
00337 S32 num_new_rows = msg->getNumberOfBlocks("Data");
00338 for (S32 i = 0; i < num_new_rows; i++)
00339 {
00340 msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i);
00341 msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, DB_FIRST_NAME_BUF_SIZE, first_name, i);
00342 msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, DB_LAST_NAME_BUF_SIZE, last_name, i);
00343
00344 LLString avatar_name;
00345 if (avatar_id.isNull())
00346 {
00347 self->childSetTextArg("NotFound", "[TEXT]", self->childGetText("Edit"));
00348 avatar_name = self->childGetValue("NotFound").asString();
00349 self->mListNames->setEnabled(FALSE);
00350 }
00351 else
00352 {
00353 avatar_name = LLString(first_name) + " " + last_name;
00354 self->mListNames->setEnabled(TRUE);
00355 found_one = TRUE;
00356 }
00357 LLSD element;
00358 element["id"] = avatar_id;
00359 element["columns"][0]["value"] = avatar_name;
00360 self->mListNames->addElement(element);
00361 }
00362
00363 if (found_one)
00364 {
00365 self->mListNames->selectFirstItem();
00366 self->onList(self->mListNames, self);
00367 self->mListNames->setFocus(TRUE);
00368 }
00369 }
00370 }
00371
00372
00373 void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data)
00374 {
00375 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)user_data;
00376 if (caller->getText().size() >= 3)
00377 {
00378 self->childSetEnabled("Find",TRUE);
00379 }
00380 else
00381 {
00382 self->childSetEnabled("Find",FALSE);
00383 }
00384 }
00385
00386
00387 BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
00388 {
00389 if (key == KEY_RETURN
00390 && mask == MASK_NONE)
00391 {
00392 if (childHasFocus("Edit"))
00393 {
00394 onBtnFind(this);
00395 return TRUE;
00396 }
00397 else
00398 {
00399 onBtnAdd(this);
00400 return TRUE;
00401 }
00402 }
00403 else if (key == KEY_ESCAPE && mask == MASK_NONE)
00404 {
00405 close();
00406 return TRUE;
00407 }
00408
00409 return LLFloater::handleKeyHere(key, mask, called_from_parent);
00410 }