diff options
| author | James Cook <james@lindenlab.com> | 2009-10-16 23:20:05 +0000 | 
|---|---|---|
| committer | James Cook <james@lindenlab.com> | 2009-10-16 23:20:05 +0000 | 
| commit | a4c657a49dd055cdc773c95b04713f403ea9c44c (patch) | |
| tree | ab4731917d9d330c636773d4ce5015f59dd070a4 | |
| parent | e3c4b5ad26e6c4583fc2a736aea1370cc06ac6b2 (diff) | |
Group inspectors now work.  They are hooked up to About Land, build tools floater, and anywhere secondlife:///app/group URLs appear.  Reviewed with Leyla.
| -rw-r--r-- | indra/llui/llurlentry.cpp | 3 | ||||
| -rw-r--r-- | indra/llui/tests/llurlentry_test.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterland.cpp | 22 | ||||
| -rw-r--r-- | indra/newview/llgroupactions.cpp | 66 | ||||
| -rw-r--r-- | indra/newview/llgroupactions.h | 7 | ||||
| -rw-r--r-- | indra/newview/llgroupmgr.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llinspectgroup.cpp | 367 | ||||
| -rw-r--r-- | indra/newview/llinspectgroup.h | 41 | ||||
| -rw-r--r-- | indra/newview/llpanelgroup.cpp | 46 | ||||
| -rw-r--r-- | indra/newview/llpanelgroup.h | 2 | ||||
| -rw-r--r-- | indra/newview/llselectmgr.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llviewerfloaterreg.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_test_inspectors.xml | 30 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/inspect_group.xml | 106 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 4 | 
16 files changed, 649 insertions, 65 deletions
| diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index c1da73fa83..e04ccfbc2f 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -302,10 +302,11 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa  //  // LLUrlEntryGroup Describes a Second Life group Url, e.g.,  // secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about +// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect  //  LLUrlEntryGroup::LLUrlEntryGroup()  { -	mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/about", +	mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/\\w+",  							boost::regex::perl|boost::regex::icase);  	mMenuName = "menu_url_group.xml";  	mIcon = "Generic_Group"; diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 468fae2ec5..128cd134c1 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -308,6 +308,10 @@ namespace tut  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about",  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about"); +		testRegex("Group Url ", r, +				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect", +				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect"); +  		testRegex("Group Url in text", r,  				  "XXX secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about XXX",  				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about"); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 37acdc3cef..c630a56c8d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -240,6 +240,7 @@ set(viewer_SOURCE_FILES      llimview.cpp      llimcontrolpanel.cpp      llinspectavatar.cpp +    llinspectgroup.cpp      llinspectobject.cpp      llinventorybridge.cpp      llinventoryclipboard.cpp @@ -709,6 +710,7 @@ set(viewer_HEADER_FILES      llimview.h      llimcontrolpanel.h      llinspectavatar.h +    llinspectgroup.h      llinspectobject.h      llinventorybridge.h      llinventoryclipboard.h diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index c1031ee437..488d71aa70 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -744,6 +744,7 @@ void LLPanelLandGeneral::refreshNames()  	if (!parcel)  	{  		mTextOwner->setText(LLStringUtil::null); +		mTextGroup->setText(LLStringUtil::null);  		return;  	} @@ -764,6 +765,13 @@ void LLPanelLandGeneral::refreshNames()  	}  	mTextOwner->setText(owner); +	std::string group; +	if (!parcel->getGroupID().isNull()) +	{ +		group = LLSLURL::buildCommand("group", parcel->getGroupID(), "inspect"); +	} +	mTextGroup->setText(group); +  	const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();  	if(auth_buyer_id.notNull())  	{ @@ -781,20 +789,6 @@ void LLPanelLandGeneral::refreshNames()  // virtual  void LLPanelLandGeneral::draw()  { -	LLParcel *parcel = mParcel->getParcel(); -	if (parcel) -	{ -		std::string group; -		if (!parcel->getGroupID().isNull()) -		{ -			// *TODO: Change to "inspect" when we have group inspectors and -			// move into refreshNames() above -			// group = LLSLURL::buildCommand("group", parcel->getGroupID(), "inspect"); -			gCacheName->getGroupName(parcel->getGroupID(), group); -		} -		mTextGroup->setText(group); -	} -  	LLPanel::draw();  } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index d1cbe96906..220fb3c8a0 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -35,13 +35,14 @@  #include "llgroupactions.h" +// Viewer includes  #include "llagent.h" +#include "llcommandhandler.h"  #include "llfloaterreg.h"  #include "llgroupmgr.h"  #include "llimview.h" // for gIMMgr  #include "llsidetray.h" - -#include "llcommandhandler.h" +#include "llstatusbar.h"	// can_afford_transaction()  //  // Globals @@ -96,6 +97,13 @@ public:  			return true;  		} +		if (tokens[1].asString() == "inspect") +		{ +			LLSD key; +			key["group_id"] = group_id; +			LLFloaterReg::showInstance("inspect_group", key); +			return true; +		}  		return false;  	}  }; @@ -108,6 +116,52 @@ void LLGroupActions::search()  }  // static +void LLGroupActions::join(const LLUUID& group_id) +{ +	LLGroupMgrGroupData* gdatap =  +		LLGroupMgr::getInstance()->getGroupData(group_id); + +	if (gdatap) +	{ +		S32 cost = gdatap->mMembershipFee; +		LLSD args; +		args["COST"] = llformat("%d", cost); +		LLSD payload; +		payload["group_id"] = group_id; + +		if (can_afford_transaction(cost)) +		{ +			LLNotifications::instance().add("JoinGroupCanAfford", args, payload, onJoinGroup); +		} +		else +		{ +			LLNotifications::instance().add("JoinGroupCannotAfford", args, payload); +		} +	} +	else +	{ +		llwarns << "LLGroupMgr::getInstance()->getGroupData(" << group_id  +			<< ") was NULL" << llendl; +	} +} + +// static +bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotification::getSelectedOption(notification, response); + +	if (option == 1) +	{ +		// user clicked cancel +		return false; +	} + +	LLGroupMgr::getInstance()-> +		sendGroupMemberJoin(notification["payload"]["group_id"].asUUID()); +	return false; +} + +// static  void LLGroupActions::leave(const LLUUID& group_id)  {  	if (group_id.isNull()) @@ -240,6 +294,14 @@ void LLGroupActions::startChat(const LLUUID& group_id)  }  // static +bool LLGroupActions::isInGroup(const LLUUID& group_id) +{ +	// *TODO: Move all the LLAgent group stuff into another class, such as +	// this one. +	return gAgent.isInGroup(group_id); +} + +// static  bool LLGroupActions::isAvatarMemberOfGroup(const LLUUID& group_id, const LLUUID& avatar_id)  {  	if(group_id.isNull() || avatar_id.isNull()) diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index 9fe1da8af2..74c84d1561 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -47,6 +47,9 @@ public:  	 */  	static void search(); +	/// Join a group.  Assumes LLGroupMgr has data for that group already. +	static void join(const LLUUID& group_id); +  	/**  	 * Invokes "Leave Group" floater.  	 */ @@ -87,6 +90,9 @@ public:  	 */  	static void startChat(const LLUUID& group_id); +	/// Returns if the current user is a member of the group +	static bool isInGroup(const LLUUID& group_id); +  	/**  	 * Returns true if avatar is in group.  	 * @@ -97,6 +103,7 @@ public:  	static bool isAvatarMemberOfGroup(const LLUUID& group_id, const LLUUID& avatar_id);  private: +	static bool onJoinGroup(const LLSD& notification, const LLSD& response);  	static bool onLeaveGroup(const LLSD& notification, const LLSD& response);  }; diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 5e50fad008..01d0f2296a 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -1325,11 +1325,16 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc)  {  	for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi)  	{ +		LLUUID group_id = gi->first;  		if (gi->second->mChanged)  		{ +			// Copy the map because observers may remove themselves on update +			observer_multimap_t observers = mObservers; +  			// find all observers for this group id -			observer_multimap_t::iterator oi = mObservers.find(gi->first); -			for (; oi != mObservers.end(); ++oi) +			observer_multimap_t::iterator oi = observers.lower_bound(group_id); +			observer_multimap_t::iterator end = observers.upper_bound(group_id); +			for (; oi != end; ++oi)  			{  				oi->second->changed(gc);  			} diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp new file mode 100644 index 0000000000..184d413743 --- /dev/null +++ b/indra/newview/llinspectgroup.cpp @@ -0,0 +1,367 @@ +/**  + * @file llinspectgroup.cpp + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 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 "llinspectgroup.h" + +// viewer files +#include "llgroupactions.h" +#include "llgroupmgr.h" + +// Linden libraries +#include "llcontrol.h"	// LLCachedControl +#include "llfloater.h" +#include "llfloaterreg.h" +#include "llresmgr.h"	// getMonetaryString() +#include "lltooltip.h"	// positionViewNearMouse() +#include "lltrans.h" +#include "lluictrl.h" + +class LLFetchGroupData; + + +////////////////////////////////////////////////////////////////////////////// +// LLInspectGroup +////////////////////////////////////////////////////////////////////////////// + +/// Group Inspector, a small information window used when clicking +/// on group names in the 2D UI +class LLInspectGroup : public LLFloater +{ +	friend class LLFloaterReg; +	 +public: +	// key["group_id"] - Group ID for which to show information +	// Inspector will be positioned relative to current mouse position +	LLInspectGroup(const LLSD& key); +	virtual ~LLInspectGroup(); +	 +	/*virtual*/ void draw(); +	 +	// Because floater is single instance, need to re-parse data on each spawn +	// (for example, inspector about same group but in different position) +	/*virtual*/ void onOpen(const LLSD& group_id); + +	// When closing they should close their gear menu  +	/*virtual*/ void onClose(bool app_quitting); +	 +	// Inspectors close themselves when they lose focus +	/*virtual*/ void onFocusLost(); +	 +	// Update view based on information from group manager +	void processGroupData(); +	 +	// Make network requests for all the data to display in this view. +	// Used on construction and if avatar id changes. +	void requestUpdate(); +		 +	// Callback for gCacheName to look up group name +	// Faster than waiting for group properties to return +	void nameUpdatedCallback(const LLUUID& id, +							 const std::string& first, +							 const std::string& last, +							 BOOL is_group); + +	// Button/menu callbacks +	void onClickViewProfile(); +	void onClickJoin(); +	void onClickLeave(); +	 +private: +	LLUUID				mGroupID; +	// an in-flight network request for group properties  +	// is represented by this object +	LLFetchGroupData*	mPropertiesRequest; +	LLFrameTimer		mCloseTimer; +	LLFrameTimer		mOpenTimer; +}; + +////////////////////////////////////////////////////////////////////////////// +// LLFetchGroupData +////////////////////////////////////////////////////////////////////////////// + +// This object represents a pending request for avatar properties information +class LLFetchGroupData : public LLGroupMgrObserver +{ +public: +	// If the inspector closes it will delete the pending request object, so the +	// inspector pointer will be valid for the lifetime of this object +	LLFetchGroupData(const LLUUID& group_id, LLInspectGroup* inspector) +	:	LLGroupMgrObserver(group_id), +		mInspector(inspector) +	{ +		LLGroupMgr* mgr = LLGroupMgr::getInstance(); +		// register ourselves as an observer +		mgr->addObserver(this); +		// send a request +		mgr->sendGroupPropertiesRequest(group_id); +	} +	 +	~LLFetchGroupData() +	{ +		// remove ourselves as an observer +		LLGroupMgr::getInstance()->removeObserver(this); +	} +	 +	void changed(LLGroupChange gc) +	{ +		if (gc == GC_PROPERTIES) +		{ +			mInspector->processGroupData(); +		} +	} +	 +	LLInspectGroup* mInspector; +}; + +LLInspectGroup::LLInspectGroup(const LLSD& sd) +:	LLFloater( LLSD() ),	// single_instance, doesn't really need key +	mGroupID(),			// set in onOpen() +	mPropertiesRequest(NULL), +	mCloseTimer() +{ +	mCommitCallbackRegistrar.add("InspectGroup.ViewProfile", +		boost::bind(&LLInspectGroup::onClickViewProfile, this)); +	mCommitCallbackRegistrar.add("InspectGroup.Join", +		boost::bind(&LLInspectGroup::onClickJoin, this));	 +	mCommitCallbackRegistrar.add("InspectGroup.Leave", +		boost::bind(&LLInspectGroup::onClickLeave, this));	 + +	// can't make the properties request until the widgets are constructed +	// as it might return immediately, so do it in postBuild. +} + +LLInspectGroup::~LLInspectGroup() +{ +	// clean up any pending requests so they don't call back into a deleted +	// view +	delete mPropertiesRequest; +	mPropertiesRequest = NULL; +} + +void LLInspectGroup::draw() +{ +	static LLCachedControl<F32> FADE_TIME(*LLUI::sSettingGroups["config"], "InspectorFadeTime", 1.f); +	if (mOpenTimer.getStarted()) +	{ +		F32 alpha = clamp_rescale(mOpenTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 0.f, 1.f); +		LLViewDrawContext context(alpha); +		LLFloater::draw(); +		if (alpha == 1.f) +		{ +			mOpenTimer.stop(); +		} + +	} +	else if (mCloseTimer.getStarted()) +	{ +		F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 1.f, 0.f); +		LLViewDrawContext context(alpha); +		LLFloater::draw(); +		if (mCloseTimer.getElapsedTimeF32() > FADE_TIME) +		{ +			closeFloater(false); +		} +	} +	else +	{ +		LLFloater::draw(); +	} +} + + +// Multiple calls to showInstance("inspect_avatar", foo) will provide different +// LLSD for foo, which we will catch here. +//virtual +void LLInspectGroup::onOpen(const LLSD& data) +{ +	mCloseTimer.stop(); +	mOpenTimer.start(); + +	mGroupID = data["group_id"]; + +	// Position the inspector relative to the mouse cursor +	// Similar to how tooltips are positioned +	// See LLToolTipMgr::createToolTip +	if (data.has("pos")) +	{ +		LLUI::positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger()); +	} +	else +	{ +		LLUI::positionViewNearMouse(this); +	} + +	// can't call from constructor as widgets are not built yet +	requestUpdate(); +} + +// virtual +void LLInspectGroup::onClose(bool app_quitting) +{   +}	 + +//virtual +void LLInspectGroup::onFocusLost() +{ +	// Start closing when we lose focus +	mCloseTimer.start(); +	mOpenTimer.stop(); +} + +void LLInspectGroup::requestUpdate() +{ +	// Don't make network requests when spawning from the debug menu at the +	// login screen (which is useful to work on the layout). +	if (mGroupID.isNull()) +	{ +		return; +	} + +	// Clear out old data so it doesn't flash between old and new +	getChild<LLUICtrl>("group_name")->setValue(""); +	getChild<LLUICtrl>("group_subtitle")->setValue(""); +	getChild<LLUICtrl>("group_details")->setValue(""); +	getChild<LLUICtrl>("group_cost")->setValue(""); +	// Must have a visible button so the inspector can take focus +	getChild<LLUICtrl>("leave_btn")->setVisible(true); +	getChild<LLUICtrl>("join_btn")->setVisible(false); +	 +	// Make a new request for properties +	delete mPropertiesRequest; +	mPropertiesRequest = new LLFetchGroupData(mGroupID, this); + +	// Name lookup will be faster out of cache, use that +	gCacheName->get(mGroupID, TRUE, +		boost::bind(&LLInspectGroup::nameUpdatedCallback, +			this, _1, _2, _3, _4)); +} + +void LLInspectGroup::nameUpdatedCallback( +	const LLUUID& id, +	const std::string& first, +	const std::string& last, +	BOOL is_group) +{ +	if (id == mGroupID) +	{ +		// group names are returned as a first name +		childSetValue("group_name", LLSD(first) ); +	} +	 +	// Otherwise possibly a request for an older inspector, ignore it +} + +void LLInspectGroup::processGroupData() +{ +	LLGroupMgrGroupData* data = +		LLGroupMgr::getInstance()->getGroupData(mGroupID); + +	if (data) +	{ +		// Noun pluralization depends on language +		std::string lang = LLUI::getLanguage(); +		std::string members = +			LLTrans::getCountString(lang, "GroupMembers", data->mMemberCount); +		getChild<LLUICtrl>("group_subtitle")->setValue( LLSD(members) ); + +		getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) ); + +		getChild<LLUICtrl>("group_icon")->setValue( LLSD(data->mInsigniaID) ); + +		std::string cost; +		bool is_member = LLGroupActions::isInGroup(mGroupID); +		if (is_member) +		{ +			cost = getString("YouAreMember"); +		} +		else if (data->mOpenEnrollment) +		{ +			if (data->mMembershipFee == 0) +			{ +				cost = getString("FreeToJoin"); +			} +			else +			{ +				std::string amount = +					LLResMgr::getInstance()->getMonetaryString( +						data->mMembershipFee); +				LLStringUtil::format_map_t args; +				args["[AMOUNT]"] = amount; +				cost = getString("CostToJoin", args); +			} +		} +		else +		{ +			cost = getString("PrivateGroup"); +		} +		getChild<LLUICtrl>("group_cost")->setValue(cost); + +		getChild<LLUICtrl>("join_btn")->setVisible(!is_member); +		getChild<LLUICtrl>("leave_btn")->setVisible(is_member); + +		// Only enable join button if you are allowed to join +		bool can_join = !is_member && data->mOpenEnrollment; +		getChild<LLUICtrl>("join_btn")->setEnabled(can_join); +	} + +	// Delete the request object as it has been satisfied +	delete mPropertiesRequest; +	mPropertiesRequest = NULL; +} + +void LLInspectGroup::onClickViewProfile() +{ +	closeFloater(); +	LLGroupActions::show(mGroupID); +} + +void LLInspectGroup::onClickJoin() +{ +	closeFloater(); +	LLGroupActions::join(mGroupID); +} + +void LLInspectGroup::onClickLeave() +{ +	closeFloater(); +	LLGroupActions::leave(mGroupID); +} + +////////////////////////////////////////////////////////////////////////////// +// LLInspectGroupUtil +////////////////////////////////////////////////////////////////////////////// +void LLInspectGroupUtil::registerFloater() +{ +	LLFloaterReg::add("inspect_group", "inspect_group.xml", +					  &LLFloaterReg::build<LLInspectGroup>); +} diff --git a/indra/newview/llinspectgroup.h b/indra/newview/llinspectgroup.h new file mode 100644 index 0000000000..dfd5cbcd55 --- /dev/null +++ b/indra/newview/llinspectgroup.h @@ -0,0 +1,41 @@ +/**  + * @file llinspectgroup.h + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 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$ + */ + +#ifndef LLINSPECTGROUP_H +#define LLINSPECTGROUP_H + +namespace LLInspectGroupUtil +{ +	// Register with LLFloaterReg +	void registerFloater(); +} + +#endif diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 206d8428be..f9e93a1d38 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -33,19 +33,22 @@  #include "llpanelgroup.h" +// Library includes  #include "llbutton.h"  #include "lltabcontainer.h"  #include "lltextbox.h" -#include "llviewermessage.h"  #include "lluictrlfactory.h" + +// Viewer includes +#include "llviewermessage.h"  #include "llviewerwindow.h"  #include "llappviewer.h"  #include "llnotifications.h"  #include "llfloaterreg.h"  #include "llfloater.h" +#include "llgroupactions.h"  #include "llagent.h"  -#include "llstatusbar.h"	// can_afford_transaction()  #include "llsidetraypanelcontainer.h" @@ -274,46 +277,11 @@ void LLPanelGroup::onBtnApply(void* user_data)  	LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);  	self->apply();  } +  void LLPanelGroup::onBtnJoin()  {  	lldebugs << "joining group: " << mID << llendl; - -	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); - -	if (gdatap) -	{ -		S32 cost = gdatap->mMembershipFee; -		LLSD args; -		args["COST"] = llformat("%d", cost); -		LLSD payload; -		payload["group_id"] = mID; - -		if (can_afford_transaction(cost)) -		{ -			LLNotifications::instance().add("JoinGroupCanAfford", args, payload, LLPanelGroup::joinDlgCB); -		} -		else -		{ -			LLNotifications::instance().add("JoinGroupCannotAfford", args, payload); -		} -	} -	else -	{ -		llwarns << "LLGroupMgr::getInstance()->getGroupData(" << mID	<< ") was NULL" << llendl; -	} -} -bool LLPanelGroup::joinDlgCB(const LLSD& notification, const LLSD& response) -{ -	S32 option = LLNotification::getSelectedOption(notification, response); - -	if (option == 1) -	{ -		// user clicked cancel -		return false; -	} - -	LLGroupMgr::getInstance()->sendGroupMemberJoin(notification["payload"]["group_id"].asUUID()); -	return false; +	LLGroupActions::join(mID);  }  void LLPanelGroup::onBtnCancel() diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 628e2389b6..5c7b0ddd06 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -101,8 +101,6 @@ protected:  	static void onBtnApply(void*);  	static void onBtnRefresh(void*); -	static bool joinDlgCB(const LLSD& notification, const LLSD& response); -  	void reposButton(const std::string& name);  	void reposButtons(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5630e8a0e9..a7f0ce16d3 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2460,8 +2460,7 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name)  		BOOL public_owner = (first_id.isNull() && !first_group_owned);  		if (first_group_owned)  		{ -			// *TODO: We don't have group inspectors yet -			name = LLSLURL::buildCommand("group", first_id, "about"); +			name = LLSLURL::buildCommand("group", first_id, "inspect");  		}  		else if(!public_owner)  		{ diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 22081f9efa..26498ffc9b 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -109,6 +109,7 @@  #include "llfloaterwindlight.h"  #include "llfloaterworldmap.h"  #include "llinspectavatar.h" +#include "llinspectgroup.h"  #include "llinspectobject.h"  #include "llmediaremotectrl.h"  #include "llmoveview.h" @@ -172,6 +173,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);  	LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>);  	LLInspectAvatarUtil::registerFloater(); +	LLInspectGroupUtil::registerFloater();  	LLInspectObjectUtil::registerFloater();  	LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>); diff --git a/indra/newview/skins/default/xui/en/floater_test_inspectors.xml b/indra/newview/skins/default/xui/en/floater_test_inspectors.xml index 2011f57d8b..126bca2074 100644 --- a/indra/newview/skins/default/xui/en/floater_test_inspectors.xml +++ b/indra/newview/skins/default/xui/en/floater_test_inspectors.xml @@ -93,7 +93,9 @@      top_pad="10"      left_delta="0"      height="20" -    width="100"/> +    width="100" + 	  commit_callback.function="ShowGroupInspector" +	  commit_callback.parameter="" />    <button      name="place_btn"      label="Place" @@ -112,13 +114,35 @@    follows="left|top"    font="SansSerif"    height="20" -  layout="topleft"    left="0"    max_length="65536"    name="slurl"    top_pad="4" -  width="100"> +  width="150">      secondlife:///app/agent/00000000-0000-0000-0000-000000000000/inspect    </text> +  <text +  follows="left|top" +  font="SansSerif" +  height="20" +  left="0" +  max_length="65536" +  name="slurl_group" +  top_pad="4" +  width="150"> +    secondlife:///app/group/00000000-0000-0000-0000-000000000000/inspect +  </text> + +  <text +  follows="left|top" +  font="SansSerif" +  height="20" +  left="0" +  max_length="65536" +  name="slurl_group_about" +  top_pad="4" +  width="150"> +    secondlife:///app/group/00000000-0000-0000-0000-000000000000/about +  </text>  </floater> diff --git a/indra/newview/skins/default/xui/en/inspect_group.xml b/indra/newview/skins/default/xui/en/inspect_group.xml new file mode 100644 index 0000000000..d3f599cbbf --- /dev/null +++ b/indra/newview/skins/default/xui/en/inspect_group.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- +  Not can_close / no title to avoid window chrome +  Single instance - only have one at a time, recycle it each spawn +--> +<floater + bevel_style="in" + bg_opaque_color="MouseGray" + can_close="false" + can_minimize="false" + height="138" + layout="topleft" + name="inspect_group" + single_instance="true" + sound_flags="0" + visible="true" + width="245"> +  <string name="PrivateGroup">Private group</string> +  <string name="FreeToJoin">Free to join</string> +  <string name="CostToJoin">L$[AMOUNT] to join</string> +  <string name="YouAreMember">You are a member</string> +  <text +     follows="all" +     font="SansSerifLargeBold" +     height="18" +     left="8" +     name="group_name" +     top="5" +     text_color="white" +     use_ellipses="true" +     width="240" +     word_wrap="false"> +    Grumpity's Grumpy Group of Moose +  </text> +  <text +   follows="all" +   font="SansSerifSmallBold" +   text_color="White" +   height="18" +   left="8" +   name="group_subtitle" +   use_ellipses="true" +   top_pad="0" +   width="170"> +    123 members +  </text> +  <text +   follows="all" +   height="50" +   left="8" +   name="group_details" +   top_pad="0" +   width="170" +   word_wrap="true"> +A group of folks charged with creating a room with a moose. +Fear the moose!  Fear it!  And the mongoose too! +  </text> +  <text +   follows="all" +   height="15" +   left="8" +   name="group_cost" +   top_pad="2" +   width="170"> +L$123 to join +  </text> +  <icon +     follows="all" +     height="38" +     right="-25" +     mouse_opaque="true" +     name="group_icon" +     top="24" +     width="38" /> +    <button +     follows="top|left" +     height="18" +     image_disabled="ForwardArrow_Disabled" +     image_selected="ForwardArrow_Press" +     image_unselected="ForwardArrow_Off" +     name="view_profile_btn" +     picture_style="true" +     right="-8" +     top="35" +     left_delta="110" +     tab_stop="false" +     width="18" /> +  <button +   follows="bottom|left" +   height="23" +   label="Join" +   left="8" +   top="246" +   name="join_btn" +   width="100" +   commit_callback.function="InspectGroup.Join"/> +  <button +   follows="bottom|left" +   height="23" +   label="Leave" +   left="8" +   top="246" +   name="leave_btn" +   width="100" +   commit_callback.function="InspectGroup.Leave"/> +</floater> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 2a616d8e2f..d13f5dbde3 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1951,6 +1951,10 @@ this texture in your inventory    <string name="AgeDaysA">[COUNT] day</string>    <string name="AgeDaysB">[COUNT] days</string>    <string name="AgeDaysC">[COUNT] days</string> +  <!-- Group member counts --> +  <string name="GroupMembersA">[COUNT] member</string> +  <string name="GroupMembersB">[COUNT] members</string> +  <string name="GroupMembersC">[COUNT] members</string>    <!-- Account types, see LLAvatarPropertiesProcessor -->    <string name="AcctTypeResident">Resident</string> | 
