diff --git a/indra/newview/llfloateravatarinfo.cpp b/indra/newview/llfloateravatarinfo.cpp index 224099794..847f8ed54 100644 --- a/indra/newview/llfloateravatarinfo.cpp +++ b/indra/newview/llfloateravatarinfo.cpp @@ -57,8 +57,6 @@ const LLRect FAI_RECT(0, 530, 420, 0); // Globals //----------------------------------------------------------------------------- -LLMap< const LLUUID, LLFloaterAvatarInfo* > gAvatarInfoInstances; - class LLAgentHandler : public LLCommandHandler { public: @@ -107,7 +105,7 @@ BOOL LLFloaterAvatarInfo::postBuild() } LLFloaterAvatarInfo::LLFloaterAvatarInfo(const std::string& name, const LLRect &rect, const LLUUID &avatar_id) -: LLPreview(name, rect, FLOATER_TITLE, LLUUID::null, LLUUID::null), +: LLPreview(name, rect, FLOATER_TITLE, LLUUID::null, LLUUID::null), LLInstanceTracker(avatar_id), mAvatarID( avatar_id ), mSuggestedOnlineStatus(ONLINE_STATUS_NO) { @@ -124,16 +122,13 @@ LLFloaterAvatarInfo::LLFloaterAvatarInfo(const std::string& name, const LLRect & mPanelAvatarp->selectTab(0); } - gAvatarInfoInstances.addData(avatar_id, this); // must be done before callback below is called. //gCacheName->get(avatar_id, FALSE, callbackLoadAvatarName); - LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterAvatarInfo::callbackLoadAvatarName, _1, _2)); + LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterAvatarInfo::callbackLoadAvatarName, this, _1, _2)); } // virtual LLFloaterAvatarInfo::~LLFloaterAvatarInfo() { - // child views automatically deleted - gAvatarInfoInstances.removeData(mAvatarID); } void LLFloaterAvatarInfo::resetGroupList() @@ -155,28 +150,21 @@ LLFloaterAvatarInfo* LLFloaterAvatarInfo::show(const LLUUID &avatar_id) return NULL; } - LLFloaterAvatarInfo *floater; - if (gAvatarInfoInstances.checkData(avatar_id)) + LLFloaterAvatarInfo *floater = LLFloaterAvatarInfo::getInstance(avatar_id); + if(!floater) { - // ...bring that window to front - floater = gAvatarInfoInstances.getData(avatar_id); - floater->open(); /*Flawfinder: ignore*/ - } - else - { - floater = new LLFloaterAvatarInfo("avatarinfo", FAI_RECT, - avatar_id ); + floater = new LLFloaterAvatarInfo("avatarinfo", FAI_RECT, avatar_id ); floater->center(); - floater->open(); /*Flawfinder: ignore*/ } + + // ...bring that window to front + floater->open(); /*Flawfinder: ignore*/ return floater; } // Open profile to a certain tab. // static -void LLFloaterAvatarInfo::showFromObject( - const LLUUID& avatar_id, - std::string tab_name) +void LLFloaterAvatarInfo::showFromObject(const LLUUID& avatar_id,std::string tab_name) { LLFloaterAvatarInfo *floater = show(avatar_id); if (floater) @@ -216,24 +204,15 @@ void LLFloaterAvatarInfo::showFromProfile(const LLUUID &avatar_id, LLRect rect) return; } - LLFloaterAvatarInfo *floater; - if (gAvatarInfoInstances.checkData(avatar_id)) + LLFloaterAvatarInfo *floater = LLFloaterAvatarInfo::getInstance(avatar_id); + if(!floater) { - // ...bring that window to front - floater = gAvatarInfoInstances.getData(avatar_id); - } - else - { - floater = new LLFloaterAvatarInfo("avatarinfo", FAI_RECT, - avatar_id); + floater = new LLFloaterAvatarInfo("avatarinfo", FAI_RECT, avatar_id); floater->translate(rect.mLeft - floater->getRect().mLeft + 16, rect.mTop - floater->getRect().mTop - 16); floater->mPanelAvatarp->setAvatarID(avatar_id, LLStringUtil::null, ONLINE_STATUS_NO); } - if (floater) - { - floater->open(); - } + floater->open(); } void LLFloaterAvatarInfo::showProfileCallback(S32 option, void *userdata) @@ -244,20 +223,13 @@ void LLFloaterAvatarInfo::showProfileCallback(S32 option, void *userdata) } } -// static -void LLFloaterAvatarInfo::callbackLoadAvatarName(const LLUUID& id, - const LLAvatarName& av_name) +void LLFloaterAvatarInfo::callbackLoadAvatarName(const LLUUID& id, const LLAvatarName& av_name) { - LLFloaterAvatarInfo *floater = gAvatarInfoInstances.getIfThere(id); - - if (floater) - { - // Build a new title including the avatar name. - std::ostringstream title; - //title << first << " " << last << " - " << floater->getTitle(); - title << av_name.getCompleteName()<< " - " << floater->getTitle(); - floater->setTitle(title.str()); - } + // Build a new title including the avatar name. + std::ostringstream title; + //title << first << " " << last << " - " << floater->getTitle(); + title << av_name.getCompleteName()<< " - " << getTitle(); + setTitle(title.str()); } //// virtual @@ -273,11 +245,6 @@ BOOL LLFloaterAvatarInfo::canClose() return mPanelAvatarp && mPanelAvatarp->canClose(); } -LLFloaterAvatarInfo* LLFloaterAvatarInfo::getInstance(const LLUUID &id) -{ - return gAvatarInfoInstances.getIfThere(gAgentID); -} - void LLFloaterAvatarInfo::loadAsset() { if (mPanelAvatarp) { diff --git a/indra/newview/llfloateravatarinfo.h b/indra/newview/llfloateravatarinfo.h index 4df618d5e..b9682b308 100644 --- a/indra/newview/llfloateravatarinfo.h +++ b/indra/newview/llfloateravatarinfo.h @@ -43,6 +43,7 @@ #include "llpreview.h" #include "lluuid.h" #include "llpanelavatar.h" +#include "llinstancetracker.h" class LLAvatarName; class LLButton; @@ -60,7 +61,7 @@ class LLViewerTexture; class LLViewerObject; class LLFloaterAvatarInfo -: public LLPreview +: public LLPreview, public LLInstanceTracker { public: static void* createPanelAvatar(void* data); @@ -89,9 +90,8 @@ public: static void showFromProfile(const LLUUID &avatar_id, LLRect rect); - static LLFloaterAvatarInfo* getInstance(const LLUUID &id); static void showProfileCallback(S32 option, void *userdata); - static void callbackLoadAvatarName(const LLUUID& agent_id, const LLAvatarName& av_name); + void callbackLoadAvatarName(const LLUUID& agent_id, const LLAvatarName& av_name); void resetGroupList(); private: diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index dc0ad358c..5f0700eb4 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -1,31 +1,25 @@ /** * @file llfloateravatarpicker.cpp * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,13 +29,12 @@ // Viewer includes #include "llagent.h" +#include "llcallingcard.h" #include "llfocusmgr.h" -#include "llfoldervieweventlistener.h" -#include "llinventoryfunctions.h" -#include "llinventorymodel.h" -#include "llinventorypanel.h" +#include "llimview.h" // for gIMMgr +#include "lltooldraganddrop.h" // for LLToolDragAndDrop #include "llviewercontrol.h" -#include "llviewerregion.h" +#include "llviewerregion.h" // getCapability() #include "llworld.h" // Linden libraries @@ -50,7 +43,7 @@ #include "llcachename.h" #include "lllineeditor.h" #include "llscrolllistctrl.h" -#include "lltextbox.h" +#include "lltabcontainer.h" #include "lluictrlfactory.h" #include "message.h" @@ -58,40 +51,38 @@ #include "rlvhandler.h" // [/RLVa:KB] -const S32 MIN_WIDTH = 200; -const S32 MIN_HEIGHT = 340; -const LLRect FLOATER_RECT(0, 380, 240, 0); -const std::string FLOATER_TITLE = "Choose Resident"; - -// static -LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL; +//put it back as a member once the legacy path is out? static std::map sAvatarNameMap; LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback, BOOL allow_multiple, BOOL closeOnSelect) { - // TODO: This class should not be a singleton as it's used in multiple places - // and therefore can't be used simultaneously. -MG - - LLFloaterAvatarPicker* floater = sInstance ? sInstance : new LLFloaterAvatarPicker(); - floater->open(); /* Flawfinder: ignore */ - if(!sInstance) - { - sInstance = floater; - floater->center(); - } + // *TODO: Use a key to allow this not to be an effective singleton + + LLFloaterAvatarPicker* floater = getInstance(); + floater->open(); floater->mSelectionCallback = callback; floater->setAllowMultiple(allow_multiple); floater->mNearMeListComplete = FALSE; floater->mCloseOnSelect = closeOnSelect; + + if (!closeOnSelect) + { + // Use Select/Close + std::string select_string = floater->getString("Select"); + std::string close_string = floater->getString("Close"); + floater->getChild("ok_btn")->setLabel(select_string); + floater->getChild("cancel_btn")->setLabel(close_string); + } + return floater; } // Default constructor LLFloaterAvatarPicker::LLFloaterAvatarPicker() : - LLFloater(std::string("avatarpicker"), FLOATER_RECT, FLOATER_TITLE, TRUE, MIN_WIDTH, MIN_HEIGHT), + LLFloater(), mNumResultsReturned(0), mNearMeListComplete(FALSE), mCloseOnSelect(FALSE) @@ -101,8 +92,8 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker() : BOOL LLFloaterAvatarPicker::postBuild() { - childSetKeystrokeCallback("Edit", editKeystroke, this); - childSetKeystrokeCallback("EditUUID", editKeystroke, this); + childSetKeystrokeCallback("Edit", &LLFloaterAvatarPicker::editKeystroke, (void*)this); + childSetKeystrokeCallback("EditUUID", &LLFloaterAvatarPicker::editKeystroke, (void*)this); childSetAction("Find", boost::bind(&LLFloaterAvatarPicker::onBtnFind, this)); getChildView("Find")->setEnabled(FALSE); @@ -118,9 +109,14 @@ BOOL LLFloaterAvatarPicker::postBuild() nearme->setDoubleClickCallback(boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); nearme->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this)); - childSetAction("Select", boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); - getChildView("Select")->setEnabled(FALSE); - childSetAction("Cancel", boost::bind(&LLFloaterAvatarPicker::onBtnClose, this)); + LLScrollListCtrl* friends = getChild("Friends"); + friends->setDoubleClickCallback(boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + childSetAction("RefreshFriends", boost::bind(&LLFloaterAvatarPicker::populateFriend, this)); + getChild("Friends")->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this)); + + childSetAction("ok_btn", boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); + getChildView("ok_btn")->setEnabled(FALSE); + childSetAction("cancel_btn", boost::bind(&LLFloaterAvatarPicker::onBtnClose, this)); getChild("Edit")->setFocus(TRUE); @@ -133,32 +129,32 @@ BOOL LLFloaterAvatarPicker::postBuild() getChild("SearchResults")->setCommentText(getString("no_results")); - LLInventoryPanel* inventory_panel = getChild("InventoryPanel"); - inventory_panel->setFilterTypes(0x1 << LLInventoryType::IT_CALLINGCARD); - inventory_panel->setFollowsAll(); - inventory_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - inventory_panel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD); - inventory_panel->setSelectCallback(boost::bind(&LLFloaterAvatarPicker::onCallingCardSelectionChange, this, _1, _2)); - getChild("ResidentChooserTabs")->setCommitCallback( boost::bind(&LLFloaterAvatarPicker::onTabChanged,this)); - + setAllowMultiple(FALSE); + + center(); + + populateFriend(); return TRUE; } +void LLFloaterAvatarPicker::setOkBtnEnableCb(validate_callback_t cb) +{ + mOkButtonValidateSignal.connect(cb); +} + void LLFloaterAvatarPicker::onTabChanged() { - childSetEnabled("Select", visibleItemsSelected()); + getChildView("ok_btn")->setEnabled(isSelectBtnEnabled()); } // Destroys the object LLFloaterAvatarPicker::~LLFloaterAvatarPicker() { gFocusMgr.releaseFocusIfNeeded( this ); - - sInstance = NULL; } void LLFloaterAvatarPicker::onBtnFind() @@ -166,79 +162,61 @@ void LLFloaterAvatarPicker::onBtnFind() find(); } -static void getSelectedAvatarData(const LLScrollListCtrl* from, uuid_vec_t& avatar_ids, std::vector& avatar_names) +static void addAvatarUUID(const LLUUID av_id, uuid_vec_t& avatar_ids, std::vector& avatar_names) { - std::vector items = from->getAllSelected(); - for (std::vector::iterator iter = items.begin(); iter != items.end(); ++iter) + if (av_id.notNull()) { - LLScrollListItem* item = *iter; - if (item->getUUID().notNull()) - { - avatar_ids.push_back(item->getUUID()); + avatar_ids.push_back(av_id); - std::map::iterator iter = sAvatarNameMap.find(item->getUUID()); - if (iter != sAvatarNameMap.end()) - { - avatar_names.push_back(iter->second); - } - else - { - // the only case where it isn't in the name map is friends - // but it should be in the name cache - LLAvatarName av_name; - LLAvatarNameCache::get(item->getUUID(), &av_name); - avatar_names.push_back(av_name); - } + std::map::iterator iter = sAvatarNameMap.find(av_id); + if (iter != sAvatarNameMap.end()) + { + avatar_names.push_back(iter->second); + } + else + { + // the only case where it isn't in the name map is friends + // but it should be in the name cache + LLAvatarName av_name; + LLAvatarNameCache::get(av_id, &av_name); + avatar_names.push_back(av_name); } } } +static void getSelectedAvatarData(const LLUICtrl* from, uuid_vec_t& avatar_ids, std::vector& avatar_names) +{ + const LLScrollListCtrl* list = dynamic_cast(from); + if(list) + { + std::vector items = list->getAllSelected(); + for (std::vector::iterator iter = items.begin(); iter != items.end(); ++iter) + { + addAvatarUUID((*iter)->getUUID(), avatar_ids, avatar_names); + } + } + else + addAvatarUUID(from->getValue().asUUID(), avatar_ids, avatar_names); +} + + void LLFloaterAvatarPicker::onBtnSelect() { // If select btn not enabled then do not callback - if (!visibleItemsSelected()) + if (!isSelectBtnEnabled()) return; if(mSelectionCallback) { - std::vector avatar_names; - std::vector avatar_ids; std::string active_panel_name; - LLScrollListCtrl* list = NULL; - LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs"); + LLUICtrl* list = NULL; + LLPanel* active_panel = getChild("ResidentChooserTabs")->getCurrentPanel(); if(active_panel) { active_panel_name = active_panel->getName(); } - if(active_panel_name == "CallingCardsPanel") - { - avatar_ids = mSelectedInventoryAvatarIDs; - for(std::vector::size_type i = 0; i < avatar_ids.size(); ++i) - { - std::map::iterator iter = sAvatarNameMap.find(avatar_ids[i]); - LLAvatarName av_name; - if (iter != sAvatarNameMap.end()) - { - avatar_names.push_back(iter->second); - } - else if(LLAvatarNameCache::get(avatar_ids[i], &av_name)) - { - avatar_names.push_back(av_name); - } - else - { - std::string name = gCacheName->buildLegacyName(mSelectedInventoryAvatarNames[i]); - std::string::size_type pos = name.find(' '); - av_name.mLegacyFirstName = name.substr(pos); - av_name.mLegacyLastName = pos!=std::string::npos ? name.substr(pos+1) : "Resident"; - av_name.mDisplayName = name; - av_name.mUsername = ""; - avatar_names.push_back(av_name); - } - } - } - else if(active_panel_name == "SearchPanel") + if(active_panel_name == "SearchPanel") { list = getChild("SearchResults"); } @@ -246,38 +224,26 @@ void LLFloaterAvatarPicker::onBtnSelect() { list = getChild("NearMe"); } + else if (active_panel_name == "FriendsPanel") + { + list = getChild("Friends"); + } else if(active_panel_name == "KeyPanel") { - LLUUID specified = getChild("EditUUID")->getValue().asUUID(); - if(specified.isNull()) - return; - avatar_ids.push_back(specified); - - std::map::iterator iter = sAvatarNameMap.find(specified); - if (iter != sAvatarNameMap.end()) - { - avatar_names.push_back(iter->second); - } - else - { - LLAvatarName av_name; - LLAvatarNameCache::get(specified, &av_name); - avatar_names.push_back(av_name); - } + list = getChild("EditUUID"); } if(list) { + uuid_vec_t avatar_ids; + std::vector avatar_names; getSelectedAvatarData(list, avatar_ids, avatar_names); - } - if(!avatar_names.empty() && !avatar_ids.empty()) - { mSelectionCallback(avatar_ids, avatar_names); } } - getChild("InventoryPanel")->setSelection(LLUUID::null, FALSE); getChild("SearchResults")->deselectAllItems(TRUE); getChild("NearMe")->deselectAllItems(TRUE); + getChild("Friends")->deselectAllItems(TRUE); if(mCloseOnSelect) { mCloseOnSelect = FALSE; @@ -304,41 +270,7 @@ void LLFloaterAvatarPicker::onRangeAdjust() void LLFloaterAvatarPicker::onList() { - getChildView("Select")->setEnabled(visibleItemsSelected()); -} - -// Callback for inventory picker (select from calling cards) -void LLFloaterAvatarPicker::onCallingCardSelectionChange(const std::deque &items, BOOL user_action) -{ - bool panel_active = (childGetVisibleTab("ResidentChooserTabs") == getChild("CallingCardsPanel")); - - mSelectedInventoryAvatarIDs.clear(); - mSelectedInventoryAvatarNames.clear(); - - if (panel_active) - { - childSetEnabled("Select", FALSE); - } - - std::deque::const_iterator item_it; - for (item_it = items.begin(); item_it != items.end(); ++item_it) - { - LLFolderViewEventListener* listenerp = (*item_it)->getListener(); - if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) - { - LLInventoryItem* item = gInventory.getItem(listenerp->getUUID()); - if (item) - { - mSelectedInventoryAvatarIDs.push_back(item->getCreatorUUID()); - mSelectedInventoryAvatarNames.push_back(listenerp->getName()); - } - } - } - - if (panel_active) - { - childSetEnabled("Select", visibleItemsSelected()); - } + getChildView("ok_btn")->setEnabled(isSelectBtnEnabled()); } void LLFloaterAvatarPicker::populateNearMe() @@ -380,13 +312,13 @@ void LLFloaterAvatarPicker::populateNearMe() if (empty) { getChildView("NearMe")->setEnabled(FALSE); - getChildView("Select")->setEnabled(FALSE); + getChildView("ok_btn")->setEnabled(FALSE); near_me_scroller->setCommentText(getString("no_one_near")); } else { getChildView("NearMe")->setEnabled(TRUE); - getChildView("Select")->setEnabled(TRUE); + getChildView("ok_btn")->setEnabled(TRUE); near_me_scroller->selectFirstItem(); onList(); near_me_scroller->setFocus(TRUE); @@ -398,8 +330,39 @@ void LLFloaterAvatarPicker::populateNearMe() } } +void LLFloaterAvatarPicker::populateFriend() +{ + LLScrollListCtrl* friends_scroller = getChild("Friends"); + friends_scroller->deleteAllItems(); + LLCollectAllBuddies collector; + LLAvatarTracker::instance().applyFunctor(collector); + LLCollectAllBuddies::buddy_map_t::iterator it; + + for(it = collector.mOnline.begin(); it!=collector.mOnline.end(); it++) + { + friends_scroller->addStringUUIDItem(it->first, it->second); + } + for(it = collector.mOffline.begin(); it!=collector.mOffline.end(); it++) + { + friends_scroller->addStringUUIDItem(it->first, it->second); + } + friends_scroller->sortByColumnIndex(0, TRUE); +} + void LLFloaterAvatarPicker::draw() { + // sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars). + // lets check this via mOkButtonValidateSignal callback periodically. + static LLFrameTimer timer; + if (timer.hasExpired()) + { + timer.setTimerExpirySec(0.33f); // three times per second should be enough. + + // simulate list changes. + onList(); + timer.start(); + } + LLFloater::draw(); // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-1.0.0e @@ -425,7 +388,7 @@ void LLFloaterAvatarPicker::draw() } // [/RLVa:KB] - if (!mNearMeListComplete && childGetVisibleTab("ResidentChooserTabs") == getChild("NearMePanel")) + if (!mNearMeListComplete && getChild("ResidentChooserTabs")->getCurrentPanel() == getChild("NearMePanel")) { populateNearMe(); } @@ -433,20 +396,20 @@ void LLFloaterAvatarPicker::draw() BOOL LLFloaterAvatarPicker::visibleItemsSelected() const { - LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs"); + LLPanel* active_panel = getChild("ResidentChooserTabs")->getCurrentPanel(); if(active_panel == getChild("SearchPanel")) { return getChild("SearchResults")->getFirstSelectedIndex() >= 0; } - else if(active_panel == getChild("CallingCardsPanel")) - { - return !mSelectedInventoryAvatarIDs.empty(); - } else if(active_panel == getChild("NearMePanel")) { return getChild("NearMe")->getFirstSelectedIndex() >= 0; } + else if(active_panel == getChild("FriendsPanel")) + { + return getChild("Friends")->getFirstSelectedIndex() >= 0; + } else if(active_panel == getChild("KeyPanel")) { LLUUID specified = getChild("EditUUID")->getValue().asUUID(); @@ -473,10 +436,9 @@ public: // just set it to process so it displays 'not found' if ((200 <= status && status < 300) || status == 400) { - LLFloaterAvatarPicker* floater = LLFloaterAvatarPicker::sInstance; - if (floater) + if (LLFloaterAvatarPicker::instanceExists()) { - floater->processResponse(mQueryID, content); + LLFloaterAvatarPicker::getInstance()->processResponse(mQueryID, content); } } else @@ -495,7 +457,7 @@ void LLFloaterAvatarPicker::find() //clear our stored LLAvatarNames sAvatarNameMap.clear(); - const std::string& text = childGetValue("Edit").asString(); + std::string text = getChild("Edit")->getValue().asString(); mQueryID.generate(); @@ -536,15 +498,90 @@ void LLFloaterAvatarPicker::find() getChild("SearchResults")->deleteAllItems(); getChild("SearchResults")->setCommentText(getString("searching")); - childSetEnabled("Select", FALSE); + getChildView("ok_btn")->setEnabled(FALSE); mNumResultsReturned = 0; } void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple) { getChild("SearchResults")->setAllowMultipleSelection(allow_multiple); - getChild("InventoryPanel")->setAllowMultiSelect(allow_multiple); getChild("NearMe")->setAllowMultipleSelection(allow_multiple); + getChild("Friends")->setAllowMultipleSelection(allow_multiple); +} + +LLScrollListCtrl* LLFloaterAvatarPicker::getActiveList() +{ + std::string acvtive_panel_name; + LLScrollListCtrl* list = NULL; + LLPanel* active_panel = getChild("ResidentChooserTabs")->getCurrentPanel(); + if(active_panel) + { + acvtive_panel_name = active_panel->getName(); + } + if(acvtive_panel_name == "SearchPanel") + { + list = getChild("SearchResults"); + } + else if(acvtive_panel_name == "NearMePanel") + { + list = getChild("NearMe"); + } + else if (acvtive_panel_name == "FriendsPanel") + { + list = getChild("Friends"); + } + return list; +} + +BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, + void *cargo_data, EAcceptance *accept, + std::string& tooltip_msg) +{ + LLScrollListCtrl* list = getActiveList(); + if(list) + { + LLRect rc_list; + LLRect rc_point(x,y,x,y); + if (localRectToOtherView(rc_point, &rc_list, list)) + { + // Keep selected only one item + list->deselectAllItems(TRUE); + list->selectItemAt(rc_list.mLeft, rc_list.mBottom, mask); + LLScrollListItem* selection = list->getFirstSelected(); + if (selection) + { + LLUUID session_id = LLUUID::null; + LLUUID dest_agent_id = selection->getUUID(); + std::string avatar_name = selection->getColumn(0)->getValue().asString(); + if (dest_agent_id.notNull() && dest_agent_id != gAgentID) + { + if (drop) + { + // Start up IM before give the item + session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, dest_agent_id); + } + return LLToolDragAndDrop::handleGiveDragAndDrop(dest_agent_id, session_id, drop, + cargo_type, cargo_data, accept); + } + } + } + } + *accept = ACCEPT_NO; + return TRUE; +} + + +void LLFloaterAvatarPicker::openFriendsTab() +{ + LLTabContainer* tab_container = getChild("ResidentChooserTabs"); + if (tab_container == NULL) + { + llassert(tab_container != NULL); + return; + } + + tab_container->selectTabByName("FriendsPanel"); } // static @@ -562,8 +599,9 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* // Not for us if (agent_id != gAgent.getID()) return; - // Dialog already closed - LLFloaterAvatarPicker *floater = sInstance; + if(!instanceExists()) + return; + LLFloaterAvatarPicker *floater = getInstance(); // floater is closed or these are not results from our last request if (NULL == floater || query_id != floater->mQueryID) @@ -591,10 +629,10 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* if (avatar_id.isNull()) { LLStringUtil::format_map_t map; - map["[TEXT]"] = floater->childGetText("Edit"); + map["[TEXT]"] = floater->getChild("Edit")->getValue().asString(); avatar_name = floater->getString("not_found", map); search_results->setEnabled(FALSE); - floater->getChildView("Select")->setEnabled(FALSE); + floater->getChildView("ok_btn")->setEnabled(FALSE); } else { @@ -619,7 +657,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* if (found_one) { - floater->getChildView("Select")->setEnabled(TRUE); + floater->getChildView("ok_btn")->setEnabled(TRUE); search_results->selectFirstItem(); floater->onList(); search_results->setFocus(TRUE); @@ -644,7 +682,7 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& item["columns"][0]["value"] = getString("not_found", map); search_results->addElement(item); search_results->setEnabled(false); - getChildView("Select")->setEnabled(false); + getChildView("ok_btn")->setEnabled(false); return; } @@ -670,7 +708,7 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& sAvatarNameMap[row["id"].asUUID()] = avatar_name; } - getChildView("Select")->setEnabled(true); + getChildView("ok_btn")->setEnabled(true); search_results->setEnabled(true); search_results->selectFirstItem(); onList(); @@ -681,14 +719,10 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data) { LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)user_data; - LLPanel* active_panel = self->childGetVisibleTab("ResidentChooserTabs"); - if(active_panel == self->getChild("SearchPanel")) - self->childSetEnabled("Find", caller->getText().size() >= 3); - else if(active_panel == self->getChild("KeyPanel")) - { - LLUUID specified = self->getChild("EditUUID")->getValue().asUUID(); - self->childSetEnabled("Select", specified.notNull()); - } + if(caller->getName() == "Edit") + self->getChildView("Find")->setEnabled(caller->getText().size() >= 3); + else + self->childSetEnabled("Select", caller->getValue().asUUID().notNull()); } // virtual @@ -714,3 +748,45 @@ BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask) return LLFloater::handleKeyHere(key, mask); } + +bool LLFloaterAvatarPicker::isSelectBtnEnabled() +{ + bool ret_val = visibleItemsSelected(); + + if ( ret_val && mOkButtonValidateSignal.num_slots() ) + { + std::string active_panel_name; + LLUICtrl* list = NULL; + LLPanel* active_panel = getChild("ResidentChooserTabs")->getCurrentPanel(); + if(active_panel) + { + active_panel_name = active_panel->getName(); + } + if(active_panel_name == "SearchPanel") + { + list = getChild("SearchResults"); + } + else if(active_panel_name == "NearMePanel") + { + list = getChild("NearMe"); + } + else if (active_panel_name == "FriendsPanel") + { + list = getChild("Friends"); + } + else if(active_panel_name == "KeyPanel") + { + list = getChild("EditUUID"); + } + + if(list) + { + uuid_vec_t avatar_ids; + std::vector avatar_names; + getSelectedAvatarData(list, avatar_ids, avatar_names); + return mOkButtonValidateSignal(avatar_ids); + } + } + + return ret_val; +} diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 2fc8543a8..7e38611f1 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -2,31 +2,25 @@ * @file llfloateravatarpicker.h * @brief was llavatarpicker.h * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,7 +34,7 @@ class LLAvatarName; class LLScrollListCtrl; -class LLFloaterAvatarPicker : public LLFloater +class LLFloaterAvatarPicker : public LLFloater, public LLSingleton { public: typedef boost::signals2::signal validate_signal_t; @@ -52,14 +46,25 @@ public: static LLFloaterAvatarPicker* show(select_callback_t callback, BOOL allow_multiple = FALSE, BOOL closeOnSelect = FALSE); + + // do not call these directly + LLFloaterAvatarPicker(); + virtual ~LLFloaterAvatarPicker(); virtual BOOL postBuild(); + void setOkBtnEnableCb(validate_callback_t cb); + static void processAvatarPickerReply(class LLMessageSystem* msg, void**); void processResponse(const LLUUID& query_id, const LLSD& content); - static LLFloaterAvatarPicker* sInstance; -private: + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, + void *cargo_data, EAcceptance *accept, + std::string& tooltip_msg); + void openFriendsTab(); + +private: static void editKeystroke(class LLLineEditor* caller, void* user_data); void onBtnFind(); @@ -69,30 +74,26 @@ private: void onBtnClose(); void onList(); void onTabChanged(); - - void onCallingCardSelectionChange(const std::deque &items, BOOL user_action); + bool isSelectBtnEnabled(); void populateNearMe(); + void populateFriend(); BOOL visibleItemsSelected() const; // Returns true if any items in the current tab are selected. void find(); void setAllowMultiple(BOOL allow_multiple); + LLScrollListCtrl* getActiveList(); virtual void draw(); virtual BOOL handleKeyHere(KEY key, MASK mask); - std::vector mSelectedInventoryAvatarIDs; - std::vector mSelectedInventoryAvatarNames; LLUUID mQueryID; int mNumResultsReturned; BOOL mNearMeListComplete; BOOL mCloseOnSelect; + validate_signal_t mOkButtonValidateSignal; select_callback_t mSelectionCallback; - - // do not call these directly - LLFloaterAvatarPicker(); - virtual ~LLFloaterAvatarPicker(); }; #endif diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 2cbe64c02..18d4b3a01 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -112,8 +112,6 @@ LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; BOOL LLVoiceChannel::sSuspended = FALSE; -std::set LLFloaterIMPanel::sFloaterIMPanels; - void session_starter_helper( const LLUUID& temp_session_id, const LLUUID& other_participant_id, @@ -1124,10 +1122,6 @@ LLFloaterIMPanel::LLFloaterIMPanel( llwarns << "Other participant is NULL" << llendl; } - // [Ansariel: Display name support] - sFloaterIMPanels.insert(this); - // [/Ansariel: Display name support] - init(session_label); } @@ -1164,10 +1158,6 @@ LLFloaterIMPanel::LLFloaterIMPanel( { llwarns << "Other participant is NULL" << llendl; } - - // [Ansariel: Display name support] - sFloaterIMPanels.insert(this); - // [/Ansariel: Display name support] mSessionInitialTargetIDs = ids; init(session_label); @@ -1299,28 +1289,18 @@ void LLFloaterIMPanel::init(const std::string& session_label) void LLFloaterIMPanel::lookupName() { - LLAvatarNameCache::get(mOtherParticipantUUID, boost::bind(&LLFloaterIMPanel::onAvatarNameLookup, _1, _2, this)); + LLAvatarNameCache::get(mOtherParticipantUUID, boost::bind(&LLFloaterIMPanel::onAvatarNameLookup, this, _1, _2)); } -//static -void LLFloaterIMPanel::onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name, void* data) +void LLFloaterIMPanel::onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name) { - LLFloaterIMPanel* self = (LLFloaterIMPanel*)data; - - if (self && sFloaterIMPanels.count(self) != 0) - { - std::string title; - LLAvatarNameCache::getPNSName(avatar_name, title); - self->setTitle(title); - } + std::string title; + LLAvatarNameCache::getPNSName(avatar_name, title); + setTitle(title); } LLFloaterIMPanel::~LLFloaterIMPanel() { - // [Ansariel: Display name support] - sFloaterIMPanels.erase(this); - // [/Ansariel: Display name support] - delete mSpeakers; mSpeakers = NULL; diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 61d8c01f7..5cccd78b4 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -197,7 +197,7 @@ public: virtual ~LLFloaterIMPanel(); void lookupName(); - static void onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name, void* data); + void onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name); /*virtual*/ BOOL postBuild(); diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 904a809c9..0b52174d9 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -1586,10 +1586,9 @@ void LLPanelAvatar::setOnlineStatus(EOnlineStatus online_status) } } -void LLPanelAvatar::on_avatar_name_response(const LLUUID& agent_id, const LLAvatarName& av_name, void *userdata){ - LLPanelAvatar* self = (LLPanelAvatar*)userdata; - LLLineEditor* dnname_edit = self->getChild("dnname"); - if(LLAvatarNameCache::useDisplayNames() && agent_id==self->mAvatarID) dnname_edit->setText(av_name.getCompleteName()); +void LLPanelAvatar::onAvatarNameResponse(const LLUUID& agent_id, const LLAvatarName& av_name){ + LLLineEditor* dnname_edit = getChild("dnname"); + if(LLAvatarNameCache::useDisplayNames() && agent_id==mAvatarID) dnname_edit->setText(av_name.getCompleteName()); } void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name, @@ -1664,7 +1663,7 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name } else{ dnname_edit->setText(name_edit->getText()); - LLAvatarNameCache::get(avatar_id, boost::bind(&LLPanelAvatar::on_avatar_name_response, _1, _2, this)); + LLAvatarNameCache::get(avatar_id, boost::bind(&LLPanelAvatar::onAvatarNameResponse, this, _1, _2)); } childSetVisible("dnname",TRUE); childSetVisible("name",FALSE); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 6d2c9441e..f564fe168 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -299,6 +299,8 @@ public: void setAvatar(LLViewerObject *avatarp); + void onAvatarNameResponse(const LLUUID& agent_id, const LLAvatarName& av_name); + // Fill in the avatar ID and handle some field fill-in, as well as // button enablement. // Pass one of the ONLINE_STATUS_foo constants above. @@ -350,7 +352,6 @@ private: static bool finishUnfreeze(const LLSD& notification, const LLSD& response); static void showProfileCallback(S32 option, void *userdata); - static void on_avatar_name_response(const LLUUID& agent_id, const LLAvatarName& av_name, void *userdata); static void* createPanelAvatar(void* data); static void* createFloaterAvatarInfo(void* data); static void* createPanelAvatarSecondLife(void* data); diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 2f44a34bc..c1c29be8d 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -49,7 +49,9 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -class LLPanelGroupInvite::impl +#include + +class LLPanelGroupInvite::impl : public boost::signals2::trackable { public: impl(const LLUUID& group_id); @@ -67,12 +69,10 @@ public: static void callbackClickAdd(void* userdata); static void callbackClickRemove(void* userdata); static void callbackSelect(LLUICtrl* ctrl, void* userdata); - static void callbackAddUsers(const uuid_vec_t& agent_ids, - void* user_data); + void callbackAddUsers(const uuid_vec_t& agent_idsa); - static void onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name, - void* user_data); + void onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name); bool inviteOwnerCallback(const LLSD& notification, const LLSD& response); @@ -307,7 +307,7 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata) //instead of being it's own separate floater. But that is next week. //This will do for now. -jwolk May 10, 2006 LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( - boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE); + boost::bind(&impl::callbackAddUsers, panelp->mImplementation, _1), TRUE); if (picker) { gFloaterView->getParentFloater(panelp)->addDependentFloater(picker); @@ -376,34 +376,25 @@ void LLPanelGroupInvite::impl::callbackClickOK(void* userdata) } - -//static -void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data) +void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids) { std::vector names; for (S32 i = 0; i < (S32)agent_ids.size(); i++) { LLAvatarNameCache::get(agent_ids[i], - boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data)); + boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, this, _1, _2)); } - } void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name, - void* user_data) + const LLAvatarName& av_name) { - impl* selfp = (impl*) user_data; - - if (selfp) - { - std::vector names; - uuid_vec_t agent_ids; - agent_ids.push_back(agent_id); - names.push_back(av_name.getCompleteName()); + std::vector names; + uuid_vec_t agent_ids; + agent_ids.push_back(agent_id); + names.push_back(av_name.getCompleteName()); - selfp->addUsers(names, agent_ids); - } + addUsers(names, agent_ids); } LLPanelGroupInvite::LLPanelGroupInvite(const std::string& name, diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e359a4c40..17d831dbf 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -191,7 +191,6 @@ extern AIHTTPTimeoutPolicy authHandler_timeout; // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) #include "llfloateravatarinfo.h" -extern LLMap< const LLUUID, LLFloaterAvatarInfo* > gAvatarInfoInstances; // Only defined in llfloateravatarinfo.cpp // [/RLVa:KB] // @@ -2690,7 +2689,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && - (RlvUtil::isNearbyAgent(from_id)) && (!gAvatarInfoInstances.checkData(from_id)); + (RlvUtil::isNearbyAgent(from_id)) && (!LLFloaterAvatarInfo::getInstance(from_id)); args["NAME"] = (!fRlvObfuscate) ? name : RlvStrings::getAnonym(name); // [/RLVa:KB] //args["NAME"] = name; @@ -2701,7 +2700,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && - (RlvUtil::isNearbyAgent(from_id)) && (!gAvatarInfoInstances.checkData(from_id)); + (RlvUtil::isNearbyAgent(from_id)) && (!LLFloaterAvatarInfo::getInstance(from_id)); args["NAME"] = (!fRlvObfuscate) ? name : RlvStrings::getAnonym(name); // [/RLVa:KB] //args["NAME"] = name; diff --git a/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml index cf1d22f2f..b18d5e3cf 100644 --- a/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml @@ -1,7 +1,29 @@ + + '[TEXT]' not found + + + No one near + + + No results + + + Searching... + + + Select + Close @@ -29,19 +51,23 @@ multi_select="false" name="SearchResults" width="115" /> - - Select a calling card: + Select a person: - + + multi_select="false" name="Friends" width="115" /> -