PageRenderTime 789ms CodeModel.GetById 181ms app.highlight 459ms RepoModel.GetById 140ms app.codeStats 0ms

/indra/newview/llpanelgroupgeneral.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 964 lines | 802 code | 107 blank | 55 comment | 98 complexity | c0473b5454bff034861802289d2cc164 MD5 | raw file
  1/** 
  2 * @file llpanelgroupgeneral.cpp
  3 * @brief General information about a group.
  4 *
  5 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llpanelgroupgeneral.h"
 30
 31#include "lluictrlfactory.h"
 32#include "llagent.h"
 33#include "roles_constants.h"
 34
 35// UI elements
 36#include "llbutton.h"
 37#include "llcheckboxctrl.h"
 38#include "llcombobox.h"
 39#include "lldbstrings.h"
 40#include "llavataractions.h"
 41#include "llgroupactions.h"
 42#include "lllineeditor.h"
 43#include "llnamelistctrl.h"
 44#include "llnotificationsutil.h"
 45#include "llscrolllistitem.h"
 46#include "llspinctrl.h"
 47#include "llslurl.h"
 48#include "lltextbox.h"
 49#include "lltexteditor.h"
 50#include "lltexturectrl.h"
 51#include "lltrans.h"
 52#include "llviewerwindow.h"
 53
 54static LLRegisterPanelClassWrapper<LLPanelGroupGeneral> t_panel_group_general("panel_group_general");
 55
 56// consts
 57const S32 MATURE_CONTENT = 1;
 58const S32 NON_MATURE_CONTENT = 2;
 59const S32 DECLINE_TO_STATE = 0;
 60
 61
 62LLPanelGroupGeneral::LLPanelGroupGeneral()
 63:	LLPanelGroupTab(),
 64	mPendingMemberUpdate(FALSE),
 65	mChanged(FALSE),
 66	mFirstUse(TRUE),
 67	mGroupNameEditor(NULL),
 68	mFounderName(NULL),
 69	mInsignia(NULL),
 70	mEditCharter(NULL),
 71	mListVisibleMembers(NULL),
 72	mCtrlShowInGroupList(NULL),
 73	mComboMature(NULL),
 74	mCtrlOpenEnrollment(NULL),
 75	mCtrlEnrollmentFee(NULL),
 76	mSpinEnrollmentFee(NULL),
 77	mCtrlReceiveNotices(NULL),
 78	mCtrlListGroup(NULL),
 79	mActiveTitleLabel(NULL),
 80	mComboActiveTitle(NULL)
 81{
 82
 83}
 84
 85LLPanelGroupGeneral::~LLPanelGroupGeneral()
 86{
 87}
 88
 89BOOL LLPanelGroupGeneral::postBuild()
 90{
 91	bool recurse = true;
 92
 93	mEditCharter = getChild<LLTextEditor>("charter", recurse);
 94	if(mEditCharter)
 95	{
 96		mEditCharter->setCommitCallback(onCommitAny, this);
 97		mEditCharter->setFocusReceivedCallback(boost::bind(onFocusEdit, _1, this));
 98		mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this));
 99	}
100
101
102
103	mListVisibleMembers = getChild<LLNameListCtrl>("visible_members", recurse);
104	if (mListVisibleMembers)
105	{
106		mListVisibleMembers->setDoubleClickCallback(openProfile, this);
107		mListVisibleMembers->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
108		
109		mListVisibleMembers->setSortCallback(boost::bind(&LLPanelGroupGeneral::sortMembersList,this,_1,_2,_3));
110	}
111
112	// Options
113	mCtrlShowInGroupList = getChild<LLCheckBoxCtrl>("show_in_group_list", recurse);
114	if (mCtrlShowInGroupList)
115	{
116		mCtrlShowInGroupList->setCommitCallback(onCommitAny, this);
117	}
118
119	mComboMature = getChild<LLComboBox>("group_mature_check", recurse);	
120	if(mComboMature)
121	{
122		mComboMature->setCurrentByIndex(0);
123		mComboMature->setCommitCallback(onCommitAny, this);
124		if (gAgent.isTeen())
125		{
126			// Teens don't get to set mature flag. JC
127			mComboMature->setVisible(FALSE);
128			mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
129		}
130	}
131	mCtrlOpenEnrollment = getChild<LLCheckBoxCtrl>("open_enrollement", recurse);
132	if (mCtrlOpenEnrollment)
133	{
134		mCtrlOpenEnrollment->setCommitCallback(onCommitAny, this);
135	}
136
137	mCtrlEnrollmentFee = getChild<LLCheckBoxCtrl>("check_enrollment_fee", recurse);
138	if (mCtrlEnrollmentFee)
139	{
140		mCtrlEnrollmentFee->setCommitCallback(onCommitEnrollment, this);
141	}
142
143	mSpinEnrollmentFee = getChild<LLSpinCtrl>("spin_enrollment_fee", recurse);
144	if (mSpinEnrollmentFee)
145	{
146		mSpinEnrollmentFee->setCommitCallback(onCommitAny, this);
147		mSpinEnrollmentFee->setPrecision(0);
148		mSpinEnrollmentFee->resetDirty();
149	}
150
151	BOOL accept_notices = FALSE;
152	BOOL list_in_profile = FALSE;
153	LLGroupData data;
154	if(gAgent.getGroupData(mGroupID,data))
155	{
156		accept_notices = data.mAcceptNotices;
157		list_in_profile = data.mListInProfile;
158	}
159	mCtrlReceiveNotices = getChild<LLCheckBoxCtrl>("receive_notices", recurse);
160	if (mCtrlReceiveNotices)
161	{
162		mCtrlReceiveNotices->setCommitCallback(onCommitUserOnly, this);
163		mCtrlReceiveNotices->set(accept_notices);
164		mCtrlReceiveNotices->setEnabled(data.mID.notNull());
165	}
166	
167	mCtrlListGroup = getChild<LLCheckBoxCtrl>("list_groups_in_profile", recurse);
168	if (mCtrlListGroup)
169	{
170		mCtrlListGroup->setCommitCallback(onCommitUserOnly, this);
171		mCtrlListGroup->set(list_in_profile);
172		mCtrlListGroup->setEnabled(data.mID.notNull());
173		mCtrlListGroup->resetDirty();
174	}
175
176	mActiveTitleLabel = getChild<LLTextBox>("active_title_label", recurse);
177	
178	mComboActiveTitle = getChild<LLComboBox>("active_title", recurse);
179	if (mComboActiveTitle)
180	{
181		mComboActiveTitle->setCommitCallback(onCommitAny, this);
182	}
183
184	mIncompleteMemberDataStr = getString("incomplete_member_data_str");
185
186	// If the group_id is null, then we are creating a new group
187	if (mGroupID.isNull())
188	{
189		mEditCharter->setEnabled(TRUE);
190
191		mCtrlShowInGroupList->setEnabled(TRUE);
192		mComboMature->setEnabled(TRUE);
193		mCtrlOpenEnrollment->setEnabled(TRUE);
194		mCtrlEnrollmentFee->setEnabled(TRUE);
195		mSpinEnrollmentFee->setEnabled(TRUE);
196
197	}
198
199	return LLPanelGroupTab::postBuild();
200}
201
202void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)
203{
204	mInsignia = getChild<LLTextureCtrl>("insignia");
205	if (mInsignia)
206	{
207		mInsignia->setCommitCallback(onCommitAny, this);
208	}
209	mFounderName = getChild<LLTextBox>("founder_name");
210
211
212	mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor");
213	mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCII );
214	
215
216}
217
218// static
219void LLPanelGroupGeneral::onFocusEdit(LLFocusableElement* ctrl, void* data)
220{
221	LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
222	self->updateChanged();
223	self->notifyObservers();
224}
225
226// static
227void LLPanelGroupGeneral::onCommitAny(LLUICtrl* ctrl, void* data)
228{
229	LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
230	self->updateChanged();
231	self->notifyObservers();
232}
233
234// static
235void LLPanelGroupGeneral::onCommitUserOnly(LLUICtrl* ctrl, void* data)
236{
237	LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
238	self->mChanged = TRUE;
239	self->notifyObservers();
240}
241
242
243// static
244void LLPanelGroupGeneral::onCommitEnrollment(LLUICtrl* ctrl, void* data)
245{
246	onCommitAny(ctrl, data);
247
248	LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
249	// Make sure both enrollment related widgets are there.
250	if (!self->mCtrlEnrollmentFee || !self->mSpinEnrollmentFee)
251	{
252		return;
253	}
254
255	// Make sure the agent can change enrollment info.
256	if (!gAgent.hasPowerInGroup(self->mGroupID,GP_MEMBER_OPTIONS)
257		|| !self->mAllowEdit)
258	{
259		return;
260	}
261
262	if (self->mCtrlEnrollmentFee->get())
263	{
264		self->mSpinEnrollmentFee->setEnabled(TRUE);
265	}
266	else
267	{
268		self->mSpinEnrollmentFee->setEnabled(FALSE);
269		self->mSpinEnrollmentFee->set(0);
270	}
271}
272
273// static
274void LLPanelGroupGeneral::onClickInfo(void *userdata)
275{
276	LLPanelGroupGeneral *self = (LLPanelGroupGeneral *)userdata;
277
278	if ( !self ) return;
279
280	lldebugs << "open group info: " << self->mGroupID << llendl;
281
282	LLGroupActions::show(self->mGroupID);
283
284}
285
286// static
287void LLPanelGroupGeneral::openProfile(void* data)
288{
289	LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
290
291	if (self && self->mListVisibleMembers)
292	{
293		LLScrollListItem* selected = self->mListVisibleMembers->getFirstSelected();
294		if (selected)
295		{
296			LLAvatarActions::showProfile(selected->getUUID());
297		}
298	}
299}
300
301bool LLPanelGroupGeneral::needsApply(std::string& mesg)
302{ 
303	updateChanged();
304	mesg = getString("group_info_unchanged");
305	return mChanged || mGroupID.isNull();
306}
307
308void LLPanelGroupGeneral::activate()
309{
310	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
311	if (mGroupID.notNull()
312		&& (!gdatap || mFirstUse))
313	{
314		LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
315		LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
316
317		
318		if (!gdatap || !gdatap->isMemberDataComplete() )
319		{
320			LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
321		}
322
323		mFirstUse = FALSE;
324	}
325	mChanged = FALSE;
326	
327	update(GC_ALL);
328}
329
330void LLPanelGroupGeneral::draw()
331{
332	LLPanelGroupTab::draw();
333
334	if (mPendingMemberUpdate)
335	{
336		updateMembers();
337	}
338}
339
340bool LLPanelGroupGeneral::apply(std::string& mesg)
341{
342	if (!mGroupID.isNull() && mAllowEdit && mComboActiveTitle && mComboActiveTitle->isDirty())
343	{
344		LLGroupMgr::getInstance()->sendGroupTitleUpdate(mGroupID,mComboActiveTitle->getCurrentID());
345		update(GC_TITLES);
346		mComboActiveTitle->resetDirty();
347	}
348
349	BOOL has_power_in_group = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);
350
351	if (has_power_in_group || mGroupID.isNull())
352	{
353		llinfos << "LLPanelGroupGeneral::apply" << llendl;
354
355		// Check to make sure mature has been set
356		if(mComboMature &&
357		   mComboMature->getCurrentIndex() == DECLINE_TO_STATE)
358		{
359			LLNotificationsUtil::add("SetGroupMature", LLSD(), LLSD(), 
360											boost::bind(&LLPanelGroupGeneral::confirmMatureApply, this, _1, _2));
361			return false;
362		}
363
364		if (mGroupID.isNull())
365		{
366			// Validate the group name length.
367			S32 group_name_len = mGroupNameEditor->getText().size();
368			if ( group_name_len < DB_GROUP_NAME_MIN_LEN 
369				|| group_name_len > DB_GROUP_NAME_STR_LEN)
370			{
371				std::ostringstream temp_error;
372				temp_error << "A group name must be between " << DB_GROUP_NAME_MIN_LEN
373					<< " and " << DB_GROUP_NAME_STR_LEN << " characters.";
374				mesg = temp_error.str();
375				return false;
376			}
377
378			LLNotificationsUtil::add("CreateGroupCost",  LLSD(), LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2));
379
380			return false;
381		}
382
383		LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
384		if (!gdatap)
385		{
386			mesg = LLTrans::getString("NoGroupDataFound");
387			mesg.append(mGroupID.asString());
388			return false;
389		}
390		bool can_change_ident = false;
391		bool can_change_member_opts = false;
392		can_change_ident = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);
393		can_change_member_opts = gAgent.hasPowerInGroup(mGroupID,GP_MEMBER_OPTIONS);
394
395		if (can_change_ident)
396		{
397			if (mEditCharter) gdatap->mCharter = mEditCharter->getText();
398			if (mInsignia) gdatap->mInsigniaID = mInsignia->getImageAssetID();
399			if (mComboMature)
400			{
401				if (!gAgent.isTeen())
402				{
403					gdatap->mMaturePublish = 
404						mComboMature->getCurrentIndex() == MATURE_CONTENT;
405				}
406				else
407				{
408					gdatap->mMaturePublish = FALSE;
409				}
410			}
411			if (mCtrlShowInGroupList) gdatap->mShowInList = mCtrlShowInGroupList->get();
412		}
413
414		if (can_change_member_opts)
415		{
416			if (mCtrlOpenEnrollment) gdatap->mOpenEnrollment = mCtrlOpenEnrollment->get();
417			if (mCtrlEnrollmentFee && mSpinEnrollmentFee)
418			{
419				gdatap->mMembershipFee = (mCtrlEnrollmentFee->get()) ? 
420					(S32) mSpinEnrollmentFee->get() : 0;
421				// Set to the used value, and reset initial value used for isdirty check
422				mSpinEnrollmentFee->set( (F32)gdatap->mMembershipFee );
423			}
424		}
425
426		if (can_change_ident || can_change_member_opts)
427		{
428			LLGroupMgr::getInstance()->sendUpdateGroupInfo(mGroupID);
429		}
430	}
431
432	BOOL receive_notices = false;
433	BOOL list_in_profile = false;
434	if (mCtrlReceiveNotices)
435		receive_notices = mCtrlReceiveNotices->get();
436	if (mCtrlListGroup) 
437		list_in_profile = mCtrlListGroup->get();
438
439	gAgent.setUserGroupFlags(mGroupID, receive_notices, list_in_profile);
440
441	resetDirty();
442
443	mChanged = FALSE;
444
445	return true;
446}
447
448void LLPanelGroupGeneral::cancel()
449{
450	mChanged = FALSE;
451
452	//cancel out all of the click changes to, although since we are
453	//shifting tabs or closing the floater, this need not be done...yet
454	notifyObservers();
455}
456
457// invoked from callbackConfirmMature
458bool LLPanelGroupGeneral::confirmMatureApply(const LLSD& notification, const LLSD& response)
459{
460	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
461	// 0 == Yes
462	// 1 == No
463	// 2 == Cancel
464	switch(option)
465	{
466	case 0:
467		mComboMature->setCurrentByIndex(MATURE_CONTENT);
468		break;
469	case 1:
470		mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
471		break;
472	default:
473		return false;
474	}
475
476	// If we got here it means they set a valid value
477	std::string mesg = "";
478	bool ret = apply(mesg);
479	if ( !mesg.empty() )
480	{
481		LLSD args;
482		args["MESSAGE"] = mesg;
483		LLNotificationsUtil::add("GenericAlert", args);
484	}
485
486	return ret;
487}
488
489// static
490bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LLSD& response)
491{
492	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
493	switch(option)
494	{
495	case 0:
496		{
497			// Yay!  We are making a new group!
498			U32 enrollment_fee = (mCtrlEnrollmentFee->get() ? 
499									(U32) mSpinEnrollmentFee->get() : 0);
500		
501			LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(),
502												mEditCharter->getText(),
503												mCtrlShowInGroupList->get(),
504												mInsignia->getImageAssetID(),
505												enrollment_fee,
506												mCtrlOpenEnrollment->get(),
507												false,
508												mComboMature->getCurrentIndex() == MATURE_CONTENT);
509
510		}
511		break;
512	case 1:
513	default:
514		break;
515	}
516	return false;
517}
518
519static F32 sSDTime = 0.0f;
520static F32 sElementTime = 0.0f;
521static F32 sAllTime = 0.0f;
522
523// virtual
524void LLPanelGroupGeneral::update(LLGroupChange gc)
525{
526	if (mGroupID.isNull()) return;
527
528	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
529
530	if (!gdatap) return;
531
532	LLGroupData agent_gdatap;
533	bool is_member = false;
534	if (gAgent.getGroupData(mGroupID,agent_gdatap)) is_member = true;
535
536	if (mComboActiveTitle)
537	{
538		mComboActiveTitle->setVisible(is_member);
539		mComboActiveTitle->setEnabled(mAllowEdit);
540		
541		if ( mActiveTitleLabel) mActiveTitleLabel->setVisible(is_member);
542
543		if (is_member)
544		{
545			LLUUID current_title_role;
546
547			mComboActiveTitle->clear();
548			mComboActiveTitle->removeall();
549			bool has_selected_title = false;
550
551			if (1 == gdatap->mTitles.size())
552			{
553				// Only the everyone title.  Don't bother letting them try changing this.
554				mComboActiveTitle->setEnabled(FALSE);
555			}
556			else
557			{
558				mComboActiveTitle->setEnabled(TRUE);
559			}
560
561			std::vector<LLGroupTitle>::const_iterator citer = gdatap->mTitles.begin();
562			std::vector<LLGroupTitle>::const_iterator end = gdatap->mTitles.end();
563			
564			for ( ; citer != end; ++citer)
565			{
566				mComboActiveTitle->add(citer->mTitle,citer->mRoleID, (citer->mSelected ? ADD_TOP : ADD_BOTTOM));
567				if (citer->mSelected)
568				{
569					mComboActiveTitle->setCurrentByID(citer->mRoleID);
570					has_selected_title = true;
571				}
572			}
573			
574			if (!has_selected_title)
575			{
576				mComboActiveTitle->setCurrentByID(LLUUID::null);
577			}
578		}
579
580	}
581
582	// After role member data was changed in Roles->Members
583	// need to update role titles. See STORM-918.
584	if (gc == GC_ROLE_MEMBER_DATA)
585		LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
586
587	// If this was just a titles update, we are done.
588	if (gc == GC_TITLES) return;
589
590	bool can_change_ident = false;
591	bool can_change_member_opts = false;
592	can_change_ident = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);
593	can_change_member_opts = gAgent.hasPowerInGroup(mGroupID,GP_MEMBER_OPTIONS);
594
595	if (mCtrlShowInGroupList) 
596	{
597		mCtrlShowInGroupList->set(gdatap->mShowInList);
598		mCtrlShowInGroupList->setEnabled(mAllowEdit && can_change_ident);
599	}
600	if (mComboMature)
601	{
602		if(gdatap->mMaturePublish)
603		{
604			mComboMature->setCurrentByIndex(MATURE_CONTENT);
605		}
606		else
607		{
608			mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
609		}
610		mComboMature->setEnabled(mAllowEdit && can_change_ident);
611		mComboMature->setVisible( !gAgent.isTeen() );
612	}
613	if (mCtrlOpenEnrollment) 
614	{
615		mCtrlOpenEnrollment->set(gdatap->mOpenEnrollment);
616		mCtrlOpenEnrollment->setEnabled(mAllowEdit && can_change_member_opts);
617	}
618	if (mCtrlEnrollmentFee) 
619	{	
620		mCtrlEnrollmentFee->set(gdatap->mMembershipFee > 0);
621		mCtrlEnrollmentFee->setEnabled(mAllowEdit && can_change_member_opts);
622	}
623	
624	if (mSpinEnrollmentFee)
625	{
626		S32 fee = gdatap->mMembershipFee;
627		mSpinEnrollmentFee->set((F32)fee);
628		mSpinEnrollmentFee->setEnabled( mAllowEdit &&
629						(fee > 0) &&
630						can_change_member_opts);
631	}
632	if (mCtrlReceiveNotices)
633	{
634		mCtrlReceiveNotices->setVisible(is_member);
635		if (is_member)
636		{
637			mCtrlReceiveNotices->setEnabled(mAllowEdit);
638		}
639	}
640
641
642	if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident);
643	if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident);
644	
645	if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE);
646	if (mFounderName) mFounderName->setText(LLSLURL("agent", gdatap->mFounderID, "inspect").getSLURLString());
647	if (mInsignia)
648	{
649		if (gdatap->mInsigniaID.notNull())
650		{
651			mInsignia->setImageAssetID(gdatap->mInsigniaID);
652		}
653		else
654		{
655			mInsignia->setImageAssetName(mInsignia->getDefaultImageName());
656		}
657	}
658
659	if (mEditCharter)
660	{
661		mEditCharter->setText(gdatap->mCharter);
662	}
663	
664	if (mListVisibleMembers)
665	{
666		mListVisibleMembers->deleteAllItems();
667
668		if (gdatap->isMemberDataComplete())
669		{
670			mMemberProgress = gdatap->mMembers.begin();
671			mPendingMemberUpdate = TRUE;
672
673			sSDTime = 0.0f;
674			sElementTime = 0.0f;
675			sAllTime = 0.0f;
676		}
677		else
678		{
679			std::stringstream pending;
680			pending << "Retrieving member list (" << gdatap->mMembers.size() << "\\" << gdatap->mMemberCount  << ")";
681
682			LLSD row;
683			row["columns"][0]["value"] = pending.str();
684			row["columns"][0]["column"] = "name";
685
686			mListVisibleMembers->setEnabled(FALSE);
687			mListVisibleMembers->addElement(row);
688		}
689	}
690
691	resetDirty();
692}
693
694void LLPanelGroupGeneral::updateMembers()
695{
696	mPendingMemberUpdate = FALSE;
697
698	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
699
700	if (!mListVisibleMembers || !gdatap 
701		|| !gdatap->isMemberDataComplete()
702		|| gdatap->mMembers.empty())
703	{
704		return;
705	}
706
707	static LLTimer all_timer;
708	static LLTimer sd_timer;
709	static LLTimer element_timer;
710
711	all_timer.reset();
712	S32 i = 0;
713
714	for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME; 
715			++mMemberProgress, ++i)
716	{
717		//llinfos << "Adding " << iter->first << ", " << iter->second->getTitle() << llendl;
718		LLGroupMemberData* member = mMemberProgress->second;
719		if (!member)
720		{
721			continue;
722		}
723		// Owners show up in bold.
724		std::string style = "NORMAL";
725		sd_timer.reset();
726		LLSD row;
727		row["id"] = member->getID();
728
729		row["columns"][0]["column"] = "name";
730		row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
731		row["columns"][0]["font"]["style"] = style;
732		// value is filled in by name list control
733
734		row["columns"][1]["column"] = "title";
735		row["columns"][1]["value"] = member->getTitle();
736		row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL";
737		row["columns"][1]["font"]["style"] = style;
738
739		std::string status = member->getOnlineStatus();
740		
741		row["columns"][2]["column"] = "status";
742		row["columns"][2]["value"] = status;
743		row["columns"][2]["font"]["name"] = "SANSSERIF_SMALL";
744		row["columns"][2]["font"]["style"] = style;
745
746		sSDTime += sd_timer.getElapsedTimeF32();
747
748		element_timer.reset();
749		LLScrollListItem* member_row = mListVisibleMembers->addElement(row);
750		
751		if ( member->isOwner() )
752		{
753			LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
754			if (name_textp)
755				name_textp->setFontStyle(LLFontGL::BOLD);
756		}
757		sElementTime += element_timer.getElapsedTimeF32();
758	}
759	sAllTime += all_timer.getElapsedTimeF32();
760
761	llinfos << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl;
762	if (mMemberProgress == gdatap->mMembers.end())
763	{
764		llinfos << "   member list completed." << llendl;
765		mListVisibleMembers->setEnabled(TRUE);
766
767		llinfos << "All Time: " << sAllTime << llendl;
768		llinfos << "SD Time: " << sSDTime << llendl;
769		llinfos << "Element Time: " << sElementTime << llendl;
770	}
771	else
772	{
773		mPendingMemberUpdate = TRUE;
774		mListVisibleMembers->setEnabled(FALSE);
775	}
776}
777
778void LLPanelGroupGeneral::updateChanged()
779{
780	// List all the controls we want to check for changes...
781	LLUICtrl *check_list[] =
782	{
783		mGroupNameEditor,
784		mFounderName,
785		mInsignia,
786		mEditCharter,
787		mCtrlShowInGroupList,
788		mComboMature,
789		mCtrlOpenEnrollment,
790		mCtrlEnrollmentFee,
791		mSpinEnrollmentFee,
792		mCtrlReceiveNotices,
793		mCtrlListGroup,
794		mActiveTitleLabel,
795		mComboActiveTitle
796	};
797
798	mChanged = FALSE;
799
800	for( size_t i=0; i<LL_ARRAY_SIZE(check_list); i++ )
801	{
802		if( check_list[i] && check_list[i]->isDirty() )
803		{
804			mChanged = TRUE;
805			break;
806		}
807	}
808}
809
810void LLPanelGroupGeneral::reset()
811{
812	mFounderName->setVisible(false);
813
814	
815	mCtrlReceiveNotices->set(false);
816	
817	
818	mCtrlListGroup->set(true);
819	
820	mCtrlReceiveNotices->setEnabled(false);
821	mCtrlReceiveNotices->setVisible(true);
822
823	mCtrlListGroup->setEnabled(false);
824
825	mGroupNameEditor->setEnabled(TRUE);
826	mEditCharter->setEnabled(TRUE);
827
828	mCtrlShowInGroupList->setEnabled(false);
829	mComboMature->setEnabled(TRUE);
830	
831	mCtrlOpenEnrollment->setEnabled(TRUE);
832	
833	mCtrlEnrollmentFee->setEnabled(TRUE);
834	
835	mSpinEnrollmentFee->setEnabled(TRUE);
836	mSpinEnrollmentFee->set((F32)0);
837
838	mGroupNameEditor->setVisible(true);
839
840	mComboActiveTitle->setVisible(false);
841
842	mInsignia->setImageAssetID(LLUUID::null);
843	
844	mInsignia->setEnabled(true);
845
846	mInsignia->setImageAssetName(mInsignia->getDefaultImageName());
847
848	{
849		std::string empty_str = "";
850		mEditCharter->setText(empty_str);
851		mGroupNameEditor->setText(empty_str);
852	}
853	
854	{
855		LLSD row;
856		row["columns"][0]["value"] = "no members yet";
857		row["columns"][0]["column"] = "name";
858
859		mListVisibleMembers->deleteAllItems();
860		mListVisibleMembers->setEnabled(FALSE);
861		mListVisibleMembers->addElement(row);
862	}
863
864
865	{
866		mComboMature->setEnabled(true);
867		mComboMature->setVisible( !gAgent.isTeen() );
868		mComboMature->selectFirstItem();
869	}
870
871
872	resetDirty();
873}
874
875void	LLPanelGroupGeneral::resetDirty()
876{
877	// List all the controls we want to check for changes...
878	LLUICtrl *check_list[] =
879	{
880		mGroupNameEditor,
881		mFounderName,
882		mInsignia,
883		mEditCharter,
884		mCtrlShowInGroupList,
885		mComboMature,
886		mCtrlOpenEnrollment,
887		mCtrlEnrollmentFee,
888		mSpinEnrollmentFee,
889		mCtrlReceiveNotices,
890		mCtrlListGroup,
891		mActiveTitleLabel,
892		mComboActiveTitle
893	};
894
895	for( size_t i=0; i<LL_ARRAY_SIZE(check_list); i++ )
896	{
897		if( check_list[i] )
898			check_list[i]->resetDirty() ;
899	}
900
901
902}
903
904void LLPanelGroupGeneral::setGroupID(const LLUUID& id)
905{
906	LLPanelGroupTab::setGroupID(id);
907
908	if(id == LLUUID::null)
909	{
910		reset();
911		return;
912	}
913
914	BOOL accept_notices = FALSE;
915	BOOL list_in_profile = FALSE;
916	LLGroupData data;
917	if(gAgent.getGroupData(mGroupID,data))
918	{
919		accept_notices = data.mAcceptNotices;
920		list_in_profile = data.mListInProfile;
921	}
922	mCtrlReceiveNotices = getChild<LLCheckBoxCtrl>("receive_notices");
923	if (mCtrlReceiveNotices)
924	{
925		mCtrlReceiveNotices->set(accept_notices);
926		mCtrlReceiveNotices->setEnabled(data.mID.notNull());
927	}
928	
929	mCtrlListGroup = getChild<LLCheckBoxCtrl>("list_groups_in_profile");
930	if (mCtrlListGroup)
931	{
932		mCtrlListGroup->set(list_in_profile);
933		mCtrlListGroup->setEnabled(data.mID.notNull());
934	}
935
936	mCtrlShowInGroupList->setEnabled(data.mID.notNull());
937
938	mActiveTitleLabel = getChild<LLTextBox>("active_title_label");
939	
940	mComboActiveTitle = getChild<LLComboBox>("active_title");
941
942	mFounderName->setVisible(true);
943
944	mInsignia->setImageAssetID(LLUUID::null);
945
946	resetDirty();
947
948	activate();
949}
950S32 LLPanelGroupGeneral::sortMembersList(S32 col_idx,const LLScrollListItem* i1,const LLScrollListItem* i2)
951{
952	const LLScrollListCell *cell1 = i1->getColumn(col_idx);
953	const LLScrollListCell *cell2 = i2->getColumn(col_idx);
954
955	if(col_idx == 2)
956	{
957		if(LLStringUtil::compareDict(cell1->getValue().asString(),"Online") == 0 )
958			return 1;
959		if(LLStringUtil::compareDict(cell2->getValue().asString(),"Online") == 0 )
960			return -1;
961	}
962
963	return LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
964}