/** * @file llpanelgroup.cpp * * $LicenseInfo:firstyear=2006&license=viewergpl$ * * Copyright (c) 2006-2009, Linden Research, Inc. * * 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 * * 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 * * 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. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llpanelgroup.h" #include "llbutton.h" #include "lltabcontainer.h" #include "lltextbox.h" #include "llviewermessage.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" #include "llappviewer.h" #include "llnotifications.h" #include "llfloaterreg.h" #include "llfloater.h" #include "llagent.h" #include "llstatusbar.h" // can_afford_transaction() #include "llsidetraypanelcontainer.h" #include "llpanelgroupnotices.h" #include "llpanelgroupgeneral.h" #include "llsidetray.h" #include "llaccordionctrltab.h" #include "llaccordionctrl.h" static LLRegisterPanelClassWrapper t_panel_group("panel_group_info_sidetray"); LLPanelGroupTab::LLPanelGroupTab() : LLPanel(), mAllowEdit(TRUE), mHasModal(FALSE) { mGroupID = LLUUID::null; } LLPanelGroupTab::~LLPanelGroupTab() { } BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp) { //default to being visible return TRUE; } BOOL LLPanelGroupTab::postBuild() { return TRUE; } void LLPanelGroupTab::handleClickHelp() { // Display the help text. std::string help_text( getHelpText() ); if ( !help_text.empty() ) { LLSD args; args["MESSAGE"] = help_text; LLFloater* parent_floater = gFloaterView->getParentFloater(this); LLNotification::Params params(parent_floater->contextualNotification("GenericAlert")); params.substitutions(args); LLNotifications::instance().add(params); } } LLPanelGroup::LLPanelGroup() : LLPanel() ,LLGroupMgrObserver( LLUUID() ) ,mAllowEdit(TRUE) { // Set up the factory callbacks. // Roles sub tabs LLGroupMgr::getInstance()->addObserver(this); } LLPanelGroup::~LLPanelGroup() { LLGroupMgr::getInstance()->removeObserver(this); } void LLPanelGroup::onOpen(const LLSD& key) { if(!key.has("group_id")) return; LLUUID group_id = key["group_id"]; if(!key.has("action")) { setGroupID(group_id); return; } std::string str_action = key["action"]; if(str_action == "refresh") { if(mID == group_id || group_id == LLUUID::null) refreshData(); } else if(str_action == "close") { onBackBtnClick(); } else if(str_action == "create") { setGroupID(LLUUID::null); } else if(str_action == "refresh_notices") { LLPanelGroupNotices* panel_notices = findChild("group_notices_tab_panel"); if(panel_notices) panel_notices->refreshNotices(); } } BOOL LLPanelGroup::postBuild() { mDefaultNeedsApplyMesg = getString("default_needs_apply_text"); mWantApplyMesg = getString("want_apply_text"); LLButton* button; button = getChild("btn_apply"); button->setClickedCallback(onBtnApply, this); button->setVisible(true); button->setEnabled(false); button = getChild("btn_join"); button->setVisible(false); button->setEnabled(true); button = getChild("btn_cancel"); button->setVisible(false); button->setEnabled(true); button = getChild("btn_refresh"); button->setClickedCallback(onBtnRefresh, this); button->setVisible(mAllowEdit); getChild("btn_create")->setVisible(false); childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL); childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL); childSetCommitCallback("btn_join",boost::bind(&LLPanelGroup::onBtnJoin,this),NULL); childSetCommitCallback("btn_cancel",boost::bind(&LLPanelGroup::onBtnCancel,this),NULL); LLPanelGroupTab* panel_general = findChild("group_general_tab_panel"); LLPanelGroupTab* panel_roles = findChild("group_roles_tab_panel"); LLPanelGroupTab* panel_notices = findChild("group_notices_tab_panel"); LLPanelGroupTab* panel_land = findChild("group_land_tab_panel"); if(panel_general) mTabs.push_back(panel_general); if(panel_roles) mTabs.push_back(panel_roles); if(panel_notices) mTabs.push_back(panel_notices); if(panel_land) mTabs.push_back(panel_land); if(panel_general) panel_general->setupCtrls(this); return TRUE; } void LLPanelGroup::reposButton(const std::string& name) { LLButton* button = findChild(name); if(!button) return; LLRect btn_rect = button->getRect(); btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight()); button->setRect(btn_rect); } void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent ) { LLPanel::reshape(width, height, called_from_parent ); reposButton("btn_apply"); reposButton("btn_create"); reposButton("btn_refresh"); reposButton("btn_cancel"); } void LLPanelGroup::onBackBtnClick() { LLSideTrayPanelContainer* parent = dynamic_cast(getParent()); if(parent) { parent->openPreviousPanel(); } } void LLPanelGroup::onBtnCreate() { LLPanelGroupGeneral* panel_general = findChild("group_general_tab_panel"); if(!panel_general) return; std::string apply_mesg; if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create... return; if ( !apply_mesg.empty() ) { LLSD args; args["MESSAGE"] = apply_mesg; LLNotifications::instance().add("GenericAlert", args); } } void LLPanelGroup::onBtnRefresh(void* user_data) { LLPanelGroup* self = static_cast(user_data); self->refreshData(); } void LLPanelGroup::onBtnApply(void* user_data) { LLPanelGroup* self = static_cast(user_data); self->apply(); } void LLPanelGroup::onBtnJoin() { lldebugs << "joining group: " << mID << llendl; LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); if (gdatap) { S32 cost = gdatap->mMembershipFee; LLSD args; args["COST"] = llformat("%d", cost); LLSD payload; payload["group_id"] = mID; if (can_afford_transaction(cost)) { LLNotifications::instance().add("JoinGroupCanAfford", args, payload, LLPanelGroup::joinDlgCB); } else { LLNotifications::instance().add("JoinGroupCannotAfford", args, payload); } } else { llwarns << "LLGroupMgr::getInstance()->getGroupData(" << mID << ") was NULL" << llendl; } } bool LLPanelGroup::joinDlgCB(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); if (option == 1) { // user clicked cancel return false; } LLGroupMgr::getInstance()->sendGroupMemberJoin(notification["payload"]["group_id"].asUUID()); return false; } void LLPanelGroup::onBtnCancel() { onBackBtnClick(); } void LLPanelGroup::changed(LLGroupChange gc) { for(std::vector::iterator it = mTabs.begin();it!=mTabs.end();++it) (*it)->update(gc); update(gc); } void LLPanelGroup::notifyObservers() { changed(GC_ALL); } void LLPanelGroup::update(LLGroupChange gc) { LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); if(gdatap) { childSetValue("group_name", gdatap->mName); LLGroupData agent_gdatap; bool is_member = gAgent.getGroupData(mID,agent_gdatap); LLButton* btn_join = getChild("btn_join"); bool join_btn_visible = !is_member && gdatap->mOpenEnrollment; btn_join->setVisible(join_btn_visible); if(join_btn_visible) { LLStringUtil::format_map_t string_args; string_args["[AMOUNT]"] = llformat("%d", gdatap->mMembershipFee); std::string fee_buff = getString("group_join_btn", string_args); btn_join->setLabelSelected(fee_buff); btn_join->setLabelUnselected(fee_buff); } } } void LLPanelGroup::setGroupID(const LLUUID& group_id) { std::string str_group_id; group_id.toString(str_group_id); LLGroupMgr::getInstance()->removeObserver(this); mID = group_id; LLGroupMgr::getInstance()->addObserver(this); for(std::vector::iterator it = mTabs.begin();it!=mTabs.end();++it) (*it)->setGroupID(group_id); LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); if(gdatap) childSetValue("group_name", gdatap->mName); LLButton* button_apply = findChild("btn_apply"); LLButton* button_refresh = findChild("btn_refresh"); LLButton* button_create = findChild("btn_create"); LLButton* button_join = findChild("btn_join"); LLButton* button_cancel = findChild("btn_cancel"); bool is_null_group_id = group_id == LLUUID::null; if(button_apply) button_apply->setVisible(!is_null_group_id); if(button_refresh) button_refresh->setVisible(!is_null_group_id); if(button_create) button_create->setVisible(is_null_group_id); if(button_cancel) button_cancel->setVisible(!is_null_group_id); getChild("prepend_founded_by")->setVisible(!is_null_group_id); LLAccordionCtrl* tab_ctrl = findChild("group_accordion"); if(tab_ctrl) tab_ctrl->reset(); LLAccordionCtrlTab* tab_general = findChild("group_general_tab"); LLAccordionCtrlTab* tab_roles = findChild("group_roles_tab"); LLAccordionCtrlTab* tab_notices = findChild("group_notices_tab"); LLAccordionCtrlTab* tab_land = findChild("group_land_tab"); if(!tab_general || !tab_roles || !tab_notices || !tab_land) return; if(button_join) button_join->setVisible(false); if(is_null_group_id)//creating new group { if(!tab_general->getDisplayChildren()) tab_general->changeOpenClose(tab_general->getDisplayChildren()); if(tab_roles->getDisplayChildren()) tab_roles->changeOpenClose(tab_roles->getDisplayChildren()); if(tab_notices->getDisplayChildren()) tab_notices->changeOpenClose(tab_notices->getDisplayChildren()); if(tab_land->getDisplayChildren()) tab_land->changeOpenClose(tab_land->getDisplayChildren()); tab_roles->canOpenClose(false); tab_notices->canOpenClose(false); tab_land->canOpenClose(false); getChild("group_name")->setVisible(false); getChild("group_name_editor")->setVisible(true); } else { if(!tab_general->getDisplayChildren()) tab_general->changeOpenClose(tab_general->getDisplayChildren()); if(!tab_roles->getDisplayChildren()) tab_roles->changeOpenClose(tab_roles->getDisplayChildren()); if(!tab_notices->getDisplayChildren()) tab_notices->changeOpenClose(tab_notices->getDisplayChildren()); if(!tab_land->getDisplayChildren()) tab_land->changeOpenClose(tab_land->getDisplayChildren()); tab_roles->canOpenClose(true); tab_notices->canOpenClose(true); tab_land->canOpenClose(true); getChild("group_name")->setVisible(true); getChild("group_name_editor")->setVisible(false); } } bool LLPanelGroup::apply(LLPanelGroupTab* tab) { if(!tab) return false; std::string mesg; if ( !tab->needsApply(mesg) ) return true; std::string apply_mesg; if(tab->apply( apply_mesg ) ) return true; if ( !apply_mesg.empty() ) { LLSD args; args["MESSAGE"] = apply_mesg; LLNotifications::instance().add("GenericAlert", args); } return false; } bool LLPanelGroup::apply() { return apply(findChild("group_general_tab_panel")) && apply(findChild("group_roles_tab_panel")) && apply(findChild("group_notices_tab_panel")) && apply(findChild("group_land_tab_panel")) ; } // virtual void LLPanelGroup::draw() { LLPanel::draw(); if (mRefreshTimer.hasExpired()) { mRefreshTimer.stop(); childEnable("btn_refresh"); } bool enable = false; std::string mesg; for(std::vector::iterator it = mTabs.begin();it!=mTabs.end();++it) enable = enable || (*it)->needsApply(mesg); childSetEnabled("btn_apply", enable); } void LLPanelGroup::refreshData() { LLGroupMgr::getInstance()->clearGroupData(getID()); setGroupID(getID()); // 5 second timeout childDisable("btn_refresh"); mRefreshTimer.start(); mRefreshTimer.setTimerExpirySec(5); } void LLPanelGroup::showNotice(const std::string& subject, const std::string& message, const bool& has_inventory, const std::string& inventory_name, LLOfferInfo* inventory_offer) { LLPanelGroupNotices* panel_notices = findChild("group_notices_tab_panel"); if(!panel_notices) { // We need to clean up that inventory offer. if (inventory_offer) { inventory_offer->forceResponse(IOR_DECLINE); } return; } panel_notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer); } //static void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id) { LLPanelGroup* panel = LLSideTray::getInstance()->findChild("panel_group_info_sidetray"); if(!panel) return; panel->setGroupID(group_id); } //static void LLPanelGroup::showNotice(const std::string& subject, const std::string& message, const LLUUID& group_id, const bool& has_inventory, const std::string& inventory_name, LLOfferInfo* inventory_offer) { LLPanelGroup* panel = LLSideTray::getInstance()->findChild("panel_group_info_sidetray"); if(!panel) return; if(panel->getID() != group_id)//???? only for current group_id or switch panels? FIXME return; panel->showNotice(subject,message,has_inventory,inventory_name,inventory_offer); }