Replace MAX_AGENT_ATTACHMENTS with sim based response Replace max groups with benefits based response Upload costs are now handled by sim response Removed no-longer-needed lleconomy files and classes Removed dead fields from hippolimits and hippogridmanager Also removed lame LL code that is redundant and silly On non SL grids, when values are not provided for benefits, they will be set to the values granting maximum liberty. Old standardized responses still work when benefits aren't implemented.
936 lines
25 KiB
C++
936 lines
25 KiB
C++
/**
|
|
* @file llpanelgroupgeneral.cpp
|
|
* @brief General information about a group.
|
|
*
|
|
* $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 "llpanelgroupgeneral.h"
|
|
|
|
#include "llagent.h"
|
|
#include "llagentbenefits.h"
|
|
#include "lluictrlfactory.h"
|
|
#include "roles_constants.h"
|
|
|
|
// UI elements
|
|
#include "llbutton.h"
|
|
#include "llcheckboxctrl.h"
|
|
#include "llcombobox.h"
|
|
#include "lldbstrings.h"
|
|
#include "llgroupactions.h"
|
|
#include "llimview.h"
|
|
#include "lllineeditor.h"
|
|
#include "llnamebox.h"
|
|
#include "llnamelistctrl.h"
|
|
#include "llnameeditor.h"
|
|
#include "llnotificationsutil.h"
|
|
#include "llspinctrl.h"
|
|
#include "llstatusbar.h" // can_afford_transaction()
|
|
#include "lltextbox.h"
|
|
#include "lltexteditor.h"
|
|
#include "lltexturectrl.h"
|
|
#include "lltrans.h"
|
|
#include "llviewerwindow.h"
|
|
|
|
#include "hippogridmanager.h"
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
// consts
|
|
const S32 MATURE_CONTENT = 1;
|
|
const S32 NON_MATURE_CONTENT = 2;
|
|
const S32 DECLINE_TO_STATE = 0;
|
|
|
|
// static
|
|
void* LLPanelGroupGeneral::createTab(void* data)
|
|
{
|
|
LLUUID* group_id = static_cast<LLUUID*>(data);
|
|
return new LLPanelGroupGeneral("panel group general", *group_id);
|
|
}
|
|
|
|
|
|
LLPanelGroupGeneral::LLPanelGroupGeneral(const std::string& name,
|
|
const LLUUID& group_id)
|
|
: LLPanelGroupTab(name, group_id),
|
|
mPendingMemberUpdate(FALSE),
|
|
mChanged(FALSE),
|
|
mFirstUse(TRUE),
|
|
mGroupNameEditor(NULL),
|
|
mFounderName(NULL),
|
|
mInsignia(NULL),
|
|
mEditCharter(NULL),
|
|
mBtnJoinGroup(NULL),
|
|
mListVisibleMembers(NULL),
|
|
mCtrlShowInGroupList(NULL),
|
|
mComboMature(NULL),
|
|
mCtrlOpenEnrollment(NULL),
|
|
mCtrlEnrollmentFee(NULL),
|
|
mSpinEnrollmentFee(NULL),
|
|
mCtrlReceiveNotices(NULL),
|
|
mCtrlReceiveChat(NULL),
|
|
mCtrlListGroup(NULL),
|
|
mActiveTitleLabel(NULL),
|
|
mComboActiveTitle(NULL)
|
|
{
|
|
|
|
}
|
|
|
|
LLPanelGroupGeneral::~LLPanelGroupGeneral()
|
|
{
|
|
for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
|
|
{
|
|
if (it->second.connected())
|
|
{
|
|
it->second.disconnect();
|
|
}
|
|
}
|
|
mAvatarNameCacheConnections.clear();
|
|
}
|
|
|
|
BOOL LLPanelGroupGeneral::postBuild()
|
|
{
|
|
LL_INFOS() << "LLPanelGroupGeneral::postBuild()" << LL_ENDL;
|
|
|
|
bool recurse = true;
|
|
|
|
// General info
|
|
mGroupNameEditor = getChild<LLLineEditor>("group_name_editor", recurse);
|
|
|
|
mInsignia = getChild<LLTextureCtrl>("insignia", recurse);
|
|
if (mInsignia)
|
|
{
|
|
mInsignia->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this));
|
|
mDefaultIconID = mInsignia->getImageAssetID();
|
|
void show_picture(const LLUUID& id, const std::string& name);
|
|
auto show_pic = [this] { show_picture(mInsignia->getImageAssetID(), "Group Insignia"); };
|
|
auto show_pic_if_not_self = [=] { if (!mInsignia->canChange()) show_pic(); };
|
|
mInsignia->setMouseUpCallback(std::bind(show_pic_if_not_self));
|
|
getChild<LLUICtrl>("bigimg")->setCommitCallback(std::bind(show_pic));
|
|
}
|
|
|
|
mEditCharter = getChild<LLTextEditor>("charter", recurse);
|
|
if(mEditCharter)
|
|
{
|
|
mEditCharter->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this));
|
|
mEditCharter->setFocusReceivedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this));
|
|
mEditCharter->setFocusChangedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this));
|
|
}
|
|
|
|
mBtnJoinGroup = getChild<LLButton>("join_button", recurse);
|
|
if ( mBtnJoinGroup )
|
|
{
|
|
mBtnJoinGroup->setClickedCallback(boost::bind(LLGroupActions::join, mGroupID));
|
|
}
|
|
|
|
mBtnInfo = getChild<LLButton>("info_button", recurse);
|
|
if ( mBtnInfo )
|
|
{
|
|
mBtnInfo->setClickedCallback(boost::bind(LLGroupActions::show, mGroupID));
|
|
}
|
|
|
|
mFounderName = getChild<LLNameBox>("founder_name");
|
|
|
|
mListVisibleMembers = getChild<LLNameListCtrl>("visible_members", recurse);
|
|
|
|
// Options
|
|
mCtrlShowInGroupList = getChild<LLCheckBoxCtrl>("show_in_group_list", recurse);
|
|
if (mCtrlShowInGroupList)
|
|
{
|
|
mCtrlShowInGroupList->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this));
|
|
}
|
|
|
|
mComboMature = getChild<LLComboBox>("group_mature_check", recurse);
|
|
if(mComboMature)
|
|
{
|
|
mComboMature->setCurrentByIndex(0);
|
|
mComboMature->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this));
|
|
if (gAgent.isTeen())
|
|
{
|
|
// Teens don't get to set mature flag. JC
|
|
mComboMature->setVisible(FALSE);
|
|
mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
|
|
}
|
|
}
|
|
mCtrlOpenEnrollment = getChild<LLCheckBoxCtrl>("open_enrollement", recurse);
|
|
if (mCtrlOpenEnrollment)
|
|
{
|
|
mCtrlOpenEnrollment->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this));
|
|
}
|
|
|
|
auto& grid = *gHippoGridManager->getConnectedGrid();
|
|
mCtrlEnrollmentFee = getChild<LLCheckBoxCtrl>("check_enrollment_fee", recurse);
|
|
if (mCtrlEnrollmentFee)
|
|
{
|
|
mCtrlEnrollmentFee->setLabelArg("[CURRENCY]", grid.getCurrencySymbol());
|
|
mCtrlEnrollmentFee->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitEnrollment,this));
|
|
}
|
|
|
|
mSpinEnrollmentFee = getChild<LLSpinCtrl>("spin_enrollment_fee", recurse);
|
|
if (mSpinEnrollmentFee)
|
|
{
|
|
mSpinEnrollmentFee->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitAny,this));
|
|
mSpinEnrollmentFee->setPrecision(0);
|
|
mSpinEnrollmentFee->resetDirty();
|
|
}
|
|
|
|
BOOL accept_notices = FALSE;
|
|
BOOL list_in_profile = FALSE;
|
|
LLGroupData data;
|
|
if(gAgent.getGroupData(mGroupID,data))
|
|
{
|
|
accept_notices = data.mAcceptNotices;
|
|
list_in_profile = data.mListInProfile;
|
|
}
|
|
mCtrlReceiveNotices = getChild<LLCheckBoxCtrl>("receive_notices", recurse);
|
|
if (mCtrlReceiveNotices)
|
|
{
|
|
mCtrlReceiveNotices->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this));
|
|
mCtrlReceiveNotices->set(accept_notices);
|
|
mCtrlReceiveNotices->setEnabled(data.mID.notNull());
|
|
mCtrlReceiveNotices->resetDirty();
|
|
}
|
|
|
|
mCtrlReceiveChat = getChild<LLCheckBoxCtrl>("receive_chat", recurse);
|
|
if (mCtrlReceiveChat)
|
|
{
|
|
mCtrlReceiveChat->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this));
|
|
mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID));
|
|
mCtrlReceiveChat->setEnabled(mGroupID.notNull());
|
|
mCtrlReceiveChat->resetDirty();
|
|
}
|
|
|
|
mCtrlListGroup = getChild<LLCheckBoxCtrl>("list_groups_in_profile", recurse);
|
|
if (mCtrlListGroup)
|
|
{
|
|
mCtrlListGroup->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitUserOnly,this));
|
|
mCtrlListGroup->set(list_in_profile);
|
|
mCtrlListGroup->setEnabled(data.mID.notNull());
|
|
mCtrlListGroup->resetDirty();
|
|
}
|
|
|
|
mActiveTitleLabel = getChild<LLTextBox>("active_title_label", recurse);
|
|
|
|
mComboActiveTitle = getChild<LLComboBox>("active_title", recurse);
|
|
if (mComboActiveTitle)
|
|
{
|
|
mComboActiveTitle->setCommitCallback(boost::bind(&LLPanelGroupGeneral::onCommitTitle,this));
|
|
mComboActiveTitle->resetDirty();
|
|
}
|
|
|
|
LLStringUtil::format_map_t args;
|
|
args["[GROUPCREATEFEE]"] = grid.formatFee(LLAgentBenefitsMgr::current().getCreateGroupCost());
|
|
mIncompleteMemberDataStr = getString("incomplete_member_data_str");
|
|
mConfirmGroupCreateStr = getString("confirm_group_create_str", args);
|
|
|
|
// If the group_id is null, then we are creating a new group
|
|
if (mGroupID.isNull())
|
|
{
|
|
mGroupNameEditor->setEnabled(TRUE);
|
|
getChildView("copy_uri")->setVisible(false); // New group has no uri
|
|
mEditCharter->setEnabled(TRUE);
|
|
|
|
mCtrlShowInGroupList->setEnabled(TRUE);
|
|
mComboMature->setEnabled(TRUE);
|
|
mCtrlOpenEnrollment->setEnabled(TRUE);
|
|
mCtrlEnrollmentFee->setEnabled(TRUE);
|
|
mSpinEnrollmentFee->setEnabled(TRUE);
|
|
|
|
mBtnJoinGroup->setVisible(FALSE);
|
|
mBtnInfo->setVisible(FALSE);
|
|
getChildView("group_name")->setVisible(FALSE);
|
|
}
|
|
|
|
std::string member_count(LLTrans::getString("LoadingData"));
|
|
if (LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID))
|
|
member_count = boost::lexical_cast<std::string>(gdatap->mMembers.size());
|
|
getChild<LLUICtrl>("text_owners_and_visible_members")->setTextArg("[COUNT]", member_count);
|
|
|
|
return LLPanelGroupTab::postBuild();
|
|
}
|
|
|
|
void LLPanelGroupGeneral::onFocusEdit()
|
|
{
|
|
updateChanged();
|
|
notifyObservers();
|
|
}
|
|
|
|
void LLPanelGroupGeneral::onCommitAny()
|
|
{
|
|
updateChanged();
|
|
notifyObservers();
|
|
}
|
|
|
|
// static
|
|
void LLPanelGroupGeneral::onCommitUserOnly()
|
|
{
|
|
mChanged = TRUE;
|
|
notifyObservers();
|
|
}
|
|
|
|
|
|
void LLPanelGroupGeneral::onCommitEnrollment()
|
|
{
|
|
onCommitAny();
|
|
|
|
// Make sure both enrollment related widgets are there.
|
|
if (!mCtrlEnrollmentFee || !mSpinEnrollmentFee)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Make sure the agent can change enrollment info.
|
|
if (!gAgent.hasPowerInGroup(mGroupID,GP_MEMBER_OPTIONS))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mCtrlEnrollmentFee->get())
|
|
{
|
|
mSpinEnrollmentFee->setEnabled(TRUE);
|
|
}
|
|
else
|
|
{
|
|
mSpinEnrollmentFee->setEnabled(FALSE);
|
|
mSpinEnrollmentFee->set(0);
|
|
}
|
|
}
|
|
|
|
void LLPanelGroupGeneral::onCommitTitle()
|
|
{
|
|
if (mGroupID.isNull()) return;
|
|
LLGroupMgr::getInstance()->sendGroupTitleUpdate(mGroupID,mComboActiveTitle->getCurrentID());
|
|
update(GC_TITLES);
|
|
mComboActiveTitle->resetDirty();
|
|
}
|
|
|
|
bool LLPanelGroupGeneral::needsApply(std::string& mesg)
|
|
{
|
|
updateChanged();
|
|
mesg = getString("group_info_unchanged");
|
|
return mChanged || mGroupID.isNull();
|
|
}
|
|
|
|
void LLPanelGroupGeneral::activate()
|
|
{
|
|
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
|
if (mGroupID.notNull()
|
|
&& (!gdatap || mFirstUse))
|
|
{
|
|
LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
|
|
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
|
|
|
|
if (!gdatap || !gdatap->isMemberDataComplete() )
|
|
{
|
|
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
|
}
|
|
|
|
mFirstUse = FALSE;
|
|
}
|
|
mChanged = FALSE;
|
|
|
|
update(GC_ALL);
|
|
}
|
|
|
|
void LLPanelGroupGeneral::draw()
|
|
{
|
|
LLPanelGroupTab::draw();
|
|
|
|
if (mPendingMemberUpdate)
|
|
{
|
|
updateMembers();
|
|
}
|
|
}
|
|
|
|
bool LLPanelGroupGeneral::apply(std::string& mesg)
|
|
{
|
|
BOOL has_power_in_group = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);
|
|
|
|
if (has_power_in_group || mGroupID.isNull())
|
|
{
|
|
LL_INFOS() << "LLPanelGroupGeneral::apply" << LL_ENDL;
|
|
|
|
// Check to make sure mature has been set
|
|
if(mComboMature &&
|
|
mComboMature->getCurrentIndex() == DECLINE_TO_STATE)
|
|
{
|
|
LLNotificationsUtil::add("SetGroupMature", LLSD(), LLSD(),
|
|
boost::bind(&LLPanelGroupGeneral::confirmMatureApply, this, _1, _2));
|
|
return false;
|
|
}
|
|
|
|
if (mGroupID.isNull())
|
|
{
|
|
// Validate the group name length.
|
|
S32 group_name_len = mGroupNameEditor->getText().size();
|
|
if ( group_name_len < DB_GROUP_NAME_MIN_LEN
|
|
|| group_name_len > DB_GROUP_NAME_STR_LEN)
|
|
{
|
|
std::ostringstream temp_error;
|
|
temp_error << "A group name must be between " << DB_GROUP_NAME_MIN_LEN
|
|
<< " and " << DB_GROUP_NAME_STR_LEN << " characters.";
|
|
mesg = temp_error.str();
|
|
return false;
|
|
}
|
|
|
|
LLSD args;
|
|
args["MESSAGE"] = mConfirmGroupCreateStr;
|
|
LLNotificationsUtil::add("GenericAlertYesCancel", args, LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2));
|
|
|
|
return false;
|
|
}
|
|
|
|
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
|
if (!gdatap)
|
|
{
|
|
mesg = LLTrans::getString("NoGroupDataFound");
|
|
mesg.append(mGroupID.asString());
|
|
return false;
|
|
}
|
|
bool can_change_ident = false;
|
|
bool can_change_member_opts = false;
|
|
can_change_ident = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);
|
|
can_change_member_opts = gAgent.hasPowerInGroup(mGroupID,GP_MEMBER_OPTIONS);
|
|
|
|
if (can_change_ident)
|
|
{
|
|
if (mEditCharter) gdatap->mCharter = mEditCharter->getText();
|
|
if (mInsignia) gdatap->mInsigniaID = mInsignia->getImageAssetID();
|
|
if (mComboMature)
|
|
{
|
|
if (!gAgent.isTeen())
|
|
{
|
|
gdatap->mMaturePublish =
|
|
mComboMature->getCurrentIndex() == MATURE_CONTENT;
|
|
}
|
|
else
|
|
{
|
|
gdatap->mMaturePublish = FALSE;
|
|
}
|
|
}
|
|
if (mCtrlShowInGroupList) gdatap->mShowInList = mCtrlShowInGroupList->get();
|
|
}
|
|
|
|
if (can_change_member_opts)
|
|
{
|
|
if (mCtrlOpenEnrollment) gdatap->mOpenEnrollment = mCtrlOpenEnrollment->get();
|
|
if (mCtrlEnrollmentFee && mSpinEnrollmentFee)
|
|
{
|
|
gdatap->mMembershipFee = (mCtrlEnrollmentFee->get()) ?
|
|
(S32) mSpinEnrollmentFee->get() : 0;
|
|
// Set to the used value, and reset initial value used for isdirty check
|
|
mSpinEnrollmentFee->set( (F32)gdatap->mMembershipFee );
|
|
}
|
|
}
|
|
|
|
if (can_change_ident || can_change_member_opts)
|
|
{
|
|
LLGroupMgr::getInstance()->sendUpdateGroupInfo(mGroupID);
|
|
}
|
|
}
|
|
|
|
BOOL receive_notices = false;
|
|
BOOL list_in_profile = false;
|
|
if (mCtrlReceiveNotices)
|
|
{
|
|
receive_notices = mCtrlReceiveNotices->get();
|
|
mCtrlReceiveNotices->resetDirty(); //resetDirty() here instead of in update because this is where the settings
|
|
//are actually being applied. onCommitUserOnly doesn't call updateChanged directly.
|
|
}
|
|
if (mCtrlListGroup)
|
|
{
|
|
list_in_profile = mCtrlListGroup->get();
|
|
mCtrlListGroup->resetDirty(); //resetDirty() here instead of in update because this is where the settings
|
|
//are actually being applied. onCommitUserOnly doesn't call updateChanged directly.
|
|
}
|
|
|
|
gAgent.setUserGroupFlags(mGroupID, receive_notices, list_in_profile);
|
|
|
|
if (mCtrlReceiveChat)
|
|
{
|
|
bool receive_chat = mCtrlReceiveChat->get();
|
|
gIMMgr->updateIgnoreGroup(mGroupID, !receive_chat);
|
|
// Save here too in case we crash somewhere down the road -- MC
|
|
gIMMgr->saveIgnoreGroup();
|
|
mCtrlReceiveChat->resetDirty();
|
|
}
|
|
|
|
mChanged = FALSE;
|
|
|
|
return true;
|
|
}
|
|
|
|
void LLPanelGroupGeneral::cancel()
|
|
{
|
|
mChanged = FALSE;
|
|
|
|
//cancel out all of the click changes to, although since we are
|
|
//shifting tabs or closing the floater, this need not be done...yet
|
|
notifyObservers();
|
|
}
|
|
|
|
// invoked from callbackConfirmMature
|
|
bool LLPanelGroupGeneral::confirmMatureApply(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
// 0 == Yes
|
|
// 1 == No
|
|
// 2 == Cancel
|
|
switch(option)
|
|
{
|
|
case 0:
|
|
mComboMature->setCurrentByIndex(MATURE_CONTENT);
|
|
break;
|
|
case 1:
|
|
mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
// If we got here it means they set a valid value
|
|
std::string mesg = "";
|
|
apply(mesg);
|
|
return false;
|
|
}
|
|
|
|
// static
|
|
bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
switch(option)
|
|
{
|
|
case 0:
|
|
{
|
|
// Yay! We are making a new group!
|
|
U32 enrollment_fee = (mCtrlEnrollmentFee->get() ?
|
|
(U32) mSpinEnrollmentFee->get() : 0);
|
|
|
|
LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(),
|
|
mEditCharter->getText(),
|
|
mCtrlShowInGroupList->get(),
|
|
mInsignia->getImageAssetID(),
|
|
enrollment_fee,
|
|
mCtrlOpenEnrollment->get(),
|
|
false,
|
|
mComboMature->getCurrentIndex() == MATURE_CONTENT);
|
|
|
|
}
|
|
break;
|
|
case 1:
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static F32 sSDTime = 0.0f;
|
|
static F32 sElementTime = 0.0f;
|
|
static F32 sAllTime = 0.0f;
|
|
|
|
// virtual
|
|
void LLPanelGroupGeneral::update(LLGroupChange gc)
|
|
{
|
|
if (mGroupID.isNull()) return;
|
|
|
|
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
|
|
|
if (!gdatap) return;
|
|
|
|
LLGroupData agent_gdatap;
|
|
bool is_member = false;
|
|
if (gAgent.getGroupData(mGroupID,agent_gdatap)) is_member = true;
|
|
|
|
if (mComboActiveTitle)
|
|
{
|
|
mComboActiveTitle->setVisible(is_member);
|
|
|
|
if ( mActiveTitleLabel) mActiveTitleLabel->setVisible(is_member);
|
|
|
|
if (is_member)
|
|
{
|
|
LLUUID current_title_role;
|
|
|
|
mComboActiveTitle->clear();
|
|
mComboActiveTitle->removeall();
|
|
bool has_selected_title = false;
|
|
|
|
if (1 == gdatap->mTitles.size())
|
|
{
|
|
// Only the everyone title. Don't bother letting them try changing this.
|
|
mComboActiveTitle->setEnabled(FALSE);
|
|
}
|
|
else
|
|
{
|
|
mComboActiveTitle->setEnabled(TRUE);
|
|
}
|
|
|
|
std::vector<LLGroupTitle>::const_iterator citer = gdatap->mTitles.begin();
|
|
std::vector<LLGroupTitle>::const_iterator end = gdatap->mTitles.end();
|
|
|
|
for ( ; citer != end; ++citer)
|
|
{
|
|
mComboActiveTitle->add(citer->mTitle,citer->mRoleID, (citer->mSelected ? ADD_TOP : ADD_BOTTOM));
|
|
if (citer->mSelected)
|
|
{
|
|
mComboActiveTitle->setCurrentByID(citer->mRoleID);
|
|
has_selected_title = true;
|
|
}
|
|
}
|
|
|
|
if (!has_selected_title)
|
|
{
|
|
mComboActiveTitle->setCurrentByID(LLUUID::null);
|
|
}
|
|
}
|
|
|
|
mComboActiveTitle->resetDirty();
|
|
}
|
|
|
|
// After role member data was changed in Roles->Members
|
|
// need to update role titles. See STORM-918.
|
|
if (gc == GC_ROLE_MEMBER_DATA)
|
|
LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
|
|
|
|
// If this was just a titles update, we are done.
|
|
if (gc == GC_TITLES) return;
|
|
|
|
bool can_change_ident = false;
|
|
bool can_change_member_opts = false;
|
|
can_change_ident = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);
|
|
can_change_member_opts = gAgent.hasPowerInGroup(mGroupID,GP_MEMBER_OPTIONS);
|
|
|
|
if (mCtrlShowInGroupList)
|
|
{
|
|
mCtrlShowInGroupList->set(gdatap->mShowInList);
|
|
mCtrlShowInGroupList->setEnabled(can_change_ident);
|
|
mCtrlShowInGroupList->resetDirty();
|
|
|
|
}
|
|
if (mComboMature)
|
|
{
|
|
if(gdatap->mMaturePublish)
|
|
{
|
|
mComboMature->setCurrentByIndex(MATURE_CONTENT);
|
|
}
|
|
else
|
|
{
|
|
mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
|
|
}
|
|
mComboMature->setEnabled(can_change_ident);
|
|
mComboMature->setVisible( !gAgent.isTeen() );
|
|
mComboMature->resetDirty();
|
|
}
|
|
if (mCtrlOpenEnrollment)
|
|
{
|
|
mCtrlOpenEnrollment->set(gdatap->mOpenEnrollment);
|
|
mCtrlOpenEnrollment->setEnabled(can_change_member_opts);
|
|
mCtrlOpenEnrollment->resetDirty();
|
|
}
|
|
if (mCtrlEnrollmentFee)
|
|
{
|
|
mCtrlEnrollmentFee->set(gdatap->mMembershipFee > 0);
|
|
mCtrlEnrollmentFee->setEnabled(can_change_member_opts);
|
|
mCtrlEnrollmentFee->resetDirty();
|
|
}
|
|
|
|
if (mSpinEnrollmentFee)
|
|
{
|
|
S32 fee = gdatap->mMembershipFee;
|
|
mSpinEnrollmentFee->set((F32)fee);
|
|
mSpinEnrollmentFee->setEnabled(fee && can_change_member_opts);
|
|
mSpinEnrollmentFee->resetDirty();
|
|
}
|
|
if ( mBtnJoinGroup )
|
|
{
|
|
std::string fee_buff;
|
|
bool visible;
|
|
|
|
visible = !is_member && gdatap->mOpenEnrollment;
|
|
mBtnJoinGroup->setVisible(visible);
|
|
|
|
if ( visible )
|
|
{
|
|
fee_buff = llformat( "Join (%s%d)",
|
|
gHippoGridManager->getConnectedGrid()->getCurrencySymbol().c_str(),
|
|
gdatap->mMembershipFee);
|
|
mBtnJoinGroup->setLabelSelected(fee_buff);
|
|
mBtnJoinGroup->setLabelUnselected(fee_buff);
|
|
}
|
|
}
|
|
if ( mBtnInfo )
|
|
{
|
|
mBtnInfo->setVisible(is_member && !mAllowEdit);
|
|
}
|
|
|
|
if(gc == GC_ALL || gc == GC_PROPERTIES)
|
|
{
|
|
if (mCtrlReceiveNotices)
|
|
{
|
|
mCtrlReceiveNotices->setVisible(is_member);
|
|
if (is_member)
|
|
{
|
|
if(!mCtrlReceiveNotices->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc.
|
|
{
|
|
mCtrlReceiveNotices->set(agent_gdatap.mAcceptNotices);
|
|
mCtrlReceiveNotices->resetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mCtrlListGroup)
|
|
{
|
|
mCtrlListGroup->setVisible(is_member);
|
|
if (is_member)
|
|
{
|
|
if(!mCtrlListGroup->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc.
|
|
{
|
|
mCtrlListGroup->set(agent_gdatap.mListInProfile);
|
|
mCtrlListGroup->resetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mCtrlReceiveChat)
|
|
{
|
|
mCtrlReceiveChat->setVisible(is_member);
|
|
if (is_member)
|
|
{
|
|
if(!mCtrlReceiveChat->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc.
|
|
{
|
|
mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID));
|
|
mCtrlReceiveChat->resetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mInsignia) mInsignia->setEnabled(can_change_ident);
|
|
if (mEditCharter) mEditCharter->setEnabled(can_change_ident);
|
|
|
|
getChildView("group_name")->setValue(mGroupID);
|
|
if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE);
|
|
if (mFounderName) mFounderName->setValue(gdatap->mFounderID);
|
|
|
|
if (auto key_edit = getChildView("group_key"))
|
|
{
|
|
key_edit->setValue(gdatap->getID().asString());
|
|
}
|
|
|
|
if (mInsignia)
|
|
{
|
|
if (gdatap->mInsigniaID.notNull())
|
|
{
|
|
mInsignia->setImageAssetID(gdatap->mInsigniaID);
|
|
}
|
|
else
|
|
{
|
|
mInsignia->setImageAssetID(mDefaultIconID);
|
|
}
|
|
}
|
|
|
|
if (mEditCharter)
|
|
{
|
|
mEditCharter->setText(gdatap->mCharter, false);
|
|
mEditCharter->resetDirty();
|
|
}
|
|
}
|
|
|
|
if (mListVisibleMembers)
|
|
{
|
|
mListVisibleMembers->deleteAllItems();
|
|
|
|
if (gdatap->isMemberDataComplete())
|
|
{
|
|
mMemberProgress = gdatap->mMembers.begin();
|
|
mPendingMemberUpdate = TRUE;
|
|
|
|
sSDTime = 0.0f;
|
|
sElementTime = 0.0f;
|
|
sAllTime = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
std::stringstream pending;
|
|
pending << "Retrieving member list (" << gdatap->mMembers.size() << "\\" << gdatap->mMemberCount << ")";
|
|
|
|
LLSD row;
|
|
row["columns"][0]["value"] = pending.str();
|
|
row["columns"][0]["column"] = "name";
|
|
|
|
mListVisibleMembers->setEnabled(FALSE);
|
|
mListVisibleMembers->addElement(row);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLPanelGroupGeneral::updateMembers()
|
|
{
|
|
mPendingMemberUpdate = FALSE;
|
|
|
|
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
|
|
|
if (!mListVisibleMembers
|
|
|| !gdatap
|
|
|| !gdatap->isMemberDataComplete()
|
|
|| gdatap->mMembers.empty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
LLTimer update_time;
|
|
update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
|
|
|
|
LLAvatarName av_name;
|
|
|
|
for( ; mMemberProgress != gdatap->mMembers.end() && !update_time.hasExpired();
|
|
++mMemberProgress)
|
|
{
|
|
LLGroupMemberData* member = mMemberProgress->second;
|
|
if (!member)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
|
|
{
|
|
addMember(mMemberProgress->second);
|
|
}
|
|
else
|
|
{
|
|
// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
|
|
avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(mMemberProgress->first);
|
|
if (it != mAvatarNameCacheConnections.end())
|
|
{
|
|
if (it->second.connected())
|
|
{
|
|
it->second.disconnect();
|
|
}
|
|
mAvatarNameCacheConnections.erase(it);
|
|
}
|
|
mAvatarNameCacheConnections[mMemberProgress->first] = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupGeneral::onNameCache, this, gdatap->getMemberVersion(), member, _2, _1));
|
|
}
|
|
}
|
|
|
|
getChild<LLUICtrl>("text_owners_and_visible_members")->setTextArg("[COUNT]", boost::lexical_cast<std::string>(gdatap->mMembers.size()));
|
|
|
|
if (mMemberProgress == gdatap->mMembers.end())
|
|
{
|
|
LL_DEBUGS() << " member list completed." << LL_ENDL;
|
|
mListVisibleMembers->setEnabled(TRUE);
|
|
}
|
|
else
|
|
{
|
|
mPendingMemberUpdate = TRUE;
|
|
mListVisibleMembers->setEnabled(FALSE);
|
|
}
|
|
}
|
|
|
|
bool is_online_status_string(const std::string& status);
|
|
|
|
void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
|
|
{
|
|
// Owners show up in bold.
|
|
std::string style = "NORMAL";
|
|
if ( member->isOwner() )
|
|
{
|
|
style = "BOLD";
|
|
}
|
|
LLNameListCtrl::NameItem item_params;
|
|
item_params.value = member->getID();
|
|
|
|
LLScrollListCell::Params column;
|
|
item_params.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL").font_style(style);
|
|
|
|
item_params.columns.add().column("title").value(member->getTitle()).font/*.name*/("SANSSERIF_SMALL").font_style(style);
|
|
|
|
static const LLCachedControl<std::string> format(gSavedSettings, "ShortDateFormat");
|
|
item_params.columns.add().column("online").value(member->getOnlineStatus())
|
|
.format(format).type(is_online_status_string(member->getOnlineStatus()) ? "text" : "date")
|
|
.font/*.name*/("SANSSERIF_SMALL").font_style(style);
|
|
|
|
/*LLScrollListItem* member_row =*/ mListVisibleMembers->addNameItemRow(item_params);
|
|
}
|
|
|
|
void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id)
|
|
{
|
|
avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(av_id);
|
|
if (it != mAvatarNameCacheConnections.end())
|
|
{
|
|
if (it->second.connected())
|
|
{
|
|
it->second.disconnect();
|
|
}
|
|
mAvatarNameCacheConnections.erase(it);
|
|
}
|
|
|
|
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
|
|
|
if (!gdatap
|
|
|| !gdatap->isMemberDataComplete()
|
|
|| gdatap->getMemberVersion() != update_id)
|
|
{
|
|
// Stale data
|
|
return;
|
|
}
|
|
|
|
addMember(member);
|
|
}
|
|
|
|
void LLPanelGroupGeneral::updateChanged()
|
|
{
|
|
// List all the controls we want to check for changes...
|
|
LLUICtrl *check_list[] =
|
|
{
|
|
mGroupNameEditor,
|
|
mFounderName,
|
|
mInsignia,
|
|
mEditCharter,
|
|
mCtrlShowInGroupList,
|
|
mComboMature,
|
|
mCtrlOpenEnrollment,
|
|
mCtrlEnrollmentFee,
|
|
mSpinEnrollmentFee,
|
|
mCtrlReceiveNotices,
|
|
mCtrlReceiveChat,
|
|
mCtrlListGroup,
|
|
mActiveTitleLabel,
|
|
mComboActiveTitle
|
|
};
|
|
|
|
mChanged = FALSE;
|
|
|
|
for( int i= 0; i< LL_ARRAY_SIZE(check_list); i++ )
|
|
{
|
|
if( check_list[i] && check_list[i]->isDirty() )
|
|
{
|
|
mChanged = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|