/** * @file llfloaterexperiences.cpp * @brief LLFloaterExperiences class implementation * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2012, Linden Research, Inc. * * 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. * * 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. * * 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$ */ #include "llviewerprecompiledheaders.h" #include "llfloaterexperiences.h" #include "llagent.h" #include "llevents.h" #include "llexperiencecache.h" #include "llfloaterregioninfo.h" #include "llhttpclient.h" #include "llnotificationsutil.h" #include "llpanelexperiencelog.h" #include "llpanelexperiencepicker.h" #include "llpanelexperiences.h" #include "lltabcontainer.h" #include "lltrans.h" #include "llviewerregion.h" #define SHOW_RECENT_TAB (0) class LLExperienceListResponder : public LLHTTPClient::Responder { public: typedef std::map NameMap; typedef boost::function Callback; LLExperienceListResponder(const LLHandle& parent, NameMap& nameMap, const std::string& errorMessage="ErrorMessage"):mParent(parent),mErrorMessage(errorMessage) { mNameMap.swap(nameMap); } Callback mCallback; LLHandle mParent; NameMap mNameMap; const std::string mErrorMessage; virtual void result(const LLSD& content) { if(mParent.isDead()) return; LLFloaterExperiences* parent=mParent.get(); LLTabContainer* tabs = parent->getChild("xp_tabs"); NameMap::iterator it = mNameMap.begin(); while(it != mNameMap.end()) { if(content.has(it->first)) { LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName(it->second); if(tab) { const LLSD& ids = content[it->first]; tab->setExperienceList(ids); if(!mCallback.empty()) { mCallback(tab, content); } } } ++it; } } virtual void error(U32 status, const std::string& reason) { LLSD subs; subs["ERROR_MESSAGE"] = reason; LLNotificationsUtil::add(mErrorMessage, subs); } }; LLFloaterExperiences::LLFloaterExperiences(const LLSD& data) :LLFloater(data) { } LLPanelExperiences* LLFloaterExperiences::addTab(const std::string& name, bool select) { LLPanelExperiences* newPanel = LLPanelExperiences::create(name); getChild("xp_tabs")->addTabPanel(LLTabContainer::TabPanelParams(). panel(newPanel). label(LLTrans::getString(name)). select_tab(select)); return newPanel; } BOOL LLFloaterExperiences::postBuild() { getChild("xp_tabs")->addTabPanel(new LLPanelExperiencePicker()); addTab("Allowed_Experiences_Tab", true); addTab("Blocked_Experiences_Tab", false); addTab("Admin_Experiences_Tab", false); addTab("Contrib_Experiences_Tab", false); LLPanelExperiences* owned = addTab("Owned_Experiences_Tab", false); owned->setButtonAction("acquire", boost::bind(&LLFloaterExperiences::sendPurchaseRequest, this)); owned->enableButton(false); #if SHOW_RECENT_TAB addTab("Recent_Experiences_Tab", false); #endif //SHOW_RECENT_TAB getChild("xp_tabs")->addTabPanel(new LLPanelExperienceLog()); resizeToTabs(); LLEventPumps::instance().obtain("experience_permission").listen("LLFloaterExperiences", boost::bind(&LLFloaterExperiences::updatePermissions, this, _1)); return TRUE; } void LLFloaterExperiences::clearFromRecent(const LLSD& ids) { #if SHOW_RECENT_TAB LLTabContainer* tabs = getChild("xp_tabs"); LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName("Recent_Experiences_Tab"); if(!tab) return; tab->removeExperiences(ids); #endif // SHOW_RECENT_TAB } void LLFloaterExperiences::setupRecentTabs() { #if SHOW_RECENT_TAB LLTabContainer* tabs = getChild("xp_tabs"); LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName("Recent_Experiences_Tab"); if(!tab) return; LLSD recent; const LLExperienceCache::cache_t& experiences = LLExperienceCache::getCached(); LLExperienceCache::cache_t::const_iterator it = experiences.begin(); while( it != experiences.end() ) { if(!it->second.has(LLExperienceCache::MISSING)) { recent.append(it->first); } ++it; } tab->setExperienceList(recent); #endif // SHOW_RECENT_TAB } void LLFloaterExperiences::resizeToTabs() { const S32 TAB_WIDTH_PADDING = 16; LLTabContainer* tabs = getChild("xp_tabs"); LLRect rect = getRect(); if(rect.getWidth() < tabs->getTotalTabWidth() + TAB_WIDTH_PADDING) { rect.mRight = rect.mLeft + tabs->getTotalTabWidth() + TAB_WIDTH_PADDING; } reshape(rect.getWidth(), rect.getHeight(), FALSE); } void LLFloaterExperiences::refreshContents() { setupRecentTabs(); LLViewerRegion* region = gAgent.getRegion(); if (region) { LLExperienceListResponder::NameMap nameMap; std::string lookup_url=region->getCapability("GetExperiences"); if(!lookup_url.empty()) { nameMap["experiences"]="Allowed_Experiences_Tab"; nameMap["blocked"]="Blocked_Experiences_Tab"; LLHTTPClient::get(lookup_url, new LLExperienceListResponder(getDerivedHandle(), nameMap)); } lookup_url = region->getCapability("GetAdminExperiences"); if(!lookup_url.empty()) { nameMap["experience_ids"]="Admin_Experiences_Tab"; LLHTTPClient::get(lookup_url, new LLExperienceListResponder(getDerivedHandle(), nameMap)); } lookup_url = region->getCapability("GetCreatorExperiences"); if(!lookup_url.empty()) { nameMap["experience_ids"]="Contrib_Experiences_Tab"; LLHTTPClient::get(lookup_url, new LLExperienceListResponder(getDerivedHandle(), nameMap)); } lookup_url = region->getCapability("AgentExperiences"); if(!lookup_url.empty()) { nameMap["experience_ids"]="Owned_Experiences_Tab"; LLHTTPClient::get(lookup_url, new LLExperienceListResponder(getDerivedHandle(), nameMap)); } } } void LLFloaterExperiences::onOpen( const LLSD& key ) { LLViewerRegion* region = gAgent.getRegion(); if(region) { if(region->capabilitiesReceived()) { refreshContents(); return; } region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterExperiences::refreshContents, this)); return; } } bool LLFloaterExperiences::updatePermissions( const LLSD& permission ) { LLTabContainer* tabs = getChild("xp_tabs"); LLUUID experience; std::string permission_string; if(permission.has("experience")) { experience = permission["experience"].asUUID(); permission_string = permission[experience.asString()]["permission"].asString(); } LLPanelExperiences* tab = (LLPanelExperiences*)tabs->getPanelByName("Allowed_Experiences_Tab"); if(tab) { if(permission.has("experiences")) { tab->setExperienceList(permission["experiences"]); } else if(experience.notNull()) { if(permission_string != "Allow") { tab->removeExperience(experience); } else { tab->addExperience(experience); } } } tab = (LLPanelExperiences*)tabs->getPanelByName("Blocked_Experiences_Tab"); if(tab) { if(permission.has("blocked")) { tab->setExperienceList(permission["blocked"]); } else if(experience.notNull()) { if(permission_string != "Block") { tab->removeExperience(experience); } else { tab->addExperience(experience); } } } return false; } void LLFloaterExperiences::onClose( bool app_quitting ) { LLEventPumps::instance().obtain("experience_permission").stopListening("LLFloaterExperiences"); LLFloater::onClose(app_quitting); } void LLFloaterExperiences::checkPurchaseInfo(LLPanelExperiences* panel, const LLSD& content) const { panel->enableButton(content.has("purchase")); } void LLFloaterExperiences::sendPurchaseRequest() const { LLViewerRegion* region = gAgent.getRegion(); std::string url = region->getCapability("AgentExperiences"); if(!url.empty()) { LLSD content; LLExperienceListResponder::NameMap nameMap; nameMap["experience_ids"]="Owned_Experiences_Tab"; LLExperienceListResponder* responder = new LLExperienceListResponder(getDerivedHandle(), nameMap, "ExperienceAcquireFailed"); responder->mCallback = boost::bind(&LLFloaterExperiences::checkPurchaseInfo, this, _1, _2); LLHTTPClient::post(url, content, responder); } }