PageRenderTime 507ms CodeModel.GetById 165ms app.highlight 145ms RepoModel.GetById 193ms app.codeStats 0ms

/indra/newview/llinspectgroup.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 322 lines | 192 code | 48 blank | 82 comment | 14 complexity | c69f73ab13146580ea0bf8fa2e224228 MD5 | raw file
  1/** 
  2 * @file llinspectgroup.cpp
  3 *
  4 * $LicenseInfo:firstyear=2009&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 "llinspectgroup.h"
 29
 30// viewer files
 31#include "llgroupactions.h"
 32#include "llgroupmgr.h"
 33#include "llinspect.h"
 34#include "llstartup.h"
 35
 36// Linden libraries
 37#include "llcontrol.h"	// LLCachedControl
 38#include "llfloater.h"
 39#include "llfloaterreg.h"
 40#include "llresmgr.h"	// getMonetaryString()
 41#include "lltooltip.h"	// positionViewNearMouse()
 42#include "lltrans.h"
 43#include "lluictrl.h"
 44
 45class LLFetchGroupData;
 46
 47
 48//////////////////////////////////////////////////////////////////////////////
 49// LLInspectGroup
 50//////////////////////////////////////////////////////////////////////////////
 51
 52/// Group Inspector, a small information window used when clicking
 53/// on group names in the 2D UI
 54class LLInspectGroup : public LLInspect
 55{
 56	friend class LLFloaterReg;
 57	
 58public:
 59	// key["group_id"] - Group ID for which to show information
 60	// Inspector will be positioned relative to current mouse position
 61	LLInspectGroup(const LLSD& key);
 62	virtual ~LLInspectGroup();
 63	
 64	// Because floater is single instance, need to re-parse data on each spawn
 65	// (for example, inspector about same group but in different position)
 66	/*virtual*/ void onOpen(const LLSD& group_id);
 67
 68	// When closing they should close their gear menu 
 69	/*virtual*/ void onClose(bool app_quitting);
 70	
 71	// Update view based on information from group manager
 72	void processGroupData();
 73	
 74	// Make network requests for all the data to display in this view.
 75	// Used on construction and if avatar id changes.
 76	void requestUpdate();
 77		
 78	// Callback for gCacheName to look up group name
 79	// Faster than waiting for group properties to return
 80	void nameUpdatedCallback(const LLUUID& id,
 81							 const std::string& name,
 82							 bool is_group);
 83
 84	// Button/menu callbacks
 85	void onClickViewProfile();
 86	void onClickJoin();
 87	void onClickLeave();
 88	
 89private:
 90	LLUUID				mGroupID;
 91	// an in-flight network request for group properties 
 92	// is represented by this object
 93	LLFetchGroupData*	mPropertiesRequest;
 94};
 95
 96//////////////////////////////////////////////////////////////////////////////
 97// LLFetchGroupData
 98//////////////////////////////////////////////////////////////////////////////
 99
100// This object represents a pending request for avatar properties information
101class LLFetchGroupData : public LLGroupMgrObserver
102{
103public:
104	// If the inspector closes it will delete the pending request object, so the
105	// inspector pointer will be valid for the lifetime of this object
106	LLFetchGroupData(const LLUUID& group_id, LLInspectGroup* inspector)
107	:	LLGroupMgrObserver(group_id),
108		mInspector(inspector)
109	{
110		LLGroupMgr* mgr = LLGroupMgr::getInstance();
111		// register ourselves as an observer
112		mgr->addObserver(this);
113		// send a request
114		mgr->sendGroupPropertiesRequest(group_id);
115	}
116	
117	~LLFetchGroupData()
118	{
119		// remove ourselves as an observer
120		LLGroupMgr::getInstance()->removeObserver(this);
121	}
122	
123	void changed(LLGroupChange gc)
124	{
125		if (gc == GC_PROPERTIES)
126		{
127			mInspector->processGroupData();
128		}
129	}
130	
131	LLInspectGroup* mInspector;
132};
133
134LLInspectGroup::LLInspectGroup(const LLSD& sd)
135:	LLInspect( LLSD() ),	// single_instance, doesn't really need key
136	mGroupID(),			// set in onOpen()
137	mPropertiesRequest(NULL)
138{
139	mCommitCallbackRegistrar.add("InspectGroup.ViewProfile",
140		boost::bind(&LLInspectGroup::onClickViewProfile, this));
141	mCommitCallbackRegistrar.add("InspectGroup.Join",
142		boost::bind(&LLInspectGroup::onClickJoin, this));	
143	mCommitCallbackRegistrar.add("InspectGroup.Leave",
144		boost::bind(&LLInspectGroup::onClickLeave, this));	
145
146	// can't make the properties request until the widgets are constructed
147	// as it might return immediately, so do it in postBuild.
148}
149
150LLInspectGroup::~LLInspectGroup()
151{
152	// clean up any pending requests so they don't call back into a deleted
153	// view
154	delete mPropertiesRequest;
155	mPropertiesRequest = NULL;
156}
157
158
159// Multiple calls to showInstance("inspect_avatar", foo) will provide different
160// LLSD for foo, which we will catch here.
161//virtual
162void LLInspectGroup::onOpen(const LLSD& data)
163{
164	// start fade animation
165	LLInspect::onOpen(data);
166
167	mGroupID = data["group_id"];
168
169	// Position the inspector relative to the mouse cursor
170	// Similar to how tooltips are positioned
171	// See LLToolTipMgr::createToolTip
172	if (data.has("pos"))
173	{
174		LLUI::positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
175	}
176	else
177	{
178		LLUI::positionViewNearMouse(this);
179	}
180
181	// can't call from constructor as widgets are not built yet
182	requestUpdate();
183}
184
185// virtual
186void LLInspectGroup::onClose(bool app_quitting)
187{
188	// *TODO: If we add a gear menu, close it here
189}	
190
191void LLInspectGroup::requestUpdate()
192{
193	// Don't make network requests when spawning from the debug menu at the
194	// login screen (which is useful to work on the layout).
195	if (mGroupID.isNull())
196	{
197		if (LLStartUp::getStartupState() >= STATE_STARTED)
198		{
199			// once we're running we don't want to show the test floater
200			// for bogus LLUUID::null links
201			closeFloater();
202		}
203		return;
204	}
205
206	// Clear out old data so it doesn't flash between old and new
207	getChild<LLUICtrl>("group_name")->setValue("");
208	getChild<LLUICtrl>("group_subtitle")->setValue("");
209	getChild<LLUICtrl>("group_details")->setValue("");
210	getChild<LLUICtrl>("group_cost")->setValue("");
211	// Must have a visible button so the inspector can take focus
212	getChild<LLUICtrl>("view_profile_btn")->setVisible(true);
213	getChild<LLUICtrl>("leave_btn")->setVisible(false);
214	getChild<LLUICtrl>("join_btn")->setVisible(false);
215	
216	// Make a new request for properties
217	delete mPropertiesRequest;
218	mPropertiesRequest = new LLFetchGroupData(mGroupID, this);
219
220	// Name lookup will be faster out of cache, use that
221	gCacheName->getGroup(mGroupID,
222		boost::bind(&LLInspectGroup::nameUpdatedCallback,
223			this, _1, _2, _3));
224}
225
226void LLInspectGroup::nameUpdatedCallback(
227	const LLUUID& id,
228	const std::string& name,
229	bool is_group)
230{
231	if (id == mGroupID)
232	{
233		getChild<LLUICtrl>("group_name")->setValue( LLSD(name) );
234	}
235	
236	// Otherwise possibly a request for an older inspector, ignore it
237}
238
239void LLInspectGroup::processGroupData()
240{
241	LLGroupMgrGroupData* data =
242		LLGroupMgr::getInstance()->getGroupData(mGroupID);
243
244	if (data)
245	{
246		// Noun pluralization depends on language
247		std::string lang = LLUI::getLanguage();
248		std::string members =
249			LLTrans::getCountString(lang, "GroupMembers", data->mMemberCount);
250		getChild<LLUICtrl>("group_subtitle")->setValue( LLSD(members) );
251
252		getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) );
253
254		getChild<LLUICtrl>("group_icon")->setValue( LLSD(data->mInsigniaID) );
255
256		std::string cost;
257		bool is_member = LLGroupActions::isInGroup(mGroupID);
258		if (is_member)
259		{
260			cost = getString("YouAreMember");
261		}
262		else if (data->mOpenEnrollment)
263		{
264			if (data->mMembershipFee == 0)
265			{
266				cost = getString("FreeToJoin");
267			}
268			else
269			{
270				std::string amount =
271					LLResMgr::getInstance()->getMonetaryString(
272						data->mMembershipFee);
273				LLStringUtil::format_map_t args;
274				args["[AMOUNT]"] = amount;
275				cost = getString("CostToJoin", args);
276			}
277		}
278		else
279		{
280			cost = getString("PrivateGroup");
281		}
282		getChild<LLUICtrl>("group_cost")->setValue(cost);
283
284		getChild<LLUICtrl>("join_btn")->setVisible(!is_member);
285		getChild<LLUICtrl>("leave_btn")->setVisible(is_member);
286
287		// Only enable join button if you are allowed to join
288		bool can_join = !is_member && data->mOpenEnrollment;
289		getChild<LLUICtrl>("join_btn")->setEnabled(can_join);
290	}
291
292	// Delete the request object as it has been satisfied
293	delete mPropertiesRequest;
294	mPropertiesRequest = NULL;
295}
296
297void LLInspectGroup::onClickViewProfile()
298{
299	closeFloater();
300	LLGroupActions::show(mGroupID);
301}
302
303void LLInspectGroup::onClickJoin()
304{
305	closeFloater();
306	LLGroupActions::join(mGroupID);
307}
308
309void LLInspectGroup::onClickLeave()
310{
311	closeFloater();
312	LLGroupActions::leave(mGroupID);
313}
314
315//////////////////////////////////////////////////////////////////////////////
316// LLInspectGroupUtil
317//////////////////////////////////////////////////////////////////////////////
318void LLInspectGroupUtil::registerFloater()
319{
320	LLFloaterReg::add("inspect_group", "inspect_group.xml",
321					  &LLFloaterReg::build<LLInspectGroup>);
322}