Group inspectors now work. They are hooked up to About Land, build tools floater, and anywhere secondlife:///app/group URLs appear. Reviewed with Leyla.
parent
e3c4b5ad26
commit
a4c657a49d
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
@ -107,6 +115,52 @@ void LLGroupActions::search()
|
|||
LLFloaterReg::showInstance("search", LLSD().insert("panel", "group"));
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
|
@ -239,6 +293,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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>);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue