diff options
Diffstat (limited to 'linden/indra/newview/llfloateravatarpicker.cpp')
-rw-r--r-- | linden/indra/newview/llfloateravatarpicker.cpp | 389 |
1 files changed, 242 insertions, 147 deletions
diff --git a/linden/indra/newview/llfloateravatarpicker.cpp b/linden/indra/newview/llfloateravatarpicker.cpp index 216eea7..25ce7c2 100644 --- a/linden/indra/newview/llfloateravatarpicker.cpp +++ b/linden/indra/newview/llfloateravatarpicker.cpp | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * $LicenseInfo:firstyear=2003&license=viewergpl$ | 4 | * $LicenseInfo:firstyear=2003&license=viewergpl$ |
5 | * | 5 | * |
6 | * Copyright (c) 2003-2008, Linden Research, Inc. | 6 | * Copyright (c) 2003-2009, Linden Research, Inc. |
7 | * | 7 | * |
8 | * Second Life Viewer Source Code | 8 | * Second Life Viewer Source Code |
9 | * The source code in this file ("Source Code") is provided by Linden Lab | 9 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -34,15 +34,18 @@ | |||
34 | 34 | ||
35 | #include "message.h" | 35 | #include "message.h" |
36 | 36 | ||
37 | #include "llagent.h" | ||
37 | #include "llbutton.h" | 38 | #include "llbutton.h" |
38 | #include "llfocusmgr.h" | 39 | #include "llfocusmgr.h" |
39 | #include "llinventoryview.h" | 40 | #include "llinventoryview.h" |
40 | #include "llinventorymodel.h" | 41 | #include "llinventorymodel.h" |
42 | #include "llinventorytype.h" | ||
41 | #include "lllineeditor.h" | 43 | #include "lllineeditor.h" |
42 | #include "llscrolllistctrl.h" | 44 | #include "llscrolllistctrl.h" |
43 | #include "lltextbox.h" | 45 | #include "lltextbox.h" |
44 | #include "lluictrlfactory.h" | 46 | #include "lluictrlfactory.h" |
45 | #include "llagent.h" | 47 | #include "llviewercontrol.h" |
48 | #include "llworld.h" | ||
46 | 49 | ||
47 | const S32 MIN_WIDTH = 200; | 50 | const S32 MIN_WIDTH = 200; |
48 | const S32 MIN_HEIGHT = 340; | 51 | const S32 MIN_HEIGHT = 340; |
@@ -58,6 +61,8 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback, | |||
58 | BOOL allow_multiple, | 61 | BOOL allow_multiple, |
59 | BOOL closeOnSelect) | 62 | BOOL closeOnSelect) |
60 | { | 63 | { |
64 | // TODO: This class should not be a singleton as it's used in multiple places | ||
65 | // and therefore can't be used simultaneously. -MG | ||
61 | if (!sInstance) | 66 | if (!sInstance) |
62 | { | 67 | { |
63 | sInstance = new LLFloaterAvatarPicker(); | 68 | sInstance = new LLFloaterAvatarPicker(); |
@@ -77,6 +82,7 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback, | |||
77 | sInstance->setAllowMultiple(allow_multiple); | 82 | sInstance->setAllowMultiple(allow_multiple); |
78 | } | 83 | } |
79 | 84 | ||
85 | sInstance->mNearMeListComplete = FALSE; | ||
80 | sInstance->mCloseOnSelect = closeOnSelect; | 86 | sInstance->mCloseOnSelect = closeOnSelect; |
81 | return sInstance; | 87 | return sInstance; |
82 | } | 88 | } |
@@ -97,39 +103,58 @@ BOOL LLFloaterAvatarPicker::postBuild() | |||
97 | 103 | ||
98 | childSetAction("Find", onBtnFind, this); | 104 | childSetAction("Find", onBtnFind, this); |
99 | childDisable("Find"); | 105 | childDisable("Find"); |
106 | childSetAction("Refresh", onBtnRefresh, this); | ||
107 | childSetCommitCallback("near_me_range", onRangeAdjust, this); | ||
100 | 108 | ||
101 | mListNames = getChild<LLScrollListCtrl>("Names"); | 109 | childSetDoubleClickCallback("SearchResults", onBtnSelect); |
102 | childSetDoubleClickCallback("Names",onBtnAdd); | 110 | childSetDoubleClickCallback("NearMe", onBtnSelect); |
103 | childSetCommitCallback("Names", onList, this); | 111 | childSetCommitCallback("SearchResults", onList, this); |
104 | childDisable("Names"); | 112 | childSetCommitCallback("NearMe", onList, this); |
113 | childDisable("SearchResults"); | ||
105 | 114 | ||
106 | childSetAction("Select", onBtnAdd, this); | 115 | childSetAction("Select", onBtnSelect, this); |
107 | childDisable("Select"); | 116 | childDisable("Select"); |
108 | 117 | ||
109 | childSetAction("Close", onBtnClose, this); | 118 | childSetAction("Cancel", onBtnClose, this); |
110 | 119 | ||
111 | childSetFocus("Edit"); | 120 | childSetFocus("Edit"); |
112 | 121 | ||
113 | if (mListNames) | 122 | LLPanel* search_panel = getChild<LLPanel>("SearchPanel"); |
123 | if (search_panel) | ||
114 | { | 124 | { |
115 | mListNames->addCommentText(std::string("No results")); // *TODO: Translate | 125 | // Start searching when Return is pressed in the line editor. |
126 | search_panel->setDefaultBtn("Find"); | ||
116 | } | 127 | } |
117 | 128 | ||
118 | mInventoryPanel = getChild<LLInventoryPanel>("Inventory Panel"); | 129 | getChild<LLScrollListCtrl>("SearchResults")->addCommentText(getString("no_results")); |
119 | if(mInventoryPanel) | 130 | |
120 | { | 131 | LLInventoryPanel* inventory_panel = getChild<LLInventoryPanel>("InventoryPanel"); |
121 | mInventoryPanel->setFilterTypes(LLInventoryType::NIT_CALLCARD); | 132 | inventory_panel->setFilterTypes(LLInventoryType::NIT_CALLCARD); |
122 | mInventoryPanel->setFollowsAll(); | 133 | inventory_panel->setFollowsAll(); |
123 | mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); | 134 | inventory_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); |
124 | mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD); | 135 | inventory_panel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD); |
125 | mInventoryPanel->setSelectCallback(LLFloaterAvatarPicker::onSelectionChange, this); | 136 | inventory_panel->setSelectCallback(LLFloaterAvatarPicker::onCallingCardSelectionChange, this); |
126 | } | 137 | |
127 | 138 | childSetTabChangeCallback("ResidentChooserTabs", "SearchPanel", onTabChanged, this); | |
139 | childSetTabChangeCallback("ResidentChooserTabs", "CallingCardsPanel", onTabChanged, this); | ||
140 | childSetTabChangeCallback("ResidentChooserTabs", "NearMePanel", onTabChanged, this); | ||
141 | |||
128 | setAllowMultiple(FALSE); | 142 | setAllowMultiple(FALSE); |
129 | 143 | ||
130 | return TRUE; | 144 | return TRUE; |
131 | } | 145 | } |
132 | 146 | ||
147 | void LLFloaterAvatarPicker::onTabChanged(void* userdata, bool from_click) | ||
148 | { | ||
149 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | ||
150 | if (!self) | ||
151 | { | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | self->childSetEnabled("Select", self->visibleItemsSelected()); | ||
156 | } | ||
157 | |||
133 | // Destroys the object | 158 | // Destroys the object |
134 | LLFloaterAvatarPicker::~LLFloaterAvatarPicker() | 159 | LLFloaterAvatarPicker::~LLFloaterAvatarPicker() |
135 | { | 160 | { |
@@ -144,22 +169,50 @@ void LLFloaterAvatarPicker::onBtnFind(void* userdata) | |||
144 | if(self) self->find(); | 169 | if(self) self->find(); |
145 | } | 170 | } |
146 | 171 | ||
147 | void LLFloaterAvatarPicker::onBtnAdd(void* userdata) | 172 | static void getSelectedAvatarData(const LLScrollListCtrl* from, std::vector<std::string>& avatar_names, std::vector<LLUUID>& avatar_ids) |
173 | { | ||
174 | std::vector<LLScrollListItem*> items = from->getAllSelected(); | ||
175 | for (std::vector<LLScrollListItem*>::iterator iter = items.begin(); iter != items.end(); ++iter) | ||
176 | { | ||
177 | LLScrollListItem* item = *iter; | ||
178 | if (item->getUUID().notNull()) | ||
179 | { | ||
180 | avatar_names.push_back(item->getColumn(0)->getValue().asString()); | ||
181 | avatar_ids.push_back(item->getUUID()); | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | void LLFloaterAvatarPicker::onBtnSelect(void* userdata) | ||
148 | { | 187 | { |
149 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | 188 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; |
150 | 189 | ||
151 | if(self->mCallback) | 190 | if(self->mCallback) |
152 | { | 191 | { |
153 | self->mCallback(self->mAvatarNames, self->mAvatarIDs, self->mCallbackUserdata); | 192 | LLPanel* active_panel = self->childGetVisibleTab("ResidentChooserTabs"); |
154 | } | 193 | |
155 | if (self->mInventoryPanel) | 194 | if(active_panel == self->getChild<LLPanel>("CallingCardsPanel")) |
156 | { | 195 | { |
157 | self->mInventoryPanel->setSelection(LLUUID::null, FALSE); | 196 | self->mCallback(self->mSelectedInventoryAvatarNames, self->mSelectedInventoryAvatarIDs, self->mCallbackUserdata); |
158 | } | 197 | } |
159 | if (self->mListNames) | 198 | else if(active_panel == self->getChild<LLPanel>("SearchPanel")) |
160 | { | 199 | { |
161 | self->mListNames->deselectAllItems(TRUE); | 200 | std::vector<std::string> avatar_names; |
201 | std::vector<LLUUID> avatar_ids; | ||
202 | getSelectedAvatarData(self->getChild<LLScrollListCtrl>("SearchResults"), avatar_names, avatar_ids); | ||
203 | self->mCallback(avatar_names, avatar_ids, self->mCallbackUserdata); | ||
204 | } | ||
205 | else if(active_panel == self->getChild<LLPanel>("NearMePanel")) | ||
206 | { | ||
207 | std::vector<std::string> avatar_names; | ||
208 | std::vector<LLUUID> avatar_ids; | ||
209 | getSelectedAvatarData(self->getChild<LLScrollListCtrl>("NearMe"), avatar_names, avatar_ids); | ||
210 | self->mCallback(avatar_names, avatar_ids, self->mCallbackUserdata); | ||
211 | } | ||
162 | } | 212 | } |
213 | self->getChild<LLInventoryPanel>("InventoryPanel")->setSelection(LLUUID::null, FALSE); | ||
214 | self->getChild<LLScrollListCtrl>("SearchResults")->deselectAllItems(TRUE); | ||
215 | self->getChild<LLScrollListCtrl>("NearMe")->deselectAllItems(TRUE); | ||
163 | if(self->mCloseOnSelect) | 216 | if(self->mCloseOnSelect) |
164 | { | 217 | { |
165 | self->mCloseOnSelect = FALSE; | 218 | self->mCloseOnSelect = FALSE; |
@@ -167,68 +220,61 @@ void LLFloaterAvatarPicker::onBtnAdd(void* userdata) | |||
167 | } | 220 | } |
168 | } | 221 | } |
169 | 222 | ||
223 | void LLFloaterAvatarPicker::onBtnRefresh(void* userdata) | ||
224 | { | ||
225 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | ||
226 | if (!self) | ||
227 | { | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | self->getChild<LLScrollListCtrl>("NearMe")->deleteAllItems(); | ||
232 | self->getChild<LLScrollListCtrl>("NearMe")->addCommentText(self->getString("searching")); | ||
233 | self->mNearMeListComplete = FALSE; | ||
234 | } | ||
235 | |||
170 | void LLFloaterAvatarPicker::onBtnClose(void* userdata) | 236 | void LLFloaterAvatarPicker::onBtnClose(void* userdata) |
171 | { | 237 | { |
172 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | 238 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; |
173 | if(self) self->close(); | 239 | if(self) self->close(); |
174 | } | 240 | } |
175 | 241 | ||
242 | void LLFloaterAvatarPicker::onRangeAdjust(LLUICtrl* source, void* data) | ||
243 | { | ||
244 | LLFloaterAvatarPicker::onBtnRefresh(data); | ||
245 | } | ||
246 | |||
176 | void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata) | 247 | void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata) |
177 | { | 248 | { |
178 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; | 249 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata; |
179 | if (!self) | 250 | if (self) |
180 | { | ||
181 | return; | ||
182 | } | ||
183 | |||
184 | self->mAvatarIDs.clear(); | ||
185 | self->mAvatarNames.clear(); | ||
186 | |||
187 | if (!self->mListNames) | ||
188 | { | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | std::vector<LLScrollListItem*> items = | ||
193 | self->mListNames->getAllSelected(); | ||
194 | for ( | ||
195 | std::vector<LLScrollListItem*>::iterator iter = items.begin(); | ||
196 | iter != items.end(); | ||
197 | ++iter) | ||
198 | { | 251 | { |
199 | LLScrollListItem* item = *iter; | 252 | self->childSetEnabled("Select", self->visibleItemsSelected()); |
200 | self->mAvatarNames.push_back(item->getColumn(0)->getValue().asString()); | ||
201 | self->mAvatarIDs.push_back(item->getUUID()); | ||
202 | self->childSetEnabled("Select", TRUE); | ||
203 | } | 253 | } |
204 | } | 254 | } |
205 | 255 | ||
206 | // static callback for inventory picker (select from calling cards) | 256 | // static callback for inventory picker (select from calling cards) |
207 | void LLFloaterAvatarPicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data) | 257 | void LLFloaterAvatarPicker::onCallingCardSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data) |
208 | { | 258 | { |
209 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data; | 259 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data; |
210 | if (self) | 260 | if (self) |
211 | { | 261 | { |
212 | self->doSelectionChange( items, user_action, data ); | 262 | self->doCallingCardSelectionChange( items, user_action, data ); |
213 | } | 263 | } |
214 | } | 264 | } |
215 | 265 | ||
216 | // Callback for inventory picker (select from calling cards) | 266 | // Callback for inventory picker (select from calling cards) |
217 | void LLFloaterAvatarPicker::doSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data) | 267 | void LLFloaterAvatarPicker::doCallingCardSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data) |
218 | { | 268 | { |
219 | if (!mListNames) | 269 | bool panel_active = (childGetVisibleTab("ResidentChooserTabs") == getChild<LLPanel>("CallingCardsPanel")); |
270 | |||
271 | mSelectedInventoryAvatarIDs.clear(); | ||
272 | mSelectedInventoryAvatarNames.clear(); | ||
273 | |||
274 | if (panel_active) | ||
220 | { | 275 | { |
221 | return; | ||
222 | } | ||
223 | |||
224 | std::vector<LLScrollListItem*> search_items = mListNames->getAllSelected(); | ||
225 | if ( search_items.size() == 0 ) | ||
226 | { // Nothing selected in the search results | ||
227 | mAvatarIDs.clear(); | ||
228 | mAvatarNames.clear(); | ||
229 | childSetEnabled("Select", FALSE); | 276 | childSetEnabled("Select", FALSE); |
230 | } | 277 | } |
231 | BOOL first_calling_card = TRUE; | ||
232 | 278 | ||
233 | std::deque<LLFolderViewItem*>::const_iterator item_it; | 279 | std::deque<LLFolderViewItem*>::const_iterator item_it; |
234 | for (item_it = items.begin(); item_it != items.end(); ++item_it) | 280 | for (item_it = items.begin(); item_it != items.end(); ++item_it) |
@@ -237,26 +283,97 @@ void LLFloaterAvatarPicker::doSelectionChange(const std::deque<LLFolderViewItem* | |||
237 | if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) | 283 | if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) |
238 | { | 284 | { |
239 | LLInventoryItem* item = gInventory.getItem(listenerp->getUUID()); | 285 | LLInventoryItem* item = gInventory.getItem(listenerp->getUUID()); |
240 | |||
241 | if (item) | 286 | if (item) |
242 | { | 287 | { |
243 | if ( first_calling_card ) | 288 | mSelectedInventoryAvatarIDs.push_back(item->getCreatorUUID()); |
244 | { // Have a calling card selected, so clear anything from the search panel | 289 | mSelectedInventoryAvatarNames.push_back(listenerp->getName()); |
245 | first_calling_card = FALSE; | ||
246 | mAvatarIDs.clear(); | ||
247 | mAvatarNames.clear(); | ||
248 | mListNames->deselectAllItems(); | ||
249 | } | ||
250 | |||
251 | // Add calling card info to the selected avatars | ||
252 | mAvatarIDs.push_back(item->getCreatorUUID()); | ||
253 | mAvatarNames.push_back(listenerp->getName()); | ||
254 | childSetEnabled("Select", TRUE); | ||
255 | } | 290 | } |
256 | } | 291 | } |
257 | } | 292 | } |
293 | |||
294 | if (panel_active) | ||
295 | { | ||
296 | childSetEnabled("Select", visibleItemsSelected()); | ||
297 | } | ||
258 | } | 298 | } |
259 | 299 | ||
300 | void LLFloaterAvatarPicker::populateNearMe() | ||
301 | { | ||
302 | BOOL all_loaded = TRUE; | ||
303 | BOOL empty = TRUE; | ||
304 | LLScrollListCtrl* near_me_scroller = getChild<LLScrollListCtrl>("NearMe"); | ||
305 | near_me_scroller->deleteAllItems(); | ||
306 | |||
307 | std::vector<LLUUID> avatar_ids; | ||
308 | LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); | ||
309 | for(U32 i=0; i<avatar_ids.size(); i++) | ||
310 | { | ||
311 | LLUUID& av = avatar_ids[i]; | ||
312 | if(av == gAgent.getID()) continue; | ||
313 | LLSD element; | ||
314 | element["id"] = av; // value | ||
315 | std::string fullname; | ||
316 | if(!gCacheName->getFullName(av, fullname)) | ||
317 | { | ||
318 | element["columns"][0]["value"] = LLCacheName::getDefaultName(); | ||
319 | all_loaded = FALSE; | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | element["columns"][0]["value"] = fullname; | ||
324 | } | ||
325 | near_me_scroller->addElement(element); | ||
326 | empty = FALSE; | ||
327 | } | ||
328 | |||
329 | if (empty) | ||
330 | { | ||
331 | childDisable("NearMe"); | ||
332 | childDisable("Select"); | ||
333 | near_me_scroller->addCommentText(getString("no_one_near")); | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | childEnable("NearMe"); | ||
338 | childEnable("Select"); | ||
339 | near_me_scroller->selectFirstItem(); | ||
340 | onList(near_me_scroller, this); | ||
341 | near_me_scroller->setFocus(TRUE); | ||
342 | } | ||
343 | |||
344 | if (all_loaded) | ||
345 | { | ||
346 | mNearMeListComplete = TRUE; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | void LLFloaterAvatarPicker::draw() | ||
351 | { | ||
352 | LLFloater::draw(); | ||
353 | if (!mNearMeListComplete && childGetVisibleTab("ResidentChooserTabs") == getChild<LLPanel>("NearMePanel")) | ||
354 | { | ||
355 | populateNearMe(); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | BOOL LLFloaterAvatarPicker::visibleItemsSelected() const | ||
360 | { | ||
361 | LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs"); | ||
362 | |||
363 | if(active_panel == getChild<LLPanel>("SearchPanel")) | ||
364 | { | ||
365 | return getChild<LLScrollListCtrl>("SearchResults")->getFirstSelectedIndex() >= 0; | ||
366 | } | ||
367 | else if(active_panel == getChild<LLPanel>("CallingCardsPanel")) | ||
368 | { | ||
369 | return mSelectedInventoryAvatarIDs.size() > 0; | ||
370 | } | ||
371 | else if(active_panel == getChild<LLPanel>("NearMePanel")) | ||
372 | { | ||
373 | return getChild<LLScrollListCtrl>("NearMe")->getFirstSelectedIndex() >= 0; | ||
374 | } | ||
375 | return FALSE; | ||
376 | } | ||
260 | 377 | ||
261 | void LLFloaterAvatarPicker::find() | 378 | void LLFloaterAvatarPicker::find() |
262 | { | 379 | { |
@@ -276,11 +393,8 @@ void LLFloaterAvatarPicker::find() | |||
276 | 393 | ||
277 | gAgent.sendReliableMessage(); | 394 | gAgent.sendReliableMessage(); |
278 | 395 | ||
279 | if (mListNames) | 396 | getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems(); |
280 | { | 397 | getChild<LLScrollListCtrl>("SearchResults")->addCommentText(getString("searching")); |
281 | mListNames->deleteAllItems(); | ||
282 | mListNames->addCommentText(std::string("Searching...")); // *TODO: Translate | ||
283 | } | ||
284 | 398 | ||
285 | childSetEnabled("Select", FALSE); | 399 | childSetEnabled("Select", FALSE); |
286 | mResultsReturned = FALSE; | 400 | mResultsReturned = FALSE; |
@@ -288,15 +402,9 @@ void LLFloaterAvatarPicker::find() | |||
288 | 402 | ||
289 | void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple) | 403 | void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple) |
290 | { | 404 | { |
291 | mAllowMultiple = allow_multiple; | 405 | getChild<LLScrollListCtrl>("SearchResults")->setAllowMultipleSelection(allow_multiple); |
292 | if (mInventoryPanel) | 406 | getChild<LLInventoryPanel>("InventoryPanel")->setAllowMultiSelect(allow_multiple); |
293 | { | 407 | getChild<LLScrollListCtrl>("NearMe")->setAllowMultipleSelection(allow_multiple); |
294 | mInventoryPanel->setAllowMultiSelect(mAllowMultiple); | ||
295 | } | ||
296 | if (mListNames) | ||
297 | { | ||
298 | mListNames->setAllowMultipleSelection(mAllowMultiple); | ||
299 | } | ||
300 | } | 408 | } |
301 | 409 | ||
302 | // static | 410 | // static |
@@ -324,52 +432,48 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* | |||
324 | return; | 432 | return; |
325 | } | 433 | } |
326 | 434 | ||
327 | if (!self->mResultsReturned) | 435 | LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("SearchResults"); |
328 | { | 436 | |
329 | // clear "Searching" label on first results | 437 | // clear "Searching" label on first results |
330 | if (self->mListNames) | 438 | search_results->deleteAllItems(); |
331 | { | 439 | |
332 | self->mListNames->deleteAllItems(); | ||
333 | } | ||
334 | } | ||
335 | self->mResultsReturned = TRUE; | 440 | self->mResultsReturned = TRUE; |
336 | 441 | ||
337 | if (self->mListNames) | 442 | BOOL found_one = FALSE; |
338 | { | 443 | S32 num_new_rows = msg->getNumberOfBlocks("Data"); |
339 | BOOL found_one = FALSE; | 444 | for (S32 i = 0; i < num_new_rows; i++) |
340 | S32 num_new_rows = msg->getNumberOfBlocks("Data"); | 445 | { |
341 | for (S32 i = 0; i < num_new_rows; i++) | 446 | msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i); |
342 | { | 447 | msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i); |
343 | msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i); | 448 | msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, last_name, i); |
344 | msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i); | ||
345 | msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, last_name, i); | ||
346 | |||
347 | std::string avatar_name; | ||
348 | if (avatar_id.isNull()) | ||
349 | { | ||
350 | LLStringUtil::format_map_t map; | ||
351 | map["[TEXT]"] = self->childGetText("Edit"); | ||
352 | avatar_name = self->getString("NotFound", map); | ||
353 | self->mListNames->setEnabled(FALSE); | ||
354 | } | ||
355 | else | ||
356 | { | ||
357 | avatar_name = first_name + " " + last_name; | ||
358 | self->mListNames->setEnabled(TRUE); | ||
359 | found_one = TRUE; | ||
360 | } | ||
361 | LLSD element; | ||
362 | element["id"] = avatar_id; // value | ||
363 | element["columns"][0]["value"] = avatar_name; | ||
364 | self->mListNames->addElement(element); | ||
365 | } | ||
366 | 449 | ||
367 | if (found_one) | 450 | std::string avatar_name; |
451 | if (avatar_id.isNull()) | ||
368 | { | 452 | { |
369 | self->mListNames->selectFirstItem(); | 453 | LLStringUtil::format_map_t map; |
370 | self->onList(self->mListNames, self); | 454 | map["[TEXT]"] = self->childGetText("Edit"); |
371 | self->mListNames->setFocus(TRUE); | 455 | avatar_name = self->getString("not_found", map); |
456 | search_results->setEnabled(FALSE); | ||
457 | self->childDisable("Select"); | ||
372 | } | 458 | } |
459 | else | ||
460 | { | ||
461 | avatar_name = first_name + " " + last_name; | ||
462 | search_results->setEnabled(TRUE); | ||
463 | found_one = TRUE; | ||
464 | } | ||
465 | LLSD element; | ||
466 | element["id"] = avatar_id; // value | ||
467 | element["columns"][0]["value"] = avatar_name; | ||
468 | search_results->addElement(element); | ||
469 | } | ||
470 | |||
471 | if (found_one) | ||
472 | { | ||
473 | self->childEnable("Select"); | ||
474 | search_results->selectFirstItem(); | ||
475 | self->onList(search_results, self); | ||
476 | search_results->setFocus(TRUE); | ||
373 | } | 477 | } |
374 | } | 478 | } |
375 | 479 | ||
@@ -377,32 +481,23 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* | |||
377 | void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data) | 481 | void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data) |
378 | { | 482 | { |
379 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)user_data; | 483 | LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)user_data; |
380 | if (caller->getText().size() >= 3) | 484 | self->childSetEnabled("Find", caller->getText().size() >= 3); |
381 | { | ||
382 | self->childSetEnabled("Find",TRUE); | ||
383 | } | ||
384 | else | ||
385 | { | ||
386 | self->childSetEnabled("Find",FALSE); | ||
387 | } | ||
388 | } | 485 | } |
389 | 486 | ||
390 | // virtual | 487 | // virtual |
391 | BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask) | 488 | BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask) |
392 | { | 489 | { |
393 | if (key == KEY_RETURN | 490 | if (key == KEY_RETURN && mask == MASK_NONE) |
394 | && mask == MASK_NONE) | ||
395 | { | 491 | { |
396 | if (childHasFocus("Edit")) | 492 | if (childHasFocus("Edit")) |
397 | { | 493 | { |
398 | onBtnFind(this); | 494 | onBtnFind(this); |
399 | return TRUE; | ||
400 | } | 495 | } |
401 | else | 496 | else |
402 | { | 497 | { |
403 | onBtnAdd(this); | 498 | onBtnSelect(this); |
404 | return TRUE; | ||
405 | } | 499 | } |
500 | return TRUE; | ||
406 | } | 501 | } |
407 | else if (key == KEY_ESCAPE && mask == MASK_NONE) | 502 | else if (key == KEY_ESCAPE && mask == MASK_NONE) |
408 | { | 503 | { |