PageRenderTime 76ms CodeModel.GetById 34ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llpanelgroup.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 625 lines | 467 code | 121 blank | 37 comment | 91 complexity | 2e6ef479ba7784547169e382ebbd5d0c MD5 | raw file
  1/** 
  2 * @file llpanelgroup.cpp
  3 *
  4 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  5 * Second Life Viewer Source Code
  6 * Copyright (C) 2010, Linden Research, Inc.
  7 * 
  8 * This library is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU Lesser General Public
 10 * License as published by the Free Software Foundation;
 11 * version 2.1 of the License only.
 12 * 
 13 * This library is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * Lesser General Public License for more details.
 17 * 
 18 * You should have received a copy of the GNU Lesser General Public
 19 * License along with this library; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 21 * 
 22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 23 * $/LicenseInfo$
 24 */
 25
 26#include "llviewerprecompiledheaders.h"
 27
 28#include "llpanelgroup.h"
 29
 30// Library includes
 31#include "llbutton.h"
 32#include "llfloatersidepanelcontainer.h"
 33#include "lltabcontainer.h"
 34#include "lltextbox.h"
 35#include "lluictrlfactory.h"
 36
 37// Viewer includes
 38#include "llviewermessage.h"
 39#include "llviewerwindow.h"
 40#include "llappviewer.h"
 41#include "llnotificationsutil.h"
 42#include "llfloaterreg.h"
 43#include "llfloater.h"
 44#include "llgroupactions.h"
 45
 46#include "llagent.h" 
 47
 48#include "llsidetraypanelcontainer.h"
 49
 50#include "llpanelgroupnotices.h"
 51#include "llpanelgroupgeneral.h"
 52
 53#include "llaccordionctrltab.h"
 54#include "llaccordionctrl.h"
 55
 56#include "lltrans.h"
 57
 58static LLRegisterPanelClassWrapper<LLPanelGroup> t_panel_group("panel_group_info_sidetray");
 59
 60
 61
 62LLPanelGroupTab::LLPanelGroupTab()
 63	: LLPanel(),
 64	  mAllowEdit(TRUE),
 65	  mHasModal(FALSE)
 66{
 67	mGroupID = LLUUID::null;
 68}
 69
 70LLPanelGroupTab::~LLPanelGroupTab()
 71{
 72}
 73
 74BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp)
 75{
 76	//default to being visible
 77	return TRUE;
 78}
 79
 80BOOL LLPanelGroupTab::postBuild()
 81{
 82	return TRUE;
 83}
 84
 85LLPanelGroup::LLPanelGroup()
 86:	LLPanel(),
 87	LLGroupMgrObserver( LLUUID() ),
 88	mSkipRefresh(FALSE),
 89	mButtonJoin(NULL)
 90{
 91	// Set up the factory callbacks.
 92	// Roles sub tabs
 93	LLGroupMgr::getInstance()->addObserver(this);
 94}
 95
 96
 97LLPanelGroup::~LLPanelGroup()
 98{
 99	LLGroupMgr::getInstance()->removeObserver(this);
100	if(LLVoiceClient::instanceExists())
101	{
102		LLVoiceClient::getInstance()->removeObserver(this);
103	}
104}
105
106void LLPanelGroup::onOpen(const LLSD& key)
107{
108	if(!key.has("group_id"))
109		return;
110	
111	LLUUID group_id = key["group_id"];
112	if(!key.has("action"))
113	{
114		setGroupID(group_id);
115		getChild<LLAccordionCtrl>("groups_accordion")->expandDefaultTab();
116		return;
117	}
118
119	std::string str_action = key["action"];
120
121	if(str_action == "refresh")
122	{
123		if(mID == group_id || group_id == LLUUID::null)
124			refreshData();
125	}
126	else if(str_action == "close")
127	{
128		onBackBtnClick();
129	}
130	else if(str_action == "create")
131	{
132		setGroupID(LLUUID::null);
133	}
134	else if(str_action == "refresh_notices")
135	{
136		LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
137		if(panel_notices)
138			panel_notices->refreshNotices();
139	}
140
141}
142
143BOOL LLPanelGroup::postBuild()
144{
145	mDefaultNeedsApplyMesg = getString("default_needs_apply_text");
146	mWantApplyMesg = getString("want_apply_text");
147
148	LLButton* button;
149
150	button = getChild<LLButton>("btn_apply");
151	button->setClickedCallback(onBtnApply, this);
152	button->setVisible(true);
153	button->setEnabled(false);
154
155	button = getChild<LLButton>("btn_call");
156	button->setClickedCallback(onBtnGroupCallClicked, this);
157
158	button = getChild<LLButton>("btn_chat");
159	button->setClickedCallback(onBtnGroupChatClicked, this);
160
161	button = getChild<LLButton>("btn_cancel");
162	button->setVisible(false);	button->setEnabled(true);
163
164	button = getChild<LLButton>("btn_refresh");
165	button->setClickedCallback(onBtnRefresh, this);
166
167	getChild<LLButton>("btn_create")->setVisible(false);
168
169	childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL);
170
171	childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL);
172	
173	childSetCommitCallback("btn_cancel",boost::bind(&LLPanelGroup::onBtnCancel,this),NULL);
174
175	LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel");
176	LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel");
177	LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
178	LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
179
180	if(panel_general)	mTabs.push_back(panel_general);
181	if(panel_roles)		mTabs.push_back(panel_roles);
182	if(panel_notices)	mTabs.push_back(panel_notices);
183	if(panel_land)		mTabs.push_back(panel_land);
184
185	if(panel_general)
186	{
187		panel_general->setupCtrls(this);
188		button = panel_general->getChild<LLButton>("btn_join");
189		button->setVisible(false);
190		button->setEnabled(true);
191		
192		mButtonJoin = button;
193		mButtonJoin->setCommitCallback(boost::bind(&LLPanelGroup::onBtnJoin,this));
194
195		mJoinText = panel_general->getChild<LLUICtrl>("join_cost_text");
196	}
197
198	LLVoiceClient::getInstance()->addObserver(this);
199	
200	return TRUE;
201}
202
203void LLPanelGroup::reposButton(const std::string& name)
204{
205	LLButton* button = findChild<LLButton>(name);
206	if(!button)
207		return;
208	LLRect btn_rect = button->getRect();
209	btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
210	button->setRect(btn_rect);
211}
212
213void LLPanelGroup::reposButtons()
214{
215	LLButton* button_refresh = findChild<LLButton>("btn_refresh");
216	LLButton* button_cancel = findChild<LLButton>("btn_cancel");
217
218	if(button_refresh && button_cancel && button_refresh->getVisible() && button_cancel->getVisible())
219	{
220		LLRect btn_refresh_rect = button_refresh->getRect();
221		LLRect btn_cancel_rect = button_cancel->getRect();
222		btn_refresh_rect.setLeftTopAndSize( btn_cancel_rect.mLeft + btn_cancel_rect.getWidth() + 2, 
223			btn_refresh_rect.getHeight() + 2, btn_refresh_rect.getWidth(), btn_refresh_rect.getHeight());
224		button_refresh->setRect(btn_refresh_rect);
225	}
226
227	reposButton("btn_apply");
228	reposButton("btn_create");
229	reposButton("btn_refresh");
230	reposButton("btn_cancel");
231	reposButton("btn_chat");
232	reposButton("btn_call");
233}
234
235void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
236{
237	LLPanel::reshape(width, height, called_from_parent );
238
239	reposButtons();
240}
241
242void LLPanelGroup::onBackBtnClick()
243{
244	LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
245	if(parent)
246	{
247		parent->openPreviousPanel();
248	}
249}
250
251
252void LLPanelGroup::onBtnCreate()
253{
254	LLPanelGroupGeneral* panel_general = findChild<LLPanelGroupGeneral>("group_general_tab_panel");
255	if(!panel_general)
256		return;
257	std::string apply_mesg;
258	if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
259		return;
260	if ( !apply_mesg.empty() )
261	{
262		LLSD args;
263		args["MESSAGE"] = apply_mesg;
264		LLNotificationsUtil::add("GenericAlert", args);
265	}
266}
267
268void LLPanelGroup::onBtnRefresh(void* user_data)
269{
270	LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
271	self->refreshData();
272}
273
274void LLPanelGroup::onBtnApply(void* user_data)
275{
276	LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
277	self->apply();
278}
279
280void LLPanelGroup::onBtnGroupCallClicked(void* user_data)
281{
282	LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
283	self->callGroup();
284}
285
286void LLPanelGroup::onBtnGroupChatClicked(void* user_data)
287{
288	LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
289	self->chatGroup();
290}
291
292void LLPanelGroup::onBtnJoin()
293{
294	lldebugs << "joining group: " << mID << llendl;
295	LLGroupActions::join(mID);
296}
297
298void LLPanelGroup::onBtnCancel()
299{
300	onBackBtnClick();
301}
302
303void LLPanelGroup::changed(LLGroupChange gc)
304{
305	for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
306		(*it)->update(gc);
307	update(gc);
308}
309
310// virtual
311void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, bool proximal)
312{
313	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
314	{
315		return;
316	}
317
318	childSetEnabled("btn_call", LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());
319}
320
321void LLPanelGroup::notifyObservers()
322{
323	changed(GC_ALL);
324}
325
326void LLPanelGroup::update(LLGroupChange gc)
327{
328	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
329	if(gdatap)
330	{
331		std::string group_name =  gdatap->mName.empty() ? LLTrans::getString("LoadingData") : gdatap->mName;
332		childSetValue("group_name", group_name);
333		childSetToolTip("group_name",group_name);
334		
335		LLGroupData agent_gdatap;
336		bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike();
337		bool join_btn_visible = !is_member && gdatap->mOpenEnrollment;
338		
339		mButtonJoin->setVisible(join_btn_visible);
340		mJoinText->setVisible(join_btn_visible);
341
342		if(join_btn_visible)
343		{
344			LLStringUtil::format_map_t string_args;
345			std::string fee_buff;
346			if(gdatap->mMembershipFee)
347			{
348				string_args["[AMOUNT]"] = llformat("%d", gdatap->mMembershipFee);
349				fee_buff = getString("group_join_btn", string_args);
350				
351			}
352			else
353			{
354				fee_buff = getString("group_join_free", string_args);
355			}
356			mJoinText->setValue(fee_buff);
357		}
358	}
359}
360
361void LLPanelGroup::setGroupID(const LLUUID& group_id)
362{
363	std::string str_group_id;
364	group_id.toString(str_group_id);
365
366	bool is_same_id = group_id == mID;
367	
368	LLGroupMgr::getInstance()->removeObserver(this);
369	mID = group_id;
370	LLGroupMgr::getInstance()->addObserver(this);
371
372	for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
373		(*it)->setGroupID(group_id);
374
375	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
376	if(gdatap)
377	{
378		std::string group_name =  gdatap->mName.empty() ? LLTrans::getString("LoadingData") : gdatap->mName;
379		childSetValue("group_name", group_name);
380		childSetToolTip("group_name",group_name);
381	}
382
383	LLButton* button_apply = findChild<LLButton>("btn_apply");
384	LLButton* button_refresh = findChild<LLButton>("btn_refresh");
385	LLButton* button_create = findChild<LLButton>("btn_create");
386	
387	LLButton* button_cancel = findChild<LLButton>("btn_cancel");
388	LLButton* button_call = findChild<LLButton>("btn_call");
389	LLButton* button_chat = findChild<LLButton>("btn_chat");
390
391
392	bool is_null_group_id = group_id == LLUUID::null;
393	if(button_apply)
394		button_apply->setVisible(!is_null_group_id);
395	if(button_refresh)
396		button_refresh->setVisible(!is_null_group_id);
397
398	if(button_create)
399		button_create->setVisible(is_null_group_id);
400	if(button_cancel)
401		button_cancel->setVisible(!is_null_group_id);
402
403	if(button_call)
404			button_call->setVisible(!is_null_group_id);
405	if(button_chat)
406			button_chat->setVisible(!is_null_group_id);
407
408	getChild<LLUICtrl>("prepend_founded_by")->setVisible(!is_null_group_id);
409
410	LLAccordionCtrl* tab_ctrl = getChild<LLAccordionCtrl>("groups_accordion");
411	tab_ctrl->reset();
412
413	LLAccordionCtrlTab* tab_general = getChild<LLAccordionCtrlTab>("group_general_tab");
414	LLAccordionCtrlTab* tab_roles = getChild<LLAccordionCtrlTab>("group_roles_tab");
415	LLAccordionCtrlTab* tab_notices = getChild<LLAccordionCtrlTab>("group_notices_tab");
416	LLAccordionCtrlTab* tab_land = getChild<LLAccordionCtrlTab>("group_land_tab");
417
418	if(mButtonJoin)
419		mButtonJoin->setVisible(false);
420
421
422	if(is_null_group_id)//creating new group
423	{
424		if(!tab_general->getDisplayChildren())
425			tab_general->changeOpenClose(tab_general->getDisplayChildren());
426		
427		if(tab_roles->getDisplayChildren())
428			tab_roles->changeOpenClose(tab_roles->getDisplayChildren());
429		if(tab_notices->getDisplayChildren())
430			tab_notices->changeOpenClose(tab_notices->getDisplayChildren());
431		if(tab_land->getDisplayChildren())
432			tab_land->changeOpenClose(tab_land->getDisplayChildren());
433
434		tab_roles->setVisible(false);
435		tab_notices->setVisible(false);
436		tab_land->setVisible(false);
437
438		getChild<LLUICtrl>("group_name")->setVisible(false);
439		getChild<LLUICtrl>("group_name_editor")->setVisible(true);
440
441		if(button_call)
442			button_call->setVisible(false);
443		if(button_chat)
444			button_chat->setVisible(false);
445	}
446	else 
447	{
448		if(!is_same_id)
449		{
450			if(!tab_general->getDisplayChildren())
451				tab_general->changeOpenClose(tab_general->getDisplayChildren());
452			if(tab_roles->getDisplayChildren())
453				tab_roles->changeOpenClose(tab_roles->getDisplayChildren());
454			if(tab_notices->getDisplayChildren())
455				tab_notices->changeOpenClose(tab_notices->getDisplayChildren());
456			if(tab_land->getDisplayChildren())
457				tab_land->changeOpenClose(tab_land->getDisplayChildren());
458		}
459
460		LLGroupData agent_gdatap;
461		bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike();
462		
463		tab_roles->setVisible(is_member);
464		tab_notices->setVisible(is_member);
465		tab_land->setVisible(is_member);
466
467		getChild<LLUICtrl>("group_name")->setVisible(true);
468		getChild<LLUICtrl>("group_name_editor")->setVisible(false);
469
470		if(button_apply)
471			button_apply->setVisible(is_member);
472		if(button_call)
473			button_call->setVisible(is_member);
474		if(button_chat)
475			button_chat->setVisible(is_member);
476	}
477
478	tab_ctrl->arrange();
479
480	reposButtons();
481	update(GC_ALL);//show/hide "join" button if data is already ready
482}
483
484bool LLPanelGroup::apply(LLPanelGroupTab* tab)
485{
486	if(!tab)
487		return false;
488
489	std::string mesg;
490	if ( !tab->needsApply(mesg) )
491		return true;
492	
493	std::string apply_mesg;
494	if(tab->apply( apply_mesg ) )
495	{
496		//we skip refreshing group after ew manually apply changes since its very annoying
497		//for those who are editing group
498		mSkipRefresh = TRUE;
499		return true;
500	}
501		
502	if ( !apply_mesg.empty() )
503	{
504		LLSD args;
505		args["MESSAGE"] = apply_mesg;
506		LLNotificationsUtil::add("GenericAlert", args);
507	}
508	return false;
509}
510
511bool LLPanelGroup::apply()
512{
513	return apply(findChild<LLPanelGroupTab>("group_general_tab_panel")) 
514		&& apply(findChild<LLPanelGroupTab>("group_roles_tab_panel"))
515		&& apply(findChild<LLPanelGroupTab>("group_notices_tab_panel"))
516		&& apply(findChild<LLPanelGroupTab>("group_land_tab_panel"))
517		;
518}
519
520
521// virtual
522void LLPanelGroup::draw()
523{
524	LLPanel::draw();
525
526	if (mRefreshTimer.hasExpired())
527	{
528		mRefreshTimer.stop();
529		childEnable("btn_refresh");
530		childEnable("groups_accordion");
531	}
532
533	LLButton* button_apply = findChild<LLButton>("btn_apply");
534	
535	if(button_apply && button_apply->getVisible())
536	{
537		bool enable = false;
538		std::string mesg;
539		for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
540			enable = enable || (*it)->needsApply(mesg);
541
542		childSetEnabled("btn_apply", enable);
543	}
544}
545
546void LLPanelGroup::refreshData()
547{
548	if(mSkipRefresh)
549	{
550		mSkipRefresh = FALSE;
551		return;
552	}
553	LLGroupMgr::getInstance()->clearGroupData(getID());
554
555	setGroupID(getID());
556	
557	// 5 second timeout
558	childDisable("btn_refresh");
559	childDisable("groups_accordion");
560
561	mRefreshTimer.start();
562	mRefreshTimer.setTimerExpirySec(5);
563}
564
565void LLPanelGroup::callGroup()
566{
567	LLGroupActions::startCall(getID());
568}
569
570void LLPanelGroup::chatGroup()
571{
572	LLGroupActions::startIM(getID());
573}
574
575void LLPanelGroup::showNotice(const std::string& subject,
576			      const std::string& message,
577			      const bool& has_inventory,
578			      const std::string& inventory_name,
579			      LLOfferInfo* inventory_offer)
580{
581	LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
582	if(!panel_notices)
583	{
584		// We need to clean up that inventory offer.
585		if (inventory_offer)
586		{
587			inventory_offer->forceResponse(IOR_DECLINE);
588		}
589		return;
590	}
591	panel_notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
592}
593
594
595
596
597//static
598void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id)
599{
600	LLPanelGroup* panel = LLFloaterSidePanelContainer::getPanel<LLPanelGroup>("people", "panel_group_info_sidetray");
601	if(!panel)
602		return;
603	panel->setGroupID(group_id);
604}
605
606//static
607
608void LLPanelGroup::showNotice(const std::string& subject,
609					   const std::string& message,
610					   const LLUUID& group_id,
611					   const bool& has_inventory,
612					   const std::string& inventory_name,
613					   LLOfferInfo* inventory_offer)
614{
615	LLPanelGroup* panel = LLFloaterSidePanelContainer::getPanel<LLPanelGroup>("people", "panel_group_info_sidetray");
616	if(!panel)
617		return;
618
619	if(panel->getID() != group_id)//???? only for current group_id or switch panels? FIXME
620		return;
621	panel->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
622
623}
624
625