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 "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 // 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         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 // 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 = 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 // static callback for inventory picker (select from calling cards)
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 // Callback for inventory picker (select from calling cards)
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         {       // Nothing selected in the search results
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                                 {       // Have a calling card selected, so clear anything from the search panel
00242                                         first_calling_card = FALSE;
00243                                         mAvatarIDs.clear();
00244                                         mAvatarNames.clear();
00245                                         mListNames->deselectAllItems();
00246                                 }
00247 
00248                                 // Add calling card info to the selected avatars
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);      // not used right now
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 // static 
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]; /*Flawfinder: ignore*/
00306         char    last_name[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
00307 
00308         msg->getUUID("AgentData", "AgentID", agent_id);
00309         msg->getUUID("AgentData", "QueryID", query_id);
00310 
00311         // Not for us
00312         if (agent_id != agent_get_id()) return;
00313 
00314         // Dialog already closed
00315         LLFloaterAvatarPicker *self = sInstance;
00316         if (!self) return;
00317 
00318         // these are not results from our last request
00319         if (query_id != self->mQueryID)
00320         {
00321                 return;
00322         }
00323 
00324         if (!self->mResultsReturned)
00325         {
00326                 // clear "Searching" label on first results
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; // value
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 //static
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 // virtual
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 }

Generated on Thu Jul 1 06:08:31 2010 for Second Life Viewer by  doxygen 1.4.7