/** * @file llfloatergroups.cpp * @brief LLFloaterGroups class implementation * * Copyright (c) 2002-2007, Linden Research, Inc. * * 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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. */ /* * Shown from Edit -> Groups... * Shows the agent's groups and allows the edit window to be invoked. * Also overloaded to allow picking of a single group for assigning * objects and land to groups. */ #include "llviewerprecompiledheaders.h" #include "llfloatergroups.h" #include "message.h" #include "llagent.h" #include "llbutton.h" #include "llfloatergroupinfo.h" #include "llfloaterdirectory.h" #include "llfocusmgr.h" #include "llalertdialog.h" #include "llselectmgr.h" #include "llscrolllistctrl.h" #include "lltextbox.h" #include "llvieweruictrlfactory.h" #include "llviewerwindow.h" const LLRect FLOATER_RECT(0, 258, 280, 0); const char FLOATER_TITLE[] = "Groups"; // static LLMap LLFloaterGroups::sInstances; ///---------------------------------------------------------------------------- /// Class LLFloaterGroups ///---------------------------------------------------------------------------- //LLEventListener //virtual bool LLFloaterGroups::handleEvent(LLPointer event, const LLSD& userdata) { if (event->desc() == "new group") { reset(); return true; } return LLView::handleEvent(event, userdata); } // Call this with an agent id and AGENT_GROUPS for an agent's // groups, otherwise, call with an object id and SET_OBJECT_GROUP // when modifying an object. // static LLFloaterGroups* LLFloaterGroups::show(const LLUUID& id, EGroupDialog type) { LLFloaterGroups* instance = NULL; if(sInstances.checkData(id)) { instance = sInstances.getData(id); if (instance->getType() != type) { // not the type we want ==> destroy it and rebuild below instance->destroy(); instance = NULL; } else { // Move the existing view to the front instance->open(); /* Flawfinder: ignore */ } } if (!instance) { S32 left = 0; S32 top = 0; LLRect rect = FLOATER_RECT; rect.translate( left - rect.mLeft, top - rect.mTop ); instance = new LLFloaterGroups("groups", rect, FLOATER_TITLE, id); if(instance) { sInstances.addData(id, instance); //instance->init(type); instance->mType = type; switch (type) { case AGENT_GROUPS: gUICtrlFactory->buildFloater(instance, "floater_groups.xml"); break; case CHOOSE_ONE: gUICtrlFactory->buildFloater(instance, "floater_choose_group.xml"); break; } instance->center(); instance->open(); /*Flawfinder: ignore*/ } } return instance; } // static LLFloaterGroups* LLFloaterGroups::getInstance(const LLUUID& id) { if(sInstances.checkData(id)) { return sInstances.getData(id); } return NULL; } // Default constructor LLFloaterGroups::LLFloaterGroups(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& id) : LLFloater(name, rect, title), mID(id), mType(AGENT_GROUPS), mOKCallback(NULL), mCallbackUserdata(NULL) { } // Destroys the object LLFloaterGroups::~LLFloaterGroups() { gFocusMgr.releaseFocusIfNeeded( this ); sInstances.removeData(mID); } // clear the group list, and get a fresh set of info. void LLFloaterGroups::reset() { LLCtrlListInterface *group_list = childGetListInterface("group list"); if (group_list) { group_list->operateOnAll(LLCtrlListInterface::OP_DELETE); } childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS)); initAgentGroups(gAgent.getGroupID()); enableButtons(); } void LLFloaterGroups::setOkCallback(void (*callback)(LLUUID, void*), void* userdata) { mOKCallback = callback; mCallbackUserdata = userdata; } BOOL LLFloaterGroups::postBuild() { childSetCommitCallback("group list", onGroupList, this); if(mType == AGENT_GROUPS) { childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS)); initAgentGroups(gAgent.getGroupID()); childSetAction("Activate", onBtnActivate, this); childSetAction("Info", onBtnInfo, this); childSetAction("Leave", onBtnLeave, this); childSetAction("Create", onBtnCreate, this); childSetAction("Search...", onBtnSearch, this); childSetAction("Close", onBtnCancel, this); setDefaultBtn("Info"); childSetDoubleClickCallback("group list", onBtnInfo); childSetUserData("group list", this); } else { initAgentGroups(gAgent.getGroupID()); childSetAction("OK", onBtnOK, this); childSetAction("Cancel", onBtnCancel, this); setDefaultBtn("OK"); childSetDoubleClickCallback("group list", onBtnOK); childSetUserData("group list", this); } enableButtons(); return TRUE; } void LLFloaterGroups::initAgentGroups(const LLUUID& highlight_id) { S32 count = gAgent.mGroups.count(); LLUUID id; LLCtrlListInterface *group_list = childGetListInterface("group list"); if (!group_list) return; group_list->operateOnAll(LLCtrlListInterface::OP_DELETE); for(S32 i = 0; i < count; ++i) { id = gAgent.mGroups.get(i).mID; LLGroupData* group_datap = &gAgent.mGroups.get(i); LLString style = "NORMAL"; if(highlight_id == id) { style = "BOLD"; } LLSD element; element["id"] = id; element["columns"][0]["column"] = "name"; element["columns"][0]["value"] = group_datap->mName; element["columns"][0]["font"] = "SANSSERIF"; element["columns"][0]["font-style"] = style; group_list->addElement(element, ADD_SORTED); } { LLString style = "NORMAL"; if (highlight_id.isNull()) { style = "BOLD"; } LLSD element; element["id"] = LLUUID::null; element["columns"][0]["column"] = "name"; element["columns"][0]["value"] = "none"; element["columns"][0]["font"] = "SANSSERIF"; element["columns"][0]["font-style"] = style; group_list->addElement(element, ADD_TOP); } group_list->selectByValue(highlight_id); childSetFocus("group list"); } void LLFloaterGroups::enableButtons() { LLCtrlListInterface *group_list = childGetListInterface("group list"); LLUUID group_id; if (group_list) { group_id = group_list->getCurrentID(); } if(mType == AGENT_GROUPS) { if(group_id != gAgent.getGroupID()) { childEnable("Activate"); } else { childDisable("Activate"); } if (group_id.notNull()) { childEnable("Info"); childEnable("Leave"); } else { childDisable("Info"); childDisable("Leave"); } if(gAgent.mGroups.count() < MAX_AGENT_GROUPS) { childEnable("Create"); } else { childDisable("Create"); } } else { childEnable("OK"); } } void LLFloaterGroups::onBtnCreate(void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->create(); } void LLFloaterGroups::onBtnActivate(void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->activate(); } void LLFloaterGroups::onBtnInfo(void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->info(); } void LLFloaterGroups::onBtnLeave(void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->leave(); } void LLFloaterGroups::onBtnSearch(void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->search(); } void LLFloaterGroups::onBtnOK(void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->ok(); } void LLFloaterGroups::onBtnCancel(void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->close(); } void LLFloaterGroups::onGroupList(LLUICtrl* ctrl, void* userdata) { LLFloaterGroups* self = (LLFloaterGroups*)userdata; if(self) self->highlightGroupList(ctrl); } void LLFloaterGroups::create() { llinfos << "LLFloaterGroups::create" << llendl; LLFloaterGroupInfo::showCreateGroup(NULL); } void LLFloaterGroups::activate() { llinfos << "LLFloaterGroups::activate" << llendl; LLCtrlListInterface *group_list = childGetListInterface("group list"); LLUUID group_id; if (group_list) { group_id = group_list->getCurrentID(); } LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ActivateGroup); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->addUUIDFast(_PREHASH_GroupID, group_id); gAgent.sendReliableMessage(); } void LLFloaterGroups::info() { llinfos << "LLFloaterGroups::info" << llendl; LLCtrlListInterface *group_list = childGetListInterface("group list"); LLUUID group_id; if (group_list && (group_id = group_list->getCurrentID()).notNull()) { LLFloaterGroupInfo::showFromUUID(group_id); } } void LLFloaterGroups::leave() { llinfos << "LLFloaterGroups::leave" << llendl; LLCtrlListInterface *group_list = childGetListInterface("group list"); LLUUID group_id; if (group_list && (group_id = group_list->getCurrentID()).notNull()) { S32 count = gAgent.mGroups.count(); S32 i; for(i = 0; i < count; ++i) { if(gAgent.mGroups.get(i).mID == group_id) break; } if(i < count) { LLUUID* cb_data = new LLUUID((const LLUUID&)group_id); LLString::format_map_t args; args["[GROUP]"] = gAgent.mGroups.get(i).mName; gViewerWindow->alertXml("GroupLeaveConfirmMember", args, callbackLeaveGroup, (void*)cb_data); } } } void LLFloaterGroups::search() { LLFloaterDirectory::showGroups(); } // static void LLFloaterGroups::callbackLeaveGroup(S32 option, void* userdata) { LLUUID* group_id = (LLUUID*)userdata; if(option == 0 && group_id) { LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_LeaveGroupRequest); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_GroupData); msg->addUUIDFast(_PREHASH_GroupID, *group_id); gAgent.sendReliableMessage(); } delete group_id; } void LLFloaterGroups::ok() { llinfos << "LLFloaterGroups::ok" << llendl; LLCtrlListInterface *group_list = childGetListInterface("group list"); LLUUID group_id; if (group_list) { group_id = group_list->getCurrentID(); } if(mOKCallback) { mOKCallback(group_id, mCallbackUserdata); } close(); } void LLFloaterGroups::highlightGroupList(LLUICtrl*) { llinfos << "LLFloaterGroups::highlightGroupList" << llendl; enableButtons(); }