llfloateravatarpicker.cpp

Go to the documentation of this file.
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 // static
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();      /* Flawfinder: ignore */
00069                 sInstance->center();
00070                 sInstance->setAllowMultiple(allow_multiple);
00071         }
00072         else
00073         {
00074                 sInstance->open();      /*Flawfinder: ignore*/
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 // Default constructor
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 // Destroys the object
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 // static callback for inventory picker (select from calling cards)
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 // Callback for inventory picker (select from calling cards)
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         {       // Nothing selected in the search results
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                                 {       // Have a calling card selected, so clear anything from the search panel
00245                                         first_calling_card = FALSE;
00246                                         mAvatarIDs.clear();
00247                                         mAvatarNames.clear();
00248                                         mListNames->deselectAllItems();
00249                                 }
00250 
00251                                 // Add calling card info to the selected avatars
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);      // not used right now
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 // static 
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]; /*Flawfinder: ignore*/
00309         char    last_name[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
00310 
00311         msg->getUUID("AgentData", "AgentID", agent_id);
00312         msg->getUUID("AgentData", "QueryID", query_id);
00313 
00314         // Not for us
00315         if (agent_id != gAgent.getID()) return;
00316 
00317         // Dialog already closed
00318         LLFloaterAvatarPicker *self = sInstance;
00319         if (!self) return;
00320 
00321         // these are not results from our last request
00322         if (query_id != self->mQueryID)
00323         {
00324                 return;
00325         }
00326 
00327         if (!self->mResultsReturned)
00328         {
00329                 // clear "Searching" label on first results
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; // value
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 //static
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 // virtual
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 }

Generated on Fri May 16 08:33:22 2008 for SecondLife by  doxygen 1.5.5