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 "lluictrlfactory.h"
00045 #include "llagent.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 LLUICtrlFactory::getInstance()->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 = getChild<LLScrollListCtrl>("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->addCommentText("No results");
00116 }
00117
00118 mInventoryPanel = getChild<LLInventoryPanel>("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 =
00193 self->mListNames->getAllSelected();
00194 for (
00195 std::vector<LLScrollListItem*>::iterator iter = items.begin();
00196 iter != items.end();
00197 ++iter)
00198 {
00199 LLScrollListItem* item = *iter;
00200 self->mAvatarNames.push_back(item->getColumn(0)->getValue().asString());
00201 self->mAvatarIDs.push_back(item->getUUID());
00202 self->childSetEnabled("Select", TRUE);
00203 }
00204 }
00205
00206
00207 void LLFloaterAvatarPicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
00208 {
00209 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data;
00210 if (self)
00211 {
00212 self->doSelectionChange( items, user_action, data );
00213 }
00214 }
00215
00216
00217 void LLFloaterAvatarPicker::doSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
00218 {
00219 if (!mListNames)
00220 {
00221 return;
00222 }
00223
00224 std::vector<LLScrollListItem*> search_items = mListNames->getAllSelected();
00225 if ( search_items.size() == 0 )
00226 {
00227 mAvatarIDs.clear();
00228 mAvatarNames.clear();
00229 childSetEnabled("Select", FALSE);
00230 }
00231 BOOL first_calling_card = TRUE;
00232
00233 std::deque<LLFolderViewItem*>::const_iterator item_it;
00234 for (item_it = items.begin(); item_it != items.end(); ++item_it)
00235 {
00236 LLFolderViewEventListener* listenerp = (*item_it)->getListener();
00237 if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
00238 {
00239 LLInventoryItem* item = gInventory.getItem(listenerp->getUUID());
00240
00241 if (item)
00242 {
00243 if ( first_calling_card )
00244 {
00245 first_calling_card = FALSE;
00246 mAvatarIDs.clear();
00247 mAvatarNames.clear();
00248 mListNames->deselectAllItems();
00249 }
00250
00251
00252 mAvatarIDs.push_back(item->getCreatorUUID());
00253 mAvatarNames.push_back(listenerp->getName());
00254 childSetEnabled("Select", TRUE);
00255 }
00256 }
00257 }
00258 }
00259
00260
00261 void LLFloaterAvatarPicker::find()
00262 {
00263 const LLString& text = childGetValue("Edit").asString();
00264
00265 mQueryID.generate();
00266
00267 LLMessageSystem* msg = gMessageSystem;
00268
00269 msg->newMessage("AvatarPickerRequest");
00270 msg->nextBlock("AgentData");
00271 msg->addUUID("AgentID", gAgent.getID());
00272 msg->addUUID("SessionID", gAgent.getSessionID());
00273 msg->addUUID("QueryID", mQueryID);
00274 msg->nextBlock("Data");
00275 msg->addString("Name", text);
00276
00277 gAgent.sendReliableMessage();
00278
00279 if (mListNames)
00280 {
00281 mListNames->deleteAllItems();
00282 mListNames->addCommentText("Searching...");
00283 }
00284
00285 childSetEnabled("Select", FALSE);
00286 mResultsReturned = FALSE;
00287 }
00288
00289 void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple)
00290 {
00291 mAllowMultiple = allow_multiple;
00292 if (mInventoryPanel)
00293 {
00294 mInventoryPanel->setAllowMultiSelect(mAllowMultiple);
00295 }
00296 if (mListNames)
00297 {
00298 mListNames->setAllowMultipleSelection(mAllowMultiple);
00299 }
00300 }
00301
00302
00303 void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)
00304 {
00305 LLUUID agent_id;
00306 LLUUID query_id;
00307 LLUUID avatar_id;
00308 char first_name[DB_FIRST_NAME_BUF_SIZE];
00309 char last_name[DB_LAST_NAME_BUF_SIZE];
00310
00311 msg->getUUID("AgentData", "AgentID", agent_id);
00312 msg->getUUID("AgentData", "QueryID", query_id);
00313
00314
00315 if (agent_id != gAgent.getID()) return;
00316
00317
00318 LLFloaterAvatarPicker *self = sInstance;
00319 if (!self) return;
00320
00321
00322 if (query_id != self->mQueryID)
00323 {
00324 return;
00325 }
00326
00327 if (!self->mResultsReturned)
00328 {
00329
00330 if (self->mListNames)
00331 {
00332 self->mListNames->deleteAllItems();
00333 }
00334 }
00335 self->mResultsReturned = TRUE;
00336
00337 if (self->mListNames)
00338 {
00339 BOOL found_one = FALSE;
00340 S32 num_new_rows = msg->getNumberOfBlocks("Data");
00341 for (S32 i = 0; i < num_new_rows; i++)
00342 {
00343 msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i);
00344 msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, DB_FIRST_NAME_BUF_SIZE, first_name, i);
00345 msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, DB_LAST_NAME_BUF_SIZE, last_name, i);
00346
00347 LLString avatar_name;
00348 if (avatar_id.isNull())
00349 {
00350 LLString::format_map_t map;
00351 map["[TEXT]"] = self->childGetText("Edit");
00352 avatar_name = self->getString("NotFound", map);
00353 self->mListNames->setEnabled(FALSE);
00354 }
00355 else
00356 {
00357 avatar_name = LLString(first_name) + " " + last_name;
00358 self->mListNames->setEnabled(TRUE);
00359 found_one = TRUE;
00360 }
00361 LLSD element;
00362 element["id"] = avatar_id;
00363 element["columns"][0]["value"] = avatar_name;
00364 self->mListNames->addElement(element);
00365 }
00366
00367 if (found_one)
00368 {
00369 self->mListNames->selectFirstItem();
00370 self->onList(self->mListNames, self);
00371 self->mListNames->setFocus(TRUE);
00372 }
00373 }
00374 }
00375
00376
00377 void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data)
00378 {
00379 LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)user_data;
00380 if (caller->getText().size() >= 3)
00381 {
00382 self->childSetEnabled("Find",TRUE);
00383 }
00384 else
00385 {
00386 self->childSetEnabled("Find",FALSE);
00387 }
00388 }
00389
00390
00391 BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask)
00392 {
00393 if (key == KEY_RETURN
00394 && mask == MASK_NONE)
00395 {
00396 if (childHasFocus("Edit"))
00397 {
00398 onBtnFind(this);
00399 return TRUE;
00400 }
00401 else
00402 {
00403 onBtnAdd(this);
00404 return TRUE;
00405 }
00406 }
00407 else if (key == KEY_ESCAPE && mask == MASK_NONE)
00408 {
00409 close();
00410 return TRUE;
00411 }
00412
00413 return LLFloater::handleKeyHere(key, mask);
00414 }